feat(a11y): wire flash-clamp into autoScrub; document 3-flash/sec audit

Clamp each per-altitude step to the WCAG 2.3.1 floor (no-op at 1200ms, guards
a future lowering). Audit: #black fade + audio crossfade can't exceed 3/sec, no
clamp needed. boot() now seeds the gate-dismissed flag (returning visitor) so
the run-sim test isn't blocked by the new interstitial.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-30 09:34:10 -07:00
parent f1ce23c4fe
commit 79105a3ef9
3 changed files with 13 additions and 2 deletions
+4 -1
View File
@@ -10,7 +10,10 @@ import { test, expect, Page } from "@playwright/test";
// ("<scale> · <clip> (i/n)").
async function boot(page: Page) {
await page.addInitScript(() => localStorage.setItem("hef.devMode", "1"));
await page.addInitScript(() => {
localStorage.setItem("hef.devMode", "1");
localStorage.setItem("hef.motionWarnDismissed", "1"); // returning visitor: skip the photosensitivity gate
});
await page.goto("/");
// Wait for the "Loading Universe" preload to finish (splash gets class "done").
await page.waitForFunction(
+8 -1
View File
@@ -705,7 +705,14 @@ function autoScrub(targetPos, perAltMs = PER_ALTITUDE_MS) {
if (autoRaf) cancelAnimationFrame(autoRaf);
const fromPos = pos, dist = targetPos - fromPos;
if (!dist) { setPos(targetPos); return; }
const ms = perAltMs * Math.abs(dist); // constant per-altitude speed → N steps take N× as long
// Photosensitivity floor (WCAG 2.3.1): each altitude step is one luminance
// transition (a blended crossfade), so a single step must take >= 1/3 s to stay
// <= 3 flashes/sec. The clamp is a no-op at today's 1200ms but guards the floor
// if PER_ALTITUDE_MS is ever lowered. (Audit: the only other luminance sources —
// the #black cover fade (200ms, single, >=1.2s apart) and the audio-coupled
// crossfade — cannot repeat faster than 3/sec, so they need no clamp.)
const safeAltMs = HEFFlash.clampDurationMs(perAltMs, 1);
const ms = safeAltMs * Math.abs(dist); // constant per-altitude speed → N steps take N× as long
let startTs = null;
const tick = (ts) => {
if (startTs === null) startTs = ts;
+1
View File
@@ -129,6 +129,7 @@
<script src="config.js"></script>
<script src="scrub.js"></script>
<script src="alteration.js"></script>
<script src="flash.js"></script>
<script src="i18n.js"></script>
<script src="app.js"></script>
</body>