← back to Homesonspec
web: honest Lennar-anchored positioning (TK-10 blocker C)
ef45303a1c1c4d4e19cb6806e2e95dda7d63419a · 2026-07-27 16:41:07 -0700 · Steve Abrams
- hero stat leads with homes+metros; shows builder count only when >1,
else 'more builders coming' (no '1 builder' under 'Every builder')
- builder count now counts only builders with live published inventory
- builder photos default OFF (BUILDER_IMAGES_ENABLED=1 to opt in) on BOTH
homepage and home-detail — media-rights safe per docs/data-rights/POLICY.md
- drop over-claims from root + /builders meta descriptions
(no 'across the United States' / 'national, regional, and local')
Verified: web build compiles clean; renders '...27 metros · more builders
coming', no builder <img>, home detail 200. Gated go-live still blocked on
TK-10 A (leaked GoDaddy key) + B (committed admin default).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
M apps/web/src/app/builders/page.tsxM apps/web/src/app/homes/[id]/page.tsxM apps/web/src/app/layout.tsxM apps/web/src/app/page.tsx
Diff
commit ef45303a1c1c4d4e19cb6806e2e95dda7d63419a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 27 16:41:07 2026 -0700
web: honest Lennar-anchored positioning (TK-10 blocker C)
- hero stat leads with homes+metros; shows builder count only when >1,
else 'more builders coming' (no '1 builder' under 'Every builder')
- builder count now counts only builders with live published inventory
- builder photos default OFF (BUILDER_IMAGES_ENABLED=1 to opt in) on BOTH
homepage and home-detail — media-rights safe per docs/data-rights/POLICY.md
- drop over-claims from root + /builders meta descriptions
(no 'across the United States' / 'national, regional, and local')
Verified: web build compiles clean; renders '...27 metros · more builders
coming', no builder <img>, home detail 200. Gated go-live still blocked on
TK-10 A (leaked GoDaddy key) + B (committed admin default).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
apps/web/src/app/builders/page.tsx | 2 +-
apps/web/src/app/homes/[id]/page.tsx | 5 +++--
apps/web/src/app/layout.tsx | 2 +-
apps/web/src/app/page.tsx | 27 ++++++++++++++++++++-------
4 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/apps/web/src/app/builders/page.tsx b/apps/web/src/app/builders/page.tsx
index 52175ec..ee7a1c5 100644
--- a/apps/web/src/app/builders/page.tsx
+++ b/apps/web/src/app/builders/page.tsx
@@ -6,7 +6,7 @@ export const dynamic = "force-dynamic";
export const metadata = {
title: "Home Builders Directory | HomesOnSpec",
description:
- "Every home builder on HomesOnSpec — national, regional, and local — with their coverage area, website, and live inventory count.",
+ "Home builders indexed on HomesOnSpec, with each builder's coverage area, website, and live verified inventory count. New builders added continuously.",
};
export default async function BuildersDirectoryPage() {
diff --git a/apps/web/src/app/homes/[id]/page.tsx b/apps/web/src/app/homes/[id]/page.tsx
index 23a7eef..340eecb 100644
--- a/apps/web/src/app/homes/[id]/page.tsx
+++ b/apps/web/src/app/homes/[id]/page.tsx
@@ -56,8 +56,9 @@ export default async function HomeDetailPage({ params }: { params: Promise<{ id:
}),
]);
const incentives = [...home.incentives, ...communityIncentives];
- // Kill-switch for third-party builder photography (media-rights gate).
- const showImages = process.env.BUILDER_IMAGES_ENABLED !== "0";
+ // Media-rights safe default: builder photos are OFF unless BUILDER_IMAGES_ENABLED=1
+ // is explicitly set (must match the homepage default — facts-only per docs/data-rights/POLICY.md).
+ const showImages = process.env.BUILDER_IMAGES_ENABLED === "1";
// Dedupe evidence to one row per field (newest retrieval). Re-crawls produce a
// fresh snapshot each time (dynamic source content), so raw evidence accumulates
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx
index 8afd51a..3eadff6 100644
--- a/apps/web/src/app/layout.tsx
+++ b/apps/web/src/app/layout.tsx
@@ -15,7 +15,7 @@ const sans = Inter({ subsets: ["latin"], variable: "--font-inter" });
export const metadata: Metadata = {
title: "HomesOnSpec — Every new home. Every builder. One search.",
description:
- "Discover, compare, and contact builders for newly constructed homes across the United States. Verified from the source.",
+ "Discover, compare, and contact builders for newly constructed homes. Verified from the source, with live verification labels — new builders and markets added continuously.",
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index 70ab6d4..016457f 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -11,7 +11,11 @@ export default async function HomePage() {
_count: { _all: true },
});
const homeCount = await prisma.inventoryHome.count({ where: { status: "PUBLISHED", isDemo: false } });
- const builderCount = await prisma.builder.count({ where: { isDemo: false } });
+ // Count only builders that actually have live inventory — never claim coverage
+ // we don't have. Builders seeded without published homes aren't counted here.
+ const builderCount = await prisma.builder.count({
+ where: { isDemo: false, homes: { some: { status: "PUBLISHED", isDemo: false } } },
+ });
// Community markers for the hero map — one point per community with live
// inventory (capped for a fast first paint). Convert Decimal lat/lon to plain
@@ -69,9 +73,10 @@ export default async function HomePage() {
{ tier: "Luxury", home: highHome },
].filter((f): f is { tier: string; home: NonNullable<typeof f.home> } => f.home !== null);
- // Kill-switch: set BUILDER_IMAGES_ENABLED=0 (pm2 env) to instantly stop showing
- // third-party builder photos site-wide, pending a media-rights decision.
- const showImages = process.env.BUILDER_IMAGES_ENABLED !== "0";
+ // Media-rights safe default: builder photos are OFF unless BUILDER_IMAGES_ENABLED=1
+ // is explicitly set (pm2 env), pending registry-recorded rights per docs/data-rights/POLICY.md.
+ // Facts-only is the binding default; opt IN to images only once rights are confirmed.
+ const showImages = process.env.BUILDER_IMAGES_ENABLED === "1";
return (
<div>
@@ -89,8 +94,8 @@ export default async function HomePage() {
<p className="mx-auto mt-3 max-w-2xl text-sm text-brand-200/90">
Search “spec home listings” today and you get scattered builder sites, generic portals, and
blog posts — there is no one place to see them all. Builders list inventory on dozens of
- separate websites that never meet. HomesOnSpec puts every builder's available inventory in
- one verified search.
+ separate websites that never meet. HomesOnSpec brings builders' available inventory into
+ one verified search — and we add builders continuously.
</p>
<form action="/search" method="get" className="mx-auto mt-8 flex max-w-xl gap-2">
<input
@@ -103,10 +108,18 @@ export default async function HomePage() {
Search
</button>
</form>
+ {/* Lead with the real scale signals (homes + metros); show the builder count
+ only once it reads as breadth (>1), otherwise state the honest forward-looking
+ posture rather than a "1 builder" that undercuts the page. */}
<p className="mt-5 text-sm text-brand-200">
<span className="font-semibold text-white">{homeCount.toLocaleString()}</span> verified homes
- {" · "}<span className="font-semibold text-white">{builderCount}</span> builders
{" · "}<span className="font-semibold text-white">{markets.length}</span> metros
+ {" · "}
+ {builderCount > 1 ? (
+ <><span className="font-semibold text-white">{builderCount}</span> builders</>
+ ) : (
+ <span className="font-semibold text-white">more builders coming</span>
+ )}
</p>
</div>
← 0d87dcd chore: v0.2.1 (session close) — spechomes pm2 prod + redeplo
·
back to Homesonspec
·
auto-save: 2026-07-27T16:52:13 (3 files) — apps/workers/src/ 2fa9a7f →