This is a browser-based Flashcards Study App built as part of an AI Coding Challenge. The application allows users to create, edit, and delete decks and cards, and study them in a responsive and accessible interface. Data is persisted using LocalStorage.
-
Navigate to the project directory in your terminal:
cd flashcardsapp -
Start a local web server. The easiest way is using
serve(requires Node.js and npm):- Install
serveglobally (if you haven't already):npm install -g serve
- Start the server in your project directory:
serve
Alternatively, if you have Python installed, you can use its built-in HTTP server:
- For Python 3:
python -m http.server
- Install
-
Open your web browser and go to the address provided by the server (e.g.,
http://localhost:3000forserve, orhttp://localhost:8000for Python).
-
Where AI saved time: AI significantly accelerated the initial scaffolding of
index.html,styles.css, andapp.js, including the basic grid layout and the modal structures. It also provided a solid starting point for complex CSS, like the 3D card flip animation, which would typically be time-consuming to write from scratch. The initial JavaScript for CRUD operations and LocalStorage helpers also saved considerable setup time. -
At least one AI bug you identified and how you fixed it: The most challenging bug identified was the persistent "Blocked aria-hidden on an element because its descendant retained focus" warning, which also prevented modals from visually closing. This was an accessibility and rendering conflict. The fix involved several iterations: first adding a
setTimeout(0)around the modal hiding, then introducing theinertattribute to non-modal content, explicitly blurringdocument.activeElementon close, and finally ensuring thehiddenandaria-hiddenattributes were applied synchronously after blur, combined with the CSS ruledisplay: none !important;for[hidden]. -
A code snippet you refactored for clarity: The
closeModalfunction inapp.jswas heavily refactored throughout the debugging process. Initially, it was a simple attribute toggle. It evolved to include focus management,inertattribute toggling, and careful sequencing of DOM updates to resolve focus-related warnings and visual bugs, making it much more robust and readable.// Original (simplified concept) // function closeModal(modalElement) { // modalElement.setAttribute('hidden', ''); // modalElement.setAttribute('aria-hidden', 'true'); // AppState.ui.isModalOpen = false; // } // Refactored version (after fixes) function closeModal(modalElement) { // Blur the currently focused element immediately to ensure no element inside the modal retains focus if (document.activeElement) { document.activeElement.blur(); } // Remove inert from background content appHeader.removeAttribute('inert'); appContainer.removeAttribute('inert'); appFooter.removeAttribute('inert'); // Set modal attributes directly without a timeout modalElement.setAttribute('hidden', ''); modalElement.setAttribute('aria-hidden', 'true'); AppState.ui.isModalOpen = false; // Return focus to the element that opened the modal, or a sensible fallback if (previouslyFocusedElement && typeof previouslyFocusedElement.focus === 'function') { previouslyFocusedElement.focus(); } else { appMainContent.focus(); // Fallback to focusing the main content area } previouslyFocusedElement = null; // Clear it after use modalElement.removeEventListener('keydown', trapTabKey); }
-
One accessibility improvement you added: The most significant accessibility improvement was the implementation of the
inertattribute. When a modal is open,inertis applied to the<header>,<div class="container">, and<footer>elements. This makes all content outside the active modal inaccessible to assistive technologies and prevents unintended keyboard navigation, creating a proper "focus trap" for the modal. Additionally,tabindex="-1"was added to<main>to provide a reliable programmatic focus target when closing modals. -
What prompt changes improved AI output: Breaking down complex features into smaller, more granular prompts greatly improved AI output. For instance, instead of a single prompt like "Build a Flashcards app with all features," asking for "a minimal HTML skeleton," then "base styles with CSS variables and responsive grid," then "an accessible modal component in plain JS," and so on, allowed for more focused and accurate code generation for each distinct part of the application. This iterative, step-by-step approach helped manage the complexity and pinpoint specific areas for refinement.