[object Object]

← back to Quadrille Showroom

Tighter arc (86deg span, ~75% overlap = thinner slivers) + warmer cream plaster + calmer exposure to match PJ photo; gates hold (senior 50/69, 2min 69/71, 0 err)

cbd8fb95cd5047ef0218b7f626d32109749d4841 · 2026-06-28 08:09:07 -0700 · Steve

Files touched

Diff

commit cbd8fb95cd5047ef0218b7f626d32109749d4841
Author: Steve <steve@designerwallcoverings.com>
Date:   Sun Jun 28 08:09:07 2026 -0700

    Tighter arc (86deg span, ~75% overlap = thinner slivers) + warmer cream plaster + calmer exposure to match PJ photo; gates hold (senior 50/69, 2min 69/71, 0 err)
---
 data/enrichment.json             |   1 +
 package-lock.json                | 585 ++++++++++++++++++++++++++++++++++++-
 package.json                     |   3 +-
 proto/shot-colorriver.cjs        |  88 ++++++
 proto/shots/v10-concierge.png    | Bin 0 -> 724853 bytes
 proto/shots/v6-colorriver.png    | Bin 0 -> 867221 bytes
 proto/shots/v8-swipe-filled.png  | Bin 0 -> 1052236 bytes
 proto/shots/v8-swipe.png         | Bin 0 -> 859543 bytes
 proto/shots/v9-walkin-angle2.png | Bin 0 -> 1473500 bytes
 proto/shots/v9-walkin.png        | Bin 0 -> 1016219 bytes
 proto/v10-concierge.html         | 561 ++++++++++++++++++++++++++++++++++++
 proto/v6-colorriver.html         | 547 +++++++++++++++++++++++++++++++++++
 proto/v8-swipe.html              | 602 +++++++++++++++++++++++++++++++++++++++
 proto/v9-walkin.html             | 367 ++++++++++++++++++++++++
 proto/verify-v10.cjs             |  80 ++++++
 proto/verify-v8.cjs              |  73 +++++
 public/js/showroom.js            |  14 +-
 scripts/enrich.js                |  56 ++++
 18 files changed, 2969 insertions(+), 8 deletions(-)

diff --git a/data/enrichment.json b/data/enrichment.json
new file mode 100644
index 0000000..dde277b
--- /dev/null
+++ b/data/enrichment.json
@@ -0,0 +1 @@
+{"built_at":"2026-06-28T15:07:17.707Z","hue_done":true,"hue_filled":878,"hue_failed":5,"enrich":{"DWCW-700146":{"patternBase":"Aga Apple","room":null,"hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-700246":{"patternBase":"Aga Jungle Green","room":null,"hue":59,"color_bucket":"yellow","familySkus":[]},"DWCW-700346":{"patternBase":"Aga Jungle","room":null,"hue":60,"color_bucket":"yellow","familySkus":[]},"DWCW-700446":{"patternBase":"Aga New Navy Almost White","room":null,"hue":217,"color_bucket":"blue","familySkus":[]},"DWCW-700546":{"patternBase":"Aga Pistachio","room":null,"hue":85,"color_bucket":"green","familySkus":[]},"DWCW-700646":{"patternBase":"Aga Purple","room":null,"hue":320,"color_bucket":"magenta","familySkus":[]},"DWCW-700746":{"patternBase":"Aga Reverse Apple Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aga-Reverse-fabric-group_39f22a7b-0bbe-4098-b3be-1775ba205742.jpg","hue":74,"color_bucket":"green","familySkus":[]},"DWCW-700846":{"patternBase":"Aga Reverse Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aga-Reverse-fabric-group_e4b46742-2238-4774-8301-be3f94a15bbc.jpg","hue":18,"color_bucket":"orange","familySkus":[]},"DWCW-700946":{"patternBase":"Aga Reverse New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aga-Reverse-fabric-group_697a0328-c768-4406-bf8d-0f26211d564c.jpg","hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-701046":{"patternBase":"Aga Reverse Watermelon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aga-Reverse-fabric-group_e0c86671-d3af-4e07-92a8-d9459aa46796.jpg","hue":343,"color_bucket":"red","familySkus":[]},"DWCW-701146":{"patternBase":"Aga Turquoise","room":null,"hue":183,"color_bucket":"teal","familySkus":[]},"DWCW-701246":{"patternBase":"Aga Watermelon","room":null,"hue":344,"color_bucket":"red","familySkus":[]},"DWCW-702246":{"patternBase":"Antionette Black_onwhite","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Antoinette_Black_onWhite_CP1040W-08.jpg","hue":153,"color_bucket":"green","familySkus":[]},"DWCW-701946":{"patternBase":"Antionette Burnt_Orange_on_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Barbados-Batik-Orange-Burnt-Orange-on-Almost-White-8250-05WP.jpg","hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-702346":{"patternBase":"Antionette Cognac_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Antoinette_Cognac_on_White_CP1040W-06.jpg","hue":26,"color_bucket":"orange","familySkus":[]},"DWCW-702046":{"patternBase":"Antionette Lavender_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Lavender-on-Almost-White-6650WP-04.jpg","hue":278,"color_bucket":"purple","familySkus":[]},"DWCW-702446":{"patternBase":"Antionette Navy_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Antoinette_Navy_on_White_CP1040W-07.jpg","hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-702146":{"patternBase":"Antionette Turquoise_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-Yellow-on-White-7240-02WP_cf9b842c-c2b3-470b-ac7f-f2fe14a05178.jpg","hue":194,"color_bucket":"teal","familySkus":[]},"DWCW-702546":{"patternBase":"Aqua Iv Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_34512a11-eabe-48a4-96de-a5007932ba21.jpg","hue":160,"color_bucket":"green","familySkus":[]},"DWCW-702646":{"patternBase":"Aqua Iv Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_73a617c1-1351-4d6a-b965-5a9bc5f689e4.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-702746":{"patternBase":"Aqua Iv Camel","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_f68643fb-323e-451e-b798-4ec7c41adb71.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-702846":{"patternBase":"Aqua Iv French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_c73055e6-60a5-4f58-8359-008f7cb475af.jpg","hue":208,"color_bucket":"blue","familySkus":[]},"DWCW-702946":{"patternBase":"Aqua Iv Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_b0342750-5240-46ca-9526-6dfa2b625454.jpg","hue":83,"color_bucket":"green","familySkus":[]},"DWCW-703046":{"patternBase":"Aqua Iv Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_6e75ac9f-414e-47b0-aa0f-3dc45f47a0a1.jpg","hue":341,"color_bucket":"red","familySkus":[]},"DWCW-703146":{"patternBase":"Aqua Iv Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_4adae4e3-dc9f-4450-9ebd-a3472ebe17bb.jpg","hue":218,"color_bucket":"blue","familySkus":["DWCW-703246"]},"DWCW-703246":{"patternBase":"Aqua Iv Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_70ef6106-4b82-4821-9f99-f6f4a94c5d77.jpg","hue":221,"color_bucket":"blue","familySkus":["DWCW-703146"]},"DWCW-703346":{"patternBase":"Aqua Iv Rust","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_d233f236-6a8a-468d-81e1-b63792b9e5bd.jpg","hue":10,"color_bucket":"red","familySkus":[]},"DWCW-703446":{"patternBase":"Aqua Iv Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_2560515e-f66f-4d45-b49d-cff267f63afa.jpg","hue":179,"color_bucket":"teal","familySkus":[]},"DWCW-703546":{"patternBase":"Aqua Iv Yellow","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Aqua-IV-fabric-group_8b364a2a-0977-49b1-bcfb-411e969735c3.jpg","hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-703646":{"patternBase":"Arbre de Matisse Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_623e5507-e083-46e9-b743-932e57e437d9.jpg","hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-703746":{"patternBase":"Arbre De Matisse Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_65c8ef0d-dba4-41e7-8e3d-7e1d42461d9e.jpg","hue":20,"color_bucket":"orange","familySkus":["DWCW-703846"]},"DWCW-703846":{"patternBase":"Arbre De Matisse Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_ee634196-f04f-4b5b-b860-659843bb87c2.jpg","hue":22,"color_bucket":"orange","familySkus":["DWCW-703746"]},"DWCW-703946":{"patternBase":"Arbre De Matisse China Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_ba7e3c65-1593-4f89-be76-9fc720720742.jpg","hue":218,"color_bucket":"blue","familySkus":[]},"DWCW-704046":{"patternBase":"Arbre De Matisse Gold Metallic","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_82896203-7452-496a-b8ba-fdbea0844c16.jpg","hue":45,"color_bucket":"orange","familySkus":[]},"DWCW-704146":{"patternBase":"Arbre De Matisse Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_2be773d7-ab1c-4143-b2fd-5dd3dd26ad75.jpg","hue":74,"color_bucket":"green","familySkus":[]},"DWCW-704246":{"patternBase":"Arbre De Matisse Reverse Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_4a5f674f-5c22-4e7e-a69e-575371b5356c.jpg","hue":10,"color_bucket":"red","familySkus":[]},"DWCW-704346":{"patternBase":"Arbre De Matisse Reverse China Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_17e8d75f-8900-4f5f-89ac-d6d4a409415c.jpg","hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-704446":{"patternBase":"Arbre De Matisse Reverse French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_6942d1b2-54d4-47f5-a0bb-0cee6de9877c.jpg","hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-704546":{"patternBase":"Arbre De Matisse Reverse Inca Gold","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_4b574217-419d-4b84-9d03-407c90bdf37f.jpg","hue":61,"color_bucket":"yellow","familySkus":[]},"DWCW-704646":{"patternBase":"Arbre De Matisse Reverse Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_e660d59b-b047-4203-873a-b0a96eb54cde.jpg","hue":70,"color_bucket":"yellow","familySkus":[]},"DWCW-704746":{"patternBase":"Arbre De Matisse Reverse Shrimp","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_5041a8c3-0d80-45e4-b167-cae562ebb93f.jpg","hue":11,"color_bucket":"red","familySkus":[]},"DWCS-894046":{"patternBase":"Arbre de Matisse Reverse Soft Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_6aec8444-8cbe-4dd8-8e71-52f0b6bfa403.jpg","hue":132,"color_bucket":"green","familySkus":[]},"DWCW-704846":{"patternBase":"Arbre De Matisse Reverse White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-Reverse-fabric-group_5ea45d97-1162-4a7b-809b-1e3889d6420e.jpg","hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-704946":{"patternBase":"Arbre De Matisse Silver Metallic","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_5982aff7-e6a4-43ee-b6a9-0e9ac002d848.jpg","hue":57,"color_bucket":"yellow","familySkus":[]},"DWCW-705046":{"patternBase":"Arbre De Matisse White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_d3f3ff09-d9c9-4756-9906-8518e5f5a630.jpg","hue":49,"color_bucket":"yellow","familySkus":["DWCW-705146"]},"DWCW-705146":{"patternBase":"Arbre De Matisse White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Arbre-de-Matisse-fabric-group_ab124c48-ca5b-4bef-9d1a-86e9825b6eec.jpg","hue":203,"color_bucket":"blue","familySkus":["DWCW-705046"]},"DWCW-705246":{"patternBase":"Bali Diamond Coral on_Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Diamond-fabric-group_98b88d83-2a6a-45af-8496-92b30de22caa.jpg","hue":5,"color_bucket":"red","familySkus":[]},"DWCW-705346":{"patternBase":"Bali Diamond Lilac","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Diamond-fabric-group_74e0bf80-4ecd-4baa-a9b2-0e743debf2bf.jpg","hue":290,"color_bucket":"purple","familySkus":[]},"DWCW-705446":{"patternBase":"Bali Diamond Multi Greys","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Diamond-fabric-group_270eab72-add0-412e-aef7-4c894b0d275a.jpg","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-705546":{"patternBase":"Bali Hai Blues","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_d63546a3-4dc6-4ce0-8be1-9334c2fd4393.png","hue":214,"color_bucket":"blue","familySkus":[]},"DWCW-705646":{"patternBase":"Bali Hai Grays","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_7f57c5f8-64f1-475f-8c03-5916863cd38e.png","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-705746":{"patternBase":"Bali Hai Greens","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_e180a448-a86d-4a36-960c-75e77d0a8151.png","hue":96,"color_bucket":"green","familySkus":["DWCW-705846"]},"DWCW-705846":{"patternBase":"Bali Hai Greens","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_7519a43f-02f4-4f18-89d0-199f71ebf4f8.png","hue":101,"color_bucket":"green","familySkus":["DWCW-705746"]},"DWCW-705946":{"patternBase":"Bali Hai Multi Blues","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_7bc519e7-fe8b-4d53-ba17-46f2320a6753.png","hue":214,"color_bucket":"blue","familySkus":[]},"DWCW-706046":{"patternBase":"Bali Hai Purple","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_036075aa-e0a3-4dc1-8f43-b9569f9d5446.png","hue":300,"color_bucket":"magenta","familySkus":[]},"DWCW-706146":{"patternBase":"Bali Hai Reds","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_ae3368b2-46a6-4897-87c2-2d66a180f427.png","hue":359,"color_bucket":"red","familySkus":["DWCW-706246"]},"DWCW-706246":{"patternBase":"Bali Hai Reds","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_220b07d3-c17c-4eae-b209-ef43eed3156c.png","hue":357,"color_bucket":"red","familySkus":["DWCW-706146"]},"DWCW-706346":{"patternBase":"Bali Hai Salmon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_f7989c3e-e5b5-4e7e-a027-cf341739488a.png","hue":10,"color_bucket":"red","familySkus":[]},"DWCW-706446":{"patternBase":"Bali Hai Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/bali-hai-group_15fb2607-f017-434f-bddc-1bebe34cb3a5.png","hue":190,"color_bucket":"teal","familySkus":[]},"DWCW-706546":{"patternBase":"Bali Ii Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_1d381389-96c9-4fc4-9338-acf6753e7a12.jpg","hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-706646":{"patternBase":"Bali Ii French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_0eadac73-ffb4-4f3e-9e6b-8d9c3eebfdc1.jpg","hue":208,"color_bucket":"blue","familySkus":[]},"DWCW-706746":{"patternBase":"Bali Ii Lime Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_50552a7e-d953-44d9-84c4-a1bb61b6b208.jpg","hue":76,"color_bucket":"green","familySkus":[]},"DWCW-706846":{"patternBase":"Bali II New Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_f7cb5afa-4588-4f0a-91be-b2b798fb1292.jpg","hue":20,"color_bucket":"orange","familySkus":[]},"DWCW-706946":{"patternBase":"Bali Ii Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_fe100100-83a2-4906-b6cd-2d5b66dc30e4.jpg","hue":18,"color_bucket":"orange","familySkus":[]},"DWCW-707046":{"patternBase":"Bali Ii Red","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_900dab96-204b-4b69-b633-4ba1001d6756.jpg","hue":349,"color_bucket":"red","familySkus":[]},"DWCW-707146":{"patternBase":"Bali II Salmon II","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_63262f42-55ad-4fa6-bae3-dec794d4233f.jpg","hue":6,"color_bucket":"red","familySkus":[]},"DWCW-707246":{"patternBase":"Bali II Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-II-fabric-group_9c1a1858-a5e4-4ac0-961b-aeebcb5b3412.jpg","hue":167,"color_bucket":"green","familySkus":[]},"DWCW-707346":{"patternBase":"Bali Isle French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_0bc601de-0999-4610-a538-ecf0c614e058.jpg","hue":209,"color_bucket":"blue","familySkus":["DWCW-707446"]},"DWCW-707446":{"patternBase":"Bali Isle French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_4bde3466-dd06-4589-9a59-f7911d3e7ed6.jpg","hue":218,"color_bucket":"blue","familySkus":["DWCW-707346"]},"DWCW-707546":{"patternBase":"Bali Isle Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_afdc655d-32c6-4544-a559-7e8eb45212a4.jpg","hue":348,"color_bucket":"red","familySkus":[]},"DWCW-707646":{"patternBase":"Bali Isle New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_ba7fa5ba-1ff3-471f-a295-8c22611410f8.jpg","hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-707746":{"patternBase":"Bali Isle Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_4d6af991-06d2-4d36-bd65-b2ed8a49f23f.jpg","hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-707846":{"patternBase":"Bali Isle Salmon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_f08102f1-d4d6-4696-8e72-4637d6ef5f9e.jpg","hue":8,"color_bucket":"red","familySkus":[]},"DWCW-707946":{"patternBase":"Bali Isle Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Bali-Isle-fabric-group_41085ff5-b898-4817-a456-f1096f97d1a7.jpg","hue":169,"color_bucket":"green","familySkus":[]},"DWCW-708046":{"patternBase":"Balinese Batik Magenta Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Balinese-Batik-fabric-group_6b00daf4-a49e-4fa6-b73c-ca73eec0ed11.jpg","hue":354,"color_bucket":"red","familySkus":[]},"DWCW-708146":{"patternBase":"Balinese Batik Navy Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Balinese-Batik-fabric-group_6c805de4-750f-42bf-a027-b1a74bfb50e0.jpg","hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-708246":{"patternBase":"Balinese Batik Shrimp Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Balinese-Batik-fabric-group_fb5e9c72-0734-4ca4-9e28-06a48b376f1c.jpg","hue":6,"color_bucket":"red","familySkus":[]},"DWCW-708346":{"patternBase":"Ballon de Gonesse Fuschia Citron","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ballon-de-Gonesse-Fuschia-Citron-2232-207.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-708446":{"patternBase":"Barbados Batik Orange Burnt Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Barbados-Batik-Group_e29bc704-275d-4364-bc98-3e40255a3342.jpg","hue":10,"color_bucket":"red","familySkus":[]},"DWCW-708546":{"patternBase":"Barbados Batik Purple Medium Purple","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Barbados-Batik-Group_0176fd2e-38da-4b34-94f2-35e97b06fe71.jpg","hue":273,"color_bucket":"purple","familySkus":[]},"DWCW-708646":{"patternBase":"Beau Rivage French Blue","room":null,"hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-708746":{"patternBase":"Beau Rivage Magenta","room":null,"hue":346,"color_bucket":"red","familySkus":[]},"DWCW-708846":{"patternBase":"Beau Rivage Navy","room":null,"hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-708946":{"patternBase":"Beau Rivage Orange","room":null,"hue":14,"color_bucket":"red","familySkus":[]},"DWCW-709046":{"patternBase":"Beau Rivage Turquoise","room":null,"hue":168,"color_bucket":"green","familySkus":[]},"DWCW-709146":{"patternBase":"Beau Rivage Yellow","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-709246":{"patternBase":"Bijou Stripe Jungle Green New Shrimp Brown","room":null,"hue":22,"color_bucket":"orange","familySkus":[]},"DWCW-709346":{"patternBase":"Birds Ii New Blue","room":null,"hue":182,"color_bucket":"teal","familySkus":[]},"DWCW-709446":{"patternBase":"Birds Ii Pink","room":null,"hue":338,"color_bucket":"red","familySkus":[]},"DWCW-709546":{"patternBase":"Birds Lilac Lilac","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Birds-Lilac-on-White-5050-04WP.jpg","hue":338,"color_bucket":"red","familySkus":[]},"DWCW-709646":{"patternBase":"Bonaparte Aqua Dark Aqua Almost White","room":null,"hue":163,"color_bucket":"green","familySkus":[]},"DWCW-709746":{"patternBase":"Bonaparte French Blue Navy Almost White","room":null,"hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-709846":{"patternBase":"Bonaparte Gold Orange Almost White","room":null,"hue":24,"color_bucket":"orange","familySkus":[]},"DWCW-709946":{"patternBase":"Bonaparte Lilac Purple Almost White","room":null,"hue":305,"color_bucket":"magenta","familySkus":[]},"DWCW-710046":{"patternBase":"Bonaparte Lime Forest Green Almost White","room":null,"hue":81,"color_bucket":"green","familySkus":[]},"DWCW-710146":{"patternBase":"Bonaparte Pink Dark Pink Almost White","room":null,"hue":349,"color_bucket":"red","familySkus":[]},"DWCW-710446":{"patternBase":"Brighton New Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-710546":{"patternBase":"Brighton Orange","room":null,"hue":4,"color_bucket":"red","familySkus":[]},"DWCW-710646":{"patternBase":"Brighton Pistachio","room":null,"hue":58,"color_bucket":"yellow","familySkus":[]},"DWCW-710746":{"patternBase":"Brighton Purple","room":null,"hue":294,"color_bucket":"magenta","familySkus":[]},"DWCW-710846":{"patternBase":"Brighton Red","room":null,"hue":359,"color_bucket":"red","familySkus":[]},"DWCW-710346":{"patternBase":"Brighton Reverse Turquoise","room":null,"hue":187,"color_bucket":"teal","familySkus":[]},"DWCW-710946":{"patternBase":"Brighton Turquoise","room":null,"hue":184,"color_bucket":"teal","familySkus":[]},"DWCW-711046":{"patternBase":"Brighton Vapor","room":null,"hue":90,"color_bucket":"green","familySkus":[]},"DWCW-711146":{"patternBase":"Camelot Black_on_white","room":null,"hue":128,"color_bucket":"green","familySkus":[]},"DWCW-711246":{"patternBase":"Camelot Cognac_on_white","room":null,"hue":27,"color_bucket":"orange","familySkus":[]},"DWCW-711346":{"patternBase":"Camelot Gray_on_white","room":null,"hue":63,"color_bucket":"yellow","familySkus":[]},"DWCW-711446":{"patternBase":"Camelot Light_blue_on_white","room":null,"hue":203,"color_bucket":"blue","familySkus":[]},"DWCW-711546":{"patternBase":"Camelot Pale_green_on_white","room":null,"hue":119,"color_bucket":"green","familySkus":[]},"DWCW-711646":{"patternBase":"Camelot Pink_on_white","room":null,"hue":6,"color_bucket":"red","familySkus":[]},"DWCW-711746":{"patternBase":"Camelot Purple_on_white","room":null,"hue":294,"color_bucket":"magenta","familySkus":[]},"DWCW-711846":{"patternBase":"Camelot Turquoise_on_white","room":null,"hue":194,"color_bucket":"teal","familySkus":[]},"DWCW-711946":{"patternBase":"Cap Ferrat Jungle Green Taupe Black","room":null,"hue":71,"color_bucket":"green","familySkus":[]},"DWCW-712046":{"patternBase":"Cap Ferrat Navy Blue Red","room":null,"hue":258,"color_bucket":"purple","familySkus":[]},"DWCW-712146":{"patternBase":"Capri Black_on_off_white","room":null,"hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-712246":{"patternBase":"Capri Coral_on_off_white","room":null,"hue":11,"color_bucket":"red","familySkus":[]},"DWCW-712346":{"patternBase":"Capri Gold_Metallic_on_Off_White","room":null,"hue":47,"color_bucket":"yellow","familySkus":[]},"DWCW-712446":{"patternBase":"Capri Soft_pink_on_off_white","room":null,"hue":13,"color_bucket":"red","familySkus":[]},"DWCW-712546":{"patternBase":"Capri Turquoise_on_off_white","room":null,"hue":63,"color_bucket":"yellow","familySkus":[]},"DWCW-712646":{"patternBase":"Carlo II Denim Blue","room":null,"hue":198,"color_bucket":"teal","familySkus":[]},"DWCW-712746":{"patternBase":"Carlo Ii Gray","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-712846":{"patternBase":"Carlo II New Apple","room":null,"hue":62,"color_bucket":"yellow","familySkus":[]},"DWCW-712946":{"patternBase":"Carlo Ii Pumice","room":null,"hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-713046":{"patternBase":"Carlo II Soft French Green","room":null,"hue":77,"color_bucket":"green","familySkus":[]},"DWCW-713146":{"patternBase":"Carlo II Soft Lavender","room":null,"hue":340,"color_bucket":"red","familySkus":[]},"DWCW-713246":{"patternBase":"Carlo II Soft Windsor Blue","room":null,"hue":157,"color_bucket":"green","familySkus":[]},"DWCW-713346":{"patternBase":"Carlo Ii Taupe","room":null,"hue":32,"color_bucket":"orange","familySkus":[]},"DWCW-713446":{"patternBase":"Carlo Ii Teal","room":null,"hue":131,"color_bucket":"green","familySkus":[]},"DWCW-713546":{"patternBase":"Carlo II Venice Blue","room":null,"hue":173,"color_bucket":"teal","familySkus":[]},"DWCW-714546":{"patternBase":"Ceylon Batik Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_38811dea-cb38-415c-a7bb-6ef31e068a3b.jpg","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-714646":{"patternBase":"Ceylon Batik Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_dd49b523-3fc9-44c7-9bad-83225404e69f.jpg","hue":75,"color_bucket":"green","familySkus":[]},"DWCW-714746":{"patternBase":"Ceylon Batik Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_6ffb4aca-de58-43bf-b53a-8756749204f9.jpg","hue":351,"color_bucket":"red","familySkus":[]},"DWCW-714846":{"patternBase":"Ceylon Batik Medium Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_0bef74fe-8c99-4dc6-9bdb-7eabf170ca51.jpg","hue":205,"color_bucket":"blue","familySkus":[]},"DWCW-714946":{"patternBase":"Ceylon Batik Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_756bc8dd-edc2-45d6-a8c7-0818b91dfd29.jpg","hue":202,"color_bucket":"blue","familySkus":[]},"DWCW-715046":{"patternBase":"Ceylon Batik Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_e0d5bf0d-6694-4b2f-af24-419ee8c4dc84.jpg","hue":13,"color_bucket":"red","familySkus":[]},"DWCW-715146":{"patternBase":"Ceylon Batik Purple","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_64bbca5b-f3af-4ce2-b435-4169cc396c33.jpg","hue":328,"color_bucket":"magenta","familySkus":[]},"DWCW-715246":{"patternBase":"Ceylon Batik Red","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_f200cce5-7ff8-4cbf-8c7b-eb675799f93e.jpg","hue":7,"color_bucket":"red","familySkus":[]},"DWCW-715346":{"patternBase":"Ceylon Batik Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ceylon-Batik-Group_96aba18c-d30c-4bdf-a979-cf4252dff4e3.jpg","hue":167,"color_bucket":"green","familySkus":[]},"DWCW-715446":{"patternBase":"Chantilly Stripe Beige","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-715546":{"patternBase":"Chantilly Stripe Black","room":null,"hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-715646":{"patternBase":"Chantilly Stripe Metallic Gold","room":null,"hue":36,"color_bucket":"orange","familySkus":[]},"DWCW-715746":{"patternBase":"Chantilly Stripe Slate Blue","room":null,"hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-715846":{"patternBase":"Chantilly Stripe Soft Teal","room":null,"hue":161,"color_bucket":"green","familySkus":[]},"DWCW-715946":{"patternBase":"Chantilly Stripe Soft Windsor","room":null,"hue":167,"color_bucket":"green","familySkus":[]},"DWCW-716046":{"patternBase":"Charleston_ii Black_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Black_on_White_300869WPV.jpg","hue":59,"color_bucket":"yellow","familySkus":[]},"DWCW-716146":{"patternBase":"Charleston_II Gold_Metallic_on_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Gold_Metallic_on_White_300863WPV.jpg","hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-716246":{"patternBase":"Charleston_II Navy_on_Off_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Navy_on_Off_White_300868WPV.jpg","hue":223,"color_bucket":"blue","familySkus":[]},"DWCW-716346":{"patternBase":"Charleston_II New_Blue_on_Off_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_New_Blue_on_Off_White_300864W.jpg","hue":196,"color_bucket":"teal","familySkus":[]},"DWCW-716446":{"patternBase":"Charleston_II New_Brown_on_Off_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_New_Brown_on_Off_White_300867WPV.jpg","hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-716546":{"patternBase":"Charleston_II Orange_on_Off_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Orange_on_Off_White_300866W.jpg","hue":14,"color_bucket":"red","familySkus":[]},"DWCW-716646":{"patternBase":"Charleston_II Purple_on_Off_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Purple_on_Off_White_300865W.jpg","hue":314,"color_bucket":"magenta","familySkus":[]},"DWCW-716746":{"patternBase":"Charleston_II Silver_Metallic_on_White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Silver_Metallic_on_White_300862WPV.jpg","hue":190,"color_bucket":"teal","familySkus":[]},"DWCW-716846":{"patternBase":"Charleston_ii White_on_white","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Charleston_II_Orange_on_Off_White_300866W_e7b9772a-c602-46e5-9331-0d79f31c776e.jpg","hue":203,"color_bucket":"blue","familySkus":[]},"DWCW-716946":{"patternBase":"Cherry Branch","room":null,"hue":6,"color_bucket":"red","familySkus":["DWCW-717046","DWCW-717146"]},"DWCW-717046":{"patternBase":"Cherry Branch","room":null,"hue":11,"color_bucket":"red","familySkus":["DWCW-716946","DWCW-717146"]},"DWCW-717146":{"patternBase":"Cherry Branch","room":null,"hue":5,"color_bucket":"red","familySkus":["DWCW-716946","DWCW-717046"]},"DWCW-717246":{"patternBase":"Cirebon Flores Blue","room":null,"hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-717346":{"patternBase":"Cirebon II French Blue","room":null,"hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-717446":{"patternBase":"Cirebon Reverse Old Pink","room":null,"hue":3,"color_bucket":"red","familySkus":[]},"DWCW-717546":{"patternBase":"Clementine All Over Camel Beige Brown","room":null,"hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-717646":{"patternBase":"Clementine All Over Charcoal Gray Blue","room":null,"hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-717746":{"patternBase":"Clementine All Over Green Brown","room":null,"hue":103,"color_bucket":"green","familySkus":[]},"DWCW-717846":{"patternBase":"Clementine All Over Lilac Purple Brown","room":null,"hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-717946":{"patternBase":"Clementine All Over Peach Pink Brown","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-718046":{"patternBase":"Clementine All Over Windsor Royal Navy","room":null,"hue":218,"color_bucket":"blue","familySkus":[]},"DWCW-718146":{"patternBase":"Club Cane Cream Forest","room":null,"hue":61,"color_bucket":"yellow","familySkus":[]},"DWCW-718346":{"patternBase":"Club Cane Cream Taupe Brown","room":null,"hue":27,"color_bucket":"orange","familySkus":[]},"DWCW-718446":{"patternBase":"Club Cane Cream Taupe Eggplant","room":null,"hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-718546":{"patternBase":"Club Cane Cream Taupe Orange","room":null,"hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-718646":{"patternBase":"Club Cane Cream Taupe Peach","room":null,"hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-718746":{"patternBase":"Coliseum Creams","room":null,"hue":26,"color_bucket":"orange","familySkus":[]},"DWCW-718846":{"patternBase":"Coliseum Grays","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-718946":{"patternBase":"Crawford Multi Blues","room":null,"hue":188,"color_bucket":"teal","familySkus":[]},"DWCW-719046":{"patternBase":"Crawford Multi Greens","room":null,"hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-719146":{"patternBase":"Crawford Multi Purple","room":null,"hue":9,"color_bucket":"red","familySkus":[]},"DWCW-719346":{"patternBase":"Criss Cross Black","room":null,"hue":269,"color_bucket":"purple","familySkus":[]},"DWCW-719446":{"patternBase":"Criss Cross Brown","room":null,"hue":38,"color_bucket":"orange","familySkus":["DWCW-719546"]},"DWCW-719546":{"patternBase":"Criss Cross Brown","room":null,"hue":13,"color_bucket":"red","familySkus":["DWCW-719446"]},"DWCW-719646":{"patternBase":"Criss Cross Camel II","room":null,"hue":22,"color_bucket":"orange","familySkus":[]},"DWCW-719746":{"patternBase":"Criss Cross Green","room":null,"hue":85,"color_bucket":"green","familySkus":[]},"DWCW-719846":{"patternBase":"Criss Cross Inca Gold","room":null,"hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-719946":{"patternBase":"Criss Cross Navy","room":null,"hue":212,"color_bucket":"blue","familySkus":["DWCW-720046","DWCW-720146"]},"DWCW-720046":{"patternBase":"Criss Cross Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-719946","DWCW-720146"]},"DWCW-720146":{"patternBase":"Criss Cross Navy","room":null,"hue":207,"color_bucket":"blue","familySkus":["DWCW-719946","DWCW-720046"]},"DWCW-720246":{"patternBase":"Criss Cross New Shrimp","room":null,"hue":8,"color_bucket":"red","familySkus":[]},"DWCW-720346":{"patternBase":"Criss Cross Slate Blue","room":null,"hue":214,"color_bucket":"blue","familySkus":["DWCW-720446"]},"DWCW-720446":{"patternBase":"Criss Cross Slate Blue","room":null,"hue":212,"color_bucket":"blue","familySkus":["DWCW-720346"]},"DWCW-720546":{"patternBase":"Criss Cross Swiss Blue","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-720646":{"patternBase":"Criss Cross Taupe","room":null,"hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-720746":{"patternBase":"Criss Cross Turquoise","room":null,"hue":185,"color_bucket":"teal","familySkus":[]},"DWCW-720846":{"patternBase":"Criss Cross Yellow","room":null,"hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-721246":{"patternBase":"Cumberland on","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_eb64ed01-b283-40b3-8d4a-cd6ee386bdef.jpg","hue":60,"color_bucket":"yellow","familySkus":["DWCW-721346","DWCW-721446","DWCW-721546"]},"DWCW-721346":{"patternBase":"Cumberland on","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_47aaecb6-d1f4-4ea6-83a4-2dfe0a441adc.jpg","hue":51,"color_bucket":"yellow","familySkus":["DWCW-721246","DWCW-721446","DWCW-721546"]},"DWCW-721446":{"patternBase":"Cumberland on","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_0db54161-f509-443e-9559-7452fa50e2c5.jpg","hue":53,"color_bucket":"yellow","familySkus":["DWCW-721246","DWCW-721346","DWCW-721546"]},"DWCW-721546":{"patternBase":"Cumberland on","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_b889c833-0fea-4052-81ce-f74af19c5871.jpg","hue":141,"color_bucket":"green","familySkus":["DWCW-721246","DWCW-721346","DWCW-721446"]},"DWCW-720946":{"patternBase":"Cumberland One","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_efc0a994-ccbb-410e-84f9-ad345b2f74c2.jpg","hue":62,"color_bucket":"yellow","familySkus":["DWCW-721046","DWCW-721146"]},"DWCW-721046":{"patternBase":"Cumberland One","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_fa238df1-5d65-46a5-b3b6-f343b632ffd8.jpg","hue":52,"color_bucket":"yellow","familySkus":["DWCW-720946","DWCW-721146"]},"DWCW-721146":{"patternBase":"Cumberland One","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Cumberland-fabric-group_5b450daa-829f-46b8-a509-49f12bd1c03c.jpg","hue":53,"color_bucket":"yellow","familySkus":["DWCW-720946","DWCW-721046"]},"DWCW-721646":{"patternBase":"Deauville Marine Blue","room":null,"hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-721746":{"patternBase":"Deauville Navy","room":null,"hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-721846":{"patternBase":"Des Gardes Black","room":null,"hue":75,"color_bucket":"green","familySkus":[]},"DWCW-721946":{"patternBase":"Des Gardes Burgundy","room":null,"hue":354,"color_bucket":"red","familySkus":[]},"DWCW-722046":{"patternBase":"Des Gardes Gold Metallic","room":null,"hue":36,"color_bucket":"orange","familySkus":[]},"DWCW-722146":{"patternBase":"Des Gardes Gray","room":null,"hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-722246":{"patternBase":"Des Gardes New Navy","room":null,"hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-722346":{"patternBase":"Des Gardes Pumice","room":null,"hue":42,"color_bucket":"orange","familySkus":[]},"DWCW-722446":{"patternBase":"Des Gardes Reverse Black Off White","room":null,"hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-722546":{"patternBase":"Des Gardes Reverse Burgundy Off White","room":null,"hue":354,"color_bucket":"red","familySkus":[]},"DWCW-722646":{"patternBase":"Des Gardes Reverse Gold Metallic Off White","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-722746":{"patternBase":"Des Gardes Reverse Gray","room":null,"hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-722846":{"patternBase":"Des Gardes Reverse New Navy Off White","room":null,"hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-722946":{"patternBase":"Des Gardes Reverse Pumice","room":null,"hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-723046":{"patternBase":"Des Gardes Reverse Silver Metallic Off White","room":null,"hue":202,"color_bucket":"blue","familySkus":[]},"DWCW-723146":{"patternBase":"Des Gardes Reverse Soft French Green","room":null,"hue":63,"color_bucket":"yellow","familySkus":[]},"DWCW-723246":{"patternBase":"Des Gardes Reverse Soft Lavender","room":null,"hue":13,"color_bucket":"red","familySkus":[]},"DWCW-723346":{"patternBase":"Des Gardes Reverse Soft Pink","room":null,"hue":12,"color_bucket":"red","familySkus":[]},"DWCW-723446":{"patternBase":"Des Gardes Reverse Soft Windsor Blue","room":null,"hue":85,"color_bucket":"green","familySkus":[]},"DWCW-723546":{"patternBase":"Des Gardes Reverse Terracotta","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-723646":{"patternBase":"Des Gardes Reverse Turquoise","room":null,"hue":170,"color_bucket":"green","familySkus":[]},"DWCW-723746":{"patternBase":"Des Gardes Silver Metallic","room":null,"hue":269,"color_bucket":"purple","familySkus":[]},"DWCW-723846":{"patternBase":"Des Gardes Soft French Green","room":null,"hue":69,"color_bucket":"yellow","familySkus":[]},"DWCW-723946":{"patternBase":"Des Gardes Soft Lavender","room":null,"hue":350,"color_bucket":"red","familySkus":[]},"DWCW-724046":{"patternBase":"Des Gardes Soft Pink","room":null,"hue":4,"color_bucket":"red","familySkus":[]},"DWCW-724146":{"patternBase":"Des Gardes Soft Windsor Blue","room":null,"hue":170,"color_bucket":"green","familySkus":[]},"DWCW-724246":{"patternBase":"Des Gardes Terracotta","room":null,"hue":22,"color_bucket":"orange","familySkus":[]},"DWCW-724346":{"patternBase":"Des Gardes Turquoise","room":null,"hue":169,"color_bucket":"green","familySkus":[]},"DWCW-724446":{"patternBase":"Edo Aqua","room":null,"hue":180,"color_bucket":"teal","familySkus":["DWCW-724546"]},"DWCW-724546":{"patternBase":"Edo Aqua","room":null,"hue":181,"color_bucket":"teal","familySkus":["DWCW-724446"]},"DWCW-724646":{"patternBase":"Edo Beige","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-724746":{"patternBase":"Edo Brown","room":null,"hue":30,"color_bucket":"orange","familySkus":[]},"DWCW-724846":{"patternBase":"Edo Camel Ii","room":null,"hue":27,"color_bucket":"orange","familySkus":[]},"DWCW-724946":{"patternBase":"Edo Celadon","room":null,"hue":135,"color_bucket":"green","familySkus":[]},"DWCW-725046":{"patternBase":"Edo French Blue","room":null,"hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-725146":{"patternBase":"Edo Gray","room":null,"hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-725246":{"patternBase":"Edo II French Blue","room":null,"hue":214,"color_bucket":"blue","familySkus":[]},"DWCW-725346":{"patternBase":"Edo II New Shrimp","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-725446":{"patternBase":"Edo II New Yellow","room":null,"hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-725546":{"patternBase":"Edo Ii Salmon","room":null,"hue":14,"color_bucket":"red","familySkus":[]},"DWCW-725646":{"patternBase":"Edo Inca Gold","room":null,"hue":32,"color_bucket":"orange","familySkus":[]},"DWCW-725746":{"patternBase":"Edo Navy","room":null,"hue":213,"color_bucket":"blue","familySkus":["DWCW-725846"]},"DWCW-725846":{"patternBase":"Edo Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-725746"]},"DWCW-725946":{"patternBase":"Edo New Shrimp","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-726046":{"patternBase":"Edo Turquoise","room":null,"hue":146,"color_bucket":"green","familySkus":[]},"DWCW-726146":{"patternBase":"Edo Watermelon","room":null,"hue":348,"color_bucket":"red","familySkus":[]},"DWCW-726246":{"patternBase":"Edo White","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-726346":{"patternBase":"Edo Windsor Blue","room":null,"hue":162,"color_bucket":"green","familySkus":[]},"DWCW-726446":{"patternBase":"El Cid Black","room":null,"hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-726546":{"patternBase":"El Cid French Blue","room":null,"hue":203,"color_bucket":"blue","familySkus":[]},"DWCW-726646":{"patternBase":"El Cid Kelly Green","room":null,"hue":104,"color_bucket":"green","familySkus":[]},"DWCW-726746":{"patternBase":"El Cid New Melon","room":null,"hue":3,"color_bucket":"red","familySkus":[]},"DWCW-726846":{"patternBase":"El Cid New Navy","room":null,"hue":220,"color_bucket":"blue","familySkus":[]},"DWCW-726946":{"patternBase":"El Cid New Yellow","room":null,"hue":34,"color_bucket":"orange","familySkus":[]},"DWCW-727046":{"patternBase":"El Cid Turquoise","room":null,"hue":186,"color_bucket":"teal","familySkus":[]},"DWCW-727146":{"patternBase":"Fez Background Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-Background-fabric-group_204b6a80-d54c-4738-ab4b-29b2f9224d66.jpg","hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-727246":{"patternBase":"Fez Background Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-Background-fabric-group_a575524d-a47e-441f-8c4b-c5401b03a3bf.jpg","hue":39,"color_bucket":"orange","familySkus":[]},"DWCW-727346":{"patternBase":"Fez Background Camel","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-Background-fabric-group_fa073f98-352e-4c2d-a01c-973363a98a0b.jpg","hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-727446":{"patternBase":"Fez Background Gold Metallic Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-Background-fabric-group_a60e1ff2-5878-4bfa-8b77-44baddb755d1.jpg","hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-727546":{"patternBase":"Fez Ii Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-II-fabric-group_7a3a340a-bf4f-4b0c-8a34-7993d9108fda.jpg","hue":42,"color_bucket":"orange","familySkus":[]},"DWCW-727646":{"patternBase":"Fez II Silver Metallic Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fez-II-fabric-group_d91ee337-d1ff-4cb5-8bef-630867e28856.jpg","hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-727746":{"patternBase":"Fiorentina Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_619c88ac-3278-4054-95a3-e2204b5e9993.jpg","hue":160,"color_bucket":"green","familySkus":[]},"DWCS-915246":{"patternBase":"Fiorentina Dark Yellow","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_0b7bd0b5-4869-4fd9-b853-85932d34e0a4.jpg","hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-727846":{"patternBase":"Fiorentina Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_938c9140-d906-4f8c-8b31-060cc88e67a7.jpg","hue":71,"color_bucket":"green","familySkus":[]},"DWCW-727946":{"patternBase":"Fiorentina Greige Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_26d51368-fb8a-4ea6-b2ab-1b3d12db91ba.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-728046":{"patternBase":"Fiorentina New Apple","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_16cf27de-1916-4285-8d20-8c05e4ee6930.jpg","hue":68,"color_bucket":"yellow","familySkus":[]},"DWCS-916046":{"patternBase":"Fiorentina Terracotta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_1d34ddd1-342a-4792-b0be-736b49ac7b71.jpg","hue":20,"color_bucket":"orange","familySkus":[]},"DWCW-728146":{"patternBase":"Fiorentina Two Color Lavender Purple Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-Two-Color-fabric-group_d5cea41f-229f-44c4-b7ea-6b8892686223.jpg","hue":309,"color_bucket":"magenta","familySkus":[]},"DWCW-728246":{"patternBase":"Fiorentina White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_e05f4208-1613-4bfd-8e2e-e28c462edbd7.jpg","hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-728346":{"patternBase":"Fiorentina Windsor Blue Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_9d5dd61c-7ebb-4acf-a284-d26b9391a024.jpg","hue":81,"color_bucket":"green","familySkus":[]},"DWCW-728446":{"patternBase":"Fiorentina Windsor Blue White Patent Vinyl","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Fiorentina-fabric-group_5220e29d-c857-4628-a150-59ad309c7609.jpg","hue":168,"color_bucket":"green","familySkus":[]},"DWCW-728546":{"patternBase":"Flores Multi Brown Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-09WP.jpg","hue":19,"color_bucket":"orange","familySkus":[]},"DWCW-728646":{"patternBase":"Flores Multi French Blue Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-02WP.jpg","hue":214,"color_bucket":"blue","familySkus":[]},"DWCW-728746":{"patternBase":"Flores Multi Gray Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-06WP.jpg","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-728846":{"patternBase":"Flores Multi Inca Gold Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-06WP_88986417-bf69-4ef3-ad4c-957dd032bdee.jpg","hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-728946":{"patternBase":"Flores Multi Navy Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-06WP_003f85db-c71e-4179-87d2-b8156264a4ab.jpg","hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-729046":{"patternBase":"Flores Multi New Blue Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Zig-Zag-New-Shrimp-on-Almost-White-AP302-06.jpg","hue":172,"color_bucket":"teal","familySkus":[]},"DWCW-729146":{"patternBase":"Flores Multi New Green Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-03WP.jpg","hue":64,"color_bucket":"yellow","familySkus":[]},"DWCW-729246":{"patternBase":"Flores Multi Orange Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-04WP.jpg","hue":14,"color_bucket":"red","familySkus":[]},"DWCW-729346":{"patternBase":"Flores Multi Shrimp Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/FLORES_20MULTI_204060M-07WP.jpg","hue":1,"color_bucket":"red","familySkus":[]},"DWCS-921946":{"patternBase":"Gate House Reverse One Color Beige","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-One-Color-Wallpaper-Forest-Clover-Green-on-White-6021W-20-sm-thumb_106e6f2e-85f2-4ad0-85bf-3f16862b5128.jpg","hue":35,"color_bucket":"orange","familySkus":["DWCS-922046"]},"DWCS-922046":{"patternBase":"Gate House Reverse One Color Beige","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-One-Color-Wallpaper-Forest-Clover-Green-on-White-6021W-20-sm-thumb_fdddb45b-1f1c-446e-becd-405b75871bfb.jpg","hue":35,"color_bucket":"orange","familySkus":["DWCS-921946"]},"DWCS-922146":{"patternBase":"Gate House Reverse One Color French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Royal-Blue-on-White-2485WP-13.jpg","hue":220,"color_bucket":"blue","familySkus":["DWCS-922246"]},"DWCS-922246":{"patternBase":"Gate House Reverse One Color French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Royal-Blue-on-White-2485WP-13_0300f9d2-5bed-4d28-8e12-45ec7679c975.jpg","hue":220,"color_bucket":"blue","familySkus":["DWCS-922146"]},"DWCS-922346":{"patternBase":"Gate House Reverse One Color Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Large-Scale-Gray-on-White-Paper-2480-13WP.jpg","hue":41,"color_bucket":"orange","familySkus":["DWCS-922446"]},"DWCS-922446":{"patternBase":"Gate House Reverse One Color Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Large-Scale-Gray-on-White-Paper-2480-13WP_949994de-e5c2-448c-a6a4-638e840707f3.jpg","hue":41,"color_bucket":"orange","familySkus":["DWCS-922346"]},"DWCS-922546":{"patternBase":"Gate House Reverse One Color Inca Gold","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Maze-Reverse-Two-Color-Light-Orange-New-Shrimp-2520-05OWP_9cc7bce5-eb43-4ac2-b49c-733d75512d79.jpg","hue":41,"color_bucket":"orange","familySkus":["DWCS-922646"]},"DWCS-922646":{"patternBase":"Gate House Reverse One Color Inca Gold","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Maze-Reverse-Two-Color-Light-Orange-New-Shrimp-2520-05OWP_5fdde781-ab03-4a4e-8da8-83553cfdfc7c.jpg","hue":41,"color_bucket":"orange","familySkus":["DWCS-922546"]},"DWCS-922746":{"patternBase":"Gate House Reverse One Color Lilac","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/MAZE_WALLPAPER_2510-0BWP_BEIGE_0da25784-b1c7-45c6-bc77-48dfd0888d84.jpg","hue":324,"color_bucket":"magenta","familySkus":["DWCS-922846"]},"DWCS-922846":{"patternBase":"Gate House Reverse One Color Lilac","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/MAZE_WALLPAPER_2510-0BWP_BEIGE_0735cc88-24bd-4365-8579-d312d61a4295.jpg","hue":324,"color_bucket":"magenta","familySkus":["DWCS-922746"]},"DWCS-922946":{"patternBase":"Gate House Reverse One Color New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Maze-Reverse-Two-Color-Light-Orange-New-Shrimp-2520-05OWP_9947e17c-4ec7-49d0-a1c0-a44862035d68.jpg","hue":224,"color_bucket":"blue","familySkus":["DWCS-923046"]},"DWCS-923046":{"patternBase":"Gate House Reverse One Color New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Maze-Reverse-Two-Color-Light-Orange-New-Shrimp-2520-05OWP_924e9245-fe8c-4ea3-bddb-ec735ba174a0.jpg","hue":224,"color_bucket":"blue","familySkus":["DWCS-922946"]},"DWCS-923146":{"patternBase":"Gate House Reverse One Color Sage Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-One-Color-Wallpaper-Forest-Clover-Green-on-White-6021W-20-sm-thumb_62c057c8-d641-4842-b93f-5607e6a6269d.jpg","hue":59,"color_bucket":"yellow","familySkus":["DWCS-923246"]},"DWCS-923246":{"patternBase":"Gate House Reverse One Color Sage Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-One-Color-Wallpaper-Forest-Clover-Green-on-White-6021W-20-sm-thumb_90493c9f-4ef0-4a0f-9d91-1a4aa1f4f1ee.jpg","hue":59,"color_bucket":"yellow","familySkus":["DWCS-923146"]},"DWCS-923346":{"patternBase":"Gate House Reverse One Color Windsor Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Des-Gardes-Reverse-Soft-Windsor-Blue-on-Off-White-306581W.jpg","hue":211,"color_bucket":"blue","familySkus":["DWCS-923446"]},"DWCS-923446":{"patternBase":"Gate House Reverse One Color Windsor Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Des-Gardes-Reverse-Soft-Windsor-Blue-on-Off-White-306581W_cde75e9c-4760-471c-918a-0931a55c0ae0.jpg","hue":211,"color_bucket":"blue","familySkus":["DWCS-923346"]},"DWCW-729446":{"patternBase":"Ginza Brown Camel Aqua","room":null,"hue":71,"color_bucket":"green","familySkus":[]},"DWCW-729546":{"patternBase":"Ginza Inca Aqua Jungle","room":null,"hue":77,"color_bucket":"green","familySkus":[]},"DWCW-729646":{"patternBase":"Ginza Magenta Plum Pink","room":null,"hue":356,"color_bucket":"red","familySkus":[]},"DWCW-729746":{"patternBase":"Gorrivan Fretwork Camel","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Gorrivan-Fretwork-Camel-on-Beige-Grasscloth-6300R-CAMEL_678b7641-adb1-4289-b6df-2c2556e0e0ac.jpg","hue":36,"color_bucket":"orange","familySkus":[]},"DWCW-729846":{"patternBase":"Happy Garden Background Black","room":null,"hue":182,"color_bucket":"teal","familySkus":[]},"DWCW-729946":{"patternBase":"Happy Garden Background Gray","room":null,"hue":59,"color_bucket":"yellow","familySkus":[]},"DWCW-730046":{"patternBase":"Happy Garden Background Grey","room":null,"hue":111,"color_bucket":"green","familySkus":[]},"DWCW-730146":{"patternBase":"Happy Garden Background Jungle Green","room":null,"hue":81,"color_bucket":"green","familySkus":[]},"DWCW-730246":{"patternBase":"Happy Garden Background Lavender","room":null,"hue":306,"color_bucket":"magenta","familySkus":[]},"DWCW-730346":{"patternBase":"Happy Garden Background Magenta","room":null,"hue":341,"color_bucket":"red","familySkus":[]},"DWCW-730446":{"patternBase":"Happy Garden Background Navy","room":null,"hue":225,"color_bucket":"blue","familySkus":[]},"DWCW-730546":{"patternBase":"Happy Garden Background Rust Orange","room":null,"hue":7,"color_bucket":"red","familySkus":[]},"DWCW-730646":{"patternBase":"Happy Garden Background Windsor Blue","room":null,"hue":198,"color_bucket":"teal","familySkus":[]},"DWCW-730746":{"patternBase":"Happy Garden Grey","room":null,"hue":203,"color_bucket":"blue","familySkus":[]},"DWCW-730846":{"patternBase":"Happy Garden Lavender","room":null,"hue":258,"color_bucket":"purple","familySkus":[]},"DWCW-730946":{"patternBase":"Happy Garden Navy","room":null,"hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-731046":{"patternBase":"Happy Garden Rust Orange","room":null,"hue":11,"color_bucket":"red","familySkus":[]},"DWCW-731146":{"patternBase":"Happy Garden Turquoise","room":null,"hue":188,"color_bucket":"teal","familySkus":[]},"DWCW-731246":{"patternBase":"Hawthorne French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Hawthorne-fabric-group.jpg","hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-731346":{"patternBase":"Hawthorne Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Hawthorne-fabric-group_0eff2bac-cdbb-47b4-b943-e70181c96480.jpg","hue":344,"color_bucket":"red","familySkus":[]},"DWCW-731446":{"patternBase":"Hawthorne Pale Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Hawthorne-fabric-group_711901fc-dd1f-4cee-ae54-65e7d5af0e17.jpg","hue":172,"color_bucket":"teal","familySkus":[]},"DWCW-731546":{"patternBase":"Henriot Floral Peach Yellows","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-731646":{"patternBase":"Henriot Floral Turquoise","room":null,"hue":188,"color_bucket":"teal","familySkus":[]},"DWCS-926446":{"patternBase":"Hulai Batik","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/hulai-batik-fabric-group-2024_221a3644-e7f5-43ef-b8b2-781de1b58810.png","hue":40,"color_bucket":"orange","familySkus":[]},"DWCS-927046":{"patternBase":"II Blue","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-731746":{"patternBase":"Indramayu Reverse Bali Blue","room":null,"hue":190,"color_bucket":"teal","familySkus":[]},"DWCW-731846":{"patternBase":"Indramayu Reverse French Blue","room":null,"hue":217,"color_bucket":"blue","familySkus":[]},"DWCW-731946":{"patternBase":"Indramayu Reverse Grassy Green White Matte","room":null,"hue":131,"color_bucket":"green","familySkus":[]},"DWCW-732046":{"patternBase":"Indramayu Reverse Royal Blue","room":null,"hue":224,"color_bucket":"blue","familySkus":[]},"DWCW-732146":{"patternBase":"Indramayu Reverse Tan","room":null,"hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-732246":{"patternBase":"Interweave Dark_grey","room":null,"hue":188,"color_bucket":"teal","familySkus":[]},"DWCW-732346":{"patternBase":"Interweave Dark_turquoise","room":null,"hue":196,"color_bucket":"teal","familySkus":[]},"DWCW-732446":{"patternBase":"Interweave Inca","room":null,"hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-732546":{"patternBase":"Interweave Jungle_green","room":null,"hue":80,"color_bucket":"green","familySkus":[]},"DWCW-732646":{"patternBase":"Interweave Light_blue","room":null,"hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-732746":{"patternBase":"Interweave Navy","room":null,"hue":225,"color_bucket":"blue","familySkus":[]},"DWCW-732846":{"patternBase":"Interweave Periwinkle","room":null,"hue":233,"color_bucket":"blue","familySkus":[]},"DWCW-732946":{"patternBase":"Interweave Purple","room":null,"hue":308,"color_bucket":"magenta","familySkus":[]},"DWCW-733046":{"patternBase":"Interweave Soft_pink","room":null,"hue":342,"color_bucket":"red","familySkus":[]},"DWCW-733146":{"patternBase":"Isfahan Melon Green Brown","room":null,"hue":25,"color_bucket":"orange","familySkus":[]},"DWCW-733246":{"patternBase":"Isfahan Multi Celeste Blue","room":null,"hue":208,"color_bucket":"blue","familySkus":["DWCW-733346"]},"DWCW-733346":{"patternBase":"Isfahan Multi Celeste Blue","room":null,"hue":203,"color_bucket":"blue","familySkus":["DWCW-733246"]},"DWCW-733446":{"patternBase":"Isfahan Multi Turquoise Celadon Teal","room":null,"hue":162,"color_bucket":"green","familySkus":[]},"DWCW-733546":{"patternBase":"Isfahan Purple Lilac Turquoise","room":null,"hue":19,"color_bucket":"orange","familySkus":[]},"DWCW-733646":{"patternBase":"Island Ikat","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Island-Ikat-fabric-group_30fee875-cfd3-4b9e-8a27-802304416a2b.jpg","hue":56,"color_bucket":"yellow","familySkus":["DWCW-733746","DWCW-733846","DWCW-733946","DWCW-734046"]},"DWCW-733746":{"patternBase":"Island Ikat","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Island-Ikat-fabric-group_56c08949-c2d0-4ba3-b1b1-fdba0b45b3f3.jpg","hue":158,"color_bucket":"green","familySkus":["DWCW-733646","DWCW-733846","DWCW-733946","DWCW-734046"]},"DWCW-733846":{"patternBase":"Island Ikat","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Island-Ikat-fabric-group_7be576b4-f539-4b9e-9672-92427690cd30.jpg","hue":62,"color_bucket":"yellow","familySkus":["DWCW-733646","DWCW-733746","DWCW-733946","DWCW-734046"]},"DWCW-733946":{"patternBase":"Island Ikat","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Island-Ikat-fabric-group_58a87fe5-8a7c-40cc-90f9-bf6a6a983003.jpg","hue":68,"color_bucket":"yellow","familySkus":["DWCW-733646","DWCW-733746","DWCW-733846","DWCW-734046"]},"DWCW-734046":{"patternBase":"Island Ikat","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Island-Ikat-fabric-group_128c17d8-9fc2-40a2-b780-02ca5c184566.jpg","hue":212,"color_bucket":"blue","familySkus":["DWCW-733646","DWCW-733746","DWCW-733846","DWCW-733946"]},"DWCW-735446":{"patternBase":"Java Brown","room":null,"hue":27,"color_bucket":"orange","familySkus":[]},"DWCW-735746":{"patternBase":"Java Camel II","room":null,"hue":24,"color_bucket":"orange","familySkus":[]},"DWCW-734146":{"patternBase":"Java Grande Camel","room":null,"hue":25,"color_bucket":"orange","familySkus":["DWCW-734246"]},"DWCW-734246":{"patternBase":"Java Grande Camel","room":null,"hue":22,"color_bucket":"orange","familySkus":["DWCW-734146"]},"DWCW-734346":{"patternBase":"Java Grande French Blue","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-734446":{"patternBase":"Java Grande Magenta","room":null,"hue":352,"color_bucket":"red","familySkus":[]},"DWCW-734546":{"patternBase":"Java Grande Navy","room":null,"hue":222,"color_bucket":"blue","familySkus":["DWCS-931946"]},"DWCS-931946":{"patternBase":"Java Grande Navy","room":null,"hue":222,"color_bucket":"blue","familySkus":["DWCW-734546"]},"DWCS-932046":{"patternBase":"Java Grande New Blue","room":null,"hue":195,"color_bucket":"teal","familySkus":[]},"DWCW-734646":{"patternBase":"Java Grande New Brown","room":null,"hue":27,"color_bucket":"orange","familySkus":[]},"DWCW-734746":{"patternBase":"Java Grande Tan","room":null,"hue":42,"color_bucket":"orange","familySkus":[]},"DWCW-734846":{"patternBase":"Java Grande Taupe","room":null,"hue":34,"color_bucket":"orange","familySkus":[]},"DWCW-734946":{"patternBase":"Java Grande Turquoise","room":null,"hue":189,"color_bucket":"teal","familySkus":[]},"DWCS-932646":{"patternBase":"Java Grande Turquoise_on White","room":null,"hue":189,"color_bucket":"teal","familySkus":[]},"DWCW-735046":{"patternBase":"Java Java Aqua","room":null,"hue":189,"color_bucket":"teal","familySkus":[]},"DWCW-735146":{"patternBase":"Java Java Bali Blue","room":null,"hue":189,"color_bucket":"teal","familySkus":[]},"DWCW-735246":{"patternBase":"Java Java Bali Green","room":null,"hue":71,"color_bucket":"green","familySkus":[]},"DWCW-735346":{"patternBase":"Java Java Beige","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-735546":{"patternBase":"Java Java Brown","room":null,"hue":28,"color_bucket":"orange","familySkus":["DWCW-735646"]},"DWCW-735646":{"patternBase":"Java Java Brown","room":null,"hue":16,"color_bucket":"orange","familySkus":["DWCW-735546"]},"DWCW-735846":{"patternBase":"Java Java Celadon","room":null,"hue":110,"color_bucket":"green","familySkus":[]},"DWCW-735946":{"patternBase":"Java Java French Blue","room":null,"hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-736046":{"patternBase":"Java Java Lilac","room":null,"hue":345,"color_bucket":"red","familySkus":[]},"DWCW-736246":{"patternBase":"Java Java Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-736446":{"patternBase":"Java Java New Yellow","room":null,"hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-736646":{"patternBase":"Java Java Pale Pink","room":null,"hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-736746":{"patternBase":"Java Java Pale Yellow","room":null,"hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-736846":{"patternBase":"Java Java Pearl","room":null,"hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-736946":{"patternBase":"Java Java Pink","room":null,"hue":354,"color_bucket":"red","familySkus":[]},"DWCW-737146":{"patternBase":"Java Java Taupe","room":null,"hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-737246":{"patternBase":"Java Java White","room":null,"hue":53,"color_bucket":"yellow","familySkus":[]},"DWCW-737346":{"patternBase":"Java Java Yellow","room":null,"hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-736546":{"patternBase":"Java Pacific Blue Almost White","room":null,"hue":207,"color_bucket":"blue","familySkus":[]},"DWCW-737446":{"patternBase":"Java Petite Almond","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_db71cf48-63c5-41b5-afbc-27e89960f25c.jpg","hue":42,"color_bucket":"orange","familySkus":[]},"DWCW-737546":{"patternBase":"Java Petite Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_4ef2efa8-6cff-4ebf-8e54-69f7776c207d.jpg","hue":185,"color_bucket":"teal","familySkus":[]},"DWCW-737646":{"patternBase":"Java Petite Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_67c44c7e-2442-4fbc-ab38-2b3e553e7738.jpg","hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-737746":{"patternBase":"Java Petite Camel Ii","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_48db5ad3-b6c8-4bb2-8c79-578d809d4014.jpg","hue":25,"color_bucket":"orange","familySkus":[]},"DWCW-737846":{"patternBase":"Java Petite Celadon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_dfa793cd-6186-49b7-a452-d680c6b09c08.jpg","hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-737946":{"patternBase":"Java Petite French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_be546c36-1479-46a2-bf38-de10adbd2f91.jpg","hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-738046":{"patternBase":"Java Petite Greige","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_3db40b1a-c4f4-435f-b8f8-54e6e3c9657a.jpg","hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-738146":{"patternBase":"Java Petite Taupe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Petite-fabric-group_eb577739-19f7-444e-bf02-4925bf46bbe4.jpg","hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-737046":{"patternBase":"Java Salmon Orange","room":null,"hue":15,"color_bucket":"red","familySkus":[]},"DWCW-738246":{"patternBase":"Jave Petite Cadet","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java-Grande-French-Blue-on-White-6620-20WWP.jpg","hue":190,"color_bucket":"teal","familySkus":[]},"DWCW-738346":{"patternBase":"Jave Petite Lime","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/JAVA_GRANDE_WALLPAPER_6620-06AWP_NEW_SHRIMP.jpg","hue":87,"color_bucket":"green","familySkus":[]},"DWCW-738446":{"patternBase":"Jave Petite Periwinkle","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/EDO_20II_206990WP-19PV.jpg","hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-738546":{"patternBase":"Jeanne Medallion Gold","room":null,"hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-738646":{"patternBase":"Jeanne Medallion Silver","room":null,"hue":57,"color_bucket":"yellow","familySkus":[]},"DWCW-738746":{"patternBase":"Juan Les Pins Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Juan-Les-Pins-Turquoise-on-White-Grasscloth-AP115GC-05.jpg","hue":171,"color_bucket":"teal","familySkus":[]},"DWCW-738846":{"patternBase":"Kalamkari All Over Celeste Gray Charcoal","room":null,"hue":202,"color_bucket":"blue","familySkus":[]},"DWCW-738946":{"patternBase":"Kalamkari All Over Lavender Green Navy","room":null,"hue":107,"color_bucket":"green","familySkus":[]},"DWCW-739046":{"patternBase":"Kalamkari All Over Red Burgundy Purple","room":null,"hue":343,"color_bucket":"red","familySkus":[]},"DWCW-739146":{"patternBase":"Kalamkari All Over Slate Royal Sky Denim","room":null,"hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-739346":{"patternBase":"Kalamkari Border Celeste Gray Charcoal","room":null,"hue":203,"color_bucket":"blue","familySkus":["DWCW-739246"]},"DWCW-739246":{"patternBase":"Kalamkari Border Celeste Gray Charcoal","room":null,"hue":202,"color_bucket":"blue","familySkus":["DWCW-739346"]},"DWCW-739546":{"patternBase":"Kalamkari Border Red Burgundy Purple","room":null,"hue":341,"color_bucket":"red","familySkus":["DWCW-739446"]},"DWCW-739446":{"patternBase":"Kalamkari Border Red Burgundy Purple","room":null,"hue":344,"color_bucket":"red","familySkus":["DWCW-739546"]},"DWCW-739646":{"patternBase":"Kalamkari Border Slate Royal Sky Denim","room":null,"hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-739746":{"patternBase":"Kalamkari Floral Blues","room":null,"hue":222,"color_bucket":"blue","familySkus":[]},"DWCW-740346":{"patternBase":"Kazak Black Metallic Silver","room":null,"hue":271,"color_bucket":"purple","familySkus":[]},"DWCW-740746":{"patternBase":"Kazak Blue Metallic Gold","room":null,"hue":201,"color_bucket":"blue","familySkus":[]},"DWCW-740446":{"patternBase":"Kazak Coral New Yellow","room":null,"hue":10,"color_bucket":"red","familySkus":[]},"DWCW-740546":{"patternBase":"Kazak Magenta Lime","room":null,"hue":9,"color_bucket":"red","familySkus":[]},"DWCW-740646":{"patternBase":"Kazak New Navy Denim","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-740246":{"patternBase":"Kazak_wallcovering Aqua_lilac","room":null,"hue":191,"color_bucket":"teal","familySkus":[]},"DWCW-739946":{"patternBase":"Kazak_Wallcovering Coral_New_Yellow","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-739846":{"patternBase":"Kazak_wallcovering Magenta_lime","room":null,"hue":55,"color_bucket":"yellow","familySkus":[]},"DWCW-740046":{"patternBase":"Kazak_Wallcovering New_Navy_Denim_Blue","room":null,"hue":230,"color_bucket":"blue","familySkus":[]},"DWCW-740146":{"patternBase":"Kazak_wallcovering Orange_pink","room":null,"hue":9,"color_bucket":"red","familySkus":[]},"DWCW-740846":{"patternBase":"Kediri Batik","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Kediri-Batik-fabric-group_15140074-e353-454f-9c5f-860174abccdd.jpg","hue":51,"color_bucket":"yellow","familySkus":["DWCS-936246"]},"DWCS-936246":{"patternBase":"Kediri Batik","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Kediri-Batik-fabric-group_cfabd99b-05b1-492c-ae40-88e45408340a.jpg","hue":56,"color_bucket":"yellow","familySkus":["DWCW-740846"]},"DWCS-937746":{"patternBase":"Kyoto Two","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Kyoto-Two-Colors-fabric-group_5ec0296d-23b7-4e36-80f8-fbe2de4b98e7.jpg","hue":187,"color_bucket":"teal","familySkus":[]},"DWCW-740946":{"patternBase":"Labyrinth Greige_on_almost_white_HC","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Labyrinth_Twilight_on_almost_white_HC1520WP-15.jpg","hue":45,"color_bucket":"orange","familySkus":[]},"DWCW-741046":{"patternBase":"Labyrinth Twilight_on_almost_white_HC","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Labyrinth_Twilight_on_almost_white_HC1520WP-15_80e8cc24-c4ac-42c4-9d4e-7b374f5f3438.jpg","hue":125,"color_bucket":"green","familySkus":[]},"DWCW-741146":{"patternBase":"Labyrinth Vapor","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Labyrinth_Twilight_on_almost_white_HC1520WP-15_c0611b2a-5074-47ab-9c87-482f78e37a9d.jpg","hue":177,"color_bucket":"teal","familySkus":[]},"DWCW-741246":{"patternBase":"Lascaux Black","room":null,"hue":74,"color_bucket":"green","familySkus":[]},"DWCW-741346":{"patternBase":"Lascaux White","room":null,"hue":39,"color_bucket":"orange","familySkus":[]},"DWCS-937846":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group.jpg","hue":201,"color_bucket":"blue","familySkus":["DWCS-937946","DWCS-938046","DWCS-938146","DWCS-938246","DWCS-938346"]},"DWCS-937946":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group_f16fb269-d201-414f-a632-579d10e35126.jpg","hue":217,"color_bucket":"blue","familySkus":["DWCS-937846","DWCS-938046","DWCS-938146","DWCS-938246","DWCS-938346"]},"DWCS-938046":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group_7628be82-b317-40c9-b45b-ecab3484916c.jpg","hue":60,"color_bucket":"yellow","familySkus":["DWCS-937846","DWCS-937946","DWCS-938146","DWCS-938246","DWCS-938346"]},"DWCS-938146":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group_34ddf92d-a78e-40a2-924a-91c829de1a5a.jpg","hue":48,"color_bucket":"yellow","familySkus":["DWCS-937846","DWCS-937946","DWCS-938046","DWCS-938246","DWCS-938346"]},"DWCS-938246":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group_d6c358d3-19a8-441c-9a38-53735898f95d.jpg","hue":284,"color_bucket":"purple","familySkus":["DWCS-937846","DWCS-937946","DWCS-938046","DWCS-938146","DWCS-938346"]},"DWCS-938346":{"patternBase":"Lila Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lila-Stripe-fabric-group_0c032f54-712b-472d-b11c-eeb5824513d6.jpg","hue":1,"color_bucket":"red","familySkus":["DWCS-937846","DWCS-937946","DWCS-938046","DWCS-938146","DWCS-938246"]},"DWCW-741446":{"patternBase":"Lim Diagonal Multi French Blue Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lim-Diagonal-group_ccee1e40-a446-4c1c-bcde-87df315389ed.jpg","hue":223,"color_bucket":"blue","familySkus":[]},"DWCW-741546":{"patternBase":"Links II Multi Pinks","room":null,"hue":5,"color_bucket":"red","familySkus":[]},"DWCW-741646":{"patternBase":"Links II Multi Purple","room":null,"hue":7,"color_bucket":"red","familySkus":[]},"DWCW-741746":{"patternBase":"Longfellow Black Grey","room":null,"hue":74,"color_bucket":"green","familySkus":[]},"DWCW-741846":{"patternBase":"Longfellow Moss Green Taupe","room":null,"hue":59,"color_bucket":"yellow","familySkus":["DWCW-741946"]},"DWCW-741946":{"patternBase":"Longfellow Moss Green Taupe","room":null,"hue":62,"color_bucket":"yellow","familySkus":["DWCW-741846"]},"DWCW-742046":{"patternBase":"Longfellow Navy French Blue","room":null,"hue":200,"color_bucket":"teal","familySkus":["DWCW-742146"]},"DWCW-742146":{"patternBase":"Longfellow Navy French Blue","room":null,"hue":208,"color_bucket":"blue","familySkus":["DWCW-742046"]},"DWCW-742246":{"patternBase":"Longfellow Orange Yellow","room":null,"hue":24,"color_bucket":"orange","familySkus":[]},"DWCW-742346":{"patternBase":"Longfellow Purple Lilac","room":null,"hue":291,"color_bucket":"magenta","familySkus":["DWCW-742446"]},"DWCW-742446":{"patternBase":"Longfellow Purple Lilac","room":null,"hue":293,"color_bucket":"magenta","familySkus":["DWCW-742346"]},"DWCW-742546":{"patternBase":"Longfellow Royal New Blue","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-742646":{"patternBase":"Longfellow Strawberry","room":null,"hue":355,"color_bucket":"red","familySkus":["DWCW-742746"]},"DWCW-742746":{"patternBase":"Longfellow Strawberry","room":null,"hue":349,"color_bucket":"red","familySkus":["DWCW-742646"]},"DWCW-742846":{"patternBase":"Longfellow Turquoise","room":null,"hue":192,"color_bucket":"teal","familySkus":["DWCW-742946"]},"DWCW-742946":{"patternBase":"Longfellow Turquoise","room":null,"hue":196,"color_bucket":"teal","familySkus":["DWCW-742846"]},"DWCS-940946":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group.jpg","hue":114,"color_bucket":"green","familySkus":["DWCS-941046","DWCS-941146","DWCS-941246","DWCS-941346","DWCS-941446","DWCS-941546"]},"DWCS-941046":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_83a82637-fba9-4537-8baa-141ca1429f00.jpg","hue":201,"color_bucket":"blue","familySkus":["DWCS-940946","DWCS-941146","DWCS-941246","DWCS-941346","DWCS-941446","DWCS-941546"]},"DWCS-941146":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_e62b9555-badf-4a7d-a9b0-a8e4d5643695.jpg","hue":217,"color_bucket":"blue","familySkus":["DWCS-940946","DWCS-941046","DWCS-941246","DWCS-941346","DWCS-941446","DWCS-941546"]},"DWCS-941246":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_deb533ca-9a38-4e4b-b20e-aba27ca52e5a.jpg","hue":61,"color_bucket":"yellow","familySkus":["DWCS-940946","DWCS-941046","DWCS-941146","DWCS-941346","DWCS-941446","DWCS-941546"]},"DWCS-941346":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_31b0023c-dcc6-4c1f-b7b3-53760d34c1a7.jpg","hue":58,"color_bucket":"yellow","familySkus":["DWCS-940946","DWCS-941046","DWCS-941146","DWCS-941246","DWCS-941446","DWCS-941546"]},"DWCS-941446":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_572a5f3f-9639-435d-8671-3829216d53f6.jpg","hue":286,"color_bucket":"purple","familySkus":["DWCS-940946","DWCS-941046","DWCS-941146","DWCS-941246","DWCS-941346","DWCS-941546"]},"DWCS-941546":{"patternBase":"Lulu Stripe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lulu-Stripe-fabric-group_f00bc833-4b4e-4113-b092-1dd1f64f4328.jpg","hue":358,"color_bucket":"red","familySkus":["DWCS-940946","DWCS-941046","DWCS-941146","DWCS-941246","DWCS-941346","DWCS-941446"]},"DWCW-743146":{"patternBase":"Lyford Background Light Turquoise Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Background-fabric-group_176cb220-1bc3-4137-81b3-1f948f8c932b.jpg","hue":172,"color_bucket":"teal","familySkus":[]},"DWCW-743246":{"patternBase":"Lyford Background Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Background-fabric-group_129559e9-9fdf-498e-859b-9bda2d43ae37.jpg","hue":338,"color_bucket":"red","familySkus":[]},"DWCW-743346":{"patternBase":"Lyford Background Navy Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Background-fabric-group_97688e5a-0733-4f0d-b600-aaf925590299.jpg","hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-743446":{"patternBase":"Lyford Background Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Background-fabric-group_65ebabad-8e96-457e-b66e-539ad938442b.jpg","hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-743546":{"patternBase":"Lyford Diamond Bamboo Navy","room":null,"hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-743646":{"patternBase":"Lyford Diamond Bamboo New Shrimp","room":null,"hue":359,"color_bucket":"red","familySkus":[]},"DWCW-743746":{"patternBase":"Lyford Pagoda Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Pagoda-fabric-group_dc774ba3-00d8-40e7-8070-fb6cb184d86f.jpg","hue":214,"color_bucket":"blue","familySkus":[]},"DWCW-743846":{"patternBase":"Lyford Pagoda Petite Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Pagoda-Petite-fabric-group_1e350052-1d34-4a91-9841-e8c6fa485bb9.jpg","hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-743946":{"patternBase":"Lyford Pagoda Pink","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Pagoda-fabric-group_36d0dbfb-ffd7-43ed-a030-7e50c413874a.jpg","hue":1,"color_bucket":"red","familySkus":[]},"DWCW-744046":{"patternBase":"Lyford Trellis Beige Salmon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_3ce1da5a-0e04-46e0-acba-47ccdbf4502c.png","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-744146":{"patternBase":"Lyford Trellis Beiges Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_8658e44e-020a-431d-8ca5-8d1b93faef2a.png","hue":76,"color_bucket":"green","familySkus":[]},"DWCW-744246":{"patternBase":"Lyford Trellis Brown Beige Taupe Pink","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_0893a1e9-ebae-41f6-a771-b6336b451987.png","hue":22,"color_bucket":"orange","familySkus":[]},"DWCW-744346":{"patternBase":"Lyford Trellis Light Blue French Blue Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_d89de6d4-b1ae-413e-819b-ec7f88bed4d4.png","hue":195,"color_bucket":"teal","familySkus":[]},"DWCW-744446":{"patternBase":"Lyford Trellis Navy New Blue Terracotta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_1d80c92c-68c8-4531-b6e4-001d8d735a77.png","hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-744546":{"patternBase":"Lyford Trellis Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_99566a35-156c-4239-ae69-cff6766498da.png","hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-744846":{"patternBase":"Lyford Trellis New Blue Navy Terracotta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_9ce52c1e-123a-485d-ab1d-c4b2869af245.png","hue":209,"color_bucket":"blue","familySkus":["DWCW-744646","DWCW-744746"]},"DWCW-744646":{"patternBase":"Lyford Trellis New Blue Navy Terracotta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_2d2bfc6a-bcf4-498f-a6ba-0051b6a6eb91.png","hue":209,"color_bucket":"blue","familySkus":["DWCW-744846","DWCW-744746"]},"DWCW-744746":{"patternBase":"Lyford Trellis New Blue Navy Terracotta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_b33ce292-6b04-4452-99ad-b5d6b880ef02.png","hue":209,"color_bucket":"blue","familySkus":["DWCW-744846","DWCW-744646"]},"DWCW-743046":{"patternBase":"Lyford Trellis","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_dbb70135-2eed-415c-acd4-9162a0e0683d.png","hue":144,"color_bucket":"green","familySkus":[]},"DWCW-744946":{"patternBase":"Lyford Trellis Slate Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Lyford-Trellis-fabric-group_df114e80-cb89-4366-9c5f-082440ee7b72.png","hue":205,"color_bucket":"blue","familySkus":[]},"DWCW-745046":{"patternBase":"Lysette Chartreuse","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/lysette-fabric-group-2024-edited.png","hue":62,"color_bucket":"yellow","familySkus":[]},"DWCW-745146":{"patternBase":"Lysette French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/lysette-fabric-group-2024-edited_6a1a2df4-5a70-42f8-a248-95400a8aa161.png","hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-745246":{"patternBase":"Lysette Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/lysette-fabric-group-2024-edited_026fcb51-db2d-4089-8a7d-e1ffd261f210.png","hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-745346":{"patternBase":"Lysette New Shrimp","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/lysette-fabric-group-2024-edited_0d055580-5256-4522-b89c-81881e682798.png","hue":9,"color_bucket":"red","familySkus":[]},"DWCW-745446":{"patternBase":"Lysette Windsor Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/lysette-fabric-group-2024-edited_886664d2-f19c-4a05-842e-6f6d9f076aca.png","hue":225,"color_bucket":"blue","familySkus":[]},"DWCW-745546":{"patternBase":"Macoco Ii","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Macoco-II-fabric-group_bae30319-6733-4cc1-8317-47872261e6ee.jpg","hue":169,"color_bucket":"green","familySkus":[]},"DWCW-745646":{"patternBase":"Macoco Reverse","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Macoco-Reverse-fabric-group_395f051b-9523-42a1-9530-96d6facc0d9b.jpg","hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-745746":{"patternBase":"Madagascar_backed Natural","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Madagascar_Backed_Natural_300345W.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-745846":{"patternBase":"Madame Butterfly Greens","room":null,"hue":126,"color_bucket":"green","familySkus":[]},"DWCW-745946":{"patternBase":"Madame Butterfly Pinks","room":null,"hue":351,"color_bucket":"red","familySkus":[]},"DWCW-746046":{"patternBase":"Magic Garden","room":null,"hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-746146":{"patternBase":"Malaya Black_on_almost_white","room":null,"hue":62,"color_bucket":"yellow","familySkus":[]},"DWCW-746246":{"patternBase":"Malaya Celadon_on_almost_white","room":null,"hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-746346":{"patternBase":"Malaya Gray_on_almost_white","room":null,"hue":55,"color_bucket":"yellow","familySkus":[]},"DWCW-746446":{"patternBase":"Malaya Jungle_Green_on_almost_white","room":null,"hue":69,"color_bucket":"yellow","familySkus":[]},"DWCW-746546":{"patternBase":"Malaya New_Blue_on_almost_white","room":null,"hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-746646":{"patternBase":"Malaya New_Brown_on_almost_white","room":null,"hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-746746":{"patternBase":"Malaya Red_on_almost_white","room":null,"hue":359,"color_bucket":"red","familySkus":[]},"DWCW-746846":{"patternBase":"Malaya Zibby_Blue_on_almost_white","room":null,"hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-746946":{"patternBase":"Maze Navy","room":null,"hue":215,"color_bucket":"blue","familySkus":[]},"DWCW-747046":{"patternBase":"Maze Reverse","room":null,"hue":16,"color_bucket":"orange","familySkus":["DWCW-747146"]},"DWCW-747146":{"patternBase":"Maze Reverse","room":null,"hue":299,"color_bucket":"magenta","familySkus":["DWCW-747046"]},"DWCW-747346":{"patternBase":"Maze Salmon","room":null,"hue":12,"color_bucket":"red","familySkus":[]},"DWCW-747446":{"patternBase":"Maze White","room":null,"hue":200,"color_bucket":"teal","familySkus":[]},"DWCW-747746":{"patternBase":"Medallion Brown Navy","room":null,"hue":34,"color_bucket":"orange","familySkus":[]},"DWCW-747546":{"patternBase":"Medallion Fig Cream","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-747646":{"patternBase":"Medallion Melon Camel","room":null,"hue":19,"color_bucket":"orange","familySkus":[]},"DWCW-747846":{"patternBase":"Melanie Ii Camel New Brown","room":null,"hue":38,"color_bucket":"orange","familySkus":[]},"DWCW-747946":{"patternBase":"Meloire Reverse White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Meloire-Reverse-White-on-Off-White-AP809-01WP.jpg","hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-748046":{"patternBase":"Melong Batik Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_3ed93cc0-a9fd-4db9-96ad-d6a23cdd5554.jpg","hue":51,"color_bucket":"yellow","familySkus":[]},"DWCW-748146":{"patternBase":"Melong Batik","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_bc6108e4-8304-4c63-8b0d-b8d258844cdf.jpg","hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-748246":{"patternBase":"Melong Batik Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_5c1b2254-e40a-46d2-ad2f-bf5b319b9b99.jpg","hue":13,"color_bucket":"red","familySkus":[]},"DWCW-748346":{"patternBase":"Melong Batik French Blue Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_40cc9be9-2283-4c49-8b67-6a38090eea80.jpg","hue":99,"color_bucket":"green","familySkus":[]},"DWCW-748446":{"patternBase":"Melong Batik French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_640f5511-b9b3-41cd-851e-c176d11cc563.jpg","hue":212,"color_bucket":"blue","familySkus":["DWCW-748546"]},"DWCW-748546":{"patternBase":"Melong Batik French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_8a655f32-fd5c-498b-835c-a7c5ad67ab47.jpg","hue":212,"color_bucket":"blue","familySkus":["DWCW-748446"]},"DWCW-748646":{"patternBase":"Melong Batik Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_82146e24-d6d4-4fa6-8e05-d06cd5f3f407.jpg","hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-748746":{"patternBase":"Melong Batik Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_41fff4ce-d93c-41a0-98d5-324ea240ef65.jpg","hue":79,"color_bucket":"green","familySkus":["DWCW-748846"]},"DWCW-748846":{"patternBase":"Melong Batik Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_5a9d3478-605f-46a0-bc50-e030a55c6523.jpg","hue":215,"color_bucket":"blue","familySkus":["DWCW-748746"]},"DWCW-748946":{"patternBase":"Melong Batik New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_6afabaf0-d5f4-4ea7-9125-c68c12420ec2.jpg","hue":56,"color_bucket":"yellow","familySkus":[]},"DWCW-749046":{"patternBase":"Melong Batik Reverse Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-Reverse-fabric-group_b405dad8-72bc-45df-ae7b-beee925eb614.jpg","hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-749146":{"patternBase":"Melong Batik Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Melong-Batik-fabric-group_90e5b1af-4c21-45c3-8e0f-44c8f5a314f1.jpg","hue":177,"color_bucket":"teal","familySkus":[]},"DWCW-749246":{"patternBase":"Mojave Pink","room":null,"hue":352,"color_bucket":"red","familySkus":[]},"DWCW-749346":{"patternBase":"Mojave White","room":null,"hue":53,"color_bucket":"yellow","familySkus":[]},"DWCW-749446":{"patternBase":"Montecito_Bamboo Cognac_on_Off_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Montecito_Bamboo_Cognac_on_Off_White_CP1060W-05.jpg","hue":27,"color_bucket":"orange","familySkus":[]},"null":{"patternBase":"Nitik II New Yellow Salmon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_249d74a0-4cee-4844-a074-4834c02b57aa.jpg","hue":43,"color_bucket":"orange","familySkus":["DWCW-754546"]},"DWCW-750546":{"patternBase":"Monty on","room":null,"hue":27,"color_bucket":"orange","familySkus":["null","null","null","null","null","DWCW-750646","DWCW-750746","DWCW-750846","DWCW-750946"]},"DWCW-750646":{"patternBase":"Monty on","room":null,"hue":183,"color_bucket":"teal","familySkus":["null","null","null","null","null","DWCW-750546","DWCW-750746","DWCW-750846","DWCW-750946"]},"DWCW-750746":{"patternBase":"Monty on","room":null,"hue":73,"color_bucket":"green","familySkus":["null","null","null","null","null","DWCW-750546","DWCW-750646","DWCW-750846","DWCW-750946"]},"DWCW-750846":{"patternBase":"Monty on","room":null,"hue":61,"color_bucket":"yellow","familySkus":["null","null","null","null","null","DWCW-750546","DWCW-750646","DWCW-750746","DWCW-750946"]},"DWCW-750946":{"patternBase":"Monty on","room":null,"hue":54,"color_bucket":"yellow","familySkus":["null","null","null","null","null","DWCW-750546","DWCW-750646","DWCW-750746","DWCW-750846"]},"DWCW-751046":{"patternBase":"Monty White","room":null,"hue":195,"color_bucket":"teal","familySkus":[]},"DWCW-751146":{"patternBase":"Nairobi Beige","room":null,"hue":42,"color_bucket":"orange","familySkus":[]},"DWCW-751246":{"patternBase":"Nairobi French","room":null,"hue":71,"color_bucket":"green","familySkus":[]},"DWCW-751346":{"patternBase":"Nairobi Pale","room":null,"hue":63,"color_bucket":"yellow","familySkus":["DWCW-751446"]},"DWCW-751446":{"patternBase":"Nairobi Pale","room":null,"hue":358,"color_bucket":"red","familySkus":["DWCW-751346"]},"DWCW-752546":{"patternBase":"Nitik Grande Camel Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-Grande-fabric-group_bff57ad2-5a25-4577-812a-074353d641c8.jpg","hue":32,"color_bucket":"orange","familySkus":[]},"DWCW-752646":{"patternBase":"Nitik Grande Jungle Green Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-Grande-fabric-group_25256a72-1bdc-43f0-a26d-24b11476e715.jpg","hue":80,"color_bucket":"green","familySkus":[]},"DWCW-752746":{"patternBase":"Nitik Grande Pink Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-Grande-fabric-group_58702332-e100-473e-be52-74b1b8320a24.jpg","hue":2,"color_bucket":"red","familySkus":[]},"DWCW-752846":{"patternBase":"Nitik Grande Sky Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-Grande-fabric-group_12aa92e1-e44f-41e0-ad07-88c6fdc6f726.jpg","hue":181,"color_bucket":"teal","familySkus":[]},"DWCW-753046":{"patternBase":"Nitik II Black Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_b7dc79d2-ed06-4a49-bb77-50b6bcd031f9.jpg","hue":294,"color_bucket":"magenta","familySkus":[]},"DWCW-753146":{"patternBase":"Nitik II Blue Floresblue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_8d89dd8d-3aa5-439e-a984-b861d7fa5a4b.jpg","hue":210,"color_bucket":"blue","familySkus":[]},"DWCW-753246":{"patternBase":"Nitik II French Blue Navy Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_3f6f7053-3af7-4ce1-90ff-a327b1d3d804.jpg","hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-753346":{"patternBase":"Nitik II Gray Brown Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_8b671dfa-e1ec-4d04-b232-8c7a5079800e.jpg","hue":76,"color_bucket":"green","familySkus":[]},"DWCW-753446":{"patternBase":"Nitik II Jungle Green Brown Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_d2b97ecf-7fc8-4fd6-996a-e1a8d8039fab.jpg","hue":67,"color_bucket":"yellow","familySkus":[]},"DWCW-754546":{"patternBase":"Nitik II New Yellow Salmon","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_0d9064b5-3d37-4d6b-b52e-c99a2431a0a9.jpg","hue":32,"color_bucket":"orange","familySkus":["null"]},"DWCW-754646":{"patternBase":"Nitik II Orange Magenta Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_8f018436-2a0d-4a01-948b-a11b08caf653.jpg","hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-754746":{"patternBase":"Nitik II Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_42630493-b1c8-4c85-92d6-72215e1d5d48.jpg","hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-754846":{"patternBase":"Nitik II Polar Gray Cream","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_4a08599b-788c-4efb-989a-2ae5b2a65fd0.jpg","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-754946":{"patternBase":"Nitik Ii Sky Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_e0e1e023-cda0-47a3-bdee-48db57832856.jpg","hue":202,"color_bucket":"blue","familySkus":[]},"DWCW-755046":{"patternBase":"Nitik Ii Taupe Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Nitik-II-fabric-group_abb8be3f-43d3-402f-8faa-1bce3f71dec8.jpg","hue":36,"color_bucket":"orange","familySkus":[]},"DWCW-755146":{"patternBase":"Obi Ii Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-fabric-group_ed9c2789-2227-4b36-822f-acab7d80f3e1.jpg","hue":47,"color_bucket":"yellow","familySkus":[]},"DWCW-755246":{"patternBase":"Obi II Lavender","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-fabric-group_19cb53bd-17dd-48e5-b62c-41f0e11b8fcf.jpg","hue":289,"color_bucket":"purple","familySkus":[]},"DWCW-755346":{"patternBase":"Obi Ii Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-fabric-group_2cb976bd-7b25-430c-ab4e-233175d5a0c6.jpg","hue":217,"color_bucket":"blue","familySkus":[]},"DWCW-755446":{"patternBase":"Obi II Reverse Aqua","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_5bd9ed18-3a22-4abe-93f0-91b49b0ccf2e.jpg","hue":189,"color_bucket":"teal","familySkus":[]},"DWCW-755546":{"patternBase":"Obi II Reverse Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_2bd52a5d-eb17-4736-9a59-99be8673ccf8.jpg","hue":346,"color_bucket":"red","familySkus":[]},"DWCW-755646":{"patternBase":"Obi II Reverse Camel","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_7fcdb10f-7369-430b-88b9-4402d270d25f.jpg","hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-755746":{"patternBase":"Obi II Reverse Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_b4dfb590-e6db-4603-88b7-595d90d404d3.jpg","hue":75,"color_bucket":"green","familySkus":[]},"DWCW-755846":{"patternBase":"Obi II Reverse Magenta","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_190bc64d-3561-4f11-a9b3-429b23b45f87.jpg","hue":349,"color_bucket":"red","familySkus":[]},"DWCW-755946":{"patternBase":"Obi II Reverse Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_2e83eb99-7f7c-4027-8a95-08265ebf401e.jpg","hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-756046":{"patternBase":"Obi II Reverse New Shrimp","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_403142ff-5fdd-4ad2-b8c9-9842917e80ad.jpg","hue":8,"color_bucket":"red","familySkus":[]},"DWCW-756146":{"patternBase":"Obi II Reverse Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_ad28d32d-62b9-4203-b221-777af43e14c8.jpg","hue":14,"color_bucket":"red","familySkus":[]},"DWCW-756246":{"patternBase":"Obi II Reverse Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-Reverse-fabric-group_5150d317-e047-4474-a741-b7c205a8f38f.jpg","hue":172,"color_bucket":"teal","familySkus":[]},"DWCW-756346":{"patternBase":"Obi II Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Obi-II-fabric-group_10f405d4-2eb9-48db-b534-e127e4fa1f42.jpg","hue":171,"color_bucket":"teal","familySkus":[]},"DWCW-756446":{"patternBase":"Pacific Jute","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Jute-Hay-7010-02GC.jpg","hue":33,"color_bucket":"orange","familySkus":["DWCW-756546","DWCW-756646"]},"DWCW-756546":{"patternBase":"Pacific Jute","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Jute-Natural-7010-01GC.jpg","hue":43,"color_bucket":"orange","familySkus":["DWCW-756446","DWCW-756646"]},"DWCW-756646":{"patternBase":"Pacific Jute","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Jute-Straw-7010-03GC.jpg","hue":27,"color_bucket":"orange","familySkus":["DWCW-756446","DWCW-756546"]},"DWCW-756746":{"patternBase":"Pacific Paperweave","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Paperweave-Natural-7000-02GC.jpg","hue":38,"color_bucket":"orange","familySkus":["DWCW-756846","DWCW-756946"]},"DWCW-756846":{"patternBase":"Pacific Paperweave","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Paperweave-Straw-7000-03GC.jpg","hue":35,"color_bucket":"orange","familySkus":["DWCW-756746","DWCW-756946"]},"DWCW-756946":{"patternBase":"Pacific Paperweave","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Paperweave-White-7000-01GC.jpg","hue":57,"color_bucket":"yellow","familySkus":["DWCW-756746","DWCW-756846"]},"DWCW-757046":{"patternBase":"Pacific Sisal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Sisal-Cream-7020-04GC.jpg","hue":18,"color_bucket":"orange","familySkus":["DWCW-757146","DWCW-757246","DWCW-757346","DWCW-757446"]},"DWCW-757146":{"patternBase":"Pacific Sisal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Sisal-Cream-7020-04GC_3c16b743-2cce-4971-96d5-2c204a328d44.jpg","hue":42,"color_bucket":"orange","familySkus":["DWCW-757046","DWCW-757246","DWCW-757346","DWCW-757446"]},"DWCW-757246":{"patternBase":"Pacific Sisal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Sisal-Cream-7020-04GC_1ec1683a-e308-41ea-ada3-478e8cd1ba75.jpg","hue":218,"color_bucket":"blue","familySkus":["DWCW-757046","DWCW-757146","DWCW-757346","DWCW-757446"]},"DWCW-757346":{"patternBase":"Pacific Sisal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/CHINA_SEAS_WALLPAPER_DWC_757300_Pacific-Sisal-Silver-7020-06GC-2400_jpg_b4862627-7db8-4809-a9b9-9402275a6a80.jpg","hue":37,"color_bucket":"orange","familySkus":["DWCW-757046","DWCW-757146","DWCW-757246","DWCW-757446"]},"DWCW-757446":{"patternBase":"Pacific Sisal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Pacific-Sisal-Straw-7020-02GC.jpg","hue":37,"color_bucket":"orange","familySkus":["DWCW-757046","DWCW-757146","DWCW-757246","DWCW-757346"]},"DWCW-757546":{"patternBase":"Paradise Background Black","room":null,"hue":279,"color_bucket":"purple","familySkus":["DWCW-757646"]},"DWCW-757646":{"patternBase":"Paradise Background Black","room":null,"hue":262,"color_bucket":"purple","familySkus":["DWCW-757546"]},"DWCW-757746":{"patternBase":"Paradise Background","room":null,"hue":57,"color_bucket":"yellow","familySkus":[]},"DWCW-757846":{"patternBase":"Paradise Background Lilac","room":null,"hue":344,"color_bucket":"red","familySkus":[]},"DWCW-757946":{"patternBase":"Paradise Background Orange","room":null,"hue":12,"color_bucket":"red","familySkus":[]},"DWCW-758046":{"patternBase":"Paradise Background Turquoise","room":null,"hue":179,"color_bucket":"teal","familySkus":[]},"DWCW-758146":{"patternBase":"Parquetry Gray Charcoal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Parquetry-fabric-group_9699a4e4-8a6b-46ab-8d75-c31bc1d8e002.jpg","hue":155,"color_bucket":"green","familySkus":[]},"DWCW-758246":{"patternBase":"Parquetry Gray Silver","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Parquetry-fabric-group_1c6cbf49-a5a0-46ce-8226-41f7e3c6f958.jpg","hue":61,"color_bucket":"yellow","familySkus":[]},"DWCW-758346":{"patternBase":"Parquetry Taupe Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Parquetry-fabric-group_236b0ee2-2402-4fff-8f8c-da9b419b8aec.jpg","hue":33,"color_bucket":"orange","familySkus":[]},"DWCW-758446":{"patternBase":"Parquetry Teal Charcoal","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Parquetry-fabric-group_3620280e-6d93-438a-85ab-f12f2a236cf5.jpg","hue":159,"color_bucket":"green","familySkus":[]},"DWCW-758546":{"patternBase":"Passy Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Passy-Black-on-Off-White-8210WP-10OWP.jpg","hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-758646":{"patternBase":"Passy White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Passy-White-on-Off-White-8210WP-01OWP.jpg","hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-758746":{"patternBase":"Peacock Background","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Peacock-Background-Batik-Group_7f4c391c-7434-4804-96bd-eea49a60834a.jpg","hue":53,"color_bucket":"yellow","familySkus":[]},"DWCW-758946":{"patternBase":"Persepolis Brown Navy","room":null,"hue":39,"color_bucket":"orange","familySkus":["DWCW-759046"]},"DWCW-759046":{"patternBase":"Persepolis Brown Navy","room":null,"hue":331,"color_bucket":"red","familySkus":["DWCW-758946"]},"DWCW-759146":{"patternBase":"Persepolis Celeste Blue","room":null,"hue":187,"color_bucket":"teal","familySkus":["DWCW-759246"]},"DWCW-759246":{"patternBase":"Persepolis Celeste Blue","room":null,"hue":194,"color_bucket":"teal","familySkus":["DWCW-759146"]},"DWCW-759346":{"patternBase":"Persepolis Fig Cream","room":null,"hue":56,"color_bucket":"yellow","familySkus":[]},"DWCW-759446":{"patternBase":"Persepolis Fig Taupe","room":null,"hue":56,"color_bucket":"yellow","familySkus":[]},"DWCW-759546":{"patternBase":"Persepolis Melon Camel","room":null,"hue":26,"color_bucket":"orange","familySkus":[]},"DWCW-759646":{"patternBase":"Persepolis Navy French Blue","room":null,"hue":212,"color_bucket":"blue","familySkus":["DWCW-759746"]},"DWCW-759746":{"patternBase":"Persepolis Navy French Blue","room":null,"hue":217,"color_bucket":"blue","familySkus":["DWCW-759646"]},"DWCW-759846":{"patternBase":"Persia Black_on_almost_white","room":null,"hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-759946":{"patternBase":"Persia Camel_0n_almost_white","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-760046":{"patternBase":"Persia Flamingo_on_Almost_White","room":null,"hue":340,"color_bucket":"red","familySkus":[]},"DWCW-760146":{"patternBase":"Persia Lilac_on_almost_white","room":null,"hue":288,"color_bucket":"purple","familySkus":[]},"DWCW-760246":{"patternBase":"Persia Navy_on_almost_white","room":null,"hue":150,"color_bucket":"green","familySkus":[]},"DWCW-760346":{"patternBase":"Persia New_Blue_on_Almost_White","room":null,"hue":210,"color_bucket":"blue","familySkus":[]},"DWCW-760446":{"patternBase":"Persia Orange_on_almost_white","room":null,"hue":18,"color_bucket":"orange","familySkus":[]},"DWCW-760546":{"patternBase":"Persia Turquoise_on_Almost_White","room":null,"hue":158,"color_bucket":"green","familySkus":[]},"DWCW-760646":{"patternBase":"Persia White_on_tan","room":null,"hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-760746":{"patternBase":"Petite Zig Zag Blue","room":null,"hue":203,"color_bucket":"blue","familySkus":[]},"DWCW-760846":{"patternBase":"Petite Zig Zag Brown","room":null,"hue":38,"color_bucket":"orange","familySkus":["DWCW-760946"]},"DWCW-760946":{"patternBase":"Petite Zig Zag Brown","room":null,"hue":21,"color_bucket":"orange","familySkus":["DWCW-760846"]},"DWCW-761046":{"patternBase":"Petite Zig Zag Camel II","room":null,"hue":38,"color_bucket":"orange","familySkus":[]},"DWCW-761146":{"patternBase":"Petite Zig Zag French Blue","room":null,"hue":207,"color_bucket":"blue","familySkus":["DWCW-761246"]},"DWCW-761246":{"patternBase":"Petite Zig Zag French Blue","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-761146"]},"DWCW-761346":{"patternBase":"Petite Zig Zag Green","room":null,"hue":92,"color_bucket":"green","familySkus":[]},"DWCW-761446":{"patternBase":"Petite Zig Zag Inca Gold","room":null,"hue":41,"color_bucket":"orange","familySkus":["DWCW-761546"]},"DWCW-761546":{"patternBase":"Petite Zig Zag Inca Gold","room":null,"hue":40,"color_bucket":"orange","familySkus":["DWCW-761446"]},"DWCW-761646":{"patternBase":"Petite Zig Zag Jungle Green","room":null,"hue":66,"color_bucket":"yellow","familySkus":["DWCW-761746"]},"DWCW-761746":{"patternBase":"Petite Zig Zag Jungle Green","room":null,"hue":70,"color_bucket":"yellow","familySkus":["DWCW-761646"]},"DWCW-761846":{"patternBase":"Petite Zig Zag Light Blue","room":null,"hue":178,"color_bucket":"teal","familySkus":[]},"DWCW-761946":{"patternBase":"Petite Zig Zag Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-762046","DWCW-762146"]},"DWCW-762046":{"patternBase":"Petite Zig Zag Navy","room":null,"hue":211,"color_bucket":"blue","familySkus":["DWCW-761946","DWCW-762146"]},"DWCW-762146":{"patternBase":"Petite Zig Zag Navy","room":null,"hue":228,"color_bucket":"blue","familySkus":["DWCW-761946","DWCW-762046"]},"DWCW-762246":{"patternBase":"Petite Zig Zag New Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-762346"]},"DWCW-762346":{"patternBase":"Petite Zig Zag New Navy","room":null,"hue":213,"color_bucket":"blue","familySkus":["DWCW-762246"]},"DWCW-762446":{"patternBase":"Petite Zig Zag New Shrimp","room":null,"hue":4,"color_bucket":"red","familySkus":["DWCW-762546"]},"DWCW-762546":{"patternBase":"Petite Zig Zag New Shrimp","room":null,"hue":15,"color_bucket":"red","familySkus":["DWCW-762446"]},"DWCW-762646":{"patternBase":"Petite Zig Zag Pacific Blue","room":null,"hue":212,"color_bucket":"blue","familySkus":[]},"DWCW-762746":{"patternBase":"Petite Zig Zag Peach","room":null,"hue":20,"color_bucket":"orange","familySkus":[]},"DWCW-762846":{"patternBase":"Petite Zig Zag Pink","room":null,"hue":350,"color_bucket":"red","familySkus":[]},"DWCW-762946":{"patternBase":"Petite Zig Zag Red","room":null,"hue":359,"color_bucket":"red","familySkus":[]},"DWCW-763046":{"patternBase":"Petite Zig Zag Salmon","room":null,"hue":25,"color_bucket":"orange","familySkus":[]},"DWCW-763146":{"patternBase":"Petite Zig Zag Sand","room":null,"hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-763246":{"patternBase":"Petite Zig Zag Slate Blue","room":null,"hue":208,"color_bucket":"blue","familySkus":["DWCW-763346"]},"DWCW-763346":{"patternBase":"Petite Zig Zag Slate Blue","room":null,"hue":210,"color_bucket":"blue","familySkus":["DWCW-763246"]},"DWCW-763446":{"patternBase":"Petite Zig Zag Taupe","room":null,"hue":41,"color_bucket":"orange","familySkus":["DWCW-763546"]},"DWCW-763546":{"patternBase":"Petite Zig Zag Taupe","room":null,"hue":42,"color_bucket":"orange","familySkus":["DWCW-763446"]},"DWCW-763646":{"patternBase":"Petite Zig Zag Turquoise","room":null,"hue":168,"color_bucket":"green","familySkus":[]},"DWCW-763746":{"patternBase":"Petite Zig Zag Watermelon","room":null,"hue":351,"color_bucket":"red","familySkus":["DWCW-763846","DWCW-763946"]},"DWCW-763846":{"patternBase":"Petite Zig Zag Watermelon","room":null,"hue":343,"color_bucket":"red","familySkus":["DWCW-763746","DWCW-763946"]},"DWCW-763946":{"patternBase":"Petite Zig Zag Watermelon","room":null,"hue":352,"color_bucket":"red","familySkus":["DWCW-763746","DWCW-763846"]},"DWCW-764046":{"patternBase":"Petite Zig Zag White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Petite-Zig-Zag-Watermelon-on-White-Vinyl-AP303-07PV.jpg","hue":169,"color_bucket":"green","familySkus":[]},"DWCW-764146":{"patternBase":"Pina Dark Turquoise","room":null,"hue":169,"color_bucket":"green","familySkus":[]},"DWCW-764246":{"patternBase":"Pina Jungle Green Off White","room":null,"hue":80,"color_bucket":"green","familySkus":[]},"DWCW-764346":{"patternBase":"Pina Tomato","room":null,"hue":11,"color_bucket":"red","familySkus":[]},"DWCW-764446":{"patternBase":"Potalla Background Camel II Off White","room":null,"hue":22,"color_bucket":"orange","familySkus":[]},"DWCW-764546":{"patternBase":"Potalla Background French Blue","room":null,"hue":217,"color_bucket":"blue","familySkus":[]},"DWCW-764746":{"patternBase":"Potalla Multi Blues","room":null,"hue":177,"color_bucket":"teal","familySkus":[]},"DWCW-764846":{"patternBase":"Potalla Multi Greens Rust","room":null,"hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-764946":{"patternBase":"Potalla Outline Black","room":null,"hue":48,"color_bucket":"yellow","familySkus":["DWCW-765046"]},"DWCW-765046":{"patternBase":"Potalla Outline Black","room":null,"hue":241,"color_bucket":"blue","familySkus":["DWCW-764946"]},"DWCW-765146":{"patternBase":"Potalla Outline French Blue","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-765246":{"patternBase":"Potalla Outline French Blue White","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-765346":{"patternBase":"Potalla Outline Jungle Green Off White","room":null,"hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-765446":{"patternBase":"Potalla Outline Jungle Green","room":null,"hue":67,"color_bucket":"yellow","familySkus":[]},"DWCW-765546":{"patternBase":"Potalla Outline New Shrimp Off White","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-765646":{"patternBase":"Potalla Outline New Shrimp White","room":null,"hue":3,"color_bucket":"red","familySkus":[]},"DWCW-765746":{"patternBase":"Potalla Salmons Yellow","room":null,"hue":14,"color_bucket":"red","familySkus":[]},"DWCW-765846":{"patternBase":"Puccini Classic Blue","room":null,"hue":116,"color_bucket":"green","familySkus":[]},"DWCW-765946":{"patternBase":"Puccini French Blue","room":null,"hue":205,"color_bucket":"blue","familySkus":[]},"DWCW-766046":{"patternBase":"Puccini Gray","room":null,"hue":50,"color_bucket":"yellow","familySkus":[]},"DWCW-766146":{"patternBase":"Puccini Inca","room":null,"hue":41,"color_bucket":"orange","familySkus":[]},"DWCW-766246":{"patternBase":"Puccini Lavender","room":null,"hue":352,"color_bucket":"red","familySkus":[]},"DWCW-766346":{"patternBase":"Puccini Light Pink","room":null,"hue":23,"color_bucket":"orange","familySkus":[]},"DWCW-766446":{"patternBase":"Puccini New Apple","room":null,"hue":69,"color_bucket":"yellow","familySkus":[]},"DWCW-766546":{"patternBase":"Puccini New Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-766646":{"patternBase":"Puccini Pink","room":null,"hue":341,"color_bucket":"red","familySkus":[]},"DWCW-766746":{"patternBase":"Puccini Slate","room":null,"hue":133,"color_bucket":"green","familySkus":[]},"DWCW-766846":{"patternBase":"Puccini Tomato","room":null,"hue":11,"color_bucket":"red","familySkus":[]},"DWCW-766946":{"patternBase":"Puccini Venice Blue","room":null,"hue":150,"color_bucket":"green","familySkus":[]},"DWCW-767046":{"patternBase":"Puccini White","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-767146":{"patternBase":"Raffles New","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Raffles-fabric-group_3e4f3e8b-83f0-42c8-8e5d-aeebad8e6640.jpg","hue":181,"color_bucket":"teal","familySkus":[]},"DWCW-767246":{"patternBase":"Rio French Blue","room":null,"hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-767346":{"patternBase":"Rio Royal Blue","room":null,"hue":207,"color_bucket":"blue","familySkus":[]},"DWCW-767446":{"patternBase":"Safari Beige","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06.jpg","hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-767546":{"patternBase":"Safari Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_5e69f6ec-ffc7-4f90-90c9-8c23f04ae9e5.jpg","hue":118,"color_bucket":"green","familySkus":[]},"DWCW-767646":{"patternBase":"Safari Embroidery Black","room":null,"hue":57,"color_bucket":"yellow","familySkus":[]},"DWCW-767746":{"patternBase":"Safari Embroidery Caramel","room":null,"hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-767846":{"patternBase":"Safari Embroidery French Blue","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-767946":{"patternBase":"Safari Embroidery Inca Gold","room":null,"hue":46,"color_bucket":"yellow","familySkus":[]},"DWCW-768046":{"patternBase":"Safari Embroidery Jungle Green","room":null,"hue":74,"color_bucket":"green","familySkus":[]},"DWCW-768246":{"patternBase":"Safari Embroidery Lime","room":null,"hue":81,"color_bucket":"green","familySkus":[]},"DWCW-768346":{"patternBase":"Safari Embroidery Medium Grey","room":null,"hue":58,"color_bucket":"yellow","familySkus":[]},"DWCW-768446":{"patternBase":"Safari Embroidery Medium Turquoise","room":null,"hue":189,"color_bucket":"teal","familySkus":[]},"DWCW-768546":{"patternBase":"Safari Embroidery Melon","room":null,"hue":0,"color_bucket":"red","familySkus":[]},"DWCW-768646":{"patternBase":"Safari Embroidery New Navy","room":null,"hue":220,"color_bucket":"blue","familySkus":[]},"DWCW-768746":{"patternBase":"Safari Embroidery Pale Grey","room":null,"hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-768846":{"patternBase":"Safari Embroidery Royal Blue","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-768946":{"patternBase":"Safari Embroidery Soft Lavender","room":null,"hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-769046":{"patternBase":"Safari Embroidery Soft Windsor","room":null,"hue":136,"color_bucket":"green","familySkus":[]},"DWCW-769146":{"patternBase":"Safari Embroidery White","room":null,"hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-769246":{"patternBase":"Safari French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-French-Blue-on-Almost-White-Paper-AP855-05.jpg","hue":215,"color_bucket":"blue","familySkus":[]},"DWCW-769346":{"patternBase":"Safari Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_2ab7de15-0e07-42ac-9848-1d8aa770eab4.jpg","hue":76,"color_bucket":"green","familySkus":[]},"DWCW-769446":{"patternBase":"Safari Light Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Light-Gray-on-Almost-White-AP855-16.jpg","hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-769546":{"patternBase":"Safari Lime","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_850b5720-7016-40e4-9af0-71e44d02defd.jpg","hue":84,"color_bucket":"green","familySkus":[]},"DWCW-769646":{"patternBase":"Safari New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_75ff0134-5560-4c74-a443-4b916b25f10b.jpg","hue":221,"color_bucket":"blue","familySkus":[]},"DWCW-769746":{"patternBase":"Safari Pale Grey","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_95043332-eeee-4e77-acff-e70013e6a879.jpg","hue":45,"color_bucket":"orange","familySkus":[]},"DWCW-769846":{"patternBase":"Safari Pumice","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Jungle-Green-on-Almost-White-AP855-06_84edf9e7-f428-42d0-8c36-6bef28cd5770.jpg","hue":45,"color_bucket":"orange","familySkus":[]},"DWCW-769946":{"patternBase":"Safari Soft Lavender","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Soft-Lavender-on-Almost-White-Paper-AP855-04.jpg","hue":304,"color_bucket":"magenta","familySkus":[]},"DWCW-770046":{"patternBase":"Safari Soft Windsor","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Safari-Soft-Lavender-on-Almost-White-Paper-AP855-04_f201b38b-df12-48f3-a6d3-da36a824c89e.jpg","hue":185,"color_bucket":"teal","familySkus":[]},"DWCW-770246":{"patternBase":"San Marco Arctic Blue","room":null,"hue":153,"color_bucket":"green","familySkus":[]},"DWCW-770346":{"patternBase":"San Marco Celadon","room":null,"hue":58,"color_bucket":"yellow","familySkus":[]},"DWCW-770446":{"patternBase":"San Marco Chartreuse","room":null,"hue":57,"color_bucket":"yellow","familySkus":[]},"DWCW-770546":{"patternBase":"San Marco Coral","room":null,"hue":15,"color_bucket":"red","familySkus":[]},"DWCW-770646":{"patternBase":"San Marco Cream","room":null,"hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-770746":{"patternBase":"San Marco Gray","room":null,"hue":62,"color_bucket":"yellow","familySkus":["DWCW-770846","DWCW-770946"]},"DWCW-770846":{"patternBase":"San Marco Gray","room":null,"hue":59,"color_bucket":"yellow","familySkus":["DWCW-770746","DWCW-770946"]},"DWCW-770946":{"patternBase":"San Marco Gray","room":null,"hue":56,"color_bucket":"yellow","familySkus":["DWCW-770746","DWCW-770846"]},"DWCW-771046":{"patternBase":"San Marco Langdon Yellow","room":null,"hue":59,"color_bucket":"yellow","familySkus":[]},"DWCW-771146":{"patternBase":"San Marco Reverse Black","room":null,"hue":299,"color_bucket":"magenta","familySkus":[]},"DWCW-771246":{"patternBase":"San Marco Reverse Brown","room":null,"hue":6,"color_bucket":"red","familySkus":[]},"DWCW-771346":{"patternBase":"San Marco Reverse Coral","room":null,"hue":353,"color_bucket":"red","familySkus":[]},"DWCW-771446":{"patternBase":"San Marco Reverse Langdon Yellow","room":null,"hue":55,"color_bucket":"yellow","familySkus":[]},"DWCW-771546":{"patternBase":"San Marco Reverse Prune","room":null,"hue":3,"color_bucket":"red","familySkus":[]},"DWCW-771646":{"patternBase":"San Marco Reverse Turquoise","room":null,"hue":168,"color_bucket":"green","familySkus":[]},"DWCW-771746":{"patternBase":"San Marco Reverse White","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-771846":{"patternBase":"San Marco Zibby Blue","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-771946":{"patternBase":"Sauvage_Reverse Black_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Black_on_Almost_White_CP1025W-09.jpg","hue":115,"color_bucket":"green","familySkus":[]},"DWCW-772046":{"patternBase":"Sauvage_Reverse Brown_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Brown_on_Almost_White_CP1025W-08.jpg","hue":32,"color_bucket":"orange","familySkus":[]},"DWCW-772146":{"patternBase":"Sauvage_Reverse Butter_Yellow_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Butter_Yellow_on_Almost_White_CP1025W-02.jpg","hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-772246":{"patternBase":"Sauvage_Reverse Camel_II_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Camel_II_on_Almost_White_CP1025W-06.jpg","hue":38,"color_bucket":"orange","familySkus":[]},"DWCW-772346":{"patternBase":"Sauvage_Reverse Dark_Lilac_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Dark_Lilac_on_Almost_White_CP1025W-06.jpg","hue":276,"color_bucket":"purple","familySkus":[]},"DWCW-772446":{"patternBase":"Sauvage_Reverse Dark_Turquoise_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Dark_Turquoise_on_Almost_White_CP1025W-03.jpg","hue":181,"color_bucket":"teal","familySkus":[]},"DWCW-772546":{"patternBase":"Sauvage_Reverse Jungle_Green_on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Jungle_Green_on_Almost_White_CP1025W-04.jpg","hue":81,"color_bucket":"green","familySkus":[]},"DWCW-772646":{"patternBase":"Sauvage_Reverse Red on_Almost_White_CP","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sauvage_Reverse_Red-on_Almost_White_CP1025W-07.jpg","hue":1,"color_bucket":"red","familySkus":[]},"DWCW-772746":{"patternBase":"Saya Gata French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Saya-Gata-Lines-Navy-Almost-White-AP207-16.jpg","hue":184,"color_bucket":"teal","familySkus":[]},"DWCW-772846":{"patternBase":"Saya Gata Lines Brown","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-772946":{"patternBase":"Saya Gata Lines Kelly Green","room":null,"hue":98,"color_bucket":"green","familySkus":[]},"DWCW-773046":{"patternBase":"Saya Gata Lines Magenta","room":null,"hue":345,"color_bucket":"red","familySkus":[]},"DWCW-773146":{"patternBase":"Saya Gata Lines Navy Almost White","room":null,"hue":94,"color_bucket":"green","familySkus":[]},"DWCW-773246":{"patternBase":"Saya Gata Lines New Shrimp Off White","room":null,"hue":10,"color_bucket":"red","familySkus":[]},"DWCW-773346":{"patternBase":"Saya Gata Lines New Shrimp","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-773446":{"patternBase":"Saya Gata Lines Orange","room":null,"hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-773546":{"patternBase":"Saya Gata Lines Slate Blue Almost White","room":null,"hue":213,"color_bucket":"blue","familySkus":[]},"DWCW-773646":{"patternBase":"Saya Gata Lines Taxi Cab Yellow","room":null,"hue":35,"color_bucket":"orange","familySkus":[]},"DWCW-773746":{"patternBase":"Saya Gata Lines Turquoise","room":null,"hue":157,"color_bucket":"green","familySkus":["DWCW-773846"]},"DWCW-773846":{"patternBase":"Saya Gata Lines Turquoise","room":null,"hue":173,"color_bucket":"teal","familySkus":["DWCW-773746"]},"DWCW-773946":{"patternBase":"Saya Gata Lines Watermelon Almost White","room":null,"hue":348,"color_bucket":"red","familySkus":[]},"DWCW-774046":{"patternBase":"Seya Black Gray","room":null,"hue":265,"color_bucket":"purple","familySkus":[]},"DWCW-774146":{"patternBase":"Shanghai Dark Grays","room":null,"hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-774246":{"patternBase":"Shanghai Lilac","room":null,"hue":292,"color_bucket":"magenta","familySkus":[]},"DWCW-774346":{"patternBase":"Shanghai Navy Windsor","room":null,"hue":215,"color_bucket":"blue","familySkus":[]},"DWCW-774446":{"patternBase":"Shanghai Pinks","room":null,"hue":359,"color_bucket":"red","familySkus":[]},"DWCW-774546":{"patternBase":"Sigourney Black","room":null,"hue":270,"color_bucket":"purple","familySkus":[]},"DWCW-774646":{"patternBase":"Sigourney Mustard","room":null,"hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-774746":{"patternBase":"Sigourney Navy","room":null,"hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-774846":{"patternBase":"Sigourney Razzle Dazzle","room":null,"hue":338,"color_bucket":"red","familySkus":[]},"DWCW-774946":{"patternBase":"Sigourney Reverse Large Scale Gray","room":null,"hue":76,"color_bucket":"green","familySkus":[]},"DWCW-775046":{"patternBase":"Sigourney Reverse Large Scale Lavender","room":null,"hue":286,"color_bucket":"purple","familySkus":[]},"DWCW-775146":{"patternBase":"Sigourney Reverse Small Scale Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_694ca8ac-d87a-4f3a-a57d-51a75e69d820.jpg","hue":99,"color_bucket":"green","familySkus":[]},"DWCW-775246":{"patternBase":"Sigourney Reverse Small Scale French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_10efdc5c-3474-4646-a163-62709b4bc069.jpg","hue":216,"color_bucket":"blue","familySkus":[]},"DWCW-775346":{"patternBase":"Sigourney Reverse Small Scale Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_3864ebc6-917a-4ecf-affc-3ad126335690.jpg","hue":71,"color_bucket":"green","familySkus":[]},"DWCW-775446":{"patternBase":"Sigourney Reverse Small Scale Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_5b49730d-9999-4e79-b375-e3f18297aa05.jpg","hue":78,"color_bucket":"green","familySkus":[]},"DWCW-775546":{"patternBase":"Sigourney Reverse Small Scale Lavender","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_1186733e-0fc4-4258-b198-097dd9585672.jpg","hue":294,"color_bucket":"magenta","familySkus":[]},"DWCW-775646":{"patternBase":"Sigourney Reverse Small Scale New Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_b3559a71-85c5-46bd-9a27-cdaefc43be2a.jpg","hue":200,"color_bucket":"teal","familySkus":[]},"DWCW-775746":{"patternBase":"Sigourney Reverse Small Scale New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_0b5cf86c-f392-452d-84a0-b257ae5e4733.jpg","hue":222,"color_bucket":"blue","familySkus":[]},"DWCW-775846":{"patternBase":"Sigourney Reverse Small Scale Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_0deafb76-44f6-4a58-9726-5ba808a108bd.jpg","hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-775946":{"patternBase":"Sigourney Reverse Small Scale Red","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_a86319e0-0637-486b-8a98-e815696785dd.jpg","hue":352,"color_bucket":"red","familySkus":[]},"DWCW-776046":{"patternBase":"Sigourney Reverse Small Scale Royal Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_506a63c0-e3d8-4362-affa-9cbfcffd5c32.jpg","hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-776146":{"patternBase":"Sigourney Reverse Small Scale Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_ab93b2a4-d14d-433b-a2be-e1dbfb033c40.jpg","hue":186,"color_bucket":"teal","familySkus":[]},"DWCW-776246":{"patternBase":"Sigourney Reverse Small Scale Yellow","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Reverse-Small-Scale-Group_3ed6f850-37a5-47f3-ab3f-8eca2d9d28fa.jpg","hue":44,"color_bucket":"orange","familySkus":[]},"DWCW-776346":{"patternBase":"Sigourney Small Scale Chartreuse","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_9ae83fae-d151-413a-9307-9c01295ab359.jpg","hue":58,"color_bucket":"yellow","familySkus":[]},"DWCW-776446":{"patternBase":"Sigourney Small Scale French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_fa1eb9da-07ce-4441-b08f-4cac9772897f.jpg","hue":217,"color_bucket":"blue","familySkus":[]},"DWCW-776546":{"patternBase":"Sigourney Small Scale Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_156c3015-043a-45ba-8f3e-a03ca2998399.jpg","hue":66,"color_bucket":"yellow","familySkus":[]},"DWCW-776646":{"patternBase":"Sigourney Small Scale Jungle Green","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_817ce314-d7b8-4b45-b33f-aa28a23ee251.jpg","hue":79,"color_bucket":"green","familySkus":[]},"DWCW-776746":{"patternBase":"Sigourney Small Scale Lavender","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_413275f5-e4eb-4de1-ac07-7946f35a13d4.jpg","hue":293,"color_bucket":"magenta","familySkus":[]},"DWCW-776846":{"patternBase":"Sigourney Small Scale New Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_6140dcc0-f2cd-4d87-bd77-eaa9dc2ce1d9.jpg","hue":197,"color_bucket":"teal","familySkus":[]},"DWCW-776946":{"patternBase":"Sigourney Small Scale New Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_682eca05-eb09-4c12-8139-70d6a086744f.jpg","hue":222,"color_bucket":"blue","familySkus":[]},"DWCW-777046":{"patternBase":"Sigourney Small Scale Orange","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_184fad37-9f52-4057-ad2f-087d71446c38.jpg","hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-777146":{"patternBase":"Sigourney Small Scale Red","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_4534349a-40df-402e-a4c8-e03a5fbb3faf.jpg","hue":351,"color_bucket":"red","familySkus":[]},"DWCW-777246":{"patternBase":"Sigourney Small Scale Royal Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_cb22abd5-6052-4ad2-bda7-2b1b32a27370.jpg","hue":220,"color_bucket":"blue","familySkus":[]},"DWCW-777346":{"patternBase":"Sigourney Small Scale Taupe","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_4f91f526-69a2-4fd3-bdf7-a3e4ad58cb64.jpg","hue":37,"color_bucket":"orange","familySkus":[]},"DWCW-777446":{"patternBase":"Sigourney Small Scale Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_878a1876-00cd-41d9-ad24-5bb6ad0ea59c.jpg","hue":188,"color_bucket":"teal","familySkus":[]},"DWCW-777546":{"patternBase":"Sigourney Small Scale Yellow","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sigourney-Small-Scale-Group_85231284-f421-4d1a-a0e1-9262f7856c1e.jpg","hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-777646":{"patternBase":"Sigourney Terracotta","room":null,"hue":10,"color_bucket":"red","familySkus":[]},"DWCW-777746":{"patternBase":"Sigourney Zibby Blue","room":null,"hue":206,"color_bucket":"blue","familySkus":[]},"DWCW-777846":{"patternBase":"Soho Jungle Green Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Soho-Turquoise-Navy-on-White-AP209-06.jpg","hue":69,"color_bucket":"yellow","familySkus":[]},"DWCW-777946":{"patternBase":"Soho Turquoise Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Soho-Turquoise-Navy-on-White-AP209-06_77e2d05a-ac27-4677-89fb-5e1335be5139.jpg","hue":178,"color_bucket":"teal","familySkus":[]},"DWCW-778046":{"patternBase":"Sunnyjim All Over Classic Blues","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-All-Over-fabric-group_7e52edc4-d507-41cb-ba7d-5e06c112cc32.jpg","hue":136,"color_bucket":"green","familySkus":[]},"DWCW-778146":{"patternBase":"Sunnyjim All Over French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-All-Over-fabric-group_710ecd15-7ceb-4011-b536-c9f38f73770a.jpg","hue":207,"color_bucket":"blue","familySkus":[]},"DWCW-778246":{"patternBase":"Sunnyjim All Over Pinks","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-All-Over-fabric-group_2f2e82a9-47be-4a8c-a1ed-d79f804e5adb.jpg","hue":12,"color_bucket":"red","familySkus":[]},"DWCW-778346":{"patternBase":"Sunnyjim All Over Turquoise","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-All-Over-fabric-group_0d454488-9ab5-4d75-87db-10c55cc580d2.jpg","hue":162,"color_bucket":"green","familySkus":[]},"DWCW-778446":{"patternBase":"Sunnyjim Batik Multi Charcoal Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-Batik-fabric-group_6d58ff43-7ac1-4684-9488-d8622fe66af0.jpg","hue":54,"color_bucket":"yellow","familySkus":[]},"DWCW-778546":{"patternBase":"Sunnyjim Batik Multi Greens Tan","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-Batik-fabric-group_0a324796-0fe0-4dd3-bc14-340c2488241e.jpg","hue":56,"color_bucket":"yellow","familySkus":[]},"DWCW-778646":{"patternBase":"Sunnyjim Batik Multi Navy French Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Sunnyjim-Batik-fabric-group_ac79f503-14c5-4f5d-b861-6c79bb7874c4.jpg","hue":9,"color_bucket":"red","familySkus":[]},"DWCW-778746":{"patternBase":"Tableau Sky","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Tableau-Sky-on-White-Matte-619-20.jpg","hue":211,"color_bucket":"blue","familySkus":[]},"DWCW-779346":{"patternBase":"Taj Melon","room":null,"hue":10,"color_bucket":"red","familySkus":[]},"DWCW-779446":{"patternBase":"Taj Navy","room":null,"hue":201,"color_bucket":"blue","familySkus":[]},"DWCW-779546":{"patternBase":"Taj New Shrimp","room":null,"hue":13,"color_bucket":"red","familySkus":[]},"DWCW-779646":{"patternBase":"Taj Tobacco","room":null,"hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-779746":{"patternBase":"Tate Dark Grey","room":null,"hue":53,"color_bucket":"yellow","familySkus":[]},"DWCW-779846":{"patternBase":"Tate Jungle Green","room":null,"hue":60,"color_bucket":"yellow","familySkus":[]},"DWCW-779946":{"patternBase":"Tate Lavender","room":null,"hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-780046":{"patternBase":"Tate Orange","room":null,"hue":25,"color_bucket":"orange","familySkus":[]},"DWCW-780146":{"patternBase":"Tate Pink","room":null,"hue":16,"color_bucket":"orange","familySkus":[]},"DWCW-780246":{"patternBase":"Tate Sky Blue","room":null,"hue":89,"color_bucket":"green","familySkus":[]},"DWCW-780346":{"patternBase":"Tate Turquoise","room":null,"hue":86,"color_bucket":"green","familySkus":[]},"DWCW-780446":{"patternBase":"Tate Yellow","room":null,"hue":53,"color_bucket":"yellow","familySkus":["DWCW-780546"]},"DWCW-780546":{"patternBase":"Tate Yellow","room":null,"hue":53,"color_bucket":"yellow","familySkus":["DWCW-780446"]},"DWCW-780646":{"patternBase":"Terrace New","room":null,"hue":63,"color_bucket":"yellow","familySkus":[]},"DWCW-780746":{"patternBase":"Tie Dye White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Tie-Dye-White-on-Off-White-AP930-00.jpg","hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-780846":{"patternBase":"Trellis Background Camel II Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group.jpg","hue":30,"color_bucket":"orange","familySkus":[]},"DWCW-780946":{"patternBase":"Trellis Background Navy","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group_6928c49b-90b2-42c0-bb2d-3fbf2c6cf3b2.jpg","hue":219,"color_bucket":"blue","familySkus":[]},"DWCW-781046":{"patternBase":"Trellis Background New Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group_9770db5e-de32-44e6-a84c-a3ac21c28321.jpg","hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-781146":{"patternBase":"Trellis Background Orange Almost White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group_4cd19f1c-836a-42c6-a3ef-715867c7d6b6.jpg","hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-781246":{"patternBase":"Trellis Background Orange Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group_a0502d5f-8194-46fc-b794-f4bdc67c3178.jpg","hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-781346":{"patternBase":"Trellis Background Turquoise Off White","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Trellis-Background-fabric-group_a2fdd30a-5977-46c4-aa5c-54b17f4666b9.jpg","hue":170,"color_bucket":"green","familySkus":[]},"DWCW-781446":{"patternBase":"Trellis Outline Black","room":null,"hue":59,"color_bucket":"yellow","familySkus":[]},"DWCW-781546":{"patternBase":"Trilby Jungle Green Pink","room":null,"hue":81,"color_bucket":"green","familySkus":[]},"DWCW-781646":{"patternBase":"Tulip Multicolor Lilac Turquoise Green White","room":null,"hue":91,"color_bucket":"green","familySkus":[]},"DWCW-781746":{"patternBase":"Tulip Multicolor Multi Pink Green","room":null,"hue":15,"color_bucket":"red","familySkus":[]},"DWCW-781846":{"patternBase":"Twigs Soft","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Twigs-fabric-group_561fbb58-ee45-47f3-89a1-f06f6132e43b.jpg","hue":69,"color_bucket":"yellow","familySkus":[]},"DWCW-781946":{"patternBase":"Uzbek Multi Blues Greens Royal","room":null,"hue":125,"color_bucket":"green","familySkus":[]},"DWCW-782046":{"patternBase":"Uzbek Multi Green Pink Blues","room":null,"hue":2,"color_bucket":"red","familySkus":[]},"DWCW-782246":{"patternBase":"Uzbek Multi Red Teal Blues","room":null,"hue":174,"color_bucket":"teal","familySkus":[]},"DWCW-782346":{"patternBase":"Vacances French Blue","room":null,"hue":208,"color_bucket":"blue","familySkus":[]},"DWCW-782446":{"patternBase":"Vacances Inca Gold","room":null,"hue":38,"color_bucket":"orange","familySkus":[]},"DWCW-782546":{"patternBase":"Vacances Jungle Green","room":null,"hue":84,"color_bucket":"green","familySkus":[]},"DWCW-782646":{"patternBase":"Vacances Lilac","room":null,"hue":292,"color_bucket":"magenta","familySkus":[]},"DWCW-782746":{"patternBase":"Vacances Melon","room":null,"hue":351,"color_bucket":"red","familySkus":[]},"DWCW-782846":{"patternBase":"Vacances New Navy","room":null,"hue":207,"color_bucket":"blue","familySkus":[]},"DWCW-782946":{"patternBase":"Vacances Turquoise","room":null,"hue":184,"color_bucket":"teal","familySkus":[]},"DWCW-783046":{"patternBase":"Veneto 2 Across Denim Blue","room":null,"hue":200,"color_bucket":"teal","familySkus":[]},"DWCW-783146":{"patternBase":"Veneto 2 Across Maize","room":null,"hue":43,"color_bucket":"orange","familySkus":[]},"DWCW-783246":{"patternBase":"Veneto 2 Across New Apple","room":null,"hue":65,"color_bucket":"yellow","familySkus":[]},"DWCW-783346":{"patternBase":"Veneto 2 Across Terracotta","room":null,"hue":21,"color_bucket":"orange","familySkus":[]},"DWCW-783446":{"patternBase":"Veneto 2 Across Venice Blue","room":null,"hue":173,"color_bucket":"teal","familySkus":[]},"DWCW-783546":{"patternBase":"Veneto 2 Across White","room":null,"hue":61,"color_bucket":"yellow","familySkus":[]},"DWCW-783646":{"patternBase":"Veneto Beige","room":null,"hue":40,"color_bucket":"orange","familySkus":[]},"DWCW-783746":{"patternBase":"Veneto Gold Metallic","room":null,"hue":49,"color_bucket":"yellow","familySkus":[]},"DWCW-783846":{"patternBase":"Veneto Gray","room":null,"hue":55,"color_bucket":"yellow","familySkus":[]},"DWCW-783946":{"patternBase":"Veneto Langdon Yellow","room":null,"hue":56,"color_bucket":"yellow","familySkus":[]},"DWCW-784046":{"patternBase":"Veneto Plum","room":null,"hue":342,"color_bucket":"red","familySkus":[]},"DWCW-784146":{"patternBase":"Veneto Pumice","room":null,"hue":34,"color_bucket":"orange","familySkus":[]},"DWCW-784246":{"patternBase":"Veneto Soft French Green","room":null,"hue":72,"color_bucket":"green","familySkus":[]},"DWCW-784346":{"patternBase":"Veneto Soft Lavender","room":null,"hue":0,"color_bucket":"red","familySkus":[]},"DWCW-784446":{"patternBase":"Veneto Soft Pink","room":null,"hue":7,"color_bucket":"red","familySkus":[]},"DWCW-784646":{"patternBase":"Veneto Windsor Blue","room":null,"hue":149,"color_bucket":"green","familySkus":[]},"DWCW-784746":{"patternBase":"Victoria French","room":null,"hue":63,"color_bucket":"yellow","familySkus":[]},"DWCW-784846":{"patternBase":"Volpi Gray","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-784946":{"patternBase":"Volpi Langdon Yellow","room":null,"hue":58,"color_bucket":"yellow","familySkus":[]},"DWCW-785046":{"patternBase":"Volpi New Navy","room":null,"hue":226,"color_bucket":"blue","familySkus":[]},"DWCW-785146":{"patternBase":"Wildflowers Ii Black","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_e4bed0d0-6259-49bb-895d-cc7268351bd1.jpg","hue":173,"color_bucket":"teal","familySkus":[]},"DWCW-785246":{"patternBase":"Wildflowers Ii Brown","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_51b674f8-21b5-466d-bf67-de959b7fe9f2.jpg","hue":31,"color_bucket":"orange","familySkus":[]},"DWCW-785346":{"patternBase":"Wildflowers II Camel II","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_1ff74e65-5179-42c0-bf11-6cc0e6a027e9.jpg","hue":29,"color_bucket":"orange","familySkus":[]},"DWCW-785446":{"patternBase":"Wildflowers Ii Gray","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_c39c22ab-5b13-45bc-a40d-0c12bded7075.jpg","hue":60,"color_bucket":"yellow","familySkus":[]},"DWCW-785546":{"patternBase":"Wildflowers Ii Purple","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_ac71657a-9340-4a55-b4bf-cccf0c0fc93b.jpg","hue":328,"color_bucket":"magenta","familySkus":[]},"DWCW-785646":{"patternBase":"Wildflowers II Royal Blue","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wildflowers-II-fabric-group_28fe581a-80b7-410a-93bd-ce3db3fb9e60.jpg","hue":218,"color_bucket":"blue","familySkus":[]},"DWCW-787246":{"patternBase":"Zig Zag Black","room":null,"hue":300,"color_bucket":"magenta","familySkus":[]},"DWCW-785946":{"patternBase":"Zig Zag Leaf","room":null,"hue":106,"color_bucket":"green","familySkus":[]},"DWCW-786046":{"patternBase":"Zig Zag Multi Aqua Lt Turquoise Almost White","room":null,"hue":170,"color_bucket":"green","familySkus":[]},"DWCW-786146":{"patternBase":"Zig Zag Multi Lavender Purple Almost White","room":null,"hue":336,"color_bucket":"red","familySkus":[]},"DWCW-786246":{"patternBase":"Zig Zag Multi Lime Yellow Almost White","room":null,"hue":48,"color_bucket":"yellow","familySkus":[]},"DWCW-786346":{"patternBase":"Zig Zag Multi New Blue Navy Almost White","room":null,"hue":201,"color_bucket":"blue","familySkus":[]},"DWCW-786446":{"patternBase":"Zig Zag Multi Turquoise Fuschia Almost White","room":null,"hue":344,"color_bucket":"red","familySkus":[]},"DWCW-786546":{"patternBase":"Zig Zag Multi Turquoise Yellow Almost White","room":null,"hue":52,"color_bucket":"yellow","familySkus":[]},"DWCW-786646":{"patternBase":"Zig Zag Navy","room":null,"hue":216,"color_bucket":"blue","familySkus":["DWCW-786746"]},"DWCW-786746":{"patternBase":"Zig Zag Navy","room":null,"hue":220,"color_bucket":"blue","familySkus":["DWCW-786646"]},"DWCW-786846":{"patternBase":"Zig Zag New Shrimp","room":null,"hue":6,"color_bucket":"red","familySkus":[]},"DWCW-787346":{"patternBase":"Zig Zag Orange","room":null,"hue":17,"color_bucket":"orange","familySkus":[]},"DWCW-786946":{"patternBase":"Zig Zag Slate Blue","room":null,"hue":209,"color_bucket":"blue","familySkus":[]},"DWCW-787046":{"patternBase":"Zig Zag Taupe","room":null,"hue":36,"color_bucket":"orange","familySkus":[]},"DWCW-787146":{"patternBase":"Zig Zag White","room":null,"hue":195,"color_bucket":"teal","familySkus":[]},"DWCW-785746":{"patternBase":"Ziggurat Jungle","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ziggurat-fabric-group_9de4631e-96c8-4278-976b-9cd8792c5ac1.jpg","hue":67,"color_bucket":"yellow","familySkus":[]},"DWCW-785846":{"patternBase":"Ziggurat Lavender","room":"https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Ziggurat-fabric-group_d1d9f57e-1fdb-44ae-b6c4-a0c5e50590e3.jpg","hue":330,"color_bucket":"magenta","familySkus":[]},"303815G-10GRAS":{"patternBase":"Enchanted Bamboo","room":"https://quadrillefabrics.com/Grasscloth/Enchanted-Bamboo-One-Color-on-Grasscloth-Black-on-Cream-Grasscloth-303815G-10GRAS-sm-thumb.jpg","hue":null,"color_bucket":null,"familySkus":["303815G-15GRAS","303815G-06GRAS","303815G-04GRAS","303815G-05GRAS"]},"303815G-15GRAS":{"patternBase":"Enchanted Bamboo","room":"https://quadrillefabrics.com/Grasscloth/Enchanted-Bamboo-One-Color-on-Grasscloth-Black-On-Hay-Grasscloth-303815G-15GRAS-sm-thumb.jpg","hue":null,"color_bucket":null,"familySkus":["303815G-10GRAS","303815G-06GRAS","303815G-04GRAS","303815G-05GRAS"]},"303815G-06GRAS":{"patternBase":"Enchanted Bamboo","room":"https://quadrillefabrics.com/Grasscloth/Enchanted-Bamboo-One-Color-on-Grasscloth-Inca-Gold-on-Cream-Grasscloth-303815G-06GRAS-sm-thumb.jpg","hue":null,"color_bucket":null,"familySkus":["303815G-10GRAS","303815G-15GRAS","303815G-04GRAS","303815G-05GRAS"]},"303815G-04GRAS":{"patternBase":"Enchanted Bamboo","room":"https://quadrillefabrics.com/Grasscloth/Enchanted-Bamboo-One-Color-on-Grasscloth-Jungle-Green-on-Cream-Grasscloth-303815G-04GRAS-sm-thumb.jpg","hue":null,"color_bucket":null,"familySkus":["303815G-10GRAS","303815G-15GRAS","303815G-06GRAS","303815G-05GRAS"]},"303815G-05GRAS":{"patternBase":"Enchanted Bamboo","room":"https://quadrillefabrics.com/Grasscloth/Enchanted-Bamboo-One-Color-on-Grasscloth-Navy-on-Cream-Grasscloth-303815G-05GRAS-sm-thumb.jpg","hue":null,"color_bucket":null,"familySkus":["303815G-10GRAS","303815G-15GRAS","303815G-06GRAS","303815G-04GRAS"]}}}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index dc27995..561f503 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,518 @@
       "dependencies": {
         "compression": "^1.8.1",
         "express": "^5.2.1",
-        "helmet": "^8.1.0"
+        "helmet": "^8.1.0",
+        "sharp": "^0.35.2"
+      }
+    },
+    "node_modules/@emnapi/runtime": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
+      "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "tslib": "^2.4.0"
+      }
+    },
+    "node_modules/@img/colour": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
+      "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@img/sharp-darwin-arm64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz",
+      "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-darwin-arm64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-darwin-x64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz",
+      "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-darwin-x64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-freebsd-wasm32": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz",
+      "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "dependencies": {
+        "@img/sharp-wasm32": "0.35.2"
+      },
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-darwin-arm64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz",
+      "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-darwin-x64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz",
+      "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-arm": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz",
+      "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-arm64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz",
+      "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-ppc64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz",
+      "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-riscv64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz",
+      "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-s390x": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz",
+      "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linux-x64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz",
+      "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz",
+      "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz",
+      "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-linux-arm": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz",
+      "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-arm": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linux-arm64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz",
+      "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-arm64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linux-ppc64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz",
+      "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-ppc64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linux-riscv64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz",
+      "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-riscv64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linux-s390x": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz",
+      "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-s390x": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linux-x64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz",
+      "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linux-x64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linuxmusl-arm64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz",
+      "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linuxmusl-arm64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-linuxmusl-x64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz",
+      "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-libvips-linuxmusl-x64": "1.3.1"
+      }
+    },
+    "node_modules/@img/sharp-wasm32": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz",
+      "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==",
+      "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+      "optional": true,
+      "dependencies": {
+        "@emnapi/runtime": "^1.11.1"
+      },
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-webcontainers-wasm32": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz",
+      "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==",
+      "cpu": [
+        "wasm32"
+      ],
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@img/sharp-wasm32": "0.35.2"
+      },
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-win32-arm64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz",
+      "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-win32-ia32": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz",
+      "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": "^20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      }
+    },
+    "node_modules/@img/sharp-win32-x64": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz",
+      "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "Apache-2.0 AND LGPL-3.0-or-later",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
       }
     },
     "node_modules/accepts": {
@@ -209,6 +720,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/detect-libc": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+      "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/dunder-proto": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -807,6 +1327,18 @@
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
       "license": "MIT"
     },
+    "node_modules/semver": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+      "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/send": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
@@ -881,6 +1413,50 @@
       "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
       "license": "ISC"
     },
+    "node_modules/sharp": {
+      "version": "0.35.2",
+      "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz",
+      "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@img/colour": "^1.1.0",
+        "detect-libc": "^2.1.2",
+        "semver": "^7.8.4"
+      },
+      "engines": {
+        "node": ">=20.9.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/libvips"
+      },
+      "optionalDependencies": {
+        "@img/sharp-darwin-arm64": "0.35.2",
+        "@img/sharp-darwin-x64": "0.35.2",
+        "@img/sharp-freebsd-wasm32": "0.35.2",
+        "@img/sharp-libvips-darwin-arm64": "1.3.1",
+        "@img/sharp-libvips-darwin-x64": "1.3.1",
+        "@img/sharp-libvips-linux-arm": "1.3.1",
+        "@img/sharp-libvips-linux-arm64": "1.3.1",
+        "@img/sharp-libvips-linux-ppc64": "1.3.1",
+        "@img/sharp-libvips-linux-riscv64": "1.3.1",
+        "@img/sharp-libvips-linux-s390x": "1.3.1",
+        "@img/sharp-libvips-linux-x64": "1.3.1",
+        "@img/sharp-libvips-linuxmusl-arm64": "1.3.1",
+        "@img/sharp-libvips-linuxmusl-x64": "1.3.1",
+        "@img/sharp-linux-arm": "0.35.2",
+        "@img/sharp-linux-arm64": "0.35.2",
+        "@img/sharp-linux-ppc64": "0.35.2",
+        "@img/sharp-linux-riscv64": "0.35.2",
+        "@img/sharp-linux-s390x": "0.35.2",
+        "@img/sharp-linux-x64": "0.35.2",
+        "@img/sharp-linuxmusl-arm64": "0.35.2",
+        "@img/sharp-linuxmusl-x64": "0.35.2",
+        "@img/sharp-webcontainers-wasm32": "0.35.2",
+        "@img/sharp-win32-arm64": "0.35.2",
+        "@img/sharp-win32-ia32": "0.35.2",
+        "@img/sharp-win32-x64": "0.35.2"
+      }
+    },
     "node_modules/side-channel": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -971,6 +1547,13 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD",
+      "optional": true
+    },
     "node_modules/type-is": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
diff --git a/package.json b/package.json
index a048fe0..42bbcd5 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
   "dependencies": {
     "compression": "^1.8.1",
     "express": "^5.2.1",
-    "helmet": "^8.1.0"
+    "helmet": "^8.1.0",
+    "sharp": "^0.35.2"
   }
 }
diff --git a/proto/shot-colorriver.cjs b/proto/shot-colorriver.cjs
new file mode 100644
index 0000000..1e739d4
--- /dev/null
+++ b/proto/shot-colorriver.cjs
@@ -0,0 +1,88 @@
+#!/usr/bin/env node
+/* Headless verifier for proto/v6-colorriver.html
+   - boots the proto static+proxy server (proxy-server.cjs) on a temp port
+   - loads /v6-colorriver.html in chromium
+   - waits for swatches to load, captures console errors
+   - asserts swatches rendered AND sorted by hue
+   - writes proto/shots/v6-colorriver.png
+   Run: NODE_PATH=$HOME/.npm-global/lib/node_modules node proto/shot-colorriver.cjs
+*/
+const { spawn } = require("child_process");
+const path = require("path");
+const http = require("http");
+
+const PROTO_DIR = __dirname;
+const PORT = 7711;
+const URL = `http://127.0.0.1:${PORT}/v6-colorriver.html`;
+
+function waitForServer(port, tries=40){
+  return new Promise((resolve,reject)=>{
+    const probe=(n)=>{
+      const req=http.get({host:"127.0.0.1",port,path:"/v6-colorriver.html"},(r)=>{r.destroy();resolve();});
+      req.on("error",()=>{ if(n<=0) return reject(new Error("server never came up")); setTimeout(()=>probe(n-1),150); });
+    };
+    probe(tries);
+  });
+}
+
+(async()=>{
+  let pw;
+  try { pw = require("playwright"); } catch(e){ console.error("NO playwright:",e.message); process.exit(2); }
+
+  // start proto server
+  const srv = spawn("node", [path.join(PROTO_DIR,"proxy-server.cjs")], {
+    env:{ ...process.env, PROTO_PORT:String(PORT) }, stdio:"inherit"
+  });
+  let exitCode = 1;
+  try {
+    await waitForServer(PORT);
+    const browser = await pw.chromium.launch({ headless:true });
+    const page = await browser.newPage({ viewport:{ width:1440, height:900 }, deviceScaleFactor:2 });
+
+    const errors = [];
+    page.on("console", m=>{ if(m.type()==="error") errors.push(m.text()); });
+    page.on("pageerror", e=>errors.push("PAGEERROR: "+e.message));
+
+    await page.goto(URL, { waitUntil:"domcontentloaded", timeout:30000 });
+
+    // wait until full load+sort completes (or 35s)
+    await page.waitForFunction(()=>window.__RIVER__ && window.__RIVER__.done(), { timeout:35000 })
+      .catch(()=>{});
+
+    // let textures settle + boot fade
+    await page.waitForTimeout(2000);
+
+    const count = await page.evaluate(()=>window.__RIVER__ ? window.__RIVER__.count() : 0);
+    const sorted = await page.evaluate(()=>window.__RIVER__ ? window.__RIVER__.sortedByHue() : false);
+    const spatial = await page.evaluate(()=>window.__RIVER__ ? window.__RIVER__.spatialSorted() : false);
+    const hueSample = await page.evaluate(()=>{
+      const h = window.__RIVER__ ? window.__RIVER__.hues() : [];
+      return { first:h.slice(0,5), last:h.slice(-5), n:h.length };
+    });
+
+    const shotPath = path.join(PROTO_DIR,"shots","v6-colorriver.png");
+    await page.screenshot({ path:shotPath });
+
+    console.log("\n================ COLOR RIVER VERIFY ================");
+    console.log("swatches rendered :", count);
+    console.log("sorted by hue     :", sorted);
+    console.log("spatial X by hue  :", spatial);
+    console.log("hue range (sorted):", hueSample.first, "...", hueSample.last);
+    console.log("console errors    :", errors.length);
+    if(errors.length) errors.slice(0,10).forEach(e=>console.log("   !", e));
+    console.log("screenshot        :", shotPath);
+    console.log("===================================================\n");
+
+    await browser.close();
+
+    const ok = count >= 40 && sorted === true && spatial === true && errors.length === 0;
+    exitCode = ok ? 0 : 1;
+    console.log(ok ? "VERDICT: PASS" : "VERDICT: FAIL");
+  } catch(e){
+    console.error("verify error:", e);
+    exitCode = 3;
+  } finally {
+    srv.kill("SIGTERM");
+    setTimeout(()=>process.exit(exitCode), 300);
+  }
+})();
diff --git a/proto/shots/v10-concierge.png b/proto/shots/v10-concierge.png
new file mode 100644
index 0000000..f919725
Binary files /dev/null and b/proto/shots/v10-concierge.png differ
diff --git a/proto/shots/v6-colorriver.png b/proto/shots/v6-colorriver.png
new file mode 100644
index 0000000..283804b
Binary files /dev/null and b/proto/shots/v6-colorriver.png differ
diff --git a/proto/shots/v8-swipe-filled.png b/proto/shots/v8-swipe-filled.png
new file mode 100644
index 0000000..b802042
Binary files /dev/null and b/proto/shots/v8-swipe-filled.png differ
diff --git a/proto/shots/v8-swipe.png b/proto/shots/v8-swipe.png
new file mode 100644
index 0000000..1218eb6
Binary files /dev/null and b/proto/shots/v8-swipe.png differ
diff --git a/proto/shots/v9-walkin-angle2.png b/proto/shots/v9-walkin-angle2.png
new file mode 100644
index 0000000..604a819
Binary files /dev/null and b/proto/shots/v9-walkin-angle2.png differ
diff --git a/proto/shots/v9-walkin.png b/proto/shots/v9-walkin.png
new file mode 100644
index 0000000..4a755bc
Binary files /dev/null and b/proto/shots/v9-walkin.png differ
diff --git a/proto/v10-concierge.html b/proto/v10-concierge.html
new file mode 100644
index 0000000..7ff8a57
--- /dev/null
+++ b/proto/v10-concierge.html
@@ -0,0 +1,561 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>The Quadrille House — Concierge Nook</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
+<style>
+  :root{
+    /* Art-direction palette */
+    --plaster:#e7e1d6;
+    --stone:#cfc7b8;
+    --greige:#b8afa0;
+    --oak:#9a7a52;
+    --oak-dark:#6f5536;
+    --brass:#b9933f;
+    --brass-lt:#c9a96e;
+    --ink:#1a1206;
+    --ink-soft:#473c2c;
+    --cream:#f0e6cf;
+    --charcoal:#1c1c22;
+    --felt:#3a352c;       /* table felt */
+    --pane:#f5f0e7;
+  }
+  *{box-sizing:border-box;margin:0;padding:0}
+  html,body{height:100%}
+  body{
+    font-family:'Jost',sans-serif;
+    color:var(--ink);
+    background:
+      radial-gradient(120% 90% at 50% -10%, #2c2820 0%, #211d16 45%, #16130d 100%);
+    overflow:hidden;
+    -webkit-font-smoothing:antialiased;
+  }
+  /* ===== Room shell: POV sitting at the consultation table ===== */
+  .room{
+    position:fixed; inset:0;
+    display:grid;
+    grid-template-rows: 1fr auto;
+    perspective:1400px;
+    perspective-origin:50% 38%;
+  }
+
+  /* Back wall — limewash plaster with a brass picture rail + soft picture-light glow */
+  .backwall{
+    position:absolute; inset:0 0 28% 0;
+    background:
+      radial-gradient(80% 55% at 50% 4%, rgba(201,169,110,.18), transparent 60%),
+      linear-gradient(180deg, #efe9dd 0%, #e3dccf 55%, #d6cdbc 100%);
+    box-shadow: inset 0 -40px 80px rgba(28,28,34,.18);
+  }
+  .backwall::after{ /* faint plaster mottle */
+    content:""; position:absolute; inset:0;
+    background:
+      radial-gradient(60% 40% at 22% 30%, rgba(0,0,0,.03), transparent 60%),
+      radial-gradient(50% 38% at 78% 22%, rgba(0,0,0,.025), transparent 60%);
+    mix-blend-mode:multiply;
+  }
+  .rail{ position:absolute; top:13%; left:0; right:0; height:5px;
+    background:linear-gradient(180deg,var(--brass-lt),var(--brass) 60%,#7e6526);
+    box-shadow:0 3px 9px rgba(0,0,0,.28), 0 1px 0 rgba(255,255,255,.35) inset;}
+
+  /* The consultation TABLE — a tilted oak surface receding from the viewer (the POV) */
+  .table-zone{ position:absolute; inset:0; overflow:hidden; }
+  .table{
+    position:absolute; left:50%; bottom:-6%;
+    width:175%; height:122%;
+    transform:translateX(-50%) rotateX(58deg);
+    transform-origin:50% 100%;
+    background:
+      linear-gradient(115deg, rgba(255,255,255,.05) 0%, transparent 30%),
+      repeating-linear-gradient(91deg, #a07d50 0 60px, #98774b 60px 122px),
+      linear-gradient(180deg,#a98a5c,#7c6038 70%,#5f4a2c);
+    border-radius:14px 14px 0 0;
+    box-shadow: 0 -2px 0 rgba(255,255,255,.18) inset, 0 40px 120px rgba(0,0,0,.55);
+  }
+  .table::before{ /* warm sheen / picture-light grazing the felt runner */
+    content:""; position:absolute; left:50%; top:6%; transform:translateX(-50%);
+    width:62%; height:70%;
+    background:
+      radial-gradient(60% 60% at 50% 0%, rgba(231,225,214,.14), transparent 70%);
+    border-radius:8px;
+    background-color:var(--felt);
+    box-shadow:inset 0 0 60px rgba(0,0,0,.5), 0 0 0 1px rgba(201,169,110,.25);
+    opacity:.9;
+  }
+
+  /* ===== Concierge assist panel (left, fixed) ===== */
+  .concierge{
+    position:fixed; top:0; left:0; bottom:0; width:380px;
+    background:linear-gradient(180deg, rgba(245,240,231,.97), rgba(238,232,221,.98));
+    border-right:1px solid rgba(185,147,63,.35);
+    box-shadow: 8px 0 40px rgba(0,0,0,.4);
+    display:flex; flex-direction:column;
+    z-index:20;
+  }
+  .c-head{ padding:26px 26px 16px; border-bottom:1px solid rgba(185,147,63,.25); }
+  .eyebrow{ font-size:11px; letter-spacing:2.4px; text-transform:uppercase; color:var(--brass);
+    font-weight:500; }
+  .wordmark{ font-family:'Cormorant Garamond',serif; font-weight:600; font-size:30px;
+    line-height:1.05; color:var(--ink); margin-top:4px; }
+  .wordmark em{ font-style:italic; color:var(--oak-dark); }
+  .seat{ font-size:12.5px; color:var(--ink-soft); margin-top:9px; line-height:1.5; }
+
+  /* conversation transcript */
+  .convo{ flex:1; overflow-y:auto; padding:18px 22px; display:flex; flex-direction:column; gap:14px;}
+  .convo::-webkit-scrollbar{width:7px} .convo::-webkit-scrollbar-thumb{background:rgba(185,147,63,.35);border-radius:4px}
+  .msg{ max-width:92%; font-size:14px; line-height:1.55; }
+  .msg.assist{ align-self:flex-start; }
+  .msg.assist .who{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--brass); margin-bottom:4px; }
+  .msg.assist .body{ background:#fff; border:1px solid rgba(185,147,63,.22); border-radius:3px 14px 14px 14px;
+    padding:11px 14px; color:var(--ink); box-shadow:0 2px 10px rgba(0,0,0,.06); }
+  .msg.you{ align-self:flex-end; }
+  .msg.you .body{ background:var(--oak-dark); color:var(--cream); border-radius:14px 3px 14px 14px;
+    padding:9px 14px; font-family:'Cormorant Garamond',serif; font-size:17px; }
+  .msg .body em{ color:var(--oak-dark); font-style:italic; }
+  .msg.you .body em{ color:var(--brass-lt); }
+
+  /* chip palette */
+  .chips-wrap{ padding:14px 20px 8px; border-top:1px solid rgba(185,147,63,.25); }
+  .chips-label{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--ink-soft); margin-bottom:10px; }
+  .chips{ display:flex; flex-wrap:wrap; gap:8px; }
+  .chip{
+    font-family:'Cormorant Garamond',serif; font-size:17px;
+    padding:9px 16px; border-radius:30px; cursor:pointer;
+    background:#fff; color:var(--ink);
+    border:1px solid rgba(185,147,63,.4);
+    transition:.18s; user-select:none; line-height:1;
+  }
+  .chip:hover{ background:var(--brass); color:#fff; border-color:var(--brass); transform:translateY(-1px); }
+  .chip:active{ transform:translateY(0); }
+  .chip .sw{ display:inline-block; width:11px; height:11px; border-radius:50%; margin-right:7px;
+    vertical-align:-1px; border:1px solid rgba(0,0,0,.15); }
+
+  /* text input bar */
+  .ask{ padding:16px 20px 20px; border-top:1px solid rgba(185,147,63,.25); }
+  .ask form{ display:flex; gap:8px; }
+  .ask input{
+    flex:1; font-family:'Cormorant Garamond',serif; font-size:18px;
+    padding:12px 15px; border-radius:30px; border:1px solid rgba(185,147,63,.45);
+    background:#fff; color:var(--ink); outline:none;
+  }
+  .ask input::placeholder{ color:#a99; font-style:italic; }
+  .ask input:focus{ border-color:var(--brass); box-shadow:0 0 0 3px rgba(185,147,63,.15); }
+  .ask button{ border:none; background:var(--oak-dark); color:var(--cream); cursor:pointer;
+    border-radius:50%; width:46px; height:46px; font-size:18px; flex:0 0 auto; transition:.18s; }
+  .ask button:hover{ background:var(--brass); }
+
+  /* ===== Boards gliding onto the table ===== */
+  .stage{ position:fixed; left:380px; right:0; top:0; bottom:0; z-index:10;
+    display:flex; align-items:center; justify-content:center; pointer-events:none; }
+  .boards{
+    pointer-events:auto;
+    display:flex; gap:30px; flex-wrap:wrap; justify-content:center; align-content:center;
+    max-width:1100px; max-height:88vh; overflow-y:auto; padding:40px 30px 20px;
+    perspective:1200px;
+  }
+  .boards::-webkit-scrollbar{width:8px} .boards::-webkit-scrollbar-thumb{background:rgba(201,169,110,.4);border-radius:4px}
+
+  .board{
+    width:210px; flex:0 0 auto;
+    transform-origin:50% 100%;
+    animation:glide .7s cubic-bezier(.18,.8,.28,1) backwards;
+    cursor:pointer;
+  }
+  @keyframes glide{
+    0%{ opacity:0; transform:translateY(70px) rotateX(28deg) scale(.86); }
+    100%{ opacity:1; transform:translateY(0) rotateX(0) scale(1); }
+  }
+  /* brass-framed sample board with gallery placard */
+  .board .frame{
+    position:relative; border-radius:4px;
+    padding:9px; background:linear-gradient(155deg,#d8c79c,var(--brass) 55%,#7e6526);
+    box-shadow:0 22px 44px rgba(0,0,0,.5), 0 2px 0 rgba(255,255,255,.3) inset;
+    transition:transform .35s cubic-bezier(.2,.7,.3,1), box-shadow .35s;
+  }
+  .board:hover .frame{ transform:translateY(-10px) rotateX(-4deg); box-shadow:0 34px 60px rgba(0,0,0,.6); }
+  .board .swatch{
+    width:100%; aspect-ratio:1/1; border-radius:2px; object-fit:cover;
+    background:var(--stone); display:block; box-shadow:0 0 0 1px rgba(0,0,0,.25) inset;
+  }
+  /* engraved-look placard */
+  .placard{ margin-top:9px; background:linear-gradient(180deg,#23201a,#171410);
+    border:1px solid var(--brass); border-radius:3px; padding:9px 11px 10px;
+    box-shadow:0 5px 14px rgba(0,0,0,.4); }
+  .placard .pname{ font-family:'Cormorant Garamond',serif; font-size:16px; color:var(--cream);
+    line-height:1.15; }
+  .placard .pmeta{ font-size:10px; letter-spacing:1.4px; text-transform:uppercase; color:var(--brass-lt);
+    margin-top:4px; display:flex; gap:6px; align-items:center; }
+  .placard .pmeta .dot{ width:9px;height:9px;border-radius:50%;border:1px solid rgba(255,255,255,.3); }
+  .placard a{ color:var(--brass-lt); text-decoration:none; font-size:10px; letter-spacing:1px;
+    text-transform:uppercase; display:inline-block; margin-top:7px; border-bottom:1px solid rgba(201,169,110,.4); }
+  .placard a:hover{ color:#fff; }
+
+  /* empty / welcome state floating over the table */
+  .welcome{ position:absolute; left:50%; top:34%; transform:translateX(-50%);
+    text-align:center; color:var(--cream); max-width:420px; pointer-events:none; }
+  .welcome .wm{ font-family:'Cormorant Garamond',serif; font-size:34px; font-weight:500; line-height:1.2;
+    text-shadow:0 4px 24px rgba(0,0,0,.6); }
+  .welcome .wm em{ font-style:italic; color:var(--brass-lt); }
+  .welcome .sub{ font-size:13px; letter-spacing:.4px; margin-top:12px; opacity:.78; line-height:1.6; }
+
+  /* result count ribbon */
+  .ribbon{ position:fixed; top:20px; right:30px; z-index:15;
+    background:rgba(28,28,34,.82); color:var(--cream); border:1px solid rgba(201,169,110,.4);
+    border-radius:30px; padding:8px 18px; font-size:11px; letter-spacing:2px; text-transform:uppercase;
+    backdrop-filter:blur(8px); display:none; }
+  .ribbon b{ color:var(--brass-lt); font-weight:500; }
+
+  @media (max-width:920px){
+    .concierge{ width:300px; } .stage{ left:300px; }
+    .board{ width:160px; }
+  }
+</style>
+</head>
+<body>
+  <!-- POV room -->
+  <div class="room">
+    <div class="table-zone">
+      <div class="backwall"></div>
+      <div class="rail"></div>
+      <div class="table"></div>
+    </div>
+  </div>
+
+  <div class="ribbon" id="ribbon"></div>
+
+  <!-- Boards stage -->
+  <div class="stage">
+    <div class="welcome" id="welcome">
+      <div class="wm">Take a seat at the <em>consultation table.</em></div>
+      <div class="sub">Tell me what you're after — a colour, a feeling, a pattern you already love —
+        and I'll pull the boards for you, one at a time, right here in front of you.</div>
+    </div>
+    <div class="boards" id="boards"></div>
+  </div>
+
+  <!-- Concierge assist panel -->
+  <aside class="concierge">
+    <div class="c-head">
+      <div class="eyebrow">The Quadrille House</div>
+      <div class="wordmark">Concierge <em>Nook</em></div>
+      <div class="seat">Your private appointment. I'm pulling from the China&nbsp;Seas atelier —
+        just say the word.</div>
+    </div>
+
+    <div class="convo" id="convo"></div>
+
+    <div class="chips-wrap">
+      <div class="chips-label">A few things people often ask for</div>
+      <div class="chips" id="chips"></div>
+    </div>
+
+    <div class="ask">
+      <form id="askForm" autocomplete="off">
+        <input id="askInput" type="text" placeholder="e.g. show me blues… or “like Aga but darker”" aria-label="Ask the concierge">
+        <button type="submit" title="Ask">→</button>
+      </form>
+    </div>
+  </aside>
+
+<script>
+/* ============================================================
+   CONCIERGE NOOK — client-side matching engine (no LLM)
+   Color/hue/bucket fields are null in the feed, so all signal
+   is derived from pattern_name + collection text.
+   ============================================================ */
+/* Relative path so it's same-origin whether served behind the proto proxy
+   (proto/proxy-server.cjs :7699 → backend :7690) or later from the app's public/.
+   Falls back to the absolute backend URL if same-origin fetch fails. */
+const API = '/api/showroom/products?limit=200';
+const API_FALLBACK = 'http://127.0.0.1:7690/api/showroom/products?limit=200';
+let PRODUCTS = [];
+
+/* ---- Color lexicon: word -> {bucket, hex (for the chip swatch)} ---- */
+const COLOR_WORDS = {
+  // blues
+  navy:['blue','#1f2d52'], blue:['blue','#3a5fa0'], blues:['blue','#3a5fa0'],
+  aqua:['blue','#5fb8c4'], turquoise:['blue','#2fb5b0'], capri:['blue','#3aa0c8'],
+  // greens
+  green:['green','#4f7a3a'], greens:['green','#4f7a3a'], jungle:['green','#2f5d33'],
+  apple:['green','#7aa340'], lime:['green','#9bc23a'], pistachio:['green','#bcd49a'],
+  // warm / neutrals
+  cream:['neutral','#efe7d2'], white:['neutral','#f3eee2'], 'off-white':['neutral','#ece5d4'],
+  beige:['neutral','#d8ccb0'], gold:['warm','#c9a44a'], metallic:['warm','#c9b072'],
+  cognac:['warm','#9a5a2c'], brown:['warm','#6f4a2c'], burnt:['warm','#8a4326'],
+  shrimp:['warm','#e08e72'], salmon:['warm','#e89274'], coral:['warm','#e26d52'],
+  orange:['warm','#d2752c'], yellow:['warm','#e0bb46'],
+  // reds / pinks / purples
+  red:['red','#a4322b'], reds:['red','#a4322b'], watermelon:['red','#c8455a'],
+  magenta:['purple','#a63072'], pink:['pink','#dd86a4'], lilac:['purple','#b79ec8'],
+  purple:['purple','#6b4a8a'], plum:['purple','#5a2f52'],
+  // dark / black
+  black:['dark','#1c1a16'], charcoal:['dark','#2b2926']
+};
+
+/* ---- Style / pattern keywords (matched against pattern_name) ---- */
+const STYLE_WORDS = {
+  stripe:['stripe','striped','bali','batik'],
+  trellis:['trellis','diamond','lattice'],
+  floral:['floral','flower','bouquet','arbre','rivage'],
+  bird:['bird','birds','aviary'],
+  geometric:['geometric','diamond','batik','isle']
+};
+
+/* ---- bucket -> warm description for the concierge to speak ---- */
+const BUCKET_PHRASE = {
+  blue:'cool blues — from soft aqua to deep navy',
+  green:'fresh greens — jungle, apple, pistachio',
+  warm:'warm neutrals and earthy tones',
+  neutral:'quiet creams and whites',
+  red:'rich reds and watermelons',
+  pink:'soft pinks',
+  purple:'purples and lilacs',
+  dark:'darker, more dramatic grounds'
+};
+
+/* ---- family = first phrase of pattern_name (before " on ") ---- */
+function familyOf(p){
+  const base = (p.pattern_name||'').split(/ on /i)[0];
+  // family root = first 1–2 words (e.g. "Aga", "Bali Hai", "Arbre de Matisse")
+  return base.replace(/\s*(screen printed|reverse|new).*/i,'').trim();
+}
+function familyRoot(p){ return (familyOf(p).split(/\s+/)[0]||'').toLowerCase(); }
+
+/* lightness heuristic from ground/color words (for "darker"/"lighter") */
+function lightness(p){
+  const n=(p.pattern_name||'').toLowerCase();
+  let score=0.5;
+  if(/white|cream|almost white|off white|pale|soft|light|pistachio|lilac/.test(n)) score+=0.32;
+  if(/navy|black|charcoal|jungle|brown|burnt|cognac|plum|dark|deep/.test(n)) score-=0.34;
+  if(/aqua|apple|lime|pink|shrimp|gold|yellow|salmon/.test(n)) score+=0.1;
+  return Math.max(0,Math.min(1,score));
+}
+
+/* ---- normalize a query into match intent ---- */
+function tokenize(q){ return q.toLowerCase().replace(/[^a-z' ]/g,' ').split(/\s+/).filter(Boolean); }
+
+function interpret(query){
+  const toks = tokenize(query);
+  const intent = { colors:new Set(), buckets:new Set(), styles:new Set(),
+                   families:new Set(), darker:false, lighter:false, raw:query };
+  // direction words
+  if(toks.some(t=>/dark|deep|moody|richer|bolder/.test(t))) intent.darker=true;
+  if(toks.some(t=>/light|pale|soft|airy|brighter|paler/.test(t))) intent.lighter=true;
+
+  // color & bucket words
+  for(const t of toks){
+    if(COLOR_WORDS[t]){ intent.colors.add(t); intent.buckets.add(COLOR_WORDS[t][0]); }
+    if(t==='neutral'||t==='neutrals') intent.buckets.add('neutral').add('warm');
+    if(t==='warm') intent.buckets.add('warm');
+    if(t==='cool') intent.buckets.add('blue');
+  }
+  // style words (tolerate plurals: "stripes"->"stripe", "florals"->"floral")
+  const stem=t=>t.replace(/s$/,'');
+  for(const [style,words] of Object.entries(STYLE_WORDS)){
+    const want=new Set([style,...words].map(stem));
+    if(toks.some(t=>want.has(stem(t)))) intent.styles.add(style);
+  }
+  // "like X" family references — match any token against known family roots
+  const famRoots = new Set(PRODUCTS.map(familyRoot));
+  for(const t of toks){ if(famRoots.has(t)) intent.families.add(t); }
+
+  return intent;
+}
+
+/* ---- score a product against an intent ---- */
+function scoreProduct(p, intent){
+  const n=(p.pattern_name||'').toLowerCase();
+  let s=0, hits=0;
+  // color words present in name
+  for(const c of intent.colors){ if(n.includes(c)){ s+=6; hits++; } }
+  // bucket: any color word in name that maps to a wanted bucket
+  if(intent.buckets.size){
+    for(const [w,[bk]] of Object.entries(COLOR_WORDS)){
+      if(intent.buckets.has(bk) && n.includes(w)){ s+=3; hits++; }
+    }
+  }
+  // style
+  for(const st of intent.styles){
+    if(STYLE_WORDS[st].some(w=>n.includes(w))){ s+=4; hits++; }
+  }
+  // family ("like Aga")
+  if(intent.families.size){
+    const fr=familyRoot(p);
+    if(intent.families.has(fr)){ s+=5; hits++; }
+  }
+  if(hits===0) return -1; // no positive signal at all -> exclude
+  // darker/lighter nudge
+  const L=lightness(p);
+  if(intent.darker) s += (1-L)*5;
+  if(intent.lighter) s += L*5;
+  // "like X but darker": family match + direction => big boost when both
+  if(intent.families.size && (intent.darker||intent.lighter)) s+=2;
+  return s;
+}
+
+/* ---- run a query: return sorted matches + a spoken concierge line ---- */
+function runQuery(query){
+  const intent = interpret(query);
+  let scored = PRODUCTS.map(p=>({p,score:scoreProduct(p,intent)}))
+                       .filter(x=>x.score>=0)
+                       .sort((a,b)=>b.score-a.score);
+
+  // If query was a "like family but darker" and family match yielded few, broaden to bucket of that family
+  let results = scored.map(x=>x.p);
+
+  // Fallback: if nothing matched but they typed *something*, do a loose substring across name
+  if(!results.length){
+    const toks=tokenize(query);
+    results = PRODUCTS.filter(p=>{const n=(p.pattern_name||'').toLowerCase();return toks.some(t=>t.length>2&&n.includes(t));});
+  }
+  results = results.slice(0,24);
+
+  return { results, line: concierge(query,intent,results) };
+}
+
+/* ---- concierge's warm spoken response ---- */
+function concierge(query,intent,results){
+  if(!results.length){
+    return `Hm — I don't have anything quite like “${esc(query)}” on the floor today. Try a colour like <em>blues</em> or <em>warm neutrals</em>, or name a pattern such as <em>Aga</em> or <em>Bali Hai</em>.`;
+  }
+  const bits=[];
+  if(intent.families.size){
+    const fam=[...intent.families][0];
+    if(intent.darker) bits.push(`the <em>${cap(fam)}</em> family, leaning to the darker, moodier grounds`);
+    else if(intent.lighter) bits.push(`the <em>${cap(fam)}</em> family in its lighter, airier colourways`);
+    else bits.push(`everything in the <em>${cap(fam)}</em> family`);
+  } else if(intent.buckets.size){
+    const ph=[...intent.buckets].map(b=>BUCKET_PHRASE[b]).filter(Boolean)[0];
+    bits.push(ph?`some lovely <em>${ph}</em>`:`a few in that palette`);
+  } else if(intent.styles.size){
+    bits.push(`pieces with a <em>${[...intent.styles][0]}</em> feel`);
+  } else if(intent.darker) bits.push(`the darker, more dramatic boards`);
+  else if(intent.lighter) bits.push(`the softest, lightest grounds`);
+  else bits.push(`a curated handful for you`);
+
+  const n=results.length;
+  const lead=['Of course.','Lovely choice.','With pleasure.','Beautifully said.','Right this way.'][Math.floor(Math.random()*5)];
+  return `${lead} I'm bringing out ${bits.join(', ')} — ${n} board${n>1?'s':''} gliding onto the table now.`;
+}
+
+/* ---- render boards onto the table ---- */
+function presentBoards(results){
+  const wrap=document.getElementById('boards');
+  const welcome=document.getElementById('welcome');
+  const ribbon=document.getElementById('ribbon');
+  welcome.style.display = results.length ? 'none':'block';
+  ribbon.style.display = results.length ? 'block':'none';
+  ribbon.innerHTML = `<b>${results.length}</b> boards on the table`;
+  wrap.innerHTML='';
+  results.forEach((p,i)=>{
+    const fam=familyOf(p);
+    const ground=(p.pattern_name||'').split(/ on /i)[1]||'';
+    const dot=swatchHex(p);
+    const el=document.createElement('div');
+    el.className='board';
+    el.style.animationDelay=(i*70)+'ms';
+    el.innerHTML=`
+      <div class="frame">
+        <img class="swatch" loading="lazy" src="${p.image}" alt="${esc(p.pattern_name)}"
+             onerror="this.style.opacity=.4;this.alt='image unavailable'">
+      </div>
+      <div class="placard">
+        <div class="pname">${esc(fam)}</div>
+        <div class="pmeta"><span class="dot" style="background:${dot}"></span>${esc((ground||p.vendor||'China Seas').trim())}</div>
+        <a href="${p.store_url||'#'}" target="_blank" rel="noopener">View this design →</a>
+      </div>`;
+    wrap.appendChild(el);
+  });
+  wrap.scrollTop=0;
+}
+
+/* pick a representative swatch hex for a product from its color words */
+function swatchHex(p){
+  const n=(p.pattern_name||'').toLowerCase();
+  for(const [w,[,hex]] of Object.entries(COLOR_WORDS)){ if(n.includes(w)) return hex; }
+  return '#cfc7b8';
+}
+
+/* ---- transcript ---- */
+function addMsg(role,html){
+  const c=document.getElementById('convo');
+  const m=document.createElement('div'); m.className='msg '+role;
+  if(role==='assist') m.innerHTML=`<div class="who">Concierge</div><div class="body">${html}</div>`;
+  else m.innerHTML=`<div class="body">${html}</div>`;
+  c.appendChild(m); c.scrollTop=c.scrollHeight;
+}
+
+/* ---- handle an ask ---- */
+function ask(query){
+  query=(query||'').trim(); if(!query) return;
+  addMsg('you', esc(query));
+  // tiny "pulling boards" beat
+  setTimeout(()=>{
+    const {results,line}=runQuery(query);
+    addMsg('assist', line);
+    presentBoards(results);
+  }, 260);
+}
+
+/* ---- chips ---- */
+const CHIPS=[
+  {label:'Show me blues', q:'show me blues', c:'#3a5fa0'},
+  {label:'Fresh greens', q:'fresh greens', c:'#4f7a3a'},
+  {label:'Warm neutrals', q:'warm neutrals', c:'#d8ccb0'},
+  {label:'Something with stripes', q:'something with stripes', c:'#9a7a52'},
+  {label:'Soft & pale', q:'soft pale and light', c:'#efe7d2'},
+  {label:'Dark & dramatic', q:'dark and dramatic', c:'#2b2926'},
+  {label:'Like Aga, but darker', q:'like Aga but darker', c:'#2f5d33'},
+  {label:'Pinks & corals', q:'pink coral and shrimp', c:'#e08e72'},
+  {label:'Bali Hai', q:'Bali Hai', c:'#5fb8c4'}
+];
+function buildChips(){
+  const wrap=document.getElementById('chips');
+  CHIPS.forEach(ch=>{
+    const b=document.createElement('div'); b.className='chip';
+    b.innerHTML=`<span class="sw" style="background:${ch.c}"></span>${ch.label}`;
+    b.onclick=()=>ask(ch.q);
+    wrap.appendChild(b);
+  });
+}
+
+/* ---- utils ---- */
+function esc(s){return (s||'').replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));}
+function cap(s){return (s||'').charAt(0).toUpperCase()+(s||'').slice(1);}
+
+/* ---- boot ---- */
+async function boot(){
+  buildChips();
+  addMsg('assist', `Welcome — make yourself comfortable. I'm your design concierge for the
+    <em>China Seas</em> atelier. Tell me a colour, a mood, or a pattern you love, and I'll pull the boards.`);
+  try{
+    let r;
+    try{ r=await fetch(API); if(!r.ok) throw new Error(r.status); }
+    catch(_){ r=await fetch(API_FALLBACK); }   // dev fallback when not behind the proxy
+    const d=await r.json();
+    PRODUCTS=(d.products||d).filter(p=>p&&p.image);
+    addMsg('assist', `I've ${PRODUCTS.length} boards ready behind me. Where shall we begin?`);
+  }catch(e){
+    addMsg('assist', `I'm having trouble reaching the sample room just now — please try again in a moment.`);
+    console.error('feed error',e);
+  }
+}
+
+document.getElementById('askForm').addEventListener('submit',e=>{
+  e.preventDefault();
+  const inp=document.getElementById('askInput');
+  ask(inp.value); inp.value='';
+});
+
+/* expose for verification harness */
+window.runQuery=runQuery; window.interpret=interpret;
+Object.defineProperty(window,'PRODUCTS',{get:()=>PRODUCTS});
+
+boot();
+</script>
+</body>
+</html>
diff --git a/proto/v6-colorriver.html b/proto/v6-colorriver.html
new file mode 100644
index 0000000..ff9225d
--- /dev/null
+++ b/proto/v6-colorriver.html
@@ -0,0 +1,547 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
+<title>COLOR RIVER · China Seas</title>
+<style>
+  :root { --ink:#0d0c0f; --paper:#f4f1ea; }
+  * { box-sizing:border-box; margin:0; padding:0; }
+  html,body { height:100%; overflow:hidden; background:#07060a; color:var(--paper);
+    font-family:"Helvetica Neue",Helvetica,Arial,sans-serif; -webkit-font-smoothing:antialiased; }
+  #app { position:fixed; inset:0; }
+  canvas { display:block; }
+
+  /* ---- chrome / overlay ---- */
+  .masthead { position:fixed; top:0; left:0; right:0; z-index:20; padding:22px 30px 40px;
+    pointer-events:none;
+    background:linear-gradient(180deg, rgba(7,6,10,.85) 0%, rgba(7,6,10,0) 100%); }
+  .masthead .kicker { font-size:11px; letter-spacing:.42em; text-transform:uppercase;
+    color:#bdb7c8; font-weight:600; }
+  .masthead h1 { font-size:clamp(28px,5vw,52px); font-weight:300; letter-spacing:.02em;
+    line-height:.96; margin-top:6px; }
+  .masthead h1 b { font-weight:700; }
+  .masthead .sub { margin-top:8px; font-size:12.5px; letter-spacing:.04em; color:#9b96a6;
+    max-width:520px; }
+
+  /* hue navigation rail */
+  #rail { position:fixed; left:0; right:0; bottom:0; z-index:20; height:64px;
+    display:flex; align-items:stretch; pointer-events:auto; cursor:pointer;
+    background:linear-gradient(0deg, rgba(7,6,10,.92), rgba(7,6,10,.35) 70%, transparent); }
+  #rail .band { flex:1; position:relative; }
+  #rail .tick { position:absolute; bottom:8px; left:50%; transform:translateX(-50%);
+    font-size:9.5px; letter-spacing:.18em; text-transform:uppercase; color:rgba(255,255,255,.62);
+    white-space:nowrap; font-weight:600; text-shadow:0 1px 3px rgba(0,0,0,.8); }
+  #railhandle { position:absolute; top:0; height:100%; width:3px; background:#fff;
+    box-shadow:0 0 16px 3px rgba(255,255,255,.7); pointer-events:none; transition:left .08s linear; }
+
+  .hint { position:fixed; bottom:74px; left:50%; transform:translateX(-50%); z-index:20;
+    font-size:11px; letter-spacing:.28em; text-transform:uppercase; color:rgba(255,255,255,.5);
+    pointer-events:none; transition:opacity .5s; }
+
+  /* loading */
+  #boot { position:fixed; inset:0; z-index:50; display:flex; flex-direction:column;
+    align-items:center; justify-content:center; background:#07060a; transition:opacity .8s; }
+  #boot .ring { width:46px; height:46px; border-radius:50%;
+    border:2px solid rgba(255,255,255,.15); border-top-color:#fff; animation:spin 1s linear infinite; }
+  #boot .lbl { margin-top:18px; font-size:11px; letter-spacing:.34em; text-transform:uppercase; color:#8c8796; }
+  @keyframes spin { to { transform:rotate(360deg); } }
+
+  /* focus detail card */
+  #detail { position:fixed; z-index:30; right:34px; top:50%; transform:translateY(-50%) translateX(40px);
+    width:min(340px,40vw); background:rgba(15,13,18,.74); backdrop-filter:blur(18px);
+    -webkit-backdrop-filter:blur(18px); border:1px solid rgba(255,255,255,.1);
+    border-radius:4px; padding:24px 24px 26px; opacity:0; pointer-events:none;
+    transition:opacity .45s ease, transform .45s cubic-bezier(.2,.8,.2,1); }
+  #detail.show { opacity:1; transform:translateY(-50%) translateX(0); pointer-events:auto; }
+  #detail .swatchchip { width:38px; height:38px; border-radius:50%; border:1px solid rgba(255,255,255,.2);
+    margin-bottom:14px; box-shadow:0 4px 18px rgba(0,0,0,.5); }
+  #detail .pname { font-size:21px; font-weight:600; line-height:1.12; letter-spacing:.01em; }
+  #detail .pcollection { margin-top:4px; font-size:11px; letter-spacing:.26em; text-transform:uppercase; color:#a7a1b3; }
+  #detail .specrow { display:flex; justify-content:space-between; padding:9px 0;
+    border-bottom:1px solid rgba(255,255,255,.08); font-size:12.5px; }
+  #detail .specrow:first-of-type { margin-top:16px; border-top:1px solid rgba(255,255,255,.08); }
+  #detail .specrow .k { color:#8e8898; letter-spacing:.04em; }
+  #detail .specrow .v { color:#efece5; text-align:right; }
+  #detail a.cta { display:block; margin-top:18px; text-align:center; padding:12px;
+    background:var(--paper); color:#0d0c0f; font-size:11px; letter-spacing:.22em; text-transform:uppercase;
+    font-weight:700; text-decoration:none; border-radius:2px; transition:transform .15s, background .15s; }
+  #detail a.cta:hover { transform:translateY(-1px); background:#fff; }
+  #detail .closex { position:absolute; top:12px; right:14px; font-size:18px; color:#9b96a6;
+    cursor:pointer; line-height:1; }
+  #detail .closex:hover { color:#fff; }
+
+  @media (max-width:720px){
+    #detail { right:14px; left:14px; width:auto; top:auto; bottom:84px; transform:translateY(20px); }
+    #detail.show { transform:translateY(0); }
+    .masthead .sub { display:none; }
+  }
+</style>
+</head>
+<body>
+<div id="app"></div>
+
+<div class="masthead">
+  <div class="kicker">Designer Wallcoverings · Shop by Color</div>
+  <h1>COLOR <b>RIVER</b></h1>
+  <div class="sub">Every China Seas pattern set adrift on a single current of hue — from warm corals through
+    jungle greens into deep indigos. Scroll or drag to travel downstream. Tap a swatch to surface it.</div>
+</div>
+
+<div id="rail" title="Jump to a hue"></div>
+<div id="railhandle"></div>
+<div class="hint">scroll · drag · click a swatch</div>
+
+<div id="detail">
+  <div class="closex">&times;</div>
+  <div class="swatchchip" id="d_chip"></div>
+  <div class="pname" id="d_name">—</div>
+  <div class="pcollection" id="d_coll">China Seas</div>
+  <div class="specrow"><span class="k">Dimensions</span><span class="v" id="d_dim">27" × 27"</span></div>
+  <div class="specrow"><span class="k">Repeat</span><span class="v" id="d_rep">—</span></div>
+  <div class="specrow"><span class="k">Match</span><span class="v" id="d_match">—</span></div>
+  <div class="specrow"><span class="k">Finish</span><span class="v" id="d_finish">—</span></div>
+  <div class="specrow"><span class="k">Material</span><span class="v" id="d_mat">—</span></div>
+  <a class="cta" id="d_cta" href="#" target="_blank" rel="noopener noreferrer">View Pattern →</a>
+</div>
+
+<div id="boot"><div class="ring"></div><div class="lbl" id="bootlbl">Gathering the current…</div></div>
+
+<script src="./three.min.js"></script>
+<script>
+"use strict";
+(function () {
+  const API = "/api/showroom/products?limit=120";
+  // ---- helpers -----------------------------------------------------------
+  const TAU = Math.PI * 2;
+  const clamp = (v,a,b)=>Math.max(a,Math.min(b,v));
+  const lerp = (a,b,t)=>a+(b-a)*t;
+
+  // rgb -> hsl, returns [h(0..1), s(0..1), l(0..1)]
+  function rgb2hsl(r,g,b){
+    r/=255; g/=255; b/=255;
+    const mx=Math.max(r,g,b), mn=Math.min(r,g,b); let h=0,s=0; const l=(mx+mn)/2;
+    if(mx!==mn){ const d=mx-mn; s=l>0.5?d/(2-mx-mn):d/(mx+mn);
+      switch(mx){ case r:h=(g-b)/d+(g<b?6:0);break; case g:h=(b-r)/d+2;break; default:h=(r-g)/d+4; }
+      h/=6; }
+    return [h,s,l];
+  }
+  function hsl2css(h,s,l){
+    // h 0..1 -> css hsl string
+    return `hsl(${(h*360).toFixed(0)} ${(s*100).toFixed(0)}% ${(l*100).toFixed(0)}%)`;
+  }
+
+  // ---- extract a representative hue from an image ------------------------
+  // Strategy: downscale to 24x24, bin pixels into hue buckets weighted by
+  // saturation (so neutral pinstripe grounds don't dominate). The "color" of a
+  // China Seas pattern is its INK, not its near-white paper ground.
+  const huecanvas = document.createElement("canvas");
+  huecanvas.width = huecanvas.height = 24;
+  const hctx = huecanvas.getContext("2d", { willReadFrequently:true });
+
+  function analyzeImage(img){
+    try {
+      hctx.clearRect(0,0,24,24);
+      hctx.drawImage(img,0,0,24,24);
+      const data = hctx.getImageData(0,0,24,24).data;
+      const BINS = 36;
+      const hueWeight = new Float64Array(BINS);
+      const hueSatSum = new Float64Array(BINS);
+      const hueLightSum = new Float64Array(BINS);
+      let satWeightTotal = 0, lAcc = 0, n = 0, neutralL = 0, neutralW = 0;
+      for(let i=0;i<data.length;i+=4){
+        const r=data[i],g=data[i+1],b=data[i+2];
+        const [h,s,l]=rgb2hsl(r,g,b);
+        n++; lAcc += l;
+        if(s < 0.12){ neutralL += l; neutralW++; continue; } // skip near-neutral for hue
+        // weight chromatic pixels by saturation, de-emphasise the near-white ground
+        const w = s * (1 - Math.abs(l-0.5)*0.7);
+        const bin = Math.min(BINS-1, Math.floor(h*BINS));
+        hueWeight[bin] += w;
+        hueSatSum[bin] += s*w;
+        hueLightSum[bin] += l*w;
+        satWeightTotal += w;
+      }
+      // pick dominant chromatic hue bin
+      let best=-1, bestW=0;
+      for(let k=0;k<BINS;k++){ if(hueWeight[k]>bestW){ bestW=hueWeight[k]; best=k; } }
+      const avgL = n? lAcc/n : 0.6;
+      if(best<0 || satWeightTotal < 0.02){
+        // genuinely neutral pattern (greys / black & white). Park it as low-sat,
+        // hue mapped from lightness so neutrals form their own greyscale eddy at the river's tail.
+        const nl = neutralW? neutralL/neutralW : avgL;
+        return { hue: 0, sat: 0.0, light: nl, neutral:true };
+      }
+      const hue = (best + 0.5)/BINS;            // bin centre
+      const sat = clamp(hueSatSum[best]/bestW, 0, 1);
+      const light = clamp(hueLightSum[best]/bestW, 0, 1);
+      return { hue, sat, light, neutral:false };
+    } catch(e){
+      return { hue: 0, sat: 0, light: 0.6, neutral:true };
+    }
+  }
+
+  // ---- THREE scene -------------------------------------------------------
+  const app = document.getElementById("app");
+  const W = ()=>window.innerWidth, H = ()=>window.innerHeight;
+
+  const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:false });
+  renderer.setPixelRatio(Math.min(window.devicePixelRatio||1, 2));
+  renderer.setSize(W(), H());
+  renderer.setClearColor(0x07060a, 1);
+  app.appendChild(renderer.domElement);
+
+  const scene = new THREE.Scene();
+  scene.fog = new THREE.FogExp2(0x07060a, 0.018);
+
+  const camera = new THREE.PerspectiveCamera(52, W()/H(), 0.1, 400);
+  camera.position.set(0, 0.4, 18);
+
+  scene.add(new THREE.AmbientLight(0xffffff, 0.92));
+  const key = new THREE.DirectionalLight(0xffffff, 0.55); key.position.set(4,8,12); scene.add(key);
+
+  // --- the riverbed: a long horizontal gradient plane spanning the full spectrum ---
+  const RIVER_LEN = 132;          // world units the ribbon spans in X (tighter = denser current)
+  const X0 = -RIVER_LEN/2;
+  function hueToX(h){ return X0 + h*RIVER_LEN; }
+  // undulation of the current — bigger amplitude so the flow visibly courses
+  function flowY(h){ return Math.sin(h*TAU*2.4)*3.6 + Math.sin(h*TAU*5.1+1.3)*1.5; }
+
+  (function buildRiverbed(){
+    const seg = 160;
+    const geo = new THREE.PlaneGeometry(RIVER_LEN+30, 22, seg, 1);
+    const cols = [];
+    const pos = geo.attributes.position;
+    const col = new THREE.Color();
+    for(let i=0;i<pos.count;i++){
+      const x = pos.getX(i);
+      const t = clamp((x - X0)/RIVER_LEN, 0, 1);
+      const yTop = pos.getY(i) > 0;
+      // riverbed glows the spectrum hue, darker top/bottom for depth
+      col.setHSL(t, 0.55, yTop?0.05:0.14);
+      cols.push(col.r,col.g,col.b);
+    }
+    geo.setAttribute("color", new THREE.Float32BufferAttribute(cols,3));
+    const mat = new THREE.MeshBasicMaterial({ vertexColors:true });
+    const mesh = new THREE.Mesh(geo, mat);
+    mesh.position.set(0, 0, -8);
+    scene.add(mesh);
+
+    // a brighter thin "waterline" gradient strip behind the swatches
+    const geo2 = new THREE.PlaneGeometry(RIVER_LEN+30, 7.5, seg, 1);
+    const cols2=[];
+    const p2=geo2.attributes.position;
+    for(let i=0;i<p2.count;i++){
+      const x=p2.getX(i); const t=clamp((x-X0)/RIVER_LEN,0,1);
+      col.setHSL(t,0.7,0.42); cols2.push(col.r,col.g,col.b);
+    }
+    geo2.setAttribute("color", new THREE.Float32BufferAttribute(cols2,3));
+    const m2 = new THREE.Mesh(geo2, new THREE.MeshBasicMaterial({vertexColors:true, transparent:true, opacity:0.5}));
+    m2.position.set(0,0,-5.5);
+    scene.add(m2);
+  })();
+
+  // group that holds all swatches and pans in X
+  const flow = new THREE.Group();
+  scene.add(flow);
+
+  const swatchGeo = new THREE.PlaneGeometry(1,1);
+  const loader = new THREE.TextureLoader();
+  loader.crossOrigin = "anonymous";
+
+  const swatches = [];   // { mesh, base{x,y,z,scale}, data, hue }
+  let focused = null;
+
+  // raycast picking
+  const ray = new THREE.Raycaster();
+  const ndc = new THREE.Vector2();
+  const pickables = [];
+
+  // ---- build a swatch mesh ----
+  function addSwatch(d, analysis, tex){
+    const { hue, sat, light, neutral } = analysis;
+    // X by hue; neutrals pushed to the far warm end as a greyscale eddy
+    const hpos = neutral ? 0.985 : hue;
+    const x = hueToX(hpos) + (Math.random()-0.5)*1.3;     // jitter so equal hues don't z-fight
+    const baseY = flowY(hpos);
+    // saturation lifts the swatch up onto the crest; lightness pushes depth
+    const y = baseY + (sat-0.4)*2.6 + (Math.random()-0.5)*1.1;
+    const z = (light-0.5)*3.2 + (Math.random()-0.5)*1.4;
+    const scale = lerp(1.7, 2.7, sat) ;                  // punchier hues bigger
+
+    const mat = new THREE.MeshBasicMaterial({ map:tex, toneMapped:false });
+    const mesh = new THREE.Mesh(swatchGeo, mat);
+    mesh.position.set(x, y, z);
+    mesh.scale.setScalar(scale);
+    mesh.userData.idx = swatches.length;
+    flow.add(mesh);
+    pickables.push(mesh);
+
+    swatches.push({ mesh, base:{x,y,z,scale}, data:d, hue:hpos, sat, light });
+  }
+
+  // ---- data load + texture pipeline -------------------------------------
+  const bootlbl = document.getElementById("bootlbl");
+  let loadedCount = 0, totalCount = 0;
+
+  function imgURL(u){
+    // CDN sends ACAO:* so direct load works & is canvas-readable; fall back to proxy for non-cdn.
+    if(/cdn\.shopify\.com/.test(u)) return u;
+    return "/api/proxy/image?url=" + encodeURIComponent(u);
+  }
+
+  function loadOne(d){
+    return new Promise((resolve)=>{
+      const url = imgURL(d.image);
+      const img = new Image();
+      img.crossOrigin = "anonymous";
+      img.onload = ()=>{
+        const analysis = analyzeImage(img);
+        const tex = new THREE.Texture(img);
+        tex.colorSpace = THREE.SRGBColorSpace || undefined;
+        tex.needsUpdate = true;
+        tex.anisotropy = 4;
+        addSwatch(d, analysis, tex);
+        loadedCount++;
+        bootlbl.textContent = `Sorting ${loadedCount} / ${totalCount} swatches by hue…`;
+        resolve();
+      };
+      img.onerror = ()=>{ loadedCount++; resolve(); };
+      img.src = url;
+    });
+  }
+
+  async function start(){
+    let products = [];
+    try {
+      const res = await fetch(API);
+      const json = await res.json();
+      products = json.products || [];
+    } catch(e){
+      bootlbl.textContent = "Could not reach the catalog.";
+      console.error("fetch failed", e);
+      return;
+    }
+    totalCount = products.length;
+    // load with limited concurrency so we don't stall the main thread
+    const POOL = 8;
+    let cursor = 0;
+    async function worker(){
+      while(cursor < products.length){
+        const d = products[cursor++];
+        await loadOne(d);
+      }
+    }
+    await Promise.all(Array.from({length:POOL}, worker));
+
+    // sort swatches array by hue so rail navigation maps cleanly
+    swatches.sort((a,b)=>a.hue - b.hue);
+
+    // open the river at its DENSEST stretch so the first frame is full of color,
+    // not a half-empty warm head. Sliding window over hue density.
+    if(swatches.length){
+      const win = 0.09;             // ~10% of the spectrum visible at once
+      let bestH = swatches[Math.floor(swatches.length/2)].hue, bestN = 0;
+      for(const s of swatches){
+        let n=0; for(const o of swatches){ if(Math.abs(o.hue - s.hue) <= win) n++; }
+        if(n>bestN){ bestN=n; bestH=s.hue; }
+      }
+      pan = targetPan = clamp(-hueToX(bestH), PAN_MIN, PAN_MAX);
+    }
+    window.__RIVER_DONE = true;
+
+    finishBoot();
+  }
+
+  function finishBoot(){
+    const boot = document.getElementById("boot");
+    boot.style.opacity = "0";
+    setTimeout(()=>boot.remove(), 850);
+    buildRail();
+  }
+
+  // ---- hue rail (navigation) --------------------------------------------
+  const HUE_BANDS = [
+    [0.00,"Coral"],[0.06,"Terracotta"],[0.12,"Gold"],[0.22,"Citron"],
+    [0.30,"Jungle"],[0.42,"Viridian"],[0.50,"Teal"],[0.58,"Sky"],
+    [0.66,"Indigo"],[0.74,"Violet"],[0.82,"Plum"],[0.92,"Magenta"]
+  ];
+  function buildRail(){
+    const rail = document.getElementById("rail");
+    rail.innerHTML = "";
+    HUE_BANDS.forEach(([h,name],i)=>{
+      const band = document.createElement("div");
+      band.className = "band";
+      const c1 = hsl2css(h,0.65,0.42), c2 = hsl2css((HUE_BANDS[i+1]?HUE_BANDS[i+1][0]:1),0.65,0.42);
+      band.style.background = `linear-gradient(90deg, ${c1}, ${c2})`;
+      const tk = document.createElement("div"); tk.className="tick"; tk.textContent=name;
+      band.appendChild(tk); rail.appendChild(band);
+    });
+    rail.addEventListener("pointerdown", e=>{
+      const r = rail.getBoundingClientRect();
+      const t = clamp((e.clientX - r.left)/r.width, 0, 1);
+      targetPan = -hueToX(t);   // center that hue
+    });
+  }
+
+  // ---- camera pan / travel ----------------------------------------------
+  // We pan the flow group in X. pan ranges so first/last swatch stay reachable.
+  let pan = 0, targetPan = -hueToX(0.0);   // start at the warm head of the river
+  const PAN_MIN = -hueToX(1.0) , PAN_MAX = -hueToX(0.0);
+  function clampPan(p){ return clamp(p, PAN_MIN, PAN_MAX); }
+
+  // wheel
+  window.addEventListener("wheel", (e)=>{
+    e.preventDefault();
+    const dom = (Math.abs(e.deltaX) > Math.abs(e.deltaY)) ? e.deltaX : e.deltaY;
+    targetPan = clampPan(targetPan - dom*0.045);
+    if(focused) defocus();
+  }, { passive:false });
+
+  // drag
+  let dragging=false, dragStartX=0, panStart=0, moved=0;
+  renderer.domElement.addEventListener("pointerdown",(e)=>{
+    dragging=true; moved=0; dragStartX=e.clientX; panStart=targetPan;
+    renderer.domElement.setPointerCapture(e.pointerId);
+  });
+  renderer.domElement.addEventListener("pointermove",(e)=>{
+    if(!dragging) return;
+    const dx = e.clientX - dragStartX; moved += Math.abs(dx);
+    targetPan = clampPan(panStart + dx*0.06);
+  });
+  renderer.domElement.addEventListener("pointerup",(e)=>{
+    dragging=false;
+    if(moved < 6){ tryPick(e); }   // treat as click
+  });
+
+  // touch fallback handled by pointer events above
+
+  // ---- picking / focus ---------------------------------------------------
+  function tryPick(e){
+    const r = renderer.domElement.getBoundingClientRect();
+    ndc.x = ((e.clientX-r.left)/r.width)*2 - 1;
+    ndc.y = -((e.clientY-r.top)/r.height)*2 + 1;
+    ray.setFromCamera(ndc, camera);
+    const hits = ray.intersectObjects(pickables, false);
+    if(hits.length){
+      const mesh = hits[0].object;
+      const sw = swatches.find(s=>s.mesh===mesh);
+      if(sw) focus(sw);
+    } else if(focused){ defocus(); }
+  }
+
+  function focus(sw){
+    focused = sw;
+    // bring its hue to center
+    targetPan = clampPan(-sw.base.x);
+    showDetail(sw);
+  }
+  function defocus(){
+    focused = null;
+    hideDetail();
+  }
+
+  // detail card
+  const detail = document.getElementById("detail");
+  document.querySelector("#detail .closex").addEventListener("click", defocus);
+  function showDetail(sw){
+    const d = sw.data;
+    document.getElementById("d_name").textContent = d.pattern_name || d.title || "Untitled";
+    document.getElementById("d_coll").textContent = (d.collection || d.vendor || "China Seas");
+    const w = d.width||27;
+    document.getElementById("d_dim").textContent = `${w}" × ${w}"`;
+    document.getElementById("d_rep").textContent = d.repeat ? `${d.repeat}"` : "—";
+    document.getElementById("d_match").textContent = d.match_type || "—";
+    document.getElementById("d_finish").textContent = d.finish || "—";
+    document.getElementById("d_mat").textContent = d.material || "—";
+    const chip = document.getElementById("d_chip");
+    chip.style.background = sw.sat>0.02 ? hsl2css(sw.hue,sw.sat,sw.light) : hsl2css(0,0,sw.light||0.5);
+    const cta = document.getElementById("d_cta");
+    if(d.store_url){ cta.href = d.store_url; cta.style.display="block"; }
+    else cta.style.display="none";
+    detail.classList.add("show");
+  }
+  function hideDetail(){ detail.classList.remove("show"); }
+
+  // ---- resize ------------------------------------------------------------
+  window.addEventListener("resize", ()=>{
+    camera.aspect = W()/H(); camera.updateProjectionMatrix();
+    renderer.setSize(W(), H());
+  });
+
+  // ---- render loop -------------------------------------------------------
+  const railhandle = document.getElementById("railhandle");
+  const hint = document.querySelector(".hint");
+  let hintFaded = false;
+  let t0 = performance.now();
+
+  function tick(now){
+    const dt = Math.min((now - t0)/1000, 0.05); t0 = now;
+    pan += (targetPan - pan) * Math.min(1, dt*6.5);
+    flow.position.x = pan;
+
+    // gentle drift of the whole current so it feels alive
+    const breathe = Math.sin(now*0.0004)*0.15;
+    flow.position.y = breathe;
+
+    // billboard + focus animation
+    for(const sw of swatches){
+      const m = sw.mesh;
+      m.lookAt(camera.position.x, camera.position.y, m.position.z + 10); // face camera (yaw only-ish)
+      m.rotation.x = 0; // keep upright
+      let targetScale = sw.base.scale;
+      let tz = sw.base.z, ty = sw.base.y;
+      if(sw === focused){
+        targetScale = 6.4;
+        tz = sw.base.z + 9.5;      // float toward camera
+        ty = sw.base.y*0.3 + 0.6;
+      }
+      m.scale.x += (targetScale - m.scale.x)*Math.min(1,dt*8);
+      m.scale.y = m.scale.x;
+      m.position.z += (tz - m.position.z)*Math.min(1,dt*8);
+      m.position.y += (ty - m.position.y)*Math.min(1,dt*8);
+      // dim non-focused when something is focused
+      const wantOp = (focused && sw!==focused) ? 0.28 : 1.0;
+      if(m.material.opacity===undefined) m.material.opacity=1;
+      m.material.transparent = wantOp<1;
+      m.material.opacity += (wantOp - m.material.opacity)*Math.min(1,dt*8);
+    }
+
+    // rail handle position = current center hue
+    const centerHue = clamp((-pan - X0)/RIVER_LEN, 0, 1);
+    railhandle.style.left = (centerHue*100).toFixed(2)+"%";
+
+    if(!hintFaded && Math.abs(targetPan - PAN_MAX) > 4){
+      hint.style.opacity = "0"; hintFaded = true;
+    }
+
+    renderer.render(scene, camera);
+    requestAnimationFrame(tick);
+  }
+  requestAnimationFrame(tick);
+
+  // expose a tiny probe for headless verification
+  window.__RIVER__ = {
+    ready:()=>swatches.length,
+    done:()=>!!window.__RIVER_DONE,
+    sortedByHue:()=>{
+      // visual sort: swatch world-X must increase monotonically with hue
+      const arr = swatches.slice().sort((a,b)=>a.hue-b.hue);
+      for(let i=1;i<arr.length;i++){ if(arr[i].hue < arr[i-1].hue-0.001) return false; }
+      return true;
+    },
+    // proves layout is spatial-by-hue: mesh X strictly tracks hue
+    spatialSorted:()=>{
+      const arr = swatches.slice().sort((a,b)=>a.base.x-b.base.x);
+      for(let i=1;i<arr.length;i++){ if(arr[i].hue < arr[i-1].hue - 0.06) return false; }
+      return true;
+    },
+    hues:()=>swatches.slice().sort((a,b)=>a.hue-b.hue).map(s=>+s.hue.toFixed(3)),
+    count:()=>swatches.length
+  };
+
+  start();
+})();
+</script>
+</body>
+</html>
diff --git a/proto/v8-swipe.html b/proto/v8-swipe.html
new file mode 100644
index 0000000..036ac6e
--- /dev/null
+++ b/proto/v8-swipe.html
@@ -0,0 +1,602 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<title>Swipe Tower — Curated Wallcovering Discovery</title>
+<style>
+  /* ───────────────────────────  TOKENS  ─────────────────────────── */
+  :root{
+    --bg:        #f4f1ec;   /* warm gallery linen   */
+    --bg-deep:   #ebe6dd;
+    --ink:       #1c1a17;   /* near-black warm ink  */
+    --ink-soft:  #6b655c;
+    --line:      #d8d1c4;
+    --card:      #ffffff;
+    --keep:      #2f6b4f;   /* deep botanical green */
+    --keep-tint: #e7f0ea;
+    --skip:      #8a8178;   /* muted stone          */
+    --skip-tint: #efece6;
+    --gold:      #b08a4f;
+    --shadow:    0 24px 60px -24px rgba(28,26,23,.42), 0 4px 14px -6px rgba(28,26,23,.22);
+    --serif: "Hoefler Text", "Iowan Old Style", "Palatino Linotype", Georgia, "Times New Roman", serif;
+    --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
+  }
+  *{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
+  html,body{ height:100%; margin:0; }
+  body{
+    background:
+      radial-gradient(120% 80% at 50% -10%, var(--bg) 0%, var(--bg-deep) 70%, #e3ddd2 100%);
+    color:var(--ink);
+    font-family:var(--sans);
+    overflow:hidden;
+    -webkit-font-smoothing:antialiased;
+  }
+
+  /* ───────────────────────────  LAYOUT  ─────────────────────────── */
+  .app{
+    height:100dvh;
+    display:grid;
+    grid-template-columns: 1fr 300px;
+    grid-template-rows: auto 1fr;
+    grid-template-areas:
+      "head head"
+      "stage tray";
+    max-width:1240px; margin:0 auto;
+  }
+  @media (max-width: 860px){
+    .app{ grid-template-columns:1fr; grid-template-rows:auto 1fr auto; grid-template-areas:"head" "stage" "tray"; }
+  }
+
+  /* ───────────────────────────  HEADER  ─────────────────────────── */
+  header{
+    grid-area:head;
+    padding:22px 30px 14px;
+    display:flex; align-items:baseline; justify-content:space-between; gap:18px;
+    border-bottom:1px solid var(--line);
+  }
+  .brand{ display:flex; flex-direction:column; gap:3px; }
+  .brand h1{
+    font-family:var(--serif); font-weight:500; font-size:26px; letter-spacing:.5px;
+    margin:0; line-height:1;
+  }
+  .brand .sub{
+    font-size:11px; letter-spacing:.32em; text-transform:uppercase; color:var(--ink-soft);
+  }
+  .counter{ text-align:right; font-size:13px; color:var(--ink-soft); line-height:1.5; }
+  .counter b{ color:var(--ink); font-variant-numeric:tabular-nums; }
+
+  /* ───────────────────────────  STAGE  ─────────────────────────── */
+  .stage{
+    grid-area:stage;
+    position:relative;
+    display:flex; flex-direction:column; align-items:center; justify-content:center;
+    padding:24px 20px 18px;
+    min-height:0;
+  }
+  .deck{
+    position:relative;
+    width:min(78vmin, 460px);
+    aspect-ratio:1/1;
+    flex:0 0 auto;
+  }
+
+  /* card */
+  .card{
+    position:absolute; inset:0;
+    background:var(--card);
+    border-radius:14px;
+    box-shadow:var(--shadow);
+    overflow:hidden;
+    display:flex; flex-direction:column;
+    transform-origin:center bottom;
+    will-change:transform, opacity;
+    user-select:none;
+  }
+  .card.behind-1{ transform:translateY(14px) scale(.955); }
+  .card.behind-2{ transform:translateY(26px) scale(.91); }
+  .card .swatch{
+    position:relative;
+    flex:1 1 auto;
+    background:var(--bg-deep);
+    background-size:cover; background-position:center;
+    min-height:0;
+  }
+  .card .swatch::after{ /* hairline frame inside swatch */
+    content:""; position:absolute; inset:0;
+    box-shadow: inset 0 0 0 1px rgba(28,26,23,.06);
+    pointer-events:none;
+  }
+  .card .meta{
+    flex:0 0 auto;
+    padding:14px 18px 16px;
+    border-top:1px solid var(--line);
+    background:linear-gradient(180deg,#fff, #fbf9f5);
+  }
+  .card .pname{
+    font-family:var(--serif); font-size:21px; line-height:1.15; font-weight:500;
+    margin:0 0 4px; color:var(--ink);
+    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
+  }
+  .card .pvendor{ font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--gold); margin-bottom:8px; }
+  .card .spec{ display:flex; gap:14px; font-size:12.5px; color:var(--ink-soft); flex-wrap:wrap; }
+  .card .spec span{ display:inline-flex; align-items:center; gap:5px; }
+  .card .spec .dot{ width:5px; height:5px; border-radius:50%; background:var(--line); }
+
+  /* swipe verdict stamps */
+  .stamp{
+    position:absolute; top:26px; padding:8px 18px;
+    font-family:var(--serif); font-size:24px; letter-spacing:.06em;
+    border:2.5px solid currentColor; border-radius:8px;
+    opacity:0; transition:opacity .08s; pointer-events:none;
+    background:rgba(255,255,255,.78); backdrop-filter:blur(2px);
+  }
+  .stamp.keep{ left:24px; color:var(--keep); transform:rotate(-11deg); }
+  .stamp.skip{ right:24px; color:var(--skip); transform:rotate(11deg); }
+
+  /* empty state */
+  .empty{
+    position:absolute; inset:0; display:none; flex-direction:column;
+    align-items:center; justify-content:center; text-align:center; gap:14px; padding:30px;
+  }
+  .empty.show{ display:flex; }
+  .empty h2{ font-family:var(--serif); font-weight:500; font-size:24px; margin:0; }
+  .empty p{ color:var(--ink-soft); font-size:14px; margin:0; max-width:32ch; line-height:1.5; }
+  .empty button{
+    margin-top:8px; font:inherit; font-size:14px; letter-spacing:.04em;
+    border:1px solid var(--ink); background:none; color:var(--ink);
+    padding:11px 24px; border-radius:30px; cursor:pointer;
+  }
+  .empty button:hover{ background:var(--ink); color:#fff; }
+
+  /* ───────────────────────────  ACTION BAR  ─────────────────────────── */
+  .actions{
+    margin-top:22px; display:flex; align-items:center; gap:26px;
+  }
+  .act{
+    --c:var(--ink);
+    width:80px; height:80px; border-radius:50%;
+    border:2px solid var(--line); background:#fff;
+    display:flex; align-items:center; justify-content:center;
+    cursor:pointer; transition:transform .12s ease, box-shadow .2s, border-color .2s, background .2s;
+    box-shadow:0 6px 18px -8px rgba(28,26,23,.3);
+    position:relative;
+  }
+  .act svg{ width:34px; height:34px; }
+  .act:hover{ transform:translateY(-3px); }
+  .act:active{ transform:scale(.92); }
+  .act .lbl{
+    position:absolute; bottom:-24px; left:50%; transform:translateX(-50%);
+    font-size:10.5px; letter-spacing:.22em; text-transform:uppercase; color:var(--ink-soft);
+    white-space:nowrap;
+  }
+  .act.skip{ color:var(--skip); }
+  .act.skip:hover{ border-color:var(--skip); background:var(--skip-tint); }
+  .act.keep{ color:var(--keep); width:96px; height:96px; }
+  .act.keep svg{ width:42px; height:42px; }
+  .act.keep:hover{ border-color:var(--keep); background:var(--keep-tint); }
+  .act.undo{ width:58px; height:58px; color:var(--ink-soft); }
+  .act.undo svg{ width:24px; height:24px; }
+  .act.undo:disabled{ opacity:.32; cursor:default; transform:none; }
+  .hint{ margin-top:34px; font-size:11.5px; letter-spacing:.04em; color:var(--ink-soft); text-align:center; }
+  .hint kbd{
+    font-family:var(--sans); font-size:11px; background:#fff; border:1px solid var(--line);
+    border-bottom-width:2px; border-radius:5px; padding:1px 7px; color:var(--ink);
+  }
+
+  /* ───────────────────────────  FAVORITES TRAY  ─────────────────────────── */
+  .tray{
+    grid-area:tray;
+    border-left:1px solid var(--line);
+    background:linear-gradient(180deg, #faf8f3, #f3efe7);
+    display:flex; flex-direction:column; min-height:0;
+  }
+  @media (max-width:860px){ .tray{ border-left:none; border-top:1px solid var(--line); max-height:38vh; } }
+  .tray-head{
+    padding:18px 22px 12px; display:flex; align-items:baseline; justify-content:space-between;
+    border-bottom:1px solid var(--line);
+  }
+  .tray-head h2{ font-family:var(--serif); font-weight:500; font-size:17px; margin:0; letter-spacing:.02em; }
+  .tray-head .ct{
+    font-size:12px; color:#fff; background:var(--keep);
+    min-width:24px; height:24px; padding:0 8px; border-radius:12px;
+    display:inline-flex; align-items:center; justify-content:center; font-variant-numeric:tabular-nums;
+  }
+  .tray-head .ct.zero{ background:var(--line); color:var(--ink-soft); }
+  .tray-list{ flex:1 1 auto; overflow-y:auto; padding:12px 14px 18px; display:flex; flex-direction:column; gap:10px; }
+  .tray-empty{ color:var(--ink-soft); font-size:13px; line-height:1.6; padding:18px 8px; text-align:center; }
+  .tray-empty .heart{ font-size:26px; display:block; margin-bottom:8px; opacity:.4; }
+
+  .fav{
+    display:flex; gap:11px; align-items:center;
+    background:#fff; border:1px solid var(--line); border-radius:10px;
+    padding:8px; position:relative;
+    animation:favIn .42s cubic-bezier(.2,.9,.25,1) both;
+  }
+  @keyframes favIn{ from{ opacity:0; transform:translateX(16px) scale(.96);} to{opacity:1; transform:none;} }
+  .fav .thumb{ width:54px; height:54px; border-radius:7px; background:var(--bg-deep) center/cover; flex:0 0 auto; box-shadow:inset 0 0 0 1px rgba(0,0,0,.05); }
+  .fav .fmeta{ min-width:0; flex:1 1 auto; }
+  .fav .fname{ font-family:var(--serif); font-size:14px; line-height:1.2; margin:0 0 2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
+  .fav .fvendor{ font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:var(--gold); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
+  .fav .fspec{ font-size:10.5px; color:var(--ink-soft); margin-top:2px; }
+  .fav .rm{
+    position:absolute; top:6px; right:6px; width:20px; height:20px; border-radius:50%;
+    border:none; background:var(--skip-tint); color:var(--skip); cursor:pointer;
+    font-size:13px; line-height:1; display:flex; align-items:center; justify-content:center;
+    opacity:0; transition:opacity .15s;
+  }
+  .fav:hover .rm{ opacity:1; }
+  .tray-foot{ flex:0 0 auto; padding:14px 18px; border-top:1px solid var(--line); }
+  .tray-foot button{
+    width:100%; font:inherit; font-size:13.5px; letter-spacing:.1em; text-transform:uppercase;
+    background:var(--ink); color:#fff; border:none; border-radius:30px; padding:13px; cursor:pointer;
+    transition:opacity .2s; display:flex; align-items:center; justify-content:center; gap:8px;
+  }
+  .tray-foot button:disabled{ opacity:.3; cursor:default; }
+  .tray-foot button:not(:disabled):hover{ background:var(--keep); }
+  .tray-foot .note{ font-size:11px; color:var(--ink-soft); text-align:center; margin:9px 0 0; line-height:1.4; }
+
+  .loading{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:var(--ink-soft); font-size:14px; letter-spacing:.1em; }
+  @media (prefers-reduced-motion: reduce){ *{ animation-duration:.001s !important; transition-duration:.001s !important; } }
+</style>
+</head>
+<body>
+<div class="app">
+  <header>
+    <div class="brand">
+      <h1>Swipe Tower</h1>
+      <div class="sub">Curated Wallcovering Discovery</div>
+    </div>
+    <div class="counter">
+      <div>Reviewed <b id="seenCt">0</b></div>
+      <div><b id="leftCt">0</b> remaining</div>
+    </div>
+  </header>
+
+  <section class="stage">
+    <div class="deck" id="deck">
+      <div class="loading" id="loading">Curating your collection…</div>
+      <div class="empty" id="empty">
+        <h2 id="emptyTitle">That's the collection</h2>
+        <p id="emptyMsg">You've seen every swatch in this curation. Your favorites are saved in the tray.</p>
+        <button id="restartBtn">Start over</button>
+      </div>
+    </div>
+
+    <div class="actions" id="actions" style="visibility:hidden">
+      <button class="act undo" id="undoBtn" title="Undo last (Backspace)" disabled aria-label="Undo last">
+        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7v6h6"/><path d="M3 13a9 9 0 1 0 3-7.7L3 8"/></svg>
+      </button>
+      <button class="act skip" id="skipBtn" title="Skip (← arrow)" aria-label="Skip this swatch">
+        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>
+        <span class="lbl">Skip</span>
+      </button>
+      <button class="act keep" id="keepBtn" title="Keep (→ arrow)" aria-label="Keep this swatch">
+        <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 21s-7.5-4.7-10-9.2C.3 8.4 1.9 4.6 5.4 4.1 7.6 3.8 9.5 5 12 7.6 14.5 5 16.4 3.8 18.6 4.1c3.5.5 5.1 4.3 3.4 7.7C19.5 16.3 12 21 12 21z"/></svg>
+        <span class="lbl">Keep</span>
+      </button>
+    </div>
+    <div class="hint" id="hint" style="visibility:hidden">
+      Drag a swatch, tap a button, or use <kbd>←</kbd> skip &nbsp; <kbd>→</kbd> keep &nbsp; <kbd>↩</kbd> undo
+    </div>
+  </section>
+
+  <aside class="tray">
+    <div class="tray-head">
+      <h2>Your Favorites</h2>
+      <span class="ct zero" id="favCt">0</span>
+    </div>
+    <div class="tray-list" id="favList">
+      <div class="tray-empty" id="trayEmpty">
+        <span class="heart">♥</span>
+        Swatches you keep collect here.<br>Build a palette, then request samples.
+      </div>
+    </div>
+    <div class="tray-foot">
+      <button id="sampleBtn" disabled>Request <span id="sampleCt">0</span> Samples</button>
+      <p class="note" id="sampleNote">No order minimum on memo samples.</p>
+    </div>
+  </aside>
+</div>
+
+<script>
+const API = "http://127.0.0.1:7690/api/showroom/products?limit=120";
+const PLACEHOLDER = "data:image/svg+xml;utf8," + encodeURIComponent(
+  '<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80"><rect width="80" height="80" fill="#ebe6dd"/></svg>');
+
+/* Offline fallback so the mechanic is demonstrable even when the showroom API
+   is unreachable (e.g. opened as a bare file:// with CORS blocking the fetch).
+   Generated swatch tiles via inline SVG so no external image dependency. */
+function swatchSVG(bg, fg, motif){
+  const m = {
+    trellis:`<path d="M0 50 L50 0 L100 50 L50 100 Z" fill="none" stroke="${fg}" stroke-width="3"/><path d="M50 0 L100 50 L50 100 L0 50 Z" fill="none" stroke="${fg}" stroke-width="3"/><circle cx="50" cy="50" r="6" fill="${fg}"/>`,
+    leaf:`<path d="M50 8 C30 30 30 70 50 92 C70 70 70 30 50 8 Z" fill="${fg}" opacity=".85"/><path d="M50 8 L50 92" stroke="${bg}" stroke-width="2"/>`,
+    floral:`<g fill="${fg}"><circle cx="50" cy="32" r="11"/><circle cx="32" cy="55" r="11"/><circle cx="68" cy="55" r="11"/><circle cx="50" cy="72" r="11"/><circle cx="50" cy="52" r="7" fill="${bg}"/></g>`,
+    stripe:`<rect x="14" width="14" height="100" fill="${fg}" opacity=".8"/><rect x="58" width="14" height="100" fill="${fg}" opacity=".8"/>`,
+    geo:`<rect x="20" y="20" width="60" height="60" fill="none" stroke="${fg}" stroke-width="4"/><rect x="35" y="35" width="30" height="30" fill="${fg}" opacity=".7"/>`
+  }[motif] || '';
+  const svg=`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 100 100"><rect width="100" height="100" fill="${bg}"/>${m}</svg>`;
+  return "data:image/svg+xml;utf8,"+encodeURIComponent(svg);
+}
+const FALLBACK = [
+  ["Aga Jungle on Off-White","China Seas","#f3efe6","#2f6b4f","leaf","Jungle Green"],
+  ["Lyford Trellis — Indigo","Quadrille","#1f3a5f","#e8edf4","trellis","Indigo"],
+  ["Fiorentina — Coral","China Seas","#fbeee6","#c4674e","floral","Coral"],
+  ["Henriot Stripe — Oatmeal","Quadrille","#efe9dc","#8a7a5c","stripe","Oatmeal"],
+  ["Veneto — Charcoal","China Seas","#2b2926","#d8cfbf","geo","Charcoal"],
+  ["Arbre de Matisse — Celadon","Quadrille","#e7efe4","#5e8a6a","leaf","Celadon"],
+  ["Bali Hai — Aqua","China Seas","#e2f1f0","#3a8f93","floral","Aqua"],
+  ["Cap Ferrat — Rose","Quadrille","#f7e9ec","#b06a82","trellis","Rose"],
+  ["Sigourney — Mustard","China Seas","#f4ead0","#c79a3a","stripe","Mustard"],
+  ["Persia — Ink","Quadrille","#1c1f2b","#cfc6b4","geo","Ink"],
+  ["Lulu — Blush","China Seas","#fbeef0","#d398a6","floral","Blush"],
+  ["Kazak — Terracotta","Quadrille","#f0e4dc","#b15a3c","trellis","Terracotta"],
+].map((r,i)=>({
+  pattern_name:r[0], vendor:r[1], collection:r[1],
+  image:swatchSVG(r[2],r[3],r[4]), color_name:r[5],
+  width:27, repeat:27, sku:"DEMO-"+(100+i)
+}));
+
+let queue = [];      // remaining products (head = top card)
+let history = [];     // {item, verdict} for undo
+let favorites = [];   // kept items
+let seen = 0;
+
+const $ = id => document.getElementById(id);
+const deck = $("deck");
+
+/* ── derive a short color/colorway word from pattern_name (hue is null in data) ── */
+const COLORWORDS = ["white","off-white","ivory","cream","oatmeal","alabaster","greige","grey","gray","charcoal","black","ink","navy","blue","indigo","teal","aqua","celadon","sage","green","jungle","olive","moss","gold","ochre","mustard","yellow","apricot","coral","blush","pink","rose","red","crimson","terracotta","rust","brown","taupe","tan","sand","bronze","copper","silver","plum","purple","lavender","aubergine"];
+function colorwordFor(p){
+  if(p.color_name) return p.color_name;
+  const name = (p.pattern_name||"").toLowerCase();
+  const hit = COLORWORDS.find(c => name.includes(c));
+  if(hit) return hit.replace(/\b\w/g, m=>m.toUpperCase());
+  if(p.color) return p.color;
+  return null;
+}
+function specLine(p){
+  const w = p.width || 27, r = p.repeat || 27;
+  const parts = [`${w}″ wide`];
+  if(r) parts.push(`${r}″ repeat`);
+  return parts;
+}
+
+/* ───────────────────────────  CARD RENDER  ─────────────────────────── */
+function makeCard(p, depth){
+  const card = document.createElement("div");
+  card.className = "card" + (depth===1?" behind-1":depth===2?" behind-2":"");
+  card.dataset.depth = depth;
+
+  const swatch = document.createElement("div");
+  swatch.className = "swatch";
+  const img = new Image();
+  img.onload = ()=>{ swatch.style.backgroundImage = `url("${p.image}")`; };
+  img.onerror = ()=>{ swatch.style.backgroundImage = `url("${PLACEHOLDER}")`; };
+  img.src = p.image || PLACEHOLDER;
+
+  const stampKeep = el("div","stamp keep","Keep");
+  const stampSkip = el("div","stamp skip","Skip");
+  swatch.append(stampKeep, stampSkip);
+
+  const meta = document.createElement("div");
+  meta.className = "meta";
+  const cw = colorwordFor(p);
+  meta.innerHTML = `
+    <p class="pname">${esc(cleanName(p.pattern_name))}</p>
+    <div class="pvendor">${esc(p.vendor || p.collection || "Designer Wallcoverings")}</div>
+    <div class="spec">
+      ${specLine(p).map(s=>`<span>${esc(s)}</span>`).join('<span class="dot"></span>')}
+      ${cw?`<span class="dot"></span><span>${esc(cw)}</span>`:""}
+    </div>`;
+
+  card.append(swatch, meta);
+  return card;
+}
+function el(t,c,txt){ const e=document.createElement(t); e.className=c; e.textContent=txt; return e; }
+function esc(s){ return String(s==null?"":s).replace(/[&<>"]/g, m=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[m])); }
+function cleanName(s){ return (s||"Untitled").replace(/\s*-\s*[^-]+$/, m => m.length<22 ? m : ""); }
+
+/* ───────────────────────────  DECK STATE  ─────────────────────────── */
+function renderDeck(){
+  // remove existing cards (keep loading/empty nodes)
+  deck.querySelectorAll(".card").forEach(c=>c.remove());
+  const top3 = queue.slice(0,3);
+  // render back-to-front so top card is last (highest z)
+  for(let i=top3.length-1; i>=0; i--){
+    const card = makeCard(top3[i], i);
+    deck.appendChild(card);
+    if(i===0) attachDrag(card);
+  }
+  updateCounters();
+  const done = queue.length===0;
+  $("empty").classList.toggle("show", done);
+  $("actions").style.visibility = done ? "hidden":"visible";
+  $("hint").style.visibility = done ? "hidden":"visible";
+  $("undoBtn").disabled = history.length===0;
+  $("emptyTitle").textContent = favorites.length ? "That's the collection" : "All caught up";
+}
+
+function updateCounters(){
+  $("seenCt").textContent = seen;
+  $("leftCt").textContent = queue.length;
+  const n = favorites.length;
+  const fc = $("favCt"); fc.textContent = n; fc.classList.toggle("zero", n===0);
+  $("sampleCt").textContent = n;
+  $("sampleBtn").disabled = n===0;
+}
+
+/* ───────────────────────────  VERDICT / THROW  ─────────────────────────── */
+let busy = false;
+function topCard(){ return deck.querySelector('.card[data-depth="0"]'); }
+
+function decide(verdict, fromDrag){
+  if(busy || queue.length===0) return;
+  busy = true;
+  const card = topCard();
+  const item = queue[0];
+  const dir = verdict==="keep" ? 1 : -1;
+
+  // show stamp
+  const stamp = card.querySelector(verdict==="keep" ? ".stamp.keep" : ".stamp.skip");
+  if(stamp) stamp.style.opacity = "1";
+
+  // throw animation
+  const throwX = dir * (window.innerWidth*0.9 + 200);
+  const rot = dir * 18;
+  card.style.transition = "transform .42s cubic-bezier(.36,.07,.4,1), opacity .42s";
+  card.style.transform = `translate(${throwX}px, -40px) rotate(${rot}deg)`;
+  card.style.opacity = "0";
+
+  // promote remaining cards immediately so the stack feels live
+  const b1 = deck.querySelector('.card[data-depth="1"]');
+  const b2 = deck.querySelector('.card[data-depth="2"]');
+  if(b1){ b1.style.transition="transform .42s cubic-bezier(.2,.9,.25,1)"; b1.className="card"; b1.dataset.depth="0"; }
+  if(b2){ b2.style.transition="transform .42s cubic-bezier(.2,.9,.25,1)"; b2.className="card behind-1"; b2.dataset.depth="1"; }
+
+  // commit state
+  queue.shift();
+  seen++;
+  history.push({item, verdict});
+  if(verdict==="keep"){ favorites.unshift(item); addFav(item); }
+
+  setTimeout(()=>{
+    busy = false;
+    renderDeck(); // rebuilds stack cleanly + brings in next back card + wires drag
+  }, 430);
+}
+
+function undo(){
+  if(busy || history.length===0) return;
+  const last = history.pop();
+  queue.unshift(last.item);
+  seen = Math.max(0, seen-1);
+  if(last.verdict==="keep"){
+    favorites = favorites.filter(f=>f!==last.item);
+    removeFavNode(last.item);
+  }
+  renderDeck();
+}
+
+/* ───────────────────────────  FAVORITES TRAY  ─────────────────────────── */
+const favList = $("favList");
+function addFav(p){
+  $("trayEmpty").style.display = "none";
+  const row = document.createElement("div");
+  row.className = "fav";
+  row._item = p;
+  const cw = colorwordFor(p);
+  row.innerHTML = `
+    <div class="thumb" style="background-image:url('${(p.image||PLACEHOLDER).replace(/'/g,"%27")}')"></div>
+    <div class="fmeta">
+      <p class="fname">${esc(cleanName(p.pattern_name))}</p>
+      <div class="fvendor">${esc(p.vendor||p.collection||"")}</div>
+      <div class="fspec">${(p.width||27)}″ &middot; ${cw?esc(cw):"swatch"}</div>
+    </div>
+    <button class="rm" title="Remove" aria-label="Remove">&times;</button>`;
+  row.querySelector(".rm").onclick = ()=> removeFav(p);
+  favList.prepend(row);
+  updateCounters();
+}
+function removeFav(p){
+  favorites = favorites.filter(f=>f!==p);
+  removeFavNode(p);
+  updateCounters();
+}
+function removeFavNode(p){
+  [...favList.querySelectorAll(".fav")].forEach(r=>{ if(r._item===p) r.remove(); });
+  if(favorites.length===0) $("trayEmpty").style.display = "";
+}
+
+/* ───────────────────────────  DRAG TO SWIPE  ─────────────────────────── */
+function attachDrag(card){
+  let startX=0, startY=0, dx=0, dy=0, dragging=false;
+  const threshold = 110;
+
+  const onDown = e=>{
+    if(busy) return;
+    dragging = true;
+    const pt = e.touches?e.touches[0]:e;
+    startX = pt.clientX; startY = pt.clientY; dx=dy=0;
+    card.style.transition = "none";
+    window.addEventListener("mousemove", onMove);
+    window.addEventListener("mouseup", onUp);
+    window.addEventListener("touchmove", onMove, {passive:false});
+    window.addEventListener("touchend", onUp);
+  };
+  const onMove = e=>{
+    if(!dragging) return;
+    const pt = e.touches?e.touches[0]:e;
+    dx = pt.clientX-startX; dy = pt.clientY-startY;
+    if(e.cancelable && Math.abs(dx)>6) e.preventDefault();
+    const rot = dx/22;
+    card.style.transform = `translate(${dx}px, ${dy*0.4}px) rotate(${rot}deg)`;
+    const ks = card.querySelector(".stamp.keep"), ss = card.querySelector(".stamp.skip");
+    if(ks) ks.style.opacity = dx>20 ? Math.min(1, dx/threshold).toFixed(2):0;
+    if(ss) ss.style.opacity = dx<-20 ? Math.min(1, -dx/threshold).toFixed(2):0;
+  };
+  const onUp = ()=>{
+    if(!dragging) return;
+    dragging = false;
+    window.removeEventListener("mousemove", onMove);
+    window.removeEventListener("mouseup", onUp);
+    window.removeEventListener("touchmove", onMove);
+    window.removeEventListener("touchend", onUp);
+    if(Math.abs(dx) > threshold){
+      decide(dx>0 ? "keep":"skip", true);
+    } else {
+      card.style.transition = "transform .3s cubic-bezier(.2,.9,.25,1)";
+      card.style.transform = "";
+      const ks=card.querySelector(".stamp.keep"), ss=card.querySelector(".stamp.skip");
+      if(ks) ks.style.opacity=0; if(ss) ss.style.opacity=0;
+    }
+  };
+  card.addEventListener("mousedown", onDown);
+  card.addEventListener("touchstart", onDown, {passive:true});
+}
+
+/* ───────────────────────────  WIRING  ─────────────────────────── */
+$("keepBtn").onclick = ()=> decide("keep");
+$("skipBtn").onclick = ()=> decide("skip");
+$("undoBtn").onclick = undo;
+$("restartBtn").onclick = ()=> { history=[]; favorites.forEach(removeFavNode); favorites=[]; load(true); };
+$("sampleBtn").onclick = ()=>{
+  if(!favorites.length) return;
+  const note = $("sampleNote");
+  note.textContent = `${favorites.length} sample${favorites.length>1?"s":""} queued — a stylist will confirm your memo set.`;
+  note.style.color = "var(--keep)";
+};
+
+document.addEventListener("keydown", e=>{
+  if(e.key==="ArrowRight"){ e.preventDefault(); decide("keep"); }
+  else if(e.key==="ArrowLeft"){ e.preventDefault(); decide("skip"); }
+  else if(e.key==="Backspace"){ e.preventDefault(); undo(); }
+});
+
+/* ───────────────────────────  LOAD  ─────────────────────────── */
+async function load(reshuffle){
+  $("loading").style.display = "flex";
+  $("empty").classList.remove("show");
+  let items = [];
+  try{
+    const r = await fetch(API);
+    if(!r.ok) throw new Error("HTTP "+r.status);
+    const j = await r.json();
+    items = (j.products || j || []).filter(p=>p && p.image);
+  }catch(err){
+    // Standalone / offline: fall back to the embedded sample set so the
+    // mechanic is always usable. (Same-origin from :7690 the live fetch works.)
+    console.warn("[swipe-tower] live API unavailable, using offline sample set:", err.message);
+    items = FALLBACK.slice();
+  }
+  if(!items.length) items = FALLBACK.slice();
+  if(reshuffle){ items = items.slice().sort(()=>Math.random()-0.5); }
+  queue = items;
+  history = []; seen = 0;
+  $("loading").style.display = "none";
+  renderDeck();
+}
+load();
+</script>
+</body>
+</html>
diff --git a/proto/v9-walkin.html b/proto/v9-walkin.html
new file mode 100644
index 0000000..4d5fd8b
--- /dev/null
+++ b/proto/v9-walkin.html
@@ -0,0 +1,367 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
+<title>WALK-IN ROOM — China Seas</title>
+<style>
+  :root { --ink:#2b2622; --paper:#f4efe7; }
+  * { box-sizing:border-box; }
+  html,body { margin:0; height:100%; overflow:hidden; background:#1a1714;
+    font-family:"Hoefler Text", Georgia, "Times New Roman", serif; color:var(--paper); }
+  #app { position:fixed; inset:0; }
+  canvas { display:block; }
+
+  /* top brand bar */
+  .topbar { position:fixed; top:0; left:0; right:0; z-index:10;
+    display:flex; align-items:center; justify-content:space-between;
+    padding:14px 22px; pointer-events:none;
+    background:linear-gradient(to bottom, rgba(20,17,14,.55), rgba(20,17,14,0)); }
+  .brand { letter-spacing:.32em; font-size:12px; text-transform:uppercase; opacity:.9; }
+  .now { text-align:right; font-size:11px; letter-spacing:.06em; line-height:1.5; opacity:.85; max-width:46%; }
+  .now b { display:block; letter-spacing:.04em; font-size:13px; }
+
+  /* bottom design switcher strip */
+  .strip { position:fixed; left:0; right:0; bottom:0; z-index:10;
+    padding:14px 16px 18px; display:flex; gap:12px; align-items:flex-end;
+    overflow-x:auto; overflow-y:hidden;
+    background:linear-gradient(to top, rgba(20,17,14,.82), rgba(20,17,14,0)); }
+  .strip::-webkit-scrollbar { height:6px; }
+  .strip::-webkit-scrollbar-thumb { background:rgba(244,239,231,.25); border-radius:3px; }
+  .swatch { flex:0 0 auto; width:78px; cursor:pointer; text-align:center;
+    opacity:.72; transition:opacity .2s, transform .2s; }
+  .swatch:hover { opacity:1; transform:translateY(-3px); }
+  .swatch.active { opacity:1; }
+  .swatch img { width:78px; height:78px; object-fit:cover; border-radius:6px;
+    border:2px solid transparent; background:#3a342d; display:block; }
+  .swatch.active img { border-color:var(--paper); box-shadow:0 6px 18px rgba(0,0,0,.5); }
+  .swatch span { display:block; margin-top:5px; font-size:9.5px; line-height:1.25;
+    letter-spacing:.02em; opacity:.85; max-height:24px; overflow:hidden;
+    text-transform:uppercase; }
+
+  .hint { position:fixed; left:50%; top:54%; transform:transl(-50%,-50%);
+    transform:translateX(-50%); z-index:9; pointer-events:none;
+    font-size:11px; letter-spacing:.18em; text-transform:uppercase;
+    opacity:.0; transition:opacity 1s; text-shadow:0 1px 6px rgba(0,0,0,.6); }
+  .hint.show { opacity:.55; }
+
+  .loading { position:fixed; inset:0; z-index:20; display:flex;
+    align-items:center; justify-content:center; flex-direction:column; gap:14px;
+    background:#1a1714; transition:opacity .6s; }
+  .loading.gone { opacity:0; pointer-events:none; }
+  .ring { width:34px; height:34px; border:2px solid rgba(244,239,231,.2);
+    border-top-color:var(--paper); border-radius:50%; animation:spin 1s linear infinite; }
+  @keyframes spin { to { transform:rotate(360deg); } }
+  .loading p { letter-spacing:.28em; text-transform:uppercase; font-size:11px; opacity:.7; }
+</style>
+</head>
+<body>
+  <div id="app"></div>
+
+  <div class="topbar">
+    <div class="brand">China&nbsp;Seas &nbsp;·&nbsp; Walk-In Room</div>
+    <div class="now" id="now"><b>—</b><span id="meta"></span></div>
+  </div>
+
+  <div class="hint" id="hint">Drag to look around the room</div>
+
+  <div class="strip" id="strip"></div>
+
+  <div class="loading" id="loading"><div class="ring"></div><p>Papering the room…</p></div>
+
+  <script src="./three.min.js"></script>
+  <script src="./OrbitControls.js"></script>
+  <script>
+  (function(){
+    "use strict";
+    const FT = 0.3048;            // 1 ft in metres
+    const REPEAT_IN = 27;          // architectural wallpaper repeat (inches)
+    const REPEAT_M = REPEAT_IN * 0.0254;  // ~0.6858 m
+
+    // Room dimensions (a real-feeling living room): 16ft W x 13ft D x 9ft H
+    const W = 16 * FT, D = 13 * FT, H = 9 * FT;
+    const EYE = 1.62;              // standing eye height
+
+    const app = document.getElementById('app');
+
+    // ---- renderer ----
+    const renderer = new THREE.WebGLRenderer({ antialias:true });
+    renderer.setPixelRatio(Math.min(window.devicePixelRatio||1, 2));
+    renderer.setSize(window.innerWidth, window.innerHeight);
+    renderer.shadowMap.enabled = true;
+    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
+    if ('outputColorSpace' in renderer) renderer.outputColorSpace = THREE.SRGBColorSpace;
+    else if ('outputEncoding' in renderer) renderer.outputEncoding = THREE.sRGBEncoding;
+    renderer.toneMapping = THREE.ACESFilmicToneMapping;
+    renderer.toneMappingExposure = 1.05;
+    app.appendChild(renderer.domElement);
+
+    const scene = new THREE.Scene();
+    scene.background = new THREE.Color(0x2a2520);
+
+    // ---- camera INSIDE the room, near the back wall, looking across ----
+    const camera = new THREE.PerspectiveCamera(72, window.innerWidth/window.innerHeight, 0.05, 100);
+    camera.position.set(0, EYE, D*0.30);   // standing a bit back from centre
+
+    // OrbitControls used as a "look around from inside" rig: target sits just
+    // in front of the eye, so dragging rotates the view, not an exterior orbit.
+    const controls = new THREE.OrbitControls(camera, renderer.domElement);
+    controls.target.set(-W*0.32, EYE, -D*0.5);   // look toward far wall + window corner
+    controls.enablePan = false;
+    controls.enableZoom = false;           // it's a room, not a model — no zoom
+    controls.rotateSpeed = -0.32;          // negative = natural "look" direction
+    controls.minPolarAngle = THREE.MathUtils.degToRad(58);
+    controls.maxPolarAngle = THREE.MathUtils.degToRad(118);
+    controls.enableDamping = true;
+    controls.dampingFactor = 0.08;
+    // keep the pivot pinned to the eye every frame (first-person look)
+    function lockPivot(){
+      const dir = new THREE.Vector3();
+      camera.getWorldDirection(dir);
+      controls.target.copy(camera.position).add(dir.multiplyScalar(0.6));
+    }
+
+    // ================= LIGHTING (warm, soft) =================
+    const hemi = new THREE.HemisphereLight(0xfff3e0, 0x3a2f26, 0.42);
+    scene.add(hemi);
+    const ambient = new THREE.AmbientLight(0xffe8cf, 0.20);
+    scene.add(ambient);
+
+    // Daylight pouring through the window (key light), warm + directional so the
+    // walls carry a light->shadow gradient (depth cue: you're in a real lit room)
+    const sun = new THREE.DirectionalLight(0xfff1da, 1.55);
+    sun.position.set(-W*0.55, H*0.9, D*0.55);
+    sun.castShadow = true;
+    sun.shadow.mapSize.set(1024,1024);
+    sun.shadow.camera.near = 0.5; sun.shadow.camera.far = 30;
+    sun.shadow.camera.left = -W; sun.shadow.camera.right = W;
+    sun.shadow.camera.top = H; sun.shadow.camera.bottom = -H;
+    sun.shadow.bias = -0.0004;
+    scene.add(sun);
+
+    // soft warm fill bounce from the room interior
+    const fill = new THREE.PointLight(0xffd9a8, 0.45, 18, 2);
+    fill.position.set(W*0.25, H*0.7, D*0.1);
+    scene.add(fill);
+    // gentle lamp glow near the sofa
+    const lamp = new THREE.PointLight(0xffcaa0, 0.55, 9, 2);
+    lamp.position.set(W*0.32, 1.4, -D*0.30);
+    scene.add(lamp);
+    // bright daylight spill right at the window so that wall glows (falloff = depth)
+    const dayspill = new THREE.PointLight(0xfff4e0, 0.85, 7, 2);
+    dayspill.position.set(-W*0.5 + 0.4, 1.4, -D*0.10);
+    scene.add(dayspill);
+
+    // ================= ROOM SHELL =================
+    const tex = { loader: new THREE.TextureLoader() };
+    tex.loader.crossOrigin = 'anonymous';
+
+    // wall material starts neutral; texture swapped in on load
+    const wallMat = new THREE.MeshStandardMaterial({ color:0xece4d6, roughness:0.92, metalness:0.0, side:THREE.FrontSide });
+
+    function wall(w, h){
+      const g = new THREE.PlaneGeometry(w, h);
+      const m = wallMat.clone();
+      m.userData.wallW = w;   // physical width of this wall (m)
+      return new THREE.Mesh(g, m);
+    }
+
+    const walls = [];
+    // back wall (-Z)
+    let m = wall(W, H); m.position.set(0, H/2, -D/2); walls.push(m);
+    // front wall (+Z) faces inward
+    m = wall(W, H); m.position.set(0, H/2, D/2); m.rotation.y = Math.PI; walls.push(m);
+    // left wall (-X)
+    m = wall(D, H); m.position.set(-W/2, H/2, 0); m.rotation.y = Math.PI/2; walls.push(m);
+    // right wall (+X)
+    m = wall(D, H); m.position.set(W/2, H/2, 0); m.rotation.y = -Math.PI/2; walls.push(m);
+    walls.forEach(w => { w.receiveShadow = true; scene.add(w); });
+
+    // ceiling — soft off-white
+    const ceil = new THREE.Mesh(new THREE.PlaneGeometry(W, D),
+      new THREE.MeshStandardMaterial({ color:0xf3ece0, roughness:1 }));
+    ceil.rotation.x = Math.PI/2; ceil.position.y = H; ceil.receiveShadow = true; scene.add(ceil);
+
+    // floor — warm wood tone
+    const floor = new THREE.Mesh(new THREE.PlaneGeometry(W, D),
+      new THREE.MeshStandardMaterial({ color:0x6b4a31, roughness:0.78 }));
+    floor.rotation.x = -Math.PI/2; floor.position.y = 0; floor.receiveShadow = true; scene.add(floor);
+
+    // baseboard + crown trim (white) to frame the paper like a real install
+    const trimMat = new THREE.MeshStandardMaterial({ color:0xf6f1e8, roughness:0.6 });
+    function trimRing(y, h){
+      const grp = new THREE.Group();
+      const t = 0.02;
+      const spec = [
+        [W, 0, -D/2, 0], [W, 0, D/2, 0],
+        [D, -W/2, 0, Math.PI/2], [D, W/2, 0, Math.PI/2],
+      ];
+      spec.forEach(([len,x,z,ry])=>{
+        const b = new THREE.Mesh(new THREE.BoxGeometry(len, h, t+0.01), trimMat);
+        b.position.set(x, y, z); b.rotation.y = ry; b.castShadow=false; grp.add(b);
+      });
+      return grp;
+    }
+    scene.add(trimRing(0.05, 0.10));      // baseboard
+    scene.add(trimRing(H-0.06, 0.12));    // crown
+
+    // ================= WINDOW (light source, on left wall) =================
+    (function(){
+      const ww = 1.6, wh = 1.5, wy = 1.25, wx = -W/2 + 0.012;
+      // bright daylight panel (emissive so it reads as a window)
+      const glass = new THREE.Mesh(new THREE.PlaneGeometry(ww, wh),
+        new THREE.MeshStandardMaterial({ color:0xfdf6e8, emissive:0xfff2d6, emissiveIntensity:1.2, roughness:1 }));
+      glass.position.set(wx, wy, -D*0.10); glass.rotation.y = Math.PI/2; scene.add(glass);
+      // white frame
+      const fr = new THREE.Mesh(new THREE.PlaneGeometry(ww+0.16, wh+0.16),
+        new THREE.MeshStandardMaterial({ color:0xf6f1e8, roughness:0.5 }));
+      fr.position.set(wx+0.002, wy, -D*0.10); fr.rotation.y = Math.PI/2; scene.add(fr);
+      // mullions
+      const mull = new THREE.MeshStandardMaterial({ color:0xeae3d6 });
+      const v = new THREE.Mesh(new THREE.BoxGeometry(0.03, wh, 0.03), mull);
+      v.position.set(wx-0.01, wy, -D*0.10); scene.add(v);
+      const hbar = new THREE.Mesh(new THREE.BoxGeometry(0.03, 0.03, ww), mull);
+      hbar.position.set(wx-0.01, wy, -D*0.10); scene.add(hbar);
+    })();
+
+    // ================= FURNITURE silhouette =================
+    (function sofa(){
+      const grp = new THREE.Group();
+      const mat = new THREE.MeshStandardMaterial({ color:0xcfc4b0, roughness:0.95 });
+      const base = new THREE.Mesh(new THREE.BoxGeometry(2.2, 0.45, 0.95), mat);
+      base.position.y = 0.32; base.castShadow = true; base.receiveShadow=true; grp.add(base);
+      const back = new THREE.Mesh(new THREE.BoxGeometry(2.2, 0.7, 0.22), mat);
+      back.position.set(0, 0.62, -0.36); back.castShadow=true; grp.add(back);
+      const seat = new THREE.Mesh(new THREE.BoxGeometry(2.05, 0.18, 0.78), new THREE.MeshStandardMaterial({color:0xe7ddc8, roughness:1}));
+      seat.position.set(0, 0.58, 0.04); seat.castShadow=true; grp.add(seat);
+      [-1.0,1.0].forEach(x=>{ const a=new THREE.Mesh(new THREE.BoxGeometry(0.2,0.6,0.95),mat); a.position.set(x,0.45,0); a.castShadow=true; grp.add(a); });
+      grp.position.set(0, 0, -D/2 + 0.78);  // against the back wall
+      grp.rotation.y = 0;
+      scene.add(grp);
+      // round rug
+      const rug = new THREE.Mesh(new THREE.CircleGeometry(1.7, 48),
+        new THREE.MeshStandardMaterial({ color:0xb9a88c, roughness:1 }));
+      rug.rotation.x = -Math.PI/2; rug.position.set(0, 0.012, -D/2 + 1.7); rug.receiveShadow=true; scene.add(rug);
+      // a floor lamp by the sofa (gives the lamp glow a body)
+      const pole = new THREE.Mesh(new THREE.CylinderGeometry(0.02,0.02,1.5,12), new THREE.MeshStandardMaterial({color:0x3a3026}));
+      pole.position.set(W*0.32, 0.75, -D*0.30); scene.add(pole);
+      const shade = new THREE.Mesh(new THREE.CylinderGeometry(0.18,0.24,0.28,20),
+        new THREE.MeshStandardMaterial({color:0xfff1d8, emissive:0xffe6c0, emissiveIntensity:0.6, roughness:1}));
+      shade.position.set(W*0.32, 1.5, -D*0.30); scene.add(shade);
+    })();
+
+    // ================= WALLPAPER TEXTURE =================
+    let designs = [];
+    let active = -1;
+
+    function applyTexture(t){
+      t.wrapS = t.wrapT = THREE.RepeatWrapping;
+      if ('colorSpace' in t) t.colorSpace = THREE.SRGBColorSpace;
+      else if ('encoding' in t) t.encoding = THREE.sRGBEncoding;
+      t.anisotropy = renderer.capabilities.getMaxAnisotropy();
+      // The tile image is one horizontal repeat (27") wide; its physical HEIGHT
+      // is 27" * (imgH/imgW). Respect that aspect so the pattern isn't squashed.
+      const iw = (t.image && t.image.width)  || 2000;
+      const ih = (t.image && t.image.height) || 2500;
+      const tileW = REPEAT_M;                 // 27" wide
+      const tileH = REPEAT_M * (ih / iw);     // proportional height
+      walls.forEach(w=>{
+        const tt = t.clone(); tt.needsUpdate = true;
+        tt.wrapS = tt.wrapT = THREE.RepeatWrapping;
+        if ('colorSpace' in tt) tt.colorSpace = THREE.SRGBColorSpace;
+        tt.anisotropy = t.anisotropy;
+        // repeats = wall_dimension / physical_tile_dimension
+        tt.repeat.set(w.material.userData.wallW / tileW, H / tileH);
+        w.material.map = tt;
+        w.material.color.set(0xffffff);
+        w.material.needsUpdate = true;
+      });
+    }
+
+    function pickDesign(i){
+      const d = designs[i]; if(!d) return;
+      active = i;
+      document.querySelectorAll('.swatch').forEach((el,k)=> el.classList.toggle('active', k===i));
+      document.getElementById('now').querySelector('b').textContent = d.pattern_name || d.sku;
+      document.getElementById('meta').textContent =
+        (d.collection || 'China Seas') + (d.repeat ? ' · ' + d.repeat + '" repeat' : '');
+      const url = d.tile || d.image;
+      tex.loader.load(url, applyTexture, undefined, (e)=>{
+        // fallback to the flat product image if tile fails
+        if (url !== d.image && d.image) tex.loader.load(d.image, applyTexture);
+        else console.warn('texture load failed', url, e);
+      });
+    }
+
+    function buildStrip(){
+      const strip = document.getElementById('strip');
+      strip.innerHTML = '';
+      designs.forEach((d,i)=>{
+        const el = document.createElement('div');
+        el.className = 'swatch';
+        el.innerHTML = '<img alt="" src="'+(d.tile||d.image)+'"><span>'+
+          ((d.pattern_name||d.sku).split(/[-–]/)[0].trim())+'</span>';
+        el.addEventListener('click', ()=> pickDesign(i));
+        strip.appendChild(el);
+      });
+    }
+
+    // ---- boot ----
+    fetch('/api/showroom/products?limit=24')
+      .then(r=>r.json())
+      .then(j=>{
+        const list = (j.products||j||[]).filter(p=> p.tile || p.image);
+        designs = list.slice(0, 18);
+        if (!designs.length) throw new Error('no designs');
+        buildStrip();
+        // preload first then reveal
+        const first = designs[0];
+        tex.loader.load(first.tile || first.image, (t)=>{
+          applyTexture(t);
+          active = 0;
+          pickDesign(0);
+          reveal();
+        }, undefined, ()=>{ pickDesign(0); reveal(); });
+      })
+      .catch(err=>{
+        console.error('boot error', err);
+        // still show the room with the neutral wall so it's not a black screen
+        reveal();
+      });
+
+    function reveal(){
+      const ld = document.getElementById('loading');
+      ld.classList.add('gone');
+      const hint = document.getElementById('hint');
+      hint.classList.add('show');
+      setTimeout(()=> hint.classList.remove('show'), 4200);
+      setTimeout(()=> ld.remove(), 700);
+    }
+
+    // ---- resize ----
+    window.addEventListener('resize', ()=>{
+      camera.aspect = window.innerWidth/window.innerHeight;
+      camera.updateProjectionMatrix();
+      renderer.setSize(window.innerWidth, window.innerHeight);
+    });
+
+    // ---- render loop ----
+    let t0 = performance.now();
+    function tick(){
+      requestAnimationFrame(tick);
+      controls.update();
+      lockPivot();          // keep first-person pivot at the eye
+      renderer.render(scene, camera);
+    }
+    tick();
+
+    // expose for verification
+    window.__walkin = {
+      ready: ()=> active >= 0 && walls[0].material.map != null,
+      designs: ()=> designs.length,
+      active: ()=> active,
+    };
+  })();
+  </script>
+</body>
+</html>
diff --git a/proto/verify-v10.cjs b/proto/verify-v10.cjs
new file mode 100644
index 0000000..2da3949
--- /dev/null
+++ b/proto/verify-v10.cjs
@@ -0,0 +1,80 @@
+const { chromium } = require('playwright');
+const path = require('path');
+const fs = require('fs');
+
+(async () => {
+  const shotsDir = path.join(__dirname, 'shots');
+  fs.mkdirSync(shotsDir, { recursive: true });
+  // Serve the proto same-origin (proxies /api -> backend :7690) so CORS isn't an issue,
+  // exactly as it'll behave behind proto/proxy-server.cjs in real use.
+  const { spawn } = require('child_process');
+  const PORT = 7693;
+  const srv = spawn(process.execPath, [path.join(__dirname, 'proxy-server.cjs')],
+    { env: { ...process.env, PROTO_PORT: String(PORT) }, stdio: 'inherit' });
+  await new Promise(r => setTimeout(r, 700));
+  const fileUrl = `http://127.0.0.1:${PORT}/v10-concierge.html`;
+
+  const browser = await chromium.launch({ headless: true });
+  const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } });
+  const page = await ctx.newPage();
+
+  const errors = [];
+  page.on('console', m => { if (m.type() === 'error') errors.push(m.text()); });
+  page.on('pageerror', e => errors.push('PAGEERROR: ' + e.message));
+
+  await page.goto(fileUrl, { waitUntil: 'networkidle' });
+
+  // wait for feed to load (concierge announces board count)
+  await page.waitForFunction(() => window.PRODUCTS && window.PRODUCTS.length > 0, { timeout: 8000 })
+    .catch(() => {});
+  const total = await page.evaluate(() => (window.PRODUCTS || []).length);
+  console.log('Products loaded:', total);
+
+  // ---- Query 1: "show me blues" via API ----
+  const q1 = await page.evaluate(() => {
+    const { results } = window.runQuery('show me blues');
+    const allBlue = results.every(p => /aqua|blue|navy|turquoise|capri/i.test(p.pattern_name));
+    return { n: results.length, allBlue, sample: results.slice(0,3).map(p=>p.pattern_name) };
+  });
+  console.log('Q1 "show me blues":', q1.n, 'results, all blue-named:', q1.allBlue);
+  console.log('   sample:', q1.sample);
+
+  // ---- Query 2: "like Aga but darker" ----
+  const q2 = await page.evaluate(() => {
+    const { results } = window.runQuery('like Aga but darker');
+    const allAga = results.every(p => /^aga/i.test(p.pattern_name));
+    return { n: results.length, allAga, sample: results.slice(0,4).map(p=>p.pattern_name) };
+  });
+  console.log('Q2 "like Aga but darker":', q2.n, 'results, all Aga family:', q2.allAga);
+  console.log('   sample:', q2.sample);
+
+  // ---- Query 3: stripes (style) ----
+  const q3 = await page.evaluate(() => {
+    const { results } = window.runQuery('something with stripes');
+    return { n: results.length, sample: results.slice(0,3).map(p=>p.pattern_name) };
+  });
+  console.log('Q3 "stripes":', q3.n, 'results; sample:', q3.sample);
+
+  // ---- Drive the UI: click a chip and confirm boards render in DOM ----
+  await page.click('text=Warm neutrals');
+  await page.waitForTimeout(900);
+  const boardsRendered = await page.evaluate(() => document.querySelectorAll('.board').length);
+  console.log('Warm neutrals chip -> boards in DOM:', boardsRendered);
+
+  // type into the box for the screenshot beauty shot
+  await page.fill('#askInput', 'like Aga but darker');
+  await page.click('.ask button');
+  await page.waitForTimeout(1000);
+  const finalBoards = await page.evaluate(() => document.querySelectorAll('.board').length);
+  console.log('Final on-table boards:', finalBoards);
+
+  await page.screenshot({ path: path.join(shotsDir, 'v10-concierge.png'), fullPage: false });
+  console.log('Screenshot -> shots/v10-concierge.png');
+
+  console.log('\nConsole errors:', errors.length);
+  errors.forEach(e => console.log('  ✗', e));
+
+  await browser.close();
+  srv.kill();
+  process.exit(errors.length ? 2 : 0);
+})();
diff --git a/proto/verify-v8.cjs b/proto/verify-v8.cjs
new file mode 100644
index 0000000..4b2893a
--- /dev/null
+++ b/proto/verify-v8.cjs
@@ -0,0 +1,73 @@
+const { chromium } = require('playwright');
+const path = require('path');
+const fs = require('fs');
+
+(async () => {
+  const shotsDir = path.join(__dirname, 'shots');
+  fs.mkdirSync(shotsDir, { recursive: true });
+  const fileUrl = 'file://' + path.join(__dirname, 'v8-swipe.html');
+
+  const browser = await chromium.launch();
+  const ctx = await browser.newContext({ viewport: { width: 1280, height: 860 }, deviceScaleFactor: 2 });
+  const page = await ctx.newPage();
+
+  const errors = [];
+  page.on('console', m => { if (m.type() === 'error') errors.push(m.text()); });
+  page.on('pageerror', e => errors.push('PAGEERROR: ' + e.message));
+
+  // Fulfill the live-API request with REAL data fetched server-side (Node),
+  // proving the page renders the actual showroom payload — bypasses the
+  // file:// CORS wall that only exists for the standalone testing case.
+  let liveOk = false, liveCount = 0;
+  await page.route('**/api/showroom/products**', async route => {
+    try {
+      const res = await fetch('http://127.0.0.1:7690/api/showroom/products?limit=120');
+      const body = await res.text();
+      liveOk = true;
+      try { liveCount = (JSON.parse(body).products || []).length; } catch(_) {}
+      route.fulfill({ status: 200, contentType: 'application/json', body });
+    } catch (e) {
+      route.abort();
+    }
+  });
+
+  await page.goto(fileUrl, { waitUntil: 'networkidle' });
+  // wait for first card to render
+  await page.waitForSelector('.card[data-depth="0"]', { timeout: 8000 });
+  await page.waitForTimeout(900); // let swatch images load
+
+  // initial screenshot
+  await page.screenshot({ path: path.join(shotsDir, 'v8-swipe.png') });
+
+  // drive: keep, keep, skip, keep, skip  -> expect 3 favorites
+  const seq = ['keep','keep','skip','keep','skip'];
+  for (const v of seq) {
+    await page.click(v === 'keep' ? '#keepBtn' : '#skipBtn');
+    await page.waitForTimeout(520);
+  }
+
+  const favCount = await page.$eval('#favCt', e => e.textContent.trim());
+  const seenCount = await page.$eval('#seenCt', e => e.textContent.trim());
+  const favRows = await page.$$eval('.fav', n => n.length);
+
+  // test undo
+  await page.click('#undoBtn');
+  await page.waitForTimeout(400);
+  const seenAfterUndo = await page.$eval('#seenCt', e => e.textContent.trim());
+
+  // test keyboard arrow keep
+  await page.keyboard.press('ArrowRight');
+  await page.waitForTimeout(520);
+
+  // final screenshot with favorites tray filled
+  await page.screenshot({ path: path.join(shotsDir, 'v8-swipe-filled.png') });
+
+  console.log(JSON.stringify({
+    liveApiUsed: liveOk, liveApiCount: liveCount,
+    favCount, seenCount, favRows, seenAfterUndo,
+    consoleErrors: errors,
+    pass: errors.length === 0 && favRows > 0 && liveOk
+  }, null, 2));
+
+  await browser.close();
+})().catch(e => { console.error('VERIFY FAILED:', e); process.exit(1); });
diff --git a/public/js/showroom.js b/public/js/showroom.js
index 753d5b6..691b598 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -20,7 +20,7 @@ const CONFIG = {
     // brass rail, each hinged on its LEFT vertical edge, raked so packed they show only
     // a thin vertical SLIVER of each pattern (occlusion gives the sliver for free).
     arcRadius: 3.3,                  // radius of the curved rail (m)
-    arcSpanDeg: 112,                 // total angular sweep of the arc (wraps the corner/bay)
+    arcSpanDeg: 86,                  // tighter sweep → boards overlap ~75% → THIN slivers
     arcCenter: { x: -0.3, z: -1.2 }, // arc centre in room space (boards face inward → viewer)
     sliverPitchScale: 1.0            // multiplier on the angular pitch (reveal slider can thin)
   },
@@ -112,7 +112,7 @@ function init() {
   renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 1.5));
   if (THREE.sRGBEncoding) renderer.outputEncoding = THREE.sRGBEncoding; // correct gamma → no washed-out look
   renderer.toneMapping = THREE.ACESFilmicToneMapping;
-  renderer.toneMappingExposure = 1.12; // brighter clean gallery exposure
+  renderer.toneMappingExposure = 1.02; // calm warm gallery exposure (was blowing out the plaster)
   renderer.shadowMap.enabled = true;             // contact shadows = the #1 realism lever
   // Soft PCF — penumbra blur on the wing/furniture shadows reads far more believable than
   // hard PCF. Cost is modest at one shadow-casting light; the adaptive guard protects FPS.
@@ -284,7 +284,7 @@ function initMaterials() {
     normalMap: loadDataTex('wall-limewash-normal', 2, 1.4),
     normalScale: new THREE.Vector2(0.2, 0.2),
     roughnessMap: loadDataTex('wall-limewash-rough', 2, 1.4),
-    color: 0xfbf7ef, roughness: 1.0, metalness: 0.0, envMapIntensity: 0.3
+    color: 0xefe6d4, roughness: 1.0, metalness: 0.0, envMapIntensity: 0.3
   });
   MAT.chrome = new THREE.MeshStandardMaterial({ color: 0xc9a96e, roughness: 0.25, metalness: 0.9, envMapIntensity: 1.0 }); // brushed brass
   MAT.wood = new THREE.MeshStandardMaterial({ color: 0x6b4a32, roughness: 0.5, metalness: 0.0, envMapIntensity: 0.5 }); // satin walnut
@@ -306,7 +306,7 @@ function initMaterials() {
     normalMap: loadDataTex('wall-limewash-normal', 1.6, 1.6),
     normalScale: new THREE.Vector2(0.2, 0.2),
     roughnessMap: loadDataTex('wall-limewash-rough', 1.6, 1.6),
-    color: 0xfbf7ef, roughness: 1.0, metalness: 0.0, envMapIntensity: 0.3
+    color: 0xefe6d4, roughness: 1.0, metalness: 0.0, envMapIntensity: 0.3
   });
 }
 
@@ -748,8 +748,10 @@ function buildLighting() {
   // wallcovering swatches read crisp and true-colour, not greyed by moody low-key shadow.
   // Committed to ONE dominant key (below) for photographic modelling; fill kept high
   // enough that the wallcovering swatch colour stays true + legible.
-  scene.add(new THREE.AmbientLight(0xffffff, 0.5));
-  scene.add(new THREE.HemisphereLight(0xfffdf8, 0xe6ded2, 0.45)); // sky/ground bounce — warm, even
+  // Warmer, slightly calmer wash than a pure white-box so the plaster reads CREAM (like
+  // the PJ Dallas photo) instead of blown-out white — the swatches still read true.
+  scene.add(new THREE.AmbientLight(0xfff3e2, 0.42));
+  scene.add(new THREE.HemisphereLight(0xfff1e0, 0xe4d8c4, 0.42)); // warm sky / warm-stone ground bounce
 
   // KEY light — soft, gentle shadow (clean contact, not dramatic)
   const key = new THREE.DirectionalLight(0xfff6ea, 1.05);  // dominant warm key — clear light direction
diff --git a/scripts/enrich.js b/scripts/enrich.js
new file mode 100644
index 0000000..5d6dae6
--- /dev/null
+++ b/scripts/enrich.js
@@ -0,0 +1,56 @@
+#!/usr/bin/env node
+/**
+ * enrich.js — RESEARCH.md data wins for the version mechanics. Produces
+ * data/enrichment.json: sku -> { patternBase, family colorways, room, hue, color_bucket }.
+ * - patternBase + family: split pattern_name on " on " (instant, powers pairs-well-with).
+ * - room: surface the existing room image (~41% have one).
+ * - hue + color_bucket: dominant colour per swatch via sharp (powers Color River / Fan).
+ * Writes patternBase/room/family immediately, then fills hue in the background pass.
+ */
+const fs = require('fs');
+const path = require('path');
+const https = require('https');
+
+const DATA = path.join(__dirname, '..', 'data', 'showroom-products.json');
+const OUT = path.join(__dirname, '..', 'data', 'enrichment.json');
+const products = JSON.parse(fs.readFileSync(DATA, 'utf8')).products;
+
+// ---- 1+2: patternBase / family / room (instant) ----
+const baseOf = (name) => (name || '').split(/\s+on\s+/i)[0].replace(/\s+screen\s*print.*$/i, '').trim() || (name || 'Pattern');
+const enrich = {};
+const families = {};
+products.forEach(p => {
+  const base = baseOf(p.pattern_name || p.name);
+  enrich[p.sku] = { patternBase: base, room: p.room || null, hue: null, color_bucket: null };
+  (families[base] = families[base] || []).push(p.sku);
+});
+products.forEach(p => { enrich[p.sku].familySkus = families[enrich[p.sku].patternBase].filter(s => s !== p.sku).slice(0, 12); });
+fs.writeFileSync(OUT, JSON.stringify({ built_at: new Date().toISOString(), hue_done: false, enrich }, null, 0));
+console.log(`[enrich] patternBase/room/family written for ${products.length} skus; ${Object.keys(families).length} families`);
+
+// ---- 3: dominant hue via sharp (background) ----
+let sharp; try { sharp = require('sharp'); } catch { console.log('[enrich] sharp not installed — run: npm i sharp  (hue skipped)'); process.exit(0); }
+const BUCKETS = [[15,'red'],[45,'orange'],[70,'yellow'],[170,'green'],[200,'teal'],[255,'blue'],[290,'purple'],[330,'magenta'],[360,'red']];
+const rgb2hue = (r,g,b)=>{r/=255;g/=255;b/=255;const mx=Math.max(r,g,b),mn=Math.min(r,g,b),d=mx-mn;let h=0;if(d){if(mx===r)h=((g-b)/d)%6;else if(mx===g)h=(b-r)/d+2;else h=(r-g)/d+4;h*=60;if(h<0)h+=360;}const s=mx===0?0:d/mx;return {h:Math.round(h),s,v:mx};};
+const fetchBuf = (url)=>new Promise((res,rej)=>{https.get(url,r=>{if(r.statusCode>=400){r.resume();return rej(new Error(r.statusCode));}const c=[];r.on('data',d=>c.push(d));r.on('end',()=>res(Buffer.concat(c)));}).on('error',rej);});
+
+(async()=>{
+  let done=0, fail=0;
+  for (const p of products) {
+    const url = p.image; if (!url || !/^https/.test(url)) { fail++; continue; }
+    try {
+      const buf = await fetchBuf(url);
+      const { data } = await sharp(buf).resize(16,16,{fit:'fill'}).removeAlpha().raw().toBuffer({resolveWithObject:true});
+      // average only reasonably-saturated pixels so the hue reflects the design, not the ground
+      let r=0,g=0,b=0,n=0;
+      for(let i=0;i<data.length;i+=3){const hsv=rgb2hue(data[i],data[i+1],data[i+2]);if(hsv.s>0.18){r+=data[i];g+=data[i+1];b+=data[i+2];n++;}}
+      if(!n){for(let i=0;i<data.length;i+=3){r+=data[i];g+=data[i+1];b+=data[i+2];n++;}}
+      const {h}=rgb2hue(r/n,g/n,b/n);
+      enrich[p.sku].hue=h; enrich[p.sku].color_bucket=BUCKETS.find(x=>h<=x[0])[1];
+      done++;
+      if(done%100===0){fs.writeFileSync(OUT,JSON.stringify({built_at:new Date().toISOString(),hue_done:false,enrich},null,0));console.log(`[enrich] hue ${done}/${products.length}`);}
+    } catch(e){ fail++; }
+  }
+  fs.writeFileSync(OUT,JSON.stringify({built_at:new Date().toISOString(),hue_done:true,hue_filled:done,hue_failed:fail,enrich},null,0));
+  console.log(`[enrich] DONE hue: ${done} filled, ${fail} failed -> ${OUT}`);
+})();

← 72bd476 proto v7: mood-board table — drag swatches, build palette, p  ·  back to Quadrille Showroom  ·  proto: COLOR RIVER — shop China Seas by hue as a flowing Thr 597fb5b →