Lesson 04 | Act 4: Elderly Mode
Act 4: Elderly Mode (Episodes 8-10)
The most challenging part — making it usable and accessible for a 65-year-old.
Episode 8: Two Modes, One Codebase
Scene: Standard mode is done, now we need to add elderly mode. We can't build two separate versions.
- CSS Custom Properties +
body.elderly-mode: One class toggles all visuals - Elderly mode visual standards: 68px buttons (originally set to 80px, tested 68px as comfortable), 26px font, 7:1 contrast
- Three mode toggle methods: UI button + keyboard
mkey + localStorage preference - 300ms CSS transition for smooth shifting (
background,font-size,width) - Elderly mode hides
( )%buttons — simplifying the UI, not removing features - Use
visibility: hidden+pointer-events: noneinstead ofdisplay: none(to preserve Grid cells) - Core concept: CSS variables make theme switching just a matter of altering a few values
Output Files:
style.css—.elderly-modefull override styles (white background, blue theme, large buttons & text)app.js— Mode toggle logic (initMode / toggleMode + localStorage)index.html—data-hide-elderlyattribute + mode toggle button + sound toggle buttontests/mode/switch.test.js— Mode toggle tests
Command: /gsd-discuss-phase 3, /gsd-plan-phase 3, /gsd-execute-phase 3
Episode 9: Accessibility is Not a Bonus, It's Fundamental
Scene: Visuals look good, but how do blind users navigate? What about screen readers for elderly users?
- ARIA labels: Chinese descriptions for every button (e.g.
aria-label="Seven",aria-label="Divide") - Focus indicator: Pressing Tab shows where you are, 3px blue outline in elderly mode (WCAG AAA requires thicker outlines)
- Screen readers: After calculating
2+3=5, it should announce"2+3 equals 5"(dynamicaria-labelupdates) - Long-press backspace: Holding ⌫ for 500ms in elderly mode clears all (
touchstarttimer) - Button sounds: Web Audio API 800Hz 0.05s beep, default off, localStorage remembers toggle state
- Why sounds matter: As elderly users' vision declines, auditory feedback serves as a secondary confirmation channel
- Core concept: Accessibility is not an afterthought patch, it's part of the design
Output Files:
app.js— Dynamic ARIA updates (announceResult) + long-press detection (_longPressTimer) + sound system (playClickSound)tests/a11y/aria.test.js— ARIA attribute teststests/a11y/focus.test.js— Focus indicator tests
Command: /gsd-execute-phase 3 (continued)
Episode 10: Bug Hunt — Elderly Mode Buttons Overflow
Scene: Thought we were done, but opening elderly mode reveals buttons breaking the container bounds.
- Bug: Buttons overflowing the container edge
- Root cause:
display: nonebreaks CSS Grid auto-placement (hidden elements don't take up space) - Fix:
visibility: hidden+pointer-events: none(takes space but invisible and unclickable) - Fortification:
grid-template-columns: repeat(4, 1fr)+width: autoto prevent overflow - Color fix: Elderly mode white background + blue theme (
#1a73e8), contrast > 7:1 - Layout tweaks: Blue gradient background for the display area, layered shadow effects for buttons
file://protocol limit: Chrome ES module isn't supported, revert to traditional<script>+exportscompatibility- Core concept: CSS Grid hidden rules — a hidden element does not equal a removed element
Output Files: No new files, updated style.css + index.html
Command: /gsd-quick or direct manual fix