The owner's orders of 7 October 2026 (header, logos, footer, phone scene) and the Counter ASIC lane's public text (docs/plans/counter-asic-3-public-text-2026-10-07.md, b10c7ac2) with the disclosure prize held back until its publish word.
Header: the one-screen home no longer hides items; the sheet carries exactly Litepaper, Miner, App, Wallet, Live devnet, Ledger and Download; 44 px bar links, 48 px sheet rows, the burger turns into an X; tools/ci/site-nav-check.mjs runs after every build and in the gate.
Cards: the Windows four-pane, Apple and Tux marks from 80c5618, white on the ember card, the card's own text colour on the mono cards (so they flip with the theme).
Footer: the ledger page renders through tools/ledger-page.mjs and now underlines Ledger; the Reddit profile is the one the owner named.
Renderer: narrow, narrowBreak 720, narrowWindow 30, narrowLanes 4, narrowMinNode 11; hairlines off except the selected chain; checkpoint labels as the percent; fps 60 on the home and /live mounts. Measured in headless chromium at 390 with 4x CPU throttling: 50 to 56 frames a second (the cap is 60).
Evidence row 17 rewritten in the table's eight columns. The forbidden list gains "disclosure prize" and the word-bounded rig names.
Tested with Playwright at 390 and 768 in both themes with real taps on every public page and the 404: 48 rows, 0 problems; captures in docs/plans/site-ui-4-shots/chrome.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
26 lines
2.5 KiB
JavaScript
26 lines
2.5 KiB
JavaScript
#!/usr/bin/env node
|
|
// Every served page carries the same header: the mark and wordmark, the six items (Litepaper, Miner, App, Wallet, Live devnet,
|
|
// Ledger) and the Download button, in the bar and in the sheet. A page with a shorter nav fails the build and the gate
|
|
// (the owner's rule, 7 October 2026: the header has all of these on every page and the mobile header works).
|
|
// node tools/ci/site-nav-check.mjs [site-dir]
|
|
import { readdirSync, readFileSync } from 'node:fs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
const site = process.argv[2] || join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'site');
|
|
const ITEMS = [['/litepaper', 'Litepaper'], ['/miner', 'Miner'], ['/app', 'App'], ['/wallet', 'Wallet'], ['/live', 'Live devnet'], ['/ledger', 'Ledger']];
|
|
const pages = readdirSync(site).filter(f => f.endsWith('.html'));
|
|
const bad = [];
|
|
for (const page of pages) {
|
|
const html = readFileSync(join(site, page), 'utf8');
|
|
const nav = html.match(/<nav class="nav"[\s\S]*?<\/nav>/); if (!nav) { bad.push(`${page}: no <nav class="nav">`); continue; }
|
|
const bar = nav[0].match(/<div class="links" id="nav-links">[\s\S]*?<\/div>/), sheet = nav[0].match(/<div class="nav-sheet" id="nav-sheet">[\s\S]*?<\/div>/);
|
|
if (!bar || !sheet) { bad.push(`${page}: the bar or the sheet is missing`); continue; }
|
|
for (const [href, label] of ITEMS) for (const [name, part] of [['bar', bar[0]], ['sheet', sheet[0]]]) if (!new RegExp(`<a href="${href}"[^>]*>${label}<\\/a>`).test(part)) bad.push(`${page}: ${name} lacks ${label} (${href})`);
|
|
if (!/<a href="\/miner#get" class="btn primary small cta">Download<\/a>/.test(nav[0])) bad.push(`${page}: no Download button in the bar`);
|
|
if (!/<a href="\/miner#get" class="btn primary">Download<\/a>/.test(sheet[0])) bad.push(`${page}: no Download in the sheet`);
|
|
if (!/<button class="burger" id="nav-burger"[^>]*aria-expanded="false"[^>]*aria-controls="nav-sheet"/.test(nav[0])) bad.push(`${page}: the burger lacks its aria attributes`);
|
|
if (!/<span class="word">IGNEUM<\/span>/.test(nav[0])) bad.push(`${page}: no wordmark`);
|
|
if (/\.nav \.links a[^{]*\{[^}]*display:\s*none/.test(html) || /\.nav-sheet a[^{]*\{[^}]*display:\s*none/.test(html)) bad.push(`${page}: a page style hides header items`);
|
|
}
|
|
if (bad.length) { console.error('site nav check: ' + bad.length + ' problems\n' + bad.join('\n')); process.exit(1); }
|
|
console.log(`site nav check: ${pages.length} pages carry the six items, the Download button and the burger`);
|