Site Control Layer
site.json, the SiteConfig schema, and the three-level control panel that drives dh-site-engine.
Live foundationThe universal SITE layer of the stack. One file holds every site-wide knob: width, spacing, header, footer, universal sections, breakpoints, radii, z-index. Edit it, the whole site re-renders. This fills the "siteStructure": {} slot that sat empty in bex.json.
The three-layer boundary
Keep these clean and the whole system stays swappable.
| Layer | File | Owns | Editor today |
|---|---|---|---|
| 1. Site | site.json |
Skeleton: widths, spacing, header, footer, universal sections | No panel yet, Level 2 build |
| 2. Brand | brand.json |
Skin: colors, fonts, vibe, surface palettes | Brand With AI editor |
| 3. Content | Notion DBs | Subject: locations, people, articles, copy | Notion |
Rule: site.json carries no colors and no font families. The site layer says “the signature surface exists and the CTA band uses it.” The brand pack says “the signature surface is teal.” That separation is what lets one site skeleton wear unlimited brands.
What site.json actually controls
Layout
outerMax (1200px), contentMax, readingMax (720px prose column), cardMax, gutters per breakpoint, section rhythm as a fluid clamp, a density preset (tight/comfortable/spacious).
Header + footer
Nav height, sticky/blur, logo mode, nav links, CTA button, footer columns, social row, legal line. One definition, rendered identically on every page.
Surfaces
The 5 .s-* section skins: light, sand, dark, deep, signature. Surface MODES are structural (live here). Surface COLORS are brand-pack (live in brand.json).
Universal sections
Announcement bar, ticker, CTA band, newsletter strip. Each has an enabled flag and a default surface, toggled site-wide from one place.
The control panel ladder
Level 1 — Prototype (shipped)
A hand-built faithful mock. Drag a knob, download the file, hand it to the engine, rebuild. Source of truth is a downloaded file.
Level 2 — Connected (next)
The REAL engine output renders in an iframe. Drag → see the real render in seconds. A one-click preview link (*.pages.dev). Two build slices: the real-engine iframe (the visible win), then the “activation pass” that wires every already-emitted CSS variable into the actual stylesheet so no knob in the panel ever lies.
Level 3 — Live cockpit (after the Strapi blog stack lands)
Edits write straight to the Strapi SiteConfig singleton. Publish is one click, the live site updates on next refresh. The Site panel, the Brand With AI editor, and Notion become three tabs on one cockpit: skeleton, skin, subject. Anyone can run it, Andrew, Rene, or a client.
Two engines, one domain
designhacker.com runs two render engines behind one domain, joined at the /blog seam.
| Apex engine | Blog engine | |
|---|---|---|
| Serves | /, /watch, /about, /join, /contact |
/blog, /blog/{slug} |
| Tech | dh-site-engine (Notion + Node, Cloudflare Pages) | Rene’s Strapi + Next.js |
| Content | Notion (Video DB) + copy | Strapi articles |
| Owner | Andrew | Rene |
What keeps the seam invisible: both engines render the same brand values (#A5205B plum, Poppins), both render site.json’s header/footer as the one shared chrome contract, and nav always points /blog at the same place. The apex itself stays lean, 4 page types plus 2 forms: Home, Watch index, Watch detail, About, Join, Contact.
Where the real build actually stands
- Live and deployed: designhacker.com serves the current hero, the rewired opt-in (consent, honeypot),
/thanks/checklist/,/club-offer/, and/story/revenue-brain/(DH Build Story #1). The Cloudflare zone-rule exception that lets/club-offer/*and/story/*serve from CF Pages instead of hopping to community.designhacker.com is verified live. - Workers live:
bbe-lead,bbe-events,bbe-rules,bbe-rollup. Beacon confirmed firing on home and thanks pages. - Domain posture: production stays ROBOTS DISALLOW (staging posture) until a deliberate ROBOTS=allow decision at soft launch.
/club-offer/carries its own hardcoded noindex separate from that global flip. - Agent surface: md twins,
llms.txt,feed.json,offers.json,concepts.jsonare built locally in dh-site-engine, deliberately unpushed until the full-site era.
Standing engine-level rules
Only designhacker.com publishes indexable content, subfolders compound, subdomains never rank, per the Domain Law ruling. Podia appears only as checkout links. Anything built here that a second brand could reuse gets written brand-agnostic and logged as engine IP in the BBE Master Plan, never DH-only.