diff --git a/simulator/e2e/tests/a11y.spec.ts b/simulator/e2e/tests/a11y.spec.ts new file mode 100644 index 0000000..8229e6b --- /dev/null +++ b/simulator/e2e/tests/a11y.spec.ts @@ -0,0 +1,28 @@ +import { test, expect } from "@playwright/test"; + +// Accessibility pass (feat/accessibility-pass) — non-kiosk public-web a11y. +// Each block maps to a task in +// docs/superpowers/plans/2026-06-30-accessibility-and-about-page.md. + +test.describe("Task 1 — Output panel layout", () => { + test("language picker sits below the Audio control", async ({ page }) => { + await page.goto("/"); + const audio = page.locator("#audio"); + const lang = page.locator("#lang-select"); + await expect(audio).toBeVisible(); + await expect(lang).toBeVisible(); + const aBox = await audio.boundingBox(); + const lBox = await lang.boundingBox(); + expect(lBox!.y).toBeGreaterThan(aBox!.y); // lang renders lower than audio + }); + + test("globe icon is inline-left of the language select (same row)", async ({ page }) => { + await page.goto("/"); + const pick = page.locator(".lang-pick"); + const select = page.locator("#lang-select"); + const pBox = await pick.boundingBox(); + const sBox = await select.boundingBox(); + expect(sBox!.x).toBeGreaterThan(pBox!.x); // select right of the label's left edge + expect(pBox!.height).toBeLessThan(40); // one row, not stacked + }); +}); diff --git a/simulator/static/i18n.js b/simulator/static/i18n.js index 864ce6d..497b34d 100644 --- a/simulator/static/i18n.js +++ b/simulator/static/i18n.js @@ -31,6 +31,7 @@ "knobs.feel": { en: "Feel", es: "Sentir", fr: "Ressentir", ja: "感じる" }, "knobs.mood": { en: "Mood — dark ◀ 0 ▶ light", es: "Ánimo — oscuro ◀ 0 ▶ claro", fr: "Humeur — sombre ◀ 0 ▶ clair", ja: "ムード — 暗 ◀ 0 ▶ 明" }, "devmode.label": { en: "Dev Mode", es: "Modo desarrollo", fr: "Mode dév", ja: "開発モード" }, + "rm.label": { en: "Reduce motion", es: "Reducir movimiento", fr: "Réduire les animations", ja: "動きを減らす" }, "scale.cosmos": { en: "cosmos", es: "cosmos", fr: "cosmos", ja: "宇宙" }, "scale.orbit": { en: "orbit", es: "órbita", fr: "orbite", ja: "軌道" }, "scale.sky": { en: "sky", es: "cielo", fr: "ciel", ja: "空" }, diff --git a/simulator/static/index.html b/simulator/static/index.html index 469e09f..dc91fbe 100644 --- a/simulator/static/index.html +++ b/simulator/static/index.html @@ -36,9 +36,6 @@
Output - + +
diff --git a/simulator/static/style.css b/simulator/static/style.css index 849acbd..3541cd9 100644 --- a/simulator/static/style.css +++ b/simulator/static/style.css @@ -92,6 +92,9 @@ main { display: flex; gap: 1rem; padding: 1rem; flex-wrap: wrap; align-items: fl .run-sim:active { transform: translate(-50%, -50%) scale(0.98); } /* Stack the two Output toggles (Video / Audio) with a little breathing room. */ .dev-switch + .dev-switch { margin-top: 0.45rem; } +/* Globe + language select on one row (the select no longer goes full-width here). */ +.lang-pick { display: flex; align-items: center; gap: 0.4rem; margin: 0.6rem 0 0.2rem; } +.lang-pick select { flex: 1; width: auto; } /* Live audio status readout (diagnostic) — turns green when actually playing. */ .audio-status { margin-top: 0.5rem; font: 11px/1.4 monospace; color: #9ab; } .audio-status.playing { color: #4e9; }