[object Object]

← back to Parked Landers

Swap in real flux-schnell images (replace placeholder tiles); add image-gen reference

736f725a9b8f0ba1fd7ed57bdb09a371d6fe94bb · 2026-09-09 11:48:23 -0700 · Steve

Files touched

Diff

commit 736f725a9b8f0ba1fd7ed57bdb09a371d6fe94bb
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Sep 9 11:48:23 2026 -0700

    Swap in real flux-schnell images (replace placeholder tiles); add image-gen reference
---
 deploy-remote.sh                                   |  28 +++++++
 finish.sh                                          |  18 ++++
 gen-images.py                                      |  91 +++++++++++++++++++++
 sites/cannabisofthemonthclub.com/img/01.jpg        | Bin 0 -> 152034 bytes
 sites/cannabisofthemonthclub.com/img/02.jpg        | Bin 0 -> 108975 bytes
 sites/cannabisofthemonthclub.com/img/03.jpg        | Bin 0 -> 230144 bytes
 sites/cannabisofthemonthclub.com/img/04.jpg        | Bin 0 -> 151991 bytes
 sites/cannabisofthemonthclub.com/img/05.jpg        | Bin 0 -> 176374 bytes
 sites/cannabisofthemonthclub.com/img/06.jpg        | Bin 0 -> 82561 bytes
 sites/cannabisofthemonthclub.com/index.html        |   5 +-
 sites/hempofthemonthclub.com/img/01.jpg            | Bin 0 -> 487490 bytes
 sites/hempofthemonthclub.com/img/02.jpg            | Bin 0 -> 103515 bytes
 sites/hempofthemonthclub.com/index.html            |   3 +-
 .../hospitalitysalesrepresentatives.com/index.html |   1 +
 sites/marijuanaofthemonthclub.com/index.html       |   1 +
 sites/mymemosamples.com/img/01.jpg                 | Bin 0 -> 103166 bytes
 sites/mymemosamples.com/index.html                 |   3 +-
 sites/potofthemonthclub.com/index.html             |   1 +
 sites/protectyourspec.com/img/01.jpg               | Bin 0 -> 257364 bytes
 sites/protectyourspec.com/img/02.jpg               | Bin 0 -> 101400 bytes
 sites/protectyourspec.com/img/03.jpg               | Bin 0 -> 168449 bytes
 sites/protectyourspec.com/img/04.jpg               | Bin 0 -> 190601 bytes
 sites/protectyourspec.com/img/05.jpg               | Bin 0 -> 167869 bytes
 sites/protectyourspec.com/img/06.jpg               | Bin 0 -> 177226 bytes
 sites/protectyourspec.com/index.html               |   5 +-
 sites/weedofthemonthclub.com/index.html            |   1 +
 swap-html.py                                       |  30 +++++++
 27 files changed, 181 insertions(+), 6 deletions(-)

diff --git a/deploy-remote.sh b/deploy-remote.sh
new file mode 100644
index 0000000..c042908
--- /dev/null
+++ b/deploy-remote.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Runs ON Kamatera. vhost + cert + reload + verify for the 8 parked landers.
+set -e
+DOMS="protectyourspec.com cannabisofthemonthclub.com hempofthemonthclub.com marijuanaofthemonthclub.com potofthemonthclub.com weedofthemonthclub.com mymemosamples.com hospitalitysalesrepresentatives.com"
+for d in $DOMS; do
+  root="/var/www/parked-landers/$d"
+  [ -f "$root/index.html" ] || { echo "SKIP $d (no index.html uploaded)"; continue; }
+  conf="/etc/nginx/sites-available/$d.conf"
+  if [ ! -f "$conf" ]; then
+    printf 'server {\n    listen 80;\n    listen [::]:80;\n    server_name %s www.%s;\n    root %s;\n    index index.html;\n    location / { try_files $uri $uri/ /index.html; }\n}\n' "$d" "$d" "$root" > "$conf"
+    ln -sf "$conf" "/etc/nginx/sites-enabled/$d.conf"
+    echo "vhost created: $d"
+  else
+    echo "vhost exists (left as-is): $d"
+  fi
+done
+nginx -t && systemctl reload nginx
+for d in $DOMS; do
+  certbot --nginx --non-interactive --agree-tos -m info@designerwallcoverings.com --redirect -d "$d" -d "www.$d" >/dev/null 2>&1 && echo "cert ok: $d" || echo "certbot FAILED: $d (check rate limit / www)"
+done
+nginx -t && systemctl reload nginx
+echo "=== VERIFY (expect 200 + cert=<the domain itself>) ==="
+for d in $DOMS; do
+  code=$(curl -sSI "https://$d/" -o /dev/null -w "%{http_code}" 2>/dev/null)
+  subj=$(echo | openssl s_client -servername "$d" -connect "$d":443 2>/dev/null | openssl x509 -noout -subject 2>/dev/null | sed -E 's/.*CN ?= ?//')
+  printf "%-38s %s  cert=%s\n" "$d" "$code" "$subj"
+done
+echo "=== REMOTE DONE ==="
diff --git a/finish.sh b/finish.sh
new file mode 100755
index 0000000..cbf0202
--- /dev/null
+++ b/finish.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+cd "$HOME/Projects/parked-landers"
+log="gen-images.log"
+# wait up to ~12 min for the batch to finish
+for i in $(seq 1 144); do
+  grep -q '^DONE' "$log" 2>/dev/null && break
+  sleep 5
+done
+echo "=== batch log tail ==="; tail -3 "$log"
+imgs=$(find sites -name '*.jpg' | wc -l | tr -d ' ')
+echo "images on disk: $imgs/48"
+echo "=== swapping placeholders -> real imgs ==="
+python3 swap-html.py
+echo "=== git commit ==="
+git add -A && git -c user.email="steve@designerwallcoverings.com" -c user.name="Steve" commit -q -m "Swap in real flux-schnell images (replace placeholder tiles); add image-gen reference" && git log --oneline -1
+echo "=== cost ==="
+gen=$(grep -c '^ok' "$log"); echo "generated ~$gen new images · flux-schnell @ \$0.003 = ~\$$(python3 -c "print(f'{$gen*0.003:.3f}')")"
+echo "FINISHER_DONE"
diff --git a/gen-images.py b/gen-images.py
new file mode 100644
index 0000000..6715818
--- /dev/null
+++ b/gen-images.py
@@ -0,0 +1,91 @@
+import os,json,time,urllib.request,urllib.error,subprocess
+BASE=os.path.expanduser("~/Projects/parked-landers/sites")
+TOKEN=subprocess.check_output(
+  "grep -E '^REPLICATE_API_TOKEN=' ~/Projects/secrets-manager/.env | head -1 | cut -d= -f2-",
+  shell=True).decode().strip()
+LOG=os.path.expanduser("~/Projects/parked-landers/gen-images.log")
+def log(m):
+  open(LOG,"a").write(m+"\n"); print(m,flush=True)
+
+NEG="no text, no words, no letters, no watermark, no logo, no people, no hands"
+BOX="premium curated monthly subscription box, elegant minimalist packaging, apothecary glass jars, botanical still life, soft natural light, editorial product photography, marble and neutral tones, "+NEG
+PROMPTS={
+ "protectyourspec.com":[
+  "an architect's desk with material finish samples fanned over technical drawings, editorial photography, "+NEG,
+  "close-up of architectural specification documents and finish swatches in a binder, "+NEG,
+  "a modern commercial office interior with premium wall finishes and clean lines, "+NEG,
+  "a designer material library shelf lined with tile, fabric and wood samples, "+NEG,
+  "flat lay of finish sample chips and a floor plan on a neutral desk, "+NEG,
+  "an elegant boardroom with design finish boards on the wall, "+NEG],
+ "cannabisofthemonthclub.com":[BOX,"flat lay of a curated wellness subscription box with tissue paper and small glass jars, "+NEG,
+  "premium apothecary jars with dried botanicals on a marble surface, "+NEG,
+  "minimalist kraft gift box with a card and botanical sprigs, top-down, "+NEG,
+  "elegant botanical still life with amber glass jars and linen, "+NEG,
+  "a tasteful monthly delivery box with premium neutral packaging, "+NEG],
+ "hempofthemonthclub.com":["flat lay of natural hemp fiber, hemp textile and seeds on linen, editorial, "+NEG,
+  "premium hemp wellness products in minimalist packaging, marble surface, "+NEG,BOX,
+  "green hemp plant leaves arranged as a botanical still life, "+NEG,
+  "natural hemp rope, fabric and neutral packaging flat lay, "+NEG,
+  "apothecary jars of hemp botanicals with soft window light, "+NEG],
+ "marijuanaofthemonthclub.com":[BOX,"elegant botanical apothecary flat lay with amber jars and dried herbs, "+NEG,
+  "premium neutral subscription box with tissue and a card, top-down, "+NEG,
+  "minimalist herbal wellness packaging on a marble slab, "+NEG,
+  "botanical still life with glass jars and linen napkin, soft light, "+NEG,
+  "curated monthly gift box with premium matte packaging, "+NEG],
+ "potofthemonthclub.com":[BOX,"a rustic-modern flat lay of a monthly botanical box with kraft paper, "+NEG,
+  "apothecary shelf with labeled amber jars and dried botanicals, "+NEG,
+  "minimalist herbal subscription packaging on a wood table, "+NEG,
+  "botanical still life with a small ceramic pot and dried herbs, "+NEG,
+  "elegant curated wellness box with neutral tones, top-down, "+NEG],
+ "weedofthemonthclub.com":[BOX,"botanical apothecary flat lay with green herbs and amber glass, "+NEG,
+  "premium minimalist subscription box with tissue paper, top-down, "+NEG,
+  "dried botanical bundle and glass jars on linen, editorial, "+NEG,
+  "neutral matte packaging and botanical sprigs flat lay, "+NEG,
+  "curated monthly wellness delivery with elegant packaging, "+NEG],
+ "mymemosamples.com":[  # 01 already exists (skip)
+  "SKIP",
+  "a designer fanning wallcovering sample swatches over a desk, editorial, "+NEG,
+  "close-up macro of layered textile swatch edges and textures, "+NEG,
+  "an open wallcovering sample book with tabbed pages, top-down, "+NEG,
+  "a memo sample mailer envelope with fabric swatches spilling out, "+NEG,
+  "neatly organized fabric swatch cards in a fan on marble, "+NEG],
+ "hospitalitysalesrepresentatives.com":[
+  "a luxury boutique hotel lobby with elegant contract furnishings, "+NEG,
+  "an upscale restaurant dining room interior, warm evening light, "+NEG,
+  "a modern hotel reception desk with premium materials, "+NEG,
+  "a stylish hospitality lounge with designer seating and textiles, "+NEG,
+  "a boutique hotel guest room with tailored contract furniture, "+NEG,
+  "a hotel bar interior with rich materials and ambient light, "+NEG],
+}
+def gen(prompt):
+  body=json.dumps({"input":{"prompt":prompt,"aspect_ratio":"4:3","num_outputs":1,"output_format":"jpg","output_quality":88}}).encode()
+  req=urllib.request.Request("https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions",
+    data=body,headers={"Authorization":"Bearer "+TOKEN,"Content-Type":"application/json","Prefer":"wait"})
+  r=json.load(urllib.request.urlopen(req,timeout=150))
+  # poll if not done
+  for _ in range(30):
+    if r.get("status")=="succeeded": break
+    if r.get("status") in ("failed","canceled"): return None
+    time.sleep(3)
+    r=json.load(urllib.request.urlopen(urllib.request.Request(r["urls"]["get"],
+      headers={"Authorization":"Bearer "+TOKEN}),timeout=30))
+  o=r.get("output"); url=o[0] if isinstance(o,list) and o else o
+  return url
+open(LOG,"w").write("")
+n=0; ok=0
+for dom,prompts in PROMPTS.items():
+  d=os.path.join(BASE,dom,"img"); os.makedirs(d,exist_ok=True)
+  for i,p in enumerate(prompts,1):
+    fp=os.path.join(d,f"{i:02d}.jpg")
+    if p=="SKIP" or os.path.exists(fp):
+      log(f"skip {dom}/{i:02d}.jpg"); ok+=1; continue
+    n+=1
+    try:
+      url=gen(p)
+      if not url: log(f"FAIL {dom}/{i:02d} (no url)"); continue
+      urllib.request.urlretrieve(url,fp)
+      sz=os.path.getsize(fp); ok+=1
+      log(f"ok   {dom}/{i:02d}.jpg  {sz}B")
+    except Exception as e:
+      log(f"ERR  {dom}/{i:02d}: {e}")
+log(f"DONE generated={n} present={ok}/48  est_cost=${n*0.003:.3f}")
diff --git a/sites/cannabisofthemonthclub.com/img/01.jpg b/sites/cannabisofthemonthclub.com/img/01.jpg
new file mode 100644
index 0000000..5ee1584
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/01.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/img/02.jpg b/sites/cannabisofthemonthclub.com/img/02.jpg
new file mode 100644
index 0000000..c5c8ad6
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/02.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/img/03.jpg b/sites/cannabisofthemonthclub.com/img/03.jpg
new file mode 100644
index 0000000..5365809
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/03.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/img/04.jpg b/sites/cannabisofthemonthclub.com/img/04.jpg
new file mode 100644
index 0000000..eacdb17
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/04.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/img/05.jpg b/sites/cannabisofthemonthclub.com/img/05.jpg
new file mode 100644
index 0000000..a5fe0ae
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/05.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/img/06.jpg b/sites/cannabisofthemonthclub.com/img/06.jpg
new file mode 100644
index 0000000..2b6098d
Binary files /dev/null and b/sites/cannabisofthemonthclub.com/img/06.jpg differ
diff --git a/sites/cannabisofthemonthclub.com/index.html b/sites/cannabisofthemonthclub.com/index.html
index 5b73c1a..d9c7fb0 100644
--- a/sites/cannabisofthemonthclub.com/index.html
+++ b/sites/cannabisofthemonthclub.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
@@ -82,8 +83,8 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
     <a class="cta" href="mailto:info@designerwallcoverings.com?subject=Domain%20inquiry%3A%20cannabisofthemonthclub.com">Make an offer →</a>
     <a class="ghost" href="#gallery">Learn more</a>
   </div>
-  <div class="galhead"><h2>Gallery</h2><span class="n">6 images · placeholders — swap real assets before launch</span></div>
-  <div class="gallery" id="gallery"><div class="tile"><span class="ph">Placeholder 01</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 02</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
+  <div class="galhead"><h2>Gallery</h2><span class="n">6 images</span></div>
+  <div class="gallery" id="gallery"><div class="tile"><img src="img/01.jpg" alt="cannabisofthemonthclub.com — image 01" loading="lazy"></div><div class="tile"><img src="img/02.jpg" alt="cannabisofthemonthclub.com — image 02" loading="lazy"></div><div class="tile"><img src="img/03.jpg" alt="cannabisofthemonthclub.com — image 03" loading="lazy"></div><div class="tile"><img src="img/04.jpg" alt="cannabisofthemonthclub.com — image 04" loading="lazy"></div><div class="tile"><img src="img/05.jpg" alt="cannabisofthemonthclub.com — image 05" loading="lazy"></div><div class="tile"><img src="img/06.jpg" alt="cannabisofthemonthclub.com — image 06" loading="lazy"></div></div>
   <div class="about"><span class="k">About this domain</span><p><b>cannabisofthemonthclub.com</b> — A high-recall subscription brand for the regulated cannabis market.</p></div>
   <div class="foot"><span>Part of a curated domain portfolio · inquiries welcome</span><span class="dom">cannabisofthemonthclub.com</span></div>
 </main>
diff --git a/sites/hempofthemonthclub.com/img/01.jpg b/sites/hempofthemonthclub.com/img/01.jpg
new file mode 100644
index 0000000..6a036f6
Binary files /dev/null and b/sites/hempofthemonthclub.com/img/01.jpg differ
diff --git a/sites/hempofthemonthclub.com/img/02.jpg b/sites/hempofthemonthclub.com/img/02.jpg
new file mode 100644
index 0000000..c4efa44
Binary files /dev/null and b/sites/hempofthemonthclub.com/img/02.jpg differ
diff --git a/sites/hempofthemonthclub.com/index.html b/sites/hempofthemonthclub.com/index.html
index 0d011cd..e95a729 100644
--- a/sites/hempofthemonthclub.com/index.html
+++ b/sites/hempofthemonthclub.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
@@ -83,7 +84,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
     <a class="ghost" href="#gallery">Learn more</a>
   </div>
   <div class="galhead"><h2>Gallery</h2><span class="n">6 images · placeholders — swap real assets before launch</span></div>
-  <div class="gallery" id="gallery"><div class="tile"><span class="ph">Placeholder 01</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 02</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
+  <div class="gallery" id="gallery"><div class="tile"><img src="img/01.jpg" alt="hempofthemonthclub.com — image 01" loading="lazy"></div><div class="tile"><img src="img/02.jpg" alt="hempofthemonthclub.com — image 02" loading="lazy"></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
   <div class="about"><span class="k">About this domain</span><p><b>hempofthemonthclub.com</b> — A clean subscription-commerce name for the hemp and CBD category.</p></div>
   <div class="foot"><span>Part of a curated domain portfolio · inquiries welcome</span><span class="dom">hempofthemonthclub.com</span></div>
 </main>
diff --git a/sites/hospitalitysalesrepresentatives.com/index.html b/sites/hospitalitysalesrepresentatives.com/index.html
index aa1714c..5c6bf87 100644
--- a/sites/hospitalitysalesrepresentatives.com/index.html
+++ b/sites/hospitalitysalesrepresentatives.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
diff --git a/sites/marijuanaofthemonthclub.com/index.html b/sites/marijuanaofthemonthclub.com/index.html
index d2c46c9..913d169 100644
--- a/sites/marijuanaofthemonthclub.com/index.html
+++ b/sites/marijuanaofthemonthclub.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
diff --git a/sites/mymemosamples.com/img/01.jpg b/sites/mymemosamples.com/img/01.jpg
new file mode 100644
index 0000000..eca2d91
Binary files /dev/null and b/sites/mymemosamples.com/img/01.jpg differ
diff --git a/sites/mymemosamples.com/index.html b/sites/mymemosamples.com/index.html
index ab6d374..354ecc4 100644
--- a/sites/mymemosamples.com/index.html
+++ b/sites/mymemosamples.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
@@ -83,7 +84,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
     <a class="ghost" href="#gallery">Learn more</a>
   </div>
   <div class="galhead"><h2>Gallery</h2><span class="n">6 images · placeholders — swap real assets before launch</span></div>
-  <div class="gallery" id="gallery"><div class="tile"><span class="ph">Placeholder 01</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 02</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
+  <div class="gallery" id="gallery"><div class="tile"><img src="img/01.jpg" alt="mymemosamples.com — image 01" loading="lazy"></div><div class="tile"><span class="ph">Placeholder 02</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
   <div class="about"><span class="k">About this domain</span><p><b>mymemosamples.com</b> — A precise SaaS-ready brand for memo-sample management in textiles and wallcoverings.</p></div>
   <div class="foot"><span>Part of a curated domain portfolio · inquiries welcome</span><span class="dom">mymemosamples.com</span></div>
 </main>
diff --git a/sites/potofthemonthclub.com/index.html b/sites/potofthemonthclub.com/index.html
index 574a14d..4385eae 100644
--- a/sites/potofthemonthclub.com/index.html
+++ b/sites/potofthemonthclub.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
diff --git a/sites/protectyourspec.com/img/01.jpg b/sites/protectyourspec.com/img/01.jpg
new file mode 100644
index 0000000..38d7be5
Binary files /dev/null and b/sites/protectyourspec.com/img/01.jpg differ
diff --git a/sites/protectyourspec.com/img/02.jpg b/sites/protectyourspec.com/img/02.jpg
new file mode 100644
index 0000000..647a817
Binary files /dev/null and b/sites/protectyourspec.com/img/02.jpg differ
diff --git a/sites/protectyourspec.com/img/03.jpg b/sites/protectyourspec.com/img/03.jpg
new file mode 100644
index 0000000..4584f57
Binary files /dev/null and b/sites/protectyourspec.com/img/03.jpg differ
diff --git a/sites/protectyourspec.com/img/04.jpg b/sites/protectyourspec.com/img/04.jpg
new file mode 100644
index 0000000..d60ee1b
Binary files /dev/null and b/sites/protectyourspec.com/img/04.jpg differ
diff --git a/sites/protectyourspec.com/img/05.jpg b/sites/protectyourspec.com/img/05.jpg
new file mode 100644
index 0000000..d0c4230
Binary files /dev/null and b/sites/protectyourspec.com/img/05.jpg differ
diff --git a/sites/protectyourspec.com/img/06.jpg b/sites/protectyourspec.com/img/06.jpg
new file mode 100644
index 0000000..f4a5b0c
Binary files /dev/null and b/sites/protectyourspec.com/img/06.jpg differ
diff --git a/sites/protectyourspec.com/index.html b/sites/protectyourspec.com/index.html
index 919c62b..6fcc204 100644
--- a/sites/protectyourspec.com/index.html
+++ b/sites/protectyourspec.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
@@ -82,8 +83,8 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
     <a class="cta" href="mailto:info@designerwallcoverings.com?subject=Domain%20inquiry%3A%20protectyourspec.com">Make an offer →</a>
     <a class="ghost" href="#gallery">Learn more</a>
   </div>
-  <div class="galhead"><h2>Gallery</h2><span class="n">6 images · placeholders — swap real assets before launch</span></div>
-  <div class="gallery" id="gallery"><div class="tile"><span class="ph">Placeholder 01</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 02</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 03</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 04</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 05</span><span class="lbl">1600 × 1200 · swap real image</span></div><div class="tile"><span class="ph">Placeholder 06</span><span class="lbl">1600 × 1200 · swap real image</span></div></div>
+  <div class="galhead"><h2>Gallery</h2><span class="n">6 images</span></div>
+  <div class="gallery" id="gallery"><div class="tile"><img src="img/01.jpg" alt="protectyourspec.com — image 01" loading="lazy"></div><div class="tile"><img src="img/02.jpg" alt="protectyourspec.com — image 02" loading="lazy"></div><div class="tile"><img src="img/03.jpg" alt="protectyourspec.com — image 03" loading="lazy"></div><div class="tile"><img src="img/04.jpg" alt="protectyourspec.com — image 04" loading="lazy"></div><div class="tile"><img src="img/05.jpg" alt="protectyourspec.com — image 05" loading="lazy"></div><div class="tile"><img src="img/06.jpg" alt="protectyourspec.com — image 06" loading="lazy"></div></div>
   <div class="about"><span class="k">About this domain</span><p><b>protectyourspec.com</b> — A punchy brand for spec-protection and substitution monitoring in the A&amp;D world.</p></div>
   <div class="foot"><span>Part of a curated domain portfolio · inquiries welcome</span><span class="dom">protectyourspec.com</span></div>
 </main>
diff --git a/sites/weedofthemonthclub.com/index.html b/sites/weedofthemonthclub.com/index.html
index f08f126..78d4702 100644
--- a/sites/weedofthemonthclub.com/index.html
+++ b/sites/weedofthemonthclub.com/index.html
@@ -67,6 +67,7 @@ h1{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-h
 .about b{color:var(--ink)}
 .foot{margin:40px 0 0;padding-top:20px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:10px 18px;justify-content:space-between;color:var(--faint);font-size:12.5px}
 .foot .dom{font-family:var(--mono);color:var(--muted)}
+.tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
 </style>
 </head>
 <body>
diff --git a/swap-html.py b/swap-html.py
new file mode 100644
index 0000000..563f855
--- /dev/null
+++ b/swap-html.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+"""Replace placeholder gallery tiles with real <img> tags in each lander, for images that exist."""
+import os, re, glob
+BASE = os.path.expanduser("~/Projects/parked-landers/sites")
+CSS_RULE = ".tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}"
+swapped = 0
+for idx in sorted(glob.glob(os.path.join(BASE, "*", "index.html"))):
+    dom = os.path.basename(os.path.dirname(idx))
+    imgdir = os.path.join(os.path.dirname(idx), "img")
+    html = open(idx).read()
+    tiles = []
+    for i in range(1, 7):
+        fp = os.path.join(imgdir, f"{i:02d}.jpg")
+        if os.path.exists(fp):
+            tiles.append(f'<div class="tile"><img src="img/{i:02d}.jpg" alt="{dom} — image {i:02d}" loading="lazy"></div>')
+        else:  # keep placeholder if the image is missing
+            tiles.append(f'<div class="tile"><span class="ph">Placeholder {i:02d}</span>'
+                         f'<span class="lbl">1600 × 1200 · swap real image</span></div>')
+    new_gallery = '<div class="gallery" id="gallery">' + "".join(tiles) + '</div>'
+    html2 = re.sub(r'<div class="gallery" id="gallery">.*?</div>\s*(?=<div class="about">)',
+                   new_gallery + "\n  ", html, count=1, flags=re.S)
+    if CSS_RULE not in html2:
+        html2 = html2.replace("</style>", CSS_RULE + "\n</style>", 1)
+    # update the gallery caption to drop "placeholders" once all 6 are real
+    if all(os.path.exists(os.path.join(imgdir, f"{i:02d}.jpg")) for i in range(1, 7)):
+        html2 = html2.replace("6 images · placeholders — swap real assets before launch", "6 images")
+    if html2 != html:
+        open(idx, "w").write(html2); swapped += 1
+        print(f"swapped {dom} ({sum(1 for i in range(1,7) if os.path.exists(os.path.join(imgdir,f'{i:02d}.jpg')))}/6 real)")
+print(f"done — {swapped} files updated")

← f83f71c auto-data-snapshot: 2026-09-09T11:42:56 (1 data files) — .gi  ·  back to Parked Landers  ·  All 8 landers: real flux images swapped in (0 placeholders) 5283034 →