← back to Parked Landers
gen-landers.py
124 lines
import os,html
OUT="/private/tmp/claude-501/-Users-macstudio3/4dea47cf-86bd-4fb4-b16c-e84321b6a10d/scratchpad/parked-landers"
DOMAINS=[
("protectyourspec.com","Protect Your Spec",158,"Keep your specification intact from design through install.","A punchy brand for spec-protection and substitution monitoring in the A&D world."),
("cannabisofthemonthclub.com","Cannabis of the Month Club",128,"A curated cannabis selection, delivered monthly.","A high-recall subscription brand for the regulated cannabis market."),
("hempofthemonthclub.com","Hemp of the Month Club",138,"Premium hemp goods, curated and delivered monthly.","A clean subscription-commerce name for the hemp and CBD category."),
("marijuanaofthemonthclub.com","Marijuana of the Month Club",118,"A monthly membership for the discerning enthusiast.","A direct, keyword-strong subscription brand in the cannabis vertical."),
("potofthemonthclub.com","Pot of the Month Club",108,"Small-batch selections, delivered monthly.","A friendly, informal subscription brand for the cannabis market."),
("weedofthemonthclub.com","Weed of the Month Club",148,"A curated monthly membership.","A conversational, high-search subscription name in the cannabis category."),
("mymemosamples.com","My Memo Samples",262,"Order, track, and manage your memo samples in one place.","A precise SaaS-ready brand for memo-sample management in textiles and wallcoverings."),
("hospitalitysalesrepresentatives.com","Hospitality Sales Representatives",168,"Specialist reps for the hospitality supply market.","A descriptive, authority-signalling name for hospitality-sector sales representation."),
]
TPL=r'''<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{TITLE}</title>
<meta name="description" content="{DESC}">
<meta name="robots" content="noindex,nofollow">
<link rel="canonical" href="https://{DOM}/">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,600;9..144,700&family=Public+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap">
<style>
:root{{
--h:{HUE};
--bg:#f2f1ec;--panel:#ffffff;--panel2:#faf9f5;--ink:#17181b;--muted:#5c5f66;--faint:#8b8d93;
--rule:#e4e2da;--accent:hsl(var(--h) 55% 38%);--accent-ink:#fff;
--tile-a:hsl(var(--h) 34% 90%);--tile-b:hsl(var(--h) 46% 76%);--tile-lbl:hsl(var(--h) 30% 34%);
--shadow:0 1px 2px rgba(20,20,25,.05),0 10px 30px rgba(20,20,25,.06);
--disp:'Fraunces',Georgia,serif;--sans:'Public Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
--mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;
}}
@media (prefers-color-scheme:dark){{:root:not([data-theme="light"]){{
--bg:#111214;--panel:#191b1e;--panel2:#15171a;--ink:#ecebe6;--muted:#a3a5ab;--faint:#74767c;
--rule:#2a2d31;--accent:hsl(var(--h) 60% 64%);--accent-ink:#0d0f11;
--tile-a:hsl(var(--h) 26% 20%);--tile-b:hsl(var(--h) 34% 30%);--tile-lbl:hsl(var(--h) 40% 74%);
--shadow:0 1px 2px rgba(0,0,0,.35),0 12px 34px rgba(0,0,0,.4);
}}}}
:root[data-theme="dark"]{{
--bg:#111214;--panel:#191b1e;--panel2:#15171a;--ink:#ecebe6;--muted:#a3a5ab;--faint:#74767c;
--rule:#2a2d31;--accent:hsl(var(--h) 60% 64%);--accent-ink:#0d0f11;
--tile-a:hsl(var(--h) 26% 20%);--tile-b:hsl(var(--h) 34% 30%);--tile-lbl:hsl(var(--h) 40% 74%);
--shadow:0 1px 2px rgba(0,0,0,.35),0 12px 34px rgba(0,0,0,.4);
}}
*{{box-sizing:border-box}}
body{{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.5;-webkit-font-smoothing:antialiased}}
@media (prefers-reduced-motion:reduce){{*{{transition:none!important;animation:none!important}}}}
.stage{{max-width:1080px;margin:0 auto;padding:48px 22px 64px}}
.top{{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:26px}}
.brand{{font-family:var(--mono);font-size:12.5px;color:var(--muted)}}
.tbtn{{font-family:var(--sans);font-size:12.5px;color:var(--muted);background:var(--panel);border:1px solid var(--rule);border-radius:8px;padding:8px 12px;cursor:pointer}}
.tbtn:hover{{color:var(--ink);border-color:var(--accent)}}
.tbtn:focus-visible,.cta:focus-visible,.ghost:focus-visible{{outline:2px solid var(--accent);outline-offset:2px}}
.eyebrow{{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:12px;color:var(--accent);border:1px solid color-mix(in srgb,var(--accent) 40%,var(--rule));background:var(--panel);padding:5px 11px;border-radius:999px}}
.eyebrow .dot{{width:7px;height:7px;border-radius:50%;background:var(--accent)}}
h1{{font-family:var(--disp);font-weight:600;font-size:clamp(38px,7vw,68px);line-height:1.02;letter-spacing:-.02em;margin:20px 0 0;text-wrap:balance;max-width:14ch}}
.lede{{font-size:clamp(16px,2.3vw,20px);color:var(--muted);max-width:56ch;margin:16px 0 0}}
.actions{{display:flex;flex-wrap:wrap;gap:12px;margin:26px 0 0}}
.cta{{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:15px;background:var(--accent);color:var(--accent-ink);border-radius:10px;padding:12px 20px;text-decoration:none;transition:.15s}}
.cta:hover{{filter:brightness(1.06);transform:translateY(-1px)}}
.ghost{{display:inline-flex;font-weight:500;font-size:15px;color:var(--ink);text-decoration:none;border:1px solid var(--rule);border-radius:10px;padding:12px 18px;background:var(--panel)}}
.ghost:hover{{border-color:var(--accent);color:var(--accent)}}
.galhead{{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:52px 0 14px;flex-wrap:wrap}}
.galhead h2{{font-family:var(--disp);font-weight:600;font-size:22px;margin:0}}
.galhead .n{{font-family:var(--mono);font-size:11.5px;color:var(--faint)}}
.gallery{{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}}
@media(max-width:760px){{.gallery{{grid-template-columns:repeat(2,1fr)}}}}
@media(max-width:460px){{.gallery{{grid-template-columns:1fr}}}}
.tile{{position:relative;aspect-ratio:4/3;border-radius:12px;overflow:hidden;border:1px solid var(--rule);background:linear-gradient(135deg,var(--tile-a),var(--tile-b));box-shadow:var(--shadow);display:flex;align-items:flex-end;padding:12px}}
.tile::before{{content:"";position:absolute;inset:0;background:radial-gradient(120% 90% at 15% 12%,color-mix(in srgb,#fff 22%,transparent),transparent 55%)}}
.tile .lbl{{position:relative;font-family:var(--mono);font-size:11px;color:var(--tile-lbl);background:color-mix(in srgb,var(--panel) 72%,transparent);border:1px solid color-mix(in srgb,var(--tile-lbl) 22%,transparent);padding:4px 8px;border-radius:6px}}
.tile .ph{{position:absolute;top:12px;left:12px;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:color-mix(in srgb,var(--tile-lbl) 80%,transparent)}}
.about{{margin:48px 0 0;padding:22px 24px;background:var(--panel2);border:1px solid var(--rule);border-radius:14px;display:grid;grid-template-columns:auto 1fr;gap:18px}}
@media(max-width:560px){{.about{{grid-template-columns:1fr}}}}
.about .k{{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}}
.about p{{margin:0;color:var(--muted);font-size:14.5px;max-width:60ch}}
.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)}}
</style>
</head>
<body>
<main class="stage">
<div class="top">
<span class="brand">{DOM}</span>
<button class="tbtn" id="theme" type="button" aria-label="Toggle light or dark theme">◐ Theme</button>
</div>
<span class="eyebrow"><span class="dot"></span>{DOM}</span>
<h1>{TITLE}</h1>
<p class="lede">{LEDE}</p>
<div class="actions">
<a class="cta" href="mailto:info@designerwallcoverings.com?subject=Domain%20inquiry%3A%20{DOM}">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">{TILES}</div>
<div class="about"><span class="k">About this domain</span><p><b>{DOM}</b> — {ABOUT}</p></div>
<div class="foot"><span>Part of a curated domain portfolio · inquiries welcome</span><span class="dom">{DOM}</span></div>
</main>
<script>
(function(){{var r=document.documentElement,b=document.getElementById("theme");
function ap(m){{if(m==="light"||m==="dark")r.setAttribute("data-theme",m);else r.removeAttribute("data-theme");}}
try{{var t=localStorage.getItem("pl.theme");if(t)ap(t);}}catch(e){{}}
b.addEventListener("click",function(){{var c=r.getAttribute("data-theme");var n=c==="dark"?"light":(c==="light"?"dark":(matchMedia("(prefers-color-scheme:dark)").matches?"light":"dark"));ap(n);try{{localStorage.setItem("pl.theme",n);}}catch(e){{}}}});}})();
</script>
</body>
</html>
'''
def tiles():
out=""
for i in range(1,7):
out+=f'<div class="tile"><span class="ph">Placeholder {i:02d}</span><span class="lbl">1600 × 1200 · swap real image</span></div>'
return out
for dom,title,hue,lede,about in DOMAINS:
d=os.path.join(OUT,dom); os.makedirs(d,exist_ok=True)
page=TPL.format(DOM=dom,TITLE=html.escape(title),DESC=html.escape(lede),HUE=hue,LEDE=html.escape(lede),ABOUT=html.escape(about),TILES=tiles())
open(os.path.join(d,"index.html"),"w").write(page)
print("Generated",len(DOMAINS),"landers:")
for dom,_,_,_,_ in DOMAINS:
p=os.path.join(OUT,dom,"index.html")
print(f" {dom:38s} {os.path.getsize(p):>6d} bytes {p}")