← back to Quadrille Showroom

RESEARCH.md

785 lines

# Quadrille Showroom — Research Pass
Generated 2026-06-28. Feeds the officer-yolo build + contrarian gate.
Do not edit manually — re-run the research agent to refresh.

---

## LOCAL DATA AUDIT (showroom-products.json)

**883 products total.** 878 China Seas, 5 Grasscloth.
Fields present on every record: `pattern_name`, `sku`, `vendor`, `image`, `width`, `repeat`,
`match_type`, `finish`, `specs_known`, `collection`, `material`, `store_url`, `title`, `published_at`.
Fields present but EMPTY on all records: `hue` (0/883 populated), `color_bucket` (0/883).
Fields partially populated: `room` (364/883 have a room-setting image URL).
Widths: 27" (856 products), 36" (27 products). Repeat: 27" (all non-null).
Finishes: "Hand screen print" or "Woven natural fiber". Materials: "Hand screen-printed on paper"
or "Natural grasscloth on paper backing".

**Color signal in pattern names** (keyword frequency): white 750, blue 133, navy 97, green 63,
turquoise 53, brown 49, black 38, gray 37, cream 35, pink 32, orange 29, aqua 28, yellow 28,
beige 24, gold 22, purple 21, lavender 19, red 16.
This is extractable without scraping — just parse `pattern_name`.

**Design categories derivable from pattern_name keywords:**
- Global/exotic motifs (batik, ikat, java, pacific, bali, edo): ~134 items
- Geometric (stripe, ikat, check, zig, lattice, cross, frame): ~122 items
- Botanical (bamboo, palm, flower, branch, foliage, cherry, orchid): ~49 items
- Texture/natural fiber (sisal, jute, paperweave, grasscloth): ~24 items
- Uncategorized (Aga, Antionette, Monty, Lula, etc. — named pattern families): ~554 items

**Key structural insight**: The 781 distinct pattern-name roots collapse to ~150 base pattern
families (Aga has 11 colorways, Lulu Stripe has 7, Island Ikat has 5, etc.). The
`" on "` split in pattern_name separates the pattern root from the colorway description in
most records. This is the foundation for the Color River and Mood-Board grouping logic.

---

## PART 1 — BEST-IN-CLASS INTERACTIVE 3D / SPATIAL COMMERCE REFERENCES

### Studio Tier

**Immersive Garden** (Paris)
The definitive luxury-product spatial commerce studio. Built Cartier Watches & Wonders
2024 and 2025: six self-contained 3D alcoves, one per watch, scrolled through like rooms
in a museum. Stack: Three.js (WebGL), Blender (assets), GSAP + Lenis (scroll + motion),
Web Audio API (soundscape). Hidden gestures reward exploration. 60fps optimization
throughout. This is the closest analog to the Quadrille showroom concept.
- Awwwards SOTD: https://www.awwwards.com/watches-wonders-immersive-experience-for-cartier.html
- Studio portfolio: https://immersive-g.com/projects/cartier-watches-and-wonders-24/
- Awwwards 2025: https://www.awwwards.com/sites/cartier-watches-wonders-2025
- Awwwards 2026: https://www.awwwards.com/sites/cartier-watches-wonders-2026

**MONOGRID** (Milan)
Built Gucci Beauty Wishes: users explore a nocturnal 3D enchanted garden, products
"bloom like flowers." Custom 3D particle generator triggered by mouse movement with
projecting distance based on camera movement. Custom reflector material for aquatic
reflections. Stack: Three.js + Vue. QR-code accessible in Gucci stores globally.
- Project page: https://monogrid.com/project/gucci-beauty-wishes
- TBD writeup: https://thebrandingdesign.com/project/gucci-beauty-wishes-a-webgl-experience-designed-by-monogrid/
- Awwwards: https://www.awwwards.com/sites/gucci-beauty-wishes

**Active Theory** (Venice Beach)
Proprietary Hydra framework (custom 3D engine with visual GUI, Flash-to-HTML5 lineage).
Real-time particles, AI-powered navigation, fully immersive 3D environments. Their own
portfolio site is an office you walk through. Best reference for V9 (Walk-In Room) spatial
navigation architecture.
- WebGPU showcase: https://www.webgpu.com/showcase/active-theory-portfolio/

**Unseen Studio** (London)
Cited for "World Flip" (Animal Futures), liquid-like deformations, and post-processing
that makes surfaces feel physical. 2025 wrapped: SOTD winner multiple times.
- Portfolio: https://unseen.co/
- 2025 Year in Review: https://2025.unseen.co/
- Awwwards: https://www.awwwards.com/unseenstudio/

**Lusion** (London)
Codrops/awards darling; scroll parallax, Porsche Dream Machine, Meta Spatial Fusion.
Bridge between agency and product; "tasteful 3D, pragmatic stack." Scroll-driven
animation is their signature.
- Studio: https://lusion.co/

**Resn** (Auckland)
"Surrealist playground." Hold-to-reveal 3D diamond crystal on load. WebGL cursor
tracking, glitchy transitions. Best for creative risk-taking; not a product-commerce
ref, but best for V7 (Infinite White) dramatic isolation UX.
- Portfolio signals: https://www.thewebfactory.us/blogs/25-stunning-interactive-website-examples-design-trends/

**Bruno Simon** (Paris)
Three.js + Cannon.js physics portfolio (drive a car through a 3D world). Uses
*primitive collision shapes* matching visual geometry — avoids complex mesh collision.
Built entirely in Blender, exported to Three.js. Best reference for V9's physics-free
first-person navigation pattern.
- Case study: https://medium.com/@bruno_simon/bruno-simon-portfolio-case-study-960402cc259b
- Awwwards: https://www.awwwards.com/brunos-portfolio-case-study.html

### Brand Examples

**IKEA Kreativ** — AI-powered 3D room planner with Scene Scanner. Core tech: Geomagical
Labs (spatial ML). DemoModern built an IKEA wall space planner in Vue.js + Three.js (WebGL)
with drag-drop 3D products. Best reference for V8 (Living Room Setting) and V9 (Walk-In).
- TechCrunch: https://techcrunch.com/2022/06/22/ikea-rolls-out-an-ai-powered-interactive-design-experience-for-shoppers/
- IKEA newsroom: https://www.ikea.com/us/en/newsroom/corporate-news/ikea-launches-new-ai-powered-digital-experience-empowering-customers-to-create-lifelike-room-designs-pub58c94890/
- DemoModern Three.js implementation: https://demodern.com/blog/ikea-wallspace-planner-insights

**Burberry** — Virtual scarf try-on using web AR/3D; scroll campaigns are "spatial not linear."
- 2024 AR press: https://www.burberryplc.com/news/brand/2024/burberry-builds-on-legacy-of-digital-innovation-with-virtual-sca

**Cartier** — Awwwards collections: scroll-driven luxury product alcoves.
- WebGL collections: https://www.awwwards.com/awwwards/collections/webgl/

---

## PART 2 — PHILLIP JEFFRIES + WALLCOVERING DISPLAY SYSTEMS

### PJ Showroom Facts (from public sources)

- **LA showroom**: 450+ display boards, wallcovering installations, intimate design work areas.
  - https://landing.phillipjeffries.com/los-angeles-showroom
- **Chicago showroom**: 430+ display boards.
  - https://landing.phillipjeffries.com/chicago-showroom
- **Dallas showroom**: Canon reference image already saved at `public/ref/pj-dallas-showroom.png`.
  - https://landing.phillipjeffries.com/dallas-showroom
- PJ calls their board display a **"sample pegboard"** — a wall display stocked with popular
  wallcoverings in an array of colors. Trade-only showrooms, open to design trade.
- PJ fan decks ("Books & Binders"): Hundred Hemps Fan Deck (FD-HUNDREDHEMPS), The Drop 2024
  fan deck (THEDROP-24SP). Physical format is a radial fan on a ring — swatches radiate from
  a central pin.
  - Fan decks shop: https://www.phillipjeffries.com/shop/fan-decks
  - Hundred Hemps: https://www.phillipjeffries.com/shop/books-binders/FD-HUNDREDHEMPS
- PJ blog/showroom tag:
  - https://blog.phillipjeffries.com/tag/showroom

### Wing Rack Fixture Manufacturers (physical specs for 3D recreation)

**BOYA Display** (primary reference — explicitly makes wallpaper/wallcovering wing racks)
Wing-type book page-turning display racks. Hinged panels flip like pages; each panel swings
smoothly on precision hinges. Customizable: height, panel width, number of wings, finish
(matte black, white, grey). Example sizes: 150×600mm to 450×450mm panels.
- Wing rack product: https://boyadisplays.com/product/wing%E2%80%91type-book-page%E2%80%91turning-display-rack-for-flooring-samples/
- Wallpaper display racks: https://boyadisplays.com/product/aluminum-wallpaper-display-racks/
- Custom wing: https://www.stonedisplayracks.com/wing-rack-display

**McColl Display** (US-made, powder-coated steel, wall-track system)
Wall Track Wing Rack: powder-coated steel frame and wings; "Flip Through For Easy Viewing";
samples "slide in and out of channels." American-made. Customizable colors.
- Wall track wing: https://www.mccolldisplay.com/Wall.Track.Wing.Rack.Tile.Displays.html
- Sample board overview: https://www.mccolldisplay.com/Sample.Board.Displays.html

**Amazon listing (concrete spec)**: Wings 52.5"H × 26"W × 2.25"D per wing, holds
4-22×26" samples per wing.
- https://www.amazon.com/Count-Sample-Board-Wings-Display/dp/B079YRWH9T

**3D Recreation Dimensions (from WINGBOARD-SPEC.md + above)**
- Board: ~30"W × 72"H (2.54ft × 6ft), ~0.1016m pitch (4" sliver exposed)
- Hinge: single vertical edge hinge, swings ~65° open
- Rail: horizontal brass rail at ceiling/top (~8ft height)
- Frame: dark bronze metal surround on each board

### White Conveyors — Dry-Clean Conveyor Specs (V2)

V2's conveyor reference. White Conveyors X Press-U-Veyor specifications:
- Rail tube: 1-5/16" OD, 13-gauge zinc-plated steel
- Chain speed: 75 ft/min
- Bi-directional hand/foot switch (forward, stop, reverse) — maps exactly to ARROW KEY control
- Microprocessor option: automatic positioning + multi-station lockout
- Motor: fractional HP to 2HP, TEFC, inverter-controlled
- Configurations: single or two-tier, 3/5/10-slot frames
- All horizontal bends reinforced; floor or ceiling mount
- https://white-conveyors.com/standard-specs.php

**Closet Carousel by Railex** (V5 reference)
Rotating closet rod carousel — circular rotating rack for residential closets. Directly
named "Closet Carousel" — confirms our V5 naming.
- https://railexcorp.com/products/closet-carousel-by-railex/

---

## PART 3 — SHOP-BY-COLOR / COLOR ORGANIZATION

### Industry Examples

**Farrow & Ball** — 303 paint colors browsed via hierarchical filter sidebar: 12 hue groups
(Blues 55 items, Greens 56 items, etc.) + Light/Mid/Dark tone segmentation + finish filters.
NOT a visual gradient/river. Their approach is categorical, text-driven.
- All colors: https://www.farrow-ball.com/paint/all-paint-colours

**Gap / Fashion apps** — The swipe-right-to-buy "Tinder for e-commerce" interface for fashion
was piloted by Bijou Commerce; 300 fashion businesses requested it in one year.
- Digiday: https://digiday.com/marketing/swipe-right-buy-e-commerce-apps-take-design-cues-tinder/

### Color Extraction Tech Stack

**Color Thief** (best library, battle-tested)
Extracts dominant colors + full palette from images. Returns HSL: `{ h: 331, s: 77, l: 59 }`.
Six swatch roles: Vibrant, Muted, DarkVibrant, DarkMuted, LightVibrant, LightMuted.
- https://lokeshdhakar.com/projects/color-thief/

**Vibrant.js** — similar but older, returns hex swatches.
- https://jariz.github.io/vibrant.js/

**Canvas HSL extraction** — load image onto canvas, sample every 5px, average RGB, convert
to HSL. Sort by hue value. Gist implementation:
- https://gist.github.com/Pomax/0dec927f805f7c0af5b2

**Data gap to close**: `hue` and `color_bucket` are NULL on all 883 products. Run Color Thief
against each `product.image` URL, store the dominant H (0–360) in `hue` and bucket into 8–10
named buckets (red/orange/yellow/green/teal/blue/purple/neutral) in `color_bucket`. This
alone powers V6 (Color River). Can run client-side on first load and cache in localStorage,
or pre-computed server-side in a one-time script.

**HSL sort to create a "river"**: Sort products by `hue` (0–360). Render as a horizontal
scroll of swatch thumbnails flowing from red through orange/yellow/green/blue/purple back to
red. The existing `pattern_name` color keywords (blue: 133 items, navy: 97, green: 63, etc.)
give a fallback sort before Color Thief runs.

---

## PART 4 — SWIPE-TO-SHOP / MOOD-BOARD / PAIRS-WELL-WITH

### Swipe-to-Shop (V8)

**Swing.js** — the canonical open-source Tinder-style card swipe library. Hammer.js for
touch/pan. CSS `transform` with GPU acceleration. Each card absolutely positioned in a stack.
Drag threshold (~25% of screen width) triggers keep/skip. `addNewCard()` cycles stack.
- GitHub: https://github.com/gajus/swing
- CSS Script: https://www.cssscript.com/card-carousel-tinder/

**Pure-JS implementation**: Hammer.js (25KB) + CSS 3D transform.
deltaX on panend → rotation value between 0 and ±45°. Swipe far enough → animates off-screen.
- Codepen: https://codepen.io/RobVermeer/pen/japZpY/
- Tutorial: https://codingartistweb.com/2025/06/creating-a-tinder-style-swipe-card-ui-with-html-css-and-javascript/

**UX critique**: "Swiping is great for discovery, bad for search." Good for V8 (Swipe Tower)
as a dedicated discovery mode, not a replacement for grid/filter navigation.

### Mood-Board (V7)

**Morpholio Board** — top-rated iOS app for interior design mood boards; drag-drop swatches
onto canvas, auto-palette, product linking.
- https://www.morpholioapps.com/board/

**Foyr** — 750K+ product library, Benjamin Moore/Sherwin-Williams/Dulux paint integration,
drag-drop snap. Best for understanding the expected UX of interior mood boards.
- https://foyr.com/learn/best-mood-board-apps-and-software/

**Milanote** — flexible infinite canvas with real-time collaboration. Best for understanding
the spatial mood-board mental model users already have.
- https://www.milanote.com

**Rayon** — specifically mood boards for interior design projects.
- https://www.rayon.design/use-cases/mood-board

### Pairs-Well-With (V7 + V10)

**Pinterest "Complete the Look"** — scene-based visual complementary recommendation system.
Deep CNN: image featurizer + CTL head with global feature similarity + local spatial attention.
In interior design, the attention map is diffuse (considers whole-room aesthetics, not a single
object). Paper accepted CVPR 2019.
- Engineering blog: https://medium.com/pinterest-engineering/introducing-complete-the-look-a-scene-based-complementary-recommendation-system-eb891c3fe88

**Practical implementation for Quadrille**: Without ML, use rule-based:
same pattern-family base name (colorway siblings pair) + color-complement logic (opposite hue bucket).
The `" on "` pattern-name split already groups 11 Aga colorways, 7 Lulu Stripe variants, etc.
Cross-family pairs: geometric + botanical (V7's "pairs well with" column).

**Design-world coordination rules** (from Fabrics & Papers):
- Match base tone of companion to background color of wallpaper
- Large-scale pattern + solid/subtly textured companion
- Mix patterns at different scales (large hero + small accent)
- https://www.fabricsandpapers.com/blog/how-to-coordinate-fabric-and-wallpaper

---

## PART 5 — CHINA SEAS / QUADRILLE PUBLIC DATA

### Quadrille Collection Structure (from quadrillefabrics.com)

10 collections total: Quadrille (flagship handprints), China Seas (coastal/nautical), Alan
Campbell, Home Couture, Cloth & Paper, Charles Burger, Lulu DK, Plains, Wallpapers (incl.
grasscloth), Suncloth/Outdoor.
- Collections hub: https://quadrillefabrics.com/collections.html
- China Seas main: https://quadrillefabrics.com/chinaseas.html
- Wallpaper only: https://quadrillefabrics.com/Wallpaper_chinaseas.html

### China Seas Pattern Families (from public scrape of quadrillefabrics.com)

**Batik group**: Malay Batik, New Batik (17 colorways), Melong Batik, Biron Batik, Sunnyjim
Batik, Inger Batik. All linen/cotton 52-54".

**Geometric/stripe**: Malay Stripe, Macao Zig Zag, Sarong Zig Zag, Island Ikat, Sunnyjim
Geometric, Petite Zig Zag.

**Botanical/foliage**: Foliage, Foliage Reverse, Arbre de Matisse, Palm Grove, Lost Tree Palm
Club, Enchanted Bamboo, Cherry Branch.

**Named character patterns**: Aga (~11 colorways in data), Antionette (~6), Monty (~10),
Aqua Iv, Bali Hai, Bali Isle, Cumberland, San Marco, Gate House, Lulu Stripe (~7),
Lila Stripe (~6), Criss Cross, Sigourney.

**Texture/natural fiber**: Pacific Sisal (~5), Pacific Jute, Pacific Paperweave.

**Colorway naming convention**: `[Pattern Base] [Color] on [Background] [Technique] - [Accent]`
Example: "Aga Apple on Almost White Screen Printed - Off-White"
The `" on "` split gives: pattern root + colorway. Colorways are named descriptively
(French Blue, Jungle Green, Watermelon, Razzle Dazzle, Navy, Turquoise, etc.).

**SKU pattern**: DWCW-7##### (China Seas wallpaper). All 883 are wallpaper, not fabric.

**Coordinating fabric pairs are documented by Quadrille publicly** — upholstery fabric in
matching patterns is a content asset we could surface in V7 (Mood-Board):
- https://quadrillefabrics.com/coordinating-upholstery-fabric-with-wallpaper-pc-247.html

**Additional editorial content** (public, citable):
- Sigourney editorial: https://quadrillefabrics.com/Editorials-Pages/Sigourney-wallpaper-Janie-Molster-Designs.html
- General Quadrille collection overview: https://quadrillefabrics.com/quadrille-fabrics-a-general-collection-overview-pc-161.html

---

## PART 6 — VERSION-BY-VERSION BUILD NOTES

### V1 — Wingboard Arc Rack

**Best reference**: PJ Dallas showroom (`public/ref/pj-dallas-showroom.png`) — exact canonical
target per WINGBOARD-SPEC.md. Immersive Garden's Cartier alcoves (https://immersive-g.com)
for the "room + product hero" spatial composition.

**Three.js technique**: Arc rack = `CatmullRomCurve3` through 3–4 control points in a gentle
quarter-circle arc. Distribute 50 board Groups along `curve.getSpacedPoints(50)`, each Group
oriented to face inward via `lookAt(center)`. Each board is a PlaneGeometry (0.762m W × 1.83m H)
inside a darker BoxGeometry frame. Hinge = vertical axis: board's pivot Group sits at the LEFT
edge; board mesh offset +0.381m on X so rotation occurs about the left edge. GSAP `.to(hinge.rotation, { y: -Math.PI * (65/180) })` for the 65° open. Occlusion at 0.1016m pitch gives the
4" sliver for free — no UV slicing needed.

**Data we have**: All 883 image URLs. Peruse can iterate `products` array, `getSpacedPoints` the
next 50-item window on page turn.

BUILD NOTE: Copy the pivot-Group hinge pattern from the Three.js forum thread
https://discourse.threejs.org/t/correct-way-to-rotate-objects-around-a-pivot-point/29845.
GSAP `gsap.to(hingeGroup.rotation, { y: DEG65_IN_RADIANS, duration: 0.6, ease: "power2.inOut" })`
on click. CatmullRomCurve3 arc: 5 control points curving ~90° around a corner. 50 boards
on the arc, pitch 0.1016m. On load: middle board open, others closed.

---

### V2 — Dry-Clean Conveyor Rack

**Best reference**: White Conveyors X Press-U-Veyor (https://white-conveyors.com/standard-specs.php)
for physical proportions. The real conveyor is bi-directional, arrow-key controllable, 75ft/min.

**Three.js technique**: Closed loop of N hooks on a `CatmullRomCurve3` (closed=true, tension=0.5).
Each hook position = `curve.getPointAt(t)`, tangent = `curve.getTangentAt(t)`. Products hang as
PlaneGeometry from hooks. On ARROW KEY or "Next": increment loop offset, re-sample `getPointAt`
for all hooks, GSAP tween each hook's position. User stays stationary; the rack rotates to bring
the next item to dead-center front. Front item enlarges and dims others (isolate effect same as V1).
Chain-drive visual: thin CylinderGeometry tube following the same curve.

**Data we have**: 883 products cycle through the loop, paginated in windows of 20–30 visible.

BUILD NOTE: Canonical Codrops circular carousel (Dec 2025):
https://tympanus.net/codrops/2025/12/14/the-mechanics-behind-a-scroll-driven-circular-3d-carousel-with-three-js-and-post-processing/
Trigonometry: `x = Math.cos(angle) * radius`, `y = Math.sin(angle) * radius`. Adapt from a
2D circle to a 3D conveyor loop by rotating the circle to vertical (XZ plane) and adding
a front Z-bulge. Dual-sided planes avoid mirrored texture on the back side of loop.

---

### V3 — Sample-Card Wall on Hooks

**Best reference**: PJ "sample pegboard" wall (https://blog.phillipjeffries.com/tag/showroom)
described as "a wall display stocked with popular wallcoverings in an array of colors."
WINGBOARD-SPEC.md Image #8. McColl Display wall-track systems for the physical peg/hook detail.

**Three.js technique**: InstancedMesh with texture atlas. Pack all 883 swatch thumbnails into
a sprite atlas (e.g., 10×88 grid at 64px per thumb = a single 640×5632 texture).
InstancedBufferAttribute stores per-instance UV offset (column, row) into the atlas. One draw
call for all 883 cards. View-frustum culling: only visible cards consume GPU fill rate.
Hook: small CylinderGeometry or ExtrudeGeometry per card (can also be instanced).
Card tilt: slight ±3° random rotation on Z per instance stored in InstancedBufferAttribute.
Tap card → GSAP camera zoom + scale up the selected instance + show spec overlay (HTML DOM).

**Key Three.js forum solution**: Texture atlas with instanced UV offsets renders 1 million
planes without perf issues. Source: https://discourse.threejs.org/t/instancedmesh-can-it-be-used-to-draw-hundreds-of-planes-with-different-textures/13221
Set `colorSpace = THREE.SRGBColorSpace` on the atlas texture to prevent washed-out colors.

**Data we have**: 883 `image` URLs. Pre-generate the atlas server-side (Node + canvas or sharp).
364/883 products also have `room` URLs — show as alternate face on card flip.

BUILD NOTE: Single InstancedMesh + `InstancedBufferAttribute` for UV offsets. Atlas: 64px
per card, 30 columns × 30 rows = 900 slots (fits 883). Pre-bake atlas in
`scripts/build-atlas.js` using the existing `product.image` URLs. Frustum cull by toggling
`setColorAt(i, transparent)` for off-screen instances.

---

### V4 — Fan-on-Table

**Best reference**: PJ fan decks (FD-HUNDREDHEMPS, THEDROP-24SP) at
https://www.phillipjeffries.com/shop/fan-decks. Physical fan: swatches radiate from a central
ring pin, laid flat on a table. Codrops THREE.JS object wheel tutorial:
https://medium.com/swlh/create-a-three-js-object-wheel-638f04439bc4

**Three.js technique**: Swatches arranged in a radial pinwheel on the XZ plane (laid flat).
Each card = PlaneGeometry, rotated 90° to lie flat. Position: `x = r * cos(i * 2π/N)`,
`z = r * sin(i * 2π/N)` where r grows with N (inner + outer rings for 883 items).
Center pivot: a small CylinderGeometry pin. Drag interaction: pointer delta X → rotate
the entire group around Y axis. GSAP spring-snap to nearest swatch on release.
Fan organization: group by color_bucket after Color Thief runs, so color families appear
in arcs (all blues together, then greens, etc.) — like a real fan deck.

**Data we have**: 883 images. Need `hue` values from Color Thief pre-compute.
Color Thief reference: https://lokeshdhakar.com/projects/color-thief/

BUILD NOTE: Fan Group: flat-rotated PlaneGeometry cards, radial position. Drag = `addEventListener
('pointermove', delta => group.rotation.y += delta.x * 0.005)`. GSAP snap on pointerup.
Sort order: by `hue` HSL value (0–360) so fan sweeps the spectrum. If no pre-computed hue:
fall back to `pattern_name` color keyword sort (750 "white" items need secondary sort by blue/navy/green/etc.).

---

### V5 — Closet Carousel

**Best reference**: Railex "Closet Carousel" rotating rack (https://railexcorp.com/products/closet-carousel-by-railex/).
Two-tier circular rotating rack in a closet alcove. Real product confirms our V5 naming exactly.
Codrops infinite 3D carousel: https://tympanus.net/codrops/2025/11/11/building-a-3d-infinite-carousel-with-reactive-background-gradients/

**Three.js technique**: Two concentric `CatmullRomCurve3` circles (inner + outer tier) in the
XZ plane. Products hang from hangers on each loop. Motor = constant `group.rotation.y += 0.002`
in RAF loop. Click = `group.rotation.y` tween to snap clicked item to front (12 o'clock position).
Closet millwork: warm wood texture on box walls + ceiling (BoxGeometry with inward normals).
Spotlight from above. Warm amber PointLight.

**Data we have**: 883 products, can distribute 440 per tier.

BUILD NOTE: Inner and outer CatmullRomCurve3 circles (r=1.2m, r=2.0m), 40 items each visible
at a time. Constant rotation via `ticker.add(() => group.rotation.y += 0.001)`. Click raycasts
to nearest hanger → tween group.rotation to bring it front-center. Background: closed BoxGeometry
room with warm wood texture on 3 walls + ceiling.

---

### V6 — Color River (Shop by Color)

**Best reference**: No single site does a true "color river" for wallpaper — this is genuinely
differentiated. Farrow & Ball does categorical color groups, not a visual gradient.
The closest technical implementation: the Codrops scroll-reactive depth gallery (March 2026)
https://tympanus.net/codrops/2026/03/09/building-a-scroll-reactive-3d-gallery-with-three-js-velocity-and-mood-based-backgrounds/
which uses per-image mood palettes that shift the background as you scroll.

**Three.js technique**: Sort all 883 products by `hue` (0–360). Lay out as a horizontal
infinite scroll band of swatch PlaneGeometry tiles. Background gradient shifts to match the
current hue zone (CSS `background` or a full-width THREE.PlaneGeometry with ShaderMaterial
that lerps between two `color_bucket` colors). Camera pans along X axis; GSAP ScrollTrigger
or wheel events drive `camera.position.x`. Color bucket labels float above each section
as 3D text (THREE.TextGeometry or CSS3DRenderer labels).

**Data gap**: `hue` and `color_bucket` both NULL. Need Color Thief pre-compute.
Pre-compute script: for each product, `fetch(image)`, draw on offscreen canvas (128×128),
run Color Thief `.getColor()`, store `{ hue: hsv.h, color_bucket: bucketName }` to a sidecar
JSON. Then re-serve `showroom-products.json` with those fields filled. One-time run.

**Existing data as fallback**: Parse `pattern_name` color keywords. Products containing "navy"
or "blue" → bucket blue. "green" → green. "white" with no other color → neutral. This covers
~70% of items well enough for an MVP Color River.

BUILD NOTE: Sort by hue. Horizontal scroll band (X axis). ShaderMaterial background lerps
`color_bucket` color. Label zones with CSS3DRenderer floating text above the band.
Reference: Codrops velocity+mood gallery for the lerp background pattern (Engine.js +
Background.js + Scroll.js modular split). Farrow & Ball's categorical approach (12 hue groups,
light/mid/dark tone) is a good secondary filter sidebar alongside the visual river.

---

### V7 — Mood-Board Table

**Best reference**: Morpholio Board (https://www.morpholioapps.com/board/) — the industry-leading
interior design mood board app. Foyr Moodboard for snap-to-grid UX. Pinterest "Complete the Look"
(CVPR 2019, https://medium.com/pinterest-engineering/introducing-complete-the-look-a-scene-based-complementary-recommendation-system-eb891c3fe88)
for the "pairs well with" recommendation logic.

**Three.js technique**: 3D consultation table (round or rectangular BoxGeometry with warm wood
texture) in the center of frame. Drag swatch cards from a side panel onto the table surface.
Cards on table = PlaneGeometry with `position.y = tableTop + 0.001` (flush with surface).
Drag: pointer ray → intersect with table PlaneGeometry → set card XZ to intersection point.
"Pairs well with": after placing a card, query the same pattern-base-name siblings (colorway
matches) + cross-family suggestions (geometric + botanical rule). Show 3–4 suggestion cards
floating at the table edge.

**Pairs-well-with logic** (rule-based, no ML needed):
1. Sibling colorways: `products.filter(p => p.pattern_name.split(' on ')[0] === currentBase)` — instant.
2. Texture complement: if current = `finish === 'Hand screen print'`, suggest `'Woven natural fiber'` companions and vice versa.
3. Color complement: if `color_bucket === 'blue'` → suggest `color_bucket === 'gold'` or `'coral'`.

**Data we have**: All product images + pattern_name. The `" on "` split gives colorway grouping
instantly. 364 room images can show "see it installed" on the table surface.

BUILD NOTE: Table = BoxGeometry with UV-mapped wood texture. Drag cards via raycasting against
a `THREE.Plane` at `tableTop` Y. Suggestions panel = 4 PlaneGeometry cards auto-arranged at
table edge. HTML DOM overlay for the spec sheet on hover. Quadrille's own coordination guide
(https://quadrillefabrics.com/coordinating-upholstery-fabric-with-wallpaper-pc-247.html) lists
actual pairs we can hard-code as a starting point.

---

### V8 — Swipe Tower

**Best reference**: Swing.js (https://github.com/gajus/swing) — open source, Hammer.js, production
proven. Digiday swipe-for-fashion article: https://digiday.com/marketing/swipe-right-buy-e-commerce-apps-take-design-cues-tinder/
Bijou Commerce implementation (300 fashion retailers adopted in one year).
Tinder-style codepen: https://codepen.io/RobVermeer/pen/japZpY/

**Mechanic**: One large swatch at a time, full viewport. Hammer.js on the card. Pan: card
rotates ±20° on Y proportional to deltaX. On release: if |deltaX| > threshold → keep (swipe
right, add to favorites stack) or skip (swipe left). Favorites counter badge in top corner.
Favorites stack: slide-out panel showing selected swatches as thumbnails.

**NOT Three.js** — pure CSS 3D transform is the right approach here. `transform: rotate3d(0,1,0,Ndeg) translateX(Npx)` on the card element. GPU-accelerated. Faster to implement than WebGL for this mechanic.

**Data we have**: All 883 `image` URLs. `title` for the card label. `store_url` for the "Buy" CTA.

BUILD NOTE: Swing.js or vanilla Hammer.js. Card stack = 5 cards in DOM (visible stack illusion
via CSS scale + translateY offsets). On swipe, shift array, re-render next card. Keep = push to
`dw_favorites[]` in localStorage (same localStorage key as the existing selection system).
Show spec (width, finish, match_type) on card as lower-third overlay.

---

### V9 — Walk-In Room

**Best reference**: IKEA Kreativ (room scanner + 3D walk-through, https://www.ingka.com/newsroom/ikea-launches-new-ai-powered-experience-empowering-customers-to-create-lifelike-room-designs/),
Tilesview wallpaper visualizer (https://tilesview.ai/wallpaper-visualizer),
Three.js PointerLockControls official example (https://threejs.org/examples/misc_controls_pointerlock.html).
Panolens.js for 360° room panorama alternative (https://github.com/pchen66/panolens.js).

**Three.js technique**: BoxGeometry room (inside-out — invert normals so you stand INSIDE).
Four walls + ceiling + floor. Wall material = `THREE.MeshStandardMaterial({ map: wallpaperTexture })`
tiling the selected pattern at physical scale (27" wide = 0.6858m, repeat the UV accordingly:
`texture.repeat.set(roomWidth / 0.6858, roomHeight / 1.83)`). First-person navigation:
`PointerLockControls` (W/A/S/D + mouse look). On product switch: `GSAP.to(material, { opacity: 0 })`
→ swap texture → `opacity: 1` fade transition. Room dimensions: standard 12'×14' room (3.66m × 4.27m),
9' ceiling (2.74m).

**364 room images available**: show the existing `product.room` image on an accent wall or
inset "mood board" panel inside the room as a secondary reference.

BUILD NOTE: Inside-out BoxGeometry with `side: THREE.BackSide`. UV repeat = room_width / pattern_width.
PointerLockControls: lock on click, unlock on Escape. Product switcher: floating HUD panel (HTML)
outside the canvas. Pattern scale: 27" = 0.6858m world units → texture.repeat.x = roomWidth / 0.6858.
Add a window (cutout PlaneGeometry with transparency or alpha map) for ambient realism. Soft
HDRI-equivalent: rectangular SpotLight from ceiling + ambient PointLight 0.3 intensity.

---

### V10 — Concierge Nook

**Best reference**: AI interior design chatbot landscape (Decorilla, Palazzo by Venus Williams,
ChatGPT shopping integration):
- https://businessofhome.com/articles/the-ai-interior-design-race-has-a-surprising-frontrunner
- https://www.decorilla.com/online-decorating/ai-interior-design-for-room-design/
- https://botsquad.ai/ai-chatbot-for-interior-design-services
Wallpaper's Back concierge (already built locally in this project cluster) as implementation model.

**Mechanic**: POV = seated at the consultation table (camera at ~42" height, slight downward tilt
into the table surface). The "concierge" is an HTML overlay chat panel on the right side. User
types a query ("show me something tropical in blue"). The assist surface:
1. Filters `showroom-products.json` by matching keywords in `pattern_name`.
2. Animates 2–3 matching boards physically "pulled" to the front of the arc rack (V1 open-board
   animation) or placed on the table surface (V7).
3. Shows spec cards for each recommendation.

**AI integration options** (cheapest to richest):
- Level 0: Keyword filter on `pattern_name` + `color_bucket` (zero cost, instant).
- Level 1: Embed product titles client-side, cosine-similarity against user query (50KB Wink NLP or
  use-lite tensor model, runs in browser, $0).
- Level 2: POST query + product list to `/api/concierge` → call Anthropic Haiku 4.5
  (~$0.0013/query, cost shown per query per CLAUDE.md rule).

**Data we have**: All `pattern_name`, `finish`, `material`, `color_bucket` (once populated).
Natural language queries map directly to keyword fields: "tropical" → Batik/Palm/Island patterns.
"Geometric" → Zig Zag/Lattice/Ikat patterns. "Neutral" → "white" + "natural" color keywords.

BUILD NOTE: Camera at y=1.07m, slight pitch down (-15°). Consultation table in foreground
(same as V7 table asset). Bouclé chairs visible left/right. The concierge panel = right-side
HTML `<div>` with a chat input. Response renders matched product cards with a "Pull to rack" CTA
that triggers V1-style board opening. Use Level 0 keyword filter for initial build; stub the
Haiku endpoint for later upgrade. Existing wallpapersback.com concierge in
`/root/public-projects/wallpapersback` is the proven implementation model.

---

## PART 7 — TECHNICAL IMPLEMENTATION REFERENCE STACK

### Core Three.js Techniques by Version

| Version | Primary Technique | Key Reference |
|---------|------------------|---------------|
| V1 Arc Rack | CatmullRomCurve3 arc + pivot-Group hinge + GSAP .y rotation | discourse.threejs.org pivot thread |
| V2 Conveyor | Closed CatmullRomCurve3 loop + getPointAt(t) tick | Codrops circular carousel Dec 2025 |
| V3 Card Wall | InstancedMesh + texture atlas + InstancedBufferAttribute UV | threejs.org InstancedMesh docs |
| V4 Fan Table | Radial PlaneGeometry + drag rotation + hue sort | Color Thief + cos/sin layout |
| V5 Closet | Dual CatmullRomCurve3 circles + constant RAF rotation | Railex physical ref |
| V6 Color River | Horizontal X-scroll + ShaderMaterial bg lerp + hue sort | Codrops velocity+mood Mar 2026 |
| V7 Mood Board | Table BoxGeometry + raycasting drag + sibling-colorway query | Morpholio Board UX model |
| V8 Swipe Tower | CSS 3D transform + Hammer.js panend | Swing.js + Codepen |
| V9 Walk-In | Inside-out BoxGeometry + PointerLockControls + UV repeat | Three.js PointerLock example |
| V10 Concierge | Camera at table height + HTML chat overlay + keyword filter | WPB concierge implementation |

### Performance Targets (from WINGBOARD-SPEC.md)

FPS target: 50+. Verify with `node scripts/walkthrough-record.js`.
Key optimizations:
- V3 Card Wall: InstancedMesh + atlas = 1 draw call for 883 cards
- V1/V2: Only 50 boards visible at once; texture lazy-load on board open
- V6 Color River: Virtual scroll — only render visible window of products
- All versions: `THREE.SRGBColorSpace` on all textures to prevent washed-out images

### Data Gaps to Close Before Build

1. **`hue` + `color_bucket` fields** (0/883 populated): Run Color Thief against all 883 `image` URLs.
   Script: `scripts/compute-hues.js`. Outputs updated `showroom-products.json` with hue (0–360)
   and color_bucket ('blue'|'green'|'yellow'|'orange'|'red'|'purple'|'neutral'|'multi').
   Powers V4 (Fan sort), V6 (Color River), V7 (pairs-well-with color complement), V10 (concierge filter).

2. **Texture atlas** (needed for V3 Card Wall): Build `scripts/build-atlas.js` — fetch all 883
   `image` URLs, resize to 64×64, pack into a 30-column sprite sheet PNG + JSON manifest with
   (col, row) per SKU. Save to `public/atlas/cs-883.png` + `cs-883.json`.

3. **Pattern family grouping** (needed for V7 pairs-well-with): One-time JSON file mapping each
   SKU to its `patternBase` (the `" on "` split prefix). Can be pre-computed inline in the
   products JSON or as a separate `pattern-families.json`.

---

## PART 8 — TOP 3 DATA/STRUCTURE IDEAS FOR BEST-IN-INDUSTRY QUALITY

### Idea 1: Pre-Computed Hue Layer (powers V4, V6, V7, V10)

Run Color Thief on all 883 product images once, store hue + bucket in the data. This single
addition makes four versions dramatically better. The Color River (V6) goes from
keyword-guessing to pixel-accurate HSL sort. The Fan (V4) becomes a true spectrum fan. The
Mood Board (V7) can suggest true color complements. The Concierge (V10) can answer
"show me something coral" accurately. Estimated compute time: ~883 HTTP fetches + canvas
operations, ~5 minutes in Node. Color Thief: https://lokeshdhakar.com/projects/color-thief/

### Idea 2: Pattern Family Grouping (powers V7 "pairs well", V10 concierge, V3 card wall header)

The 883 products collapse to ~150 base pattern families via the `" on "` split. Pre-compute
this grouping and add a `patternBase` and `patternFamily` field. This makes:
- V7 Mood Board's "pairs well with" = instant sibling colorway suggestions (no ML)
- V3 Card Wall = group cards by pattern family with a label header per group
- V10 Concierge = much better categorical answers ("show me Aga in blue" → filter patternBase=Aga + blue)
China Seas' public design categories (Batik, Geometric, Botanical, Texture) are extractable
from the public catalog page: https://quadrillefabrics.com/chinaseas.html

### Idea 3: Room Image Integration Across All Versions (364/883 products have a `room` URL)

41% of products already have a room-setting image. Use this systematically:
- V1 Wingboard: when a board is "open", show the room image as a secondary inset panel next to
  the open board (like "see it installed" alongside the pattern close-up)
- V3 Card Wall: card flip-back = room image (flip card animation on tap, front=swatch, back=room)
- V7 Mood Board: the table surface itself can show a room-scale preview derived from the `room` image
- V9 Walk-In: the 364 room images can initialize the room texture by mapping the room image onto
  the back wall as a "reference shot" before the user switches to the actual pattern tile view
This costs nothing new (URLs already in the data) and dramatically raises the perceived quality.

---

## CITATIONS

[1] Immersive Garden / Cartier. "Watches & Wonders Immersive Experience." Awwwards SOTD.
    https://www.awwwards.com/watches-wonders-immersive-experience-for-cartier.html

[2] MONOGRID. "Gucci Beauty Wishes WebGL Experience." TheBrandingDesign.
    https://thebrandingdesign.com/project/gucci-beauty-wishes-a-webgl-experience-designed-by-monogrid/

[3] Active Theory. "Portfolio — Hydra Framework WebGL." WebGPU Community Showcase.
    https://www.webgpu.com/showcase/active-theory-portfolio/

[4] Lusion Studio. Official portfolio. https://lusion.co/

[5] Unseen Studio. Annual review 2025. https://2025.unseen.co/

[6] Codrops / Sebastien Matos. "Scroll-Reactive 3D Gallery, Three.js + Velocity + Mood Backgrounds."
    March 2026. https://tympanus.net/codrops/2026/03/09/building-a-scroll-reactive-3d-gallery-with-three-js-velocity-and-mood-based-backgrounds/

[7] Codrops. "Mechanics Behind a Scroll-Driven Circular 3D Carousel with Three.js."
    December 2025. https://tympanus.net/codrops/2025/12/14/the-mechanics-behind-a-scroll-driven-circular-3d-carousel-with-three-js-and-post-processing/

[8] Codrops. "Building a 3D Infinite Carousel with Reactive Background Gradients."
    November 2025. https://tympanus.net/codrops/2025/11/11/building-a-3d-infinite-carousel-with-reactive-background-gradients/

[9] Bruno Simon. "Portfolio Case Study — Three.js + Cannon.js."
    https://medium.com/@bruno_simon/bruno-simon-portfolio-case-study-960402cc259b

[10] Three.js Forum. "InstancedMesh with Different Textures — Atlas Solution."
     https://discourse.threejs.org/t/instancedmesh-can-it-be-used-to-draw-hundreds-of-planes-with-different-textures/13221

[11] Three.js Forum. "Correct Way to Rotate Objects Around a Pivot Point."
     https://discourse.threejs.org/t/correct-way-to-rotate-objects-around-a-pivot-point/29845

[12] Three.js Docs. "PointerLockControls."
     https://threejs.org/docs/pages/PointerLockControls.html

[13] Swing.js (gajus). "Tinder-style swipeable cards."
     https://github.com/gajus/swing

[14] Phillip Jeffries. "Fan Decks — Books & Binders."
     https://www.phillipjeffries.com/shop/fan-decks

[15] Phillip Jeffries. "Los Angeles Showroom — 450+ display boards."
     https://landing.phillipjeffries.com/los-angeles-showroom

[16] Phillip Jeffries. "Dallas Showroom."
     https://landing.phillipjeffries.com/dallas-showroom

[17] BOYA Display. "Wing-Type Book Page-Turning Display Rack for Flooring/Wallpaper Samples."
     https://boyadisplays.com/product/wing%E2%80%91type-book-page%E2%80%91turning-display-rack-for-flooring-samples/

[18] BOYA Display. "Wallpaper Display Rack Showroom Solutions."
     https://stonedisplayracks.com/wallpaper-display-rack/

[19] McColl Display. "Wall Track Wing Rack."
     https://www.mccolldisplay.com/Wall.Track.Wing.Rack.Tile.Displays.html

[20] White Conveyors. "Standard Dry Cleaning Conveyor Specifications — X Press-U-Veyor."
     https://white-conveyors.com/standard-specs.php

[21] Railex. "Closet Carousel by Railex."
     https://railexcorp.com/products/closet-carousel-by-railex/

[22] Quadrille Wallpapers & Fabrics. "China Seas Collection."
     https://quadrillefabrics.com/chinaseas.html

[23] Quadrille. "Coordinating Upholstery Fabric With Wallpaper."
     https://quadrillefabrics.com/coordinating-upholstery-fabric-with-wallpaper-pc-247.html

[24] Quadrille. "Collections Overview."
     https://quadrillefabrics.com/collections.html

[25] Color Thief (Lokesh Dhakar). "Extract dominant color palette from images."
     https://lokeshdhakar.com/projects/color-thief/

[26] Vibrant.js. "Extract prominent colors from images."
     https://jariz.github.io/vibrant.js/

[27] Pomax GitHub Gist. "Sort images by dominant hue."
     https://gist.github.com/Pomax/0dec927f805f7c0af5b2

[28] Pinterest Engineering. "Complete the Look — Scene-Based Complementary Recommendation System."
     CVPR 2019. https://medium.com/pinterest-engineering/introducing-complete-the-look-a-scene-based-complementary-recommendation-system-eb891c3fe88

[29] Digiday. "Swipe right to buy — E-commerce apps take design cues from Tinder."
     https://digiday.com/marketing/swipe-right-buy-e-commerce-apps-take-design-cues-tinder/

[30] Farrow & Ball. "All Paint Colours — Browse UI."
     https://www.farrow-ball.com/paint/all-paint-colours

[31] Morpholio Board. "Interior design mood board app."
     https://www.morpholioapps.com/board/

[32] IKEA / Ingka Group. "IKEA Kreativ AI-powered room design."
     https://www.ingka.com/newsroom/ikea-launches-new-ai-powered-experience-empowering-customers-to-create-lifelike-room-designs/

[33] DemoModern. "IKEA Interactive 3D Wallspace Planner — Vue.js + Three.js."
     https://demodern.com/blog/ikea-wallspace-planner-insights

[34] Fabrics & Papers. "How to Coordinate Fabric and Wallpaper."
     https://www.fabricsandpapers.com/blog/how-to-coordinate-fabric-and-wallpaper

[35] Awwwards. "WebGL Website Collection."
     https://www.awwwards.com/awwwards/collections/webgl/

[36] Burberry. "Virtual Scarf Try-On Experience — AR Web 3D." 2024.
     https://www.burberryplc.com/news/brand/2024/burberry-builds-on-legacy-of-digital-innovation-with-virtual-sca

[37] VR Me Up. "InstancedMesh Performance Optimizations."
     https://vrmeup.com/devlog/devlog_10_threejs_instancedmesh_performance_optimizations.html

[38] Utsubo. "100 Three.js Tips That Actually Improve Performance (2026)."
     https://www.utsubo.com/blog/threejs-best-practices-100-tips

[39] Business of Home. "The AI Interior Design Race — Front-Runners."
     https://businessofhome.com/articles/the-ai-interior-design-race-has-a-surprising-frontrunner

[40] Decorilla. "AI Interior Design Tools."
     https://www.decorilla.com/online-decorating/ai-interior-design-for-room-design/