feat: transition website product page to platform #391

Merged
ahmido merged 1 commits from feat/401-tenantial-platform-page into website-dev 2026-05-19 21:34:32 +00:00
21 changed files with 3781 additions and 136 deletions

View File

@ -943,6 +943,7 @@ ## Active Technologies
- PostgreSQL (Sail)
- Tailwind CSS v4
- TypeScript 5.9, Astro 6 static components, HTML, CSS + Astro 6.0.0, Tailwind CSS 4.2.2 through CSS-first `@theme` and `@tailwindcss/vite`, `astro-icon`, `@iconify-json/lucide`, Playwright 1.59.1 (400-tenantial-homepage-visual-rebuild)
- TypeScript 5.9.3, Astro 6.0.0, Tailwind CSS v4.2.2 via `@tailwindcss/vite`, `astro-icon`, `@iconify-json/lucide`, and Playwright smoke tests for the static website; no database, CMS, API, customer data, tenant data, or runtime persistence. (401-tenantial-platform-page)
## Recent Changes
- 066-rbac-ui-enforcement-helper-v2-session-1769732329: Planned UiEnforcement v2 (spec + plan + design artifacts)

View File

@ -9,6 +9,9 @@ const publicSiteUrl = process.env.PUBLIC_SITE_URL ?? 'https://tenantial.example'
export default defineConfig({
integrations: [icon()],
output: 'static',
redirects: {
'/product': '/platform',
},
site: publicSiteUrl,
server: {
host: true,

View File

@ -720,13 +720,13 @@ const evidenceItems = [
.finding-list {
display: grid;
gap: 0.38rem;
gap: 0.42rem;
}
.finding-row {
display: grid;
grid-template-columns: 0.82rem minmax(0, 1fr) auto auto;
gap: 0.42rem;
grid-template-columns: 0.72rem minmax(0, 1fr) auto;
gap: 0.34rem 0.44rem;
align-items: center;
}
@ -761,6 +761,16 @@ const evidenceItems = [
line-height: 1.15;
}
.row-status-label {
grid-column: 3;
grid-row: 1 / span 2;
width: fit-content;
}
.finding-row small {
display: none;
}
.timeline-list {
position: relative;
display: grid;
@ -1072,13 +1082,7 @@ const evidenceItems = [
}
.finding-row {
grid-template-columns: 0.82rem minmax(0, 1fr);
}
.row-status-label,
.finding-row small {
grid-column: 2;
width: fit-content;
grid-template-columns: 0.72rem minmax(0, 1fr) auto;
}
.timeline-list li {

View File

@ -1,5 +1,6 @@
---
import PrimaryCTA from '@/components/content/PrimaryCTA.astro';
import TenantialLogo from '@/components/content/TenantialLogo.astro';
import Container from '@/components/primitives/Container.astro';
import { getFooterLead, getFooterNavigationGroups, siteMetadata } from '@/lib/site';
@ -11,47 +12,80 @@ const { currentPath: _currentPath } = Astro.props;
const currentYear = new Date().getFullYear();
const footerLead = getFooterLead(_currentPath);
const footerNavigationGroups = await getFooterNavigationGroups();
const isQuietFooter = _currentPath === '/platform';
---
<footer class="section-divider px-[var(--space-page-x)] pt-10 sm:pt-12" data-footer-intent={footerLead.intent}>
<footer class="section-divider px-[var(--space-page-x)] pt-10 sm:pt-12" data-footer-intent={isQuietFooter ? 'quiet' : footerLead.intent}>
<Container width="wide">
<div class="surface-card-muted grid gap-8 rounded-[var(--radius-panel)] p-6 lg:grid-cols-[1.3fr,1fr] lg:p-8">
<div class="space-y-5">
<p class="m-0 text-sm font-semibold uppercase text-[var(--color-brand)]">
{footerLead.eyebrow}
</p>
<h2 class="m-0 max-w-xl font-[var(--font-display)] text-3xl leading-tight text-[var(--color-foreground)] sm:text-4xl">
{footerLead.title}
</h2>
<p class="m-0 max-w-xl text-base leading-7 text-[var(--color-copy)]">
{footerLead.description}
</p>
<PrimaryCTA cta={footerLead.primaryCta} size="sm" />
</div>
{isQuietFooter ? (
<div class="grid gap-8 py-3 lg:grid-cols-[0.85fr_1.15fr] lg:items-start">
<div class="space-y-4">
<TenantialLogo imageClass="h-[2.25rem] w-auto" />
<p class="m-0 max-w-sm text-[0.95rem] leading-7 text-[var(--color-copy)]">
Evidence-first governance for Microsoft tenants.
</p>
</div>
<div class="grid gap-6 sm:grid-cols-2 xl:grid-cols-4">
{
footerNavigationGroups.map((group) => (
<div>
<p class="m-0 text-sm font-semibold uppercase text-[var(--color-foreground)]">
{group.title}
</p>
<ul class="mt-4 space-y-3 p-0 text-sm text-[var(--color-copy)]">
{group.items.map((item) => (
<li class="list-none">
<a class="transition hover:text-[var(--color-brand)]" href={item.href}>
{item.label}
</a>
</li>
))}
</ul>
</div>
))
}
<div class="grid gap-6 sm:grid-cols-2 xl:grid-cols-5">
{
footerNavigationGroups.map((group) => (
<div>
<p class="m-0 text-[0.88rem] font-semibold uppercase text-[var(--color-foreground)]">
{group.title}
</p>
<ul class="mt-4 space-y-3 p-0 text-[0.92rem] text-[var(--color-copy)]">
{group.items.map((item) => (
<li class="list-none">
<a class="transition hover:text-[var(--color-brand)]" href={item.href}>
{item.label}
</a>
</li>
))}
</ul>
</div>
))
}
</div>
</div>
</div>
) : (
<div class="surface-card-muted grid gap-8 rounded-[var(--radius-panel)] p-6 lg:grid-cols-[1.3fr,1fr] lg:p-8">
<div class="space-y-5">
<p class="m-0 text-sm font-semibold uppercase text-[var(--color-brand)]">
{footerLead.eyebrow}
</p>
<h2 class="m-0 max-w-xl font-[var(--font-display)] text-3xl leading-tight text-[var(--color-foreground)] sm:text-4xl">
{footerLead.title}
</h2>
<p class="m-0 max-w-xl text-base leading-7 text-[var(--color-copy)]">
{footerLead.description}
</p>
<PrimaryCTA cta={footerLead.primaryCta} size="sm" />
</div>
<div class="flex flex-col gap-3 py-6 text-sm text-[var(--color-copy)] sm:flex-row sm:items-center sm:justify-between">
<div class="grid gap-6 sm:grid-cols-2 xl:grid-cols-4">
{
footerNavigationGroups.map((group) => (
<div>
<p class="m-0 text-sm font-semibold uppercase text-[var(--color-foreground)]">
{group.title}
</p>
<ul class="mt-4 space-y-3 p-0 text-sm text-[var(--color-copy)]">
{group.items.map((item) => (
<li class="list-none">
<a class="transition hover:text-[var(--color-brand)]" href={item.href}>
{item.label}
</a>
</li>
))}
</ul>
</div>
))
}
</div>
</div>
)}
<div class="flex flex-col gap-3 py-6 text-[0.9rem] text-[var(--color-copy)] sm:flex-row sm:items-center sm:justify-between">
<p class="m-0">© {currentYear} {siteMetadata.siteName}. Evidence-first governance for Microsoft tenants.</p>
<p class="m-0">
Static public website with sample preview values only.

View File

@ -26,7 +26,7 @@ export const homeHero: HeroContent = {
label: 'Book a demo',
},
secondaryCta: {
href: '/product',
href: '/platform',
label: 'Explore the platform',
variant: 'secondary',
},
@ -105,7 +105,7 @@ export const homeCtaSection = {
label: 'Book a demo',
} as CtaLink,
secondary: {
href: '/product',
href: '/platform',
label: 'Explore the platform',
variant: 'secondary',
} as CtaLink,

View File

@ -0,0 +1,304 @@
import type { CtaLink, FeatureItemContent, HeroContent, PageSeo } from '@/types/site';
export interface GovernanceLoopItem {
description: string;
label: string;
tone?: 'default' | 'focus' | 'source';
}
export interface OperatingModelStep {
badge: string;
description: string;
icon: string;
label: string;
}
export interface PlatformBoundaryContent {
description: string;
headline: string;
items: string[];
}
export interface PlatformCapabilityPrimary {
ctaLabel: string;
description: string;
icon: string;
proofPoints: string[];
title: string;
}
export interface PlatformHeroTrustSignal {
icon: string;
label: string;
}
export interface PlatformWorkflowContent {
audience: string;
description: string;
icon: string;
}
export interface TruthLayerContent {
description: string;
question: string;
title: string;
}
export const platformSeo: PageSeo = {
title: 'Tenantial Platform | Evidence-first governance for Microsoft tenants',
description:
'Tenantial Platform connects backup, restore, drift detection, findings, evidence, audit trails, exceptions, and reviews for Microsoft tenant governance.',
path: '/platform',
};
export const platformHero: HeroContent = {
eyebrow: 'TENANTIAL PLATFORM',
title: 'Govern Microsoft tenants through evidence, drift context, and reviewable decisions.',
description:
'Tenantial continuously maps Microsoft tenant configuration into reviewable records, so backup records, configuration drift, findings, evidence, audit trails, and structured reviews stay connected.',
primaryCta: {
href: '/contact',
label: 'Book a demo',
},
secondaryCta: {
href: '#governance-loop',
label: 'See the governance loop',
variant: 'secondary',
},
};
export const platformHeroTrustSignals: PlatformHeroTrustSignal[] = [
{
icon: 'lucide:cloud-cog',
label: 'Microsoft tenant focused',
},
{
icon: 'lucide:file-check-2',
label: 'Evidence-oriented workflows',
},
{
icon: 'lucide:refresh-cw',
label: 'Reviewable decisions',
},
{
icon: 'lucide:users-round',
label: 'Operator-led governance',
},
];
export const operatingModelSteps: OperatingModelStep[] = [
{
badge: 'Observed',
icon: 'lucide:camera',
label: 'Snapshot',
description: 'Capture the current state of policies, identities, roles, and configuration.',
},
{
badge: 'Detected',
icon: 'lucide:activity',
label: 'Drift',
description: 'Detect meaningful movement against known baselines and recent evidence.',
},
{
badge: 'Qualified',
icon: 'lucide:triangle-alert',
label: 'Finding',
description: 'Qualify drift with risk context, affected scope, and remediation options.',
},
{
badge: 'Decided',
icon: 'lucide:users-round',
label: 'Review',
description: 'Let the responsible operator inspect context before the next action is chosen.',
},
{
badge: 'Documented',
icon: 'lucide:file-check-2',
label: 'Evidence',
description: 'Attach artifacts, screenshots, notes, and logs to the review record.',
},
{
badge: 'Recorded',
icon: 'lucide:shield-check',
label: 'Audit trail',
description: 'Retain who decided what, when, and which evidence supported the decision.',
},
];
export const governanceLoopIntro = {
eyebrow: 'Governance loop',
title: 'Context, evidence, and auditability stay connected.',
description:
'Every decision is grounded in verifiable data. Nothing gets lost in handoffs or memory, and review work stays tied to the source material that created it.',
bullets: [
'End-to-end traceability from change to decision',
'Immutable evidence with screenshots and logs',
'Clear accountability for every action',
'Ready for internal and external reviews',
],
};
export const governanceLoop: GovernanceLoopItem[] = [
{
label: 'Source of truth',
description: 'Graph, Entra ID, SharePoint, Exchange, Defender, Azure AD, and operator scripts.',
tone: 'source',
},
{
label: 'Snapshot',
description: 'Point-in-time state captured.',
},
{
label: 'Diff',
description: 'Baseline comparison highlights drift.',
},
{
label: 'Finding',
description: 'Risk context and suggested remediation.',
},
{
label: 'Exception',
description: 'Accepted risk with owner and expiry.',
},
{
label: 'Review',
description: 'Operator reviews context and decides.',
tone: 'focus',
},
{
label: 'Evidence',
description: 'Artifacts and notes attach to the decision.',
tone: 'focus',
},
{
label: 'Audit trail',
description: 'Decision history stays traceable.',
},
];
export const platformCapabilityPrimary: PlatformCapabilityPrimary = {
icon: 'lucide:archive-restore',
title: 'Backup & Restore',
description:
'Protect critical tenant configurations and data. Preview, validate, and restore with confidence from preserved configuration evidence.',
ctaLabel: 'Explore backups',
proofPoints: ['Point-in-time records', 'Restore preview context', 'Evidence for each decision'],
};
export const platformCapabilities: FeatureItemContent[] = [
{
icon: 'git-branch',
title: 'Drift Detection',
description: 'Detect policy, access, and configuration changes before they turn into audit work.',
meta: 'Detected',
},
{
icon: 'search',
title: 'Findings',
description: 'Risk-rank drift with context, impact, and recommended actions.',
meta: 'Qualified',
},
{
icon: 'file-check',
title: 'Evidence',
description: 'Capture and organize artifacts that prove every decision.',
meta: 'Documented',
},
{
icon: 'clipboard',
title: 'Audit Trail',
description: 'Maintain history of changes, decisions, and operator actions.',
meta: 'Traceable',
},
{
icon: 'flag',
title: 'Exceptions',
description: 'Document accepted risks with owners and review cadence.',
meta: 'Owned',
},
{
icon: 'users',
title: 'Governance Reviews',
description: 'Run structured reviews with tasks, approvals, and reporting.',
meta: 'Review cadence',
},
];
export const truthLayers: TruthLayerContent[] = [
{
title: 'Execution truth',
description: 'What is happening right now in the tenant.',
question: 'What changed?',
},
{
title: 'Artifact truth',
description: 'The evidence and logs that prove it.',
question: 'What proves it?',
},
{
title: 'Backup truth',
description: 'What we have protected and can restore.',
question: 'What can we recover?',
},
{
title: 'Recovery evidence',
description: 'Proof of restores, tests, and recovery actions.',
question: 'How do we restore?',
},
{
title: 'Operator next action',
description: 'What the operator should do or review next.',
question: 'What should we do now?',
},
];
export const operatorWorkflows: PlatformWorkflowContent[] = [
{
audience: 'MSP Operator',
icon: 'lucide:user-round',
description: 'Manage multiple clients with consistent guardrails, backups, and reviews.',
},
{
audience: 'Enterprise IT',
icon: 'lucide:building-2',
description: 'Maintain secure posture with drift context and clear actions.',
},
{
audience: 'Security Reviewer',
icon: 'lucide:shield-check',
description: 'Investigate, validate, and ensure issues are remediated.',
},
{
audience: 'Compliance / Audit',
icon: 'lucide:scroll-text',
description: 'Access evidence and reports to meet internal and external needs.',
},
];
export const platformBoundary: PlatformBoundaryContent = {
headline: 'Built for governance of record and recovery context.',
description:
'Tenantial is designed to preserve context, evidence, and governance control so operators can act with confidence.',
items: [
'We do not take actions on your behalf.',
'We do not manage devices.',
'We do not replace your ITSM, SIEM, ticketing, or Microsoft admin centers.',
'We support reviewable decisions.',
],
};
export const platformFinalCta = {
eyebrow: 'Evaluate the loop',
title: 'See how evidence-first governance fits your Microsoft tenant operations.',
description:
'Explore a focused demo of Tenantial and see how your team can turn signal into trusted decisions.',
primary: {
href: '/contact',
label: 'Book a demo',
} as CtaLink,
secondary: {
href: '#governance-loop',
label: 'Explore the platform',
variant: 'secondary',
} as CtaLink,
};

View File

@ -133,7 +133,7 @@ const headerCtaByFamily: Record<PageFamily, CtaLink> = {
export const canonicalCoreRoutes: SitePath[] = [
'/',
'/product',
'/platform',
'/trust',
'/changelog',
'/contact',
@ -142,7 +142,7 @@ export const canonicalCoreRoutes: SitePath[] = [
];
export const retainedSecondaryRoutes: SitePath[] = ['/legal', '/terms', '/solutions', '/integrations'];
export const compatibilityRoutes: SitePath[] = ['/security-trust'];
export const compatibilityRoutes: SitePath[] = ['/product', '/security-trust'];
export const primaryConversionRoute: SitePath = '/contact';
export const unpublishedEditorialCollections: CollectionName[] = ['articles'];
@ -157,7 +157,7 @@ export async function getSurfaceAvailability(): Promise<SurfaceAvailability> {
}
const primaryNavigationSeeds: CollectionGatedNavigationItem[] = [
{ href: '/product', label: 'Platform', description: 'Explore the evidence-first governance surface.' },
{ href: '/platform', label: 'Platform', description: 'Explore the evidence-first governance surface.' },
{ href: '/solutions', label: 'Solutions', description: 'Review MSP and enterprise governance fit.' },
{ href: '/changelog', label: 'Resources', description: 'Use the changelog as the current public resource baseline.' },
{ href: '/contact', label: 'Pricing', description: 'Pricing is handled through a scoped demo conversation.' },
@ -167,7 +167,7 @@ const primaryNavigationSeeds: CollectionGatedNavigationItem[] = [
const footerNavigationGroupSeeds: FooterGroupSeed[] = [
{
title: 'Platform',
items: [{ href: '/product', label: 'Explore the platform' }],
items: [{ href: '/platform', label: 'Explore the platform' }],
},
{
title: 'Solutions',
@ -254,10 +254,10 @@ export const pageDefinitions: Record<SitePath, PageDefinition> = {
surfaceGroup: 'core',
inSitemap: true,
},
'/product': {
path: '/product',
canonicalPath: '/product',
pageRole: 'product',
'/platform': {
path: '/platform',
canonicalPath: '/platform',
pageRole: 'platform',
family: 'landing',
shellTone: 'brand',
priority: 'required',
@ -265,6 +265,17 @@ export const pageDefinitions: Record<SitePath, PageDefinition> = {
surfaceGroup: 'core',
inSitemap: true,
},
'/product': {
path: '/product',
canonicalPath: '/platform',
pageRole: 'product',
family: 'landing',
shellTone: 'brand',
priority: 'compatibility',
journeyStage: 'first-clarification',
surfaceGroup: 'compatibility',
inSitemap: false,
},
'/trust': {
path: '/trust',
canonicalPath: '/trust',

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +0,0 @@
---
import Callout from '@/components/content/Callout.astro';
import PageShell from '@/components/layout/PageShell.astro';
import Container from '@/components/primitives/Container.astro';
import Grid from '@/components/primitives/Grid.astro';
import Section from '@/components/primitives/Section.astro';
import SectionHeader from '@/components/primitives/SectionHeader.astro';
import CTASection from '@/components/sections/CTASection.astro';
import FeatureGrid from '@/components/sections/FeatureGrid.astro';
import PageHero from '@/components/sections/PageHero.astro';
import {
productHero,
productMetrics,
productModelBlocks,
productNarrative,
productSeo,
} from '@/content/pages/product';
---
<PageShell currentPath="/product" title={productSeo.title} description={productSeo.description}>
<PageHero
hero={productHero}
metrics={productMetrics}
calloutTitle="Connected governance model"
calloutDescription="Tenantial connects present-state inventory, immutable snapshots, restore posture, drift, exceptions, and evidence so teams can explain what happened before they decide what to do next."
/>
<FeatureGrid
eyebrow="Connected governance model"
title="Explain what the product does before asking for buyer trust."
titleHtml='Explain what the product does before asking for <span class="accent">buyer trust</span>.'
description="This page should explain how the pieces fit together so visitors do not mistake the product for a loose collection of backup, reporting, and restore features."
items={productModelBlocks}
tone="tinted"
/>
<Section tone="muted" density="base" layer="3">
<Container width="wide">
<div class="space-y-8">
<SectionHeader
eyebrow="Narrative"
title="Keep the path from product truth into trust and action readable."
description="The public product page should make it obvious how the product helps a team move from current-state understanding into trust review, visible progress, and reviewable action."
/>
<Grid cols="3">
{productNarrative.map((block) => <Callout content={block} />)}
</Grid>
</div>
</Container>
</Section>
<CTASection
eyebrow="Continue"
title="Trust review and visible progress should follow the product explanation cleanly."
description="Once the product model is clear, the next useful moves are to inspect the Trust surface, verify current progress, and start the contact path."
primary={{ href: '/changelog', label: 'Read the changelog' }}
secondary={{
href: '/contact',
label: 'Start the working session',
variant: 'secondary',
}}
/>
</PageShell>

View File

@ -2,6 +2,7 @@ export type ButtonVariant = 'primary' | 'secondary' | 'ghost';
export type PageFamily = 'landing' | 'trust' | 'content';
export type PageRole =
| 'home'
| 'platform'
| 'product'
| 'trust'
| 'changelog'
@ -14,6 +15,7 @@ export type PageRole =
| 'terms';
export type SitePath =
| '/'
| '/platform'
| '/product'
| '/trust'
| '/changelog'

View File

@ -29,7 +29,7 @@ test('core IA publishes Tenantial homepage navigation without dead template rout
const header = page.getByRole('banner');
const footer = page.getByRole('contentinfo');
await expect(header.getByRole('link', { name: 'Platform', exact: true })).toHaveAttribute('href', '/product');
await expect(header.getByRole('link', { name: 'Platform', exact: true })).toHaveAttribute('href', '/platform');
await expect(header.getByRole('link', { name: 'Solutions', exact: true })).toHaveAttribute('href', '/solutions');
await expect(header.getByRole('link', { name: 'Resources', exact: true })).toHaveAttribute('href', '/changelog');
await expect(header.getByRole('link', { name: 'Pricing', exact: true })).toHaveAttribute('href', '/contact');

View File

@ -1,6 +1,7 @@
import { expect, test } from '@playwright/test';
import {
expectCompatibilityRedirect,
expectCtaHierarchy,
expectDisclosureLayer,
expectFooterLinks,
@ -29,6 +30,32 @@ const forbiddenHomepageTerms = [
'TenantAtlas',
] as const;
const forbiddenPlatformTerms: Array<[string, RegExp]> = [
['AstroDeck', /AstroDeck/i],
['TemplateDeck', /TemplateDeck/i],
['Open Source', /Open Source/i],
['MIT', /\bMIT\b/i],
['TenantAtlas', /TenantAtlas/i],
['TenantPilot', /TenantPilot/i],
['TenantCTRL', /TenantCTRL/i],
] as const;
const unsupportedPlatformClaims = [
/SOC 2/i,
/\bISO(?:\s?\d+)?\b/i,
/HIPAA/i,
/blanket GDPR/i,
/end-to-end encryption/i,
/guaranteed recovery/i,
/guaranteed compliance/i,
/zero drift/i,
/real-time everywhere/i,
/trusted by/i,
/customer logos/i,
/Microsoft certification/i,
/Microsoft partnership/i,
] as const;
async function expectForbiddenHomepageResidueAbsent(page: import('@playwright/test').Page): Promise<void> {
const body = page.locator('body');
const metadata = await page.locator('head').evaluate((head) => {
@ -47,6 +74,24 @@ async function expectForbiddenHomepageResidueAbsent(page: import('@playwright/te
}
}
async function expectPlatformResidueAbsent(page: import('@playwright/test').Page): Promise<void> {
const body = page.locator('body');
const metadata = await page.locator('head').evaluate((head) => {
const title = document.title;
const meta = Array.from(head.querySelectorAll('meta'))
.map((element) => element.getAttribute('content') ?? '')
.join(' ');
const canonical = head.querySelector('link[rel="canonical"]')?.getAttribute('href') ?? '';
return `${title} ${meta} ${canonical}`;
});
for (const [term, pattern] of forbiddenPlatformTerms) {
await expect(body).not.toContainText(pattern);
expect(metadata, `Platform metadata should not contain ${term}`).not.toMatch(pattern);
}
}
test('home first read positions Tenantial with one clear action hierarchy', async ({ page }) => {
await visitPage(page, '/');
await expectShell(page, 'Evidence-first governance for Microsoft tenants.');
@ -68,7 +113,7 @@ test('home first read positions Tenantial with one clear action hierarchy', asyn
await expect(skipLink).toBeFocused();
});
test('homepage hero explains Tenantial, Microsoft tenant context, and required CTA routes', async ({ page }) => {
test('homepage hero explains Tenantial, Microsoft tenant context, and platform CTA route', async ({ page }) => {
await visitPage(page, '/');
await expectHomepageHeroStructure(page);
await expect(page.locator('[data-homepage-hero="true"] [data-hero-eyebrow]')).toContainText(
@ -84,7 +129,7 @@ test('homepage hero explains Tenantial, Microsoft tenant context, and required C
/backup and restore with confidence\. detect drift before it becomes audit work\. preserve snapshot history/i,
);
await expectHomepageHeroCtaPair(page, 'Book a demo', 'Explore the platform');
await expectHomepageHeroRouteTargets(page, ['/contact', '/product']);
await expectHomepageHeroRouteTargets(page, ['/contact', '/platform']);
});
test('homepage uses neutral trust statements and the six required feature pillars', async ({ page }) => {
@ -144,7 +189,7 @@ test('homepage keeps the final CTA and launch-readiness sections in order', asyn
await expect(page.locator('[data-section="cta"]')).toContainText(
'Build tenant governance on evidence, not assumptions.',
);
await expectOnwardRouteReachable(page, ['/product', '/contact']);
await expectOnwardRouteReachable(page, ['/platform', '/contact']);
});
test.describe('homepage mobile', () => {
@ -170,24 +215,177 @@ test.describe('homepage mobile', () => {
'product-near-visual',
]);
await expectHomepageHeroVisibleOnMobile(page);
await expectHomepageHeroRouteTargets(page, ['/contact', '/product']);
await expectHomepageHeroRouteTargets(page, ['/contact', '/platform']);
});
});
test('product keeps the connected operating model readable without collapsing into a feature list', async ({
page,
}) => {
await visitPage(page, '/product');
await expectShell(page, /operating model|restore posture|governance/i);
test('platform hero explains Tenantial governance model', async ({ page }) => {
await visitPage(page, '/platform');
await expectShell(page, /govern Microsoft tenants through evidence/i);
await expectPageFamily(page, 'landing');
await expectDisclosureLayer(page, '1');
await expectDisclosureLayer(page, '2');
await expectPrimaryNavigation(page);
await expectNavigationVsCtaDifferentiation(page);
await expectFooterLinks(page);
await expect(
page.getByRole('heading', { name: 'Explain what the product does before asking for buyer trust.' }),
).toBeVisible();
await expectCtaHierarchy(page, 'Review the trust posture', 'Start the working session');
await expect(page.getByRole('main').getByRole('link', { name: 'Read the changelog' }).first()).toBeVisible();
const main = page.getByRole('main');
await expect(main.locator('[data-hero-eyebrow]').first()).toContainText(/TENANTIAL PLATFORM/i);
await expect(page.getByRole('heading', { level: 1 })).toHaveCount(1);
await expect(page.getByRole('heading', { level: 1 })).toContainText(
/govern Microsoft tenants through evidence/i,
);
await expect(main.locator('[data-hero-supporting-copy]').first()).toContainText(/backup records/i);
await expect(main.locator('[data-hero-supporting-copy]').first()).toContainText(/configuration drift/i);
await expect(main.locator('[data-hero-supporting-copy]').first()).toContainText(/structured reviews/i);
await expectCtaHierarchy(page, 'Book a demo', 'See the governance loop');
await expect(main.locator('a[href="/contact"]').filter({ hasText: 'Book a demo' }).first()).toBeVisible();
await expect(main.locator('a[href="#governance-loop"]').filter({ hasText: 'See the governance loop' }).first()).toBeVisible();
await expect(main.locator('[data-platform-dashboard-preview]').first()).toBeVisible();
await expect(main.locator('[data-platform-dashboard-preview]').first()).toContainText(/Governance overview/i);
await expect(main.locator('[data-platform-dashboard-preview]').first()).toContainText(/Static demo preview/i);
await expect(main.locator('[data-platform-dashboard-preview]').first()).toContainText(/Evidence spotlight/i);
for (const signal of [
'Microsoft tenant focused',
'Evidence-oriented workflows',
'Reviewable decisions',
'Operator-led governance',
]) {
await expect(main.locator('[data-hero-trust-subclaims]').getByText(signal, { exact: true })).toBeVisible();
}
});
test('platform metadata is Tenantial clean', async ({ page }) => {
await visitPage(page, '/platform');
await expect(page).toHaveTitle(/Tenantial Platform/i);
await expect(page).toHaveTitle(/Evidence-first governance/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /backup/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /restore/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /drift detection/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /findings/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /evidence/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /audit trails/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /exceptions/i);
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /reviews/i);
await expect(page.locator('link[rel="canonical"]')).toHaveAttribute('href', /\/platform$/);
await expectPlatformResidueAbsent(page);
});
test('platform governance flow explains reviewable evidence', async ({ page }) => {
await visitPage(page, '/platform');
const operatingModel = page.locator('[data-section="operating-model"]');
const governanceLoop = page.locator('[data-section="governance-loop"]');
await expect(operatingModel).toBeVisible();
await expect(operatingModel.locator('[data-operating-flow]')).toBeVisible();
for (const step of ['Snapshot', 'Drift', 'Finding', 'Review', 'Evidence', 'Audit trail']) {
await expect(operatingModel.getByText(step, { exact: true })).toBeVisible();
}
await expect(governanceLoop).toBeVisible();
await expect(governanceLoop.locator('[data-governance-loop-diagram]')).toBeVisible();
for (const label of [
'Source of truth',
'Snapshot',
'Diff',
'Finding',
'Exception',
'Review',
'Evidence',
'Audit trail',
]) {
await expect(governanceLoop.getByText(label, { exact: true })).toBeVisible();
}
await expect(governanceLoop).toContainText(/operator reviews/i);
await expect(governanceLoop).toContainText(/evidence/i);
await expect(governanceLoop).toContainText(/auditability/i);
});
test('platform governance flow avoids automation guarantees', async ({ page }) => {
await visitPage(page, '/platform');
await expect(page.locator('body')).not.toContainText(
/automatic remediation|guaranteed recovery|live device actions|real-time tenant operations/i,
);
});
test('platform capabilities cover governance primitives', async ({ page }) => {
await visitPage(page, '/platform');
const capabilities = page.locator('[data-section="platform-capabilities"]');
await expect(capabilities).toBeVisible();
await expect(capabilities.locator('[data-capability-system-grid]')).toBeVisible();
await expect(capabilities.locator('[data-capability-primary]')).toBeVisible();
await expect(capabilities.getByRole('heading', { name: 'Backup & Restore', exact: true })).toBeVisible();
for (const capability of [
'Drift Detection',
'Findings',
'Evidence',
'Audit Trail',
'Exceptions',
'Governance Reviews',
]) {
await expect(capabilities.getByRole('heading', { name: capability, exact: true })).toBeVisible();
}
});
test('platform boundaries keep claims conservative', async ({ page }) => {
await visitPage(page, '/platform');
const boundaries = page.locator('[data-section="platform-boundaries"]');
await expect(boundaries).toBeVisible();
await expect(boundaries).toContainText(/Built for governance of record/i);
await expect(boundaries).toContainText(/do not take actions on your behalf/i);
await expect(boundaries).toContainText(/do not manage devices/i);
await expect(boundaries).toContainText(/do not replace your ITSM/i);
await expect(boundaries).toContainText(/support reviewable decisions/i);
for (const claim of unsupportedPlatformClaims) {
await expect(page.locator('body')).not.toContainText(claim);
}
});
test.describe('platform mobile', () => {
test.use({ viewport: { width: 390, height: 844 } });
test('platform mobile layout stays readable without overflow', async ({ page }) => {
await visitPage(page, '/platform');
await expectMobileReadability(page);
await expectNoBodyHorizontalOverflow(page);
await expect(page.locator('[data-section="platform-capabilities"]').first()).toBeVisible();
await expect(page.locator('[data-section="platform-boundaries"]').first()).toBeVisible();
await expect(page.locator('[data-section="platform-capabilities"]').first()).toContainText(/Backup/i);
await expect(page.locator('[data-truth-layer-stack]').first()).toBeVisible();
await expect(page.locator('[data-governance-loop-diagram]').first()).toBeVisible();
await expect(page.locator('[data-section="platform-boundaries"]').first()).toContainText(/governance of record/i);
expect(await page.locator('[data-color-meaning="with-text"]').count()).toBeGreaterThan(0);
});
});
test('primary navigation and footer point Platform links to platform', async ({ page }) => {
await visitPage(page, '/platform');
await expectPrimaryNavigation(page);
await expectFooterLinks(page);
await expect(page.getByRole('contentinfo')).toHaveAttribute('data-footer-intent', 'quiet');
await expect(page.locator('[data-section="platform-final-cta"]')).toBeVisible();
await expect(page.getByRole('contentinfo')).not.toContainText(/Build tenant governance on evidence/i);
});
test('product redirects to platform', async ({ page }) => {
await expectCompatibilityRedirect(page, '/product', '/platform');
await expect(page.locator('body')).not.toContainText(
/AstroDeck|TemplateDeck|Open Source|MIT Licensed|TenantAtlas|TenantPilot|TenantCTRL/i,
);
});

View File

@ -1,6 +1,6 @@
import { expect, type Page } from '@playwright/test';
export const coreRoutePaths = ['/', '/product', '/trust', '/changelog', '/contact', '/privacy', '/imprint'] as const;
export const coreRoutePaths = ['/', '/platform', '/trust', '/changelog', '/contact', '/privacy', '/imprint'] as const;
export const secondaryRoutePaths = ['/legal', '/terms', '/solutions', '/integrations'] as const;
export const primaryNavigationLabels = ['Platform', 'Solutions', 'Resources', 'Pricing', 'Company'] as const;
@ -55,7 +55,7 @@ export async function expectPageFamily(page: Page, family: 'content' | 'landing'
export async function expectPrimaryNavigation(page: Page): Promise<void> {
const header = page.getByRole('banner');
const expectedRoutes: Record<(typeof primaryNavigationLabels)[number], string> = {
Platform: '/product',
Platform: '/platform',
Solutions: '/solutions',
Resources: '/changelog',
Pricing: '/contact',
@ -84,13 +84,22 @@ export async function expectPrimaryNavigation(page: Page): Promise<void> {
export async function expectFooterLinks(page: Page): Promise<void> {
const footer = page.getByRole('contentinfo');
const expectedRoutes: Partial<Record<(typeof footerLabels)[number], string>> = {
'Explore the platform': '/platform',
};
for (const label of footerGroupLabels) {
await expect(footer.getByText(label, { exact: true }).first()).toBeVisible();
}
for (const label of footerLabels) {
await expect(footer.getByRole('link', { name: label, exact: true }).first()).toBeVisible();
const link = footer.getByRole('link', { name: label, exact: true }).first();
await expect(link).toBeVisible();
if (expectedRoutes[label]) {
await expect(link).toHaveAttribute('href', expectedRoutes[label]);
}
}
for (const label of hiddenFooterLabels) {

View File

@ -0,0 +1,38 @@
# Specification Quality Checklist: Tenantial Platform Page
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-05-18
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Validation iteration 1 passed.
- No clarification markers remain.
- Route, repository boundary, and proof-command references are retained because the active Spec Kit and repository workflow require them; the feature requirements avoid HOW-level implementation choices such as component structure, framework internals, APIs, databases, or code design.
- Review outcome class: `acceptable-special-case`.
- Workflow outcome: `keep`.

View File

@ -0,0 +1,92 @@
openapi: 3.1.0
info:
title: Tenantial Platform Public Route Contract
version: 0.1.0
description: >
Static public website route contract for Spec 401. These are HTML page
routes, not backend application APIs.
servers:
- url: https://tenantial.example
paths:
/platform:
get:
summary: Render the canonical Tenantial Platform page
operationId: getTenantialPlatformPage
tags:
- Public Website
responses:
"200":
description: Canonical Platform page renders successfully.
content:
text/html:
schema:
type: string
examples:
requiredContent:
summary: Required visible content signals
value: >
TENANTIAL PLATFORM. Govern Microsoft tenants through
evidence, drift context, and reviewable decisions.
x-route-contract:
canonicalPath: /platform
sitemap: true
requiredVisibleText:
- TENANTIAL PLATFORM
- Govern Microsoft tenants through evidence
- Backup
- Restore
- Drift Detection
- Findings
- Evidence
- Audit Trail
- Exceptions
- Governance Reviews
- Built for governance of record
forbiddenVisibleText:
- AstroDeck
- TemplateDeck
- Open Source
- MIT
- TenantAtlas
- TenantPilot
- TenantCTRL
requiredMetadata:
titleIncludes:
- Tenantial Platform
- Evidence-first governance
descriptionIncludes:
- backup
- restore
- drift detection
- findings
- evidence
- audit trails
- exceptions
- reviews
requiredAccessibility:
onePrimaryHeading: true
keyboardAccessibleCtas: true
noColorOnlyMeaning: true
noBodyHorizontalOverflow: true
/product:
get:
summary: Redirect product route compatibility to the canonical Platform page
operationId: getProductCompatibilityRoute
tags:
- Public Website
responses:
"301":
description: Compatibility route redirects permanently to /platform.
"302":
description: Compatibility route redirects temporarily to /platform if the current static build cannot emit a permanent redirect.
x-route-contract:
canonicalPath: /platform
primaryNavigationTarget: false
allowedBehaviors:
- redirectToPlatform
forbiddenBehavior:
- renderEquivalentPlatformContentWithCanonicalPlatformMetadata
- exposeStaleProductCopy
- exposeConflictingCanonicalMetadata
- remainPrimaryPlatformNavigationTarget
smokeCoverageRequired: true

View File

@ -0,0 +1,268 @@
# Data Model: Tenantial Platform Page
This feature uses static public website content only. The "entities" below are content models and route contracts, not database tables or persisted application records.
## Platform Page
**Purpose**: Canonical public route that explains Tenantial's evidence-first governance platform.
**Fields**:
- `path`: `/platform`
- `canonicalPath`: `/platform`
- `title`: Tenantial Platform page title
- `description`: SEO description covering backup, restore, drift detection, findings, evidence, audit trails, exceptions, and reviews
- `hero`: Platform Hero content
- `operatingModelSteps`: ordered list of Operating Model Steps
- `capabilities`: list of Capability items
- `governanceLoop`: Governance Loop content
- `truthLayers`: optional list of Truth Layer items
- `operatorWorkflows`: optional list of Operator Workflow items
- `platformBoundary`: Platform Boundary content
- `finalCta`: CTA content
**Validation rules**:
- `path` must be `/platform`.
- Page must have exactly one primary heading.
- Metadata must use Tenantial branding and must not contain stale public brand/template terms.
- Page must not depend on tenant data, customer data, platform APIs, auth state, Microsoft Graph, or backend fetches.
- Page must include required sections from the spec: hero, operating model overview, capability grid, governance loop, platform boundaries, final CTA, and footer.
**Relationships**:
- Links from homepage secondary CTA.
- Links from header Platform navigation.
- Links from footer Platform navigation.
- May be reached from `/product` only through redirect compatibility.
**State transitions**: N/A - static route content.
## Platform Hero
**Purpose**: First viewport explanation of what Tenantial is and why the visitor is on this page.
**Fields**:
- `eyebrow`: "TENANTIAL PLATFORM" or equivalent
- `headline`: product-specific governance headline
- `description`: backup, drift, findings, evidence, audit trail, and reviews in one operating loop
- `primaryCta`: "Book a demo" linking to the current intentional conversion route
- `secondaryCta`: "See the governance loop" linking to the relevant page section
- `visual`: large static dashboard/product preview
**Validation rules**:
- Must be understandable in the first viewport.
- Must use a split layout where the product preview is the dominant visual anchor.
- Must not duplicate homepage hero copy exactly.
- Must not imply live tenant data.
- Must keep "Book a demo" primary.
**Relationships**:
- References Governance Loop via secondary CTA.
- Uses Platform Page metadata and shell.
**State transitions**: N/A.
## Operating Model Step
**Purpose**: Explain the operator-led governance sequence.
**Fields**:
- `label`: step name
- `description`: plain-language explanation
- `order`: numeric display order
**Required ordered values**:
1. Snapshot
2. Drift
3. Finding
4. Review
5. Evidence
6. Audit trail
**Validation rules**:
- Steps must render as a compact connected sequence on desktop.
- Steps must stack or simplify on mobile.
- Copy must avoid implying automatic remediation.
**Relationships**:
- Supports Platform Hero and Governance Loop.
**State transitions**: N/A.
## Capability
**Purpose**: Describe a core Tenantial platform capability in a grouped section with one larger primary block and smaller supporting cards.
**Fields**:
- `title`: capability name
- `description`: concise public explanation
- `icon`: optional decorative icon identifier
**Required values**:
- Backup & Restore
- Drift Detection
- Findings
- Evidence
- Audit Trail
- Exceptions
- Governance Reviews
**Validation rules**:
- One primary Backup & Restore block and 6 supporting capability cards should render.
- Descriptions must not claim guaranteed compliance, guaranteed recovery, full automation, zero drift, or real-time coverage.
- Icons are decorative unless explicitly labelled.
**Relationships**:
- Belongs to Platform Page capability grid.
**State transitions**: N/A.
## Governance Loop
**Purpose**: Show how configuration change becomes reviewable evidence.
**Fields**:
- `headline`: section heading
- `description`: public explanation of why context and evidence matter
- `steps`: ordered loop labels
**Required loop labels**:
- Source of truth
- Snapshot
- Diff
- Finding
- Exception
- Review
- Evidence
- Audit trail
**Validation rules**:
- Must be shown as a connected visual diagram, not only a text grid.
- Must make operator review explicit.
- Must make evidence preservation explicit.
- Must make auditability explicit.
- Must not imply live remediation or device actions.
**Relationships**:
- Referenced by Platform Hero secondary CTA.
- Connects Operating Model Steps and Capability items.
**State transitions**: N/A.
## Truth Layer
**Purpose**: Explain that different forms of product truth are not collapsed into one misleading status.
**Fields**:
- `title`: layer name
- `description`: plain-language explanation
**Expected values**:
- Execution Truth
- Artifact Truth
- Backup Truth
- Recovery Evidence
- Operator Next Action
**Validation rules**:
- Must be understandable to IT leaders and operators.
- Must avoid claiming perfect knowledge of all external systems.
- Must not create a runtime status taxonomy.
**Relationships**:
- Optional section on Platform Page.
**State transitions**: N/A.
## Operator Workflow
**Purpose**: Help target audiences recognize how they would use the platform.
**Fields**:
- `audience`: target audience label
- `description`: short workflow statement
**Expected audiences**:
- MSP Operator
- Enterprise IT
- Security Reviewer
- Compliance / Audit Stakeholder
**Validation rules**:
- Copy must be short and conservative.
- Must not include fake logos, named customer claims, or unverified proof.
**Relationships**:
- Optional section on Platform Page.
**State transitions**: N/A.
## Platform Boundary
**Purpose**: Prevent misunderstanding of Tenantial's role.
**Fields**:
- `headline`: boundary statement
- `description`: what Tenantial is designed for and what it is not replacing
**Validation rules**:
- Must clarify governance of record and recovery context.
- Must state that Tenantial does not take actions on the customer's behalf, does not manage devices, does not replace ITSM/SIEM/ticketing/Microsoft admin centers, and supports reviewable decisions.
- Must remain sales-friendly and not hostile.
**Relationships**:
- Required section on Platform Page.
**State transitions**: N/A.
## Product Compatibility Route
**Purpose**: Keep existing `/product` route reachable without exposing stale or conflicting public content.
**Fields**:
- `path`: `/product`
- `canonicalPath`: `/platform`
- `behavior`: redirect to `/platform`
- `sitemap`: excluded when treated as compatibility
**Validation rules**:
- Must not expose inconsistent or stale public product copy.
- Must not render equivalent page content at `/product`.
- Must not remain the primary Platform navigation target.
- Must be covered by smoke tests if retained.
**Relationships**:
- Compatibility route for historical links.
- Canonical route is Platform Page.
**State transitions**: N/A.

View File

@ -0,0 +1,193 @@
# Implementation Plan: Tenantial Platform Page
**Branch**: `feat/401-tenantial-platform-page` | **Date**: 2026-05-18 | **Spec**: [/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/spec.md](/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/spec.md)
**Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/spec.md`
## Summary
Create a canonical public Tenantial Platform page at `/platform` inside the standalone Astro website. The implementation should reuse the Spec 400 public visual direction and existing website shell/content primitives, move homepage/header/footer Platform links to `/platform`, and treat the current `/product` page as redirect-only compatibility to the canonical Platform page. The follow-up visual refactor tightens the page around the supplied mockup target: split hero with large static dashboard preview, compact connected Operating Model, central Governance Loop diagram, asymmetric Capabilities, visual Truth Layers, warmer Operator Workflows, clear Boundaries band, focused CTA, and quiet footer. The feature remains static website content with route smoke coverage; it introduces no Laravel platform runtime behavior, no backend API, no database changes, no authentication, and no Microsoft Graph integration.
## Technical Context
**Language/Version**: TypeScript 5.9.3 and Astro 6.0.0 in `apps/website`; Node >=20.0.0 via workspace package metadata.
**Primary Dependencies**: Astro, Tailwind CSS v4.2.2 through `@tailwindcss/vite`, `astro-icon`, `@iconify-json/lucide`, Playwright smoke tests.
**Storage**: N/A - static website content only; no database, CMS, API, customer data, tenant data, or runtime persistence.
**Testing**: Playwright smoke tests in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke`; website build through root `build:website`.
**Validation Lanes**: Browser lane plus static build and whitespace diff check.
**Target Platform**: Static public Astro website under `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website`.
**Project Type**: Monorepo with standalone website app and separate Laravel platform app; this feature is website-only.
**Performance Goals**: Static page remains mostly HTML/CSS, uses no backend fetches, no platform API calls, no tracking scripts, and no unapproved large raster screenshots.
**Constraints**: Preserve root pnpm script names, `WEBSITE_PORT` convention, internal package name, public Tenantial brand, Spec 400 visual system, mobile readability, keyboard access, and no body-level horizontal overflow.
**Scale/Scope**: One canonical public route (`/platform`), one redirect-only compatibility route for `/product`, shared navigation/footer link updates, route metadata, focused smoke assertions, and website-only visual composition updates for `/platform`.
## UI / Surface Guardrail Plan
- **Guardrail scope**: No operator-facing admin surface change; public website marketing surface only.
- **Native vs custom classification summary**: N/A for Filament/admin nativity. Website work should reuse existing Astro website primitives and section components where they fit.
- **Shared-family relevance**: None for shared operator interaction families.
- **State layers in scope**: Public website shell, page route, static page content, route metadata.
- **Audience modes in scope**: Public buyer/stakeholder audience only; no customer/read-only, operator/MSP admin mode, or support/platform mode.
- **Decision/diagnostic/raw hierarchy plan**: Public product explanation first; no diagnostics or raw evidence surfaces.
- **Raw/support gating plan**: N/A - no raw/support evidence is shown.
- **One-primary-action / duplicate-truth control**: "Book a demo" remains the dominant conversion CTA; "See the governance loop" is a subordinate in-page learning action.
- **Handling modes by drift class or surface**: N/A.
- **Repository-signal treatment**: Report-only for public website route/content smoke; no admin guardrail signals.
- **Special surface test profiles**: N/A.
- **Required tests or manual smoke**: Website smoke tests for `/platform`, homepage/header/footer route intent, `/product` compatibility, forbidden residue, visual structure signals, quiet footer behavior, and mobile overflow.
- **Exception path and spread control**: None.
- **Active feature PR close-out entry**: Smoke Coverage.
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: No for operator shared interaction classes.
- **Systems touched**: Public website shell, public navigation, public footer, page definitions, static content, and smoke tests.
- **Shared abstractions reused**: Existing website content modules in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages`, shared shell in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/components/layout`, and page/section primitives in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/components`.
- **New abstraction introduced? why?**: None planned. Page-local arrays and existing typed content shapes are sufficient.
- **Why the existing abstraction was sufficient or insufficient**: Existing PageShell, navigation, content modules, SEO helpers, primitives, and smoke helpers already support static public pages.
- **Bounded deviation / spread control**: If a new visual section is needed for the governance loop, keep it page-local or a narrow website section component; do not create a generic governance UI framework.
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: No.
- **Central contract reused**: N/A.
- **Delegated UX behaviors**: N/A.
- **Surface-owned behavior kept local**: N/A.
- **Queued DB-notification policy**: N/A.
- **Terminal notification path**: N/A.
- **Exception path**: None.
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: No.
- **Provider-owned seams**: N/A.
- **Platform-core seams**: N/A.
- **Neutral platform terms / contracts preserved**: Runtime provider/platform contracts are untouched.
- **Retained provider-specific semantics and why**: Public copy may refer to Microsoft tenant environments because the product positioning requires it; this does not change runtime provider abstractions.
- **Bounded extraction or follow-up path**: None.
## Constitution Check
*GATE: Passed before Phase 0 research and re-checked after Phase 1 design, with explicit repository-wide PHP/Pest/Pint close-out commands documented for finalization.*
- Inventory-first: N/A - no Inventory, snapshot, backup, or tenant runtime state changes.
- Read/write separation: Pass - public website content only; no write/change behavior.
- Graph contract path: Pass - no Microsoft Graph calls or contract registry changes.
- Deterministic capabilities: N/A - no capability derivation changes.
- RBAC-UX and workspace/tenant isolation: Pass - no `/admin`, `/system`, tenant, workspace, global search, policy, capability, or authorization changes.
- Destructive confirmations: N/A - no destructive actions.
- Run observability and OperationRun UX: Pass - no queued, scheduled, long-running, remote, or operational action.
- Automation: N/A - no queued or scheduled operations.
- Data minimization: Pass - no customer, tenant, Microsoft API, tracking, or runtime data is introduced.
- Test governance: Pass - Browser classification and smoke coverage are explicit, website-scoped, and avoid platform fixtures. Repository-wide Pest and Pint gates are covered as close-out commands, not as additional feature proof.
- Proportionality: Pass - one public route/content slice; no persisted truth, domain state, abstraction, enum, status, resolver, registry, or taxonomy.
- No premature abstraction / few layers: Pass - reuse existing website content/shell components; keep any new page sections narrow.
- Persisted truth / behavioral state: Pass - no persistence or behavioral state.
- UI semantics / badge semantics: Pass - no admin status semantics; public labels stay descriptive.
- Shared pattern first: Pass - no shared operator interaction family touched; website shell patterns are reused.
- Provider boundary: Pass - public Microsoft tenant wording does not touch platform-core seams.
- Filament-native UI and Filament Action Surface Contract: N/A - no Filament, Blade admin, Livewire, Resource, RelationManager, or Page changes.
- Decision-first / audience-aware operator disclosure: N/A - no operator-facing admin detail/status surface.
- UI review workflow: Pass - plan keeps the spec's `no operator-facing surface change` classification.
### Post-Design Constitution Check
Phase 0 and Phase 1 design artifacts preserve the same decisions: static website-only scope, no backend/API/runtime coupling, no new persistence, no new abstractions, and browser smoke validation as the feature proof. Repository-wide Pest and Pint close-out commands are explicit, so no unresolved gate violations remain.
## Test Governance Check
- **Test purpose / classification by changed surface**: Browser for public website route, navigation, metadata, copy safety, and responsive behavior.
- **Affected validation lanes**: browser.
- **Why this lane mix is the narrowest sufficient proof**: The feature is a static public page. Playwright route/content checks plus build validation prove user-visible route behavior without Laravel, database, workspace, tenant, provider, or session setup.
- **Narrowest proving command(s)**: `corepack pnpm build:website`; `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke`; `git diff --check`; desktop and mobile browser screenshot review.
- **Repository-wide constitution close-out**: Run `cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail artisan test --compact tests/Deprecation/IsPlatformSuperadminDeprecationTest.php` and `cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail bin pint --dirty` before finalizing. These commands satisfy the repository-wide gate without adding platform fixtures or treating Laravel behavior as the feature proof.
- **Fixture / helper / factory / seed / context cost risks**: None.
- **Expensive defaults or shared helper growth introduced?**: No.
- **Heavy-family additions, promotions, or visibility changes**: None beyond existing website smoke family.
- **Surface-class relief / special coverage rule**: N/A.
- **Closing validation and reviewer handoff**: Reviewers should confirm smoke coverage remains website-scoped and asserts `/platform`, homepage CTA route, header/footer route, `/product` compatibility, old public-brand residue absence, claim safety, and mobile overflow.
- **Budget / baseline / trend follow-up**: None expected.
- **Review-stop questions**: Stop if tests require platform services, hidden fixtures, backend auth, database, broad browser families, or unbounded visual regression scope.
- **Escalation path**: document-in-feature.
- **Active feature PR close-out entry**: Smoke Coverage.
- **Why no dedicated follow-up spec is needed**: The smoke expansion is feature-local and does not create recurring test-lane cost or new infrastructure.
## Project Structure
### Documentation (this feature)
```text
/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/
|-- plan.md
|-- research.md
|-- data-model.md
|-- quickstart.md
|-- contracts/
| `-- public-routes.openapi.yaml
|-- checklists/
| `-- requirements.md
`-- tasks.md # created later by /speckit.tasks
```
### Source Code (repository root)
```text
/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/
|-- package.json
|-- src/
| |-- components/
| | |-- content/
| | |-- layout/
| | |-- primitives/
| | `-- sections/
| |-- content/pages/
| | |-- home.ts
| | |-- platform.ts # static page content and visual-section copy
| | `-- product.ts # planned stale-content retirement path
| |-- lib/
| | |-- seo.ts
| | `-- site.ts
| |-- pages/
| | |-- index.astro
| | |-- platform.astro # canonical route and mockup-aligned visual composition
| | `-- product.astro # planned redirect compatibility route
| |-- styles/
| `-- types/
`-- tests/smoke/
|-- home-product.spec.ts # planned update or split
`-- smoke-helpers.ts # planned route expectations update
```
**Structure Decision**: Use the existing standalone Astro website structure under `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website`. Keep content in typed page content modules, render through existing layout and section primitives, and extend existing smoke tests instead of adding a second website architecture.
## Complexity Tracking
No constitution violations or BLOAT-001-triggering runtime complexity are introduced.
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| None | N/A | N/A |
## Proportionality Review
- **Current operator problem**: Public buyers and stakeholders cannot yet understand Tenantial's platform operating model from a dedicated page after the homepage.
- **Existing structure is insufficient because**: The homepage introduces the promise, while existing `/product` copy is not the canonical `/platform` journey and still leaves route confusion.
- **Narrowest correct implementation**: One canonical static `/platform` page, route/navigation alignment, `/product` redirect compatibility, metadata, and focused smoke checks.
- **Ownership cost created**: One additional public page, static content maintenance, route compatibility expectations, and a small smoke-test expansion.
- **Alternative intentionally rejected**: Build pricing, trust center, CMS, i18n, live screenshots, backend integration, or platform runtime hooks in this slice.
- **Release truth**: Current public website truth.
## Phase 0 Research
See [/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/research.md](/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/research.md).
## Phase 1 Design
See:
- [/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/data-model.md](/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/data-model.md)
- [/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/contracts/public-routes.openapi.yaml](/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/contracts/public-routes.openapi.yaml)
- [/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/quickstart.md](/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/quickstart.md)
## Phase 2 Planning Boundary
This `/speckit.plan` run stops after Phase 2 planning artifacts. Implementation tasks are intentionally left for `/speckit.tasks`.

View File

@ -0,0 +1,90 @@
# Quickstart: Tenantial Platform Page
## Prerequisites
- Work from `/Users/ahmeddarrazi/Documents/projects/wt-website`.
- Use branch `feat/401-tenantial-platform-page`.
- Keep scope limited to `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website` and this feature spec directory.
- Do not modify `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform` for this feature.
## Implementation Outline
1. Verify the current website route structure:
```bash
find apps/website/src/pages -maxdepth 1 -type f | sort
```
2. Add the canonical Platform route:
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
3. Update website route and navigation definitions:
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/types/site.ts`
4. Update homepage Platform CTA destinations:
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/home.ts`
5. Handle `/product` compatibility:
- Redirect `/product` to `/platform`.
- Retire or stop importing stale `/product` page content so the route cannot render conflicting public copy.
6. Add or update smoke coverage:
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/smoke-helpers.ts`
## Validation Commands
Run from `/Users/ahmeddarrazi/Documents/projects/wt-website`:
```bash
corepack pnpm build:website
WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke
git diff --check
```
Also review desktop and mobile screenshots for the mockup-aligned visual structure: split hero with dashboard preview, compact Operating Model flow, connected Governance Loop diagram, asymmetric Capabilities, Truth Layers visual, warmer Operator Workflows, Boundaries band, focused CTA, and quiet footer.
Before finalizing, also run the repository-wide constitution Quality Gates without treating Laravel behavior as the feature proof:
```bash
cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail artisan test --compact tests/Deprecation/IsPlatformSuperadminDeprecationTest.php
cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail bin pint --dirty
```
## Manual Review Checklist
- `/platform` renders the Tenantial Platform page.
- First viewport explains evidence-first governance for Microsoft tenants and includes a large static dashboard/product preview.
- Operating Model renders as a compact connected flow: Snapshot, Drift, Finding, Review, Evidence, Audit trail.
- Capability section uses a larger Backup & Restore block plus Drift Detection, Findings, Evidence, Audit Trail, Exceptions, and Governance Reviews.
- Governance loop renders as a connected diagram and makes operator review, evidence preservation, and auditability explicit.
- Truth Layers render as a layer-stack or equivalent visual model.
- Operator Workflow cards are compact and visually warmer than the main control-room sections.
- Platform boundaries state that Tenantial is not a helpdesk action tool, live device action tool, SIEM, or Microsoft admin center replacement.
- Final CTA and footer do not create two equally heavy closing CTA zones.
- Homepage "Explore the platform" reaches `/platform`.
- Header and footer Platform links reach `/platform`.
- `/product`, if retained, redirects to `/platform` and does not expose stale or conflicting public copy.
- Page metadata uses Tenantial branding and canonical `/platform`.
- No visible or metadata occurrences of AstroDeck, TemplateDeck, Open Source, MIT, TenantAtlas, TenantPilot, or TenantCTRL.
- No unsupported claims: SOC 2, ISO, HIPAA, blanket GDPR, guaranteed recovery, guaranteed compliance, zero drift, real-time everywhere, named customers, Microsoft certification, or Microsoft partnership.
- Mobile, tablet, desktop, and wide desktop review show no body-level horizontal overflow.
- Links and CTAs are keyboard-accessible and have visible focus states.
## Out-of-Scope Checks
Stop and return to planning if implementation appears to require:
- Laravel, Filament, Livewire, or Blade admin changes.
- Database migrations, persisted entities, queues, workers, or schedules.
- Microsoft Graph calls or platform API calls.
- Authentication, sessions, account creation, or demo-booking backend logic.
- Third-party tracking scripts or external embeds.
- Real customer screenshots, tenant identifiers, customer logos, certifications, or partnership claims.

View File

@ -0,0 +1,100 @@
# Phase 0 Research: Tenantial Platform Page
## Decision: Keep the feature inside the standalone Astro website
**Rationale**: The active spec is public website-only. The repository already has a standalone Astro app at `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website` with typed content modules, reusable layout components, Tailwind v4 styling, SEO helpers, and Playwright smoke tests. Keeping the work there preserves the boundary from the Laravel platform app.
**Alternatives considered**:
- Change `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform`: rejected because the spec excludes Laravel, Filament, Livewire, auth, APIs, database, queues, and runtime tenant data.
- Add a separate website package or docs system: rejected because the existing Astro website already supports the needed static route and public shell.
## Decision: Make `/platform` the canonical route
**Rationale**: The feature is explicitly a Tenantial Platform page and Spec 400 created an "Explore the platform" journey. A canonical `/platform` route is clearer for buyers than retaining `/product` as the primary destination.
**Alternatives considered**:
- Keep `/product` as primary: rejected because the spec asks for `/platform` and the current homepage CTA should become a clean platform journey.
- Remove `/product` immediately with no compatibility: rejected because the route already exists and current tests/navigation may still reference it during the transition.
## Decision: Treat `/product` as redirect-only compatibility
**Rationale**: The current repository has `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/product.astro` and `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/product.ts`. The narrowest safe path is to keep `/product` reachable while preventing stale or conflicting copy by redirecting it to `/platform`. This avoids maintaining two renderable public product pages or duplicate metadata during the transition.
**Alternatives considered**:
- Leave `/product` unchanged: rejected because it would create route confusion and keep homepage/platform semantics split.
- Delete `/product` in the same slice: rejected because it can break existing public links and smoke tests without adding product value.
- Render equivalent Platform content at `/product`: rejected because it keeps a second renderable product page and makes metadata/canonical drift more likely than redirect-only compatibility.
## Decision: Store Platform page content in a typed static content module
**Rationale**: Existing public pages use `apps/website/src/content/pages/*.ts` to hold SEO and page content, then render through `apps/website/src/pages/*.astro`. A new `platform.ts` content module matches the current pattern and keeps static copy centralized without adding a CMS or new data source.
**Alternatives considered**:
- Put all copy inline in `platform.astro`: rejected because it would diverge from current website content conventions.
- Add a CMS or content collection for the Platform page: rejected because the spec excludes CMS complexity.
## Decision: Reuse existing website shell, primitives, and section components first
**Rationale**: Existing components already cover PageShell, Navbar, Footer, PageHero, FeatureGrid, CTASection, Section, Container, Grid, Card, Badge, and CTA primitives. Reusing them keeps Spec 401 aligned with Spec 400 and avoids a parallel public-site component language.
**Alternatives considered**:
- Create a full new Platform page component system: rejected as unnecessary abstraction for one route.
- Use a large raster screenshot as the primary visual: rejected because no approved Tenantial product screenshot exists and the spec prohibits fake live data.
## Decision: Use static diagrams and structured panels for the platform model
**Rationale**: The page needs to explain operating model, governance loop, truth layers, and boundaries without implying live tenant data. Static HTML/CSS/SVG-like structure or existing panel/card components can communicate the model accessibly and keep performance simple.
**Alternatives considered**:
- Use real tenant screenshots: rejected because no approved customer or tenant environment assets are available.
- Use heavy animation or diagram libraries: rejected because the spec requires mostly static content and no unnecessary client-side JavaScript.
## Decision: Update site route definitions and navigation metadata
**Rationale**: `apps/website/src/lib/site.ts` owns primary navigation, footer navigation, route definitions, canonical routes, and sitemap inclusion. Adding `/platform` there keeps header/footer/sitemap/canonical behavior consistent with current site conventions.
**Alternatives considered**:
- Hardcode `/platform` only in page files: rejected because header/footer and smoke helpers would remain inconsistent.
- Add a second route registry: rejected as needless parallel state.
## Decision: Keep "Book a demo" pointed at the existing contact route
**Rationale**: The current public conversion path is `/contact`, and the spec excludes a demo-booking backend. Reusing `/contact` keeps CTA behavior intentional and avoids fake form behavior.
**Alternatives considered**:
- Create `/demo` or `/pricing`: rejected because those pages/flows are out of scope.
- Use a dead placeholder link: rejected because the spec requires intentional, working CTA destinations.
## Decision: Expand website smoke coverage and explicitly close repository-wide gates
**Rationale**: The feature changes a public static route, navigation, metadata, copy safety, and responsive behavior. Existing Playwright smoke tests are the correct feature proof surface. No new Laravel/Pest/database/Filament product test should be introduced because no platform behavior changes. Repository-wide close-out still runs a targeted existing Pest hygiene check plus Pint dirty formatting before finalization.
**Alternatives considered**:
- Add platform feature tests: rejected because they would introduce unrelated setup and false confidence for a website-only route.
- Add broad visual regression infrastructure: rejected because this feature only needs focused route/content/mobile smoke coverage.
## Decision: Preserve conservative public claim boundaries
**Rationale**: Tenantial's public trust depends on avoiding unsupported claims. The page should use language such as evidence-oriented, reviewable decisions, recovery context, operator confirmation, and traceable records while avoiding certifications, guarantees, named customers, Microsoft endorsement, and real-time claims unless approved evidence exists.
**Alternatives considered**:
- Use stronger enterprise proof language for sales impact: rejected because unsupported claims create trust and compliance risk.
- Omit boundaries entirely: rejected because the page must clarify that Tenantial is not a helpdesk, SIEM, device action tool, or Microsoft admin center replacement.
## Decision: No unresolved clarifications remain
**Rationale**: The current repository answers the planning unknowns: Astro website exists, `/product` exists, `/platform` does not yet exist, navigation points to `/product`, smoke tests exist, and `/contact` is the current conversion path.
**Alternatives considered**:
- Ask for route/CTA clarification: rejected because the spec provides reasonable defaults and current repository state supports a safe path.

View File

@ -0,0 +1,280 @@
# Feature Specification: Tenantial Platform Page
**Feature Branch**: `feat/401-tenantial-platform-page`
**Created**: 2026-05-18
**Status**: Draft
**Input**: User description: "Spec 401 - Tenantial Platform Page. Create a dedicated public `/platform` page for Tenantial that explains the evidence-first governance operating model, core capabilities, governance loop, safe product boundaries, navigation consistency, Tenantial metadata, accessibility, responsiveness, conservative claims, and website-only runtime scope."
**Visual Refactor Update**: 2026-05-18 follow-up request: refactor `/platform` so it closely follows the provided Tenantial mockup as a target for composition, visual hierarchy, density, product expression, dashboard-preview hero, connected governance diagrams, asymmetric capability grouping, truth-layer visual, warmer operator workflow zone, clear boundaries band, focused CTA, and quiet footer.
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
- **Problem**: After the homepage rebuild, visitors have a stronger first impression but no dedicated page that explains what Tenantial governs, how the governance loop works, and how backup, restore, drift, findings, evidence, audit trails, exceptions, and reviews connect.
- **Today's failure**: A buyer can mistake Tenantial for a generic backup tool, helpdesk product, device action tool, or template site because the public website does not yet explain the product model beyond the homepage promise.
- **User-visible improvement**: The Platform page gives IT, MSP, security, and audit stakeholders a structured explanation of Tenantial's evidence-first governance model and clear next steps without unsupported security, compliance, customer, or runtime-data claims.
- **Smallest enterprise-capable version**: Add one canonical public Platform page, align public navigation and homepage CTA links to it, preserve or resolve `/product` compatibility if needed, provide Tenantial-specific metadata, include conservative product boundaries, and add website smoke coverage for the route and key claims.
- **Explicit non-goals**: No platform runtime changes, no admin UI, no Filament or Livewire changes, no authentication, no backend APIs, no Microsoft Graph calls, no real tenant data, no CMS, no i18n, no pricing page, no trust center, no demo-booking backend, and no customer logos or unsupported certifications.
- **Permanent complexity imported**: One public website page narrative, route and navigation expectations, static content sections, website-only smoke expectations, and ongoing responsibility to keep public Tenantial copy aligned with Spec 400.
- **Why now**: Spec 400 makes "Explore the platform" a natural next step; without a real Platform page, the primary homepage journey is incomplete and the public product story remains underexplained.
- **Why not local**: A homepage-only copy patch cannot answer product-model questions or resolve `/platform` versus `/product` navigation consistency across the public site.
- **Approval class**: Core Enterprise
- **Red flags triggered**: None. The feature introduces no persisted truth, domain state, runtime abstraction, provider contract, or cross-domain UI framework.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 2 | Wiederverwendung: 1 | **Gesamt: 11/12**
- **Decision**: approve
## Spec Scope Fields *(mandatory)*
- **Scope**: Public website. This is outside workspace, tenant, and canonical admin scopes.
- **Primary Routes**: `/platform`; existing `/product` route must be retained only as redirect compatibility to `/platform` if present.
- **Data Ownership**: Static public website content only. No workspace-owned, tenant-owned, platform runtime, or persisted application data is introduced.
- **RBAC**: None. The Platform page is public and introduces no authorization behavior.
## Relationship To Existing Specs
- Spec 400 establishes the Tenantial homepage direction, dark premium visual language, public brand copy, and the homepage "Explore the platform" journey.
- Spec 401 extends that direction into the first dedicated public product explanation page.
- Spec 223 remains historical website rebuild context if still present, but Spec 401 is the Tenantial-specific Platform page slice.
- If no local Spec 227 artifact exists, this spec does not create one. Any homepage/platform visual foundation overlap is treated as refined by Specs 400 and 401.
## Visual Refactor Target
- `/platform` should read as a product-marketing page with governance-control-room density, not as a documentation page or a repeated stack of equal dark cards.
- The first viewport must use a split layout: concise positioning and CTAs on the left, a large static dashboard/product preview on the right.
- The Operating Model must render as a compact connected step chain: Snapshot, Drift, Finding, Review, Evidence, Audit trail.
- The Governance Loop must be a central visual diagram connecting Source of truth, Snapshot, Diff, Finding, Exception, Review, Evidence, and Audit trail.
- Capabilities must be visually grouped with a larger Backup & Restore primary block and secondary capability cards for Drift Detection, Findings, Evidence, Audit Trail, Exceptions, and Governance Reviews.
- Truth Layers must use a layer-stack or equivalent visual model for Execution truth, Artifact truth, Backup truth, Recovery evidence, and Operator next action.
- Operator Workflows should be compact, persona-oriented, and visually warmer than the control-room sections.
- Platform Boundaries must read as a trust/honesty band with short boundary statements rather than a defensive list.
- Final CTA and footer must avoid two equally heavy closing sections; the footer should be calmer after the focused CTA.
- The refactor remains website-only and must not change `apps/platform`, workspace contracts, packages, dependencies, or lockfiles.
## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*
N/A - no shared operator interaction family touched. This feature changes public marketing navigation and content, not admin notifications, operator status messaging, operation links, dashboard signals, alerts, report viewers, or shared operator interaction contracts.
## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*
N/A - no OperationRun start, completion, deduplication, resume, block, or link semantics touched.
## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*
N/A - no shared provider/platform boundary touched. The page may describe Microsoft tenant governance at a public product level, but it does not change provider contracts, platform-core vocabulary, identity scope, compare strategy, governed-subject taxonomy, or runtime provider behavior.
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
N/A - no operator-facing admin surface change. This feature changes a public marketing page only and does not affect Filament/admin pages, tenant-scoped operator workflows, shared operator components, action surfaces, or governance decision surfaces.
## Proportionality Review *(mandatory when structural complexity is introduced)*
- **New source of truth?**: Yes, limited to public Platform page messaging and public route intent. No product runtime or tenant-governance truth is introduced.
- **New persisted entity/table/artifact?**: No.
- **New abstraction?**: No runtime abstraction. Any page sections are website-local presentation content for this public page.
- **New enum/state/reason family?**: No.
- **New cross-domain UI framework/taxonomy?**: No.
- **Current operator problem**: Prospective buyers and stakeholders cannot yet understand Tenantial's governance operating model from a dedicated public page.
- **Existing structure is insufficient because**: The homepage introduces the promise but cannot carry a full explanation of the platform model, capability relationships, route expectations, boundaries, and proof-safe positioning.
- **Narrowest correct implementation**: One static public Platform page with aligned navigation, route compatibility expectations, conservative copy, accessibility/responsive requirements, Tenantial metadata, and route smoke coverage.
- **Ownership cost**: Platform page copy, static section content, navigation labels, metadata, and smoke assertions must be maintained as later website pages are added.
- **Alternative intentionally rejected**: Building pricing, trust, solutions, resources, i18n, CMS, or live product-data integration in the same slice. Those would broaden scope before the core Platform explanation is stable.
- **Release truth**: Current public website truth, not platform runtime truth or future live data truth.
### Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility for stale public `/product` copy is not preserved as a product requirement. If `/product` already exists, it must remain only as a redirect compatibility path to `/platform`. No public route may expose stale AstroDeck, TemplateDeck, TenantAtlas, TenantPilot, or TenantCTRL copy.
Internal package names, workspace scripts, and platform runtime contracts must not be renamed by this feature. In particular, an internal website package name may remain unchanged even if it includes a historical repository name.
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
- **Test purpose / classification**: Browser.
- **Validation lane(s)**: browser.
- **Why this classification and these lanes are sufficient**: The feature changes a public static website route, navigation, content, metadata, responsive behavior, and copy safety. Website build and smoke checks are the narrowest honest proof.
- **New or expanded test families**: Platform route website smoke coverage only.
- **Fixture / helper cost impact**: None. No database, workspace, membership, provider, session, seed, or platform setup should be required.
- **Heavy-family visibility / justification**: Browser coverage is intentional and scoped to the public Platform route plus route compatibility where needed.
- **Special surface test profile**: N/A.
- **Standard-native relief or required special coverage**: Website smoke checks plus desktop/mobile visual review.
- **Reviewer handoff**: Reviewers must confirm browser coverage remains website-scoped, no hidden platform setup is introduced, and the proof checks visible content, metadata cleanup, navigation, and mobile overflow.
- **Budget / baseline / trend impact**: None expected beyond a small Platform route smoke addition.
- **Escalation needed**: document-in-feature.
- **Active feature PR close-out entry**: Smoke Coverage.
- **Planned validation commands**: `corepack pnpm build:website`; `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke`; `git diff --check`.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Understand The Platform Model (Priority: P1)
A first-time buyer or stakeholder opens the Platform page and understands that Tenantial is an evidence-first governance platform for Microsoft tenant environments, not only a backup tool or generic SaaS site.
**Why this priority**: This is the minimum viable Platform page outcome. If the page does not explain the product model, the homepage CTA journey remains incomplete.
**Independent Test**: Can be tested by opening `/platform` and verifying that the first viewport shows Tenantial Platform positioning, a clear governance headline, Microsoft tenant context, and a product-oriented explanation.
**Acceptance Scenarios**:
1. **Given** a visitor follows "Explore the platform" from the homepage, **When** `/platform` opens, **Then** they see Tenantial Platform branding and a headline about governing Microsoft tenants through evidence, drift context, and reviewable decisions.
2. **Given** a visitor reads the first viewport, **When** they scan the hero, **Then** they can identify backup records, configuration drift, findings, evidence, audit trails, and structured reviews as connected parts of the platform model, supported by a large static dashboard/product preview.
3. **Given** a visitor is deciding what to do next, **When** they inspect the page actions, **Then** "Book a demo" is available as the primary CTA and "See the governance loop" guides them deeper into the page.
---
### User Story 2 - See How Governance Work Flows (Priority: P2)
An IT, MSP, security, or compliance stakeholder reviews the operating model and understands how raw tenant change becomes reviewable governance evidence.
**Why this priority**: Tenantial's public promise depends on explaining the governance loop, not just listing features.
**Independent Test**: Can be tested by reviewing the operating model and governance loop sections for the required steps and conservative operator-led language.
**Acceptance Scenarios**:
1. **Given** a stakeholder reaches the operating model section, **When** they review the workflow, **Then** they see a compact connected sequence covering Snapshot, Drift, Finding, Review, Evidence, and Audit trail.
2. **Given** the governance loop is visible, **When** the visitor scans the section, **Then** they understand through a connected diagram that governance is about preserving context and reviewable decisions, not only knowing current configuration state.
3. **Given** the page describes findings and restore context, **When** a visitor reads the copy, **Then** it does not imply automatic remediation, guaranteed recovery, or device action workflows.
---
### User Story 3 - Evaluate Capabilities And Boundaries (Priority: P3)
A stakeholder evaluates the page and can distinguish Tenantial's core capabilities from out-of-scope helpdesk, SIEM, device action, or Microsoft admin center replacement promises.
**Why this priority**: Product trust depends on explaining what the platform does and where its boundaries are.
**Independent Test**: Can be tested by reviewing capability, truth-layer, workflow, and boundary sections for required concepts and absence of unsupported claims.
**Acceptance Scenarios**:
1. **Given** a visitor reads the capability section, **When** they scan the grouped capability zone, **Then** they see Backup & Restore as the primary block plus Drift Detection, Findings, Evidence, Audit Trail, Exceptions, and Governance Reviews as supporting capabilities.
2. **Given** a visitor reads the platform boundaries section, **When** they compare Tenantial to other tools, **Then** they understand it is built for governance of record and recovery context, not helpdesk actions or live device operations.
3. **Given** a security or audit stakeholder reviews the page, **When** they inspect claims, **Then** the page contains no unsupported certifications, guarantees, customer logos, Microsoft endorsement, uptime promises, or blanket compliance statements.
---
### User Story 4 - Navigate A Brand-Clean Public Site (Priority: P4)
A website owner reviews the public site journey and confirms that navigation, metadata, and compatibility routing support the Platform page without stale brand or template residue.
**Why this priority**: The Platform page should become the canonical next step after the homepage without introducing route confusion.
**Independent Test**: Can be tested through link review, metadata review, visible-copy review, and website smoke coverage for `/platform` plus redirect behavior from `/product` if `/product` remains.
**Acceptance Scenarios**:
1. **Given** the homepage is available, **When** a visitor activates "Explore the platform", **Then** they reach `/platform`.
2. **Given** the global header or footer includes Platform, **When** a visitor follows that link, **Then** it reaches the canonical Platform page.
3. **Given** `/product` exists before implementation, **When** route compatibility is reviewed, **Then** it redirects to `/platform` and exposes no stale public copy or conflicting metadata.
### Edge Cases
- If `/product` already exists, it must redirect to `/platform` and must not remain a renderable primary public product route with inconsistent or stale content.
- If no dedicated demo-booking flow exists, "Book a demo" must point to an existing intentional contact path or use another explicitly documented non-dead destination.
- If no approved product screenshot exists, the page may use static diagrams, structured panels, or product-process visuals rather than fake live screenshots.
- If no customer logos, certifications, partnership proof, or compliance evidence are available, the page must use conservative product language instead of social proof.
- If a visitor uses a narrow mobile viewport, diagrams and card grids must simplify or stack without body-level horizontal overflow.
- If icons or visual diagrams are unavailable to assistive technology, adjacent text must communicate the same meaning.
- If status or capability meaning is shown with accent colors, the same meaning must be available through text labels.
- If Spec 400 components are not available in the current branch, the page must still follow the same visual direction rather than inventing a separate brand style.
## Requirements *(mandatory)*
**Constitution alignment (required):** This feature introduces no Microsoft Graph calls, no write/change behavior, no queued or scheduled work, no OperationRun, no AuditLog changes, no tenant isolation changes, and no platform runtime behavior.
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** This feature introduces no persisted product truth, no domain abstraction, no enum/status/reason family, and no cross-domain UI framework. The only new source of truth is public Platform page messaging and route intent, bounded to the website.
**Constitution alignment (XCUT-001):** This feature does not touch shared operator interaction families. Public website navigation, CTAs, static diagrams, and marketing visuals must remain website-local.
**Constitution alignment (DECIDE-AUD-001 / OPSURF-001):** This feature does not change admin detail/status surfaces, audience modes, support/raw evidence disclosure, or operator next-action surfaces.
**Constitution alignment (PROV-001):** This feature does not change provider/platform seams. Microsoft tenant language is public positioning only and must not create runtime provider coupling.
**Constitution alignment (TEST-GOV-001):** Browser coverage is intentional, Platform-route-scoped, and must not introduce database, workspace, provider, membership, session, or platform defaults.
**Constitution alignment (OPS-UX / OPS-UX-START-001):** N/A - no OperationRun behavior is created, queued, completed, deduplicated, resumed, blocked, or linked.
**Constitution alignment (RBAC-UX):** N/A - no authorization plane, capability, membership, global search, mutation, or destructive action behavior changes.
**Constitution alignment (BADGE-001):** N/A - no admin status badge semantics change. Public marketing labels must remain descriptive and not become a shared status taxonomy.
**Constitution alignment (UI-FIL-001):** N/A - no Filament, Blade admin, Livewire, Resource, RelationManager, or Page changes.
**Constitution alignment (UI-NAMING-001 / DECIDE-001 / UI surface rules):** N/A for operator-facing naming and action-surface contracts. Public Platform copy must still use precise user-facing language and avoid implementation-first labels.
### Functional Requirements
- **FR-001**: The public website MUST provide a canonical Platform page at `/platform`.
- **FR-002**: The Platform page MUST present Tenantial as an evidence-first governance platform for Microsoft tenant environments.
- **FR-003**: The first viewport MUST include the eyebrow "TENANTIAL PLATFORM" or equivalent wording with the same meaning.
- **FR-004**: The first viewport MUST include a headline that communicates governing Microsoft tenants through evidence, drift context, and reviewable decisions.
- **FR-005**: The first viewport supporting copy MUST connect backup records, configuration drift, findings, evidence, audit trails, and structured reviews into one governance operating loop.
- **FR-006**: The first viewport MUST provide "Book a demo" as the primary CTA.
- **FR-007**: The first viewport MUST provide a secondary CTA that navigates to the governance loop section or equivalent in-page explanation.
- **FR-008**: The Platform page MUST include a large static dashboard/product preview in the hero that is clearly public marketing content and not live tenant data.
- **FR-009**: The Platform page MUST include a compact connected operating model overview showing the sequence: Snapshot, Drift, Finding, Review, Evidence, and Audit trail.
- **FR-010**: The Platform page MUST include a visually grouped capability section with Backup & Restore as the primary block plus Drift Detection, Findings, Evidence, Audit Trail, Exceptions, and Governance Reviews as supporting capabilities.
- **FR-011**: Capability descriptions MUST be concise, product-specific, and free of claims that imply guaranteed remediation, guaranteed compliance, or full automation.
- **FR-012**: The Platform page MUST include a governance loop section with a connected visual diagram explaining how source-of-truth context, snapshots, diffs, findings, exceptions, reviews, evidence, and audit trails connect.
- **FR-013**: The governance loop MUST make operator review and evidence preservation explicit.
- **FR-014**: The Platform page SHOULD include a truth-layers section with a visual layer-stack or equivalent model explaining execution truth, artifact truth, backup truth, recovery evidence, and operator next action in plain language.
- **FR-015**: The Platform page SHOULD include compact operator workflow examples for MSP operators, enterprise IT, security reviewers, and compliance or audit stakeholders, with a warmer visual treatment than the main control-room sections.
- **FR-016**: The Platform page MUST include a platform boundaries section stating that Tenantial is built for governance of record and recovery context, does not take actions on the customer's behalf, does not manage devices, does not replace ITSM/SIEM/ticketing/Microsoft admin centers, and supports reviewable decisions.
- **FR-017**: The Platform page MUST include a focused final CTA that invites visitors to see how evidence-first governance fits their Microsoft tenant operations, followed by a calmer footer.
- **FR-018**: "Book a demo" CTA destinations MUST be intentional and MUST NOT point to missing or stale template routes.
- **FR-019**: Homepage "Explore the platform" navigation MUST point to `/platform`.
- **FR-020**: Header and footer Platform navigation MUST point to `/platform`.
- **FR-021**: If `/product` exists, it MUST redirect to `/platform` and MUST NOT render stale, conflicting, or primary public product content.
- **FR-022**: No public route involved in this feature MAY expose stale AstroDeck, TemplateDeck, Open Source, MIT, TenantAtlas, TenantPilot, or TenantCTRL public copy.
- **FR-023**: The Platform page MUST use public Tenantial branding and MUST NOT rename internal package or workspace conventions.
- **FR-024**: The Platform page title MUST communicate "Tenantial Platform" and evidence-first governance for Microsoft tenants.
- **FR-025**: The Platform page description metadata MUST mention backup, restore, drift detection, findings, evidence, audit trails, exceptions, and reviews for Microsoft tenant governance.
- **FR-026**: Metadata MUST NOT contain AstroDeck, TemplateDeck, old public brand names, unsupported compliance claims, or unsupported security claims.
- **FR-027**: The Platform page MUST NOT claim SOC 2 certification, ISO certification, HIPAA compliance, blanket GDPR compliance, end-to-end encryption, guaranteed recovery, guaranteed compliance, zero drift, universal real-time coverage, named customer trust, Microsoft certification, or Microsoft partnership unless independently approved evidence exists.
- **FR-028**: The Platform page MUST use the Spec 400 public visual direction and the provided mockup target: dark premium background, warm light text, muted secondary text, restrained borders, mint/teal accents, strong product surfaces, subtle grid/wave/glow elements, enterprise calm, and higher visual density than the initial card-heavy implementation.
- **FR-029**: The Platform page MUST avoid generic bright startup gradients, cybersecurity cliche visuals, fake customer logos, and unapproved customer environment screenshots.
- **FR-030**: The Platform page MUST have exactly one primary `h1`.
- **FR-031**: Page sections MUST use a meaningful heading hierarchy and semantic structure.
- **FR-032**: Links and CTAs MUST be keyboard-accessible and have visible focus states.
- **FR-033**: Diagrams and icons MUST have text equivalents or adjacent explanatory text.
- **FR-034**: No meaning MAY be conveyed by color alone.
- **FR-035**: Text and controls MUST remain readable on mobile, tablet, desktop, and wide desktop viewports.
- **FR-036**: The page MUST NOT create body-level horizontal overflow on narrow mobile viewports.
- **FR-037**: The page MUST remain mostly static and MUST NOT introduce third-party tracking scripts, backend fetches, platform API calls, auth/session coupling, or live tenant-data dependencies.
- **FR-038**: Existing root workspace scripts, website port conventions, and platform runtime contracts MUST remain unchanged.
### Key Entities
- **Platform Page Message**: The public brand, product category, governance promise, supporting explanation, and CTA hierarchy for `/platform`.
- **Operating Model Step**: A public explanation step in the governance flow, such as snapshot, drift detection, finding creation, review context, evidence attachment, decision, or audit trail.
- **Capability**: A concise public description of a Tenantial capability: Backup, Restore, Drift Detection, Findings, Evidence, Audit Trail, Exceptions, or Governance Reviews.
- **Governance Loop**: A visual and textual explanation of how configuration state, drift context, operator decisions, evidence, and auditability connect.
- **Truth Layer**: A plain-language distinction between execution truth, artifact truth, backup truth, recovery evidence, and operator next action.
- **Operator Workflow**: A short public persona workflow for MSP operators, enterprise IT, security reviewers, or compliance and audit stakeholders.
- **Platform Boundary**: A product expectation statement that clarifies what Tenantial is not intended to replace or claim.
### Assumptions
- The public brand for this page is Tenantial.
- `/platform` is the canonical public route for this feature.
- `/product` currently exists in the website and is treated as redirect-only compatibility to `/platform` rather than the primary public route after this feature.
- "Book a demo" defaults to the existing contact destination unless a dedicated demo route is already present when implementation starts.
- No approved customer logos, certifications, Microsoft partnership proof, compliance guarantees, uptime guarantees, real tenant screenshots, or live product telemetry are available for this slice.
- Static diagrams or structured panels are acceptable substitutes for screenshots when no approved Tenantial product asset exists.
- Spec 400 is the visual and copy baseline for public Tenantial pages.
- This feature is website-only and does not change the Laravel platform, Filament admin, Livewire behavior, Microsoft Graph integration, database schema, queues, workers, sessions, or authentication.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: In stakeholder review, at least 8 of 10 reviewers can identify Tenantial as an evidence-first Microsoft tenant governance platform within 5 seconds of viewing the Platform page first viewport.
- **SC-002**: 100% of required Platform page sections render on desktop and mobile review: hero, operating model overview, capability grid, governance loop, platform boundaries, final CTA, and footer.
- **SC-003**: At least 90% of reviewers can explain how backup records, drift, findings, evidence, audit trails, exceptions, and reviews connect after reading the page.
- **SC-004**: Visible copy and metadata review finds 0 occurrences of AstroDeck, TemplateDeck, Open Source, MIT, TenantAtlas, TenantPilot, TenantCTRL, or other stale public brand/template positioning.
- **SC-005**: Claims review finds 0 unsupported customer, certification, partnership, uptime, recovery, security, or blanket compliance claims.
- **SC-006**: Navigation review confirms the homepage "Explore the platform" CTA, header Platform link, and footer Platform link all reach `/platform`.
- **SC-007**: If `/product` remains available, route review confirms it redirects to `/platform` and does not expose inconsistent public content or conflicting metadata.
- **SC-008**: Desktop and mobile review confirms 0 body-level horizontal overflow issues at narrow mobile, tablet, desktop, and wide desktop widths.
- **SC-009**: Accessibility review confirms one primary heading, meaningful section headings, keyboard-accessible CTAs, visible focus states, readable contrast, and no color-only meaning.
- **SC-010**: Website smoke validation confirms `/platform` renders, required brand/capability/boundary copy is visible, old template/public brand residue is absent, and route compatibility behavior is covered if `/product` remains.

View File

@ -0,0 +1,255 @@
# Tasks: Tenantial Platform Page
**Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/`
**Prerequisites**: `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/plan.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/spec.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/research.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/data-model.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/contracts/public-routes.openapi.yaml`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/quickstart.md`
**Tests**: Required. Spec 401 changes the public website runtime route and test surface; use focused Playwright smoke coverage in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke`.
**Scope Boundary**: Work is limited to `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website` plus this spec directory. Do not modify `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform`.
**Constitution Gate**: Finalization includes the repository-wide targeted Pest and Pint close-out commands documented in `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/plan.md` without treating Laravel behavior as the feature proof.
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Confirm website-only implementation boundaries and the existing route/content patterns before changing code.
- [X] T001 Review existing public page patterns in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/product.astro`, `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/product.ts`, `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`, and `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T002 [P] Confirm no dependency or script changes are needed in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/package.json` and `/Users/ahmeddarrazi/Documents/projects/wt-website/package.json`
- [X] T003 [P] Confirm Tailwind v4 styling conventions and existing surface classes in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/styles/tokens.css`, `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/styles/global.css`, and `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/components/sections/PageHero.astro`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Add route-level foundation needed before user-story implementation can compile and be tested.
**Critical**: No user-story implementation should start until `/platform` exists in route metadata and typed site definitions, and T007 confirms the repository-wide quality-gate commands are explicit.
- [X] T004 Add `/platform` to `SitePath`, `PageRole`, route unions, and related public website route typing in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/types/site.ts`
- [X] T005 Add `/platform` page definition, canonical route membership, sitemap inclusion, and `/product` redirect compatibility classification in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`
- [X] T006 Update smoke helper route constants to recognize `/platform` and preserve `/product` redirect compatibility expectations in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/smoke-helpers.ts`
- [X] T007 Confirm the repository-wide targeted Pest and Pint close-out commands are explicit in `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/plan.md`
**Checkpoint**: Website route metadata is ready; user story implementation can proceed.
---
## Phase 3: User Story 1 - Understand The Platform Model (Priority: P1) MVP
**Goal**: A first-time buyer or stakeholder opens `/platform` and understands Tenantial as an evidence-first governance platform for Microsoft tenant environments.
**Independent Test**: Open `/platform` and verify the first viewport shows Tenantial Platform positioning, Microsoft tenant context, a governance headline, static product-oriented visual, "Book a demo", and "See the governance loop".
### Tests for User Story 1
- [X] T008 [US1] Add failing `/platform` hero smoke test titled "platform hero explains Tenantial governance model" for shell, one `h1`, "TENANTIAL PLATFORM", governance headline, primary CTA, secondary CTA, and static visual in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T009 [US1] Add failing `/platform` metadata smoke test titled "platform metadata is Tenantial clean" for title, description, canonical URL, and absence of stale public-brand terms in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
### Implementation for User Story 1
- [X] T010 [US1] Create Platform page static hero, SEO, CTA, and first-viewport visual content exports in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
- [X] T011 [US1] Create canonical Platform page route using `PageShell`, existing section primitives, hero content, and static visual markup in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T012 [US1] Ensure `/platform` uses Tenantial-specific metadata, canonical `/platform`, exactly one primary heading, keyboard-accessible CTAs, and no live tenant-data language in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T013 [US1] Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke --grep "platform hero|platform metadata"` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
**Checkpoint**: `/platform` is usable as the MVP public Platform page with a clear first-viewport product model.
---
## Phase 4: User Story 2 - See How Governance Work Flows (Priority: P2)
**Goal**: A stakeholder understands how raw tenant change becomes reviewable governance evidence.
**Independent Test**: Review the operating model and governance loop sections and verify required steps, operator-led language, evidence preservation, and no automatic remediation or guaranteed recovery claims.
### Tests for User Story 2
- [X] T014 [US2] Add failing `/platform` smoke test titled "platform governance flow explains reviewable evidence" for operating model steps, governance loop labels, operator review wording, evidence preservation wording, and auditability wording in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T015 [US2] Add failing `/platform` smoke test titled "platform governance flow avoids automation guarantees" that does not imply automatic remediation, guaranteed recovery, live device actions, or real-time tenant operations in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
### Implementation for User Story 2
- [X] T016 [US2] Add ordered operating model and governance loop content arrays to `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
- [X] T017 [US2] Render the operating model overview with the required sequence in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T018 [US2] Render the governance loop section with accessible text equivalents and mobile-stacking behavior in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T019 [US2] Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke --grep "platform governance flow"` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
**Checkpoint**: The Platform page explains the governance flow independently of later capability and navigation cleanup work.
---
## Phase 5: User Story 3 - Evaluate Capabilities And Boundaries (Priority: P3)
**Goal**: A stakeholder can evaluate Tenantial's core capabilities and distinguish them from helpdesk, SIEM, device-action, or Microsoft admin center replacement promises.
**Independent Test**: Review `/platform` for all eight capabilities, truth-layer or workflow explanation, boundary language, and absence of unsupported customer, certification, partnership, uptime, recovery, security, or compliance claims.
### Tests for User Story 3
- [X] T020 [US3] Add failing `/platform` smoke test titled "platform capabilities cover governance primitives" for Backup, Restore, Drift Detection, Findings, Evidence, Audit Trail, Exceptions, and Governance Reviews in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T021 [US3] Add failing `/platform` smoke test titled "platform boundaries keep claims conservative" for platform boundary copy and unsupported-claim absence on `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T022 [US3] Add failing `/platform` mobile smoke test titled "platform mobile layout stays readable without overflow" for readable capability cards, boundary content, no color-only meaning, and no body-level horizontal overflow in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
### Implementation for User Story 3
- [X] T023 [US3] Add capability, truth-layer, operator-workflow, platform-boundary, and final CTA content exports to `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
- [X] T024 [US3] Render the capability grid using existing website primitives and lucide-compatible icon names in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T025 [US3] Render truth-layer and operator-workflow sections with concise public copy in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T026 [US3] Render platform boundary and final CTA sections with conservative claim language and working `/contact` demo CTA in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T027 [US3] Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke --grep "platform capabilities|platform boundaries|platform mobile"` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
**Checkpoint**: Stakeholders can evaluate the platform capabilities and boundaries without unsupported claims.
---
## Phase 6: User Story 4 - Navigate A Brand-Clean Public Site (Priority: P4)
**Goal**: Website owners can confirm that homepage, header, footer, metadata, and `/product` compatibility all support `/platform` without stale brand or template residue.
**Independent Test**: Follow homepage "Explore the platform", header Platform, footer Platform, and `/product`; verify they resolve to canonical `/platform` behavior, with `/product` redirecting to `/platform`.
### Tests for User Story 4
- [X] T028 [US4] Update homepage hero route-target smoke assertions from `/product` to `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T029 [US4] Update primary navigation, footer navigation, and onward-route smoke expectations for Platform links to `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/smoke-helpers.ts`
- [X] T030 [US4] Add `/product` compatibility smoke test titled "product redirects to platform" for redirect-to-`/platform` behavior and absence of stale public copy in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
### Implementation for User Story 4
- [X] T031 [US4] Update homepage "Explore the platform" CTA and final CTA destinations to `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/home.ts`
- [X] T032 [US4] Update primary navigation and footer Platform link destinations to `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`
- [X] T033 [US4] Convert `/product` to a redirect-only compatibility route pointing to `/platform` in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/product.astro`
- [X] T034 [US4] Retire stale product content usage so `/product` no longer imports or renders conflicting public copy from `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/product.ts`
- [X] T035 [US4] Update sitemap and canonical route behavior for `/platform` and `/product` redirect compatibility in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`
- [X] T036 [US4] Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke --grep "homepage.*platform|primary navigation|footer|product redirects"` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
**Checkpoint**: The public site journey consistently routes Platform intent to `/platform`.
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: Validate quality, accessibility, claim safety, and repo boundaries after all user stories are complete.
- [X] T037 [P] Run `corepack pnpm build:website` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T038 [P] Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T039 [P] Run `git diff --check` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T040 Review `/platform` at mobile, tablet, desktop, and wide desktop sizes for no body-level horizontal overflow in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T041 Review visible copy and metadata for forbidden public-brand residue and unsupported claims in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
- [X] T042 Confirm no files under `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform` were changed for this website-only feature
- [X] T043 Run `cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail bin pint --dirty` from `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform`
- [X] T044 Run `cd /Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform && ./vendor/bin/sail artisan test --compact tests/Deprecation/IsPlatformSuperadminDeprecationTest.php` from `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform`
- [X] T045 Confirm no Playwright helper change introduces platform, database, auth, provider, session, workspace, or tenant setup in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/smoke-helpers.ts`
- [X] T046 Confirm no unrelated Laravel, Filament, or Livewire product test family is introduced solely for Spec 401 website smoke proof in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke`
- [X] T047 Confirm final validation commands include `corepack pnpm build:website`, `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke`, `git diff --check`, and the constitution close-out commands from T043/T044 in `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/tasks.md`
- [X] T048 Review static website files for no third-party tracking scripts, backend fetches, platform API calls, auth/session coupling, or live tenant-data dependencies in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`, `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`, and `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/lib/site.ts`
---
## Phase 8: Mockup-Aligned Visual Refactor Follow-Up
**Purpose**: Apply the follow-up visual refactor request so `/platform` is much closer to the supplied mockup target rather than the initial card-heavy implementation.
- [X] T049 Update Spec 401 artifacts for the follow-up visual target in `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/spec.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/plan.md`, `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/data-model.md`, and `/Users/ahmeddarrazi/Documents/projects/wt-website/specs/401-tenantial-platform-page/quickstart.md`
- [X] T050 Replace `/platform` static content with mockup-aligned hero trust signals, six-step operating model, governance loop diagram copy, asymmetric capability content, truth layers, workflows, boundaries, and focused CTA in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`
- [X] T051 Refactor `/platform` page composition into split dashboard hero, compact Operating Model flow, central Governance Loop diagram, asymmetric Capabilities, Truth Layers visual, warmer Operator Workflows, Boundaries band, and focused CTA in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro`
- [X] T052 Add quiet footer behavior for `/platform` so the final CTA and footer are not two equally heavy closing sections in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/components/layout/Footer.astro`
- [X] T053 Update website smoke coverage for the new visual structure, grouped capabilities, truth-layer visual, boundaries wording, and quiet footer in `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts`
- [X] T054 Run `corepack pnpm build:website` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T055 Run `WEBSITE_PORT=4321 corepack pnpm --filter @tenantatlas/website test:smoke` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T056 Run `git diff --check` from `/Users/ahmeddarrazi/Documents/projects/wt-website`
- [X] T057 Review desktop and mobile `/platform` screenshots for mockup proximity, no body-level horizontal overflow, and no incoherent text overlap
- [X] T058 Confirm the visual refactor remains limited to `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website` and Spec 401 artifacts, with no `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/platform` changes
---
## Dependencies & Execution Order
### Phase Dependencies
- Phase 1 must complete before Phase 2.
- Phase 2 must complete before any user story implementation.
- US1 is the MVP and should complete before US2, US3, and US4 because it creates the canonical `/platform` route.
- US2 can proceed after US1 because it expands the same page with operating model and governance loop sections.
- US3 can proceed after US1 and can run in parallel with US2 if file-level coordination is handled for `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/pages/platform.astro` and `/Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/src/content/pages/platform.ts`.
- US4 should complete after US1 because homepage/header/footer links need a real canonical route target.
- Phase 7 runs after all selected user stories.
### User Story Dependency Graph
```text
Setup -> Foundation -> US1 (MVP)
|-> US2
|-> US3
`-> US4
US2 + US3 + US4 -> Polish
```
### Story Completion Order
1. US1 - Understand The Platform Model
2. US2 - See How Governance Work Flows
3. US3 - Evaluate Capabilities And Boundaries
4. US4 - Navigate A Brand-Clean Public Site
## Parallel Execution Examples
### Setup / Foundation
```text
T002 can run alongside T003 after T001 starts.
T004 and T005 should be coordinated because both affect route typing and route definitions.
T006 can run after T004/T005 interfaces are known.
```
### User Story 1
```text
T008 and T009 both edit /Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts, so coordinate them in one test-edit pass.
T010 and T011 should be sequential because the page route imports the content module.
```
### User Story 2
```text
T014 and T015 can be drafted together in /Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts before implementation.
T016 should complete before T017 and T018 render the new content.
```
### User Story 3
```text
T020, T021, and T022 can be drafted in one test-edit pass.
T023 can proceed before T024, T025, and T026 render the new sections.
```
### User Story 4
```text
T028 and T030 both edit /Users/ahmeddarrazi/Documents/projects/wt-website/apps/website/tests/smoke/home-product.spec.ts and should be coordinated.
T031 can run in parallel with T032 because they edit different files.
T033 and T034 should be coordinated because both define /product compatibility behavior.
```
### Final Validation
```text
T037, T038, and T039 are independent validation commands and can run in parallel if local resources allow.
T040, T041, T042, T045, T046, and T048 can run after validation commands finish.
T043 and T044 close the repository-wide constitution gates and should finish before T047.
```
## Implementation Strategy
### MVP First
Deliver US1 first. This creates the canonical `/platform` page with Tenantial Platform metadata, first-viewport positioning, static product-oriented visual, and primary/secondary CTA hierarchy. At that point the feature has a usable public destination even before deeper sections and compatibility cleanup land.
### Incremental Delivery
1. Complete Setup and Foundational phases.
2. Complete US1 and verify `/platform` independently.
3. Add US2 to explain the operating model and governance loop.
4. Add US3 to cover capabilities, truth layers, workflows, boundaries, and claim safety.
5. Add US4 to align homepage/header/footer navigation and redirect `/product` to `/platform`.
6. Run Phase 7 validation and record smoke coverage close-out.