"The sports agent for entrepreneurs."
The official product website for CWK. Experience — long-term business management for high-performing entrepreneurs ($150K–$5M). Built on Astro, deployed globally via Cloudflare Pages.
Live site: cwkexperience.com
| Environment | URL | Trigger |
|---|---|---|
| Production | cwkexperience.com | Push to main |
| Preview | *.houseofcwk.pages.dev |
Pull request |
Deploys are automatic via GitHub Actions → cloudflare/wrangler-action@v3. Build time is typically under 30 seconds.
npm install
npm run dev # http://localhost:4321
npm run build # Production build → dist/
npm run preview # Preview dist/ locallynpm run build
cp .dev.vars.example .dev.vars # fill in RESEND_API and other secrets
npx wrangler pages dev dist --kv WAITLIST| Layer | Technology |
|---|---|
| Framework | Astro 5 — static output, islands architecture |
| Interactivity | React 19 islands via client:visible |
| Styling | Vanilla CSS — custom dark-mode design system (no utility framework) |
| Edge functions | Cloudflare Pages Functions (src/functions/) |
| Storage | Cloudflare KV — waitlist email deduplication |
| Resend — transactional confirmation emails | |
| Sitemap | @astrojs/sitemap — auto-generated at /sitemap-index.xml |
| Analytics | Cloudflare Web Analytics — privacy-first, no cookie banner |
| Deployment | Cloudflare Pages |
src/
├── components/
│ ├── Header.astro # Fixed nav with backdrop blur
│ ├── Footer.astro # Logo, nav columns, legal
│ ├── SEO.astro # OG tags, Twitter Card, canonical URL
│ ├── WaitlistForm.tsx # React island — 5-state waitlist form
│ └── mocks/ # Static glassmorphic UI mockups
│ ├── MockDashboard.astro
│ ├── MockRelationships.astro
│ ├── MockPipeline.astro
│ ├── MockActions.astro
│ ├── MockKaia.astro
│ └── MockDestination.astro
├── layouts/
│ └── Base.astro # HTML shell, ambient orbs, noise overlay
├── middleware.ts # HTTP Basic Auth (pre-launch gate)
└── pages/
├── index.astro # Homepage — hero → pillars → proof → waitlist
├── product.astro # Agent+ product page — 6 feature showcases
└── 404.astro # Custom 404
public/
├── og-image.svg # 1200×630 branded OG image (SVG)
├── robots.txt # Allow all, sitemap link
└── _redirects # 13 × 301 redirects from old URLs
docs/
├── DESIGN.md # Full design system — tokens, components, patterns
├── SITE_STRUCTURE.md # Sitemap, page specs, component inventory
├── WEBSITE_CONTENT.md # All page copy
└── DEPLOYMENT_GUIDE.md # Cloudflare Pages setup, KV binding, Resend config
All HTTP APIs are served by a single Cloudflare Worker (cwk-api-prod)
bound to api.cwkexperience.com. Source lives at workers/api/;
see workers/api/README.md for the endpoint map,
deploy steps, and secrets.
| Endpoint | Handler |
|---|---|
POST https://api.cwkexperience.com/waitlist |
handlers/waitlist.ts |
POST https://api.cwkexperience.com/contact |
handlers/contact.ts |
GET https://api.cwkexperience.com/healthz |
{ "ok": true } |
| Response | Meaning |
|---|---|
200 |
Email stored in WAITLIST KV; confirmation sent via Resend |
409 |
Email already on the waitlist |
422 |
Invalid email format |
500 |
Server error |
Duplicate detection uses Cloudflare KV (WAITLIST namespace). Confirmation
email fires via ctx.waitUntil() — non-blocking, fire-and-forget.
Layered spam defenses (honeypot, time-floor, Turnstile, content heuristics,
disposable-email blocklist) plus KV rate limits (IP 5/10min + 20/day, email
3/day). Submissions persist to the CONTACTS KV with a 180-day TTL and salted
SHA-256 IP hashing. Full payload + response schema in
workers/api/src/handlers/contact.ts.
Copy .env.example → .env for public vars. Copy .dev.vars.example → .dev.vars for secrets (never committed).
| Variable | Where set | Purpose |
|---|---|---|
PUBLIC_SITE_URL |
.env / CF Pages |
Canonical site URL |
PUBLIC_CF_ANALYTICS_TOKEN |
.env / CF Pages |
Web Analytics token |
RESEND_API |
CF Pages secret | Resend API key |
FROM_EMAIL |
CF Pages secret | waitlist@cwkexperience.com |
FROM_NAME |
CF Pages secret | Sender display name |
REPLY_TO_EMAIL |
CF Pages secret | kris@cwkexperience.com |
REPLY_TO_NAME |
CF Pages secret | Reply-to display name |
WAITLIST |
CF Pages KV binding | KV namespace (not an env var) |
Set secrets via Wrangler:
wrangler pages secret put RESEND_API --project-name=houseofcwk| Document | Purpose |
|---|---|
| AGENTS.md | AI coding context — conventions, patterns, constraints |
| CONTEXT.md | Product context — what we're building and why |
| docs/DESIGN.md | Design system — colors, typography, glassmorphism, components |
| docs/SITE_STRUCTURE.md | Sitemap, page specs, component inventory |
| docs/WEBSITE_CONTENT.md | All page copy |
| docs/DEPLOYMENT_GUIDE.md | CF Pages setup, KV bindings, Resend, custom domain |
| Project | Repo | Relationship |
|---|---|---|
| Platform Monorepo | houseofcwk/platform | Parent repo — this project is a submodule |
| CWK Agent+ Dashboard | CWK-Experience/cwk-exp-main | Internal app — site links to it for client login |
Build. Learn. Earn. Play. — CWK. LLC