Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/(marketing)/about/AboutPageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export default function AboutPageContent() {
<div className="h-px bg-gradient-to-r from-transparent via-white/[0.06] to-transparent" />
</div>

{/* Timeline section removed 2026-05-28 the previous milestone
{/* Timeline section removed 2026-05-28, the previous milestone
array claimed customer deployments and framework launches
that hadn't actually shipped. Pulled the whole section
rather than fabricate a four-year history. /about flows hero
Expand Down
4 changes: 2 additions & 2 deletions app/(marketing)/author/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function generateMetadata({
if (!author) {
return { title: 'Author not found | FormaOS' };
}
const title = `${author.name} ${author.role} | FormaOS`;
const title = `${author.name}, ${author.role} | FormaOS`;
const description = author.bio.slice(0, 155);
return {
title,
Expand Down Expand Up @@ -77,7 +77,7 @@ export default async function AuthorPage({
]),
]
: [
// Collective bylines emit Organization rather than Person
// Collective bylines emit Organization rather than Person ,
// honest signal to crawlers about what the byline represents.
{
'@context': 'https://schema.org',
Expand Down
48 changes: 24 additions & 24 deletions app/(marketing)/blog/blogData.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/(marketing)/compare/CompareIndexContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export default function CompareIndexContent() {
<div className="h-px bg-gradient-to-r from-transparent via-white/[0.06] to-transparent" />
</div>

{/* What "compliance OS" means vs traditional GRC SSR'd */}
{/* What "compliance OS" means vs traditional GRC, SSR'd */}
<section
aria-labelledby="compare-category-explainer"
className="relative mx-auto max-w-5xl px-4 pb-14 sm:px-6 lg:px-8"
Expand Down
2 changes: 1 addition & 1 deletion app/(marketing)/compare/components/CompareHeroVisual.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface CompareHeroVisualProps {
* CompareHeroVisual
* ─────────────────
* Two side-by-side panels: the competitor and FormaOS (emphasised).
* Restrained entrance only no cursor tilt, floating loop, or blur chrome.
* Restrained entrance only, no cursor tilt, floating loop, or blur chrome.
*/
function CompareHeroVisualInner({ competitor }: CompareHeroVisualProps) {
const shouldReduceMotion = useReducedMotion();
Expand Down
2 changes: 1 addition & 1 deletion app/(marketing)/compare/healthmetrics/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default function Image() {
maxWidth: 700,
}}
>
Operational compliance execution vs clinical governance reporting
Operational compliance execution vs clinical governance reporting ,
see why Australian care providers choose FormaOS.
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/(marketing)/components/FigmaHomepage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export default function FormaOSHomepage({
<FrameworkTrustStrip />,
200,
)}
{/* Cryptographic audit-chain proof pulled to position 3
{/* Cryptographic audit-chain proof, pulled to position 3
(after hero + framework strip) on 2026-05-28 to surface
the most code-grounded section early. Before, this sat
below 8 marketing-feature sections; a buyer scrolling
Expand Down
4 changes: 2 additions & 2 deletions app/(marketing)/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export function Footer() {
{/* Main Footer Content */}
<div className="border-t border-white/[0.06] py-12 sm:py-14">
<div className="grid grid-cols-1 min-[480px]:grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-10 lg:gap-8">
{/* Brand column wider */}
{/* Brand column, wider */}
<div className="col-span-2 sm:col-span-3 lg:col-span-2 mb-2 lg:mb-0">
<Link
href="/"
Expand Down Expand Up @@ -240,7 +240,7 @@ export function Footer() {
<MapPin className="h-3 w-3 shrink-0" aria-hidden="true" />
{brand.address.locality}, {brand.address.region}, {brand.address.country}
</div>
{/* /status badge removed 2026-05-13 was hardcoded
{/* /status badge removed 2026-05-13, was hardcoded
"All systems operational" against 0% uptime data.
Route will return when a real status provider is
wired. */}
Expand Down
4 changes: 2 additions & 2 deletions app/(marketing)/components/HeroStaticShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const heroCopy = DEFAULT_RUNTIME_MARKETING.hero;
// 2026-05-23 (SEO sprint): the primary CTA path used to be rewritten
// onto `brand.seo.appUrl` (app.formaos.com.au), which sent every hero
// click through a wasted 308 hop and exposed the app subdomain as the
// CTA target. /contact is a marketing route keep it relative so the
// CTA target. /contact is a marketing route, keep it relative so the
// click stays on the canonical www host.
const primaryExternal = /^https?:\/\//i.test(heroCopy.primaryCtaHref);
const secondaryExternal = /^https?:\/\//i.test(heroCopy.secondaryCtaHref);
Expand Down Expand Up @@ -52,7 +52,7 @@ export function HeroStaticShell() {
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_50%_100%_at_100%_50%,rgba(3,7,18,0.40),transparent_70%)]" />

<div className="relative z-10 mx-auto flex min-h-[inherit] max-w-7xl flex-col items-center justify-center px-6 pb-12 pt-16 text-center sm:px-8 sm:pt-24 lg:px-12 lg:pt-28">
{/* Eyebrow restrained typographic label flanked by hairlines,
{/* Eyebrow, restrained typographic label flanked by hairlines,
no pill / icon / colour. */}
<div className="mb-7 flex items-center justify-center gap-4">
<span className="hidden h-px w-10 bg-white/20 sm:block" />
Expand Down
10 changes: 5 additions & 5 deletions app/(marketing)/components/HomeProofStaticShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const signatureEase: [number, number, number, number] = [
] as [number, number, number, number];

/* ════════════════════════════════════════════════════════════
Data three audiences, one evaluation. No per-card colour
Data, three audiences, one evaluation. No per-card colour
identity: the palette stays monochrome so the copy carries it.
════════════════════════════════════════════════════════════ */

Expand All @@ -20,7 +20,7 @@ const PROOF_BLOCKS = [
icon: FileCheck2,
eyebrow: 'For operators',
title: 'Controls run as workflows, not as documents',
body: 'Named tasks, approval gates, and evidence chains execute inside daily operations not in a separate compliance layer.',
body: 'Named tasks, approval gates, and evidence chains execute inside daily operations, not in a separate compliance layer.',
href: '/product',
cta: 'See how it works',
step: '01',
Expand All @@ -46,7 +46,7 @@ const PROOF_BLOCKS = [
] as const;

/* ════════════════════════════════════════════════════════════
Card restrained surface, hairline border, quiet hover lift.
Card, restrained surface, hairline border, quiet hover lift.
════════════════════════════════════════════════════════════ */

function ConvictionCard({
Expand All @@ -71,7 +71,7 @@ function ConvictionCard({
}}
className="group relative flex h-full flex-col rounded-2xl border border-white/[0.08] bg-white/[0.02] p-7 transition-colors duration-300 hover:border-white/20 sm:p-8"
>
{/* Quiet step index typographic, not a watermark gimmick */}
{/* Quiet step index, typographic, not a watermark gimmick */}
<span className="absolute right-6 top-6 text-sm font-medium tabular-nums text-slate-600">
{block.step}
</span>
Expand Down Expand Up @@ -117,7 +117,7 @@ export function HomeProofStaticShell() {
ref={sectionRef}
className="relative z-10 overflow-hidden bg-slate-950 px-6 pt-20 pb-4 sm:px-8 sm:pt-24 sm:pb-6 lg:px-12 lg:pt-28 lg:pb-8"
>
{/* Single hairline top seam no rainbow edge glow */}
{/* Single hairline top seam, no rainbow edge glow */}
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/[0.08] to-transparent" />

<div className="relative z-10 mx-auto max-w-7xl">
Expand Down
2 changes: 1 addition & 1 deletion app/(marketing)/components/MobileNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export function MobileNav() {
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-primary/50 to-transparent" />

<div className="max-h-[calc(100dvh-5.25rem)] overflow-y-auto overscroll-y-contain pb-[max(env(safe-area-inset-bottom),0.75rem)]" style={{ touchAction: 'pan-y' }}>
{/* Pull indicator native sheet affordance */}
{/* Pull indicator, native sheet affordance */}
<div className="flex justify-center pt-3 pb-2">
<div className="w-8 h-1 rounded-full bg-white/20" />
</div>
Expand Down
12 changes: 6 additions & 6 deletions app/(marketing)/components/homepage/AuditChainSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ const PILLARS = [
icon: History,
title: 'External anchor at 05:30 UTC',
tag: 'Verifiable without trusting us',
body: "Daily, each org's chain top is submitted to Sigstore Rekor as an RFC 6962-style Merkle entry. An auditor can verify the timestamp of any event without trusting us the proof goes through Linux Foundation infrastructure.",
body: "Daily, each org's chain top is submitted to Sigstore Rekor as an RFC 6962-style Merkle entry. An auditor can verify the timestamp of any event without trusting us, the proof goes through Linux Foundation infrastructure.",
},
{
icon: ShieldCheck,
title: 'Append-only at the database',
tag: 'Immutable, even to platform admins',
body: 'A BEFORE UPDATE OR DELETE trigger rejects any mutation of audit rows, backed by restrictive RLS deny policies. Even a platform admin with service-role credentialswhich bypasses RLS is stopped by the trigger. Enforced by Postgres, not application code.',
body: 'A BEFORE UPDATE OR DELETE trigger rejects any mutation of audit rows, backed by restrictive RLS deny policies. Even a platform admin with service-role credentials, which bypasses RLS, is stopped by the trigger. Enforced by Postgres, not application code.',
},
] as const;

Expand Down Expand Up @@ -81,7 +81,7 @@ function AuditBoard({ children }: { children: ReactNode }) {
st.x += (st.target - st.x) * Math.min(1, dt * 6);
bot.style.left = `${st.x}%`;

// Eye tracking pupils ease toward the cursor while hovering.
// Eye tracking, pupils ease toward the cursor while hovering.
const rect = board.getBoundingClientRect();
const cx = rect.left + (st.x / 100) * rect.width;
const cy = rect.top;
Expand Down Expand Up @@ -221,7 +221,7 @@ export function AuditChainSection() {
<div className="absolute inset-x-0 bottom-0 h-px bg-gradient-to-r from-transparent via-white/[0.06] to-transparent" />

<div className="relative mx-auto max-w-7xl px-6 lg:px-12">
{/* Header matches the "Operational mechanics" section */}
{/* Header, matches the "Operational mechanics" section */}
<ScrollReveal variant="slideUp" range={[0, 0.3]}>
<div className="mx-auto mb-12 max-w-2xl text-center lg:mb-14">
<p className="mb-4 text-sm font-semibold uppercase tracking-[0.18em] text-slate-500">
Expand All @@ -232,7 +232,7 @@ export function AuditChainSection() {
</h2>
<p className="mx-auto mt-5 max-w-xl text-base leading-relaxed text-slate-400">
Every org&apos;s audit log is hash-chained, RLS-locked against
mutation, and anchored daily to Sigstore Rekor the same
mutation, and anchored daily to Sigstore Rekor, the same
append-only transparency log the Linux Foundation runs for signed
open-source releases.
</p>
Expand Down Expand Up @@ -273,7 +273,7 @@ export function AuditChainSection() {
</div>
</AuditBoard>

{/* Facts bar the technical primitives, hairline-divided */}
{/* Facts bar, the technical primitives, hairline-divided */}
<ScrollReveal variant="slideUp" range={[0.1, 0.4]}>
<dl className="mt-4 grid grid-cols-2 gap-px overflow-hidden rounded-2xl border border-white/10 bg-white/[0.06] sm:grid-cols-3 lg:grid-cols-5">
{CHAIN_FACTS.map((fact) => (
Expand Down
2 changes: 1 addition & 1 deletion app/(marketing)/components/homepage/CTASection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function CTASection() {
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/[0.08] to-transparent" />
<div className="absolute inset-x-0 bottom-0 h-px bg-gradient-to-r from-transparent via-white/[0.08] to-transparent" />

{/* Subtle background glow monochrome, single neutral wash */}
{/* Subtle background glow, monochrome, single neutral wash */}
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_60%_50%_at_50%_50%,rgba(113,113,122,0.06)_0%,transparent_70%)]" />

<div className="relative z-10 py-20 sm:py-28 lg:py-40 max-w-4xl mx-auto px-5 sm:px-6 lg:px-12 text-center">
Expand Down
4 changes: 2 additions & 2 deletions app/(marketing)/components/homepage/CapabilitiesGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const capabilities = [
icon: GitBranch,
title: '9 Framework Packs',
description:
'SOC 2, ISO 27001, GDPR, HIPAA, PCI-DSS, NIST CSF, CIS Controls, NDIS Practice Standards, and Essential Eight pre-built.',
'SOC 2, ISO 27001, GDPR, HIPAA, PCI-DSS, NIST CSF, CIS Controls, NDIS Practice Standards, and Essential Eight, pre-built.',
},
{
icon: Shield,
Expand Down Expand Up @@ -61,7 +61,7 @@ const capabilities = [
icon: Bot,
title: 'AI Compliance Assistant',
description:
'Context-aware AI that drafts policies, runs gap analysis, and gives actionable steps powered by your live org data.',
'Context-aware AI that drafts policies, runs gap analysis, and gives actionable steps, powered by your live org data.',
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function ComplianceEngineDemo() {
</div>
<div className="lg:col-span-5">
<p className="max-w-md text-sm leading-relaxed text-slate-400 sm:text-base">
One connected lifecycle obligations become controls, controls
One connected lifecycle, obligations become controls, controls
generate tasks, tasks produce evidence, and every step stays
audit-ready.
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ export function ComplianceNetworkSection() {
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/[0.08] to-transparent" />

<div className="relative z-10 max-w-7xl mx-auto px-6 lg:px-12">
{/* Editorial header asymmetric, left-aligned. A labelled rule and a
{/* Editorial header, asymmetric, left-aligned. A labelled rule and a
paired description column replace the centred eyebrow-pill template. */}
<ScrollReveal variant="blurIn" range={[0, 0.3]} className="mb-10 lg:mb-16">
<div className="grid gap-x-10 gap-y-6 border-b border-white/[0.06] pb-10 lg:grid-cols-12 lg:items-end">
<div className="lg:col-span-7">
{/* Eyebrow as a relationship chain previews the graph below and
{/* Eyebrow as a relationship chain, previews the graph below and
differentiates this header from the labelled-rule used by the
sections above it. */}
<div className="mb-5 flex flex-wrap items-center gap-x-2.5 gap-y-1 text-sm font-semibold uppercase tracking-[0.14em] text-slate-500">
Expand Down
Loading
Loading