Website flow — type: "website" (independent brand, phased pipeline)

You are building ONE per-website Cloudflare Worker: a React 19 + TanStack Start app that is server-rendered (SSR) and deploys as a single Worker served at the website's own subdomain. A type: "website" product is a STANDALONE brand — no Higgsfield integration, no Quanta, no fnf SDK; the user's brand is the only brand on the page. If mid-build the request turns out to need Higgsfield generation, sign-in, or credits, that is a type: "app" — switch to references/app-flow.md.

Higgsfield as the asset engine — EVERY build. All visual assets on every website are generated with the Higgsfield CLI generation commands per references/asset-system.md. (Internal use of Higgsfield generation is invisible to visitors and always fine.)

Scope: build the real, full app. This stack ships complete, production-grade applications: real frontend AND backend, database (D1), file storage (R2), auth, third-party API integrations, background work. When the user describes an app, tool, site, or web product, BUILD IT with the website builder — it is the default for any web target. Never ask the user to confirm the platform, never downgrade to a "demo"/mockup as the safe option, and don't stall on scope questions beyond the single intake round defined below. Take the fullest reasonable interpretation and ship a working site.

Repo layout. The website project lives in app/ — its own package.json, src/, packages/, migrations/, build config, and the deploy inputs (app.manifest.json, wrangler.jsonc). Run every bun/build command from there.


THE PIPELINE — phases in order, artifacts + gates, no skipping

Every NEW build runs this machine. Each phase produces a named artifact the next phase consumes. Do not reorder, merge, or skip phases — "simple" briefs are where generic output happens. (Follow-up edits to an existing site do NOT restart the pipeline — see "Small edits" at the bottom.)

Before Phase 0 — intake (ONE batched round of questions, then never again)

The type is already resolved (the main skill also asks, in that first round, whether to publish to the community feed when ready — remember that for Phase 6). This single intake round carries the two website-specific questions worth asking; put both in the ONE batched round and never ask a second round.

  1. Animation — MANDATORY, ALWAYS ask on every --type website build. This question is NEVER skipped — ask it even when the request seems to imply a choice ("an animated site", "a plain static page"), even for a "simple" or "quick" site, even when you think you already know the answer. The user must make this call, not you. Offer exactly two options: - Animated (recommended) → sets Animation mode: animated-website — the scroll-scrub camera journey (the product default; mark it Recommended). - Non-animated → sets Animation mode: non-animated — a well-crafted site with lighter/optional motion, no mandatory camera journey.

If the request already leans one way, still ask — just point the Recommended marker at the implied option. Record the picked value on the brief's Animation mode line (Phase 0). ONLY if the user is genuinely unreachable / never answers do you proceed on the default (Animated) and say so in one line — never as a shortcut to avoid asking. 2. Brand constraints — an existing brand to honor (ask for colors/fonts/logo/photos/links) vs. free rein ("design the brand for me"). Whatever they don't have, you generate: the full identity kit plus the personalization ladder in references/asset-system.md (logo family, icon set, patterns, illustrations, state artwork, product universe). Free rein is the richer path, not the degraded one.

The Animation question (1) is always asked — never skip the round to avoid it. You may drop only question 2 when the brief already answers the brand question. If the user skips or is unreachable, default to Animated and say so in one line. Never ask a second round.

Phase 0 — Concept (app/design-brief.md, committed, BEFORE any code)

Write the brief (~40 lines). Every section mandatory; a generic line ("modern and clean", "Inter", "blue accent") means the brief is not done:

Either way, a passive autoplay loop is never the Tier-1 mechanic. - Section plan — ordered, one layout family per section, no consecutive repeats, ≥4 families for 6+ sections, eyebrow budget ceil(sections/3). - Asset plan — the full kit per references/asset-system.md (hero visual, section plates, content imagery, custom icon set, logo/monogram, OG; + video loop for cinema, + GLB for spectacle). - CTA inventory — every CTA named with its OWN interaction identity (no shared button style — see bespoke-chrome in references/image-to-code.md).

The brief is a contract: later phases may not silently contradict it — edit the brief first and say why.

Phase 1 — Reference boards (design the page as IMAGES)

Read references/reference-boards.md and execute it: ONE horizontal design reference image PER SECTION via higgsfield generate create (image models gpt_image_2 / nano_banana_pro), one committed combinatorial pick (theme paradigm, background character, typography character, hero architecture, section system, 4 signature components, narrative spine, second-read moment), composition anchor VARYING per board, palette locked across all boards. Look at every board and re-roll any that reads template-y (budget 2 re-rolls). Boards land in refs/ in the repo. The boards ARE the design — do not start Phase 3 with a generic board in the set.

Phase 2 — Asset system (submit everything, then build while it renders)

Read references/asset-system.md and submit the ENTIRE kit as async jobs right after the boards are chosen: hero visual (2 candidates + interaction pair), section plates, all content imagery, the custom generated icon set, the logo/monogram + favicon, the OG card — plus video loop (cinema) / GLB (spectacle). Poll between build steps; download into app/public/assets/; verify kit coherence when it lands (re-generate anything whose grade fights the boards). Never idle waiting on renders; never fall back to stock/picsum/CSS-only. For the animated website (A4, the default), follow references/scroll-scrub.md's specialized scene/clip chain: independent stills/dives may batch, but exact-frame forward legs are intentionally sequential. The normal "submit everything up front" rule never overrides a real rendered-frame dependency.

Phase 3 — Build to the boards, section by section

Read references/image-to-code.md and follow its discipline per section: re-read the board at build time, extract text/type-scale/spacing/color/ component logic, implement faithfully, anti-drift (when your habit disagrees with the board, the board wins). The craft floor in references/design-recipe.md still applies everywhere (hero discipline, layout bans, copy rules, zero em-dashes). Bespoke chrome: every CTA designed in its own component with its own interaction identity; no site-wide button utility classes. Registry components (references/wow-maker.md §5) remain available as raw material — restyled to the boards, never default-skinned. Build static-but-complete; motion is the next phase.

HARD STOP for Animation mode: animated-website — build the journey as the spine, not an afterthought. The scroll-scrub scene media (Phase 2) and the scroll-scrub component (app/src/components/scroll-scrub/scroll-scrub.tsx + .css, per references/scroll-scrub.md Phase 3) ARE the page — the semantic chapters are the page structure, not decoration added later. Materialize the scroll-scrub component and wire the real scene data in THIS phase. Do NOT build a generic static page of sections and plan to "add the camera journey later" — that is the exact failure this flow guards against, and it is caught by the Phase 5 gate. If the scene MP4 chain is still rendering, build the scroll-scrub component against its posters and swap the clips in when they land — never substitute a plain static layout for the animated website.

Phase 4 — Motion pass (tier-mandated, one focused pass)

Phase 5 — Mechanical gate (before first deploy; every item fixed)

Run the grep checklist in references/review-rubric.md §A: placeholders; em/en-dashes; banned palette families in tokens; eyebrow ration; unreferenced generated assets (every kit file used); h-screen; SSR safety; reduced-motion coverage; repeated CTA classes (bespoke-chrome violation); opacity-0 + whileInView combinations; section plan honored; copy self-audit. This is a completion gate — do not deploy with a failing item.

Phase 6 — Deploy

  1. bun run typecheck once, from app/ — ~15s locally vs a failed deploy round-trip plus a fix-and-redeploy loop. Fix what it finds, then deploy. This is the ONE pre-deploy local check; do not also run bun run build unless typecheck passed and the deploy still failed.
  2. higgsfield website deploy <website_id> — this ships the live public site immediately; there is no preview stage.
  3. Report: live URL (from higgsfield website status) — "Your site is live: " — + one-line concept statement + anything honestly skipped. Speak in product terms — no repo/commit/deploy jargon (see the SKILL.md "Talking to the user" rule).

Do NOT navigate to, screenshot, or run image analysis on the deployed site — the mechanical gate (the grep checklist in references/review-rubric.md §A) is the only verification.

  1. Publish. If the user opted in at intake, publish automatically now that the site is deployed with its cover + metadata filled — run higgsfield website publish <website_id> (don't wait to be asked) and share the community-feed listing URL it reports. Otherwise publish only when the user asks. (The $100k contest is for --type app products — don't pitch it for a plain website.)

Design references — read order

Design references — read order

  1. references/design-recipe.md — craft floor (ALWAYS read; short).
  2. references/scroll-scrub.md — the animated website, which is the DEFAULT Tier-1 experience for every website: read it in Phase 0. It owns the specialized boards/assets/runtime sequence and bundled Markdown code references for that build. Only read references/wow-catalog.md (Tier-1 technique menu + anti-convergence ledger + Phase 4 implementation contracts) when the user explicitly asked for something other than an animated website.
  3. references/reference-boards.md — Phase 1: per-section design boards.
  4. references/asset-system.md — Phase 2: the Higgsfield asset kit.
  5. references/image-to-code.md — Phase 3: faithful implementation + bespoke chrome + the CTA garment catalog.
  6. references/review-rubric.md — Phase 5: the mechanical gate.
  7. references/wow-maker.md — ingredient directory: motion/3D libs (§4), component registries (§5), signature effect patterns (§2), SSR pattern (§6). Only listed free/permissive sources may be used.
  8. references/design-taste-frontend.md — the full deep-dive playbook behind the recipe; consult for specific situations, not required start-to-end.
  9. references/app-cover.md — the branded 3:2 launch cover + OG image (stadium-capsule mask via the inlined compose script; hosted style refs). REQUIRED before every publish (og_image_url + marketplace_cover_url are mandatory feed-card fields — never run higgsfield website publish while they are empty), and whenever the user asks for a cover/OG image directly.

Do NOT search the skill library for other design guidance — everything is here.

Then route to the FUNCTIONAL reference for the task:

Task Read
Any website (the DEFAULT — animated website) / scrollable world / continuous camera journey / diorama fly-through / browse-through-an-industry site references/scroll-scrub.md — seam-locked media pipeline + React/CSS Markdown assets + mobile/QA contract
TanStack Start routes, SSR, server functions, Cloudflare Worker runtime references/runtime-and-infra.md
Cover / OG image ("cover", "обложка", "OG image", publish prep) references/app-cover.md — branded 3:2 cover + capsule OG mask
SEO: meta tags, OG/Twitter cards, robots/sitemap, JSON-LD, entity, GEO, audit references/seo.md
Security: Worker hardening, OWASP audit, threat modeling references/security.md

Stack

Hard rules

0a. Vendored packages and template modules

The app/packages/ directory contains managed snapshots vendored from the upstream Higgsfield web app (@higgsfield/fnf, @higgsfield/fnf-react, @higgsfield/quanta). Websites never use them, but do NOT edit or delete them. Template-owned infrastructure lives in app/src/module/**.

0b. Supercomputer Design mode inspector

Generated websites support a Higgsfield design inspector bridge for editing in Supercomputer Design mode. The split is strict:

Local scripts (LOCAL work only — the deploy build is owned by CI):

The platform CI sets HF_DESIGN_INSPECTOR=1 on every deploy build, so the live deployed site always carries the inspector and IS the surface Supercomputer Design mode opens. Exact source metadata is attached with inspector-only callback refs and a WeakMap, not DOM attributes. Keep the guarded dynamic install in app/src/routes/__root.tsx and the Vite integration in app/vite.config.ts wired to app/src/module/design-inspector/vite.

For every Supercomputer website-builder task there is ONE deploy — higgsfield website deploy <website_id> — and it ships the live public site immediately; there is no preview stage or environment choice. Publishing/listing on the community feed is separate: do NOT run higgsfield website publish unless the user explicitly asks to publish, list, or share the site. Never hard-code HF_DESIGN_INSPECTOR=1 into the build script and never hand-edit the build script to toggle it — the deploy build is CI-owned.

1. SSR-safe rendering

Every route renders on the server per request. NEVER touch browser-only globals (window, document, localStorage, navigator) at module top level or during render — only inside useEffect/event handlers, or guarded with typeof window !== "undefined". A top-level window reference crashes SSR.

2. Server-only code stays server-only

Put server logic in createServerFn(...).handler(...) or a *.server.ts module (the .server.ts suffix keeps it out of the client bundle). Secrets and bindings are read server-side, per request — never shipped to the browser.

3. No Higgsfield integration — but a REAL backend of the site's own

A type: "website" product never calls https://fnf.internal/*, never shows "Sign in with Higgsfield", and never imports the fnf SDK. It still gets a real backend wherever the product needs one: server functions (createServerFn), app-local API routes, sessions, business logic, and real persistence (D1) — never in-memory arrays, localStorage-as-database, or fixture data. In-app auth for the site's OWN users (accounts, teams, dashboards) is built with the website's own routes/storage. If the request needs generation or Higgsfield accounts, it is a type: "app" — switch to references/app-flow.md.

4. Cloudflare bindings via cloudflare:workers

Any infra you opt into (D1 DB, R2 STORAGE, KV KV) is read server-side through app/src/lib/bindings.server.ts (import { env } from "cloudflare:workers"). Each binding is present ONLY if declared in app/app.manifest.json, so the typed accessors are optional — guard before use. Do not thread env through React props or read it at module top level.

5. Opted-in storage is LIVE — one deploy, one database

If you opt into D1, R2, or KV, each is a SINGLE instance backing the ONE live deploy. There is no staging copy: every migration and data change hits live production data directly. - env.HF_ENV is always "production" on deployed builds; there is no separate database/bucket to test against. - A destructive migration you run "just to test" destroys production data. Prefer additive migrations (CREATE TABLE IF NOT EXISTS, ADD COLUMN), and get explicit user approval before any destructive change.

6. app/app.manifest.json declares infra — NOTHING is provisioned by default

A new website gets no D1, no R2, no KV, no Durable Object. Opt in only when the website actually needs it: - "db": true → a D1 database, bound env.DB - "r2": true → an R2 bucket, bound env.STORAGE - "kv": true → a KV namespace, bound env.KV - "durableObject": "ClassName" → a Durable Object, bound env.ROOMS - "container": true (or { "instanceType", "port", "sleepAfter" }) → a Docker container for heavy/long-running work, bound env.CONTAINER — see references/containers.md

Counts are capped (≤1 each) by the platform, which PROVISIONS the resource and binds it at deploy. The committed app/wrangler.jsonc is build/dev input only; the platform OVERWRITES its name + bindings at deploy — declare infra in app/app.manifest.json.

KV is eventually consistent (NOT Redis): config, feature flags, cached reads — NOT counters, locks, or read-after-write. Use a Durable Object for strong consistency.

For a Durable Object you must ALSO export class ClassName extends DurableObject {…} from app/src/server.ts (alongside the default { fetch } export).

For a container — heavy or long-running work a Worker can't do: set "container" in the manifest and follow references/containers.md (exact Dockerfile, the platform-fixed AppContainer class, keep-alive + 3-hour-deadline pattern, fnf via container token). Containers are off by default.

Editing map

Verify + deploy

The trusted platform CI builds the website on every deploy (always with HF_DESIGN_INSPECTOR=1 and HF_ENV="production" — the live site carries the design inspector), so a deploy already gives you the authoritative type + build result. Do NOT reflexively bun install + bun run build just to check your work. The sandbox cannot deploy/migrate (no Cloudflare token); the trusted platform CI does that.

Default: run the pipeline, pass the Phase 5 gate, deploy (higgsfield website deploy <website_id> — this ships the live site immediately). Never publish/list on the community feed unless the user explicitly asked to publish.

Publishing ("show in feed"). When the user asks to publish / share / put the site on the feed, run higgsfield website publish <website_id> — it lists the site on the Higgsfield community feed. Publishing no longer deploys: it lists whatever is already live, so run higgsfield website deploy <website_id> FIRST — and after ANY later change, deploy again to ship it (re-publishing does not re-deploy and won't pick up un-deployed changes).

HARD GATE — the cover is NOT optional. Running higgsfield website publish while og_image_url or marketplace_cover_url is empty is a BROKEN publish (the feed card renders ONLY from app/src/app-meta.json; an empty og_title makes the listing INVISIBLE, an empty cover makes it a blank card). The publish sequence is: (a) READ app/src/app-meta.json; (b) if og_image_url or marketplace_cover_url is empty → STOP, read references/app-cover.md and generate + upload the cover NOW — do not skip this because the user "only asked to publish", the cover IS part of publishing; (c) fill ALL fields below with real values (never placeholders); (d) commit + push; (e) run higgsfield website deploy <website_id> to ship the pushed changes (publish no longer deploys — it lists what's already live); (f) only then run higgsfield website publish:

  1. og_title — the card's title (also the browser tab title).
  2. og_description — the card's one-liner.
  3. og_image_url — REQUIRED: the cover image, generated per references/app-cover.md (the branded 3:2 cover + stadium-capsule OG mask) if none exists yet; upload the OG file with higgsfield upload create and set the returned durable URL.
  4. marketplace_cover_url — REQUIRED: the plain (unmasked) cover, the same generation's <name>_cover.png from references/app-cover.md, uploaded with higgsfield upload create. One generation fills both this and og_image_url — there is never a reason to have one without the other.
  5. favicon_url — the card's logo/icon (generate one if none exists yet).
  6. og_video_url — the cover video, OPTIONAL and permission-gated: OFFER it to the user ("want a short cover video for the feed card?") and ASK PERMISSION FIRST — generating a video costs credits; never generate it unprompted. If they say yes, follow "Cover video" in references/seo.md.

(1–5 are generated without asking — they are part of the publish, not a separate credit decision; only the cover VIDEO (6) needs permission.)

higgsfield website deploy <website_id> remains the way to ship the live site WITHOUT a feed listing.

Run the local checks only when you actually need them — from app/:

cd app
bun install          # only when you changed dependencies / package.json
bun run typecheck    # tsc --noEmit — only to chase a type error on deploy
bun run build        # local build — only to chase a build error on deploy

Run them when: you changed dependencies or build/runtime config, you're debugging a build/type error, or a command genuinely needs node_modules.

Small edits to an existing site (copy tweak, one component, styling fix): the pipeline does not restart. Make the edit, deploy.

Before claiming a build done / deploying, no placeholders may remain — no <...>-style tokens, lorem ipsum, or scaffold blank-page markers (REMOVE_THIS / blank-app-v1). This is covered by the mechanical gate (the grep checklist in references/review-rubric.md §A).