Promotee — Interview Practice Flashcard App
A web app designed and developed for people preparing for interviews in a language other than their first language. Users can import their own questions and answers from a CSV file and practise them in multiple modes without creating an account or storing the content on a server. The implementation also covers keyboard interaction, motion preferences, and announcements for dynamic updates.
Period: Jun 2025 – Sep 2025
Where this experience applies
Experience covering web app UX design, frontend implementation, state management, accessibility implementation, and validation.
- Designing a web app that handles user-provided data
- Making forms and dynamic state changes usable through keyboard and assistive technologies
- Connecting design decisions with implementation and validation
Overview
Promotee is a flashcard app for people preparing for interviews in a language other than their first language. Users can import their own questions and answers from a CSV file and practise them in their original order, randomly, or by category. Because the questions and answers are provided through CSV files, the app can be used with multiple languages. No account is required. The imported content and practice status are managed temporarily in a Zustand store, are not stored on a server, and are cleared when the page is reloaded.
Background
Based on my own experience as a non-native English speaker, I wanted a way to repeatedly practise prepared answers for situations such as job interviews. The app allows users to bring their own questions and answers instead of relying on a fixed set of learning materials. Because it handles interview preparation content, I designed it without requiring an account or storing the imported content on a server.
Challenge
- Import questions and answers from CSV files and support multiple practice modes
- Temporarily track whether each card has been remembered and allow users to repeat cards that remain unremembered
- Provide the practice flow without requiring an account or server-side storage
- Design forms, card interactions, state changes, and notifications with keyboard and assistive-technology use in mind
- Adjust motion and loading behaviour across screens containing animation and video
Users
- People preparing for interviews in a language other than their first language
- People who want to practise with questions and answers they have prepared themselves
- People who want to review their content in order, randomly, or by category
- People who do not want their interview preparation content stored on a server
Approach
Practice Flow and State Management
- Implemented a flow for importing questions and answers from a CSV file and practising them in their original order, randomly, or by category
- Allowed users to mark each card as remembered or not yet remembered and continue practising unremembered cards until the page is reloaded
- Managed imported data and practice status in a Zustand store without persistent storage
Page Structure and Keyboard Interaction
- Structured pages using landmarks such as `header`, `main`, and `footer`
- Implemented a skip link that takes users directly to the main content
- Used elements such as `label` and `fieldset` for forms
- Checked basic interactions on key screens using Tab, Shift+Tab, Enter, Space, and the arrow keys
- Added consistent `:focus-visible` styles so that the current focus position can be identified
State Changes and Notifications
- Announced dynamic updates, including card-status changes, through live regions
- Implemented a custom React Toastify wrapper for handling `role="alert"` and `aria-live`
- Added contextual text so that the type of notification can be understood when announced by a screen reader
Contrast and Motion
- Checked colour combinations using WebAIM Contrast Checker
- Adjusted text and background colours that did not meet WCAG AA contrast ratios
- Applied the operating system’s `prefers-reduced-motion` setting and the app’s own motion setting to card-flip and completion animations
- Removed rotation and confetti from state changes when reduced motion is enabled
Video and Performance
- Replaced GIFs used in the interface with WebM and MP4 video files
- Adjusted `preload` settings by page according to the purpose of the hero and instructional videos
Checks and Validation
- Ran Lighthouse audits on key screens for both desktop and mobile
- Imported dummy data locally to reproduce the required interaction states on screens that depend on client-side state
- Used VoiceOver to manually check basic interactions, forms, navigation, and state announcements on key screens
Design and Implementation Details
No Account or Persistent Storage
Interview content imported by the user is handled within a Zustand store and is not sent to or stored on the server. Reloading the page clears both the imported content and the current practice status.
Communicating State Changes Beyond Visual Feedback
Card-status changes and toast notifications are communicated through text and live regions rather than relying only on colour or animation.
Page-specific Loading Behaviour
Video formats and `preload` settings were selected according to where each video appears and how it is used, rather than applying the same loading behaviour across all pages.
Outputs
- Publicly available web app
- CSV import and flashcard practice functionality
- Ordered, random, and category-based practice modes
- Temporary remembered/not-yet-remembered state and repeat practice
- Keyboard interaction and visible focus styles
- Reduced-motion behaviour
- Notifications using live regions
- Accessibility implementation demo
- Lighthouse and contrast-checking results
Results
Lighthouse Accessibility
100 on key screens (2025)
Best Practices / SEO
100 on key screens (2025)
Performance
97+ including dynamic screens (2025)
- Released a web app that allows users to import a CSV file and practise interview questions in multiple modes without creating an account
- Implemented a structure in which imported CSV content and practice status are not stored on the server
- Checked basic interactions on key screens using the keyboard and VoiceOver
- Implemented adjustments covering contrast, motion, focus, forms, and dynamic notifications
Selected Materials
Keyboard Interaction and Skip Link
A skip link that appears on keyboard focus and moves directly to the main content.
Semantic Page Structure
Page structure organised with elements including header, main, and footer.
Contrast Check and Adjustment
An example of a colour combination checked with WebAIM Contrast Checker and then adjusted.
Reduced Motion
Card-state changes when the user’s reduced-motion preference is enabled.
Toast Live Region
Implementation used to communicate toast content to assistive technologies.
2025 Lighthouse Audit
An example of a Lighthouse audit conducted on desktop in 2025.
Reflection
- The implementation confirmed that visual judgement alone is not sufficient for evaluating colour contrast and that contrast ratios need to be measured
- Automated audits, keyboard checks, and screen-reader checks cover different aspects of an interface
- Screens with dynamic state changes required checks based on the actual interaction flow in addition to code review and automated audits
Validation Scope
- The Lighthouse scores are the results of automated audits conducted in 2025
- Dynamic screens were audited locally using dummy data to reproduce the required application state
- Screen-reader checks covered basic interactions on key screens using VoiceOver on macOS