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

6.6 KiB
Raw Permalink Blame History

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.