TenantAtlas/specs/214-website-visual-foundation/research.md
ahmido f884b16061
Some checks failed
Main Confidence / confidence (push) Failing after 40s
feat: implement website visual foundation (#251)
## 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
2026-04-19 07:19:58 +00:00

58 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Research: Website Visual Foundation
## Decision 1: Preserve the website working contract and keep the feature local to `apps/website`
- **Decision**: Treat the visual foundation as a Class A/B website-local change under the website working contract and keep all runtime behavior inside `apps/website`.
- **Rationale**: The current repo truth explicitly allows website-internal evolution while forbidding silent new coupling to `apps/platform`, shared APIs, shared auth, shared DTOs, or shared packages. This spec is about visual language, so the narrowest correct plan is to preserve that separation completely.
- **Alternatives considered**:
- Introduce a shared website-platform design system: rejected because the spec explicitly excludes cross-surface contracts and the repo does not currently verify such a coupling.
- Solve visual consistency inside platform and website together: rejected because it would violate the website-only boundary and import unnecessary coordination cost.
## Decision 2: Build the foundation on semantic token layering, not raw palette reuse
- **Decision**: Keep the current Tailwind CSS v4 CSS-first setup and formalize a two-layer token model: primitive palette and font tokens in `src/styles/tokens.css`, semantic role mapping and surface behavior in the websites shared foundation styles.
- **Rationale**: The repo already uses Tailwind v4 and CSS variables, but the current token layer is only partially semantic. A formal role model is the smallest change that can stop visual drift while preserving the current stack and keeping styling readable in Astro templates.
- **Alternatives considered**:
- Continue with page-local utilities and one-off CSS variables: rejected because it would preserve the drift problem the spec is meant to eliminate.
- Replace the current CSS-first setup with a JavaScript token system or external design-token pipeline: rejected because the website does not need that extra build or ownership complexity.
## Decision 3: Keep Astro-native primitives canonical and adapt `shadcn/ui` concepts locally
- **Decision**: Keep the existing Astro primitive layer as the canonical implementation surface. `shadcn/ui` will be treated as a design/build reference whose patterns are adapted into local primitives instead of installed as React plus official `shadcn/ui`.
- **Rationale**: `apps/website` currently has no React, Radix, or `shadcn/ui` dependency. The public site is static-first and already composed from Astro primitives. Adapting `shadcn/ui` ideas into that layer satisfies the specs requirement for controlled usage without adding a second component runtime or framework abstraction.
- **Alternatives considered**:
- Add React and official `shadcn/ui` now: rejected because it adds unnecessary runtime and dependency cost for a content-driven static site.
- Ignore `shadcn/ui` entirely: rejected because the spec explicitly requires a usage contract; the right answer is controlled adaptation, not omission.
## Decision 4: Use representative page families already in the repo to drive the foundation
- **Decision**: Drive the implementation and validation of the visual language through three website page families already present in `apps/website`: landing/product-marketing surfaces, trust/legal surfaces, and content-heavy long-form surfaces.
- **Rationale**: The visual foundation only proves itself if it survives more than one hero screen. The existing route set already provides the right coverage: Home or Product for landing behavior, Security & Trust or Privacy/Terms for trust/legal behavior, and Legal/Privacy/Terms for long-form text density and callout rhythm.
- **Alternatives considered**:
- Optimize only the Home page: rejected because the spec explicitly requires consistency across more than one page type.
- Wait for blog or changelog routes before defining the foundation: rejected because the existing legal and trust pages are sufficient to validate long-form behavior now.
## Decision 5: Encode interaction and surface semantics in shared primitives, not page-local classes
- **Decision**: Consolidate button hierarchy, link semantics, input behavior, card/surface treatments, and section rhythm through the current primitives and layout helpers instead of letting each page set those rules locally.
- **Rationale**: The repo already contains `Button`, `Card`, `Input`, `Textarea`, `Section`, `SectionHeader`, and `PageHero`. Those are the narrowest existing seams where the design foundation can be enforced consistently without inventing a new framework.
- **Alternatives considered**:
- Document the rules but leave existing primitives unchanged: rejected because the drift would persist in code even if the rules existed in prose.
- Introduce many new micro-primitives for every visual nuance: rejected because the foundation should reduce variety, not create a larger component taxonomy.
## Decision 6: Validate through build proof plus focused Playwright smoke coverage
- **Decision**: Keep validation in `fast-feedback` using `corepack pnpm build:website` and the existing Playwright smoke suite in `apps/website/tests/smoke`.
- **Rationale**: This feature changes runtime rendering, navigation shell, and CTA hierarchy, so build proof alone is not enough. The current local Playwright setup is already the narrowest realistic browser-level proof for representative pages and mobile navigation behavior.
- **Alternatives considered**:
- Build-only validation: rejected because it would miss browser-visible regressions in hierarchy, navigation, and CTA reachability.
- Visual regression or a heavier multi-browser lane: rejected because the current change does not justify that added test-governance cost yet.
## Baseline Findings
- `apps/website` already runs as an Astro 6 static app with strict TypeScript, Tailwind CSS v4, and local Playwright smoke tests.
- The site already has reusable Astro primitives (`Button`, `Card`, `Section`, `SectionHeader`, `Input`, `Textarea`, `Container`, `Grid`, `Stack`) and section components (`PageHero`, `FeatureGrid`, `TrustGrid`, `CTASection`, `LogoStrip`).
- `src/styles/tokens.css` currently defines palette and font tokens, while `src/styles/global.css` still carries important semantic choices such as focus behavior, panel backgrounds, shadows, and decorative shell treatments.
- No `shadcn/ui`, Radix, or React dependency is present in `apps/website` today.
- Existing published routes already cover the page-family range needed for foundation validation: landing/product, trust/legal, and content-heavy reading surfaces.
- Root workspace contracts already expose `corepack pnpm dev:website` and `corepack pnpm build:website`, and those must remain intact.