@@ -53,7 +58,10 @@ export function TrustSplit({
{trustSplit.snippetFile}
-
+
diff --git a/components/landing/types.ts b/components/landing/types.ts
index e786abf0..3f51136e 100644
--- a/components/landing/types.ts
+++ b/components/landing/types.ts
@@ -5,6 +5,14 @@ import type { LucideIcon } from "lucide-react";
waitlist/Resend mechanism but has no LandingContent page of its own. */
export type ProductSlug = "stargate" | "code-analysis" | "readiness";
+export interface LandingCta {
+ label: string;
+ href: string;
+ variant?: "primary" | "secondary" | "ghost";
+ arrow?: "right";
+ external?: boolean;
+}
+
export interface LandingContent {
product: ProductSlug;
wordmarkName: string;
@@ -14,6 +22,8 @@ export interface LandingContent {
titleTop: ReactNode;
titleGradient: ReactNode;
lead: ReactNode;
+ primaryCta?: LandingCta;
+ secondaryCta?: LandingCta;
};
/** Per-product hero visual rendered below the CTA row. */
HeroWindow: ComponentType;
@@ -30,24 +40,35 @@ export interface LandingContent {
OutputsBento: ComponentType;
/** Optional per-product feature-spotlight sections, rendered after OutputsBento. */
Spotlights?: ComponentType;
- marquee: { rowA: string[]; rowB: string[] };
+ marquee: { rowA: string[]; rowB: string[]; cta?: LandingCta };
trustSplit: {
eyebrow: string;
title: ReactNode;
lead?: ReactNode;
bullets: string[];
ctaLabel: string;
+ cta?: LandingCta;
snippet: string;
snippetFile: string;
+ snippetLang?: "bash" | "json" | "typescript";
};
faq: { q: string; a: ReactNode }[];
closingCta: {
title: string;
lead: string;
finePrint: string;
+ anchor?: string;
+ action?:
+ | { kind: "waitlist"; product: ProductSlug }
+ | { kind: "links"; links: LandingCta[] };
/** Defaults to true; set false for product-first pages without a parent-brand badge. */
showConceptaBrand?: boolean;
};
/** Optional visual rendered inside the closing CTA card, below the waitlist form. */
ClosingVisual?: ComponentType;
}
+
+export type LandingHeroContent = Pick<
+ LandingContent,
+ "wordmarkName" | "wordmarkShowByline" | "hero" | "HeroWindow"
+>;
diff --git a/docs/superpowers/plans/2026-07-17-rockets-landing-polish.md b/docs/superpowers/plans/2026-07-17-rockets-landing-polish.md
new file mode 100644
index 00000000..63873658
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-17-rockets-landing-polish.md
@@ -0,0 +1,97 @@
+# Plan: Rockets Standalone Landing Page Polish
+
+> Replace the overlong ecosystem narrative with a proof-first standalone Rockets page centered on the `createServer(...)` launch API.
+
+## Objective
+
+- Primary outcome: `/rockets` explains and demonstrates Rockets as a standalone backend product through one realistic `createServer(...)` definition.
+- Constraints: no `NestJS`, `Stargate`, or `defineRockets(...)` in Rockets page content or metadata; do not change behavior on other product pages.
+- Out of scope: implementing `createServer(...)` in the Rockets package repository, redesigning shared navigation/footer, or adding hosted-service flows.
+
+## Context
+
+- `components/landing/LandingRoot.tsx` currently renders every generic landing section in a fixed order, which forces Rockets through stats, statement, features, bento, spotlights, marquee, trust, FAQ, and closing CTA.
+- `components/landing/rockets/content.tsx` repeats the product thesis across all of those sections and includes the framework and ecosystem terms now excluded from the page.
+- `components/landing/rockets/snippets.ts` currently presents the invented `defineRockets(...)` facade; the approved launch-facing name is `createServer(...)` with the same options object as the existing alpha root registration.
+- `components/landing/rockets/HeroWindow.tsx` already provides accessible Server/Auth/Storage-style tab mechanics and a useful two-column code/output window.
+- `components/landing/sections/Hero.tsx`, `Faq.tsx`, `ClosingCta.tsx`, and `Aurora.tsx` are reusable primitives; only `Hero` is unnecessarily typed to the full `LandingContent` object.
+- `site-tests/rockets-integration.test.mjs` is the existing content and shell contract for the route.
+- Browser baseline: 9,782 px document height at 1440 × 900 and 14,192 px at 390 × 844, with no horizontal overflow.
+
+## Approach
+
+Give `RocketsLanding.tsx` a product-specific section composition while retaining the shared visual primitives and `.lp-root` shell. Narrow the `Hero` prop contract to only the fields it actually reads. Replace the generic grids and marquee with three Rockets-specific sections: server surface, compact provider model, and ownership boundary.
+
+- Alternative considered: make every `LandingContent` section optional in `LandingRoot` — rejected because it weakens the shared contract and spreads conditional rendering through unrelated product pages.
+- Alternative considered: keep the current bento and only rewrite copy — rejected because the bento, stats, and marquee are the main sources of repetition and page length.
+
+## Compatibility
+
+- Breaking change: no public package or application API change. The only shared type refinement is narrowing `Hero` to the subset it already consumes.
+- Migration: hard cut for `/rockets`; other product compositions remain on `LandingRoot` unchanged.
+- Data migration: none.
+- Rollback: revert the implementation commit; the existing Rockets page remains available in git history.
+
+## Work Breakdown
+
+1. Establish failing content contracts — `site-tests/rockets-integration.test.mjs`
+ - Require `createServer(` and the new standalone section names.
+ - Forbid `defineRockets(`, `NestJS`, and `Stargate` across Rockets content, snippets, custom components, and route metadata.
+ - Replace assertions tied to `OutputsBento` and the old vision/provider copy.
+ - Verification: `node --test site-tests/rockets-integration.test.mjs` fails for the expected missing/new content assertions.
+
+2. Replace the hero facade and launch sequence — `components/landing/rockets/snippets.ts`, `components/landing/rockets/HeroWindow.tsx`
+ - Rename the first tab to Server and make `createServer(...)` its default code example.
+ - Keep the authentication and storage examples grounded in current repository contracts.
+ - Map root configuration keys to concrete outcomes in the right-hand panel.
+ - Preserve semantic tabs, visible focus, reduced motion, and mobile-safe code presentation.
+ - Verification: the focused integration test passes its API-name and hero assertions.
+
+3. Build the concise product composition — `components/landing/rockets/RocketsLanding.tsx`, `components/landing/rockets/content.tsx`, `components/landing/rockets/ServerSurface.tsx`, `components/landing/rockets/ProviderSpotlights.tsx`, `components/landing/rockets/OwnershipBoundary.tsx`, `components/landing/sections/Hero.tsx`, `components/landing/types.ts`
+ - Define a Rockets content object containing only hero, FAQ, closing CTA, and copy used by the product-specific sections.
+ - Compose Aurora, Hero, ServerSurface, ProviderSpotlights, OwnershipBoundary, Faq, and ClosingCta under the existing MotionConfig and `.lp-root` shell.
+ - Narrow the shared Hero prop type to its actual content subset without changing runtime behavior for other pages.
+ - Merge identity and storage demonstrations into one compact provider section.
+ - Add a concrete Rockets-versus-team responsibility comparison.
+ - Remove `components/landing/rockets/OutputsBento.tsx` after its unique information is represented in ServerSurface.
+ - Verification: the focused integration test passes; `git diff` shows no behavioral edits to other product content.
+
+4. Tighten Rockets-specific styling — `components/landing/landing.css`
+ - Reuse the existing Night/Panel/Lift/Launch/Flame palette and Inter/JetBrains Mono roles.
+ - Add narrowly scoped layout styles for server surface and ownership boundary.
+ - Simplify obsolete Rockets vision/bento selectors and remove dead selectors associated only with deleted components.
+ - Ensure 44 px mobile tab targets, visible focus, reduced-motion behavior, and no document-level horizontal overflow.
+ - Verification: `git diff --check`; browser inspection at 1440 × 900 and 390 × 844.
+
+5. Align metadata, FAQ, and final content contracts — `src/app/rockets/page.tsx`, `components/landing/rockets/content.tsx`, `site-tests/rockets-integration.test.mjs`
+ - Remove implementation-framework naming from route metadata and all user-visible copy.
+ - Limit FAQ to six approved questions and distinguish launch facade from alpha behavior without introducing a competing facade name.
+ - Keep repository and guide CTAs external and standalone.
+ - Verification: `rg -n "NestJS|Stargate|\\bdefineRockets\\s*\\(" components/landing/rockets src/app/rockets` returns no matches; focused test passes.
+
+6. Verify, review, and publish
+ - Run `pnpm test:site`.
+ - Run `pnpm build`.
+ - Browser-test `/rockets` at desktop and mobile, exercise Server/Auth/Storage by pointer and keyboard, inspect console errors, confirm no horizontal overflow, and record document height.
+ - Review `git diff origin/main...HEAD` for unrelated files or regressions.
+ - Commit the implementation, push the current branch, open a PR against `main`, wait for required checks, and merge only when the PR diff and checks are clean.
+
+## Test Strategy
+
+- Integration contract: `site-tests/rockets-integration.test.mjs` validates the route, shell, API naming, standalone positioning, section composition, and forbidden terminology.
+- Full site regression: `pnpm test:site` confirms shared product pages remain wired.
+- Production compile: `pnpm build` catches TypeScript, Next.js, and static-rendering regressions.
+- Browser: desktop/mobile responsive layout, tab interaction, focus behavior, overflow, console, reduced motion, and page-height targets.
+
+## Risks and Stop Conditions
+
+- Risk: the launch page can drift from the package API — mitigation: use only fields present in the current root options contract and avoid claiming that the facade is already published.
+- Risk: shared CSS cleanup can affect other product pages — mitigation: remove only selectors proven Rockets-specific and inspect shared-page test/build results.
+- Risk: Chrome extensions can create hydration noise — mitigation: distinguish extension-owned errors from application-owned errors and corroborate with a production build.
+- Stop before merge if required checks fail, the PR includes unrelated files, other product-page behavior changes, mobile overflow appears, or the launch facade conflicts with current product direction.
+
+## Rollout
+
+- Feature flag: none; `/rockets` is already an isolated route on the feature branch.
+- Deployment: normal merge to `main` after PR checks.
+- Rollback: revert the implementation commit or PR merge.
diff --git a/docs/superpowers/specs/2026-07-17-rockets-landing-polish-design.md b/docs/superpowers/specs/2026-07-17-rockets-landing-polish-design.md
new file mode 100644
index 00000000..4bc815a3
--- /dev/null
+++ b/docs/superpowers/specs/2026-07-17-rockets-landing-polish-design.md
@@ -0,0 +1,289 @@
+# Rockets Standalone Landing Page Polish
+
+**Date:** 2026-07-17
+**Status:** Approved direction, implementation pending
+**Page:** `/rockets`
+
+## 1. Product Decision
+
+The Rockets landing page must present Rockets as a complete standalone product. The broader Concepta and Stargate strategy informs the page's focus—show one concrete capability before explaining a platform—but neither Stargate nor NestJS appears in the page copy.
+
+The page's single job is to convince a backend or platform engineer that one typed `createServer(...)` definition can establish the repeatable foundation of a production backend while leaving domain behavior under the team's control.
+
+### Core promise
+
+> Describe the backend once. Rockets makes it run.
+
+### Launch API
+
+The primary public API shown throughout the page is:
+
+```ts
+export const billing = createServer({
+ auth: sharedIdentity,
+ repository: postgres,
+ resources: [customers, invoices, ledger],
+ accessControl: billingPolicy,
+});
+```
+
+`createServer(...)` is the launch-facing facade for the same options object currently assembled through the alpha module-registration API. The facade changes the entry-point name, not the configuration contract. The landing page does not introduce a second aspirational name such as `defineRockets(...)`.
+
+### Explicit exclusions
+
+- Do not mention Stargate.
+- Do not mention NestJS.
+- Do not present Rockets as dependent on a hosted control plane.
+- Do not describe a language-neutral or serialized backend artifact as a current capability.
+- Do not imply that Rockets writes the product's domain logic.
+- Do not show `defineRockets(...)`.
+
+## 2. Audience and Success Criteria
+
+### Primary audience
+
+Backend and platform engineers evaluating whether Rockets can remove repeated server infrastructure without hiding or owning their domain logic.
+
+### User story
+
+As an engineer evaluating Rockets, I want to see one realistic server definition and the concrete runtime surface it creates so that I can understand the product before reading its documentation.
+
+### Acceptance criteria
+
+- The hero communicates the product promise and shows `createServer(...)` before any conceptual product explanation.
+- The default hero visual maps configuration fields to concrete server outcomes.
+- The rendered Rockets page contains neither `NestJS` nor `Stargate`, including metadata and FAQ copy.
+- The rendered page contains `createServer(` and does not contain `defineRockets(`.
+- The page has no more than six major narrative sections after the shared navigation.
+- Mobile document height at 390 × 844 is at least 25% shorter than the current 14,192 px baseline.
+- Desktop document height at 1440 × 900 is at least 20% shorter than the current 9,782 px baseline.
+- The page has no horizontal overflow at 390 px width.
+- Tabs, links, and FAQ controls remain keyboard accessible with visible focus states.
+- Motion respects `prefers-reduced-motion` through the existing `MotionConfig` behavior.
+- Existing site tests, TypeScript checks, and the production build pass.
+
+## 3. Recommended Narrative
+
+The page uses a proof-first narrative. It shows the server definition, demonstrates the resulting surface, explains provider boundaries, and then states what remains the team's responsibility.
+
+### Section 1 — Hero: the thesis and proof
+
+**Headline:** Keep the existing thesis, “Your backend should be a spec. Rockets makes it run.”
+
+**Lead:** Replace framework and ecosystem language with a direct product explanation:
+
+> Describe your domain—resources, identity, storage, access, and APIs. Rockets turns that definition into a secure, documented server with the repeatable foundation already wired.
+
+**Primary CTA:** Explore on GitHub.
+**Secondary CTA:** See `createServer`.
+
+The hero window defaults to a complete `createServer(...)` example. It retains the useful authentication and storage tabs, but the first tab is named **Server**, not **Spec**, and it is visually dominant.
+
+### Section 2 — One call, a complete server
+
+Show the direct mapping between the definition and the resulting surface:
+
+- `resources` → routes, validation, relationships, and OpenAPI
+- `auth` → one authenticated-user contract and protected endpoints
+- `repository` → default persistence with per-resource overrides
+- `accessControl` → ownership and policy enforcement
+- hooks and providers → extension points for domain behavior
+
+This replaces the current stats strip, statement, feature grid, and output bento, which repeat the same idea at different levels of abstraction.
+
+### Section 3 — Providers stay replaceable
+
+Use one compact split section with two provider cards:
+
+- **Identity:** Firebase, API keys, built-in identity, or a custom adapter resolve the same user contract.
+- **Storage:** choose a default repository and override the exception without changing domain services.
+
+The section demonstrates both configuration fragments without becoming a package inventory.
+
+### Section 4 — Rockets builds the foundation; you build the product
+
+Draw a clear product boundary.
+
+**Rockets owns:** registration, authentication plumbing, persistence routing, resource controllers, validation, access-policy wiring, hooks, and API documentation.
+
+**Your team owns:** domain rules, schemas, services, integrations, workflows, events, and operational choices.
+
+This replaces the current repeated “definition is the product” and “framework stops at the boundary” explanations with one concrete comparison.
+
+### Section 5 — Focused FAQ
+
+Keep six questions at most:
+
+1. What is Rockets?
+2. What does `createServer(...)` create?
+3. Does Rockets generate source code?
+4. Can identity and storage providers be replaced?
+5. What application code do I still write?
+6. Is Rockets stable?
+
+Answers must use product language, avoid implementation-framework naming, and distinguish launch direction from currently published alpha behavior where necessary.
+
+### Section 6 — Closing action
+
+**Title:** Define the backend. Launch the server.
+**Lead:** Start with one domain definition, inspect the generated surface, and keep extending it with ordinary application code.
+**Actions:** View the repository and read the guide.
+
+Remove the ecosystem marquee. It adds length and package vocabulary without helping the visitor understand the central product action.
+
+## 4. Visual Design
+
+### Design direction
+
+Preserve the current dark Rockets identity and refine it around a single signature interaction. The page should feel like a launch console whose input is a server definition and whose output is a live, inspectable backend surface.
+
+### Token system
+
+- **Night:** `#05040A` — page background
+- **Panel:** `#0D0B14` — code and content surfaces
+- **Lift:** `#161421` — elevated and selected surfaces
+- **Launch:** `#FF5906` — primary action and active state
+- **Flame:** `#FFAD7A` — secondary gradient and warm output highlight
+- **Signal:** `#FFFFFF` — primary text; use opacity for muted copy
+
+### Typography
+
+- **Display and reading:** Inter, using tight tracking and strong weight contrast for the hero and section titles.
+- **Utility and code:** JetBrains Mono for the wordmark, labels, configuration keys, file names, and runtime outputs.
+- Use the mono face only where the content is genuinely technical. Do not turn ordinary prose into terminal decoration.
+
+### Layout
+
+Desktop:
+
+```text
+┌──────────────────────────────────────────────────────────┐
+│ HERO THESIS + ACTIONS │
+│ ┌──────────────────────┬─────────────────────────────┐ │
+│ │ createServer(config) │ configuration → outcomes │ │
+│ └──────────────────────┴─────────────────────────────┘ │
+├──────────────────────────────────────────────────────────┤
+│ ONE CALL, A COMPLETE SERVER │
+│ resources auth storage policy API │
+├───────────────────────────┬──────────────────────────────┤
+│ IDENTITY PROVIDERS │ STORAGE PROVIDERS │
+├───────────────────────────┴──────────────────────────────┤
+│ ROCKETS BUILDS YOUR TEAM BUILDS │
+├──────────────────────────────────────────────────────────┤
+│ FAQ │
+├──────────────────────────────────────────────────────────┤
+│ CLOSING ACTION │
+└──────────────────────────────────────────────────────────┘
+```
+
+Mobile:
+
+```text
+HERO
+createServer code
+outcome sequence
+configuration outcomes
+identity providers
+storage providers
+Rockets / your team boundary
+FAQ
+closing action
+```
+
+Mobile sections stack in narrative order. Code may scroll inside its own panel only when it cannot wrap safely; the document itself must never overflow horizontally.
+
+### Signature interaction
+
+The memorable element is the **launch sequence** inside the hero window. Configuration keys on the left map to a restrained output checklist on the right. When the Server, Auth, or Storage tab changes, one coordinated transition updates both sides. The active `createServer` call and its resulting surface are the visual thesis of the page.
+
+Spend motion here and keep downstream animation quiet. Section reveals may remain subtle, but cards should not animate independently without communicating state.
+
+### Uniqueness review
+
+The current page relies on common landing-page devices: a numerical stats strip, a large philosophical statement, a generic feature grid, a bento grid, and a scrolling package marquee. Those devices are polished but not specific to Rockets.
+
+The revised design removes those generic structures. Its primary visual relationship—configuration keys becoming server capabilities—can only belong to this product. Orange remains a launch signal rather than decorative glow, and structural labels describe real configuration or runtime concepts.
+
+## 5. Component Architecture
+
+Rockets should no longer be forced through every section of the generic `LandingRoot` template. Preserve shared primitives but give the product a concise composition.
+
+### Recommended composition
+
+`RocketsLanding.tsx` becomes the page-level composition and renders:
+
+1. shared `Aurora`
+2. shared `Hero` with the Rockets `HeroWindow`
+3. new `ServerSurface`
+4. revised `ProviderSpotlights`
+5. new `OwnershipBoundary`
+6. shared `Faq`
+7. shared `ClosingCta`
+
+Keep `MotionConfig reducedMotion="user"` and the existing `.lp-root` shell. Do not make unrelated product fields optional merely to accommodate Rockets; a product-specific composition is clearer and avoids regressions to Stargate and Code Analysis pages.
+
+### File responsibilities
+
+- `RocketsLanding.tsx` — section order and page shell only
+- `content.tsx` — user-facing copy, links, FAQ, and CTA data
+- `snippets.ts` — `createServer`, authentication, and storage examples
+- `HeroWindow.tsx` — tabs plus configuration-to-output launch sequence
+- `ServerSurface.tsx` — compact configuration-to-capability mapping
+- `ProviderSpotlights.tsx` — combined identity and storage provider section
+- `OwnershipBoundary.tsx` — Rockets-versus-team responsibility comparison
+- `landing.css` — shared primitives plus narrowly scoped Rockets selectors
+- `rockets-integration.test.mjs` — positive and negative content contracts
+
+`OutputsBento.tsx` is removed once `ServerSurface.tsx` covers its unique information. Avoid leaving dead Rockets-specific selectors in `landing.css` after the component removal.
+
+## 6. Content and API Integrity
+
+The page may preview the `createServer(...)` launch facade, but it must not claim capabilities absent from the current planner and package contracts.
+
+Every output shown in the launch sequence must map to repository-backed behavior:
+
+- authentication adapter chain and authenticated-user contract
+- repository abstraction and per-entity override
+- declarative resources and generated CRUD surface
+- access-control integration
+- hooks and custom providers
+- OpenAPI registration
+
+Copy must not claim that Rockets generates business logic, provisions infrastructure, or serializes a language-neutral specification.
+
+## 7. Responsive, Accessibility, and Failure States
+
+- Preserve semantic tabs with `role="tablist"`, `role="tab"`, and `aria-selected`.
+- Add arrow-key tab navigation if it is absent during implementation.
+- Decorative output panels remain hidden from assistive technology only when equivalent explanatory text is present.
+- Interactive code tabs must retain visible focus and at least a 44 px touch target on mobile.
+- Honor reduced motion by replacing cross-fades and transforms with immediate state changes.
+- External links retain `rel="noopener noreferrer"`.
+- The page has no form or remote data dependency; its primary failure risk is inaccurate or contradictory API copy. Tests enforce required and forbidden terminology.
+
+## 8. Verification Plan
+
+### Automated
+
+- Extend `site-tests/rockets-integration.test.mjs` to require `createServer` and forbid `defineRockets`, `NestJS`, and `Stargate` in Rockets page files and metadata.
+- Verify the expected standalone sections and GitHub calls to action.
+- Run `pnpm test:site`.
+- Run the repository TypeScript check or production build used by this app.
+
+### Browser
+
+- Verify `/rockets` at 1440 × 900 and 390 × 844.
+- Exercise Server, Auth, and Storage tabs with pointer and keyboard input.
+- Confirm no horizontal overflow and measure document-height reduction against the recorded baselines.
+- Inspect the browser console for application-owned errors.
+- Confirm reduced-motion behavior.
+- Capture hero and full-page screenshots for the final design critique.
+
+## 9. Non-Goals
+
+- Implementing `createServer(...)` in the Rockets package repository
+- Rewriting the shared navigation or footer
+- Redesigning other Concepta product landing pages
+- Adding pricing, hosted services, a waitlist, or an account flow
+- Adding Stargate or broader ecosystem positioning
+- Changing the Rockets brand palette
diff --git a/globals.css b/globals.css
index 70a4e03d..8a267a90 100644
--- a/globals.css
+++ b/globals.css
@@ -110,6 +110,17 @@ html.dark[data-product="naked-ui"] {
--mix-accent-glow: rgba(96, 165, 250, 0.2);
}
+/* Rockets product: official launch-orange palette. */
+html.dark[data-product="rockets"] {
+ --nextra-primary-hue: 20deg;
+ --nextra-primary-saturation: 100%;
+ --nextra-primary-lightness: 51%;
+
+ --mix-accent: #FF5906;
+ --mix-accent-low: rgba(255, 89, 6, 0.1);
+ --mix-accent-glow: rgba(255, 89, 6, 0.2);
+}
+
/* Ack product: blue/cyan validation palette */
html.dark[data-product="ack"] {
--nextra-primary-hue: 228deg;
diff --git a/public/assets/logo_rockets_mark.svg b/public/assets/logo_rockets_mark.svg
new file mode 100644
index 00000000..eb2d9bf6
--- /dev/null
+++ b/public/assets/logo_rockets_mark.svg
@@ -0,0 +1 @@
+
diff --git a/site-tests/naked-ui-integration.test.mjs b/site-tests/naked-ui-integration.test.mjs
index 4eae0edc..df9d63e4 100644
--- a/site-tests/naked-ui-integration.test.mjs
+++ b/site-tests/naked-ui-integration.test.mjs
@@ -22,7 +22,7 @@ test('wires Naked UI into the shared product shell', () => {
assert.match(route, //)
assert.match(route, /Naked UI — Headless Flutter components/)
assert.match(layout, /p==='\/naked-ui'/)
- assert.match(layout, /Mix, Remix, Naked UI, Ack, FVM, Stargate, and Code Analysis/)
+ assert.match(layout, /Mix, Remix, Naked UI, Ack, FVM, Rockets, Stargate, and Code Analysis/)
assert.match(navbar, /id: 'naked-ui'/)
assert.match(navbar, /https:\/\/docs\.page\/btwld\/naked_ui/)
assert.match(navbar, /NAKED_UI_GITHUB_URL/)
diff --git a/site-tests/rockets-integration.test.mjs b/site-tests/rockets-integration.test.mjs
new file mode 100644
index 00000000..c161ff99
--- /dev/null
+++ b/site-tests/rockets-integration.test.mjs
@@ -0,0 +1,114 @@
+import assert from 'node:assert/strict'
+import fs from 'node:fs'
+import path from 'node:path'
+import test from 'node:test'
+
+const root = process.cwd()
+
+function read(relativePath) {
+ return fs.readFileSync(path.join(root, relativePath), 'utf8')
+}
+
+test('wires Rockets into the shared product shell', () => {
+ const route = read('src/app/rockets/page.tsx')
+ const layout = read('src/app/layout.jsx')
+ const navbar = read('components/FloatingNavbar.tsx')
+ const constants = read('components/constants.ts')
+ const footer = read('components/ProductFooter.tsx')
+ const pageMap = read('src/content/_meta.js')
+ const conceptaHome = read('components/ConceptaHome.tsx')
+ const globals = read('globals.css')
+ const landingStyles = read('components/landing/landing.css')
+
+ assert.match(route, //)
+ assert.match(route, /Rockets — Your backend should be a spec\./)
+ assert.match(layout, /p==='\/rockets'/)
+ assert.match(layout, /FVM, Rockets, Stargate/)
+ assert.match(navbar, /id: 'rockets'/)
+ assert.match(navbar, /ROCKETS_GITHUB_URL/)
+ assert.match(constants, /ROCKETS_GITHUB_URL = 'https:\/\/github\.com\/btwld\/rockets'/)
+ assert.match(footer, /isRocketsPath/)
+ assert.match(pageMap, /rockets:/)
+ assert.match(conceptaHome, /name: "Rockets"/)
+ assert.match(conceptaHome, /href: "\/rockets"/)
+ assert.match(conceptaHome, /createServer/)
+ assert.doesNotMatch(conceptaHome, /NestJS|Nest API/)
+ assert.match(globals, /data-product="rockets"/)
+ assert.match(landingStyles, /data-product='rockets'/)
+ assert.match(landingStyles, /\.lp-rockets-root \.lp-seg/)
+ assert.match(landingStyles, /min-height: 44px/)
+ assert.equal(
+ fs.existsSync(path.join(root, 'public/assets/logo_rockets_mark.svg')),
+ true,
+ )
+})
+
+test('presents Rockets as a standalone createServer product', () => {
+ const route = read('src/app/rockets/page.tsx')
+ const landing = read('components/landing/rockets/RocketsLanding.tsx')
+ const content = read('components/landing/rockets/content.tsx')
+ const hero = read('components/landing/rockets/HeroWindow.tsx')
+ const providers = read('components/landing/rockets/ProviderSpotlights.tsx')
+ const snippets = read('components/landing/rockets/snippets.ts')
+
+ assert.match(content, /Your backend should be a spec/)
+ assert.match(content, /wordmarkShowByline: false/)
+ assert.match(content, /Describe your domain/)
+ assert.match(content, /What does createServer\(\) create\?/)
+ assert.match(content, /pre-1\.0/)
+ assert.match(landing, //)
+ assert.match(landing, //)
+ assert.match(landing, //)
+ assert.doesNotMatch(landing, /LandingRoot/)
+ assert.match(hero, /role="tablist"/)
+ assert.match(hero, /role="tab"/)
+ assert.match(hero, /aria-selected=/)
+ assert.match(hero, /name: "Server"/)
+ assert.match(hero, /name: "Auth"/)
+ assert.match(hero, /name: "Storage"/)
+ assert.match(hero, /onKeyDown=/)
+ assert.match(hero, /ArrowRight/)
+ assert.match(hero, /ArrowLeft/)
+ assert.equal(
+ fs.existsSync(path.join(root, 'components/landing/rockets/ServerSurface.tsx')),
+ true,
+ )
+ assert.equal(
+ fs.existsSync(path.join(root, 'components/landing/rockets/OwnershipBoundary.tsx')),
+ true,
+ )
+ const surface = read('components/landing/rockets/ServerSurface.tsx')
+ const boundary = read('components/landing/rockets/OwnershipBoundary.tsx')
+ const rocketsPageSource = [
+ route,
+ landing,
+ content,
+ hero,
+ providers,
+ snippets,
+ surface,
+ boundary,
+ ].join('\n')
+ assert.match(surface, /One call\. A complete server\./)
+ assert.match(surface, /resources/)
+ assert.match(surface, /accessControl/)
+ assert.match(providers, /Identity and storage/)
+ assert.match(providers, /unmatched → try next · invalid match → stop/)
+ assert.match(providers, /one RepositoryInterface/)
+ assert.match(boundary, /Rockets builds the foundation/)
+ assert.match(boundary, /Your team builds the product/)
+ assert.match(snippets, /createServer/)
+ assert.match(snippets, /defineFirebaseAuth/)
+ assert.match(snippets, /defineFirestoreRepository/)
+ assert.doesNotMatch(rocketsPageSource, /\bdefineRockets\s*\(/)
+ assert.doesNotMatch(rocketsPageSource, /NestJS/)
+ assert.doesNotMatch(rocketsPageSource, /Stargate/)
+})
+
+test('keeps the open-source calls to action out of the waitlist flow', () => {
+ const content = read('components/landing/rockets/content.tsx')
+
+ assert.match(content, /kind: "links"/)
+ assert.match(content, /https:\/\/github\.com\/btwld\/rockets/)
+ assert.doesNotMatch(content, /kind: "waitlist"/)
+})
diff --git a/src/app/layout.jsx b/src/app/layout.jsx
index 8a53b77c..ae932bbe 100644
--- a/src/app/layout.jsx
+++ b/src/app/layout.jsx
@@ -20,7 +20,7 @@ const jetbrainsMono = JetBrains_Mono({
})
const description =
- 'Concepta ships the systems your business runs on — and builds the open-source delivery foundation behind them: Mix, Remix, Naked UI, Ack, FVM, Stargate, and Code Analysis.'
+ 'Concepta ships the systems your business runs on — and builds the open-source delivery foundation behind them: Mix, Remix, Naked UI, Ack, FVM, Rockets, Stargate, and Code Analysis.'
export const viewport = {
themeColor: '#111111',
@@ -72,7 +72,7 @@ export default async function RootLayout({ children }) {