The category tabs were not filtering because the generic tab event handler
was overwriting currentFilter with undefined (category tabs use data-category
not data-filter). Fixed by targeting only [data-filter] tabs and clearing
categoryFilter when switching to non-category tabs.
Added proper ARIA attributes for screen reader accessibility:
- role="tablist" on nav-tabs container
- role="tab" and aria-selected on all tab buttons
- Dynamic aria-selected updates on tab clicks
Also includes API support for category field and deploy script update.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Focus trapping:
- Manually handle all Tab key navigation within modals
- Use getComputedStyle and offsetWidth/Height to detect visible elements
- Focus appropriate input field when modal opens (PIN or Name)
Focus indicators:
- Add visible outline on buttons (:focus)
- Add visible outline on checkbox (:focus)
- Add visible outline on modal close button (:focus)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
offsetParent returns null for elements inside position:fixed containers.
Use getComputedStyle instead to check display and visibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getFocusableElements helper function
- Exclude input[type="hidden"] from selector
- Filter out elements where offsetParent is null (hidden)
- Filter out disabled elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enter in PIN input triggers Unlock
- Enter in Confirm PIN input triggers Save PIN
- Enter in Item Name input triggers Save Item
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Wrap main content in container with id="mainContent"
- Set inert attribute on background when modal opens
- Remove inert when modal closes
- This properly prevents all keyboard/mouse interaction with background
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Focus moves to first focusable element when modal opens
- Tab/Shift+Tab cycles within modal only
- Escape key closes modal
- Focus returns to previously focused element on close
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add skip-to-content link for keyboard users
- Add ARIA roles and labels to modals (dialog, aria-modal, aria-labelledby)
- Make inventory items keyboard accessible (tabindex, role=button, onkeydown)
- Make container legend items keyboard accessible with aria-pressed state
- Make stats clickable area keyboard accessible
- Add aria-labels to FAB and lock buttons
- Add aria-hidden to decorative SVGs and color dots
- Add live regions for toast notifications and loading states
- Associate form labels with inputs via for= attribute
- Add visually-hidden CSS class for screen reader text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- normalizeName() strips punctuation and normalizes whitespace/case
- findDuplicates() checks for matching normalized names
- Shows confirmation dialog if similar item exists
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add requirePin() check on add/update/delete endpoints (closes PIN bypass vulnerability)
- Restrict CORS to specific allowed origins only
- Add input length limits to sanitize() function
- Frontend now sends currentPin with all write requests
- Deploy script copies data/index.php to block directory listing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A simple web app for tracking kitchen pantry items with:
- Search and filter by stock status, spices, or container type
- PIN-protected editing
- Shopping list export (tap Out of Stock to copy)
- QR code for quick mobile access
- OpenGraph card for social sharing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>