# Implementation Plan: Website Information Architecture / Core Pages

**Branch**: `215-website-core-pages` | **Date**: 2026-04-19 | **Spec**: `specs/215-website-core-pages/spec.md`
**Input**: Feature specification from `specs/215-website-core-pages/spec.md`

**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.

## Summary

- Keep `apps/website` fully local to the website track and preserve `@tenantatlas/website`, `WEBSITE_PORT`, and the root `dev:website` / `build:website` workflows.
- Re-anchor the public-site IA in the existing Astro route and metadata layer (`src/lib/site.ts`, `src/types/site.ts`, `src/content/pages`, and published Astro pages) instead of introducing a CMS, router framework, or any `apps/platform` coupling.
- Canonicalize the initial public core around Home, Product, Trust, Changelog, Contact, Privacy, and Imprint; keep one primary conversion path; standardize optional content discoverability on `Resources`; leave the editorial `articles` collection unpublished; and keep Pricing/Docs/Solutions-hub style expansion deferred.
- Reconcile the current v0 topology with compatibility-safe changes by introducing `/trust`, `/changelog`, and `/imprint`, shrinking primary navigation to the Spec 215 core, and extending smoke coverage for the new IA contract.

## Technical Context

**Language/Version**: Astro 6.0.0 templates + TypeScript 5.9 strict  
**Primary Dependencies**: Astro 6, Tailwind CSS v4 via `@tailwindcss/vite`, Astro content collections, local Astro layout/primitive/content helpers, Playwright smoke tests  
**Storage**: Static filesystem pages, content modules, and Astro content collections under `apps/website/src` and `apps/website/public`; no database  
**Testing**: Root build proof via `corepack pnpm build:website` plus Playwright smoke coverage in `apps/website/tests/smoke`  
**Validation Lanes**: fast-feedback
**Target Platform**: Static public website for modern desktop and mobile browsers  
**Project Type**: Web (standalone Astro app inside the monorepo)  
**Performance Goals**: Preserve static HTML output for canonical public routes, keep browsing flows zero-hydration by default, and avoid introducing JS-heavy navigation or runtime platform coupling  
**Constraints**: Preserve `@tenantatlas/website`, `WEBSITE_PORT`, and Astro static output mode; keep all IA changes local to `apps/website`; do not publish placeholder routes; keep one clear primary conversion path; keep Trust top-level visible; avoid premature promotion of `Resources`, later editorial surfaces, Docs, or Pricing  
**Scale/Scope**: Current public site ships 9 routes, 3 future content collections (`articles` as unpublished editorial inventory, `changelog`, `resources`), one route-definition source in `src/lib/site.ts`, and a small Playwright smoke suite that must expand to cover the Spec 215 IA contract

## UI / Surface Guardrail Plan

- **Guardrail scope**: no operator-facing surface change
- **Native vs custom classification summary**: N/A - public Astro website only
- **Shared-family relevance**: none
- **State layers in scope**: none
- **Handling modes by drift class or surface**: N/A
- **Repository-signal treatment**: report-only
- **Special surface test profiles**: N/A
- **Required tests or manual smoke**: manual-smoke plus browser smoke for public routes
- **Exception path and spread control**: none
- **Active feature PR close-out entry**: Smoke Coverage

## 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 work stays inside `apps/website` and introduces no `/admin`, `/admin/t/{tenant}/...`, or `/system` runtime behavior.
- Read/write separation: Pass. The feature changes public route structure, navigation, and content discoverability only; Contact remains a public conversion surface, not a website-side backend workflow.
- Workspace isolation: Pass. The website remains runtime-independent from `apps/platform`, and the plan preserves the explicit website working contract.
- Data minimization: Pass. The feature only reorganizes public pages, content sources, and navigation metadata; it introduces no tenant data, secrets, auth state, or operational records.
- Test governance (TEST-GOV-001): Pass. Validation stays in `fast-feedback` with build proof plus the local Playwright smoke suite, with no database, auth, provider, or heavy-suite defaults.
- Proportionality / no premature abstraction: Pass. The plan reuses the existing `site.ts`, `types/site.ts`, Astro page routes, and content collections instead of introducing a CMS, server route layer, or generic routing framework.
- Persisted truth / new state: Pass. No database schema, queued work, new domain state family, or persisted artifact is introduced.
- UI semantics / few layers: Pass. The added semantics stay limited to website-local route roles, navigation groups, publication rules, and journey flow rather than becoming a cross-app framework.
- Website working contract: Pass. The plan keeps all implementation local to `apps/website` and preserves `@tenantatlas/website`, `WEBSITE_PORT`, and root workflow compatibility.

Status: ✅ No constitution violations for this feature. The plan remains website-only, static-first, and scoped to the existing Astro website track.

## 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 required public routes, navigation/footer topology, compatibility routing, and optional-surface suppression plus static build proof
- **Affected validation lanes**: fast-feedback
- **Why this lane mix is the narrowest sufficient proof**: The feature changes the runtime route topology and public-shell behavior of a static Astro site. Build proof catches route and artifact generation regressions; focused Playwright smoke coverage is the smallest realistic browser-level proof for link reachability, canonical paths, and the absence of placeholder navigation without adding 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 website pages require no database, auth, tenant, or provider setup
- **Expensive defaults or shared helper growth introduced?**: no; any smoke-helper changes remain local to `apps/website/tests/smoke`
- **Heavy-family additions, promotions, or visibility changes**: none
- **Surface-class relief / special coverage rule**: N/A
- **Closing validation and reviewer handoff**: Re-run the website build and smoke suite after route, shell, or navigation changes. Reviewers should verify that `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint` load; `/trust` and `/changelog` can still route visitors to `/contact` within the intended action flow; Trust is top-level visible; the brand links home; one primary CTA remains obvious; unpublished optional content hubs stay hidden; and any legacy route compatibility is explicit rather than silently duplicated.
- **Budget / baseline / trend follow-up**: none beyond small website smoke-suite growth
- **Review-stop questions**: Did any route rename break sitemap/canonical output? Did optional surfaces leak into primary nav without content? Did a compatibility path become permanent instead of transitional? Did any change introduce platform coupling or hidden runtime cost?
- **Escalation path**: document-in-feature
- **Active feature PR close-out entry**: Smoke Coverage
- **Why no dedicated follow-up spec is needed**: The change is bounded to a small public-route contract and website shell behavior. The later page-structure specs handle content/detail work, so route and navigation proof can remain inside this feature.

## Project Structure

### Documentation (this feature)

```text
specs/215-website-core-pages/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   └── public-site-ia.openapi.yaml
└── tasks.md
```

### Source Code (repository root)

```text
apps/website/
├── astro.config.mjs
├── package.json
├── playwright.config.ts
├── public/
├── src/
│   ├── components/
│   │   ├── layout/              # Navbar, Footer, PageShell
│   │   ├── primitives/          # Container, Section, Button, Card, Input, Textarea, Grid, Stack
│   │   ├── sections/            # PageHero, FeatureGrid, TrustGrid, CTASection, LogoStrip
│   │   └── content/             # CTA wrappers, callouts, text blocks
│   ├── content/
│   │   ├── changelog/           # Existing future collection for dated updates
│   │   ├── pages/               # Route-level content definitions
│   │   └── resources/           # Existing optional future collection
│   ├── content.config.ts
│   ├── layouts/
│   │   └── BaseLayout.astro
│   ├── lib/
│   │   ├── seo.ts
│   │   └── site.ts             # Current route, shell, and navigation truth
│   ├── pages/
│   │   ├── index.astro
│   │   ├── product.astro
│   │   ├── contact.astro
│   │   ├── privacy.astro
│   │   ├── solutions.astro
│   │   ├── integrations.astro
│   │   ├── security-trust.astro
│   │   ├── legal.astro
│   │   ├── terms.astro
│   │   └── sitemap.xml.ts
│   ├── styles/
│   └── types/
└── tests/
    └── smoke/
```

**Structure Decision**: Keep the existing website structure and implement the IA in the current Astro route stack. The core truth should live in `src/lib/site.ts`, `src/types/site.ts`, `src/content/pages`, and published page files. Add canonical route files for `/trust`, `/changelog`, and `/imprint`, and use compatibility-only routes only when a rename is necessary to avoid avoidable breakage.

## Complexity Tracking

None.

## Proportionality Review

- **Current operator problem**: The current website still reflects the broader v0 route inventory, with `Solutions` and `Integrations` acting as primary-nav peers, `Security & Trust` using a non-canonical path, and no `/changelog` or `/imprint` routes even though Spec 215 treats those as part of the small credible core.
- **Existing structure is insufficient because**: `src/lib/site.ts` and `src/types/site.ts` currently encode one flat route inventory but do not distinguish between required core surfaces, optional content surfaces, deferred surfaces, and compatibility paths. That makes it too easy for template-era routes to keep occupying top-level attention.
- **Narrowest correct implementation**: Reuse the existing route-definition layer and content collections to encode the new IA contract, publish only the required core routes, and tighten smoke coverage around route topology and navigation behavior. Do not introduce a CMS, API contract, or platform/shared routing abstraction.
- **Ownership cost created**: Ongoing maintenance of the explicit public IA contract, a small set of compatibility decisions for renamed routes, and lightweight smoke assertions that protect navigation and route truth.
- **Alternative intentionally rejected**: Keeping the current v0 topology and trying to solve the IA only through page copy was rejected because it leaves the route and navigation contract incoherent; adding a richer content/router system was rejected because the website does not need that extra ownership cost.
- **Release truth**: Current-release truth for `apps/website`

## Phase 0 — Outline & Research (complete)

- Output: `specs/215-website-core-pages/research.md`
- Key decisions captured:
  - Keep the IA fully local to `apps/website` and preserve the website working contract.
  - Use the existing `src/lib/site.ts` + `src/types/site.ts` route-definition layer as the canonical public IA source of truth.
  - Canonicalize the required public core around `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint`, with compatibility handling only where renames are necessary.
  - Gate optional `Resources` discoverability through the existing Astro content collections, and keep the editorial `articles` collection unpublished until a later spec activates it.
  - Reclassify current `Solutions`, `Integrations`, `Legal`, and `Terms` surfaces as secondary supporting routes so primary navigation stays buyer-first and intentionally small.
  - Validate with build proof plus route- and navigation-focused Playwright smoke coverage.

## Phase 1 — Design & Contracts (complete)

### Data model

- Output: `specs/215-website-core-pages/data-model.md`
- No database schema changes are required; the model is a website-local route, navigation, publication, and compatibility contract.

### Public IA contract

- Output: `specs/215-website-core-pages/contracts/public-site-ia.openapi.yaml`
- The contract captures required public HTML routes, navigation invariants, optional-surface gating, and compatibility-path expectations for the initial website IA.

### Quickstart

- Output: `specs/215-website-core-pages/quickstart.md`
- Quickstart covers the local development flow, implementation order, compatibility expectations, and required validation commands.

### Agent context update

- Completed via `.specify/scripts/bash/update-agent-context.sh copilot` so the Copilot context reflects the current planning artifacts.

### Constitution re-check (post-design)

- ✅ The design remains fully local to `apps/website` and preserves the website working contract.
- ✅ No database truth, backend form handling, queueing, auth, or platform-side runtime concern is introduced.
- ✅ The IA layer remains narrow: route roles, navigation groups, publication rules, and compatibility handling only.
- ✅ Validation remains cheap, representative, and website-specific.

## Phase 2 — Implementation Plan (next)

### Story 1 (P1): Canonical core-route contract

- Update `src/types/site.ts`, `src/lib/site.ts`, `src/content/pages`, and the published Astro route files so the canonical public core is `/`, `/product`, `/trust`, `/changelog`, `/contact`, `/privacy`, and `/imprint`.
- Add the missing `/changelog` and `/imprint` surfaces and replace `/security-trust` as the canonical trust path with `/trust`.
- Keep compatibility routes narrow and explicit; any legacy route retained during migration must stay out of primary navigation and must not become a second canonical truth.
- Tests / validation:
  - Update smoke helpers and assertions to reflect the new canonical navigation labels and route set.
  - Verify sitemap/canonical behavior and route reachability through build proof plus browser smoke tests.

### Story 2 (P1): Navigation and footer reduction to the Spec 215 core

- Shrink primary navigation to Product, Trust, Changelog, Contact, and optional `Resources` only when content is substantive.
- Move buyer-outcome explanation responsibility into Home and Product so `Solutions` is no longer required as a top-level peer; treat `Solutions` and `Integrations` as retained secondary supporting pages instead of core IA pillars.
- Rebuild footer groups around Product, Trust/Legal, Contact, and optional Content, with direct links to `/privacy`, `/imprint`, and the retained secondary `/terms` legal disclosure.
- Tests / validation:
  - Assert brand-to-home behavior, Trust top-level visibility, `/trust -> /contact` reachability, one clear primary CTA, and the new footer grouping.
  - Add negative assertions that placeholder or deferred routes do not appear in primary navigation.

### Story 3 (P2): Content-backed updates and optional-surface gating

- Use the existing `src/content/changelog` collection or equivalent dated entries to make `/changelog` a real progress surface rather than a placeholder.
- Keep `/resources` unpublished or unlinked until content exists, keep the editorial `articles` collection unpublished until a later blog/editorial spec, and keep Docs and Pricing out of primary navigation until later specs explicitly activate them.
- Rationalize current `/legal` and `/terms` behavior as retained secondary legal surfaces, and current `/solutions` and `/integrations` behavior as retained secondary supporting pages, without letting them inflate the initial IA.
- Tests / validation:
  - Extend smoke coverage for `/changelog`, `/imprint`, and `/changelog -> /contact` reachability.
  - Verify unpublished optional surfaces stay hidden, the editorial `articles` collection remains undiscoverable, and any compatibility or retained secondary paths stay out of primary navigation.

## Validation Evidence

- **Lane**: `fast-feedback`
- **Build proof**: `corepack pnpm build:website` completed successfully on 2026-04-19 after the final IA/content changes.
- **Browser smoke proof**: `cd apps/website && corepack pnpm exec playwright test` completed successfully on 2026-04-19 with 13 passing smoke tests.
- **Reviewer note**: If an Astro dev server is already running on `WEBSITE_PORT`, stop it before rerunning Playwright so the suite does not reuse stale content state.
