File size: 5,695 Bytes
703a33a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | import { useEffect, useState } from "react";
import { ArchitectureSection } from "./components/ArchitectureSection";
import { ContractsSection } from "./components/ContractsSection";
import { DocsPortal } from "./components/DocsPortal";
import { FaqSection } from "./components/FaqSection";
import { FooterCta } from "./components/FooterCta";
import { Hero } from "./components/Hero";
import { OverviewGrid } from "./components/OverviewGrid";
import { RouteMatrix } from "./components/RouteMatrix";
import { Section } from "./components/Section";
import { StudioSection } from "./components/StudioSection";
import { TopNav } from "./components/TopNav";
import { WorkflowShowcase } from "./components/WorkflowShowcase";
import { getConfig, getContent, getContracts } from "./content/api";
import type { AppConfig, ContentResponse, ContractMap } from "./content/types";
function App() {
const [content, setContent] = useState<ContentResponse | null>(null);
const [config, setConfig] = useState<AppConfig | null>(null);
const [contracts, setContracts] = useState<ContractMap | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function bootstrap() {
try {
const [nextConfig, nextContent, nextContracts] = await Promise.all([
getConfig(),
getContent(),
getContracts(),
]);
setConfig(nextConfig);
setContent(nextContent);
setContracts(nextContracts);
} catch (caughtError) {
setError(caughtError instanceof Error ? caughtError.message : "Failed to load app");
}
}
void bootstrap();
}, []);
if (error) {
return (
<main className="app-shell centered">
<div className="shell-block error-card">
<h1>Unable to load Aether Voice Studio</h1>
<p>{error}</p>
</div>
</main>
);
}
if (!content || !config || !contracts) {
return (
<main className="app-shell centered">
<div className="shell-block loading-card">
<h1>Loading Aether Voice Studio</h1>
<p>Preparing the docs surface, route matrix, and demo contracts.</p>
</div>
</main>
);
}
return (
<main className="app-shell">
<TopNav
links={content.site.navigation}
secondaryLinks={content.site.secondaryLinks}
demoMode={config.demoMode}
/>
<Hero hero={content.site.hero} demoMode={config.demoMode} />
<Section
id="overview"
kicker="Product overview"
title="Aether Voice Studio spans live, studio, registry, and route-aware product lanes."
description="This v1 positions the platform as a premium product surface and technical entrypoint rather than a production inference cluster."
>
<OverviewGrid features={content.features} />
</Section>
<Section
id="studio"
kicker="Aether Voice Studio"
title="Separate immediate TTS from long-form voice production."
description="The platform keeps fast preview workflows distinct from studio-grade cloning, design, and dialogue assembly."
>
<StudioSection narrative={content.site.studioNarrative} seedLibrary={content.seedLibrary} />
</Section>
<Section
id="routes"
kicker="Route / Model Matrix"
title="Canonical route intelligence is visible, not hidden."
description="Each route is tied to a workflow class, output contract, and UI surface so the system reads as infrastructure rather than generic AI glue."
>
<RouteMatrix routes={content.routes} />
</Section>
<Section
id="demos"
kicker="Demo workflows"
title="Public-safe demos still signal real operational structure."
description="The workflow panel is lightweight by design and remains useful with local content only."
aside={<span className="route-pill">Port {config.singlePort}</span>}
>
<WorkflowShowcase
demoWorkflows={content.workflows.demo}
creatorWorkflows={content.workflows.creator}
enterpriseWorkflows={content.workflows.enterprise}
demoMode={config.demoMode}
/>
</Section>
<Section
id="docs"
kicker="Docs entry"
title="The Space doubles as a docs-style portal."
description="Overview, architecture, routing, registry, and troubleshooting entry points are organized as a clean documentation surface."
>
<DocsPortal entries={content.docsNav} />
</Section>
<Section
id="architecture"
kicker="Architecture"
title="Frontend, routing, registries, and artifacts are deliberately separated."
description="That separation makes the Space credible today and extendable into richer docs or interactive flows later."
>
<ArchitectureSection layers={content.architecture} />
</Section>
<Section
id="contracts"
kicker="Data Contracts"
title="Machine-readable shapes are public by design."
description="The registry, route matrix, seed library, and provider config are exposed as JSON contracts to signal automation-native architecture."
>
<ContractsSection contracts={contracts} />
</Section>
<Section
id="faq"
kicker="FAQ"
title="Concise answers for route strategy, studio boundaries, and platform vocabulary."
description="The v1 Space emphasizes clarity over gimmicks."
>
<FaqSection faq={content.faq} />
</Section>
<FooterCta cta={content.site.cta} />
</main>
);
}
export default App;
|