← back to Wallco Ai
scripts/build-la-toile-gallery.js
105 lines
// Build a before/after LA Toile gallery from pass snapshots.
// AFTER = pass-2 (first complete post-fix run, DENSITY_MAX=0.58 + palm removal + BH palette).
// BEFORE = pass-1 (pre-fix: TONE_ON_TONE monochrome + palms + over-tight density).
const fs = require('fs');
const SCENES = [
'Hollywood Sign + Griffith Observatory domes',
'Venice Beach boardwalk, pier, surf',
'Downtown LA skyline + City Hall',
'Jacaranda-lined Sunset Boulevard',
'Beverly Hills Spanish-revival bungalows',
'Santa Monica Pier Ferris wheel',
'Chinatown paifang gate + lanterns',
'Echo Park Lake paddle boats + lotus',
'Mid-century Case Study glass houses',
'1960s convertibles on Mulholland Drive',
'Watts Towers mosaic spires',
'LA Aqueduct cascade + San Gabriels',
'Olvera Street market stalls',
'Griffith Park oak trails + mule deer',
'Malibu coastline + surfers + lighthouse',
'Art-Deco movie palaces + marquees',
'Old-LA citrus groves + packing sheds',
'Union Station + streamliner train',
'Golden-age studio backlot',
'Pasadena Rose Parade floats',
'Angels Flight funicular railway',
'La Brea Tar Pits + mammoths',
'Bradbury Building atrium stairs',
'Mulholland overlook + coyote at dusk',
'Silver Lake reservoir + modernist homes',
'Original Farmers Market clock tower',
'Topanga Canyon cabins + oaks',
'Googie LAX Theme Building arches',
'Dodger Stadium grandstands',
'Jacaranda residential streets in bloom',
];
const before = JSON.parse(fs.readFileSync('/tmp/la-toile-pass-1.json', 'utf8'));
const after = JSON.parse(fs.readFileSync('/tmp/la-toile-pass-2.json', 'utf8'));
const BASE = 'http://127.0.0.1:9905/designs/img/by-id/';
const rows = SCENES.map((label, i) => {
const slug = 'la-toile-' + String(i + 1).padStart(2, '0');
return { slug, label, before: before[slug] || null, after: after[slug] || null };
}).filter(r => r.after); // show scenes that have a post-fix winner
const cells = rows.map(r => `
<div class="card">
<div class="lbl"><b>${r.slug}</b> · ${r.label}</div>
<div class="pair">
<figure>
<div class="tag tag-b">BEFORE · pre-fix</div>
${r.before
? `<a href="${BASE}${r.before}" target="_blank"><img loading="lazy" src="${BASE}${r.before}"></a><figcaption>#${r.before} · monochrome / palmy / sparse</figcaption>`
: `<div class="missing">no pre-fix winner<br>(scene failed gates in pass 1)</div>`}
</figure>
<figure>
<div class="tag tag-a">AFTER · fixed</div>
<a href="${BASE}${r.after}" target="_blank"><img loading="lazy" src="${BASE}${r.after}"></a>
<figcaption>#${r.after} · BH multi-color · palm-free · density 0.58</figcaption>
</figure>
</div>
</div>`).join('\n');
const html = `<!doctype html><html><head><meta charset="utf-8">
<title>LA Toile de Jouy — before / after (pass 2, post-fix)</title>
<style>
:root{--ink:#1a1713;--line:#e2dcd0;--bg:#f6f2ea}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.5 -apple-system,Georgia,serif;padding:28px 32px}
h1{font:600 26px/1.2 Georgia,serif;margin:0 0 4px}
.sub{color:#6b6357;margin:0 0 24px;font-size:14px}
.sub b{color:var(--ink)}
.grid{display:grid;grid-template-columns:1fr;gap:22px;max-width:1180px}
.card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:14px 16px;box-shadow:0 1px 3px rgba(0,0,0,.04)}
.lbl{font-size:14px;margin-bottom:10px;color:#3a342b}
.lbl b{font-size:13px;letter-spacing:.02em;color:#8a7f6c;font-variant:all-small-caps}
.pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}
figure{margin:0;position:relative}
img{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:8px;display:block;background:#eee}
.missing{width:100%;aspect-ratio:1/1;border-radius:8px;display:flex;align-items:center;justify-content:center;text-align:center;color:#a99;background:#faf6f3;border:1px dashed #e2c9c9;font-size:13px}
figcaption{font-size:12px;color:#6b6357;margin-top:6px}
.tag{position:absolute;top:8px;left:8px;font:600 10px/1 -apple-system;letter-spacing:.06em;padding:5px 8px;border-radius:5px;z-index:2;color:#fff}
.tag-b{background:#9a6b63}.tag-a{background:#3f6b4e}
.legend{display:flex;gap:18px;margin-bottom:20px;font-size:13px;flex-wrap:wrap}
.legend span{display:inline-flex;align-items:center;gap:6px}
.dot{width:10px;height:10px;border-radius:3px;display:inline-block}
</style></head><body>
<h1>LA Toile de Jouy — before / after</h1>
<p class="sub">Pass 2 (first complete post-fix run) vs pass 1 (pre-fix). Fixes: <b>BH multi-color palette wins</b> (removed conflicting tone-on-tone monochrome suffix) · <b>palms removed</b> from positive prompt · <b>density 0.52→0.58</b>. ${rows.length} scenes with a post-fix winner.</p>
<div class="legend">
<span><i class="dot" style="background:#9a6b63"></i> BEFORE — pale monochrome, palms everywhere, over-rejected breathing room</span>
<span><i class="dot" style="background:#3f6b4e"></i> AFTER — full BH colorway, no palms, classic toile density</span>
</div>
<div class="grid">
${cells}
</div>
</body></html>`;
fs.writeFileSync('/tmp/la-toile-gallery-after.html', html);
console.log('wrote /tmp/la-toile-gallery-after.html — ' + rows.length + ' scenes (' +
rows.filter(r => r.before).length + ' with before/after pair, ' +
rows.filter(r => !r.before).length + ' after-only)');