diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md
index 855db1b..86bc69a 100644
--- a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md
+++ b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md
@@ -26,6 +26,15 @@ claims over the same capability.
- the public website may be widened as a professional operator/distribution
manual, but that still does not authorize it to claim ownership over the
native simulator job
+- the public website should now also say this plainly in operator-facing terms:
+ the web version is intentionally narrower and materially less powerful for
+ actual simulator work than the downloadable
+- the web version remains justified because it owns account/auth, release
+ posture, pricing, notices, support-safe onboarding, and browser-to-desktop
+ handoff without turning the simulator into a storefront or identity shell
+- the downloadable remains the main product because it owns package-validated
+ training behavior, replay/coaching execution, higher-dimensional runtime
+ families, and the current serious control/runtime evidence
## Refactor toolchain
diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md b/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md
index 7256e5d..0a0e927 100644
--- a/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md
+++ b/docs/v6_5_deep_manual_pack/HyperTwist/PRD.md
@@ -57,6 +57,18 @@ The website is therefore not superfluous, but it is intentionally inferior for
the core simulator job. Public and manual wording must keep that distinction
explicit.
+Concrete interpretation rule:
+
+- the browser version is for public docs, pricing, release posture, notices,
+ support-safe onboarding, protected account state, and browser-to-desktop
+ handoff
+- the browser version is not the place to overclaim package-validated
+ training behavior, higher-dimensional packaged execution, low-latency native
+ input authority, or finished XR/controller runtime ownership
+- the downloadable remains the materially more powerful product surface because
+ it owns the simulator itself, the higher-dimensional family maps, packaged
+ proof, and the current serious training workflows
+
The current first-party website also doubles as a bounded public-facing
operator manual:
diff --git a/website/public/manual/hypertwist-operator-manual.md b/website/public/manual/hypertwist-operator-manual.md
index 5cf5cea..435e97c 100644
--- a/website/public/manual/hypertwist-operator-manual.md
+++ b/website/public/manual/hypertwist-operator-manual.md
@@ -1,6 +1,6 @@
# HyperTwist Operator Manual
-Last updated: 2026-06-30
+Last updated: 2026-07-01
## Purpose
@@ -76,6 +76,32 @@ That narrower browser boundary is intentional. It keeps access, release,
billing, pairing, and legal-distribution work inspectable outside the simulator
while keeping the real training runtime easier to trust.
+### What you do not get if you stay browser-only
+
+If you stay only on the website, you do not get the main simulator value:
+
+- the real classic-cube practice loop
+- recognition, correction closure, and solve-guidance execution
+- replay, coaching, analytics, and local leaderboard continuity
+- dedicated `Magic120Cell` or `MagicCube5D` packaged-family runtime execution
+- the native diagnostics that prove higher-dimensional session, scene,
+ persistence-boundary, and state-semantics ownership
+
+In short:
+
+- the browser version is useful, but it is intentionally weaker than the
+ downloadable for actual training and serious study
+- the downloadable remains the primary product because it is where the current
+ simulator authority really lives
+
+### What the browser version is still excellent for
+
+- public docs, help-center, and route-atlas reading
+- pricing, launch-status, and release-note review
+- account access and protected entitlement posture
+- protected notices and corresponding-source follow-through
+- browser-to-desktop pairing and rollout-safe support coordination
+
## Browser access and account posture
The browser lane is intentionally narrower than the simulator.
@@ -232,6 +258,19 @@ The desktop runtime is the current product center for:
This is the current truthful desktop-first posture. Do not collapse it into a
generic browser simulator claim.
+## Current puzzle and workflow lineup
+
+These are the main study lanes the downloadable already owns today:
+
+- classic-cube practice and timing
+- recognition, reconstruction, and solve guidance
+- replay, coaching, analytics, and operator diagnostics
+- `Magic120Cell` packaged runtime
+- `MagicCube5D` packaged runtime
+- `MagicTile` embedded-browser runtime posture inside Unreal
+
+The website can explain every one of these. The website does not execute them.
+
## Control and settings truth
Current shipped desktop control truth includes:
@@ -351,6 +390,15 @@ Use the desktop runtime when you need:
- higher-dimensional execution
- native diagnostics or runtime-adjacent operator work
+Current public route guidance:
+
+- `/browser` explains why the web version exists and why it stays narrower than
+ the downloadable
+- `/help` acts as the knowledge-base style route for onboarding, controls,
+ troubleshooting, and rollout-safe product questions
+- `/contact` is the direct human lane when the next best move is no longer a
+ manual page
+
## Release, download, and distribution posture
HyperTwist is digitally delivered through browser account access and desktop
diff --git a/website/public/sitemap.xml b/website/public/sitemap.xml
index 543904d..5fbab3b 100644
--- a/website/public/sitemap.xml
+++ b/website/public/sitemap.xml
@@ -3,6 +3,9 @@
https://hypertwist.app/
+
+ https://hypertwist.app/browser
+ https://hypertwist.app/features
@@ -12,6 +15,9 @@
https://hypertwist.app/resources
+
+ https://hypertwist.app/help
+ https://hypertwist.app/getting-started
@@ -24,6 +30,9 @@
https://hypertwist.app/support
+
+ https://hypertwist.app/contact
+ https://hypertwist.app/changelog
diff --git a/website/src/__tests__/App.bootstrap.test.tsx b/website/src/__tests__/App.bootstrap.test.tsx
index 1fbf67d..6d0db40 100644
--- a/website/src/__tests__/App.bootstrap.test.tsx
+++ b/website/src/__tests__/App.bootstrap.test.tsx
@@ -59,7 +59,7 @@ describe('App bootstrap', () => {
render()
- expect(await screen.findByText('HyperTwist turns cube practice into a real operator-grade training stack.')).toBeTruthy()
+ expect(await screen.findByText('From first solves to 120-cell, HyperTwist keeps the real simulator in the downloadable.')).toBeTruthy()
await waitFor(() => {
expect(window.location.pathname).toBe('/')
})
diff --git a/website/src/__tests__/app-route-tree.test.tsx b/website/src/__tests__/app-route-tree.test.tsx
index 6917825..dad6211 100644
--- a/website/src/__tests__/app-route-tree.test.tsx
+++ b/website/src/__tests__/app-route-tree.test.tsx
@@ -158,7 +158,25 @@ describe('AppRouteTree', () => {
expect(screen.getByText('Loading HyperTwist...')).toBeTruthy()
expect(screen.getByText('Public release shell')).toBeTruthy()
expect(screen.getByText(/public product story, current launch posture, and browser-versus-desktop authority map/i)).toBeTruthy()
- expect(await screen.findByText('HyperTwist turns cube practice into a real operator-grade training stack.')).toBeTruthy()
+ expect(await screen.findByText('From first solves to 120-cell, HyperTwist keeps the real simulator in the downloadable.')).toBeTruthy()
+ })
+
+ it('renders the browser-guide page through the real public route tree', async () => {
+ renderRoute('/browser')
+
+ expect(screen.getByText('Browser access guide')).toBeTruthy()
+ expect(screen.getByText('Web version posture')).toBeTruthy()
+ expect(screen.getByText(/browser-versus-downloadable boundary, protected dashboard handoff, and the current web-lane purpose/i)).toBeTruthy()
+ expect(await screen.findByText('The browser version exists to support the downloadable, not replace it.')).toBeTruthy()
+ })
+
+ it('renders the help-center page through the real public route tree', async () => {
+ renderRoute('/help')
+
+ expect(screen.getByText('Help center')).toBeTruthy()
+ expect(screen.getByText('Operator knowledge base')).toBeTruthy()
+ expect(screen.getByText(/onboarding, control truth, browser-to-desktop guidance, and rollout-safe troubleshooting/i)).toBeTruthy()
+ expect(await screen.findByText('Production-grade help for the routes, runtime, and rollout you actually have.')).toBeTruthy()
})
it('renders the pricing page through the real public route tree', async () => {
diff --git a/website/src/__tests__/offline-operator-manual.test.ts b/website/src/__tests__/offline-operator-manual.test.ts
index f2eb3d4..04e1ce3 100644
--- a/website/src/__tests__/offline-operator-manual.test.ts
+++ b/website/src/__tests__/offline-operator-manual.test.ts
@@ -10,10 +10,13 @@ describe('offline operator manual', () => {
expect(manual).toContain('## Why the website stays and where it is intentionally weaker')
expect(manual).toContain('### What the browser does not claim')
+ expect(manual).toContain('### What you do not get if you stay browser-only')
expect(manual).toContain('## First-session verification checklist')
expect(manual).toContain('## Issue reporting checklist')
expect(manual).toContain('desktop-hosted native OpenXR/controller widening is `No-Go`')
expect(manual).toContain('`Magic120Cell`')
expect(manual).toContain('/app/downloads')
+ expect(manual).toContain('/browser')
+ expect(manual).toContain('/help')
})
})
diff --git a/website/src/__tests__/public-marketing-pages.test.tsx b/website/src/__tests__/public-marketing-pages.test.tsx
index 15d4a74..62425f9 100644
--- a/website/src/__tests__/public-marketing-pages.test.tsx
+++ b/website/src/__tests__/public-marketing-pages.test.tsx
@@ -114,11 +114,14 @@ vi.mock('../site-config', () => ({
import {
AboutPage,
+ BrowserExperiencePage,
ChangelogPage,
+ ContactPage,
DocsPage,
DownloadPage,
FeaturesPage,
GettingStartedPage,
+ HelpCenterPage,
HomeLanding,
LaunchStatusPage,
OpenSourceNoticesPage,
@@ -1074,6 +1077,82 @@ describe('public marketing pages', () => {
expect(screen.getByText('Runtime and training issues')).toBeTruthy()
})
+ it('renders the new browser, help, and contact guidance routes with the expected public-manual boundary language', () => {
+ mockGetAuthHealth.mockResolvedValue({
+ ok: true,
+ service: 'hypertwist-auth-server',
+ supertokens: {
+ configured: true,
+ reachable: true,
+ ready: true,
+ apiVersion: '5.4',
+ error: null,
+ oauth: {
+ github: false,
+ google: false,
+ },
+ },
+ fallback: {
+ enabled: true,
+ active: false,
+ reason: null,
+ },
+ billing: {
+ statePath: '/var/lib/hypertwist/auth/hypertwist-billing-state.json',
+ processedEventCount: 0,
+ pricePlanMapConfigured: false,
+ productPlanMapConfigured: false,
+ webhookSecretConfigured: false,
+ },
+ runtime: {
+ mode: 'mixed',
+ public_origin_ready: true,
+ cookie_secure: true,
+ api_domain: 'https://hypertwist.app',
+ website_domain: 'https://hypertwist.app',
+ warnings: [],
+ errors: [],
+ },
+ })
+ mockGetReleaseManifest.mockResolvedValue({
+ ok: true,
+ manifest: {
+ generated_at: '2026-06-22T12:00:00.000Z',
+ support_email: 'hello@hypertwist.app',
+ public_docs_url: 'https://docs.hypertwist.app',
+ release_notes_url: 'https://notes.hypertwist.app',
+ corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
+ open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
+ viewer: {
+ authenticated: false,
+ canDownload: false,
+ plan: null,
+ role: null,
+ accessStatus: null,
+ },
+ platforms: [],
+ },
+ })
+
+ const browserView = renderWithProviders(, ['/browser'])
+ expect(within(browserView.container).getByText('What the browser version is genuinely for')).toBeTruthy()
+ expect(within(browserView.container).getByText('Why the downloadable remains much more powerful')).toBeTruthy()
+ expect(within(browserView.container).getByText('How the browser and downloadable work together')).toBeTruthy()
+ expect(within(browserView.container).getByText('The browser version exists to support the downloadable, not replace it.')).toBeTruthy()
+
+ const helpView = renderWithProviders(, ['/help'])
+ expect(within(helpView.container).getByText('What this help center covers')).toBeTruthy()
+ expect(within(helpView.container).getByText('Pick the right help lane')).toBeTruthy()
+ expect(within(helpView.container).getByText('Current controls and device posture')).toBeTruthy()
+ expect(within(helpView.container).getByText('Need escalation instead of guidance?')).toBeTruthy()
+
+ const contactView = renderWithProviders(, ['/contact'])
+ expect(within(contactView.container).getByText('Contact lanes')).toBeTruthy()
+ expect(within(contactView.container).getByText('Primary contact route')).toBeTruthy()
+ expect(within(contactView.container).getByText('What to include in your message')).toBeTruthy()
+ expect(within(contactView.container).getByText('How HyperTwist classifies escalations')).toBeTruthy()
+ })
+
it('surfaces current packaged desktop proof on the public resources page', () => {
mockGetAuthHealth.mockResolvedValue({
ok: true,
@@ -1712,7 +1791,8 @@ describe('public marketing pages', () => {
renderWithProviders(, ['/changelog'])
- expect(screen.getByText('Latest changes')).toBeTruthy()
+ expect(screen.getByText('Recent release packets')).toBeTruthy()
+ expect(screen.getByText('Detailed chronological feed')).toBeTruthy()
expect(screen.getAllByText('June 24, 2026').length).toBeGreaterThan(0)
expect(screen.getByText('Signed-in operator shell now mirrors the native control roster')).toBeTruthy()
expect(screen.getByText('Native selector-recall diagnostics hardened and revalidated')).toBeTruthy()
diff --git a/website/src/__tests__/public-route-registry.test.ts b/website/src/__tests__/public-route-registry.test.ts
index a9cc5ff..deec560 100644
--- a/website/src/__tests__/public-route-registry.test.ts
+++ b/website/src/__tests__/public-route-registry.test.ts
@@ -19,9 +19,10 @@ describe('public route registry', () => {
it('exposes the intended primary navigation and footer surfaces', () => {
expect(marketingNavLinks).toEqual([
{ to: '/', label: 'Home' },
+ { to: '/browser', label: 'Browser' },
{ to: '/features', label: 'Features' },
{ to: '/about', label: 'About' },
- { to: '/resources', label: 'Resources' },
+ { to: '/help', label: 'Help Center' },
{ to: '/pricing', label: 'Pricing' },
{ to: '/download', label: 'Download' },
])
@@ -30,11 +31,17 @@ describe('public route registry', () => {
to: '/open-source-notices',
label: 'Open Source Notices',
})
+ expect(footerLinks).toContainEqual({
+ to: '/contact',
+ label: 'Contact',
+ })
})
it('keeps auth routes out of crawlable sitemap posture', () => {
expect(crawlablePublicRoutes.map((route) => route.path)).not.toContain('/login')
expect(crawlablePublicRoutes.map((route) => route.path)).not.toContain('/register')
+ expect(crawlablePublicRoutes.map((route) => route.path)).toContain('/browser')
+ expect(crawlablePublicRoutes.map((route) => route.path)).toContain('/help')
expect(crawlablePublicRoutes.map((route) => route.path)).toContain('/getting-started')
expect(crawlablePublicRoutes.map((route) => route.path)).toContain('/launch-status')
})
@@ -62,7 +69,9 @@ describe('public route registry', () => {
const xml = buildPublicSitemapXml()
expect(xml).toContain('https://hypertwist.app/')
+ expect(xml).toContain('https://hypertwist.app/browser')
expect(xml).toContain('https://hypertwist.app/features')
+ expect(xml).toContain('https://hypertwist.app/help')
expect(xml).toContain('https://hypertwist.app/getting-started')
expect(xml).toContain('https://hypertwist.app/launch-status')
expect(xml).not.toContain('/login')
diff --git a/website/src/components/layout/MarketingShell.tsx b/website/src/components/layout/MarketingShell.tsx
index 62cb000..2a6cede 100644
--- a/website/src/components/layout/MarketingShell.tsx
+++ b/website/src/components/layout/MarketingShell.tsx
@@ -16,6 +16,21 @@ export function MarketingShell({
children: React.ReactNode
}) {
const { isAuthenticated } = usePlatformAuth()
+ const footerLookup = new Map(footerLinks.map((link) => [link.to, link]))
+ const footerGroups = [
+ {
+ title: 'Product',
+ routes: ['/', '/browser', '/features', '/about', '/resources', '/help', '/docs'],
+ },
+ {
+ title: 'Access',
+ routes: ['/pricing', '/download', '/getting-started', '/launch-status', '/support', '/contact', '/changelog'],
+ },
+ {
+ title: 'Policy',
+ routes: ['/open-source-notices', '/privacy', '/terms', '/shipping-payment'],
+ },
+ ] as const
return (
+ {group.routes
+ .map((route) => footerLookup.get(route))
+ .filter((link): link is { to: string; label: string } => Boolean(link))
+ .map((link) => (
+
+ {link.label}
+
+ ))}
+
+
))}
diff --git a/website/src/pages/public-pages-commerce.tsx b/website/src/pages/public-pages-commerce.tsx
index 84f220d..cec22f2 100644
--- a/website/src/pages/public-pages-commerce.tsx
+++ b/website/src/pages/public-pages-commerce.tsx
@@ -6,10 +6,11 @@ import { OperationalStatusCallout } from '../components/ui/OperationalStatusCall
import { ProductSurfaceMatrix } from '../components/ui/ProductSurfaceMatrix'
import { PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'
import { ReleaseValidationSummary } from '../components/ui/ReleaseValidationSummary'
-import { paddleReadyDescription } from '../site-config'
+import { brandConfig, paddleReadyDescription } from '../site-config'
import { buildReleaseMetadataItems, resolveReleaseCommerceView } from '../release-manifest'
import { buildLoginPath, buildProtectedDownloadPath, buildSupportPath } from '../site-routes'
import {
+ browserLimitCards,
desktopFirstLaunchCards,
desktopDownloadSteps,
desktopReleaseSignals,
@@ -21,6 +22,7 @@ import {
operatorManualTracks,
privacyBoundaryCards,
productSurfaceMatrixRows,
+ puzzleCatalogCards,
releaseRolloutChecklist,
runtimeControlGuideCards,
supportEscalationCards,
@@ -102,6 +104,12 @@ export function PricingPage() {
+
+
@@ -134,6 +142,12 @@ export function PricingPage() {
description="Plans only make sense if the public pricing lane also says what the entitled desktop software is for once it is installed."
/>
+
+
+
+
+ Open browser guide
+
+
+ Open help center
+
+
+ Contact HyperTwist
+
+
@@ -291,6 +316,26 @@ export function DownloadPage() {
+
+
+
+
Browser guide
+
Read why HyperTwist keeps the web version, what it does well, and where it is intentionally weaker than the downloadable.
+
+
+
Help center
+
Open practical onboarding, controls, and rollout-safe troubleshooting guidance before or after the first install.
+
+
+
Contact
+
Open the human contact lane when the next move is support, rollout coordination, or pricing follow-through.
+
+
+
+
+
+
+
+
+ Contact {brandConfig.contact.email} when the next question is redistribution, corresponding-source follow-through, or release-surface notice posture rather than simulator behavior.
+
+
+
+ Open launch support
+
+
+ Open contact route
+
+
+ For browser-account, billing, release-access, or policy questions, contact {brandConfig.contact.email} and include whether the concern is public, protected, or native-runtime context.
+
+ Terms questions that affect billing, protected release access, or redistribution should go to {brandConfig.contact.email} with the exact public or protected route and the current build or release context.
+
+
+
+ Open rollout support
+
+
+ Open contact route
+
+
- HyperTwist is a native training environment for classic cube, higher-dimensional
- families, browser-assisted recognition, replay explanation, and desktop packaging.
- The public site is intentionally honest: the desktop runtime is real, the browser
- account/dashboard is real, and the optional full-browser simulator path remains spec-only.
+ HyperTwist is a native training environment for classic cube practice, recognition
+ and correction closure, replay explanation, coaching, higher-dimensional puzzle
+ families, and serious packaged study sessions. The web lane is intentionally narrower:
+ it owns access, documentation, release posture, support, and pairing so the
+ downloadable can stay focused on the simulator itself.
Download desktop app
+
+ Why keep the web version?
+
+
+ Open help center
+
Open operator dashboard
-
- Open getting started
-
-
- Explore feature atlas
-
@@ -108,8 +113,13 @@ export function HomeLanding() {
className="hero-visual-card__image"
/>
- Browser account shell outside the simulator. Native Unreal runtime inside the simulator.
+ Browser shell for access, rollout, and support. Native Unreal runtime for the simulator.
+
+
Use the web for pricing, docs, release notes, notices, and protected downloads.
+
Use the downloadable for real cube-state workflows, higher-dimensional maps, and diagnostics.
+
Read XR/controller widening honestly as a separate native completion packet, not as a finished browser or desktop claim today.
{changelogEntries.map((entry) => (
diff --git a/website/src/pages/public-pages.tsx b/website/src/pages/public-pages.tsx
index 8a783e9..801de8f 100644
--- a/website/src/pages/public-pages.tsx
+++ b/website/src/pages/public-pages.tsx
@@ -2,3 +2,4 @@ export * from './public-pages-marketing'
export * from './public-pages-features'
export * from './public-pages-commerce'
export * from './public-pages-launch'
+export * from './public-pages-guides'
diff --git a/website/src/public-route-registry.json b/website/src/public-route-registry.json
index 924a71d..0b80897 100644
--- a/website/src/public-route-registry.json
+++ b/website/src/public-route-registry.json
@@ -9,6 +9,16 @@
"footer": false,
"crawlable": true
},
+ {
+ "path": "/browser",
+ "label": "Browser",
+ "loaderTitle": "Browser access guide",
+ "loaderEyebrow": "Web version posture",
+ "loaderDescription": "Loading the browser-versus-downloadable boundary, protected dashboard handoff, and the current web-lane purpose.",
+ "nav": true,
+ "footer": true,
+ "crawlable": true
+ },
{
"path": "/features",
"label": "Features",
@@ -35,6 +45,16 @@
"loaderTitle": "Resources",
"loaderEyebrow": "Public reference portal",
"loaderDescription": "Loading rollout-safe resources, simulator guidance, and current higher-dimensional operator references.",
+ "nav": false,
+ "footer": true,
+ "crawlable": true
+ },
+ {
+ "path": "/help",
+ "label": "Help Center",
+ "loaderTitle": "Help center",
+ "loaderEyebrow": "Operator knowledge base",
+ "loaderDescription": "Loading onboarding, control truth, browser-to-desktop guidance, and rollout-safe troubleshooting.",
"nav": true,
"footer": true,
"crawlable": true
@@ -66,7 +86,7 @@
"loaderEyebrow": "Public manual",
"loaderDescription": "Loading the feature-registry-backed manual, rollout doctrine, and browser-versus-desktop usage guide.",
"nav": false,
- "footer": false,
+ "footer": true,
"crawlable": true
},
{
@@ -76,7 +96,17 @@
"loaderEyebrow": "Operator help lane",
"loaderDescription": "Loading rollout guidance, account and entitlement help, and browser-to-desktop escalation routes.",
"nav": false,
- "footer": false,
+ "footer": true,
+ "crawlable": true
+ },
+ {
+ "path": "/contact",
+ "label": "Contact",
+ "loaderTitle": "Contact HyperTwist",
+ "loaderEyebrow": "Human help lane",
+ "loaderDescription": "Loading operator contact paths, escalation packets, and release-aware support follow-through.",
+ "nav": false,
+ "footer": true,
"crawlable": true
},
{
@@ -86,7 +116,7 @@
"loaderEyebrow": "Public release history",
"loaderDescription": "Loading recent browser, package, control-boundary, and rollout changes from the active shipping lane.",
"nav": false,
- "footer": false,
+ "footer": true,
"crawlable": true
},
{
diff --git a/website/src/router/PublicRoutes.tsx b/website/src/router/PublicRoutes.tsx
index 0be5cac..dbb777e 100644
--- a/website/src/router/PublicRoutes.tsx
+++ b/website/src/router/PublicRoutes.tsx
@@ -4,13 +4,16 @@ import { GeneralPageLoader } from '../components/ui/Skeletons'
import { publicRouteRegistry, type PublicRouteDefinition } from '../public-route-registry'
const HomeLanding = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.HomeLanding })))
+const BrowserExperiencePage = lazy(() => import('../pages/public-pages-guides').then((m) => ({ default: m.BrowserExperiencePage })))
const FeaturesPage = lazy(() => import('../pages/public-pages-features').then((m) => ({ default: m.FeaturesPage })))
const AboutPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.AboutPage })))
const ResourcesPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.ResourcesPage })))
+const HelpCenterPage = lazy(() => import('../pages/public-pages-guides').then((m) => ({ default: m.HelpCenterPage })))
const GettingStartedPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.GettingStartedPage })))
const LaunchStatusPage = lazy(() => import('../pages/public-pages-launch').then((m) => ({ default: m.LaunchStatusPage })))
const DocsPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.DocsPage })))
const SupportPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.SupportPage })))
+const ContactPage = lazy(() => import('../pages/public-pages-guides').then((m) => ({ default: m.ContactPage })))
const ChangelogPage = lazy(() => import('../pages/public-pages-marketing').then((m) => ({ default: m.ChangelogPage })))
const PricingPage = lazy(() => import('../pages/public-pages-commerce').then((m) => ({ default: m.PricingPage })))
const DownloadPage = lazy(() => import('../pages/public-pages-commerce').then((m) => ({ default: m.DownloadPage })))
@@ -23,13 +26,16 @@ const RegisterPage = lazy(() => import('../pages/auth-pages').then((m) => ({ def
const publicRouteElements: Record = {
'/': ,
+ '/browser': ,
'/features': ,
'/about': ,
'/resources': ,
+ '/help': ,
'/getting-started': ,
'/launch-status': ,
'/docs': ,
'/support': ,
+ '/contact': ,
'/changelog': ,
'/pricing': ,
'/download': ,
diff --git a/website/src/site-data.ts b/website/src/site-data.ts
index 6e174b8..bd9d6d7 100644
--- a/website/src/site-data.ts
+++ b/website/src/site-data.ts
@@ -930,8 +930,10 @@ export const resourceCollections = [
title: 'Product truth',
items: [
'Feature registry-backed descriptions only',
+ 'Dedicated browser guide for the public web-version-versus-downloadable boundary',
'Dedicated getting-started route for the first real browser-to-desktop operator journey',
'Dedicated launch-status route for the canonical preview-versus-launch authority surface',
+ 'Dedicated help-center route for product-safe onboarding and troubleshooting',
'Public feature atlas for the real browser-versus-desktop product split',
'Roadmap-honest separation between shipped and retained capability',
'Release notes that surface what actually landed',
@@ -983,12 +985,257 @@ export const resourceCollections = [
items: [
'Auth fallback posture and mixed-mode recovery guidance',
'Release-authority fallback without raw package-delivery overclaim',
+ 'Direct contact route for operator, rollout, pricing, and legal follow-through questions',
'Account, package, runtime, and compliance issue separation',
'Operator-safe next steps when browser authority is degraded',
],
},
] as const
+export const browserPurposeCards = [
+ {
+ title: 'Use the browser for access, release, and rollout posture',
+ description: 'The browser lane owns the work that should stay inspectable outside the simulator.',
+ bullets: [
+ 'Open public pages for product research, pricing, release notes, legal notices, and launch-readiness posture.',
+ 'Use the protected browser dashboard for sign-in, entitlement, billing, protected downloads, and desktop-link pairing.',
+ 'Keep rollout, purchase, and legal-follow-through work on the web so the simulator is not forced to become a storefront or auth shell.',
+ ],
+ },
+ {
+ title: 'Use the browser for product-safe guidance and onboarding',
+ description: 'The web version is strong when the job is explanation, orientation, or operator coordination rather than simulator execution.',
+ bullets: [
+ 'Use the public docs, help, resources, and support routes as the current operator manual and rollout guide.',
+ 'Review first-launch guidance, control truth, package proof, and support lanes before deeper deployment or training work.',
+ 'Use the browser shell when a studio or buyer needs to understand what is real today without opening the native runtime first.',
+ ],
+ },
+ {
+ title: 'Use the browser after install when account state changes',
+ description: 'The browser remains part of the product after the desktop runtime is installed, but for bounded reasons.',
+ bullets: [
+ 'Return to the browser for account changes, plan changes, desktop-link refresh, protected notices, release-manifest review, and support escalation.',
+ 'Keep browser issues separated from native runtime issues so support can diagnose the correct surface quickly.',
+ 'Treat the browser as the operator and distribution shell around the downloadable simulator, not as a hidden second simulator.',
+ ],
+ },
+] as const
+
+export const browserLimitCards = [
+ {
+ title: 'What the browser version does not currently do',
+ description: 'The web lane is intentionally narrower and materially less powerful for the core simulator job.',
+ bullets: [
+ 'It does not own package-validated training behavior, replay execution, or the higher-dimensional packaged family maps.',
+ 'It does not own low-latency native input, device/runtime integration, or the dedicated Unreal session and scene surfaces that power the downloadable.',
+ 'It does not own finished OpenXR/controller runtime behavior, user-facing rebinding, or packaged controller validation.',
+ ],
+ },
+ {
+ title: 'Why the downloadable is the primary product',
+ description: 'The downloadable stays primary because that is where the serious simulator work actually lives.',
+ bullets: [
+ 'The desktop runtime owns recognition, correction closure, replay, coaching, analytics, and genuine session continuity.',
+ 'It owns the current dedicated `Magic120Cell` and `MagicCube5D` runtime-state, projection, persistence, and training-map execution lanes.',
+ 'It is also the current authority for packaged proof, native diagnostics, control roster truth, and serious study sessions.',
+ ],
+ },
+ {
+ title: 'When browser-only use is still worthwhile',
+ description: 'The website is not superfluous just because it is narrower.',
+ bullets: [
+ 'Use it for product evaluation, account access, protected release posture, billing, notices, help, and launch-readiness review.',
+ 'Use it when a team needs product-safe explanation, public references, or rollout coordination without opening the simulator.',
+ 'Use it as the bounded bridge into the desktop runtime rather than as a lesser substitute for the simulator itself.',
+ ],
+ },
+] as const
+
+export const browserWorkflowTracks = [
+ {
+ title: '1. Start on the web before you install anything',
+ description: 'The first job is understanding release posture and choosing the right operator path.',
+ steps: [
+ 'Review launch status, pricing, and download posture on the public site.',
+ 'Open docs, help, or resources if the team still needs rollout-safe explanation of the product topology.',
+ 'Choose the correct platform and plan posture before you cross into the protected browser shell.',
+ ],
+ },
+ {
+ title: '2. Use the protected browser shell for account-aware follow-through',
+ description: 'The browser becomes stronger after sign-in, but still stays bounded to account and release work.',
+ steps: [
+ 'Sign in, review account and entitlement posture, and generate a desktop-link token when needed.',
+ 'Use protected downloads and notices instead of expecting anonymous public pages to expose raw delivery authority.',
+ 'Keep the browser focused on release, billing, pairing, and rollout posture rather than simulator execution.',
+ ],
+ },
+ {
+ title: '3. Hand off to the downloadable for the real simulator',
+ description: 'The browser flow succeeds when it leads cleanly into the desktop runtime instead of pretending to replace it.',
+ steps: [
+ 'Install the package-validated desktop build and complete the bounded browser-to-desktop handoff.',
+ 'Use the desktop runtime for actual training, higher-dimensional work, replay, and diagnostics.',
+ 'Return to the browser later only when account, notices, rollout, or support context becomes the next real concern.',
+ ],
+ },
+] as const
+
+export const puzzleCatalogCards = [
+ {
+ title: 'Classic-cube practice and timing',
+ description: 'The downloadable already owns the current day-to-day solving lane for serious training use.',
+ bullets: [
+ 'Classic timer, scramble, hints, mode switching, voice shortcuts, and replay-aware practice already ship.',
+ 'The public control truth is literal today: the shipped `classic-wca-keyboard/v1` profile plus click/touch, orbit, zoom, hint, and hold-to-talk behavior.',
+ 'This is the fastest way to verify that a fresh install matches the current public product story.',
+ ],
+ },
+ {
+ title: 'Recognition, reconstruction, and solve guidance',
+ description: 'HyperTwist already treats physical-cube intake and correction closure as real first-party product work.',
+ bullets: [
+ 'Use the desktop runtime for bounded capture, browser-assisted recognition, manual correction closure, and solve-guidance readout.',
+ 'The browser shell helps operators reach this workflow, but the actual reconstruction authority stays in the native runtime.',
+ 'This keeps physical practice and analytical follow-through inside one coherent training system.',
+ ],
+ },
+ {
+ title: 'Replay, coaching, and analytics',
+ description: 'The downloadable also owns session review, training continuity, and operator-facing evidence.',
+ bullets: [
+ 'Replay capture, coaching review, local leaderboard persistence, diagnostics, and operator evidence already ship.',
+ 'These surfaces are part of the native runtime, not detached browser widgets pretending to be simulator parity.',
+ 'This is one of the clearest reasons the downloadable remains much more powerful than the web lane.',
+ ],
+ },
+ {
+ title: 'Magic120Cell packaged runtime',
+ description: 'HyperTwist already owns a real dedicated higher-dimensional family lane in the downloadable.',
+ bullets: [
+ 'The desktop runtime owns live `Magic120Cell` session surfaces, scene surfaces, symmetry/focus posture, and persisted selector continuity.',
+ 'Operators can inspect session, interactive-scene, persistence-boundary, and state-semantics ownership directly in native diagnostics.',
+ 'This lane is described on the public site, but it is only executed in the downloadable runtime.',
+ ],
+ },
+ {
+ title: 'MagicCube5D packaged runtime',
+ description: 'The downloadable already carries real 5D runtime ownership instead of just broad capability claims.',
+ bullets: [
+ 'Use the dedicated `MagicCube5D` map for projection-distance, stereo, focus, and face-visibility study inside the native runtime.',
+ 'Native diagnostics already expose the owning session, interactive-scene, persistence, and state-semantics seams for this family too.',
+ 'The browser can document and coordinate this lane, but it does not replace the downloadable that executes it.',
+ ],
+ },
+ {
+ title: 'MagicTile embedded-browser lane',
+ description: 'HyperTwist also carries a bounded non-Euclidean lane, but it is still intentionally hosted inside the desktop product.',
+ bullets: [
+ 'The current live `MagicTile` posture runs through the embedded browser host inside Unreal rather than through the public website.',
+ 'State bridge, scramble normalization, and timer continuity are already first-party owned around that host posture.',
+ 'Native renderer widening remains an explicit gate, so the public product story stays honest about where this lane currently lives.',
+ ],
+ },
+] as const
+
+export const audienceFitCards = [
+ {
+ title: 'New solvers',
+ description: 'The product already supports a guided early-training lane instead of only expert tooling.',
+ bullets: [
+ 'Use classic timing, hints, solve guidance, and replay-backed review to build confidence from the start.',
+ 'The website can explain the first-session path before the downloadable takes over for the real practice loop.',
+ ],
+ },
+ {
+ title: 'Serious daily trainers',
+ description: 'This is the current core audience for the desktop runtime.',
+ bullets: [
+ 'Recognition, replay, coaching, diagnostics, and continuity are already designed to support repeated deliberate practice.',
+ 'The browser lane stays useful around that work for release posture, account access, and support-safe coordination.',
+ ],
+ },
+ {
+ title: 'Hypercubers and topology-focused learners',
+ description: 'HyperTwist is already unusual in that it treats higher-dimensional work as a real shipping lane.',
+ bullets: [
+ 'Dedicated `Magic120Cell`, `MagicCube5D`, and bounded `MagicTile` posture are public, truthful, and source-backed today.',
+ 'The downloadable remains essential here because the higher-dimensional runtime ownership is not a browser claim.',
+ ],
+ },
+ {
+ title: 'Studios, educators, and rollout owners',
+ description: 'The website matters most for teams that need distribution, launch, and support posture before training sessions begin.',
+ bullets: [
+ 'Pricing, notices, support, launch status, docs, help, and browser-to-desktop handoff are deliberate operator surfaces.',
+ 'This is the strongest reason the browser lane is still worth keeping even though the downloadable remains the main product.',
+ ],
+ },
+] as const
+
+export const helpCenterCards = [
+ {
+ title: 'Account, access, and protected downloads',
+ description: 'Use the help center when the next task is getting into the right browser or release lane safely.',
+ bullets: [
+ 'Choose the right public route, preserve the requested platform through sign-in, and use the protected dashboard for entitlement-aware delivery.',
+ 'Keep sign-in, release, and desktop-link questions attached to the browser shell instead of flattening them into simulator bugs.',
+ ],
+ },
+ {
+ title: 'First launch and desktop verification',
+ description: 'The help center should also explain what a good first packaged session looks like.',
+ bullets: [
+ 'Verify package proof, release notes, the shipped control roster, and the classic-cube lane before broader rollout.',
+ 'Confirm the higher-dimensional family you plan to use instead of inferring readiness from broad marketing copy alone.',
+ ],
+ },
+ {
+ title: 'Controls, settings, and current XR truth',
+ description: 'The current input story is strong, but it is bounded and should be taught honestly.',
+ bullets: [
+ 'Keyboard, mouse, touch, camera, immersive settings, selector continuity, and dedicated-family view ownership are already real.',
+ 'The current desktop-hosted OpenXR/controller widening boundary remains explicit No-Go until dedicated runtime owners, rebinding ownership, and Windows packaged controller proof all exist together.',
+ ],
+ },
+ {
+ title: 'Rollout, pricing, notices, and release follow-through',
+ description: 'Help is not only for runtime bugs. It is also for distribution-safe operation.',
+ bullets: [
+ 'Use pricing, launch status, notices, and corresponding-source guidance together when a team is evaluating public rollout.',
+ 'Keep commercial, legal, release, and simulator questions separated so operators can move faster with less confusion.',
+ ],
+ },
+] as const
+
+export const contactChannelCards = [
+ {
+ title: 'Operator support',
+ description: 'Use this when a real user session is blocked by account, entitlement, or rollout issues.',
+ bullets: [
+ `Contact ${brandConfig.contact.email} for access, release enablement, desktop-link pairing trouble, or protected browser-lane follow-through.`,
+ 'Include the exact route, plan posture, requested platform, and whether the failure is public, protected, or native.',
+ ],
+ },
+ {
+ title: 'Runtime issue reporting',
+ description: 'Use this when the downloadable itself behaves unexpectedly.',
+ bullets: [
+ 'Name the affected lane: classic cube, recognition, replay/coaching, `Magic120Cell`, `MagicCube5D`, or `MagicTile`.',
+ 'Include build/channel context, control posture, and whether the issue is a real shipped regression or a still-explicit unfinished XR/controller expectation.',
+ ],
+ },
+ {
+ title: 'Studio rollout and commercial contact',
+ description: 'Use this when the question is deployment, pricing, or broader rollout readiness rather than one operator session.',
+ bullets: [
+ 'Bundle plan, platform, launch posture, notices, and release expectations together so commercial follow-through stays attached to real package and legal truth.',
+ 'Use this lane for production-oriented training programs, deployment review, and release-safe distribution planning.',
+ ],
+ },
+] as const
+
export const publicManualRouteAtlasCards = [
{
title: 'Home',
@@ -1000,6 +1247,16 @@ export const publicManualRouteAtlasCards = [
'Points operators toward getting started, pricing, download, and the protected dashboard without overclaiming browser parity.',
],
},
+ {
+ title: 'Browser access guide',
+ route: '/browser',
+ description: 'Open this route when you need the cleanest public explanation of what the web version is for, why it is intentionally narrower, and when to move into the downloadable.',
+ bullets: [
+ 'Explains the browser shell as a real operator/distribution surface instead of a half-promised simulator.',
+ 'Shows what the browser version does well, what it deliberately does not do, and why the downloadable remains the primary product.',
+ 'Keeps account, protected dashboard, and desktop handoff decisions visible in one place.',
+ ],
+ },
{
title: 'Feature atlas',
route: '/features',
@@ -1040,6 +1297,16 @@ export const publicManualRouteAtlasCards = [
'Acts as the shortest handoff-friendly onboarding surface on the public site.',
],
},
+ {
+ title: 'Help Center',
+ route: '/help',
+ description: 'Open this route when you need product-safe troubleshooting, onboarding guidance, control truth, or rollout-safe answers before escalating into support.',
+ bullets: [
+ 'Collects first-launch, controls, browser-to-desktop handoff, and release-surface guidance into one knowledge-base style route.',
+ 'Separates help-center guidance from direct support escalation so operators can self-serve first without losing product truth.',
+ 'Connects questions back to docs, support, download, and the protected dashboard when a live next step exists.',
+ ],
+ },
{
title: 'Launch status',
route: '/launch-status',
@@ -1070,6 +1337,16 @@ export const publicManualRouteAtlasCards = [
'Mirrors the same browser-versus-desktop split so support does not soften product truth.',
],
},
+ {
+ title: 'Contact',
+ route: '/contact',
+ description: 'Open this route when a human contact path, escalation expectation, or issue-report packet is the next real step.',
+ bullets: [
+ 'Provides the direct operator contact lane alongside what information to include for faster diagnosis.',
+ 'Keeps runtime, rollout, account, and legal/commercial contacts separated instead of flattening them together.',
+ 'Links back to support topics, download posture, and public/protected route ownership as needed.',
+ ],
+ },
{
title: 'Pricing',
route: '/pricing',
@@ -1142,6 +1419,69 @@ export const publicManualRouteAtlasCards = [
},
] as const
+export const releasePacketCards = [
+ {
+ date: 'June 30, 2026',
+ version: 'Public manual deepening packet',
+ category: 'Website, onboarding, and operator documentation',
+ notes: [
+ 'Broadened the public and offline operator manual so the website now explains concrete desktop workflows, controls, higher-dimensional families, and release follow-through instead of only broad topology prose.',
+ 'Made the browser-versus-desktop split explicit on the highest-traffic public routes so teams no longer have to infer why the downloadable remains the primary simulator.',
+ 'Kept the current XR/controller boundary visible while strengthening what the public site can honestly claim today.',
+ ],
+ },
+ {
+ date: 'June 29, 2026',
+ version: 'Validation and package-proof refresh',
+ category: 'Release integrity and package evidence',
+ notes: [
+ 'Revalidated the exact-source browser surface and refreshed the packaged higher-dimensional proof so public release pages stay attached to current native evidence.',
+ 'Reran owned source and browser validation without widening product scope and kept the live preview lane green.',
+ 'Preserved the rule that native package proof, browser release posture, and legal-distribution follow-through move together.',
+ ],
+ },
+ {
+ date: 'June 28, 2026',
+ version: 'Native diagnostics truth packet',
+ category: 'Controls, settings, and higher-dimensional ownership',
+ notes: [
+ 'Tightened native control, settings, continuity, and active-scene diagnostics so operators can see the exact higher-dimensional ownership seams that are live today.',
+ 'Improved public and protected manual language to reflect those stronger native proofs instead of leaving them buried inside internal diagnostics only.',
+ 'Strengthened the public route atlas so operators can navigate documentation, help, release, and legal surfaces as one coherent product shell.',
+ ],
+ },
+ {
+ date: 'June 27, 2026',
+ version: 'Launch-authority and onboarding packet',
+ category: 'Public routes, protected routes, and browser shell startup',
+ notes: [
+ 'Added dedicated public launch-status and getting-started routes plus stronger protected launch authority so rollout truth stopped depending on scattered callouts.',
+ 'Improved browser auth behavior, startup loading posture, and public/protected route continuity without implying browser simulator parity.',
+ 'Turned the first real desktop-session path into a clearer public manual route instead of burying it across unrelated pages.',
+ ],
+ },
+ {
+ date: 'June 24 to June 25, 2026',
+ version: 'Native XR-boundary and control-roster packet',
+ category: 'Desktop control truth and public honesty',
+ notes: [
+ 'Promoted the literal shipped control roster, settings ownership, and higher-dimensional state seams into stable native/operator surfaces.',
+ 'Kept the desktop-hosted OpenXR/controller widening decision explicit, including the reopen requirements for dedicated runtime owners, rebinding ownership, and Windows packaged controller validation.',
+ 'Mirrored that truth into the public manual, pricing, download, and support surfaces so the website cannot overclaim what the downloadable has not yet finished.',
+ ],
+ },
+ {
+ date: 'June 18 to June 23, 2026',
+ version: 'Packaging, browser shell, and MagicTile hardening packet',
+ category: 'Phase 10 package integrity plus bounded browser/runtime expansion',
+ notes: [
+ 'Closed package and integration hardening while keeping the embedded browser shell, release notes, and packaged-proof story aligned.',
+ 'Hardened MagicTile behavior proof without reopening native renderer widening and preserved the browser-host decision as the current honest shipping posture.',
+ 'Expanded the public site into a bounded operator/distribution surface around the downloadable rather than a replacement for it.',
+ ],
+ },
+] as const
+
export const changelogEntries = [
{
date: 'June 30, 2026',
diff --git a/website/src/styles/global.css b/website/src/styles/global.css
index 05a9e98..6ee080d 100644
--- a/website/src/styles/global.css
+++ b/website/src/styles/global.css
@@ -94,12 +94,20 @@ img {
align-items: center;
justify-content: space-between;
gap: 1.5rem;
- padding: 1.25rem clamp(1rem, 3vw, 2.25rem);
- border-bottom: 1px solid var(--ht-border);
+ padding: 1.35rem clamp(1rem, 3vw, 2.5rem);
+ border: 1px solid rgba(255, 255, 255, 0.04);
backdrop-filter: blur(18px);
- background: rgba(8, 12, 22, 0.42);
+ background:
+ radial-gradient(circle at top, rgba(84, 203, 255, 0.08), transparent 46%),
+ linear-gradient(180deg, rgba(8, 12, 22, 0.82), rgba(10, 16, 30, 0.72));
position: sticky;
top: 0;
+ margin: 0.75rem auto 0;
+ width: min(1260px, calc(100vw - 2rem));
+ border-radius: 1.6rem;
+ box-shadow:
+ inset 0 1px 0 rgba(255, 255, 255, 0.04),
+ 0 22px 60px rgba(0, 0, 0, 0.22);
}
.brand-mark {
@@ -111,10 +119,15 @@ img {
.brand-mark__image,
.app-sidebar__brand-image {
- width: 3rem;
- height: 3rem;
+ width: 5.4rem;
+ height: 5.4rem;
object-fit: contain;
- filter: drop-shadow(0 0 18px rgba(84, 203, 255, 0.2));
+ filter: drop-shadow(0 0 30px rgba(84, 203, 255, 0.24));
+}
+
+.brand-mark__copy {
+ display: grid;
+ gap: 0.2rem;
}
.brand-mark strong,
@@ -122,6 +135,8 @@ img {
display: block;
font-family: var(--font-display);
letter-spacing: 0.02em;
+ font-size: clamp(1.35rem, 2vw, 1.7rem);
+ line-height: 0.96;
}
.brand-mark small,
@@ -132,6 +147,11 @@ img {
color: var(--ht-muted);
}
+.brand-mark small {
+ font-size: 0.98rem;
+ max-width: 29rem;
+}
+
.site-nav,
.site-header__actions,
.button-row,
@@ -152,6 +172,11 @@ img {
justify-content: center;
}
+.site-header__actions {
+ flex-wrap: wrap;
+ justify-content: flex-end;
+}
+
.button-row {
flex-wrap: wrap;
}
@@ -165,6 +190,7 @@ img {
padding: 0.7rem 0.95rem;
border-radius: 999px;
color: var(--ht-muted);
+ font-weight: 600;
transition: 160ms ease;
}
@@ -182,12 +208,13 @@ img {
justify-content: center;
gap: 0.5rem;
min-height: 2.8rem;
- padding: 0.8rem 1.1rem;
+ padding: 0.82rem 1.18rem;
border-radius: 999px;
border: 1px solid transparent;
font-weight: 700;
+ letter-spacing: 0.01em;
cursor: pointer;
- transition: transform 160ms ease, background 160ms ease, border-color 160ms ease, color 160ms ease;
+ transition: transform 160ms ease, background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease;
}
.button:hover {
@@ -197,10 +224,11 @@ img {
.button--primary {
background: linear-gradient(120deg, var(--ht-amber), #ffc788);
color: #09111d;
+ box-shadow: 0 14px 34px rgba(247, 178, 103, 0.24);
}
.button--ghost {
- background: rgba(255, 255, 255, 0.02);
+ background: rgba(255, 255, 255, 0.04);
border-color: var(--ht-border);
color: var(--ht-text);
}
@@ -217,13 +245,35 @@ img {
}
.page-main {
- width: min(1180px, calc(100vw - 2rem));
+ width: min(1260px, calc(100vw - 2rem));
margin: 0 auto;
padding-bottom: 4rem;
}
.page-hero {
- padding: clamp(2.25rem, 6vw, 5rem) 0 1.5rem;
+ position: relative;
+ overflow: hidden;
+ margin-top: 1rem;
+ padding: clamp(2.25rem, 6vw, 4.6rem) clamp(1.2rem, 3vw, 2.2rem) 1.75rem;
+ border: 1px solid var(--ht-border);
+ border-radius: 2rem;
+ background:
+ radial-gradient(circle at top, rgba(84, 203, 255, 0.14), transparent 42%),
+ radial-gradient(circle at 82% 18%, rgba(247, 178, 103, 0.12), transparent 28%),
+ linear-gradient(180deg, rgba(10, 16, 30, 0.88), rgba(7, 11, 20, 0.78));
+ box-shadow:
+ inset 0 1px 0 rgba(255, 255, 255, 0.05),
+ 0 32px 90px rgba(0, 0, 0, 0.2);
+}
+
+.page-hero::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background:
+ linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.08), transparent);
+ mask-image: linear-gradient(180deg, rgba(255,255,255,0.5), transparent 72%);
}
.eyebrow {
@@ -258,6 +308,13 @@ img {
word-break: break-word;
}
+.page-hero__lede {
+ position: relative;
+ z-index: 1;
+ max-width: 60rem;
+ font-size: clamp(1rem, 1.3vw, 1.16rem);
+}
+
.hero-panel,
.page-section,
.site-footer,
@@ -273,18 +330,26 @@ img {
border: 1px solid var(--ht-border);
background: var(--ht-surface);
border-radius: 1.5rem;
- box-shadow: 0 24px 90px rgba(0, 0, 0, 0.15);
+ box-shadow:
+ inset 0 1px 0 rgba(255, 255, 255, 0.04),
+ 0 24px 90px rgba(0, 0, 0, 0.15);
backdrop-filter: blur(18px);
}
.hero-panel {
+ position: relative;
+ overflow: hidden;
padding: clamp(1.25rem, 3vw, 2rem);
+ background:
+ radial-gradient(circle at top left, rgba(84, 203, 255, 0.12), transparent 32%),
+ radial-gradient(circle at bottom right, rgba(247, 178, 103, 0.1), transparent 28%),
+ var(--ht-surface);
}
.hero-grid {
display: grid;
grid-template-columns: minmax(0, 1.35fr) minmax(300px, 0.85fr);
- gap: 1.5rem;
+ gap: 1.8rem;
align-items: center;
}
@@ -294,6 +359,8 @@ img {
}
.hero-visual-card {
+ position: relative;
+ overflow: hidden;
padding: 1.2rem;
background:
radial-gradient(circle at top, rgba(84, 203, 255, 0.18), transparent 42%),
@@ -319,6 +386,9 @@ img {
.metric-card {
flex: 1 1 210px;
padding: 1rem 1.1rem;
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)),
+ rgba(10, 16, 30, 0.58);
}
.metric-card strong {
@@ -333,7 +403,7 @@ img {
.page-section {
margin-top: 1.4rem;
- padding: clamp(1.25rem, 3vw, 1.85rem);
+ padding: clamp(1.3rem, 3vw, 1.95rem);
}
.section-heading {
@@ -346,6 +416,7 @@ img {
.timeline-entry h3 {
margin: 0;
font-family: var(--font-display);
+ line-height: 1.04;
}
.card-grid,
@@ -368,6 +439,17 @@ img {
.callout,
.timeline-entry {
padding: 1.15rem;
+ transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
+}
+
+.card:hover,
+.callout:hover,
+.timeline-entry:hover {
+ transform: translateY(-2px);
+ border-color: rgba(247, 178, 103, 0.26);
+ box-shadow:
+ inset 0 1px 0 rgba(255, 255, 255, 0.04),
+ 0 28px 84px rgba(0, 0, 0, 0.18);
}
.card--selected {
@@ -455,7 +537,9 @@ img {
padding: 1.2rem;
border: 1px solid var(--ht-border);
border-radius: 1.3rem;
- background: rgba(10, 16, 30, 0.56);
+ background:
+ linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent 24%),
+ rgba(10, 16, 30, 0.56);
}
.feature-band__card--link {
@@ -510,6 +594,9 @@ img {
.timeline-entry {
border-left: 4px solid var(--ht-amber);
+ background:
+ linear-gradient(180deg, rgba(247, 178, 103, 0.04), transparent 26%),
+ var(--ht-surface);
}
.timeline-entry__date {
@@ -520,15 +607,31 @@ img {
}
.site-footer {
- width: min(1180px, calc(100vw - 2rem));
+ width: min(1260px, calc(100vw - 2rem));
margin: 1rem auto 2rem;
- padding: 1.2rem;
+ padding: 1.35rem;
display: grid;
- gap: 0.9rem;
+ gap: 1.1rem;
+}
+
+.site-footer__grid {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 1rem;
+}
+
+.site-footer__group {
+ display: grid;
+ gap: 0.7rem;
}
.site-footer__links {
flex-wrap: wrap;
+ flex-direction: column;
+}
+
+.site-footer__contact {
+ color: var(--ht-text);
}
.site-footer__note {
@@ -816,6 +919,10 @@ code {
.app-main-shell {
padding: 0 0.8rem 0.8rem;
}
+
+ .site-footer__grid {
+ grid-template-columns: 1fr;
+ }
}
@media (max-width: 720px) {
@@ -827,6 +934,7 @@ code {
.site-header {
padding-inline: 0.8rem;
+ border-radius: 1.25rem;
}
.page-main {
@@ -840,6 +948,11 @@ code {
flex-direction: column;
}
+ .brand-mark__image {
+ width: 4.4rem;
+ height: 4.4rem;
+ }
+
.button-row > * {
width: 100%;
}