## Summary - implement the website-only visual foundation for apps/website - formalize semantic tokens, typography, spacing, surfaces, and shared CTA/navigation primitives - align landing, trust/legal, and content-heavy routes plus Playwright smoke coverage with the new foundation ## Validation - corepack pnpm build:website - corepack pnpm --filter @tenantatlas/website exec playwright test ## Scope - website-only change set for spec 214 - no apps/platform runtime coupling introduced Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #251
14 KiB
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/websitefully 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/uias an adaptation/reference contract rather than introducing React plus officialshadcn/uias a new required runtime layer. - Apply the foundation across representative page families already present in
apps/websiteso 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/websiteand introduces no/admin,/admin/t/{tenant}/..., or/systemruntime 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-feedbackusing 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/websiteexcept for preserving existing root workflow compatibility, and it introduces no new API, auth, DTO, or shared-package coupling toapps/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/Aornone.
- 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:websiteandcd 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)
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)
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/uiusage 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/uiwas 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/uiusage 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.
- Preserve the website working contract and keep all visual-language work local to
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 copilotso 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/websiteand 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, andTextareaexpose 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.
- Confirm the website still builds via
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/uiusage 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/uipattern 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.