diff --git a/package.json b/package.json index b92d570..6fc3948 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "check": "node scripts/verify-static.mjs" }, "dependencies": { + "@fontsource-variable/fraunces": "^5.2.9", "@fontsource-variable/inter": "^5.2.8", "@fontsource-variable/jetbrains-mono": "^5.2.8", "astro": "^5.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e17aab..9ebb06e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@fontsource-variable/fraunces': + specifier: ^5.2.9 + version: 5.2.9 '@fontsource-variable/inter': specifier: ^5.2.8 version: 5.2.8 @@ -373,6 +376,9 @@ packages: cpu: [x64] os: [win32] + '@fontsource-variable/fraunces@5.2.9': + resolution: {integrity: sha512-Y6IjunlN9Ni723np+GIgAaKzCDBrPRrqNi01TZxHs5wtHYROWFM9W6yiT+/gGwSjWIRD18oX17kD/BRWekc/Lw==} + '@fontsource-variable/inter@5.2.8': resolution: {integrity: sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==} @@ -1913,6 +1919,8 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true + '@fontsource-variable/fraunces@5.2.9': {} + '@fontsource-variable/inter@5.2.8': {} '@fontsource-variable/jetbrains-mono@5.2.8': {} diff --git a/scripts/verify-static.mjs b/scripts/verify-static.mjs index 11d001f..55d5cc2 100644 --- a/scripts/verify-static.mjs +++ b/scripts/verify-static.mjs @@ -74,14 +74,22 @@ if (existsSync(distIndex)) { } const downloadLabels = [ - 'Download for macOS', - 'Download for Windows', - 'Download for Linux', - 'Get the iOS Beta', + 'Download for macOS', // server-rendered primary (JS retargets per platform) + 'Windows', + 'Linux', + 'iOS (TestFlight)', + 'all releases', ]; + // Scope to the CTA block — words like "Windows" also appear in the + // head's JSON-LD, which would confuse a whole-document indexOf. + const ctaStart = html.indexOf('data-download-cta'); + if (ctaStart === -1) { + throw new Error('dist/index.html is missing the data-download-cta block'); + } + const ctaHtml = html.slice(ctaStart); const downloadLabelPositions = downloadLabels.map((label) => ({ label, - index: html.indexOf(label), + index: ctaHtml.indexOf(label), })); const missingDownloadLabels = downloadLabelPositions .filter(({ index }) => index === -1) @@ -91,13 +99,13 @@ if (existsSync(distIndex)) { } for (let i = 1; i < downloadLabelPositions.length; i += 1) { if (downloadLabelPositions[i - 1].index > downloadLabelPositions[i].index) { - throw new Error('Download CTA order must be macOS, Windows, Linux, then iOS beta'); + throw new Error('Download CTA order must be the macOS primary, then Windows, Linux, iOS beta, and all releases'); } } const css = await readFile(path.join(root, 'src/styles/global.css'), 'utf8'); - if (!css.includes('.download-btn[data-platform="ios"]') || !css.includes('grid-column: 1 / -1')) { - throw new Error('Download CTA must make the bottom iOS beta button span the full button grid width'); + if (!css.includes('.download-alt.is-detected') || !html.includes('data-download-primary')) { + throw new Error('Download CTA must render one retargetable primary button and hide the detected platform from the alt row'); } console.log( `Verified ${requiredPublicFiles.length} required public files, canonical favicon + OG logos, and ${requiredCopy.length} required copy strings in dist/index.html.`, diff --git a/src/components/Architecture.astro b/src/components/Architecture.astro index df3529d..32b2c6b 100644 --- a/src/components/Architecture.astro +++ b/src/components/Architecture.astro @@ -1,7 +1,7 @@ --- // Interactive architecture diagram. SVG with clickable nodes; selecting a // node updates the detail panel below the diagram. State + keyboard -// navigation are wired in the inline