# Implementation Plan: Initial Website Foundation & v0 Product Site **Branch**: `213-website-foundation-v0` | **Date**: 2026-04-18 | **Spec**: `specs/213-website-foundation-v0/spec.md` **Input**: Feature specification from `specs/213-website-foundation-v0/spec.md` **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts. ## Summary - Keep `apps/website` as a fully static Astro 6 app and preserve its runtime separation from `apps/platform`. - Introduce explicit TypeScript and Tailwind CSS v4, but implement the UI layer as custom shadcn-inspired Astro primitives instead of adding React plus official shadcn/ui. - Ship a reusable public-site foundation with global layout, navigation, footer, seven core surfaces plus Privacy and Terms, SEO basics, and a lightweight browser-smoke validation path. ## Technical Context **Language/Version**: Astro 6.0.0 templates + TypeScript 5.x (explicit setup in `apps/website`) **Primary Dependencies**: Astro 6, Tailwind CSS v4, custom Astro component primitives (shadcn-inspired), lightweight Playwright browser smoke tests **Storage**: Static filesystem content, styles, and assets under `apps/website/src` and `apps/website/public`; no database **Testing**: Root build proof via `corepack pnpm build:website` plus Playwright browser smoke coverage for public routes **Validation Lanes**: fast-feedback **Target Platform**: Static public website for modern desktop/mobile browsers **Project Type**: Web (standalone Astro app in a pnpm monorepo) **Performance Goals**: Static HTML for all core routes, zero required framework hydration for reading/navigation flows, minimal client JS reserved for purposeful interactions only **Constraints**: Preserve `@tenantatlas/website`, `WEBSITE_PORT`, root workspace scripts, and `apps/*` contracts; avoid platform auth/session/API coupling; ship one polished primary theme; publish only substantiated trust and integration claims **Scale/Scope**: 7 core public surfaces plus Privacy and Terms as published legal routes, shared layout/content/conversion/trust primitives, and a future-ready structure for blog/docs/changelog without live rollout in v0 ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first / Graph contract / deterministic capabilities / RBAC-UX / Filament surface rules: N/A for this feature because all implementation stays inside `apps/website` and introduces no `/admin`, `/admin/t/{tenant}/...`, or `/system` runtime changes. - Read/write separation: Pass. The feature is a public, static product site. Contact / Demo remains a static conversion surface in v0 and does not introduce a product-app write workflow. - Workspace isolation: Pass. The website remains runtime-independent from `apps/platform`; no shared auth, session, tenant data, or implicit API dependency is introduced. - Data minimization: Pass. Only public content, styles, metadata, and assets are authored; no tenant payloads, credentials, or operational records are stored. - Test governance (TEST-GOV-001): Pass. Validation stays in `fast-feedback` with static build proof and lightweight browser smoke coverage; no DB/auth/provider fixtures or heavy-suite defaults are added. - Proportionality / no premature abstraction: Pass. The plan adopts a small Astro/Tailwind primitive set instead of React + official shadcn/ui, a CMS, or a broader front-end framework. - Persisted truth / new state: Pass. No database entities, queued work, run lifecycle, or new status families are introduced. - UI semantics / few layers: Pass. Shared layout/content/conversion/trust primitives map directly to the website narrative without a presentation meta-framework. Status: ✅ No constitution violations for this feature. The website remains public, static, repo-owned, and separate from platform runtime concerns. ## Test Governance Check > **Fill for any runtime-changing or test-affecting feature. Docs-only or template-only work may state concise `N/A` or `none`.** - **Test purpose / classification by changed surface**: Browser smoke coverage for public routes, navigation reachability, and layout stability; static build proof for artifact generation - **Affected validation lanes**: fast-feedback - **Why this lane mix is the narrowest sufficient proof**: The feature changes only a static Astro site. Build proof alone verifies output generation, while a tiny browser smoke suite is the smallest layer that can catch broken routes, broken navigation, and browser-visible regressions without introducing backend or heavy end-to-end cost. - **Narrowest proving command(s)**: `corepack pnpm build:website` and `cd apps/website && corepack pnpm exec playwright test` - **Fixture / helper / factory / seed / context cost risks**: none; public pages do not require database, auth, provider, tenant, or workspace setup - **Expensive defaults or shared helper growth introduced?**: no; any Playwright setup stays local to `apps/website` - **Heavy-family additions, promotions, or visibility changes**: none - **Closing validation and reviewer handoff**: Re-run the website build and smoke suite after page or layout changes. Reviewers should verify that core routes load, primary/footer navigation has no dead ends, the site stays mobile-usable, and no framework hydration is introduced without explicit justification. - **Budget / baseline / trend follow-up**: none beyond tracking the small runtime cost of the website smoke suite inside this feature - **Review-stop questions**: Does the proof stay in fast-feedback? Did any change introduce backend fixtures or hidden framework coupling? Is the smoke suite still small and route-focused? - **Escalation path**: document-in-feature - **Why no dedicated follow-up spec is needed**: The validation surface is tightly bounded to this feature’s public pages. A follow-up spec is only needed if the website later grows interactive workflows, broader content tooling, or cross-app coupling. ## Project Structure ### Documentation (this feature) ```text specs/213-website-foundation-v0/ ├── plan.md # This file (/speckit.plan command output) ├── research.md # Phase 0 output (/speckit.plan command) ├── data-model.md # Phase 1 output (/speckit.plan command) ├── quickstart.md # Phase 1 output (/speckit.plan command) ├── contracts/ # Phase 1 output (/speckit.plan command) └── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) ``` ### Source Code (repository root) ```text apps/website/ ├── astro.config.mjs ├── package.json ├── public/ ├── src/ │ ├── components/ │ │ ├── layout/ # Navbar, Footer, page shell wrappers │ │ ├── primitives/ # Container, Section, Button, Badge, Card, Input, Textarea │ │ ├── sections/ # PageHero, FeatureGrid, TrustGrid, CTASection, LogoStrip │ │ └── content/ # Audience rows, evidence callouts, legal prose helpers │ ├── layouts/ │ │ └── BaseLayout.astro │ ├── lib/ # Navigation, SEO, metadata, content helpers │ ├── pages/ │ │ ├── index.astro │ │ ├── product.astro │ │ ├── solutions.astro │ │ ├── security-trust.astro │ │ ├── integrations.astro │ │ ├── contact.astro │ │ ├── legal.astro │ │ ├── privacy.astro │ │ ├── sitemap.xml.ts │ │ └── terms.astro │ ├── styles/ │ │ ├── global.css │ │ └── tokens.css # Tailwind v4 theme tokens / bridge layer │ ├── content/ # Future-ready content collections for docs/blog/changelog │ └── types/ # Content and component prop types └── tests/ └── smoke/ # Lightweight Playwright browser smoke coverage ``` **Structure Decision**: Keep the website fully isolated in `apps/website`. Use Astro pages plus a small internal design-system layer (`layout`, `primitives`, `sections`, `content`) and local browser smoke tests. Prepare a future `src/content/` and helper layer for later docs/blog/changelog expansion without shipping those sections in v0. ## Complexity Tracking > **Fill when Constitution Check has violations that must be justified OR when BLOAT-001 is triggered by new persistence, abstractions, states, or semantic frameworks.** None. ## Proportionality Review > **Fill when the feature introduces a new enum/status family, DTO/presenter/envelope, persisted entity/table/artifact, interface/contract/registry/resolver, taxonomy/classification system, or cross-domain UI framework.** - **Current operator problem**: Prospects and internal teams lack a credible public site that explains the product, trust model, and contact path without depending on the platform UI or ad hoc landing-page copy. - **Existing structure is insufficient because**: The current Astro app only contains a single placeholder-style page, handwritten global CSS, and no reusable page system for navigation, legal pages, audience storytelling, or future content expansion. - **Narrowest correct implementation**: A small Astro-native design-system layer backed by Tailwind CSS v4 and explicit TypeScript, with no React requirement and no CMS or runtime platform coupling. - **Ownership cost created**: Ongoing maintenance of public copy, shared website primitives, Tailwind tokens, and a tiny local browser smoke suite. - **Alternative intentionally rejected**: React + official shadcn/ui was rejected because it adds unnecessary client framework weight and maintenance cost for a static trust-first site; a single-page copy refresh was rejected because it would not establish a reusable v0 foundation. - **Release truth**: Current-release truth ## Phase 0 — Outline & Research (complete) - Output: `specs/213-website-foundation-v0/research.md` - Key decisions captured: - Keep Astro 6 static and runtime-independent from `apps/platform`. - Add explicit TypeScript and Tailwind CSS v4 using the CSS-first Tailwind v4 model. - Use custom shadcn-inspired Astro primitives instead of React + official shadcn/ui. - Keep the Contact / Demo surface static in v0 and avoid introducing an Astro API/contact backend in this feature. - Validate with root build proof plus a small Playwright browser smoke suite. ## Phase 1 — Design & Contracts (complete) ### Data model - Output: `specs/213-website-foundation-v0/data-model.md` - No database schema changes are required; the model is file- and route-based. ### Public site contracts - Output: `specs/213-website-foundation-v0/contracts/public-site.openapi.yaml` - Contract captures the required public GET routes and their HTML response expectations. ### Quickstart - Output: `specs/213-website-foundation-v0/quickstart.md` - Quickstart covers local development, build validation, and browser smoke execution. ### Agent context update - Completed via `.specify/scripts/bash/update-agent-context.sh copilot` so the Copilot context reflects the website stack additions. ### Constitution re-check (post-design) - ✅ Runtime separation remains intact: no platform auth/session/API coupling is introduced. - ✅ No new persisted truth, state machines, or background operations are introduced. - ✅ The chosen UI layer is the narrowest correct implementation for v0 and avoids premature React/framework abstraction. - ✅ Validation remains cheap, local, and website-specific. ## Phase 2 — Implementation Plan (next) ### Story 1 (P1): Foundation and shared shell - Add explicit TypeScript setup to `apps/website` and install Tailwind CSS v4 using the CSS-first configuration model. - Introduce site metadata, navigation, footer configuration, and shared layout primitives (`Container`, `Section`, `SectionHeader`, `Button`, `Badge`, `Card`, `Input`, `Textarea`, `Navbar`, `Footer`, `PageHero`). - Preserve the existing calm, enterprise-appropriate visual direction while shifting styling from page-local CSS toward reusable tokens and utilities. - Tests / validation: - Confirm the site still builds via `corepack pnpm build:website`. - Add browser smoke coverage for Home plus one interior route. ### Story 2 (P1/P2): Core page shells and narrative system - Build Home, Product, Solutions, Security & Trust, Integrations, Contact, Legal, Privacy, and Terms using shared `sections/` components (`FeatureGrid`, `TrustGrid`, `CTASection`, `LogoStrip`, audience-specific rows, evidence callouts). - Ensure each core page exposes page purpose, clear hierarchy, semantic metadata, and visible next-step CTA. - Keep Solutions separate from Product capabilities and keep Security & Trust limited to substantiated claims. - Tests / validation: - Extend browser smoke coverage to all published core routes. - Assert primary and footer navigation reachability. ### Story 3 (P3): Delivery hardening and future-ready structure - Add SEO and discovery basics (page titles, descriptions, Open Graph baseline, robots, explicit sitemap output, canonical metadata). - Add a future-ready content helper layer and route organization for later docs/blog/changelog expansion without publishing those sections in v0. - Ensure the Legal surface carries any required jurisdiction-specific public legal notice through the Legal hub or a linked dedicated notice page before launch. - Keep contact handling static and repo-owned in this feature; document any later external form or scheduling integration as a follow-up decision rather than coupling it into the website foundation. - Tests / validation: - Finish Playwright smoke checks for mobile navigation, CTA reachability, and absence of dead-end routes. - Re-verify root workspace scripts and package contracts remain intact.