183 lines
14 KiB
Markdown
183 lines
14 KiB
Markdown
# Implementation Plan: Website Visual Foundation
|
||
|
||
**Branch**: `214-website-visual-foundation` | **Date**: 2026-04-18 | **Spec**: `specs/214-website-visual-foundation/spec.md`
|
||
**Input**: Feature specification from `specs/214-website-visual-foundation/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 the existing workspace contracts defined by the website working contract.
|
||
- Build the visual foundation on the current Astro 6 + Tailwind CSS v4 stack by formalizing semantic token roles, typography hierarchy, spacing rules, surface logic, interaction semantics, and page-level consistency rules.
|
||
- Keep Astro-native primitives as the canonical implementation surface and treat `shadcn/ui` as an adaptation/reference contract rather than introducing React plus official `shadcn/ui` as a new required runtime layer.
|
||
- Apply the foundation across representative page families already present in `apps/website` so landing, trust/legal, and content-heavy surfaces read as one controlled enterprise website instead of locally styled variants.
|
||
|
||
## 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 component primitives, Playwright browser smoke tests
|
||
**Storage**: Static filesystem content, styles, assets, and content collections under `apps/website/src` and `apps/website/public`; no database
|
||
**Testing**: Root build proof via `corepack pnpm build:website` plus Playwright browser 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 public routes, keep reading/navigation flows zero-hydration by default, and keep UI refinements within a low-JS, accessibility-first posture
|
||
**Constraints**: Preserve `@tenantatlas/website`, `WEBSITE_PORT`, and root `dev:website` / `build:website` workflows; do not introduce platform runtime coupling; do not promote website semantics into a shared cross-surface design system; keep any `shadcn/ui` usage adapted to website-owned tokens and primitives
|
||
**Scale/Scope**: 9 published public routes, existing layout/primitives/sections/content directories, and one website-local visual foundation spanning landing, trust/legal, and content-heavy page families
|
||
|
||
## 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 planned work stays inside `apps/website` and introduces no `/admin`, `/admin/t/{tenant}/...`, or `/system` runtime behavior.
|
||
- Read/write separation: Pass. The feature changes public presentation and component composition only; it introduces no website write workflow, backend form handler, queue, or remote call path.
|
||
- Workspace isolation: Pass. The website remains runtime-independent from `apps/platform`, and the plan preserves the explicit website working contract boundaries.
|
||
- Data minimization: Pass. The feature only reorganizes or extends public styles, content composition, and component semantics; it introduces no tenant data, secrets, auth state, or operational records.
|
||
- Test governance (TEST-GOV-001): Pass. Validation remains in `fast-feedback` using the existing website build and local Playwright smoke suite, with no database, auth, provider, or heavy-suite defaults.
|
||
- Proportionality / no premature abstraction: Pass. The plan extends the current Astro/Tailwind foundation with a narrow website-local semantic layer instead of introducing React, a CMS, or a shared website-platform design system.
|
||
- Persisted truth / new state: Pass. No database schema, persisted entity, queue lifecycle, or new application state family is introduced.
|
||
- UI semantics / few layers: Pass. The added semantics stay limited to design tokens, primitive contracts, and page-composition rules for the website, not a reusable cross-app interpretation framework.
|
||
- Website working contract: Pass. The plan keeps changes local to `apps/website` except for preserving existing root workflow compatibility, and it introduces no new API, auth, DTO, or shared-package coupling to `apps/platform`.
|
||
|
||
Status: ✅ No constitution violations for this feature. The implementation 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 representative public page families plus root static build proof
|
||
- **Affected validation lanes**: fast-feedback
|
||
- **Why this lane mix is the narrowest sufficient proof**: The feature changes runtime website rendering, styling, and composition but stays within a static Astro site. Build proof catches asset and route breakage; a focused Playwright smoke suite catches browser-visible regressions in navigation, CTA visibility, representative content surfaces, and mobile usability 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 website pages require no database, auth, tenant, or provider setup
|
||
- **Expensive defaults or shared helper growth introduced?**: no; any browser assertions remain local to `apps/website/tests/smoke`
|
||
- **Heavy-family additions, promotions, or visibility changes**: none
|
||
- **Closing validation and reviewer handoff**: Re-run the website build and smoke suite after token, primitive, or page-family changes. Reviewers should verify that Home, trust/legal, and another content-heavy route still load cleanly, navigation and footer links remain reachable, CTA hierarchy stays visible, and no unnecessary client framework hydration is introduced.
|
||
- **Budget / baseline / trend follow-up**: none beyond the existing small website smoke-suite runtime
|
||
- **Review-stop questions**: Does validation remain fast-feedback only? Did any change introduce hidden React/runtime coupling, broaden the smoke suite beyond representative website flows, or create new platform-facing contracts?
|
||
- **Escalation path**: document-in-feature
|
||
- **Why no dedicated follow-up spec is needed**: This feature’s validation scope is tightly bounded to the website’s local rendering and navigation behavior. A separate test-governance spec is only needed if the website later gains interactive workflows, API-backed forms, or broader browser coverage.
|
||
|
||
## Project Structure
|
||
|
||
### Documentation (this feature)
|
||
|
||
```text
|
||
specs/214-website-visual-foundation/
|
||
├── plan.md
|
||
├── research.md
|
||
├── data-model.md
|
||
├── quickstart.md
|
||
├── contracts/
|
||
│ └── website-visual-foundation.contract.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, Badge, Card, Input, Textarea, Grid, Stack
|
||
│ │ ├── sections/ # PageHero, FeatureGrid, TrustGrid, CTASection, LogoStrip
|
||
│ │ └── content/ # Eyebrow, Headline, Lead, Callout, Metric, audience/trust helpers
|
||
│ ├── content/ # Route content and future content collections
|
||
│ ├── layouts/
|
||
│ │ └── BaseLayout.astro
|
||
│ ├── lib/ # Site metadata, SEO, and helper config
|
||
│ ├── pages/ # Published public routes
|
||
│ ├── styles/
|
||
│ │ ├── global.css
|
||
│ │ └── tokens.css
|
||
│ └── types/
|
||
└── tests/
|
||
└── smoke/
|
||
```
|
||
|
||
**Structure Decision**: Keep the existing website structure and formalize the design foundation inside the current `styles`, `primitives`, `sections`, `content`, and `layout` layers. The implementation should encode semantic design rules in the Astro-native foundation already present instead of introducing a second component stack.
|
||
|
||
## Complexity Tracking
|
||
|
||
None.
|
||
|
||
## Proportionality Review
|
||
|
||
- **Current operator problem**: Website contributors and reviewers lack a canonical, website-local visual contract, so styling decisions drift across pages and primitives and dilute enterprise trust.
|
||
- **Existing structure is insufficient because**: The current site already has tokens, gradients, rounded cards, and reusable primitives, but those choices are only partially codified. They do not yet define the semantic token roles, page-family rules, or `shadcn/ui` usage boundaries needed to prevent future drift.
|
||
- **Narrowest correct implementation**: Extend the current Astro/Tailwind foundation with explicit semantic token mapping, primitive contracts, and page-consistency rules, then apply those rules to representative routes. Do not add a new client framework, platform coupling, or shared website-platform design system.
|
||
- **Ownership cost created**: Ongoing maintenance of token semantics, shared primitives, and a small browser smoke suite that protects representative public routes.
|
||
- **Alternative intentionally rejected**: Continuing page-local styling was rejected because it preserves drift; full React plus official `shadcn/ui` was rejected because it adds unnecessary runtime and maintenance cost; a shared cross-surface design system was rejected because the feature is intentionally website-only.
|
||
- **Release truth**: Current-release truth for `apps/website`
|
||
|
||
## Phase 0 — Outline & Research (complete)
|
||
|
||
- Output: `specs/214-website-visual-foundation/research.md`
|
||
- Key decisions captured:
|
||
- Preserve the website working contract and keep all visual-language work local to `apps/website`.
|
||
- Build the foundation on semantic token layering in Tailwind CSS v4 and CSS custom properties rather than page-local utility drift.
|
||
- Keep Astro-native primitives as the canonical implementation surface and adapt any `shadcn/ui` usage to that layer instead of adding React as a new runtime dependency.
|
||
- Use representative page families already in the repo to drive the foundation: landing, trust/legal, and content-heavy surfaces.
|
||
- Validate with root build proof plus the existing Playwright smoke suite for representative public routes.
|
||
|
||
## Phase 1 — Design & Contracts (complete)
|
||
|
||
### Data model
|
||
|
||
- Output: `specs/214-website-visual-foundation/data-model.md`
|
||
- No database schema changes are required; the model is a website-local design contract expressed through token roles, primitive contracts, and page-family consistency rules.
|
||
|
||
### Design contract
|
||
|
||
- Output: `specs/214-website-visual-foundation/contracts/website-visual-foundation.contract.yaml`
|
||
- This feature has no HTTP or API contract changes. The contract artifact captures the website-local visual foundation rules that implementation must satisfy.
|
||
|
||
### Quickstart
|
||
|
||
- Output: `specs/214-website-visual-foundation/quickstart.md`
|
||
- Quickstart covers local development, representative implementation order, and the required validation commands.
|
||
|
||
### Agent context update
|
||
|
||
- Completed via `.specify/scripts/bash/update-agent-context.sh copilot` so the Copilot context reflects the current website stack and this feature’s 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, or platform-side runtime concern is introduced.
|
||
- ✅ The semantic layer remains narrow: tokens, primitives, and page-family rules only.
|
||
- ✅ Validation remains cheap, representative, and website-specific.
|
||
|
||
## Phase 2 — Implementation Plan (next)
|
||
|
||
### Story 1 (P1): Semantic token and rule foundation
|
||
|
||
- Normalize the existing palette and CSS variables into an explicit semantic role model for colors, surfaces, borders, shadows, radius, and typography.
|
||
- Encode the spacing model and section rhythm into the current Astro foundation so `Container`, `Section`, `SectionHeader`, `Card`, `Button`, `Input`, and `Textarea` expose one canonical visual language.
|
||
- Keep the site static and light-first, with focus states, contrast, and mobile readability treated as foundation rules rather than page-local cleanup.
|
||
- Tests / validation:
|
||
- Confirm the website still builds via `corepack pnpm build:website`.
|
||
- Re-run smoke coverage for Home and Product, explicitly proving focus visibility, readable contrast, non-color-only semantics, and clear navigation-vs-CTA differentiation.
|
||
|
||
### Story 2 (P1): Representative page-family alignment
|
||
|
||
- Apply the foundation consistently across representative page families already present in the app: landing (`/` or `/product`), trust/legal (`/security-trust`, `/privacy`, `/terms`), and other content-heavy routes.
|
||
- Reduce style drift in hero, section intro, callout, stat, and card usage so CTA emphasis, section spacing, surface elevation, and progressive-disclosure layering behave consistently across routes.
|
||
- Ensure the footer, navigation shell, and CTA placement logic match the foundation’s page-level rules.
|
||
- Tests / validation:
|
||
- Extend or adjust browser smoke coverage to assert representative headings, CTA visibility, shell/navigation stability, and progressive-disclosure layering across at least three page families.
|
||
- Verify mobile navigation remains usable.
|
||
|
||
### Story 3 (P2): `shadcn/ui` usage contract in code
|
||
|
||
- Encode `shadcn/ui` usage constraints through local primitives and variant APIs so future component work is forced back through website-owned tokens, surfaces, and interaction semantics.
|
||
- Keep Astro-native wrappers as the primary authoring path; any borrowed `shadcn/ui` pattern must be translated into local primitives instead of exposing uncontrolled library defaults.
|
||
- Avoid introducing React, Radix, or extra framework/runtime weight unless a later explicit spec proves a concrete need.
|
||
- Tests / validation:
|
||
- Re-run build and smoke coverage after primitive API changes.
|
||
- Review representative components to ensure no page-local style override bypasses the shared token and primitive model. |