[object Object]

← back to Designer Wallcoverings

Local room-engine bake-off: FLUX Kontext + SDXL/IP-Adapter + PIL

0302bcadffbdb7831e6ab572dffab0e6eaad0988 · 2026-07-07 07:55:35 -0700 · Steve

Replace paid Gemini room composites with local diffusion (M3 Ultra, $0/room):
- batch_kontext.sh (mflux FLUX Kontext, non-gated akx 4-bit), batch_sdxl.py
  (SDXL inpaint + IP-Adapter ViT-H, exact-swatch texture), pil_compose.py baseline
- make_wall_mask.py, empty-room + wall-mask bakeoff assets, manifest (67 SKUs)
- compare-rooms.html live gallery: swatch|Gemini|Kontext|SDXL, click-to-pick winner
- idempotent + resumable batches -> rooms-local/ (gitignored, reboot-safe)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 0302bcadffbdb7831e6ab572dffab0e6eaad0988
Author: Steve <steve@designerwallcoverings.com>
Date:   Tue Jul 7 07:55:35 2026 -0700

    Local room-engine bake-off: FLUX Kontext + SDXL/IP-Adapter + PIL
    
    Replace paid Gemini room composites with local diffusion (M3 Ultra, $0/room):
    - batch_kontext.sh (mflux FLUX Kontext, non-gated akx 4-bit), batch_sdxl.py
      (SDXL inpaint + IP-Adapter ViT-H, exact-swatch texture), pil_compose.py baseline
    - make_wall_mask.py, empty-room + wall-mask bakeoff assets, manifest (67 SKUs)
    - compare-rooms.html live gallery: swatch|Gemini|Kontext|SDXL, click-to-pick winner
    - idempotent + resumable batches -> rooms-local/ (gitignored, reboot-safe)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 .../bakeoff-assets/empty-room.png                  | Bin 0 -> 1550562 bytes
 .../bakeoff-assets/wall-mask.png                   | Bin 0 -> 3204 bytes
 .../carl-robinson-viewer/compare-rooms.html        | 500 +++++++++++++++++++++
 .../room-engines/batch_kontext.sh                  |  47 ++
 .../room-engines/batch_sdxl.py                     |  58 +++
 .../room-engines/build_comparison.py               |  77 ++++
 .../room-engines/make_wall_mask.py                 |  29 ++
 .../carl-robinson-viewer/room-engines/manifest.tsv |  67 +++
 .../room-engines/pil_compose.py                    |  42 ++
 .../carl-robinson-viewer/room-engines/sdxl_ipa.py  |  43 ++
 10 files changed, 863 insertions(+)

diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/empty-room.png b/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/empty-room.png
new file mode 100644
index 00000000..6331a33f
Binary files /dev/null and b/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/empty-room.png differ
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/wall-mask.png b/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/wall-mask.png
new file mode 100644
index 00000000..0fe23035
Binary files /dev/null and b/scripts/wallquest-refresh/carl-robinson-viewer/bakeoff-assets/wall-mask.png differ
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/compare-rooms.html b/scripts/wallquest-refresh/carl-robinson-viewer/compare-rooms.html
new file mode 100644
index 00000000..00c06b89
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/compare-rooms.html
@@ -0,0 +1,500 @@
+<!doctype html><meta charset=utf-8><title>CR Room Engine Bake-off</title>
+<style>
+ body{font:14px/1.4 -apple-system,system-ui,sans-serif;margin:0;background:#111;color:#eee}
+ header{position:sticky;top:0;background:#1b1b1b;padding:12px 18px;border-bottom:1px solid #333;z-index:5}
+ h1{font-size:16px;margin:0 0 4px} .prog{color:#9ad}
+ .card{border-bottom:1px solid #262626;padding:14px 18px}
+ .hd{font-weight:600;margin-bottom:8px;color:#ddd}
+ .row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
+ .cell{background:#191919;border:1px solid #2a2a2a;border-radius:8px;overflow:hidden}
+ .lbl{font-size:11px;color:#9a9a9a;padding:5px 8px;border-bottom:1px solid #2a2a2a}
+ .cell img{width:100%;display:block;aspect-ratio:1;object-fit:cover}
+ .pending{aspect-ratio:1;display:flex;align-items:center;justify-content:center;color:#666;font-style:italic}
+ .pick{text-align:center;font-size:11px;color:#7c7;padding:5px;cursor:pointer;user-select:none}
+ .pick.on{background:#2a5;color:#fff;font-weight:600}
+</style>
+<header>
+ <h1>Carl Robinson &rarr; Phillipe Romano &mdash; Local Room Engine Bake-off</h1>
+ <div class="prog">Kontext 0/67 &middot; SDXL 1/67 rendered &middot; all local, $0 &middot; refresh to update</div>
+</header>
+<div class="card">
+      <div class="hd">BAM-100048 &middot; Bamboo &middot; Sour Cream</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/BAM-100048.jpg" loading="lazy"><div class="pick" data-sku="BAM-100048" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50004-living.png" loading="lazy"><div class="pick" data-sku="BAM-100048" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><img src="rooms-local/BAM-100048-sdxl.png" loading="lazy"><div class="pick" data-sku="BAM-100048" data-eng="sdxl">pick sdxl</div></div>
+      </div></div><div class="card">
+      <div class="hd">BAM-100049 &middot; Bamboo &middot; Sea Shell</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/BAM-100049.jpg" loading="lazy"><div class="pick" data-sku="BAM-100049" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50005-living.png" loading="lazy"><div class="pick" data-sku="BAM-100049" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">BAM-100050 &middot; Bamboo &middot; Mica</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/BAM-100050.jpg" loading="lazy"><div class="pick" data-sku="BAM-100050" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50024-living.png" loading="lazy"><div class="pick" data-sku="BAM-100050" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">BAM-100051 &middot; Bamboo &middot; Silver Lining</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/BAM-100051.jpg" loading="lazy"><div class="pick" data-sku="BAM-100051" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50028-living.png" loading="lazy"><div class="pick" data-sku="BAM-100051" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">BAM-100052 &middot; Bamboo &middot; Shaved Ice</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/BAM-100052.jpg" loading="lazy"><div class="pick" data-sku="BAM-100052" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50029-living.png" loading="lazy"><div class="pick" data-sku="BAM-100052" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">CORK-100057 &middot; Cork &middot; Chalk</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/DWCR-50001.jpeg" loading="lazy"><div class="pick" data-sku="CORK-100057" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50001-living.png" loading="lazy"><div class="pick" data-sku="CORK-100057" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">CORK-100058 &middot; Cork &middot; Water Lily</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/DWCR-50026.jpeg" loading="lazy"><div class="pick" data-sku="CORK-100058" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50026-living.png" loading="lazy"><div class="pick" data-sku="CORK-100058" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">FIB-100059 &middot; Fiber &middot; Birch Bark</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/FIB-100059.jpg" loading="lazy"><div class="pick" data-sku="FIB-100059" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50012-living.png" loading="lazy"><div class="pick" data-sku="FIB-100059" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">FIB-100060 &middot; Fiber &middot; Cool Linen</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/FIB-100060.jpg" loading="lazy"><div class="pick" data-sku="FIB-100060" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50021-living.png" loading="lazy"><div class="pick" data-sku="FIB-100060" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100020 &middot; Grasscloth &middot; Plaster</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100020.jpg" loading="lazy"><div class="pick" data-sku="GRS-100020" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50002-living.png" loading="lazy"><div class="pick" data-sku="GRS-100020" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100021 &middot; Grasscloth &middot; Gauze</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100021.jpg" loading="lazy"><div class="pick" data-sku="GRS-100021" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50008-living.png" loading="lazy"><div class="pick" data-sku="GRS-100021" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100022 &middot; Grasscloth &middot; Bleached Coral</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100022.jpg" loading="lazy"><div class="pick" data-sku="GRS-100022" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50011-living.png" loading="lazy"><div class="pick" data-sku="GRS-100022" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100023 &middot; Grasscloth &middot; Iceberg</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100023.jpg" loading="lazy"><div class="pick" data-sku="GRS-100023" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50013-living.png" loading="lazy"><div class="pick" data-sku="GRS-100023" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100024 &middot; Grasscloth &middot; Egret</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100024.jpg" loading="lazy"><div class="pick" data-sku="GRS-100024" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50014-living.png" loading="lazy"><div class="pick" data-sku="GRS-100024" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100025 &middot; Grasscloth &middot; Almond</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100025.jpg" loading="lazy"><div class="pick" data-sku="GRS-100025" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50016-living.png" loading="lazy"><div class="pick" data-sku="GRS-100025" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100026 &middot; Grasscloth &middot; Roasted Marshmallow</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100026.jpg" loading="lazy"><div class="pick" data-sku="GRS-100026" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50017-living.png" loading="lazy"><div class="pick" data-sku="GRS-100026" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100027 &middot; Grasscloth &middot; Stardust</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100027.jpg" loading="lazy"><div class="pick" data-sku="GRS-100027" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50018-living.png" loading="lazy"><div class="pick" data-sku="GRS-100027" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100028 &middot; Grasscloth &middot; Moon</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100028.jpg" loading="lazy"><div class="pick" data-sku="GRS-100028" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50020-living.png" loading="lazy"><div class="pick" data-sku="GRS-100028" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100029 &middot; Grasscloth &middot; Vanilla</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100029.jpg" loading="lazy"><div class="pick" data-sku="GRS-100029" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50025-living.png" loading="lazy"><div class="pick" data-sku="GRS-100029" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100030 &middot; Grasscloth &middot; Ghost White</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100030.jpg" loading="lazy"><div class="pick" data-sku="GRS-100030" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50036-living.png" loading="lazy"><div class="pick" data-sku="GRS-100030" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100031 &middot; Grasscloth &middot; Bone</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100031.jpg" loading="lazy"><div class="pick" data-sku="GRS-100031" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50037-living.png" loading="lazy"><div class="pick" data-sku="GRS-100031" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100032 &middot; Grasscloth &middot; Parchment</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100032.jpg" loading="lazy"><div class="pick" data-sku="GRS-100032" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50039-living.png" loading="lazy"><div class="pick" data-sku="GRS-100032" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">GRS-100033 &middot; Grasscloth &middot; Sun Kissed</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/GRS-100033.jpg" loading="lazy"><div class="pick" data-sku="GRS-100033" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50042-living.png" loading="lazy"><div class="pick" data-sku="GRS-100033" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">JUT-100061 &middot; Jute &middot; Cotton</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/JUT-100061.jpg" loading="lazy"><div class="pick" data-sku="JUT-100061" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50034-living.png" loading="lazy"><div class="pick" data-sku="JUT-100061" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">JUT-100062 &middot; Jute &middot; Eggshell</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/JUT-100062.jpg" loading="lazy"><div class="pick" data-sku="JUT-100062" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50040-living.png" loading="lazy"><div class="pick" data-sku="JUT-100062" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">MIC-100065 &middot; Mica &middot; Mother of Pearl</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/DWCR-50019.jpeg" loading="lazy"><div class="pick" data-sku="MIC-100065" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50019-living.png" loading="lazy"><div class="pick" data-sku="MIC-100065" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100042 &middot; Netting &middot; Tan</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100042.jpg" loading="lazy"><div class="pick" data-sku="NET-100042" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50055-living.png" loading="lazy"><div class="pick" data-sku="NET-100042" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100043 &middot; Netting &middot; Sand</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100043.jpg" loading="lazy"><div class="pick" data-sku="NET-100043" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50056-living.png" loading="lazy"><div class="pick" data-sku="NET-100043" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100044 &middot; Netting &middot; Tusk</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100044.jpg" loading="lazy"><div class="pick" data-sku="NET-100044" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50058-living.png" loading="lazy"><div class="pick" data-sku="NET-100044" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100045 &middot; Netting &middot; Flour</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100045.jpg" loading="lazy"><div class="pick" data-sku="NET-100045" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50059-living.png" loading="lazy"><div class="pick" data-sku="NET-100045" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100046 &middot; Netting &middot; Paper</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100046.jpg" loading="lazy"><div class="pick" data-sku="NET-100046" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50060-living.png" loading="lazy"><div class="pick" data-sku="NET-100046" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NET-100047 &middot; Netting &middot; Lurex</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/NET-100047.jpg" loading="lazy"><div class="pick" data-sku="NET-100047" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50061-living.png" loading="lazy"><div class="pick" data-sku="NET-100047" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">NWV-100066 &middot; Nonwoven &middot; Raw Silk</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/DWCR-50031.jpeg" loading="lazy"><div class="pick" data-sku="NWV-100066" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50031-living.png" loading="lazy"><div class="pick" data-sku="NWV-100066" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100001 &middot; Paperweave &middot; Winter white</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100001.jpg" loading="lazy"><div class="pick" data-sku="PWV-100001" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50007-living.png" loading="lazy"><div class="pick" data-sku="PWV-100001" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100002 &middot; Paperweave &middot; Arctic white</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100002.jpg" loading="lazy"><div class="pick" data-sku="PWV-100002" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50009-living.png" loading="lazy"><div class="pick" data-sku="PWV-100002" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100003 &middot; Paperweave &middot; Frost</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100003.jpg" loading="lazy"><div class="pick" data-sku="PWV-100003" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50015-living.png" loading="lazy"><div class="pick" data-sku="PWV-100003" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100004 &middot; Paperweave &middot; Sail</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100004.jpg" loading="lazy"><div class="pick" data-sku="PWV-100004" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50032-living.png" loading="lazy"><div class="pick" data-sku="PWV-100004" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100005 &middot; Paperweave &middot; Crushed Silk</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100005.jpg" loading="lazy"><div class="pick" data-sku="PWV-100005" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50033-living.png" loading="lazy"><div class="pick" data-sku="PWV-100005" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100006 &middot; Paperweave &middot; Tissue</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100006.jpg" loading="lazy"><div class="pick" data-sku="PWV-100006" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50035-living.png" loading="lazy"><div class="pick" data-sku="PWV-100006" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100007 &middot; Paperweave &middot; Cabana Linen</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100007.jpg" loading="lazy"><div class="pick" data-sku="PWV-100007" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50041-living.png" loading="lazy"><div class="pick" data-sku="PWV-100007" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100008 &middot; Paperweave &middot; Wool</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100008.jpg" loading="lazy"><div class="pick" data-sku="PWV-100008" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50048-living.png" loading="lazy"><div class="pick" data-sku="PWV-100008" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100009 &middot; Paperweave &middot; Meringue</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100009.jpg" loading="lazy"><div class="pick" data-sku="PWV-100009" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50049-living.png" loading="lazy"><div class="pick" data-sku="PWV-100009" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100010 &middot; Paperweave &middot; Honeysuckle</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100010.jpg" loading="lazy"><div class="pick" data-sku="PWV-100010" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50050-living.png" loading="lazy"><div class="pick" data-sku="PWV-100010" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100011 &middot; Paperweave &middot; White Chocolate</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100011.jpg" loading="lazy"><div class="pick" data-sku="PWV-100011" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50051-living.png" loading="lazy"><div class="pick" data-sku="PWV-100011" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100012 &middot; Paperweave &middot; Foil</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100012.jpg" loading="lazy"><div class="pick" data-sku="PWV-100012" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50052-living.png" loading="lazy"><div class="pick" data-sku="PWV-100012" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100013 &middot; Paperweave &middot; Brushed Silver</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100013.jpg" loading="lazy"><div class="pick" data-sku="PWV-100013" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50053-living.png" loading="lazy"><div class="pick" data-sku="PWV-100013" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100014 &middot; Paperweave &middot; Rice Paper</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100014.jpg" loading="lazy"><div class="pick" data-sku="PWV-100014" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50054-living.png" loading="lazy"><div class="pick" data-sku="PWV-100014" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100015 &middot; Paperweave &middot; White Heron</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100015.jpg" loading="lazy"><div class="pick" data-sku="PWV-100015" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50057-living.png" loading="lazy"><div class="pick" data-sku="PWV-100015" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100016 &middot; Paperweave &middot; Pearla</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100016.jpg" loading="lazy"><div class="pick" data-sku="PWV-100016" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50062-living.png" loading="lazy"><div class="pick" data-sku="PWV-100016" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100017 &middot; Paperweave &middot; Off White</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100017.jpg" loading="lazy"><div class="pick" data-sku="PWV-100017" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50063-living.png" loading="lazy"><div class="pick" data-sku="PWV-100017" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100018 &middot; Paperweave &middot; Casablanca</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100018.jpg" loading="lazy"><div class="pick" data-sku="PWV-100018" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50064-living.png" loading="lazy"><div class="pick" data-sku="PWV-100018" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">PWV-100019 &middot; Paperweave &middot; Powdered Sugar</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/PWV-100019.jpg" loading="lazy"><div class="pick" data-sku="PWV-100019" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50065-living.png" loading="lazy"><div class="pick" data-sku="PWV-100019" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100034 &middot; Raffia &middot; Bleached Linen</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100034.jpg" loading="lazy"><div class="pick" data-sku="RAF-100034" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50003-living.png" loading="lazy"><div class="pick" data-sku="RAF-100034" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100035 &middot; Raffia &middot; Rice</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100035.jpg" loading="lazy"><div class="pick" data-sku="RAF-100035" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50022-living.png" loading="lazy"><div class="pick" data-sku="RAF-100035" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100036 &middot; Raffia &middot; Feather White</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100036.jpg" loading="lazy"><div class="pick" data-sku="RAF-100036" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50030-living.png" loading="lazy"><div class="pick" data-sku="RAF-100036" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100037 &middot; Raffia &middot; Latte</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100037.jpg" loading="lazy"><div class="pick" data-sku="RAF-100037" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50043-living.png" loading="lazy"><div class="pick" data-sku="RAF-100037" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100038 &middot; Raffia &middot; Cold Foam</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100038.jpg" loading="lazy"><div class="pick" data-sku="RAF-100038" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50044-living.png" loading="lazy"><div class="pick" data-sku="RAF-100038" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100039 &middot; Raffia &middot; Dove</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100039.jpg" loading="lazy"><div class="pick" data-sku="RAF-100039" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50045-living.png" loading="lazy"><div class="pick" data-sku="RAF-100039" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100040 &middot; Raffia &middot; Bleached Burlap</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100040.jpg" loading="lazy"><div class="pick" data-sku="RAF-100040" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50046-living.png" loading="lazy"><div class="pick" data-sku="RAF-100040" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">RAF-100041 &middot; Raffia &middot; Crisp White</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/RAF-100041.jpg" loading="lazy"><div class="pick" data-sku="RAF-100041" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50047-living.png" loading="lazy"><div class="pick" data-sku="RAF-100041" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SIS-100053 &middot; Sisal &middot; Buttercream</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SIS-100053.jpg" loading="lazy"><div class="pick" data-sku="SIS-100053" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50066-living.png" loading="lazy"><div class="pick" data-sku="SIS-100053" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SIS-100054 &middot; Sisal &middot; Coconut</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SIS-100054.jpg" loading="lazy"><div class="pick" data-sku="SIS-100054" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50069-living.png" loading="lazy"><div class="pick" data-sku="SIS-100054" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SIS-100055 &middot; Sisal &middot; Almond</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SIS-100055.jpg" loading="lazy"><div class="pick" data-sku="SIS-100055" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50070-living.png" loading="lazy"><div class="pick" data-sku="SIS-100055" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SIS-100056 &middot; Sisal &middot; Cream</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SIS-100056.jpg" loading="lazy"><div class="pick" data-sku="SIS-100056" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50071-living.png" loading="lazy"><div class="pick" data-sku="SIS-100056" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SLK-100063 &middot; Silk &middot; Cryslas</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SLK-100063.jpg" loading="lazy"><div class="pick" data-sku="SLK-100063" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50067-living.png" loading="lazy"><div class="pick" data-sku="SLK-100063" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">SLK-100064 &middot; Silk &middot; Cappuccino</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/SLK-100064.jpg" loading="lazy"><div class="pick" data-sku="SLK-100064" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50068-living.png" loading="lazy"><div class="pick" data-sku="SLK-100064" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div><div class="card">
+      <div class="hd">WDV-100067 &middot; Wood Veneer &middot; Candle</div>
+      <div class="row">
+        <div class="cell"><div class="lbl">Swatch</div><img src="img/DWCR-50010.jpeg" loading="lazy"><div class="pick" data-sku="WDV-100067" data-eng="swatch">pick swatch</div></div>
+        <div class="cell"><div class="lbl">Gemini (current)</div><img src="rooms/DWCR-50010-living.png" loading="lazy"><div class="pick" data-sku="WDV-100067" data-eng="gemini">pick gemini</div></div>
+        <div class="cell"><div class="lbl">FLUX Kontext (B)</div><div class="pending">rendering…</div></div>
+        <div class="cell"><div class="lbl">SDXL+IPA (C)</div><div class="pending">rendering…</div></div>
+      </div></div>
+<script>
+ // remember picks locally so Steve's winner choices survive refresh
+ const KEY='cr-room-picks'; const picks=JSON.parse(localStorage.getItem(KEY)||'{}');
+ document.querySelectorAll('.pick').forEach(p=>{
+   const sku=p.dataset.sku, eng=p.dataset.eng;
+   if(picks[sku]===eng) p.classList.add('on');
+   p.onclick=()=>{ picks[sku]=eng; localStorage.setItem(KEY,JSON.stringify(picks));
+     document.querySelectorAll(`.pick[data-sku="${sku}"]`).forEach(x=>x.classList.remove('on'));
+     p.classList.add('on'); };
+ });
+</script>
\ No newline at end of file
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_kontext.sh b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_kontext.sh
new file mode 100755
index 00000000..90b26641
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_kontext.sh
@@ -0,0 +1,47 @@
+#!/bin/zsh
+# Batch FLUX Kontext room renders for all 67 Carl Robinson SKUs. Idempotent
+# (skips SKUs whose {sku}-kontext.png already exists) + resumable. $0 local.
+set -u
+VEN=/tmp/cr-room-bakeoff/flux-venv/bin/mflux-generate-kontext
+VIEW=/tmp/carl-robinson-viewer
+ROOM=/tmp/cr-room-bakeoff/00-empty-room.png
+OUT=/Users/macstudio3/Projects/Designer-Wallcoverings/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local
+mkdir -p "$OUT"
+MAN=/tmp/cr-room-bakeoff/manifest.tsv
+
+# material -> texture descriptor for the prompt
+tex() { case "$1" in
+  Grasscloth) echo "hand-woven grasscloth with horizontal natural plant fibers";;
+  Paperweave) echo "woven paperweave with a fine crosshatch texture";;
+  Raffia) echo "natural raffia palm-fiber weave";;
+  Netting) echo "open natural netting weave";;
+  Bamboo) echo "vertical bamboo-reed texture";;
+  Sisal) echo "coarse sisal woven fiber";;
+  Cork) echo "natural cork with fine speckled grain";;
+  Fiber) echo "natural plant-fiber weave";;
+  Jute) echo "coarse jute burlap weave";;
+  Mica) echo "mica-flake mineral shimmer, subtle metallic texture";;
+  Nonwoven) echo "raw-silk textured nonwoven";;
+  Silk) echo "fine silk weave with soft sheen";;
+  "Wood Veneer") echo "thin natural wood-veneer grain";;
+  *) echo "natural woven $1 texture";; esac; }
+
+n=0; done=0; skip=0
+total=$(grep -c . "$MAN")
+while IFS='|' read -r sku color mat img; do
+  [ -z "$sku" ] && continue
+  n=$((n+1))
+  target="$OUT/${sku}-kontext.png"
+  if [ -f "$target" ]; then skip=$((skip+1)); echo "[$n/$total] skip $sku (exists)"; continue; fi
+  desc="$(tex "$mat")"
+  prompt="Cover the large blank accent wall with natural ${mat} wallcovering in a soft ${color} off-white tone, ${desc}, subtle organic color variation. Keep the white sofa, wood floor, side table, lamp, soft daylight and composition exactly the same. Photorealistic interior design photograph."
+  echo "$prompt" > /tmp/cr-room-bakeoff/_kp.txt
+  echo "[$n/$total] kontext $sku ($mat / $color)…"
+  "$VEN" -m akx/FLUX.1-Kontext-dev-mflux-4bit --base-model dev \
+    --steps 24 --guidance 2.5 --image-path "$ROOM" \
+    --prompt-file /tmp/cr-room-bakeoff/_kp.txt --output "$target" \
+    >> /tmp/cr-room-bakeoff/batch_kontext.log 2>&1 \
+    && { done=$((done+1)); echo "   ok -> ${sku}-kontext.png"; } \
+    || echo "   FAIL $sku (see batch_kontext.log)"
+done < "$MAN"
+echo "KONTEXT BATCH DONE: rendered=$done skipped=$skip of $total"
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_sdxl.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_sdxl.py
new file mode 100644
index 00000000..8136aac8
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/batch_sdxl.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# Batch SDXL-inpaint + IP-Adapter room renders for all 67 SKUs. Loads the pipeline
+# ONCE, loops the manifest, injects each SKU's OWN swatch (exact texture). Idempotent
+# (skips existing {sku}-sdxl.png) + resumable. $0 local.
+import os, torch
+from PIL import Image
+from diffusers import StableDiffusionXLInpaintPipeline
+from transformers import CLIPVisionModelWithProjection
+
+VIEW = '/tmp/carl-robinson-viewer'
+OUT = '/Users/macstudio3/Projects/Designer-Wallcoverings/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local'
+os.makedirs(OUT, exist_ok=True)
+DEV = 'mps' if torch.backends.mps.is_available() else 'cpu'
+DT = torch.float16 if DEV == 'mps' else torch.float32
+
+room = Image.open('/tmp/cr-room-bakeoff/00-empty-room.png').convert('RGB').resize((1024, 1024))
+mask = Image.open('/tmp/cr-room-bakeoff/wall-mask.png').convert('L').resize((1024, 1024))
+
+TEX = {'Grasscloth':'hand-woven grasscloth, horizontal natural fibers','Paperweave':'woven paperweave crosshatch',
+       'Raffia':'raffia palm-fiber weave','Netting':'open netting weave','Bamboo':'vertical bamboo reed',
+       'Sisal':'coarse sisal fiber','Cork':'cork speckled grain','Fiber':'natural plant fiber',
+       'Jute':'coarse jute burlap','Mica':'mica mineral shimmer','Nonwoven':'raw silk nonwoven',
+       'Silk':'fine silk weave','Wood Veneer':'wood veneer grain'}
+
+print('loading ViT-H encoder + SDXL inpaint + IP-Adapter…', flush=True)
+image_encoder = CLIPVisionModelWithProjection.from_pretrained(
+    'h94/IP-Adapter', subfolder='models/image_encoder', torch_dtype=DT).to(DEV)
+pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
+    'diffusers/stable-diffusion-xl-1.0-inpainting-0.1', torch_dtype=DT, variant='fp16',
+    image_encoder=image_encoder).to(DEV)
+pipe.load_ip_adapter('h94/IP-Adapter', subfolder='sdxl_models',
+                     weight_name='ip-adapter_sdxl_vit-h.safetensors')
+pipe.set_ip_adapter_scale(1.0)
+pipe.set_progress_bar_config(disable=True)
+
+rows = [l.rstrip('\n').split('|') for l in open('/tmp/cr-room-bakeoff/manifest.tsv') if l.strip()]
+total = len(rows); done = skip = fail = 0
+for i, (sku, color, mat, img) in enumerate(rows, 1):
+    target = f'{OUT}/{sku}-sdxl.png'
+    if os.path.exists(target):
+        skip += 1; print(f'[{i}/{total}] skip {sku} (exists)', flush=True); continue
+    sw = f'{VIEW}/{img}'
+    if not os.path.exists(sw):
+        fail += 1; print(f'[{i}/{total}] MISS swatch {sku} {img}', flush=True); continue
+    swatch = Image.open(sw).convert('RGB')
+    prompt = (f'natural {mat} wallcovering in a soft {color} off-white tone on the wall, '
+              f'{TEX.get(mat, mat.lower()+" texture")}, organic texture, realistic interior lighting, photorealistic')
+    neg = 'framed, poster, border, blurry, distorted, low quality, seams, tiling artifacts, furniture changed, blank wall'
+    g = torch.Generator(device='cpu').manual_seed(7)
+    try:
+        out = pipe(prompt=prompt, negative_prompt=neg, image=room, mask_image=mask,
+                   ip_adapter_image=swatch, strength=0.98, guidance_scale=6.0,
+                   num_inference_steps=30, generator=g).images[0]
+        out.save(target); done += 1
+        print(f'[{i}/{total}] ok {sku} -> {sku}-sdxl.png', flush=True)
+    except Exception as e:
+        fail += 1; print(f'[{i}/{total}] FAIL {sku}: {str(e)[:100]}', flush=True)
+print(f'SDXL BATCH DONE: rendered={done} skipped={skip} failed={fail} of {total}', flush=True)
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/build_comparison.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/build_comparison.py
new file mode 100644
index 00000000..38795831
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/build_comparison.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# Build a live room-engine comparison gallery: per SKU -> swatch | Gemini | Kontext | SDXL.
+# Reads whatever has rendered so far (idempotent; re-run anytime to refresh progress).
+import os, json, html
+VIEW = '/tmp/carl-robinson-viewer'
+CONN = os.environ.get('DATABASE_URL', 'postgresql://dw_admin@127.0.0.1:5432/dw_unified')
+rows = [l.rstrip('\n').split('|') for l in open('/tmp/cr-room-bakeoff/manifest.tsv') if l.strip()]
+
+# gemini room path per sku (from the DB room_setting_images we stored earlier)
+import subprocess
+q = "SELECT dw_sku, COALESCE(room_setting_images::text,'[]') FROM carl_robinson_catalog ORDER BY dw_sku"
+gem = {}
+out = subprocess.run(['psql', CONN, '-tAc', q], capture_output=True, text=True).stdout
+for line in out.splitlines():
+    if '|' not in line: continue
+    sku, arr = line.split('|', 1)
+    try: gem[sku] = json.loads(arr)[0] if json.loads(arr) else ''
+    except Exception: gem[sku] = ''
+
+def cell(path, label, sku, engine):
+    exists = path and os.path.exists(os.path.join(VIEW, path))
+    if exists:
+        inner = f'<img src="{path}" loading="lazy"><div class="pick" data-sku="{sku}" data-eng="{engine}">pick {engine}</div>'
+    else:
+        inner = '<div class="pending">rendering…</div>'
+    return f'<div class="cell"><div class="lbl">{label}</div>{inner}</div>'
+
+done_k = done_s = 0
+cards = []
+for sku, color, mat, img in rows:
+    k = f'rooms-local/{sku}-kontext.png'
+    s = f'rooms-local/{sku}-sdxl.png'
+    if os.path.exists(os.path.join(VIEW, k)): done_k += 1
+    if os.path.exists(os.path.join(VIEW, s)): done_s += 1
+    cards.append(f'''<div class="card">
+      <div class="hd">{html.escape(sku)} &middot; {html.escape(mat)} &middot; {html.escape(color)}</div>
+      <div class="row">
+        {cell(img, "Swatch", sku, "swatch")}
+        {cell(gem.get(sku,""), "Gemini (current)", sku, "gemini")}
+        {cell(k, "FLUX Kontext (B)", sku, "kontext")}
+        {cell(s, "SDXL+IPA (C)", sku, "sdxl")}
+      </div></div>''')
+
+total = len(rows)
+doc = f'''<!doctype html><meta charset=utf-8><title>CR Room Engine Bake-off</title>
+<style>
+ body{{font:14px/1.4 -apple-system,system-ui,sans-serif;margin:0;background:#111;color:#eee}}
+ header{{position:sticky;top:0;background:#1b1b1b;padding:12px 18px;border-bottom:1px solid #333;z-index:5}}
+ h1{{font-size:16px;margin:0 0 4px}} .prog{{color:#9ad}}
+ .card{{border-bottom:1px solid #262626;padding:14px 18px}}
+ .hd{{font-weight:600;margin-bottom:8px;color:#ddd}}
+ .row{{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}}
+ .cell{{background:#191919;border:1px solid #2a2a2a;border-radius:8px;overflow:hidden}}
+ .lbl{{font-size:11px;color:#9a9a9a;padding:5px 8px;border-bottom:1px solid #2a2a2a}}
+ .cell img{{width:100%;display:block;aspect-ratio:1;object-fit:cover}}
+ .pending{{aspect-ratio:1;display:flex;align-items:center;justify-content:center;color:#666;font-style:italic}}
+ .pick{{text-align:center;font-size:11px;color:#7c7;padding:5px;cursor:pointer;user-select:none}}
+ .pick.on{{background:#2a5;color:#fff;font-weight:600}}
+</style>
+<header>
+ <h1>Carl Robinson &rarr; Phillipe Romano &mdash; Local Room Engine Bake-off</h1>
+ <div class="prog">Kontext {done_k}/{total} &middot; SDXL {done_s}/{total} rendered &middot; all local, $0 &middot; refresh to update</div>
+</header>
+{''.join(cards)}
+<script>
+ // remember picks locally so Steve's winner choices survive refresh
+ const KEY='cr-room-picks'; const picks=JSON.parse(localStorage.getItem(KEY)||'{{}}');
+ document.querySelectorAll('.pick').forEach(p=>{{
+   const sku=p.dataset.sku, eng=p.dataset.eng;
+   if(picks[sku]===eng) p.classList.add('on');
+   p.onclick=()=>{{ picks[sku]=eng; localStorage.setItem(KEY,JSON.stringify(picks));
+     document.querySelectorAll(`.pick[data-sku="${{sku}}"]`).forEach(x=>x.classList.remove('on'));
+     p.classList.add('on'); }};
+ }});
+</script>'''
+open(f'{VIEW}/compare-rooms.html', 'w').write(doc)
+print(f'wrote {VIEW}/compare-rooms.html  (kontext {done_k}/{total}, sdxl {done_s}/{total})')
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py
new file mode 100644
index 00000000..be843f00
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/make_wall_mask.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# Build a wall mask for the empty room: white = wall to repaint, black = keep.
+# Wall = bright + low-saturation pixels in the upper region, MINUS the sofa and
+# table/lamp bounding boxes (which are also light) so inpaint won't touch furniture.
+from PIL import Image, ImageFilter, ImageDraw
+import numpy as np
+
+room = Image.open('/tmp/cr-room-bakeoff/00-empty-room.png').convert('RGB')
+W, H = room.size
+# GEOMETRIC full-wall mask: everything above the floor line is wall, then knock
+# out the furniture so inpaint repaints the ENTIRE visible wall (not a thin band).
+# (Threshold masks left most of the wall unpainted -> blank result; geometry is robust.)
+FLOOR_Y = 715
+m = Image.new('L', (W, H), 0)
+d = ImageDraw.Draw(m)
+d.rectangle([0, 0, W, FLOOR_Y], fill=255)     # full wall band
+d.rectangle([60, 430, 770, FLOOR_Y + 45], fill=0)    # sofa
+d.rectangle([765, 470, 1010, FLOOR_Y + 45], fill=0)  # side table + lamp
+# light feather only (heavy blur weakens inpaint strength across the whole wall)
+m = m.filter(ImageFilter.GaussianBlur(2))
+m.save('/tmp/cr-room-bakeoff/wall-mask.png')
+
+# quick coverage stat + a visual overlay for review
+cov = (np.asarray(m) > 128).mean() * 100
+overlay = room.copy()
+red = Image.new('RGB', (W, H), (255, 0, 0))
+overlay = Image.composite(red, overlay, m.point(lambda p: int(p * 0.45)))
+overlay.save('/tmp/cr-room-bakeoff/wall-mask-overlay.png')
+print(f'wall mask coverage: {cov:.1f}%  -> wall-mask.png + overlay')
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/manifest.tsv b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/manifest.tsv
new file mode 100644
index 00000000..d877428f
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/manifest.tsv
@@ -0,0 +1,67 @@
+BAM-100048|Sour Cream|Bamboo|img/BAM-100048.jpg
+BAM-100049|Sea Shell|Bamboo|img/BAM-100049.jpg
+BAM-100050|Mica|Bamboo|img/BAM-100050.jpg
+BAM-100051|Silver Lining|Bamboo|img/BAM-100051.jpg
+BAM-100052|Shaved Ice|Bamboo|img/BAM-100052.jpg
+CORK-100057|Chalk|Cork|img/DWCR-50001.jpeg
+CORK-100058|Water Lily|Cork|img/DWCR-50026.jpeg
+FIB-100059|Birch Bark|Fiber|img/FIB-100059.jpg
+FIB-100060|Cool Linen|Fiber|img/FIB-100060.jpg
+GRS-100020|Plaster|Grasscloth|img/GRS-100020.jpg
+GRS-100021|Gauze|Grasscloth|img/GRS-100021.jpg
+GRS-100022|Bleached Coral|Grasscloth|img/GRS-100022.jpg
+GRS-100023|Iceberg|Grasscloth|img/GRS-100023.jpg
+GRS-100024|Egret|Grasscloth|img/GRS-100024.jpg
+GRS-100025|Almond|Grasscloth|img/GRS-100025.jpg
+GRS-100026|Roasted Marshmallow|Grasscloth|img/GRS-100026.jpg
+GRS-100027|Stardust|Grasscloth|img/GRS-100027.jpg
+GRS-100028|Moon|Grasscloth|img/GRS-100028.jpg
+GRS-100029|Vanilla|Grasscloth|img/GRS-100029.jpg
+GRS-100030|Ghost White|Grasscloth|img/GRS-100030.jpg
+GRS-100031|Bone|Grasscloth|img/GRS-100031.jpg
+GRS-100032|Parchment|Grasscloth|img/GRS-100032.jpg
+GRS-100033|Sun Kissed|Grasscloth|img/GRS-100033.jpg
+JUT-100061|Cotton|Jute|img/JUT-100061.jpg
+JUT-100062|Eggshell|Jute|img/JUT-100062.jpg
+MIC-100065|Mother of Pearl|Mica|img/DWCR-50019.jpeg
+NET-100042|Tan|Netting|img/NET-100042.jpg
+NET-100043|Sand|Netting|img/NET-100043.jpg
+NET-100044|Tusk|Netting|img/NET-100044.jpg
+NET-100045|Flour|Netting|img/NET-100045.jpg
+NET-100046|Paper|Netting|img/NET-100046.jpg
+NET-100047|Lurex|Netting|img/NET-100047.jpg
+NWV-100066|Raw Silk|Nonwoven|img/DWCR-50031.jpeg
+PWV-100001|Winter white|Paperweave|img/PWV-100001.jpg
+PWV-100002|Arctic white|Paperweave|img/PWV-100002.jpg
+PWV-100003|Frost|Paperweave|img/PWV-100003.jpg
+PWV-100004|Sail|Paperweave|img/PWV-100004.jpg
+PWV-100005|Crushed Silk|Paperweave|img/PWV-100005.jpg
+PWV-100006|Tissue|Paperweave|img/PWV-100006.jpg
+PWV-100007|Cabana Linen|Paperweave|img/PWV-100007.jpg
+PWV-100008|Wool|Paperweave|img/PWV-100008.jpg
+PWV-100009|Meringue|Paperweave|img/PWV-100009.jpg
+PWV-100010|Honeysuckle|Paperweave|img/PWV-100010.jpg
+PWV-100011|White Chocolate|Paperweave|img/PWV-100011.jpg
+PWV-100012|Foil|Paperweave|img/PWV-100012.jpg
+PWV-100013|Brushed Silver|Paperweave|img/PWV-100013.jpg
+PWV-100014|Rice Paper|Paperweave|img/PWV-100014.jpg
+PWV-100015|White Heron|Paperweave|img/PWV-100015.jpg
+PWV-100016|Pearla|Paperweave|img/PWV-100016.jpg
+PWV-100017|Off White|Paperweave|img/PWV-100017.jpg
+PWV-100018|Casablanca|Paperweave|img/PWV-100018.jpg
+PWV-100019|Powdered Sugar|Paperweave|img/PWV-100019.jpg
+RAF-100034|Bleached Linen|Raffia|img/RAF-100034.jpg
+RAF-100035|Rice|Raffia|img/RAF-100035.jpg
+RAF-100036|Feather White|Raffia|img/RAF-100036.jpg
+RAF-100037|Latte|Raffia|img/RAF-100037.jpg
+RAF-100038|Cold Foam|Raffia|img/RAF-100038.jpg
+RAF-100039|Dove|Raffia|img/RAF-100039.jpg
+RAF-100040|Bleached Burlap|Raffia|img/RAF-100040.jpg
+RAF-100041|Crisp White|Raffia|img/RAF-100041.jpg
+SIS-100053|Buttercream|Sisal|img/SIS-100053.jpg
+SIS-100054|Coconut|Sisal|img/SIS-100054.jpg
+SIS-100055|Almond|Sisal|img/SIS-100055.jpg
+SIS-100056|Cream|Sisal|img/SIS-100056.jpg
+SLK-100063|Cryslas|Silk|img/SLK-100063.jpg
+SLK-100064|Cappuccino|Silk|img/SLK-100064.jpg
+WDV-100067|Candle|Wood Veneer|img/DWCR-50010.jpeg
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/pil_compose.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/pil_compose.py
new file mode 100644
index 00000000..a2c9796f
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/pil_compose.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+# PIL baseline for the room bake-off. Papers the empty room's upper wall band with
+# a tiled swatch, MULTIPLIED by the room's own luminance so the paper inherits the
+# real lighting gradient (reduces the "flat sticker" look). No AI, no API, $0.
+# Occlusion (sofa/table in front of the wall) is NOT handled — that's the known
+# PIL limitation the diffusion engines fix.
+from PIL import Image, ImageEnhance
+import numpy as np
+
+BASE = '/tmp/cr-room-bakeoff/00-empty-room.png'          # 1024x1024
+SWATCH = '/tmp/cr-room-bakeoff/00-swatch-GRS-100020.jpg'  # 650x650
+OUT = '/tmp/cr-room-bakeoff/A-pil.png'
+
+base = Image.open(BASE).convert('RGB')
+W, H = base.size
+# Clean upper wall band (above the sofa back) — full width, no occluders.
+WALL_TOP, WALL_BOT = 0, 455
+band_h = WALL_BOT - WALL_TOP
+
+# Tile the swatch to a realistic grasscloth scale (~205px repeat).
+tile_px = 205
+sw = Image.open(SWATCH).convert('RGB').resize((tile_px, tile_px), Image.LANCZOS)
+tiled = Image.new('RGB', (W, band_h))
+for y in range(0, band_h, tile_px):
+    for x in range(0, W, tile_px):
+        tiled.paste(sw, (x, y))
+
+# Pull the wall's own luminance (grayscale of the base band) as a lighting map,
+# normalize around 1.0, and multiply the texture by it -> real room light/shadow.
+wall_band = base.crop((0, WALL_TOP, W, WALL_BOT))
+lum = np.asarray(wall_band.convert('L'), dtype=np.float32) / 255.0
+lum = 0.55 + 0.75 * lum            # lift so mid-wall ~1.0, keep gradient
+lum = np.clip(lum, 0.35, 1.25)[..., None]
+tex = np.asarray(tiled, dtype=np.float32) * lum
+tex = np.clip(tex, 0, 255).astype('uint8')
+tex_img = Image.fromarray(tex, 'RGB')
+tex_img = ImageEnhance.Contrast(tex_img).enhance(1.04)
+
+out = base.copy()
+out.paste(tex_img, (0, WALL_TOP))
+out.save(OUT)
+print('wrote', OUT, out.size)
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_ipa.py b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_ipa.py
new file mode 100644
index 00000000..96a6e7a9
--- /dev/null
+++ b/scripts/wallquest-refresh/carl-robinson-viewer/room-engines/sdxl_ipa.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+# Contender C: SDXL inpaint + IP-Adapter. Repaints ONLY the wall mask, with the
+# EXACT swatch injected as an image condition via IP-Adapter (CLIP-Vision ViT-H).
+# This is the exact-texture path (vs FLUX Kontext's prompt-described texture).
+import sys, torch
+from PIL import Image
+from diffusers import StableDiffusionXLInpaintPipeline
+from transformers import CLIPVisionModelWithProjection
+
+DEV = 'mps' if torch.backends.mps.is_available() else 'cpu'
+DT = torch.float16 if DEV == 'mps' else torch.float32
+COLOR = sys.argv[1] if len(sys.argv) > 1 else 'plaster'
+
+room  = Image.open('/tmp/cr-room-bakeoff/00-empty-room.png').convert('RGB').resize((1024, 1024))
+mask  = Image.open('/tmp/cr-room-bakeoff/wall-mask.png').convert('L').resize((1024, 1024))
+swatch= Image.open('/tmp/cr-room-bakeoff/00-swatch-GRS-100020.jpg').convert('RGB')
+
+print('loading ViT-H CLIP-Vision encoder…', flush=True)
+# Load the ViT-H image encoder (1280-dim) EXPLICITLY and hand it to the pipeline.
+# ip-adapter_sdxl_vit-h needs ViT-H; the default sdxl_models/image_encoder (bigG)
+# causes a dim-mismatch crash, and a relative '../' path confuses transformers.
+image_encoder = CLIPVisionModelWithProjection.from_pretrained(
+    'h94/IP-Adapter', subfolder='models/image_encoder', torch_dtype=DT).to(DEV)
+print('loading SDXL inpaint…', flush=True)
+pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
+    'diffusers/stable-diffusion-xl-1.0-inpainting-0.1', torch_dtype=DT, variant='fp16',
+    image_encoder=image_encoder).to(DEV)
+print('loading IP-Adapter (ip-adapter_sdxl_vit-h)…', flush=True)
+pipe.load_ip_adapter('h94/IP-Adapter', subfolder='sdxl_models',
+                     weight_name='ip-adapter_sdxl_vit-h.safetensors')
+pipe.set_ip_adapter_scale(1.0)   # drive the exact swatch texture hard
+
+prompt = (f'natural woven grasscloth wallcovering in a soft {COLOR} off-white tone on the wall, '
+          'horizontal hand-woven fibers, organic texture, realistic interior lighting, photorealistic')
+neg = 'framed, poster, border, blurry, distorted, low quality, seams, tiling artifacts, furniture changed'
+
+g = torch.Generator(device='cpu').manual_seed(7)
+print('generating…', flush=True)
+out = pipe(prompt=prompt, negative_prompt=neg, image=room, mask_image=mask,
+           ip_adapter_image=swatch, strength=0.98, guidance_scale=6.0,
+           num_inference_steps=30, generator=g).images[0]
+out.save('/tmp/cr-room-bakeoff/C-sdxl-ipa.png')
+print('wrote /tmp/cr-room-bakeoff/C-sdxl-ipa.png')

← e968f838 Carl Robinson viewer: wire to local images + persist out of  ·  back to Designer Wallcoverings  ·  Local VLM auto-judge + finalize for room bake-off 8df04ff8 →