Design pass (all themes + chat UI), model picker, reduce-motion toggle
- Aero: blue gradients back on the active segment and every primary
(Review due, the card's Study button, the composer's send button); a
frosted backing behind the page heading and the All decks label; a
bottom-weighted rail tint; chat header/composer/welcome panels; calmer
orbs; stronger card veil + a stronger blur bake.
- Dark/Light: a dedicated --track token makes progress bars read (the
first attempt shifted --surface-sunken and the pixel scan caught the
sheet-contrast regression); brighter dark secondary text; darker light
segmented labels and difficulty tints; stronger light card border and
shadow.
- Chat UI: friendly model chip ("Gemma 4 31B") with the raw name in a
tooltip, larger chips, plain centered disclaimer, vertically centered
welcome panel, distinct chat-plus icon for new chat.
- Chat models: every chat-capable model from the server's /api/tags is
selectable (favourites first, search field when long, live-list
validation in the route); default CHAT_MODEL_DEFAULT or gemma4:31b.
- Reduce motion: Settings toggle (default off) that parks the scene,
collapses CSS animations and drives framer-motion's calm mode.
- Folders hint, "New" badge on fresh decks.
Contrast: 0 findings, axe clean, mobile 126/126, chat 102/102, wizard
95/95, regression 44/44, i18n 13/13, native 33/33.
Version 0.4.6, SW -> freezmo-v71.
This commit is contained in:
parent
b70b0e83cf
commit
6635b5d405
29 changed files with 468 additions and 90 deletions
|
|
@ -287,6 +287,34 @@ const AXE = axeSource();
|
|||
await context.close();
|
||||
}
|
||||
|
||||
/* 6e. reduced motion: off by default, toggled in settings -------------- */
|
||||
{
|
||||
const { context, page } = await makePage(browser, { width: 390, height: 844 });
|
||||
await seed(page, { decks: [DECK], theme: "aero" });
|
||||
await page.goto(BASE, { waitUntil: "networkidle" });
|
||||
await page.waitForTimeout(900);
|
||||
check(
|
||||
"motion: reduced motion is off by default",
|
||||
!(await page.evaluate(() => document.documentElement.classList.contains("reduce-motion"))),
|
||||
);
|
||||
await page.locator("nav.tabbar").getByRole("button").click();
|
||||
await page.getByRole("dialog").waitFor({ timeout: 6000 });
|
||||
await page.waitForTimeout(500);
|
||||
await page.getByRole("switch", { name: "Reduce motion" }).click();
|
||||
await page.waitForTimeout(500);
|
||||
const motion = await page.evaluate(() => ({
|
||||
cls: document.documentElement.classList.contains("reduce-motion"),
|
||||
bubble: getComputedStyle(document.querySelector(".ice-bubble")).animationName,
|
||||
stored: localStorage.getItem("freezmo.reduce-motion.v1"),
|
||||
}));
|
||||
check(
|
||||
"motion: the toggle parks the scene and persists",
|
||||
motion.cls && motion.bubble === "none" && motion.stored === "1",
|
||||
JSON.stringify(motion),
|
||||
);
|
||||
await context.close();
|
||||
}
|
||||
|
||||
/* 6d. touch devices blur the real backdrop (the baked layer mispaints) - */
|
||||
{
|
||||
const { context, page } = await makePage(browser, { width: 390, height: 844, isMobile: true, hasTouch: true });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue