TenantAtlas/apps/website/src/components/sections/PageHero.astro
ahmido 2d552c7ae8
Some checks failed
Main Confidence / confidence (push) Failing after 42s
feat: initial website foundation and v0 product site (#249)
## Summary
- establish the initial Astro website foundation for `apps/website` with explicit TypeScript, Tailwind CSS v4, and reusable layout/content primitives
- ship the v0 public route set for home, product, solutions, security & trust, integrations, contact, legal, privacy, and terms
- add SEO/discovery basics, Playwright browser smoke coverage, and the full Spec 213 planning bundle under `specs/213-website-foundation-v0`
- extend ignore rules for website test artifacts and refresh Copilot agent context for the new website stack

## Validation
- `corepack pnpm build:website`
- `cd apps/website && corepack pnpm exec playwright test`

## Notes
- branch: `213-website-foundation-v0`
- commit: `020d416d0d8af4d16a981ff4f4f6d90153b9c603`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #249
2026-04-18 20:56:47 +00:00

97 lines
4.5 KiB
Plaintext

---
import Badge from '@/components/primitives/Badge.astro';
import Button from '@/components/primitives/Button.astro';
import Card from '@/components/primitives/Card.astro';
import Cluster from '@/components/primitives/Cluster.astro';
import Container from '@/components/primitives/Container.astro';
import type { HeroContent, MetricItem } from '@/types/site';
interface Props {
calloutDescription?: string;
calloutTitle?: string;
hero: HeroContent;
metrics?: MetricItem[];
}
const { calloutDescription, calloutTitle, hero, metrics = [] } = Astro.props;
---
<section class="pt-8 sm:pt-10 lg:pt-14">
<Container wide>
<div class="grid gap-6 lg:grid-cols-[1.35fr,0.85fr]">
<Card class="motion-rise overflow-hidden">
<div class="space-y-6">
<Badge>{hero.eyebrow}</Badge>
<div class="space-y-4">
<h1 class="max-w-4xl font-[var(--font-display)] text-5xl leading-[0.93] tracking-[-0.04em] text-[var(--color-ink-900)] sm:text-6xl lg:text-7xl">
{hero.title}
</h1>
<p class="max-w-3xl text-lg leading-8 text-[var(--color-copy)] sm:text-xl">
{hero.description}
</p>
</div>
{(hero.primaryCta || hero.secondaryCta) && (
<Cluster>
<Button href={hero.primaryCta.href} variant={hero.primaryCta.variant ?? 'primary'}>
{hero.primaryCta.label}
</Button>
{hero.secondaryCta && (
<Button href={hero.secondaryCta.href} variant={hero.secondaryCta.variant ?? 'secondary'}>
{hero.secondaryCta.label}
</Button>
)}
</Cluster>
)}
{hero.highlights && hero.highlights.length > 0 && (
<ul class="grid gap-3 p-0 sm:grid-cols-3">
{
hero.highlights.map((highlight) => (
<li class="list-none rounded-[1.1rem] border border-[color:var(--color-line)] bg-white/70 px-4 py-3 text-sm font-medium text-[var(--color-ink-800)]">
{highlight}
</li>
))
}
</ul>
)}
</div>
</Card>
<div class="grid gap-5">
{(calloutTitle || calloutDescription) && (
<Card variant="accent" class="motion-rise">
<p class="m-0 text-sm font-semibold uppercase tracking-[0.15em] text-[var(--color-brand)]">
Trust-first launch surface
</p>
{calloutTitle && (
<h2 class="mt-4 font-[var(--font-display)] text-3xl leading-tight text-[var(--color-ink-900)]">
{calloutTitle}
</h2>
)}
{calloutDescription && (
<p class="mt-3 text-base leading-7 text-[var(--color-copy)]">{calloutDescription}</p>
)}
</Card>
)}
{metrics.length > 0 && (
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-1">
{
metrics.map((metric) => (
<Card variant="subtle">
<p class="m-0 text-3xl font-semibold tracking-[-0.04em] text-[var(--color-ink-900)]">
{metric.value}
</p>
<p class="mt-2 text-sm font-semibold uppercase tracking-[0.14em] text-[var(--color-brand)]">
{metric.label}
</p>
<p class="mt-2 text-sm leading-6 text-[var(--color-copy)]">{metric.description}</p>
</Card>
))
}
</div>
)}
</div>
</div>
</Container>
</section>