Clarify public browser versus desktop truth
This commit is contained in:
parent
58cb19955b
commit
667c151079
7 changed files with 140 additions and 4 deletions
|
|
@ -316,6 +316,26 @@ Latest public-manual clarity follow-up later on `2026-06-24`:
|
|||
|
||||
That follow-up stayed green under:
|
||||
|
||||
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx`
|
||||
- `1` test file passed
|
||||
- `12` tests passed
|
||||
|
||||
Latest browser-versus-desktop reality follow-up later on `2026-06-24`:
|
||||
|
||||
- the homepage, About, Docs, and Download routes now also share a reusable
|
||||
direct comparison section answering the more pointed operator question:
|
||||
why keep both a website and a desktop runtime at all
|
||||
- that section now states plainly:
|
||||
- what the website is for
|
||||
- what the desktop runtime is for
|
||||
- why the browser is intentionally narrower
|
||||
- what current input/XR/settings truth is actually shipped
|
||||
- the public FAQ wording also tightened so the browser lane is described as
|
||||
deliberately narrower for simulator work, not as a weaker accidental copy of
|
||||
the native runtime
|
||||
|
||||
That follow-up stayed green under:
|
||||
|
||||
- `npm --prefix website test -- --run src/__tests__/public-marketing-pages.test.tsx`
|
||||
- `1` test file passed
|
||||
- `12` tests passed
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -243,6 +243,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Operator checkout URL: missing')).toBeTruthy()
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('How the release lane works')).toBeTruthy()
|
||||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy()
|
||||
expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
|
||||
expect(screen.getByText('First launch and desktop setup')).toBeTruthy()
|
||||
expect(screen.getByText('Digital delivery workflow')).toBeTruthy()
|
||||
|
|
@ -407,6 +409,9 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Current public site status')).toBeTruthy()
|
||||
expect(await screen.findByText('Public website and release posture')).toBeTruthy()
|
||||
expect(screen.getAllByText('Preview posture').length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('What the website is for')).toBeTruthy()
|
||||
expect(screen.getByText('Current input, XR, and settings truth')).toBeTruthy()
|
||||
expect(screen.getAllByText('Paddle webhook secret: missing').length).toBeGreaterThan(0)
|
||||
expect(screen.getAllByText(/public auth runtime posture/i).length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
|
|
@ -521,6 +526,8 @@ describe('public marketing pages', () => {
|
|||
renderWithProviders(<AboutPage />, ['/about'])
|
||||
|
||||
expect(screen.getByText('How a real HyperTwist session unfolds')).toBeTruthy()
|
||||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('What the desktop runtime is for')).toBeTruthy()
|
||||
expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
|
||||
expect(screen.getByText('Stay on the public website')).toBeTruthy()
|
||||
expect(screen.getByText('Current desktop control and XR truth')).toBeTruthy()
|
||||
|
|
@ -1104,6 +1111,8 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Recovery and degraded-state manual')).toBeTruthy()
|
||||
expect(screen.getByText('Support topic quick routes')).toBeTruthy()
|
||||
expect(screen.getAllByText('Current surface authority map').length).toBeGreaterThan(0)
|
||||
expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy()
|
||||
expect(screen.getByText('Why the browser is intentionally narrower')).toBeTruthy()
|
||||
expect(screen.getByText('When to use browser versus desktop')).toBeTruthy()
|
||||
expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy()
|
||||
expect(screen.getAllByText('Protected browser dashboard').length).toBeGreaterThan(0)
|
||||
|
|
@ -1123,6 +1132,7 @@ describe('public marketing pages', () => {
|
|||
expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
|
||||
expect(screen.getByText('Common operator questions')).toBeTruthy()
|
||||
expect(screen.getByText('If the desktop app is primary, why keep the web version?')).toBeTruthy()
|
||||
expect(screen.getByText(/intentionally narrower than the simulator for training and device\/runtime work/i)).toBeTruthy()
|
||||
expect(screen.getByText('Packaged validation passed')).toBeTruthy()
|
||||
expect(await screen.findByRole('link', { name: /open public docs portal/i })).toBeTruthy()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
publicDocsUrl,
|
||||
releaseNotesUrl,
|
||||
} from '../site-config'
|
||||
import { deliverySurfaceCards } from '../site-data'
|
||||
import { browserDesktopRealityCards, deliverySurfaceCards } from '../site-data'
|
||||
import {
|
||||
buildLoginPath,
|
||||
buildProtectedDownloadPath,
|
||||
|
|
@ -189,6 +189,38 @@ export function DeliverySurfaceResponsibilitiesGrid({ limit }: { limit?: number
|
|||
)
|
||||
}
|
||||
|
||||
export function BrowserDesktopRealitySection({
|
||||
title = 'Why HyperTwist keeps both a website and a desktop runtime',
|
||||
description = 'The browser shell is intentionally narrower than the simulator. That is what keeps access, release, billing, notices, and native execution from collapsing into one confused surface.',
|
||||
}: {
|
||||
title?: string
|
||||
description?: string
|
||||
}) {
|
||||
return (
|
||||
<Section title={title} description={description}>
|
||||
<div className="card-grid">
|
||||
{browserDesktopRealityCards.map((card) => (
|
||||
<article key={card.title} className="card">
|
||||
<p className="status-pill status-pill--info">{card.posture}</p>
|
||||
<h3>{card.title}</h3>
|
||||
<p>{card.description}</p>
|
||||
<ul className="list top-gap">
|
||||
{card.bullets.map((bullet) => (
|
||||
<li key={bullet}>{bullet}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="button-row top-gap">
|
||||
<Link className="button button--ghost" to={card.action.to}>
|
||||
{card.action.label}
|
||||
</Link>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
const surfaceChoiceGuideCards = [
|
||||
{
|
||||
title: 'Stay on the public website',
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import {
|
|||
termsBoundaryCards,
|
||||
} from '../site-data'
|
||||
import {
|
||||
BrowserDesktopRealitySection,
|
||||
buildPublicReleaseManifestFallback,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
explorerFallbackPlan,
|
||||
|
|
@ -316,6 +317,8 @@ export function DownloadPage() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<BrowserDesktopRealitySection />
|
||||
|
||||
<SurfaceChoiceGuideSection description="Download posture is clearer when the current best surface is explicit: public for target and release context, protected for entitlement, and desktop for the real training runtime." />
|
||||
|
||||
<Section
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import {
|
|||
supportFaqs,
|
||||
} from '../site-data'
|
||||
import {
|
||||
BrowserDesktopRealitySection,
|
||||
DeliverySurfaceResponsibilitiesGrid,
|
||||
PublicPackagedDesktopProofSection,
|
||||
Section,
|
||||
|
|
@ -317,6 +318,8 @@ export function HomeLanding() {
|
|||
<PublicLaunchStatus title="Public website and release posture" />
|
||||
</Section>
|
||||
|
||||
<BrowserDesktopRealitySection />
|
||||
|
||||
<Section
|
||||
title="What ships now"
|
||||
description="The public site only describes current product truth or explicitly marked retained/spec-only branches."
|
||||
|
|
@ -453,6 +456,8 @@ export function AboutPage() {
|
|||
</div>
|
||||
</Section>
|
||||
|
||||
<BrowserDesktopRealitySection />
|
||||
|
||||
<Section
|
||||
title="Why the web surface remains necessary"
|
||||
description="Keeping the website does not weaken the desktop-first thesis. It keeps public distribution, release, and operator-governance work outside the simulator proper."
|
||||
|
|
@ -851,6 +856,8 @@ export function DocsPage() {
|
|||
<ProductSurfaceMatrix rows={productSurfaceMatrixRows} />
|
||||
</Section>
|
||||
|
||||
<BrowserDesktopRealitySection />
|
||||
|
||||
<Section
|
||||
title="When to use browser versus desktop"
|
||||
description="The public manual is more useful when it says plainly which jobs stay on the web and which ones stay inside the native runtime."
|
||||
|
|
|
|||
|
|
@ -65,6 +65,65 @@ export const deliverySurfaceCards = [
|
|||
},
|
||||
] as const
|
||||
|
||||
export const browserDesktopRealityCards = [
|
||||
{
|
||||
title: 'What the website is for',
|
||||
posture: 'Public and protected browser authority',
|
||||
description: 'Keep the web lane because product access, release posture, billing, notices, and operator onboarding should stay inspectable outside the simulator.',
|
||||
bullets: [
|
||||
'The website owns public docs, pricing, release notes, notices, and support-safe rollout guidance.',
|
||||
'The protected dashboard owns account state, entitlement, protected downloads, and browser-to-desktop pairing.',
|
||||
'This keeps release and commercial posture visible without turning the simulator into a checkout or auth shell.',
|
||||
],
|
||||
action: {
|
||||
to: '/docs',
|
||||
label: 'Open public manual',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'What the desktop runtime is for',
|
||||
posture: 'Native simulator authority',
|
||||
description: 'Keep the real simulator native because the desktop runtime is where package proof, training quality, device/runtime integration, and higher-dimensional execution are actually owned.',
|
||||
bullets: [
|
||||
'The desktop lane owns recognition, replay, coaching, analytics, and packaged training behavior.',
|
||||
'It owns the current dedicated-family Magic120Cell and MagicCube5D runtime lanes.',
|
||||
'It is the only current surface that can honestly claim simulator execution authority.',
|
||||
],
|
||||
action: {
|
||||
to: '/download',
|
||||
label: 'Open download center',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Why the browser is intentionally narrower',
|
||||
posture: 'Deliberate product boundary',
|
||||
description: 'The browser lane is useful precisely because it does not pretend to replace the simulator.',
|
||||
bullets: [
|
||||
'It does not claim package-validated training behavior, higher-dimensional execution, or device/runtime integration authority.',
|
||||
'It keeps identity, billing, release, and legal-distribution work outside the native runtime where operators can review it more safely.',
|
||||
'It preserves a clean browser-to-desktop pairing boundary instead of collapsing access, rollout, and simulator execution into one brittle shell.',
|
||||
],
|
||||
action: {
|
||||
to: '/app',
|
||||
label: 'Open operator dashboard',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Current input, XR, and settings truth',
|
||||
posture: 'Shipped today versus still gated',
|
||||
description: 'HyperTwist already ships meaningful desktop control/settings ownership, but it does not market unfinished XR/controller widening as complete.',
|
||||
bullets: [
|
||||
'Classic keyboard, mouse/touch classic-cube control, viewer camera settings, immersive presets, and dedicated-family selector/view ownership are real today.',
|
||||
'The public and protected manual already expose that shipped control roster instead of hiding it behind vague “customizable later” language.',
|
||||
'OpenXR/controller runtime widening and polished rebinding/preferences remain explicitly unfinished behind the current desktop-hosted No-Go boundary.',
|
||||
],
|
||||
action: {
|
||||
to: '/features',
|
||||
label: 'Open feature atlas',
|
||||
},
|
||||
},
|
||||
] as const
|
||||
|
||||
export type ProductSurfaceMatrixRow = {
|
||||
title: string
|
||||
posture: string
|
||||
|
|
@ -762,6 +821,11 @@ export const resourceCollections = [
|
|||
] as const
|
||||
|
||||
export const changelogEntries = [
|
||||
{
|
||||
date: 'June 24, 2026',
|
||||
title: 'The public manual now answers why HyperTwist keeps both a website and a desktop runtime',
|
||||
details: 'Homepage, About, Docs, and Download now share a direct browser-versus-desktop reality section explaining what the website is for, what stays native, why the browser is intentionally narrower, and how the current keyboard/mouse versus unfinished XR/controller truth should be read.',
|
||||
},
|
||||
{
|
||||
date: 'June 24, 2026',
|
||||
title: 'The remaining feature, docs, resource, changelog, and legal pages now carry the same surface handoff guidance',
|
||||
|
|
@ -906,11 +970,11 @@ export const sourceAvailability = {
|
|||
export const supportFaqs = [
|
||||
{
|
||||
question: 'Is the simulator fully in the browser?',
|
||||
answer: 'No. The current shipping lane is desktop-first and Unreal-backed. The public website offers account, operator, support, and download access, while the optional full-browser simulator path remains spec-only.',
|
||||
answer: 'No. The current shipping lane is desktop-first and Unreal-backed. The public website offers account, operator, support, and download access, while the optional full-browser simulator path remains spec-only, so the browser does not currently replace the package-validated native runtime.',
|
||||
},
|
||||
{
|
||||
question: 'If the desktop app is primary, why keep the web version?',
|
||||
answer: 'Because the browser shell owns the parts that should stay outside the simulator: public positioning, account access, billing, release posture, download gating, notices, and browser-to-desktop pairing. Keeping that work on the web makes the native runtime easier to trust and easier to operate.',
|
||||
answer: 'Because the browser shell owns the parts that should stay outside the simulator: public positioning, account access, billing, release posture, download gating, notices, and browser-to-desktop pairing. It is intentionally narrower than the simulator for training and device/runtime work, and that narrower boundary makes the native runtime easier to trust and easier to operate.',
|
||||
},
|
||||
{
|
||||
question: 'Is VR/controller support already fully finished?',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue