by default; PostLayout for stories sets data-profile="clinical"; AdminLayout sets data-profile="research".
2.3 Components
`
src/components/
├── nav/
│ ├── Header.astro fixed-top glass nav; scroll-shrink; scroll-spy; mobile drawer
│ ├── Footer.astro footer with links, EIN, legal, social
│ ├── MobileNav.astro
│ └── Breadcrumb.astro
├── hero/
│ ├── HeroLanding.astro home hero (the headline tagline pattern from your May 2026 design)
│ └── HeroPlatform.astro platform-page hero (Cytoverse/Cytoscope/Cytonome triad)
├── content/
│ ├── Prose.astro rendered MDX body with brand typography
│ ├── Pullquote.astro
│ ├── Callout.astro info, warning, tip variants
│ └── ReadingTime.astro
├── forms/ React islands (client:load)
│ ├── ContactForm.tsx
│ ├── CareerForm.tsx with CV upload (PDF)
│ ├── PartnerForm.tsx
│ ├── StoryForm.tsx HIPAA-aware
│ └── NewsletterForm.tsx
├── ui/ shadcn-derived, design-system-tokenized
│ ├── Button.tsx
│ ├── Card.tsx
│ ├── Badge.tsx
│ ├── Input.tsx
│ ├── ConsentCheckbox.tsx
│ └── FontToggle.tsx (NEW: switches between Inter/Lexend/Atkinson Hyperlegible)
├── agent/ React islands
│ ├── TalkToCytognosis.tsx fixed-position affordance bottom-right
│ └── AgentPanel.tsx consumes agent-presentation-package + fabric-client-package
├── platform/
│ ├── CytoverseCard.astro
│ ├── CytoscopeCard.astro
│ ├── CytonomeCard.astro
│ └── HelixCard.astro
└── seo/
├── SEOHead.astro
├── StructuredData.astro
└── (Open Graph card generator script)
`
2.4 Content collections
`
src/content/
├── config.ts collection schemas (TypeScript)
├── blog/
│ ├── _placeholder-post.mdx one example post demonstrating front matter + MDX
│ └── ...
├── stories/
│ └── _placeholder-story.mdx one example with HIPAA-consent metadata
└── team/
└── _placeholder-member.mdx one example with bio + photo + role
`
Front matter schemas: title, slug, author, date, tags, social card, status (draft/published), reading time. For stories, add: consent class, anonymous flag, reviewed-by, reviewed-date.
2.5 Backend (FastAPI)
`
backend/
├── main.py Uvicorn entry; mounts routers
├── pyproject.toml uv-managed; ruff + ty + nox
├── routes/
│ ├── forms.py POST /api/forms/{type} with typed SQLModel validation
│ ├── blog.py admin CRUD + public read (cached)
│ ├── stories.py admin moderation queue
│ └── newsletter.py
├── models.py SQLModel tables for every form + content type
├── database.py SQLite for dev, Cloud SQL Postgres for prod
├── auth.py Google OAuth + allowlist
├── admin.py admin endpoint helpers
├── cv_parser.py PDF to structured fields
├── email_service.py outbound transactional email
├── HIPAA_COMPLIANCE_PLAN.md documented compliance plan (mandatory file)
└── tests/ pytest + integration
`
2.6 Tests
`
tests/
├── unit/
│ ├── components/ Astro + React Testing Library
│ └── lib/
├── integration/ cross-component flows
├── accessibility/ axe-core on every shipped page
└── e2e/ Playwright: home, contact-form-submit, story-submit-with-consent, admin-login
`
2.7 Documentation
`
docs/
├── README.md how to run, how to author content, how to deploy
├── architecture.md template structure walkthrough
├── accessibility.md how WCAG rules land in this template (including AAA for clinical pages)
├── privacy.md data flow; HIPAA points; consent surfaces
├── seo.md sitemap, OG, structured data
├── content-authoring.md for non-developers: how to add a blog post or a story
└── deployment.md Cloud Run deploy steps + scripts
`
2.8 SEO + structured data
Every page has unique title + description, OG tags, Twitter card tags, canonical URL, and JSON-LD (
Organization on every page; Article on posts; Person on team; BreadcrumbList on nested pages). Sitemap and robots.txt built at compile time.
2.9 Agent CTA
A persistent "Talk to Cytognosis" affordance (bottom-right, brand-aligned, not intrusive) that opens an in-page side panel. The side panel uses the
agent-presentation-package and fabric-client-package so the agent presence is consistent with the phone / desktop / extension templates. Text-only for the first revision; voice support deferred to a later revision.
2.10 Accessibility (WCAG AAA for clinical pages)
The scaffold ships with these accessibility requirements:
Foundation pages (marketing, about, platform): WCAG AA minimum, AAA where feasible.
Clinical pages (stories, patient-facing content): WCAG AAA required. All text meets 7:1 contrast ratio. No decorative elements that interfere with comprehension.
Admin pages: WCAG AA minimum.
Font toggle component available on every page, allowing users to switch between Inter (default), Lexend (reading fluency), and Atkinson Hyperlegible (maximum distinguishability).
Font preference persists in localStorage and applies site-wide.
Skip-to-content link first focusable; visible breadcrumbs on non-home; ARIA landmarks; one per page; prefers-reduced-motion honored.
2.11 Font toggle component
The
FontToggle.tsx React island provides:
Three font options: Inter (default), Lexend, Atkinson Hyperlegible.
Accessible dropdown with clear labels explaining each font's benefit.
Applies the selected font family to the element via a CSS custom property.
Persists choice in localStorage.
Respects the active profile's default font (Foundation defaults to Inter).
Available in the header settings area and in the footer accessibility section.
2.12 Performance + accessibility budgets
The scaffold ships with these baked in:
LCP < 1.8 s, TTI < 2.5 s, CLS < 0.05, FCP < 0.9 s on mid-tier mobile + 4G.
Lighthouse: Performance 95+, Accessibility 95+, Best Practices 95+, SEO 100.
Total page weight < 500 KB (content pages), < 1 MB (home).
Reading-level checker runs in CI on /, /about, /platform; target Flesch-Kincaid grade <= 10.
3. File layout (top of
app-website/)
`
app-website/
├── README.md
├── package.json
├── astro.config.mjs
├── tsconfig.json
├── tailwind.config.ts (extends design-system preset)
├── biome.json
├── public/
│ ├── favicon.svg
│ ├── robots.txt
│ ├── manifest.webmanifest
│ ├── _redirects
│ ├── fonts/ (self-hosted: Inter, Lexend, Atkinson Hyperlegible)
│ └── assets/ (logos, icons, team photos, generated OG cards)
├── src/ (per §2.1-§2.4 above)
├── backend/ (per §2.5)
├── tests/ (per §2.6)
├── docs/ (per §2.7)
└── microcopy.json every UI string keyed
`
4. Brand alignment
Consume
design-system-package's Tailwind preset. Never inline a #hex color. Logo wordmark in the header; logo mark in the favicon. Brand voice rules apply to every visible string:
No em dashes.
No "patients" outside clinical context (story pages can use "patient" since they ARE clinical context).
No hype words (revolutionary, cure, game-changing, breakthrough, disrupt).
Active present tense.
Title Case headings, sentence case for UI labels.
"Cytognosis" always capital C; product names capital.
Hero copy follows the Foundation profile patterns: visionary yet grounded; signature gradient as hero wash; minor magenta accent for "Get involved" CTAs only.
5. What to NOT produce
No React 18 UMD + Babel inline build. The scaffold uses Astro with a proper build system.
No Google Forms / Typeform embeds. Forms are owned end-to-end.
No third-party tracking pixels or analytics SDKs.
No webfont blocking first paint. Self-host fonts where possible; Google Fonts with font-display: swap as fallback.
No "lorem ipsum" placeholder text. Use Cytognosis brand-voice-aligned placeholder copy.
No inline
2.11 Font toggle component
The
2.12 Performance + accessibility budgets
The scaffold ships with these baked in:
3. File layout (top of
4. Brand alignment
Consume
Hero copy follows the Foundation profile patterns: visionary yet grounded; signature gradient as hero wash; minor magenta accent for "Get involved" CTAs only.