From 2e9f7d33adf96278761671098a3b1331c0c3980a Mon Sep 17 00:00:00 2001 From: byteMara Date: Sun, 27 Sep 2026 14:14:16 +0100 Subject: [PATCH] chore: clean repository root artifacts Move retained references under docs, remove completed issue and PR notes, ignore logs, and relocate the SVG generator. Closes #963 --- .gitignore | 1 + CI_COMPATIBILITY_REPORT.md | 173 ------- COMMIT_MESSAGE.txt | 26 -- GIT_WORKFLOW.md | 240 ---------- IMPLEMENTATION_SUMMARY.md | 403 ----------------- ISSUE_435_RESOLUTION_SUMMARY.md | 343 -------------- ISSUE_906_DELIVERABLES.md | 425 ------------------ ISSUE_906_IMPLEMENTATION.md | 393 ---------------- ISSUE_906_PR_DESCRIPTION.md | 200 --------- ISSUE_906_VALIDATION_REPORT.md | 421 ----------------- PATTERNS_IMPLEMENTATION.md | 138 ------ PR_DESCRIPTION.md | 37 -- RESPONSIVE_AUDIT_PR_DESCRIPTION.md | 238 ---------- TODO.md | 15 - dev-server.log | Bin 7944 -> 0 bytes .../ACTIVITY_TIMELINE_DELIVERY.md | 0 .../ACTIVITY_TIMELINE_DESIGN.md | 0 .../ACTIVITY_TIMELINE_PATTERNS.md | 0 .../COLORBLIND_OUTCOMES_IMPLEMENTATION.md | 0 .../COLORBLIND_QUICK_REFERENCE.md | 14 +- .../DESIGN_ACCESSIBILITY_CHECKLIST.md | 0 .../DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md | 0 .../DESIGN_STICKY_ACTION_PANEL.md | 0 Design.md => docs/Design.md | 0 .../IMPLEMENTATION_CHECKLIST.md | 0 docs/README.md | 64 +++ TYPOGRAPHY.md => docs/TYPOGRAPHY.md | 2 +- .../TYPOGRAPHY_IMPLEMENTATION.md | 0 .../TYPOGRAPHY_TESTING.md | 0 generate-svgs.js => scripts/generate-svgs.js | 5 +- 30 files changed, 72 insertions(+), 3066 deletions(-) delete mode 100644 CI_COMPATIBILITY_REPORT.md delete mode 100644 COMMIT_MESSAGE.txt delete mode 100644 GIT_WORKFLOW.md delete mode 100644 IMPLEMENTATION_SUMMARY.md delete mode 100644 ISSUE_435_RESOLUTION_SUMMARY.md delete mode 100644 ISSUE_906_DELIVERABLES.md delete mode 100644 ISSUE_906_IMPLEMENTATION.md delete mode 100644 ISSUE_906_PR_DESCRIPTION.md delete mode 100644 ISSUE_906_VALIDATION_REPORT.md delete mode 100644 PATTERNS_IMPLEMENTATION.md delete mode 100644 PR_DESCRIPTION.md delete mode 100644 RESPONSIVE_AUDIT_PR_DESCRIPTION.md delete mode 100644 TODO.md delete mode 100644 dev-server.log rename ACTIVITY_TIMELINE_DELIVERY.md => docs/ACTIVITY_TIMELINE_DELIVERY.md (100%) rename ACTIVITY_TIMELINE_DESIGN.md => docs/ACTIVITY_TIMELINE_DESIGN.md (100%) rename ACTIVITY_TIMELINE_PATTERNS.md => docs/ACTIVITY_TIMELINE_PATTERNS.md (100%) rename COLORBLIND_OUTCOMES_IMPLEMENTATION.md => docs/COLORBLIND_OUTCOMES_IMPLEMENTATION.md (100%) rename COLORBLIND_QUICK_REFERENCE.md => docs/COLORBLIND_QUICK_REFERENCE.md (94%) rename DESIGN_ACCESSIBILITY_CHECKLIST.md => docs/DESIGN_ACCESSIBILITY_CHECKLIST.md (100%) rename DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md => docs/DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md (100%) rename DESIGN_STICKY_ACTION_PANEL.md => docs/DESIGN_STICKY_ACTION_PANEL.md (100%) rename Design.md => docs/Design.md (100%) rename IMPLEMENTATION_CHECKLIST.md => docs/IMPLEMENTATION_CHECKLIST.md (100%) rename TYPOGRAPHY.md => docs/TYPOGRAPHY.md (99%) rename TYPOGRAPHY_IMPLEMENTATION.md => docs/TYPOGRAPHY_IMPLEMENTATION.md (100%) rename TYPOGRAPHY_TESTING.md => docs/TYPOGRAPHY_TESTING.md (100%) rename generate-svgs.js => scripts/generate-svgs.js (88%) diff --git a/.gitignore b/.gitignore index ee2d677a..001524c8 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ *.pem # debug +*.log npm-debug.log* yarn-debug.log* yarn-error.log* diff --git a/CI_COMPATIBILITY_REPORT.md b/CI_COMPATIBILITY_REPORT.md deleted file mode 100644 index f4b7e04f..00000000 --- a/CI_COMPATIBILITY_REPORT.md +++ /dev/null @@ -1,173 +0,0 @@ -# CI/Build Pipeline Compatibility Report - -**Date:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss") -**Task:** Reduced-Motion Fallback Implementation (buffer #4) -**Status:** ✅ PASSED - -## Summary - -All reduced-motion implementation changes have been verified for CI/build pipeline compatibility. The implementation follows established patterns and maintains backward compatibility while adding new accessibility features. - ---- - -## Verification Checklist - -### ✅ TypeScript Compatibility -- [x] All new interfaces properly defined with optional `reducedMotion?: boolean` props -- [x] Consistent import/export statements across all modified files -- [x] Proper type annotations for hook usage and component props -- [x] SSR-safe implementation in `useReducedMotion` hook - -### ✅ ESLint Compatibility -- [x] Uses `next/core-web-vitals` configuration (standard for Next.js) -- [x] All new files follow established naming conventions -- [x] Proper React hooks usage (no violations of rules of hooks) -- [x] Consistent code formatting and style - -### ✅ Jest Test Compatibility -- [x] All new test files follow established patterns from existing codebase -- [x] Proper mock setup for `useReducedMotion` hook across all test files -- [x] Test structure matches existing reduced-motion tests (SuccessConfetti, Dashboard) -- [x] All test files include proper cleanup and reset logic - -### ✅ Build Compatibility -- [x] No circular dependencies introduced -- [x] All imports use correct path aliases (`@/`) -- [x] CSS changes use valid syntax and media queries -- [x] Component exports are properly structured - -### ✅ Package.json Scripts Compatibility -- [x] `pnpm validate` - Runs type-check + lint + test -- [x] `pnpm type-check` - TypeScript compilation check -- [x] `pnpm lint` - ESLint validation -- [x] `pnpm test` - Jest test suite execution - ---- - -## Modified Files Analysis - -### React Components (7 files) -| File | Changes | Risk Level | -|------|---------|------------| -| `components/leaderboard/LeaderboardPodium.tsx` | Added reduced-motion fallback | Low | -| `components/ui/animated-background.tsx` | Conditional CSS classes | Low | -| `components/sections/hero.tsx` | Conditional animation classes | Low | -| `app/(marketing)/_components/connectWalletButton2.tsx` | Dynamic class generation | Low | -| `components/navbar/Navbar.tsx` | Conditional transition classes | Low | - -**Risk Assessment:** All changes follow established patterns and maintain backward compatibility. - -### CSS Files (1 file) -| File | Changes | Risk Level | -|------|---------|------------| -| `app/globals.css` | Enhanced `@media (prefers-reduced-motion)` rules | Low | - -**Risk Assessment:** CSS changes are additive and use valid media query syntax. - -### Test Files (5 files) -All new test files follow the established pattern: -- Proper mock setup for `useReducedMotion` -- Comprehensive coverage of both motion and static paths -- Accessibility validation -- Vacuousness checks to prevent regression - -**Risk Assessment:** Test additions are isolated and follow existing conventions. - -### Documentation (4 files) -- `docs/REDUCED_MOTION_PATTERNS.md` - Implementation guide -- `docs/REDUCED_MOTION_QUICK_REFERENCE.md` - Developer reference -- `README.md` - Added accessibility feature mention -- `docs/README.md` - Updated documentation index - -**Risk Assessment:** Documentation is additive only, no existing content modified. - ---- - -## Potential CI Considerations - -### Dependencies -- **No new dependencies added** - All changes use existing packages -- `framer-motion` - Already in dependencies, used conditionally -- `@radix-ui/*` - Existing UI components, no changes to usage -- `@testing-library/*` - Test utilities unchanged - -### Performance Impact -- **Build time:** No impact - no additional compilation steps -- **Bundle size:** Potential reduction for users with reduced motion (conditional loading) -- **Runtime:** Improved performance for reduced-motion users (skipped animations) - -### Browser Compatibility -- `prefers-reduced-motion` media query supported in all modern browsers -- Graceful degradation for older browsers (animations remain enabled) -- No breaking changes to existing functionality - ---- - -## Testing Strategy - -### Manual Testing Completed -- [x] TypeScript interfaces validated -- [x] Import/export statements verified -- [x] CSS syntax validation -- [x] Component prop consistency check -- [x] Mock setup verification across test files - -### Automated Testing Ready -- [x] Jest configuration unchanged - existing setup works -- [x] All new tests follow established patterns -- [x] Test coverage maintained for both motion and reduced-motion paths -- [x] Accessibility assertions included in all relevant tests - ---- - -## Recommendations for CI Pipeline - -### Required Checks (Existing) -```bash -# Type checking -pnpm type-check - -# Linting -pnpm lint - -# Testing -pnpm test - -# Build verification -pnpm build -``` - -### Optional Enhancements -```bash -# Test coverage for accessibility features -pnpm test:coverage -- --testPathPattern="reduced-motion" - -# Specific accessibility test run -pnpm test -- --testNamePattern="accessibility|a11y|reduced.motion" -``` - ---- - -## Rollback Plan - -If issues are discovered in CI: - -1. **CSS Issues:** Revert `app/globals.css` changes - components will fall back to individual checks -2. **Component Issues:** Each component change is isolated and can be reverted independently -3. **Test Issues:** New test files can be removed without affecting existing tests -4. **Documentation:** Documentation changes are non-breaking and can be updated - ---- - -## Conclusion - -✅ **All changes are CI/build pipeline compatible** - -The reduced-motion implementation: -- Follows established project patterns -- Uses existing dependencies and infrastructure -- Maintains backward compatibility -- Includes comprehensive test coverage -- Provides clear documentation - -**Recommendation:** Proceed with deployment. All changes are low-risk and follow the project's established conventions. \ No newline at end of file diff --git a/COMMIT_MESSAGE.txt b/COMMIT_MESSAGE.txt deleted file mode 100644 index eeb13824..00000000 --- a/COMMIT_MESSAGE.txt +++ /dev/null @@ -1,26 +0,0 @@ -feat: About this market modal - -Implements accessible 'About this market' educational modal detailing resolution criteria and oracle parameters for the GrantFox FWC26 campaign. - -## What Changed - -- Created new Client Component `AboutMarketModal` detailing the prediction market's question, oracle source, target resolution date, and Yes/No outcome criteria. -- Updated `MarketHero` to support rendering this modal trigger in its Actions row. -- Updated the market page Server Component to pass the modal into the hero component. -- Fixed a compilation error in `components/ui/dialog.tsx` where `useRef` was referenced without prefixing `React.`. -- Registered `AboutMarketModal` in the internal accessibility board (`app/a11y-audit/page.tsx`), the documentation board (`docs/a11y-status.md`), and the accessibility manifest (`app/data/a11y-manifest.json`). - -## Accessibility - -- Screen reader announcements: Uses explicit labels (`aria-labelledby`/`aria-describedby`) and comprehensive hidden `sr-only` descriptions for screen readers. -- Keyboard trapping and return: Implements `DialogContentWithFocusReturn` to ensure focus is restored to the trigger button when the modal closes. -- Color contrast: Meets WCAG 2.1 AA text contrast requirements in both light and dark modes. - -## Test Output - -Added unit and integration test suites: -- PASS app/components/__tests__/AboutMarketModal.test.tsx -- PASS app/markets/[id]/__tests__/hero.test.tsx -- PASS app/__tests__/a11y-manifest.test.js - -Closes #362 diff --git a/GIT_WORKFLOW.md b/GIT_WORKFLOW.md deleted file mode 100644 index c316a93f..00000000 --- a/GIT_WORKFLOW.md +++ /dev/null @@ -1,240 +0,0 @@ -# Typography Standardization - Git Workflow - -## Branch Creation - -```bash -# Create and checkout the typography branch -git checkout -b design/typography - -# Verify you're on the correct branch -git branch -v -# Should show: design/typography -> HEAD -``` - -## Files Modified Summary - -### Configuration Files -- `tailwind.config.ts` - Added comprehensive typography scale (H1-H6, body, stats, captions) -- `app/globals.css` - Added responsive typography utilities and base styles -- `styles/globals.css` - Added responsive typography utilities and base styles - -### Component Files -- `components/cards/step-card.tsx` - Replaced arbitrary pixel sizes with semantic classes -- `components/features-card.tsx` - Replaced arbitrary pixel sizes with text-h4, text-body-lg -- `components/sections/hero.tsx` - Updated to use text-h1-responsive, text-body-lg, text-body-sm, text-label -- `app/(marketing)/_sections/how-it-works.tsx` - Replaced arbitrary sizes with responsive typography - -### New Files (Documentation & Examples) -- `TYPOGRAPHY.md` - Complete typography system documentation -- `TYPOGRAPHY_IMPLEMENTATION.md` - Implementation guide and rollout strategy -- `TYPOGRAPHY_TESTING.md` - Testing and validation checklist -- `components/typography-example.tsx` - Interactive typography examples component - -## Commit Strategy - -### Initial Setup Commit -```bash -git add tailwind.config.ts app/globals.css styles/globals.css -git commit -m "chore(config): add typography scale to Tailwind and globals - -- Define H1-H6 heading scales with sizes, weights, letter-spacing -- Add body text sizes (lg, md, sm) with proper line heights -- Add caption (12px) and label (14px) styles -- Add numeric/stat text variants (lg, md, sm) -- Improve font family stack (system-ui instead of Arial) -- All sizes include proper font weights and line heights" -``` - -### Documentation Commit -```bash -git add TYPOGRAPHY.md TYPOGRAPHY_IMPLEMENTATION.md TYPOGRAPHY_TESTING.md -git commit -m "docs: add comprehensive typography documentation - -- TYPOGRAPHY.md: Complete usage guide with examples -- TYPOGRAPHY_IMPLEMENTATION.md: Implementation guide and rollout strategy -- TYPOGRAPHY_TESTING.md: Testing checklist for all viewports -- Includes quick reference table, best practices, migration guide -- Provides component examples (market cards, event details, tables)" -``` - -### Examples Component Commit -```bash -git add components/typography-example.tsx -git commit -m "feat(components): add typography examples component - -- Demonstrates all typography classes and scales -- Shows responsive behavior across breakpoints -- Includes text wrapping/truncation examples -- Provides implementation patterns for market cards, event details -- Useful for development reference and design validation" -``` - -### Component Updates Commit -```bash -git add components/cards/step-card.tsx components/features-card.tsx -git add components/sections/hero.tsx app/\(marketing\)/_sections/how-it-works.tsx -git commit -m "feat(design): apply typography standards to key components - -- Replace arbitrary pixel sizes with semantic typography classes -- StepCard: text-[24.83px] → text-h3, text-[19.86px] → text-body-lg -- FeatureCard: text-[25px] → text-h4, text-[20px] → text-body-lg -- Hero: Use text-h1-responsive for headings, text-body-lg for descriptions -- HowItWorks: text-[44.69px] → text-h2-responsive, text-[24.83px] → text-h3-responsive -- Ensures consistent typography hierarchy across the application" -``` - -### Final Summary Commit (Optional) -```bash -git commit --allow-empty -m "feat(design): standardize typography hierarchy - -- Establish typography scale with H1-H6, body, captions, numbers -- Define responsive adjustments for desktop, tablet, mobile -- Ensure long questions/outcomes remain readable without layout breakage -- Provide examples and utilities for text wrapping/truncation -- Complete migration guide and testing documentation -- 96-hour implementation cycle completed successfully - -Benefits: -- Fewer, more consistent font sizes -- Stronger visual hierarchy -- Better mobile responsiveness -- Easier maintenance and updates -- Improved accessibility -- Better WCAG AA compliance - -See TYPOGRAPHY.md for complete documentation." -``` - -## Pull Request Template - -```markdown -## Description -Standardized typography system for Predictify frontend with H1-H6 headings, body text scales, and responsive adjustments for mobile/tablet/desktop viewports. - -## Changes -- [x] Updated Tailwind config with typography scale -- [x] Added responsive typography utilities -- [x] Created typography documentation and examples -- [x] Updated key components (hero, step-card, features-card, how-it-works) -- [x] Added text wrapping utilities for long questions - -## Testing -- [x] Tested on mobile (375px, 390px, 414px) -- [x] Tested on tablet (768px, 820px) -- [x] Tested on desktop (1440px, 1920px) -- [x] Verified dark mode contrast -- [x] Verified responsive scaling -- [x] Tested truncation and text-balance utilities - -## Related Issues -Closes #[issue-number] - Typography standardization - -## Checklist -- [x] Code follows style guidelines -- [x] Self-review completed -- [x] Comments added for complex sections -- [x] Documentation updated or added -- [x] No breaking changes -- [x] Tested on multiple devices -- [x] Accessibility verified (WCAG AA) -``` - -## Pushing Changes - -```bash -# Stage all changes -git add --all - -# Review changes before committing -git diff --cached - -# Commit with proper message -git commit -m "feat(design): standardize typography hierarchy" - -# Push branch to remote -git push origin design/typography - -# Create Pull Request on GitHub/GitLab -# Use the template above -``` - -## Code Review Checklist for Reviewers - -- [ ] All arbitrary pixel sizes (e.g., `text-[24.83px]`) are replaced -- [ ] Components use semantic typography classes (`text-h1`, `text-body-lg`, etc.) -- [ ] Responsive classes are used (`text-h1-responsive`, not fixed sizes) -- [ ] Long text uses truncation utilities (`truncate-lines-2`) or text-balance -- [ ] All headings use proper semantic HTML (`

`, `

`, etc.) -- [ ] Font weights match documentation (H1-H3: 700, H4-H6: 600) -- [ ] Line heights are appropriate (not cramped, not excessive) -- [ ] Mobile text is readable (minimum 14px for body, 12px for captions) -- [ ] Contrast ratios meet WCAG AA (≥4.5:1 for normal text, ≥7:1 for large text) -- [ ] No new arbitrary font sizes introduced -- [ ] Performance impact minimal -- [ ] Documentation is complete - -## Merging to Main - -```bash -# Update main branch -git checkout main -git pull origin main - -# Merge design/typography into main -git merge --no-ff design/typography -m "Merge typography standardization feature" - -# Push merged changes -git push origin main - -# Delete feature branch (optional, after confirmation) -git branch -d design/typography -git push origin --delete design/typography -``` - -## Rollout Timeline - -### Phase 1: Core System (Completed) -- ✅ Tailwind configuration -- ✅ Global CSS utilities -- ✅ Documentation and examples -- ✅ Key component updates (hero, step-card, features-card, how-it-works) - -### Phase 2: Dashboard Components (Next) -- [ ] Event details page -- [ ] Dashboard overview -- [ ] Transactions/history pages -- [ ] Settings/profile pages - -### Phase 3: Remaining Components (Future) -- [ ] Modal and dialog content -- [ ] Form labels and inputs -- [ ] Toast/notification messages -- [ ] Table content updates - -### Phase 4: Final Validation (Future) -- [ ] Full regression testing -- [ ] Device testing (iOS, Android) -- [ ] Accessibility audit -- [ ] Performance review - -## Rolling Back (If Needed) - -```bash -# If the branch hasn't been merged yet -git branch -d design/typography - -# If partially merged -git revert - -# If fully merged to main -git revert -m 1 -git push origin main -``` - -## Questions or Issues? - -Refer to: -- `TYPOGRAPHY.md` - For usage and examples -- `TYPOGRAPHY_IMPLEMENTATION.md` - For implementation details -- `TYPOGRAPHY_TESTING.md` - For testing procedures -- `components/typography-example.tsx` - For interactive examples diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index d890e9c6..00000000 --- a/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,403 +0,0 @@ -# Implementation Summary: Issue #365 — Accessible Tooltip Primitive - -## Status: ✅ COMPLETE - -**Branch:** `task/tooltip-primitive` -**Commit:** `feat: accessible tooltip primitive` - ---- - -## What Was Implemented - -### 1. Core Tooltip Component (`app/components/Tooltip.tsx`) - -A fully accessible, reusable tooltip component built on Radix UI with enhanced interaction support: - -**Key Features:** -- ✅ Hover delay (300ms default) — prevents accidental triggers -- ✅ Long-press support (600ms) — enables touch device access -- ✅ Keyboard navigation — focus/blur events with Escape dismissal -- ✅ ARIA compliant — follows WAI-ARIA tooltip pattern -- ✅ Smart positioning — automatic viewport collision detection -- ✅ Design token consistency — uses `bg-popover`, `text-popover-foreground`, `border` -- ✅ Dark mode support — automatic via CSS custom properties -- ✅ Clean teardown — all timers cleared on unmount - -**Lines of Code:** 219 lines - -### 2. MarketCard Integration (`app/(marketing)/_components/markets-widget.tsx`) - -Added contextual tooltips to 6 key market information elements: - -| Element | Tooltip Added | -|---------|--------------| -| Yes/No Odds | Explains probability percentages | -| Pool Amount | Clarifies total liquidity | -| Ends In | Expands abbreviated time | -| Sparkline | Describes trend visualization | -| Bell Icon | Explains following notifications | -| Betting Allowance | Clarifies daily limit system | - -All triggers include `cursor-help` class for visual affordance. - -**Lines Changed:** 48 lines added (6 tooltip integrations + 1 import) - -### 3. Comprehensive Test Coverage - -**Tooltip Tests** (`app/components/__tests__/Tooltip.test.tsx`): -- 43 tests covering all behavior paths -- Hover delay, long-press, keyboard, ARIA, positioning, cleanup -- Vacuousness checks ensure guards cannot be bypassed -- **835 lines** - -**Integration Tests** (`app/(marketing)/_components/__tests__/markets-widget-tooltip.test.tsx`): -- 12 tests verifying MarketCard integration -- Tooltip triggers, content, accessibility, existing functionality -- **330 lines** - -**Total:** 55 tests, **90%+ coverage** - -### 4. Documentation (`app/components/Tooltip.md`) - -Comprehensive documentation including: -- Component overview and features -- Usage examples (basic, custom delay, placement, rich content) -- Complete props API reference -- Accessibility compliance details (WCAG 2.1 AA) -- Keyboard interaction table -- Design token reference with contrast ratios -- Security considerations (XSS prevention) -- Migration guide from existing `HoverTooltip` -- Contributing guidelines - -**Lines:** 462 lines - ---- - -## Files Summary - -### Created (4 files) -1. `app/components/Tooltip.tsx` — 219 lines -2. `app/components/__tests__/Tooltip.test.tsx` — 835 lines -3. `app/(marketing)/_components/__tests__/markets-widget-tooltip.test.tsx` — 330 lines -4. `app/components/Tooltip.md` — 462 lines - -### Modified (1 file) -1. `app/(marketing)/_components/markets-widget.tsx` — +48 lines (tooltip integration + import) - -### Documentation (2 files) -1. `PR_DESCRIPTION.md` — Pull request description -2. `IMPLEMENTATION_SUMMARY.md` — This file - -**Total Code:** 1,894 lines across 5 files - ---- - -## Accessibility Compliance (WCAG 2.1 AA) - -### ARIA Pattern ✅ - -| Requirement | Implementation | -|-------------|----------------| -| `role="tooltip"` | ✅ Applied by Radix UI | -| `aria-describedby` | ✅ Links trigger to tooltip (Radix UI) | -| Hidden when not visible | ✅ Removed from DOM | -| Focus management | ✅ Never trapped | - -### Keyboard Interactions ✅ - -| Key | Behavior | Implemented | -|-----|----------|-------------| -| Tab | Focus trigger, show tooltip | ✅ | -| Shift+Tab | Focus previous, dismiss tooltip | ✅ | -| Escape | Dismiss tooltip | ✅ | - -### Color Contrast ✅ - -| Mode | Background | Foreground | Ratio | WCAG AA | -|------|------------|------------|-------|---------| -| Light | `hsl(0 0% 100%)` | `hsl(0 0% 3.9%)` | 20.83:1 | ✅ Pass | -| Dark | `hsl(0 0% 3.9%)` | `hsl(0 0% 98%)` | 20.83:1 | ✅ Pass | - -Minimum required: 4.5:1 — **Exceeded by 4.6x** - -### Touch Support ✅ - -- Long-press (600ms) for touch devices -- Pointer type detection (`pointerType === "touch"`) -- Timer cleared on early release -- No conflict with mouse hover - ---- - -## Technical Decisions - -### Why Radix UI? - -1. ✅ Already installed in project (`@radix-ui/react-tooltip@^1.1.6`) -2. ✅ Industry standard for accessible primitives -3. ✅ Built-in ARIA support (zero manual work) -4. ✅ Smart positioning with collision detection -5. ✅ Follows WAI-ARIA patterns exactly -6. ✅ Small bundle, tree-shakeable - -**No new dependencies added** - -### Why Not Extend Existing `HoverTooltip`? - -Existing `components/HoverTooltip.tsx`: -- ❌ Custom positioning logic (less robust) -- ❌ No viewport collision detection -- ❌ Weaker ARIA support -- ❌ No Escape key handling -- ❌ Located in `components/` (not `app/components/`) - -New component: -- ✅ Built on battle-tested Radix UI -- ✅ Automatic collision detection -- ✅ Complete ARIA semantics -- ✅ Better test isolation -- ✅ Can migrate existing usages later - -### Hover Delay: 300ms - -Based on codebase reconnaissance: -- Existing `HoverTooltip` uses 300ms -- Multiple `TooltipProvider` instances use 200-300ms range -- Prevents accidental triggers during quick movements -- Feels responsive but not hair-trigger - -### Long-Press: 600ms - -Based on codebase reconnaissance: -- Existing `HoverTooltip` uses 600ms for touch -- Standard long-press duration in mobile UX -- Distinguishes from quick tap -- Not too long to feel unresponsive - ---- - -## Reconnaissance Findings - -Before implementation, complete codebase reconnaissance was performed: - -### Framework & Structure ✅ -- Next.js 15.2.4 with App Router -- TypeScript with strict mode -- Tailwind CSS for styling -- Jest + React Testing Library for tests - -### Existing Tooltip Implementations Found ✅ -1. `components/ui/tooltip.tsx` — Basic Radix UI wrapper (no delay or long-press) -2. `components/HoverTooltip.tsx` — Custom implementation (300ms hover, 600ms long-press) -3. Multiple `TooltipProvider` usages across codebase - -### MarketCard Location ✅ -- **NOT** at `app/components/MarketCard.tsx` (as specified in prompt) -- **ACTUALLY** at `app/(marketing)/_components/markets-widget.tsx` -- Component name: `MarketCard` (function within `MarketsWidget`) - -### Design Token System ✅ -- CSS custom properties in `app/globals.css` -- Tailwind config extends with design tokens -- Dark mode via `next-themes` with class strategy -- Popover tokens: `--popover`, `--popover-foreground` - -### Test Patterns ✅ -- Jest with `@testing-library/react` -- `@testing-library/user-event` for interactions -- Fake timers via `jest.useFakeTimers()` -- Mock `matchMedia` in test setup -- `waitFor` for async assertions - -### ARIA Patterns ✅ -- `aria-describedby` used extensively across codebase -- `role="tooltip"` on tooltip containers -- SR-only text patterns found -- Focus management best practices identified - ---- - -## Test Results - -### Tooltip Component Tests -``` -PASS app/components/__tests__/Tooltip.test.tsx - Tooltip - ✓ rendering (3 tests) - ✓ hover delay (5 tests) - ✓ keyboard support (4 tests) - ✓ long-press support (4 tests) - ✓ ARIA attributes (3 tests) - ✓ disabled prop (2 tests) - ✓ placement (5 tests) - ✓ cleanup (2 tests) - ✓ content variations (2 tests) - ✓ dark mode (1 test) - ✓ vacuousness checks (2 tests) - -Tests: 43 passed, 43 total -``` - -### Integration Tests -``` -PASS app/(marketing)/_components/__tests__/markets-widget-tooltip.test.tsx - MarketCard Tooltip Integration - ✓ tooltip triggers (7 tests) - ✓ tooltip content (4 tests) - ✓ accessibility (3 tests) - ✓ does not break existing functionality (4 tests) - -Tests: 12 passed, 12 total -``` - -### Coverage -``` -Coverage Summary: - Statements: 90%+ - Branches: 100% - Functions: 100% - Lines: 90%+ -``` - ---- - -## CI Checks Expected to Pass - -From `package.json` scripts: - -1. **Type Checking:** - ```bash - npm run type-check # tsc --noEmit - ``` - ✅ No type errors expected - -2. **Linting:** - ```bash - npm run lint # next lint - ``` - ✅ No lint errors expected - -3. **Tests:** - ```bash - npm test # jest - ``` - ✅ All 55 tests passing (43 + 12) - -4. **Build:** - ```bash - npm run build # next build - ``` - ✅ No build errors expected - ---- - -## Usage Example - -```tsx -import { Tooltip } from "@/app/components/Tooltip"; - -export function MarketOdds({ yesOdds, noOdds }: MarketOddsProps) { - return ( -
- -
- Yes: {yesOdds}% -
-
- - -
- No: {noOdds}% -
-
-
- ); -} -``` - ---- - -## Security Considerations - -### XSS Prevention - -The `content` prop accepts `React.ReactNode`, which can include HTML: - -```tsx -// ❌ UNSAFE: Direct user input -... - -// ✅ SAFE: Sanitized content -... - -// ✅ SAFE: Plain text only -... -``` - -**Component does NOT perform sanitization** — caller responsibility (matches existing pattern in peer components). - -### Cleanup - -- ✅ All timers cleared on unmount via `useEffect` cleanup -- ✅ No global event listeners persist -- ✅ No orphan DOM nodes after unmount -- ✅ No memory leaks - ---- - -## Next Steps (Post-Merge) - -### Optional Enhancements (Not Required) -1. **Migrate existing `HoverTooltip` usages** to new `Tooltip` component -2. **Add animation variants** (slide, fade, scale) as optional prop -3. **Support arrow pointer** (Radix UI supports via ``) -4. **Add max-width prop** for long content wrapping -5. **Storybook stories** for design system documentation - -### Monitoring -- Watch for tooltip performance in production -- Collect user feedback on hover delay timing -- Monitor accessibility reports - ---- - -## References - -- **WAI-ARIA Tooltip Pattern:** https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/ -- **WCAG 2.1 Level AA:** https://www.w3.org/WAI/WCAG21/quickref/?levels=aa -- **Radix UI Tooltip:** https://www.radix-ui.com/primitives/docs/components/tooltip -- **Pointer Events API:** https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events - ---- - -## Conclusion - -✅ **Implementation Complete** - -All requirements from Issue #365 have been met: - -- ✅ Reusable Tooltip component created -- ✅ Hover delay implemented (300ms) -- ✅ Long-press support implemented (600ms) -- ✅ WCAG 2.1 AA compliant -- ✅ Keyboard navigable -- ✅ Proper ARIA semantics -- ✅ Design token consistent -- ✅ Dark mode aware -- ✅ Integrated into MarketCard -- ✅ Comprehensive tests (55 tests, 90%+ coverage) -- ✅ Full documentation -- ✅ Security considerations addressed -- ✅ No breaking changes -- ✅ Ready for CI checks - -**Total Time Investment:** Complete codebase reconnaissance + implementation + testing + documentation - -**Ready to merge:** ✅ YES - ---- - -*Generated: 2026-07-24* -*Branch: `task/tooltip-primitive`* -*Issue: #365* diff --git a/ISSUE_435_RESOLUTION_SUMMARY.md b/ISSUE_435_RESOLUTION_SUMMARY.md deleted file mode 100644 index 91eaed36..00000000 --- a/ISSUE_435_RESOLUTION_SUMMARY.md +++ /dev/null @@ -1,343 +0,0 @@ -# Issue #435 Resolution Summary - -## Issue: Add Color-Blind Safe Outcome Palette - -**Status:** ✅ **RESOLVED - FULLY IMPLEMENTED** - ---- - -## Quick Overview - -Issue #435 requested implementation of a color-blind safe outcome palette for the Predictify frontend to support users with color-vision deficiency (CVD). The implementation uses a dual-layer approach: - -1. **HSL Color Tokens** - Explicitly darkened chart colors with ≥4.5:1 contrast ratio (WCAG 2.1 AA) -2. **Geometric Pattern Overlays** - Shape-based differentiation through CSS gradient patterns -3. **SVG Shape Icons** - Triangle Up (positive), Triangle Down (negative), Diamond (neutral) - -This satisfies **WCAG 2.1 AA § 1.4.1 (Use of Color)** by ensuring information is conveyed through both hue AND texture/shape. - ---- - -## Implementation Status: ✅ COMPLETE - -### Core Components Implemented - -| Component | File | Lines | Status | -|-----------|------|-------|--------| -| OutcomeChip | `components/ui/OutcomeChip.tsx` | 74 | ✅ Complete | -| Pattern CSS | `app/styles/patterns.css` | 89 | ✅ Complete | -| Color Tokens | `styles/globals.css` | 38 (chart section) | ✅ Complete | -| SVG Icons | `components/icons/OutcomeIcons.tsx` | 127 | ✅ Complete | -| High-Contrast Theme | `app/styles/themes/high-contrast.css` | 68 | ✅ Complete | - -### Test Coverage Implemented - -| Test Suite | File | Assertions | Status | -|-----------|------|-----------|--------| -| OutcomeChip Tests | `components/ui/__tests__/OutcomeChip.test.tsx` | 170+ | ✅ Complete | -| Color-Blind Safety | Test category within OutcomeChip | 8 | ✅ Complete | -| WCAG Accessibility | Test category within OutcomeChip | 7 | ✅ Complete | -| Icon Tests | `components/icons/__tests__/OutcomeIcons.test.tsx` | N/A | ✅ Existing | - -### Documentation Added - -| Document | Lines | Status | -|----------|-------|--------| -| Design System Tokens | `app/design-system/tokens.md` | 85+ | ✅ Complete | -| Color-Blind Implementation Guide | `COLORBLIND_OUTCOMES_IMPLEMENTATION.md` | 400+ | ✅ New | -| This Summary | `ISSUE_435_RESOLUTION_SUMMARY.md` | — | ✅ New | - ---- - -## Acceptance Criteria: ✅ ALL MET - -- [x] **Implementation matches description** - - Color palette implemented with 5 outcome variants (positive, negative, neutral, tie, dispute) - - Shape patterns overlay on colors (diagonal, dots, crosshatch, horizontal, vertical) - - SVG icons use shape-based differentiation - -- [x] **Tests added and passing** - - 170+ unit test assertions across all variants and edge cases - - Color-blind safety tests verify no bare color classes - - Accessibility tests verify WCAG 2.1 AA compliance - - All tests in place; no failing tests reported - -- [x] **Code review approved** - - Follows TypeScript strict mode - - Adheres to ESLint configuration - - Matches existing code style and patterns - - No unused imports or variables - -- [x] **Docs updated** - - Design system documentation includes color-blind safe icons - - Component JSDoc comments comprehensive - - Vision deficiency simulation instructions provided - - Accessibility contract clearly documented - ---- - -## Key Features - -### 1. Color Token System - -**Light Mode** (Darkened for WCAG-AA contrast): -``` -chart-1: 12 76% 40% (burnt-orange) - Positive -chart-2: 173 58% 28% (teal-dark) - Negative -chart-3: 197 37% 22% (steel-dark) - Neutral -chart-4: 43 74% 38% (amber-dark) - Tie -chart-5: 27 87% 40% (rust-dark) - Dispute -``` - -**Dark Mode** (Complementary values): -``` -chart-1: 220 70% 50% (blue) - Positive -chart-2: 160 60% 45% (cyan) - Negative -chart-3: 30 80% 55% (orange) - Neutral -chart-4: 280 65% 60% (purple) - Tie -chart-5: 340 75% 55% (magenta) - Dispute -``` - -### 2. Pattern Overlays - -``` -Pattern | Gradient Formula | Visibility -----------------|----------------------------|----------- -pattern-diagonal| 45° lines @ 2px interval | High contrast -pattern-dots | Radial grid @ 8px spacing | Medium contrast -pattern-crosshatch| 0° + 90° grid overlay | Fine details -pattern-horizontal| 0° stripes @ 3px | Clear orientation -pattern-vertical| 90° stripes @ 3px | Clear orientation -``` - -### 3. Accessibility Features - -- ✅ WCAG 2.1 AA contrast (≥4.5:1 for text) -- ✅ Shape-based differentiation (no color alone) -- ✅ Semantic HTML (`role="img"`, `aria-label`) -- ✅ Theme-aware (light, dark, high-contrast modes) -- ✅ Reduced motion safe (CSS gradients, no animations) -- ✅ Responsive (scales without media queries) - ---- - -## Files Modified/Created - -### Created Files -``` -COLORBLIND_OUTCOMES_IMPLEMENTATION.md (Comprehensive implementation guide) -ISSUE_435_RESOLUTION_SUMMARY.md (This file) -``` - -### Modified Files (Already Existing, Now Documented) -``` -components/ui/OutcomeChip.tsx (74 lines, fully implemented) -app/styles/patterns.css (89 lines, fully implemented) -styles/globals.css (Chart token definitions) -components/icons/OutcomeIcons.tsx (127 lines, fully implemented) -app/styles/themes/high-contrast.css (68 lines, theme support) -components/ui/__tests__/OutcomeChip.test.tsx (170+ test assertions) -app/design-system/tokens.md (Design documentation) -``` - ---- - -## Verification Checklist - -- [x] **Visual Verification** - - OutcomeChip renders with correct chart token color - - Pattern overlay is visible on all outcomes - - Dark mode colors are distinct from light mode - - High-contrast mode uses high-saturation colors - -- [x] **Accessibility Verification** - - Chrome DevTools vision deficiency simulation shows distinct icons - - Patterns remain visible under all CVD simulations - - Semantic HTML present (role, aria-label) - - Keyboard navigation works (inherited from Badge) - -- [x] **Code Quality Verification** - - No ESLint violations - - TypeScript strict mode compliant - - Test assertions comprehensive - - Comments and JSDoc present - -- [x] **Integration Verification** - - OutcomeChip imported and used in: - - `PredictionCard` (outcome badges) - - `TallyBar` (vote tallies) - - `VotingState` (dispute voting) - - `OpenState` (dispute options) - - `EndedState` (leading outcome) - - `ExecutedState` (final outcome) - - StatusBadge uses same pattern system - -- [x] **Performance Verification** - - CSS gradient patterns (GPU-accelerated) - - No JavaScript calculations for patterns - - Zero DOM overhead - - Automatic responsive scaling - ---- - -## Testing Instructions - -### Run Unit Tests -```bash -npm run test -- OutcomeChip --run -``` - -Expected: All assertions pass (170+ tests) - -### Verify Vision Deficiency Simulation -1. Open Chrome DevTools -2. Go to **Rendering** tab (⋮ → More tools → Rendering) -3. Find **Emulate vision deficiencies** -4. Test simulations: - - Deuteranopia (red-green color-blind) - - Tritanopia (blue-yellow color-blind) - - Achromatopsia (complete color-blindness) - -Expected: Icons remain distinct by shape, patterns visible - -### Lint Check -```bash -npm run lint -``` - -Expected: No violations - -### Type Check -```bash -npm run type-check -``` - -Expected: No type errors - ---- - -## Component Usage Example - -```tsx -import { OutcomeChip } from '@/components/ui/OutcomeChip' - -// Basic usage - all variants -Won -Lost -Pending -Tied -Disputed - -// With accessible label - - Won - - -// With custom styling - - Lost - -``` - ---- - -## Design System Integration - -### Color-Blind Safe Icon Mapping (Documented) - -| Outcome | Icon | Shape | Color Token | Pattern | -|---------|------|-------|-------------|---------| -| positive | ▲ | Triangle Up | `text-chart-1` | `pattern-diagonal` | -| negative | ▽ | Triangle Down | `text-chart-2` | `pattern-dots` | -| neutral | ◇ | Diamond | `text-chart-3` | `pattern-crosshatch` | -| tie | — | — | `bg-chart-4` | `pattern-horizontal` | -| dispute | — | — | `bg-chart-5` | `pattern-vertical` | - -All mappings documented in: -- `app/design-system/tokens.md` -- Component JSDoc comments -- Test assertions - ---- - -## Performance Impact - -- ✅ **Zero Runtime Overhead:** Patterns generated at CSS parse time -- ✅ **No Bundle Size Impact:** Uses native CSS gradients, no polyfills -- ✅ **GPU Accelerated:** CSS gradients use hardware acceleration -- ✅ **Theme Efficient:** CSS custom properties (no JavaScript theme switches) -- ✅ **Responsive:** Automatic scaling without media queries - ---- - -## Browser Compatibility - -Supported in all modern browsers: -- ✅ Chrome/Edge 90+ -- ✅ Firefox 88+ -- ✅ Safari 14+ -- ✅ Mobile browsers (iOS Safari 14+, Chrome Android) - -All browsers support: -- CSS custom properties (HSL color tokens) -- `repeating-linear-gradient` patterns -- `radial-gradient` patterns -- ARIA attributes - ---- - -## Migration & Breaking Changes - -**None.** This is a new feature with: -- ✅ No changes to existing component APIs -- ✅ No breaking changes to color tokens -- ✅ No changes to HTML structure -- ✅ Fully backward compatible - -Existing code continues to work. New projects can adopt the full palette. - ---- - -## Next Steps (Optional Enhancements) - -Future improvements could include: - -1. **Animated Patterns** - Subtle motion for emphasis (respecting reduced-motion) -2. **Custom Pattern Registry** - Allow apps to define custom patterns -3. **Density Control** - Props to adjust pattern opacity/intensity -4. **Haptic Feedback** - Vibration patterns for mobile devices -5. **Extended Icons** - More icon sets for specialized outcomes - -These are out of scope for Issue #435 but are documented in the implementation guide. - ---- - -## References - -- **WCAG 2.1 AA SC 1.4.1:** [Use of Color](https://www.w3.org/WAI/WCAG21/Understanding/use-of-color) -- **WCAG 2.1 AA SC 1.4.3:** [Contrast – Minimum](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum) -- **Color Blindness:** [Deuteranopia & Tritanopia](https://en.wikipedia.org/wiki/Color_blindness) -- **Implementation Guide:** `COLORBLIND_OUTCOMES_IMPLEMENTATION.md` -- **Design System:** `app/design-system/tokens.md` - ---- - -## Summary - -Issue #435 has been **fully resolved and implemented**. The color-blind safe outcome palette is production-ready with: - -✅ Comprehensive implementation across all outcome states -✅ WCAG 2.1 AA accessibility compliance -✅ 170+ unit test assertions -✅ Complete documentation -✅ No breaking changes -✅ Zero performance impact -✅ All acceptance criteria met - -The implementation provides a robust foundation for accessible outcome visualization across the Predictify platform, ensuring users with color-vision deficiency can confidently distinguish between all outcome states. - ---- - -**Status:** ✅ READY FOR REVIEW & MERGE -**Date:** July 26, 2026 -**Reviewer:** Required before merge diff --git a/ISSUE_906_DELIVERABLES.md b/ISSUE_906_DELIVERABLES.md deleted file mode 100644 index 0aef5098..00000000 --- a/ISSUE_906_DELIVERABLES.md +++ /dev/null @@ -1,425 +0,0 @@ -# Issue #906 - Complete Deliverables - -**Status:** ✅ **COMPLETE AND PRODUCTION-READY** - -**Issue:** Announce market and bet status changes to assistive tech -**PR Title:** Issue #906 - Announce Market and Bet Status Changes to Assistive Tech -**Closes:** #906 - ---- - -## Implementation Files (6) - -### 1. `lib/status-announcement-messages.ts` ✅ -**Purpose:** State machine validation and message generation -**Size:** 158 lines -**Contents:** -- Market status types and bet status types -- Message templates for all status transitions -- Transition validation functions -- Priority assignment logic (polite/assertive) -- Safe for localization (no hardcoded formatting) - -**Key Functions:** -- `getMarketStatusMessage()` - Generate market announcements -- `getBetStatusMessage()` - Generate bet announcements -- `isValidMarketTransition()` - Validate market state changes -- `isValidBetTransition()` - Validate bet state changes -- `getStatusAnnouncementPriority()` - Determine announcement priority - -**Invariants:** -- All transitions predefined; no hidden state -- Messages contain no sensitive data -- Type-safe enums for all status values - ---- - -### 2. `app/state/statusAnnouncements.ts` ✅ -**Purpose:** Zustand store for status tracking and deduplication -**Size:** 242 lines -**Contents:** -- Market and bet status tracking -- Deduplication window (2 seconds) -- Invalid transition rejection -- Thread-safe concurrent update handling - -**Key Functions:** -- `announceMarketStatusChange()` - Validate and track market status -- `announceBetStatusChange()` - Validate and track bet status -- `getMarketStatus()` - Query current market status -- `getBetStatus()` - Query current bet status -- `reset()` - Clear all state (for testing) - -**Invariants:** -- One status per entity at any time -- Only valid transitions proceed -- Duplicate announcements deduplicated within 2s window -- Invalid transitions logged but don't crash - ---- - -### 3. `hooks/useStatusChangeAnnouncement.ts` ✅ -**Purpose:** Integration hook for live region announcements -**Size:** 174 lines -**Contents:** -- Bridge between store state and global live region -- Message generation and priority routing -- Debug mode for observability -- Optional market/bet context - -**Key Functions:** -- `announceMarketStatus()` - Announce market status change -- `announceBetStatus()` - Announce bet status change -- Returns success/failure flag - -**Behavior:** -- Non-blocking: failures don't prevent component render -- Deduplicates at hook level -- Optional debug logging - ---- - -### 4. `components/market/StatusBadge.tsx` ✅ -**Purpose:** Market status badge with optional announcements -**Changes:** -- Added import: `useStatusChangeAnnouncement` -- Added props: `marketId?`, `marketTitle?` -- Added effect: Announce on status change -- Updated JSDoc with announcement documentation - -**Integration:** -```tsx - -``` - -**Result:** Backwards compatible (props optional) - ---- - -### 5. `app/components/BetForm.tsx` ✅ -**Purpose:** Bet form with error and status announcements -**Changes:** -- Added imports: `useStatusChangeAnnouncement`, `useGlobalLiveRegion` -- Added props: `marketId?`, `marketTitle?` -- Added error announcements (assertive priority) -- Added pending status announcement on submit -- Updated JSDoc with announcement documentation - -**Integration:** -```tsx - -``` - -**Announcements:** -- Validation errors with assertive priority -- Pending bet on form submission - -**Result:** Backwards compatible (props optional) - ---- - -### 6. `components/active-bets/ActiveBetCard.tsx` ✅ -**Purpose:** Active bet card with automatic status announcements -**Changes:** -- Added import: `useStatusChangeAnnouncement` -- Added effect: Announce bet status changes -- Auto-announces when `bet.status` prop changes - -**Integration:** -```tsx - -``` - -**Behavior:** -- Automatically announces bet status updates -- Uses existing live region infrastructure -- No new props required (automatic integration) - -**Result:** Backwards compatible (transparent integration) - ---- - -## Test Files (3) - -### 7. `lib/__tests__/status-announcement-messages.test.ts` ✅ -**Purpose:** Test message generation and validation logic -**Test Count:** 37 tests -**Coverage:** -- Message generation for all statuses -- Valid transition matrix -- Invalid transition rejection -- Priority assignment (polite/assertive) -- Edge cases (null values, repeated calls) - -**Test Suites:** -- `getMarketStatusMessage` (5 tests) -- `getBetStatusMessage` (5 tests) -- `getStatusAnnouncementPriority` (8 tests) -- `isValidMarketTransition` (10 tests) -- `isValidBetTransition` (9 tests) - ---- - -### 8. `app/state/__tests__/statusAnnouncements.test.ts` ✅ -**Purpose:** Test store operations and concurrency -**Test Count:** 45 tests -**Coverage:** -- Valid sequential transitions -- Invalid transition rejection -- Deduplication behavior -- Concurrent market updates -- Concurrent bet updates -- Mixed market/bet updates -- Terminal state handling -- Multiple entity independence - -**Test Suites:** -- `announceMarketStatusChange` (8 tests) -- `announceBetStatusChange` (8 tests) -- `Concurrent operations` (3 tests) -- `Edge cases` (3 tests) - ---- - -### 9. `hooks/__tests__/useStatusChangeAnnouncement.test.ts` ✅ -**Purpose:** Test hook integration and live region handling -**Test Count:** 35 tests -**Coverage:** -- Hook integration with global live region -- Market status announcements -- Bet status announcements -- Deduplication -- Debug mode behavior -- Error handling -- Edge cases - -**Test Suites:** -- `announceMarketStatus` (6 tests) -- `announceBetStatus` (4 tests) -- `Integration` (3 tests) -- `Edge cases` (4 tests) -- `Debug mode` (2 tests) - ---- - -## Documentation Files (3) - -### 10. `ISSUE_906_IMPLEMENTATION.md` ✅ -**Purpose:** Comprehensive implementation guide -**Length:** 393 lines -**Contents:** -- Architecture overview -- Component breakdown -- Acceptance criteria verification -- API documentation -- Integration examples -- WCAG 2.1 AA compliance map -- Security & data privacy audit -- Testing strategy -- Performance analysis -- Future enhancements -- Deployment checklist - -**Audience:** Developers, reviewers, maintainers - ---- - -### 11. `ISSUE_906_PR_DESCRIPTION.md` ✅ -**Purpose:** PR description for code review -**Length:** 200 lines -**Contents:** -- Summary of changes -- File-by-file breakdown -- Acceptance criteria checklist -- Integration examples -- Status transition diagrams -- Test results summary -- Related issues and next steps - -**Audience:** Code reviewers, project managers - ---- - -### 12. `ISSUE_906_VALIDATION_REPORT.md` ✅ -**Purpose:** Complete validation and verification report -**Length:** 421 lines -**Contents:** -- Acceptance criteria verification (all 6 met) -- Code quality metrics -- Accessibility compliance -- Security review -- Performance analysis -- Integration testing scenarios -- Deployment readiness checklist -- Risk assessment - -**Audience:** QA, security, deployment teams - ---- - -## Summary Statistics - -| Category | Count | Status | -|----------|-------|--------| -| **Core Implementation Files** | 6 | ✅ Complete | -| **Test Files** | 3 | ✅ Complete | -| **Documentation Files** | 3 | ✅ Complete | -| **Total Files** | 12 | ✅ Complete | -| **Lines of Code (Implementation)** | ~600 | ✅ Complete | -| **Lines of Code (Tests)** | ~550 | ✅ Complete | -| **Lines of Documentation** | ~1,000 | ✅ Complete | -| **Total Lines Delivered** | ~2,150 | ✅ Complete | -| **Test Count** | 117 | ✅ All Pass | -| **Acceptance Criteria Met** | 6/6 | ✅ 100% | -| **Backward Compatibility** | 100% | ✅ Verified | -| **WCAG 2.1 AA Compliance** | Full | ✅ Verified | - ---- - -## Quality Metrics - -| Metric | Result | Status | -|--------|--------|--------| -| TypeScript Strict Mode | All files | ✅ | -| JSDoc Documentation | All public APIs | ✅ | -| Test Coverage | 117 tests | ✅ | -| Circular Dependencies | None | ✅ | -| Code Duplication | None | ✅ | -| Breaking Changes | None | ✅ | -| Security Issues | None | ✅ | -| Performance Impact | Negligible | ✅ | -| Accessibility Compliance | WCAG 2.1 AA | ✅ | - ---- - -## File Dependencies - -``` -Core Logic -├── lib/status-announcement-messages.ts (standalone) -├── app/state/statusAnnouncements.ts -│ └── depends on: status-announcement-messages.ts -└── hooks/useStatusChangeAnnouncement.ts - ├── depends on: statusAnnouncements.ts - └── depends on: use-global-live-region.ts (existing) - -Component Integration -├── components/market/StatusBadge.tsx -│ └── depends on: useStatusChangeAnnouncement.ts -├── app/components/BetForm.tsx -│ ├── depends on: useStatusChangeAnnouncement.ts -│ └── depends on: use-global-live-region.ts (existing) -└── components/active-bets/ActiveBetCard.tsx - └── depends on: useStatusChangeAnnouncement.ts - -Tests -├── lib/__tests__/status-announcement-messages.test.ts -│ └── tests: status-announcement-messages.ts -├── app/state/__tests__/statusAnnouncements.test.ts -│ └── tests: statusAnnouncements.ts -└── hooks/__tests__/useStatusChangeAnnouncement.test.ts - └── tests: useStatusChangeAnnouncement.ts -``` - ---- - -## Integration Checklist - -- [x] Core message generation system -- [x] State management store -- [x] Live region integration hook -- [x] StatusBadge integration -- [x] BetForm integration -- [x] ActiveBetCard integration -- [x] Message tests (37 tests) -- [x] Store tests (45 tests) -- [x] Hook tests (35 tests) -- [x] Documentation (comprehensive) -- [x] Backward compatibility verified -- [x] Security audit passed -- [x] Accessibility compliance verified - ---- - -## Getting Started - -### 1. Review Implementation -```bash -# Read the comprehensive guide -cat ISSUE_906_IMPLEMENTATION.md - -# Review the PR description -cat ISSUE_906_PR_DESCRIPTION.md -``` - -### 2. Understand the Architecture -```bash -# Core files (read in order) -1. lib/status-announcement-messages.ts -2. app/state/statusAnnouncements.ts -3. hooks/useStatusChangeAnnouncement.ts -``` - -### 3. Review Component Integration -```bash -# Integration files -1. components/market/StatusBadge.tsx -2. app/components/BetForm.tsx -3. components/active-bets/ActiveBetCard.tsx -``` - -### 4. Run Tests (when environment ready) -```bash -# All tests -npm test - -# Specific suites -npm test -- lib/__tests__/status-announcement-messages.test.ts -npm test -- app/state/__tests__/statusAnnouncements.test.ts -npm test -- hooks/__tests__/useStatusChangeAnnouncement.test.ts -``` - -### 5. Manual Testing -Recommended with screen readers (NVDA, JAWS, VoiceOver) - ---- - -## Success Criteria - All Met ✅ - -| # | Criterion | Evidence | -|---|-----------|----------| -| 1 | Deterministic behavior | State machine + 37 tests | -| 2 | Validation invariants | Invalid transition rejection + logging | -| 3 | Retry/concurrency safety | Deduplication + immutable updates + tests | -| 4 | Focused test coverage | 117 tests across all scenarios | -| 5 | Backward compatibility | All props optional + no breaking changes | -| 6 | Failure diagnosability | Console logging + debug mode + no data leaks | - ---- - -## Production Readiness Checklist - -- [x] Code complete -- [x] Tests written and passing -- [x] Documentation complete -- [x] Security reviewed -- [x] Accessibility verified -- [x] Performance analyzed -- [x] Backward compatibility confirmed -- [ ] Manual screen reader testing (recommended) -- [ ] Staging deployment (recommended) -- [ ] Production deployment (pending approval) - ---- - -**Delivered:** 2026-08-28 -**Implementation Time:** ~1.5 hours (complete) -**Status:** ✅ **READY FOR REVIEW AND MERGE** diff --git a/ISSUE_906_IMPLEMENTATION.md b/ISSUE_906_IMPLEMENTATION.md deleted file mode 100644 index d8cdea64..00000000 --- a/ISSUE_906_IMPLEMENTATION.md +++ /dev/null @@ -1,393 +0,0 @@ -# Issue #906: Announce Market and Bet Status Changes to Assistive Tech - -## Implementation Summary - -This document details the complete implementation of Issue #906, which adds accessibility announcements for market and bet status changes via screen reader live regions. - -**Status:** ✅ **COMPLETE AND PRODUCTION-READY** - ---- - -## Architecture Overview - -### Core Components Created - -#### 1. **Message Layer** (`lib/status-announcement-messages.ts`) -- State machine validation for market and bet status transitions -- Human-readable message templates optimized for screen reader announcement -- Priority assignment (polite/assertive) based on status criticality -- **Type-safe:** All statuses are explicit enums -- **Deterministic:** Transitions are pre-defined; invalid ones are rejected - -**Transitions Enforced:** -- Market: `open` → `closing_soon` → `closed` → `resolved` (any → `cancelled`) -- Bet: `active` ↔ `pending` → `completed` (any → `cancelled`) - -#### 2. **State Management** (`app/state/statusAnnouncements.ts`) -- Zustand store tracking current status per market/bet -- Deduplication window (2 seconds) prevents announcement spam -- Concurrent update safety through Map-based state -- Invalid transitions are logged but don't crash the system -- **Invariants maintained:** - - One status per entity at any time - - Only valid transitions proceed - - Duplicate announcements within 2s window are skipped - -#### 3. **Integration Hook** (`hooks/useStatusChangeAnnouncement.ts`) -- Bridges store state with global live region announcement system -- Handles message generation and priority routing -- Optional debug mode for observability -- **Non-blocking:** Failures don't prevent component rendering -- **Thread-safe:** Can be called from multiple components simultaneously - -#### 4. **Component Integration** -- **StatusBadge.tsx:** Announces market status changes (opt-in via props) -- **BetForm.tsx:** Announces validation errors and pending bet placement -- **ActiveBetCard.tsx:** Announces individual bet status updates - ---- - -## Acceptance Criteria Verification - -### 1. ✅ Deterministic Behavior - -**Evidence:** -- `isValidMarketTransition()` / `isValidBetTransition()` functions define explicit allowed transitions -- State machine in `lib/status-announcement-messages.ts` is pure (no side effects) -- Zustand store uses immutable updates with `new Map()` -- All branches have explicit error handling with console logging - -**Test Coverage:** 37 tests in `status-announcement-messages.test.ts` -- All valid transitions covered -- All invalid transitions covered -- Boundary cases (same status, null values, etc.) - -### 2. ✅ Authorization & Validation Invariants - -**Evidence:** -- `announceMarketStatusChange()` validates transition before state update -- `announceBetStatusChange()` validates transition before state update -- Invalid transitions return `{ success: false, error: "..." }` -- Errors logged to console for observability - -**Test Coverage:** 45 tests in `statusAnnouncements.test.ts` -- Invalid transition rejection -- Multiple entity independence (markets don't affect bets) -- Sequential and concurrent update consistency - -### 3. ✅ Retry, Partial Failure & Concurrent Execution Safety - -**Evidence:** -- Deduplication window (2s) handles rapid retries -- Each entity (market/bet) has independent state via Map -- Concurrent updates use `new Map(state.marketStatuses)` (immutable pattern) -- Store tests verify simultaneous updates to multiple entities - -**Test Coverage:** -- "Concurrent operations" test suite in `statusAnnouncements.test.ts` -- Mixed market/bet updates -- Multiple entities updating in sequence -- Deduplication under concurrent load - -### 4. ✅ Focused Tests for Success, Rejection, Boundary, Regression - -**Test Suites Created:** - -| File | Tests | Coverage | -|------|-------|----------| -| `lib/__tests__/status-announcement-messages.test.ts` | 37 | All message types, transitions, priorities, edge cases | -| `app/state/__tests__/statusAnnouncements.test.ts` | 45 | Store operations, concurrency, deduplication, errors | -| `hooks/__tests__/useStatusChangeAnnouncement.test.ts` | 35 | Hook integration, debug mode, error handling | -| **Total** | **117** | **Comprehensive coverage of all scenarios** | - -### 5. ✅ Backward Compatibility - -**Evidence:** -- All new props are **optional** with sensible defaults -- Existing code continues to work without changes -- No breaking changes to public APIs -- Announcement features are **opt-in:** - - `StatusBadge`: Pass `marketId` and `marketTitle` to enable - - `BetForm`: Pass `marketId` and `marketTitle` to enable - - `ActiveBetCard`: Automatically uses `bet.id` if available - -**Migration Path:** -```tsx -// Before (still works) - - -// After (with announcements) - -``` - -### 6. ✅ Failure Diagnosability - -**Evidence:** -- Invalid transitions logged with error message to console -- Debug mode available via `useStatusChangeAnnouncement({ debug: true })` -- All errors include context (entity ID, status, transition) -- **No sensitive data exposed:** No amounts, addresses, or wallet info in logs - -**Example Logs:** -``` -[StatusAnnouncement] Market market-1: Invalid market status transition: closed → open -[StatusAnnouncement] Market market-1: Deduplicating open announcement -[useStatusChangeAnnouncement] Market market-1: announced "Market is now open for predictions" -``` - ---- - -## API Documentation - -### `useStatusChangeAnnouncement(options?)` - -```typescript -interface UseStatusChangeAnnouncementOptions { - debug?: boolean; // Enable debug logging -} - -interface ReturnValue { - announceMarketStatus( - marketId: string, - newStatus: MarketStatus, - marketTitle?: string - ): boolean; // true if announced, false if skipped - - announceBetStatus( - betId: string, - newStatus: BetStatus, - marketTitle?: string - ): boolean; // true if announced, false if skipped -} -``` - -### `useStatusAnnouncementStore()` - -Zustand store for managing status state: - -```typescript -{ - announceMarketStatusChange(marketId, newStatus): { - success: boolean; - error?: string; - shouldAnnounce: boolean; - priority: "polite" | "assertive"; - }; - - announceBetStatusChange(betId, newStatus): { - success: boolean; - error?: string; - shouldAnnounce: boolean; - priority: "polite" | "assertive"; - }; - - getMarketStatus(marketId): MarketStatus | undefined; - getBetStatus(betId): BetStatus | undefined; - reset(): void; // For testing -} -``` - ---- - -## Integration Examples - -### Market Status Badge with Announcements - -```tsx -// In a market detail page or card - -``` - -**Result:** When status changes from `open` to `closed`, screen reader announces: -> "Market 'Will Bitcoin reach $100k?' is now closed for new predictions" - -### Bet Form with Announcements - -```tsx -// In a bet placement form - -``` - -**Result:** -- Validation error: "Invalid bet amount. Please enter an amount greater than 0." -- On submit: "Your bet is pending" - -### Active Bet Card with Announcements - -```tsx -// Active bet card automatically announces status changes - -``` - -**Result:** When bet status updates (e.g., from `pending` to `completed`), screen reader announces: -> "Your bet on 'Will Bitcoin reach $100k?' is now complete" - ---- - -## Accessibility Compliance (WCAG 2.1 AA) - -### WCAG Compliance Map - -| Criterion | Implementation | Evidence | -|-----------|-----------------|----------| -| 1.3.1 Info & Relationships | ARIA roles and attributes | `role="status"` on StatusBadge | -| 3.3.1 Error Identification | Live region announcements | Errors announced immediately | -| 3.3.4 Error Prevention | Input validation before submission | BetForm validates amount | -| 4.1.3 Status Messages (WCAG 2.1 AA new) | Live region with assertive priority | Time-critical statuses use assertive | - -### Live Region Priority Logic - -- **Assertive:** `resolved`, `completed`, `cancelled` (time-critical, may require action) -- **Polite:** `open`, `closing_soon`, `closed`, `pending`, `active` (informational) - ---- - -## Security & Data Privacy - -### No Sensitive Data Exposure - -- ✅ No wallet addresses in announcements -- ✅ No transaction amounts in announcements -- ✅ No user IDs or emails in announcements -- ✅ No API keys or tokens in logs -- ✅ All announcements use generic templates - -### Error Handling - -- ✅ Invalid transitions logged but don't crash -- ✅ Missing entity IDs handled gracefully -- ✅ Concurrent update conflicts prevented by Map-based state -- ✅ Deduplication prevents notification storm attacks - ---- - -## Testing Strategy - -### Unit Tests (State Machine) -```typescript -// tests/status-announcement-messages.test.ts -- Message generation (all statuses) -- Priority assignment (time-critical vs normal) -- Transition validation (valid/invalid) -- Edge cases (empty IDs, repeated calls) -``` - -### Integration Tests (Store) -```typescript -// tests/statusAnnouncements.test.ts -- Sequential transitions -- Concurrent updates -- Deduplication behavior -- Invalid transition rejection -- Multiple entity independence -``` - -### Hook Tests (Live Region Integration) -```typescript -// tests/useStatusChangeAnnouncement.test.ts -- Hook integration with global live region -- Debug mode behavior -- Error handling -- Deduplication at hook level -``` - ---- - -## Performance Considerations - -### Memory Footprint -- Map-based state: O(1) lookup for entity status -- Deduplication window: 2 seconds (minimal memory) -- No unbounded accumulation of announcements - -### CPU Impact -- Status transition validation: O(1) lookup in predefined transition map -- No polling or watchers -- Announcements dispatched only on explicit prop changes - -### Network Impact -- Zero network calls (all logic client-side) -- No telemetry or analytics overhead - ---- - -## Future Enhancements (Out of Scope) - -1. **i18n Support:** Messages can be localized by replacing string literals -2. **Custom Messages:** Configuration hook to override default messages -3. **Announcement History:** Track announcements for debugging/replay -4. **Metrics:** Count announcements per status type for analytics -5. **Sound Cues:** Optional notification sounds for time-critical statuses - ---- - -## Deployment Checklist - -- [x] Code review: All components reviewed and approved -- [x] Tests: 117 deterministic tests created -- [x] Backward compatibility: No breaking changes -- [x] Documentation: JSDoc comments on all public APIs -- [x] Accessibility: WCAG 2.1 AA compliance verified -- [x] Security: No sensitive data exposure -- [ ] Manual testing: Screen reader testing recommended (NVDA, JAWS, VoiceOver) -- [ ] CI/CD: Run test suite in pipeline before merge - ---- - -## Files Modified - -| File | Changes | Reason | -|------|---------|--------| -| `lib/status-announcement-messages.ts` | Created | Message generation & validation | -| `app/state/statusAnnouncements.ts` | Created | State management with Zustand | -| `hooks/useStatusChangeAnnouncement.ts` | Created | Live region integration hook | -| `components/market/StatusBadge.tsx` | Modified | Added optional announcement props | -| `app/components/BetForm.tsx` | Modified | Added optional announcement props, error announcements | -| `components/active-bets/ActiveBetCard.tsx` | Modified | Added automatic status change announcements | -| `lib/__tests__/status-announcement-messages.test.ts` | Created | 37 tests for messages | -| `app/state/__tests__/statusAnnouncements.test.ts` | Created | 45 tests for store | -| `hooks/__tests__/useStatusChangeAnnouncement.test.ts` | Created | 35 tests for hook | - ---- - -## Verification Commands - -```bash -# Run all tests -npm test - -# Run specific test suite -npm test -- lib/__tests__/status-announcement-messages.test.ts -npm test -- app/state/__tests__/statusAnnouncements.test.ts -npm test -- hooks/__tests__/useStatusChangeAnnouncement.test.ts - -# Run with coverage -npm test -- --coverage - -# Type check -npx tsc --noEmit --skipLibCheck -``` - ---- - -## Author Notes - -This implementation prioritizes **correctness over convenience**: - -1. **Deterministic:** All behavior is pre-defined; no hidden state or side effects -2. **Type-safe:** TypeScript compiler catches mistakes at compile time -3. **Testable:** Pure functions and mockable dependencies -4. **Observable:** Comprehensive logging for debugging -5. **Safe:** Invalid transitions are rejected; no silent failures -6. **Compatible:** Existing code continues to work; opt-in for new features - -The implementation follows the existing Predictify patterns (Zustand store, hooks, TypeScript strict mode) and integrates seamlessly with the WCAG 2.1 AA accessibility foundation already in place. diff --git a/ISSUE_906_PR_DESCRIPTION.md b/ISSUE_906_PR_DESCRIPTION.md deleted file mode 100644 index 2e07f5c2..00000000 --- a/ISSUE_906_PR_DESCRIPTION.md +++ /dev/null @@ -1,200 +0,0 @@ -# PR: Issue #906 - Announce Market and Bet Status Changes to Assistive Tech - -## Summary - -Implements deterministic, production-ready accessibility announcements for market and bet status changes via WCAG 2.1 AA live regions. Screen reader users now receive immediate feedback when markets change status or bets are placed/updated. - -**Closes #906** - -## Changes - -### Core Infrastructure -- **`lib/status-announcement-messages.ts`** (158 lines) - - State machine validation for market/bet status transitions - - Human-readable messages optimized for screen reader announcement - - Priority assignment (polite/assertive) based on status criticality - - Deterministic, type-safe, no silent failures - -- **`app/state/statusAnnouncements.ts`** (242 lines) - - Zustand store tracking market/bet status with deduplication - - Thread-safe concurrent update handling - - Invalid transition rejection with logging - - Maintains invariants: one status per entity, explicit transitions only - -- **`hooks/useStatusChangeAnnouncement.ts`** (174 lines) - - Integration bridge between store and global live region - - Message generation and priority routing - - Optional debug mode for observability - - Non-blocking: failures don't prevent component rendering - -### Component Integration -- **`components/market/StatusBadge.tsx`** - - Announces market status changes when props change - - Optional `marketId` and `marketTitle` props for opt-in announcements - - Deduplicates within component lifecycle - - Respects time-critical status priorities - -- **`app/components/BetForm.tsx`** - - Announces validation errors with assertive priority - - Announces pending bet placement - - Optional `marketId` and `marketTitle` props - - Non-blocking error handling - -- **`components/active-bets/ActiveBetCard.tsx`** - - Automatically announces individual bet status updates - - Listens to `bet.status` prop changes - - Announces with market title context - -### Test Coverage (117 Deterministic Tests) -- **`lib/__tests__/status-announcement-messages.test.ts`** (37 tests) - - All message types and variants - - Valid/invalid state transitions - - Priority assignment logic - - Edge cases and boundary conditions - -- **`app/state/__tests__/statusAnnouncements.test.ts`** (45 tests) - - Sequential and concurrent transitions - - Deduplication behavior - - Invalid transition rejection - - Terminal state handling - - Multiple entity independence - -- **`hooks/__tests__/useStatusChangeAnnouncement.test.ts`** (35 tests) - - Hook integration with live region - - Debug mode behavior - - Market and bet announcements - - Deduplication at hook level - - Error handling - -### Documentation -- **`ISSUE_906_IMPLEMENTATION.md`** (393 lines) - - Full implementation guide with examples - - Architecture overview - - Acceptance criteria verification - - API documentation - - Integration examples - - WCAG 2.1 AA compliance map - - Deployment checklist - -## Acceptance Criteria - -- [x] **Deterministic behavior** — All transitions validated via state machine; no silent failures -- [x] **Authorization & validation invariants** — Invalid transitions rejected with logged errors -- [x] **Retries/partial failure/concurrent execution safe** — Deduplication, Map-based state, immutable updates -- [x] **Focused tests** — 117 comprehensive tests covering success, failure, boundary, regression scenarios -- [x] **Backward compatibility** — All new props optional; existing code unaffected -- [x] **Failure diagnosability** — Console logging with context; debug mode available; no sensitive data exposed - -## Validation - -### Test Results -``` -Messages: 37 tests ✓ (transitions, priorities, edge cases) -Store: 45 tests ✓ (concurrency, deduplication, validation) -Hook: 35 tests ✓ (integration, error handling, debug) -Total: 117 tests ✓ (100% deterministic coverage) -``` - -### Code Quality -- ✓ TypeScript strict mode -- ✓ No breaking changes -- ✓ JSDoc on all public APIs -- ✓ WCAG 2.1 AA compliance -- ✓ Zero sensitive data exposure -- ✓ Follows existing codebase patterns (Zustand, hooks) - -### Backward Compatibility -- ✓ All new props optional with defaults -- ✓ Existing components work without changes -- ✓ Announcement features are opt-in -- ✓ No migration path required - -## Integration Examples - -### Announcing Market Status Changes -```tsx - -``` - -**Result:** When status changes, screen reader announces: -> "Market 'Will Bitcoin reach $100k?' is now closed for new predictions" - -### Announcing Bet Placement -```tsx - -``` - -**Result:** On submit, screen reader announces: -> "Your bet is pending" - -### Announcing Bet Updates -```tsx - -``` - -**Result:** When bet status updates, screen reader announces: -> "Your bet on 'Will Bitcoin reach $100k?' is now complete" - -## Status Transitions - -### Market Status (Validated) -``` -open → closing_soon → closed → resolved - ↓ - cancelled (allowed from any state) -``` - -### Bet Status (Validated) -``` -active ↔ pending → completed - ↓ ↓ -cancelled (allowed from any state) -``` - -## Performance Impact -- Memory: O(1) entity tracking via Map -- CPU: O(1) status validation via lookup table -- Network: Zero network calls (client-side only) -- Deduplication: 2-second window prevents spam - -## Accessibility -- WCAG 2.1 AA compliant -- Screen reader announcements via live regions -- Assertive priority for time-critical statuses (resolved, completed, cancelled) -- Polite priority for informational statuses -- No sensitive data in announcements - -## Next Steps (Manual Testing) -1. Test with NVDA (Windows) -2. Test with JAWS (Windows) -3. Test with VoiceOver (macOS) -4. Verify announcements are clear and contextual -5. Verify no duplicate announcements on rapid updates - -## Files Modified -- `lib/status-announcement-messages.ts` — NEW -- `app/state/statusAnnouncements.ts` — NEW -- `hooks/useStatusChangeAnnouncement.ts` — NEW -- `components/market/StatusBadge.tsx` — MODIFIED (added optional props) -- `app/components/BetForm.tsx` — MODIFIED (added optional props, error announcements) -- `components/active-bets/ActiveBetCard.tsx` — MODIFIED (added announcement effect) -- `lib/__tests__/status-announcement-messages.test.ts` — NEW -- `app/state/__tests__/statusAnnouncements.test.ts` — NEW -- `hooks/__tests__/useStatusChangeAnnouncement.test.ts` — NEW -- `ISSUE_906_IMPLEMENTATION.md` — NEW - -## Related Issues -- Closes #906 -- Related to accessibility roadmap -- Part of WCAG 2.1 AA compliance effort - -## Questions? -See `ISSUE_906_IMPLEMENTATION.md` for comprehensive documentation, API reference, and integration examples. diff --git a/ISSUE_906_VALIDATION_REPORT.md b/ISSUE_906_VALIDATION_REPORT.md deleted file mode 100644 index 8eaa0acb..00000000 --- a/ISSUE_906_VALIDATION_REPORT.md +++ /dev/null @@ -1,421 +0,0 @@ -# Issue #906 - Validation Report - -**Status:** ✅ **COMPLETE AND PRODUCTION-READY** - -**Date:** August 28, 2026 -**Deliverables:** 10 files (6 modified/created, 4 test files, 2 documentation files) -**Test Coverage:** 117 deterministic tests across 3 suites -**Lines of Code:** ~1,200 (implementation + tests) - ---- - -## Acceptance Criteria Verification - -### ✅ 1. Deterministic Behavior - -**Requirement:** Valid, invalid, duplicate, and boundary-case inputs must have deterministic outcomes. - -**Implementation:** -- `isValidMarketTransition()` and `isValidBetTransition()` define explicit state machine -- All transitions pre-defined in lookup tables -- No random behavior, no timing-dependent logic -- Pure functions with no side effects - -**Evidence:** -```typescript -// Explicit state machine - always returns same result for same input -const validTransitions: Record = { - open: ["closing_soon", "cancelled"], - closing_soon: ["closed", "cancelled"], - closed: ["resolved", "cancelled"], - resolved: [], - cancelled: [], -}; -``` - -**Test Coverage:** -- 37 tests in `status-announcement-messages.test.ts` -- All transition combinations covered -- Boundary cases: same status, null values, missing IDs -- **Result:** ✅ 100% deterministic - ---- - -### ✅ 2. Authorization, Validation & State-Transition Invariants - -**Requirement:** Authorization, validation, and state-transition invariants must remain enforced. - -**Implementation:** -- `announceMarketStatusChange()` validates before state update -- `announceBetStatusChange()` validates before state update -- Invalid transitions return `{ success: false, error: "..." }` -- State only updates on valid transitions -- Concurrent updates use immutable Map pattern - -**Evidence:** -```typescript -// Validation happens BEFORE state update -if (currentStatus && !isValidMarketTransition(currentStatus, newStatus)) { - const error = `Invalid market status transition: ${currentStatus} → ${newStatus}`; - console.error(`[StatusAnnouncement] Market ${marketId}: ${error}`); - return { success: false, error }; // No state change -} -``` - -**Test Coverage:** -- 45 tests in `statusAnnouncements.test.ts` -- Invalid transition rejection verified -- State consistency after failed transition -- Multiple entity independence (markets don't affect bets) -- **Result:** ✅ All invariants enforced - ---- - -### ✅ 3. Retries, Partial Failure & Concurrent Execution Safety - -**Requirement:** Retries, partial failure, and concurrent execution cannot produce unsafe or inconsistent results. - -**Implementation:** -- Deduplication window (2 seconds) handles rapid retries -- Each entity tracked in separate Map (independent state) -- Immutable updates: `new Map(state.marketStatuses).set()` -- No mutable shared state -- Announcement failures don't affect store state - -**Evidence:** -```typescript -// Immutable state update - no shared references -set((state) => ({ - marketStatuses: new Map(state.marketStatuses).set(marketId, { - status: newStatus, - lastAnnouncedAt: now, - }), -})); -``` - -**Test Coverage:** -```typescript -describe("Concurrent operations", () => { - it("should handle multiple markets being updated simultaneously", () => { - // Updates to market-1, market-2, market-3 in rapid succession - // Verifies state consistency - }); - - it("should maintain consistency during mixed market and bet updates", () => { - // Concurrent market and bet updates - // Verifies no cross-contamination - }); -}); -``` - -**Result:** ✅ Safe under concurrent load - ---- - -### ✅ 4. Focused Tests: Success, Rejection, Boundary, Regression - -**Requirement:** Comprehensive test coverage for normal operation, invalid input, retries, concurrency/timing, failure recovery. - -**Implementation:** 117 deterministic tests across 3 suites - -**Test Breakdown:** - -| Suite | Tests | Focus | -|-------|-------|-------| -| `status-announcement-messages.test.ts` | 37 | Message generation, transitions, priorities, edge cases | -| `statusAnnouncements.test.ts` | 45 | Store operations, concurrency, deduplication, validation | -| `useStatusChangeAnnouncement.test.ts` | 35 | Hook integration, error handling, debug mode | - -**Sample Test Cases:** - -```typescript -// Success case -it("should announce valid first status transition", () => { - const res = store.announceMarketStatusChange("market-1", "open"); - expect(res.success).toBe(true); - expect(res.shouldAnnounce).toBe(true); -}); - -// Rejection case -it("should reject invalid transition", () => { - store.announceMarketStatusChange("market-1", "open"); - const res = store.announceMarketStatusChange("market-1", "resolved"); - expect(res.success).toBe(false); - expect(res.error).toBeTruthy(); -}); - -// Boundary case -it("should handle empty marketId gracefully", () => { - const res = store.announceMarketStatusChange("", "open"); - expect(store.getMarketStatus("")).toBeUndefined(); -}); - -// Concurrency case -it("should handle multiple markets being updated simultaneously", () => { - act(() => { - store.announceMarketStatusChange("market-1", "open"); - store.announceMarketStatusChange("market-2", "open"); - store.announceMarketStatusChange("market-1", "closing_soon"); - }); - expect(store.getMarketStatus("market-1")).toBe("closing_soon"); - expect(store.getMarketStatus("market-2")).toBe("open"); -}); -``` - -**Result:** ✅ 117 tests, all scenarios covered - ---- - -### ✅ 5. Existing Callers Remain Compatible - -**Requirement:** Existing callers must remain compatible; breaking changes require migration plan. - -**Implementation:** -- All new props are **optional** -- Default behavior unchanged when props omitted -- No changes to existing public method signatures -- Announcement features are opt-in - -**Evidence:** - -```typescript -// Before (still works exactly the same) - - -// After (with optional announcement) - - -// BetForm integration (optional) - // No announcements - // With announcements -``` - -**Migration Path:** -- Zero migration required for existing code -- Developers can opt-in to announcements per component -- No version bump required (backward compatible) - -**Result:** ✅ 100% backward compatible - ---- - -### ✅ 6. Relevant Logs, Metrics, User-Visible Errors - -**Requirement:** Failures must be diagnosable without exposing sensitive data. - -**Implementation:** -- Console logging on all state transitions -- Debug mode available via hook option -- Error messages include context (entity ID, status, transition) -- **No sensitive data:** No amounts, addresses, wallet info, API keys - -**Evidence:** - -```typescript -// Error example (safe to log) -[StatusAnnouncement] Market market-123: Invalid market status transition: closed → open - -// Debug example (safe to log) -[useStatusChangeAnnouncement] Market market-123: announced "Market is now closed for new predictions" - -// What's NOT logged (sensitive data protection) -- ❌ Transaction amounts -- ❌ Wallet addresses -- ❌ User IDs -- ❌ API keys -- ❌ Private keys -``` - -**Result:** ✅ Fully diagnosable, no data leaks - ---- - -## Codebase Quality Metrics - -| Metric | Result | -|--------|--------| -| TypeScript Strict Mode | ✅ All files use strict mode | -| JSDoc Documentation | ✅ All public APIs documented | -| Test Coverage | ✅ 117 tests, 100% of logic covered | -| Circular Dependencies | ✅ None detected | -| Code Duplication | ✅ None (DRY principles followed) | -| Breaking Changes | ✅ None (all backward compatible) | -| Security Issues | ✅ None (no sensitive data exposure) | -| Performance | ✅ O(1) operations, minimal memory | - ---- - -## Accessibility Compliance - -### WCAG 2.1 AA Requirements Met - -| SC # | Requirement | Implementation | Status | -|------|-------------|-----------------|--------| -| 1.3.1 | Info & Relationships | `role="status"` on StatusBadge | ✅ | -| 3.3.1 | Error Identification | Errors announced via live region | ✅ | -| 3.3.4 | Error Prevention | Input validation before submission | ✅ | -| 4.1.3 | Status Messages (NEW) | Live region with appropriate priority | ✅ | - -### Live Region Priority Implementation - -```typescript -const priority = status === "resolved" || status === "cancelled" - ? "assertive" // Time-critical, needs immediate attention - : "polite"; // Informational, respects user flow -``` - ---- - -## Security Review - -### Sensitive Data Audit - -✅ **Messages:** No amounts, addresses, or user info -✅ **Logs:** No API keys, tokens, or private data -✅ **State:** No persistence of sensitive data -✅ **Network:** Zero network calls (client-side only) -✅ **Store:** No localStorage or session storage - -### Error Handling - -✅ **Invalid input:** Gracefully rejected, logged safely -✅ **Concurrent updates:** Map-based state prevents conflicts -✅ **Store failures:** Don't affect UI (non-blocking) -✅ **Announcement failures:** Don't prevent component render - ---- - -## Performance Analysis - -### Memory Footprint -- Market tracking: 1 entry per market = ~100 bytes (ID + status + timestamp) -- Bet tracking: 1 entry per bet = ~100 bytes -- **Total:** Negligible for typical app (<10KB even with 100k statuses) - -### CPU Impact -- Status validation: O(1) lookup in transition map -- Store updates: O(1) Map operations -- No polling, no watchers, no background jobs -- **Verdict:** Negligible CPU overhead - -### Network Impact -- Zero network calls from this feature -- All logic runs client-side -- **Verdict:** Zero network overhead - ---- - -## Integration Testing Scenarios - -### Scenario 1: Normal Market Lifecycle -``` -1. User views market detail page -2. Market status is "open" -3. StatusBadge announces: "Market is now open for predictions" -4. Time passes, market status changes to "closing_soon" -5. StatusBadge announces: "Market is closing soon. Place your prediction now" -6. Market closes, status = "closed" -7. StatusBadge announces: "Market is now closed for new predictions" -✅ Result: All announcements received and clear -``` - -### Scenario 2: Bet Placement Flow -``` -1. User opens bet form -2. User enters amount and submits -3. BetForm announces: "Your bet is pending" -4. Server processes, bet status = "active" -5. ActiveBetCard announces: "Your bet is now active" -6. Market resolves, bet status = "completed" -7. ActiveBetCard announces: "Your bet is complete" (assertive) -✅ Result: All announcements received and timely -``` - -### Scenario 3: Error Handling -``` -1. User tries to place bet with invalid amount -2. BetForm announces: "Invalid bet amount. Please enter an amount greater than 0." -3. User corrects amount and submits -4. BetForm announces: "Your bet is pending" -✅ Result: Error clearly communicated, user can recover -``` - -### Scenario 4: Concurrent Updates -``` -1. Multiple markets update status simultaneously -2. Market 1: open → closing_soon (announced) -3. Market 2: closed → resolved (announced assertive) -4. User's bet updates: pending → completed (announced assertive) -5. User's different bet: active → cancelled (announced assertive) -✅ Result: All announcements received without conflicts -``` - ---- - -## Deployment Readiness - -### Pre-Deployment Checklist -- [x] Code review completed -- [x] All tests passing (117/117) -- [x] TypeScript compilation successful -- [x] No breaking changes -- [x] Documentation complete -- [x] Security review passed -- [x] Accessibility compliance verified -- [ ] Manual screen reader testing (recommended) -- [ ] Staging environment testing (recommended) - -### Risk Assessment -| Risk | Probability | Impact | Mitigation | -|------|------------|--------|-----------| -| Silent failures in state machine | Low | High | Explicit validation + logging | -| Performance regression | Low | Medium | O(1) operations verified | -| Accessibility issues | Low | High | WCAG 2.1 AA compliance verified | -| Backward compatibility break | Low | High | All props optional, no breaking changes | - -**Overall Risk Level:** ✅ **LOW** - Implementation is mature, tested, and safe - ---- - -## Recommendations - -### Immediate (Before Merge) -1. ✅ Run full test suite to verify all 117 tests pass -2. ✅ Review ISSUE_906_IMPLEMENTATION.md for API documentation -3. ✅ Check TypeScript compilation with `tsc --noEmit` - -### Post-Deployment (First Week) -1. Manual testing with NVDA/JAWS/VoiceOver on multiple markets -2. Monitor console logs for any unexpected invalid transitions -3. Gather user feedback from screen reader users -4. Verify announcements are clear and contextual - -### Future Enhancements (Out of Scope) -1. i18n support for non-English users -2. Custom message configuration -3. Announcement history/replay for debugging -4. Analytics on announcement types and frequency - ---- - -## Conclusion - -**Issue #906 is COMPLETE and PRODUCTION-READY.** - -The implementation: -- ✅ Meets all 6 acceptance criteria -- ✅ Includes 117 deterministic tests -- ✅ Maintains 100% backward compatibility -- ✅ Achieves WCAG 2.1 AA compliance -- ✅ Provides clear error diagnostics -- ✅ Has zero performance impact -- ✅ Follows existing codebase patterns - -**Recommendation:** APPROVED FOR MERGE - ---- - -**Generated:** 2026-08-28T09:47:31Z -**Implementation Time:** ~1.5 hours (analysis + design + implementation + tests) -**Files Modified:** 10 (6 core + 3 tests + 1 documentation) -**Total LOC:** ~1,200 diff --git a/PATTERNS_IMPLEMENTATION.md b/PATTERNS_IMPLEMENTATION.md deleted file mode 100644 index 743ec00e..00000000 --- a/PATTERNS_IMPLEMENTATION.md +++ /dev/null @@ -1,138 +0,0 @@ -# Color-Blind Safe Patterns Implementation - -## Overview -This implementation adds color-blind safe patterns to MarketDetail status chips for the GrantFox FWC26 campaign (Stellar Wave). The patterns augment color coding to ensure status badges remain distinguishable for users with color vision deficiencies (CVD). - -## Changes Made - -### 1. New File: `styles/patterns.css` -Created a new CSS file containing five distinct, color-blind safe patterns: -- **pattern-diagonal**: 45-degree diagonal stripes (for "open" status) -- **pattern-dots**: Polka dot grid (for "closing_soon" status) -- **pattern-crosshatch**: Cross-hatch grid (for "closed" status) -- **pattern-horizontal**: Horizontal lines (for "resolved" status) -- **pattern-vertical**: Vertical lines (for "cancelled" status) - -Each pattern includes: -- Light mode variant using white semi-transparent overlays -- Dark mode variant using black semi-transparent overlays -- Subtle opacity to maintain text readability (WCAG 2.1 AA compliant) -- Proper spacing to avoid visual clutter - -### 2. Modified: `styles/globals.css` -Added import statement to include the new patterns.css file: -```css -@import './patterns.css'; -``` - -### 3. Existing Component: `components/market/StatusBadge.tsx` -The StatusBadge component already had pattern class mappings in place (lines 77-83): -```typescript -const STATUS_PATTERN_CLASSES: Record = { - open: 'pattern-diagonal', - closing_soon: 'pattern-dots', - closed: 'pattern-crosshatch', - resolved: 'pattern-horizontal', - cancelled: 'pattern-vertical', -}; -``` - -The component applies these patterns via the `patternClass` prop on line 133: -```typescript -className={cn('relative gap-1.5 overflow-hidden', patternClass, className)} -``` - -### 4. Enhanced Tests: `components/market/__tests__/StatusBadge.test.tsx` -Added a new test suite "Color-Blind Safe Patterns" with 5 focused tests: -- Verifies each status gets the correct pattern class -- Confirms patterns work alongside other required classes (overflow-hidden, relative) -- Ensures patterns persist when custom className is applied -- Tests fallback pattern behavior for unknown statuses -- Validates pattern uniqueness across all statuses - -## API Changes - -### No Breaking Changes -This implementation is purely additive and does not change any existing APIs: -- StatusBadge component interface remains unchanged -- No new props added -- No existing props modified -- Backward compatible with all existing usage - -### Visible Changes -Users will now see subtle patterns on status badges: -- Patterns are visible as texture overlays on badge backgrounds -- Patterns are subtle enough to not interfere with text readability -- Patterns provide additional visual distinction beyond color alone -- Dark mode patterns use darker overlays for consistency - -## Accessibility Compliance - -### WCAG 2.1 AA -- **Contrast**: Pattern overlays use 10-15% opacity to maintain ≥4.5:1 contrast ratio -- **Distinguishability**: Each status has a unique pattern, ensuring users can distinguish statuses without relying on color -- **Screen Readers**: No impact on screen reader functionality (patterns are purely visual) -- **Keyboard Navigation**: No impact on keyboard navigation - -### Color Vision Deficiency Support -The patterns address common forms of CVD: -- **Protanopia/Deuteranopia** (red-green blindness): Patterns provide texture distinction -- **Tritanopia** (blue-yellow blindness): Patterns work independently of blue/yellow hues -- **Achromatopsia** (monochromacy): Patterns provide grayscale distinction - -## Design Token Consistency - -### Dark Mode -Patterns use CSS variable-aware dark mode support: -- Light mode: `rgba(255, 255, 255, 0.1-0.15)` -- Dark mode: `rgba(0, 0, 0, 0.15-0.2)` -- Automatically respects system theme preference - -### Responsive Design -Patterns scale with badge size and work across all breakpoints: -- Mobile: Patterns remain visible at small sizes -- Desktop: Patterns maintain clarity at larger sizes -- No responsive breakpoints needed (patterns are resolution-independent) - -## Testing - -### Test Coverage -New tests in `StatusBadge.test.tsx` cover: -- Pattern class application for each status -- Pattern class coexistence with other classes -- Pattern persistence with custom className -- Fallback behavior for edge cases -- Pattern uniqueness validation - -### Manual Testing Recommendations -1. Test with browser dev tools to simulate color blindness -2. Verify patterns are visible in both light and dark modes -3. Check text readability remains clear with patterns -4. Confirm patterns don't cause visual vibration or discomfort - -## Browser Compatibility - -Patterns use standard CSS features with broad support: -- `linear-gradient()`: Supported in all modern browsers -- `radial-gradient()`: Supported in all modern browsers -- `repeating-linear-gradient()`: Supported in all modern browsers -- CSS custom properties: Supported in all modern browsers - -## Performance Impact - -Minimal performance impact: -- Patterns are CSS-only (no JavaScript overhead) -- Gradients are GPU-accelerated in modern browsers -- No additional HTTP requests (patterns.css is bundled) -- Pattern rendering is cached by browser - -## Future Enhancements - -Potential improvements for future iterations: -- Add pattern intensity customization via CSS variables -- Consider animated patterns for "closing_soon" status -- Add pattern-only mode for users who prefer high-contrast alternatives -- Implement pattern preference in user settings - -## Related Issues -Closes #652 diff --git a/PR_DESCRIPTION.md b/PR_DESCRIPTION.md deleted file mode 100644 index d0f846c3..00000000 --- a/PR_DESCRIPTION.md +++ /dev/null @@ -1,37 +0,0 @@ -Title: Prevent claim retries from duplicating intent - -Summary: -- Add client-side intent deduplication to prevent duplicate transaction submissions when users retry claims. -- Persist minimal intent state in `localStorage` with a 24h TTL to allow retries to reuse signed XDR or detected submission hashes. -- Integrate intent handling into `useTransaction` to ensure deterministic behavior across retries and partial failures. - -Files changed: -- `lib/transaction/intent.ts` - intent store (get/upsert/remove, computeXdrHash) -- `hooks/useTransaction.hook.ts` - integrate intent deduplication and locking -- `lib/transaction/__tests__/intent.test.ts` - intent store tests -- `hooks/__tests__/useTransaction.test.tsx` - focused transaction flow tests - -Behavior and invariants: -- Intent key: `walletAddress:sha256(builtXdr)` ensures same wallet + same built XDR map to same intent. -- If an intent has `submissionHash`, retry polls for confirmation instead of re-submitting. -- If an intent has `signedXdr` but not submitted, retry will re-submit stored `signedXdr` (avoids re-signing in many cases). -- Signed XDRs are removed shortly after successful confirmation to reduce exposure. - -Security considerations: -- Signed XDRs are persisted temporarily in `localStorage`. If this is unacceptable, switch to storing only the `xdrHash` and require re-signing on retry. -- Avoid storing private keys or secrets; only XDR strings are stored. - -Testing: -- Unit tests cover intent store operations and transaction flows for sign-submit-confirm and retry scenarios. -- Run tests locally with `pnpm test`. - -Migration / compatibility: -- No server changes or DB migrations required. -- Public API to `useTransaction.executeTransaction(buildXdr)` unchanged. - -Observability: -- Intents are stored with timestamps and status; support can inspect localStorage under `predictify:intents:v1` for debugging. - -Next steps (optional): -- Consider encrypting signed XDR in localStorage or reducing persistence TTL. -- Add telemetry/metrics when intents transition to `submitted` and `success`. diff --git a/RESPONSIVE_AUDIT_PR_DESCRIPTION.md b/RESPONSIVE_AUDIT_PR_DESCRIPTION.md deleted file mode 100644 index 714ac096..00000000 --- a/RESPONSIVE_AUDIT_PR_DESCRIPTION.md +++ /dev/null @@ -1,238 +0,0 @@ -# Responsive Layout Audit and Fixes - Issue #541 (v7) - -## Summary -This PR addresses responsive breakpoint issues identified in the Dashboard.tsx component across narrow (mobile 320-480px) and wide (desktop/ultra-wide) viewports. The audit revealed 7 specific responsive layout problems where grids, flex containers, and chart heights were not properly scaling across the full viewport range. - -## Audit Findings - -### Issue #1: Stat Cards Grid - No Mobile-First Breakpoint -**Problem:** The stat card grid used `grid gap-4 md:grid-cols-2 lg:grid-cols-4` without an explicit mobile-first `grid-cols-1` class. While the layout defaulted to single-column on mobile, this was implicit and relied on Tailwind's default behavior rather than being explicitly declared. - -**Impact:** Inconsistent grid declarations across the dashboard made the responsive behavior harder to verify and maintain. - -**Fix:** Added explicit `grid-cols-1` class to all stat card grids: -```tsx -// Before -
- -// After -
-``` - -**File:** `app/(dashboard)/dashboard/page.tsx` - `renderCards()` method (3 locations: loading, empty, success states) - ---- - -### Issue #2: Recommendation Strip - 3-Column Rigid Layout at All Sizes -**Problem:** The recommendation cards used `grid gap-3 md:grid-cols-3` with no mobile/tablet intermediate breakpoint. This forced single-column layout on mobile (correct by default), but didn't take advantage of horizontal space on tablets where a 2-column layout would be more efficient. - -**Impact:** Tablets (640-768px) displayed only one card per row when space was available for two, wasting horizontal real estate. Card content was also tightly packed vertically with no responsive text shrinking. - -**Fix:** Implemented responsive column scaling: -```tsx -// Before -
- -// After -
-``` - -**Viewport Behavior:** -- Mobile (< 640px): 1 column for readability -- Tablet (640-768px): 2 columns to use horizontal space efficiently -- Desktop (768px+): 3 columns as originally intended - -**File:** `app/(dashboard)/dashboard/page.tsx` - `renderRecommendationStrip()` method - ---- - -### Issue #3: Header Layout - Title + Actions Responsive Sizing -**Problem:** The header layout already had `flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between`, which correctly stacks on mobile and rows on tablet+. The "Create New Event" button and Kbd hint already had appropriate responsive handling with `hidden sm:inline-flex` on the Kbd component. - -**Status:** ✅ No fix needed - responsive layout already correct - ---- - -### Issue #4: Analytics Panel Grid - Missing Mobile Stacking with Proper Column Span -**Problem:** The analytics grid used `grid gap-4 md:grid-cols-2 lg:grid-cols-3` with User Growth card spanning `col-span-2`. This created a problematic layout at tablet width (768px) where a 2-column grid cannot cleanly display a 4-column span + 3-column span. The second card would wrap awkwardly to a new row, wasting space. - -**Impact:** At 768px width, the User Demographics card forced to second row despite available horizontal space. Inefficient use of tablet screen real estate. - -**Fix:** Changed to 3-column grid with proper col-span semantics: -```tsx -// Before -
- User Growth - Demographics -
- -// After -
- User Growth - Demographics -
-``` - -**Viewport Behavior:** -- Mobile (< 768px): Both cards stack in single column -- Tablet/Desktop (768px+): User Growth spans 2 cols, Demographics spans 1 col in 3-column grid (clean 2/1 split) - -**File:** `app/(dashboard)/dashboard/page.tsx` - `renderAnalyticsPanel()` method - ---- - -### Issue #5: Activity Timeline + Chart Grid - Uneven Column Span at Tablet + Fixed Chart Heights -**Problem:** The activity section used `grid gap-4 md:grid-cols-2 lg:grid-cols-7` with Platform Activity spanning `col-span-4` and Recent Activity spanning `col-span-3`. This broke at md (768px) where a 2-column grid cannot display 4/3 column spans. Additionally, the chart placeholder had a fixed height of `h-[200px]` with no responsive scaling for mobile. - -**Impact:** -1. At tablet width, layout breaks visually; activity section doesn't render as intended -2. Chart takes up too much vertical space on mobile, forcing excessive scrolling - -**Fix:** Restructured grid for proper mobile-first stacking and added responsive chart heights: -```tsx -// Before -
- Platform Activity - Recent Activity -
Activity Chart
-
- -// After -
- Platform Activity - Recent Activity -
Activity Chart
-
-``` - -**Viewport Behavior:** -- Mobile/Tablet (< 1024px): Both cards stack in single column; chart height 150px for compact layout -- Desktop (1024px+): 7-column layout with 4/3 split; chart height 200px for better visibility - -**Files:** -- `app/(dashboard)/dashboard/page.tsx` - Overview TabsContent section - ---- - -### Issue #6: Keyboard Shortcut Hint - Already Responsive -**Problem:** None identified. The Kbd component already has `hidden sm:inline-flex` for desktop-only display. - -**Status:** ✅ No fix needed - ---- - -### Issue #7: Touch Target Sizes - Scroll Arrow Buttons Below Optimal on Mobile -**Problem:** Scroll arrow buttons in the ActiveBets and RecentlyViewedRail carousels used fixed `w-8 h-8` (32px) sizing. While 32px meets the minimum WCAG AA 44x44px guideline (with padding), it's at the lower edge of what's practical for touch on mobile devices where finger precision is lower. - -**Impact:** Scroll arrows on mobile (320-480px) are harder to tap accurately, reducing usability for carousel navigation. - -**Fix:** Implemented responsive touch target sizing: -```tsx -// Before -className="w-8 h-8 rounded-full ..." - -// After (ActiveBets & RecentlyViewedRail) -className="w-10 h-10 sm:w-8 sm:h-8 rounded-full ..." -``` - -**Reasoning:** WCAG 2.1 AA requires minimum 44x44px touch targets (SC 2.5.5). Using 40px on mobile (close to the guideline) and scaling down to 32px on smaller screens (≥640px) where cursor precision is better provides better mobile UX while maintaining visual balance on desktop. - -**Files:** -- `components/active-bets/ActiveBets.tsx` - Scroll button rendering -- `app/components/RecentlyViewedRail.tsx` - Scroll button rendering - ---- - -## Testing - -### Test Coverage -Created three new focused test files following the repo's existing Jest + React Testing Library pattern: - -1. **`app/(dashboard)/dashboard/__tests__/page.responsive.test.tsx`** - - Tests explicit `grid-cols-1` presence in stat cards - - Tests responsive column scaling in recommendation cards (grid-cols-1 sm:grid-cols-2 md:grid-cols-3) - - Tests analytics grid layout (grid-cols-1 md:grid-cols-3) - - Tests overview activity section stacking (grid-cols-1 lg:grid-cols-7) - - Tests responsive chart heights (h-[150px] sm:h-[200px]) - -2. **`components/active-bets/__tests__/scroll-buttons.test.tsx`** - - Tests scroll button responsive sizing (w-10 h-10 sm:w-8 sm:h-8) - -3. **`app/components/__tests__/RecentlyViewedRail.responsive.test.tsx`** - - Tests scroll button responsive sizing (w-10 h-10 sm:w-8 sm:h-8) - -### Accessibility Verification -- **Touch targets:** Verified 40px buttons on mobile meet practical accessibility guidelines; icon sizing (16x16px icons in 40x40px container = 12px padding) provides sufficient surrounding space -- **Reading order:** No changes to DOM structure; visual reflow at breakpoints maintains logical reading order -- **Color/contrast:** No color changes; existing design tokens in light/dark mode remain unchanged -- **Motion:** No animation changes; existing `prefers-reduced-motion` logic unaffected - -### Design Token Consistency -All responsive adjustments use existing Tailwind breakpoints: -- `sm` (640px) -- `md` (768px) -- `lg` (1024px) - -No new arbitrary pixel breakpoints were created; all changes align with the repo's canonical breakpoint scale defined in `tailwind.config.ts` (uses Tailwind defaults). - ---- - -## Verification Checklist - -✅ **Responsive across full breakpoint range:** -- Mobile (320-480px): Single-column grids, appropriate touch targets -- Tablet (640-768px): 2-3 column grids taking advantage of horizontal space -- Desktop (1024px+): Multi-column layouts with 7-column grids where appropriate -- Ultra-wide (1440px+): Layouts scale cleanly without excessive whitespace - -✅ **Both light and dark mode:** All changes use existing design tokens (no new colors), verified in both themes - -✅ **WCAG 2.1 AA compliance:** -- Touch targets ≥40px on mobile (exceeds practical accessibility threshold) -- No reading order changes -- Focus order and keyboard navigation unaffected - -✅ **Tests added:** Following repo's Jest + React Testing Library pattern - -✅ **Inline documentation:** Added comments documenting each issue and fix at the code location - ---- - -## Files Modified - -1. `app/(dashboard)/dashboard/page.tsx` - 3 grid layout fixes + 1 chart height fix -2. `components/active-bets/ActiveBets.tsx` - Scroll button touch target sizing -3. `app/components/RecentlyViewedRail.tsx` - Scroll button touch target sizing -4. `app/(dashboard)/dashboard/__tests__/page.responsive.test.tsx` - New test file -5. `components/active-bets/__tests__/scroll-buttons.test.tsx` - New test file -6. `app/components/__tests__/RecentlyViewedRail.responsive.test.tsx` - New test file - ---- - -## Before/After Behavior - -| Viewport | Component | Before | After | -|----------|-----------|--------|-------| -| 640px (tablet) | Recommendation cards | 1 card/row (wasted space) | 2 cards/row | -| 768px (tablet) | Analytics panel | Demographics pushed to new row | Clean 2/1 split in 3-col grid | -| 768px (tablet) | Activity section | Layout breaks with 2-col grid | Stacked single column | -| 320px (mobile) | Scroll buttons | 32px (small touch target) | 40px (easier to tap) | -| 320px (mobile) | Chart | h-[200px] (tall, excessive scroll) | h-[150px] (compact) | -| 1024px+ (desktop) | Activity section | 2-column forced layout | 7-column proper col-span | - ---- - -## Deployment Notes - -- No breaking changes to component APIs -- No changes to component behavior, only layout spacing at different viewport sizes -- Dark mode unchanged -- Reduced-motion preferences unaffected -- All existing animations and transitions preserved -- Backward compatible with existing test suite - ---- - -## Related Issues -- Fixes #541 (v7) - Dashboard responsive breakpoint audit -- GrantFox FWC26 Stellar Wave campaign - UI/UX audit item diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 812359d0..00000000 --- a/TODO.md +++ /dev/null @@ -1,15 +0,0 @@ -# EventsGrid Skeleton — Implementation TODO - -## Steps - -- [x] 1. **Explore codebase** — Analyze existing events components, skeleton patterns, theme tokens -- [x] 2. **Plan approved** — Plan confirmed with user -- [x] 3. **Create `components/events/events-grid-skeleton.tsx`** — Themed skeleton matching grid card layout -- [x] 4. **Create `components/events/events-grid.tsx`** — Grid card view for events with loading/empty/data states -- [x] 5. **Update `components/events/events-section.tsx`** — Wire EventsGrid into the dashboard events section -- [x] 6. **Update `app/(dashboard)/events/loading.tsx`** — Update Next.js loading boundary to use grid skeleton -- [x] 7. **Create `components/events/__tests__/events-grid.test.tsx`** — Unit tests for grid + skeleton (23 tests passing) -- [x] 8. **Create `docs/events-grid.md`** — Component documentation -- [x] 9. **Update `PR_DESCRIPTION.md`** — Document all changes -- [x] 10. **Run tests + type-check** — 23/23 tests pass, zero type-errors in new files (55 pre-existing errors in other files) - diff --git a/dev-server.log b/dev-server.log deleted file mode 100644 index 0e81e4973e4e50de136829afb56ff64a497ff483..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7944 zcmeI0%Z?jW5Qa#sVBOz{y6e$;&42lE;%3ynDoUz-+Z4#^mUc!&S zW3b>w*zg2w*dQd}|Ehf4wwYK#0*OVd)weozs_InzRdu@m{NtRxV((aHW1Cpdy4JUj zO?5r8nbmcj*vN8Gdb)P)UE8&WwRG-kPFK_?mL%kQ`$n9rbjEVY9*Wx5nc2Mdll`pw zLpzl0T$*w__OW}5`3-w)g*X^F5^b`uER#he`&w_AJ=N31PQ^EtoQ}9My^nNE?UJ6q z6d#uK{W=uSOmDf5GYWslWw2^i-0*e0=llcL-IG-<=R0v*+jc|mtmq9<8-8Sxk=ucN zC@F>Pnd*J4_xrlyvAR7F1)H()K-8D<@{Yaj)`s6EnxE@Eyq(!a#p`vq?767>lG~G> z`%9aWg?RhFJ-)N;2bLrY@Yx6QBS<=S&(G|()^()k#It$_E%!7wl?U-#Z=Z>E}=^48Ap4}9xiQZVeebI8qK(du}-BN@GI%f8< zo(}a?+Imy+LFPoO?TR2sG}axS zfuwbWLp%kAJPOH~o_kI!=TGg#XOZjx zDfOl9$X|HSjRi?h%23v_sWI{oJcEZ~VSnzP4+(vj^;9y;xOzRuUTC6H9o7aA~`D;|Q=##0> zwd|VW#mQ62U)M_R$a{Ep;B_O_oVcg>NAv?(aGq#RA+NRVin=t%x=i#>mmL)EmB+fw zmc3<{-LC8Qrr#TS-+iHEDkZg=iaOMteFIoHFQkyA^ljpKq9;}bexjOOkj&Cb?3vfT zw_klmPyIU8n)fw_%GTBX0VJKewzFq4huo(!Q~Ai7iDPuKsJdg91s?vngwm2!VUnDX zmF%a(U;TH}+m>_n!I%k@`yLK|{IEDWyl9Xe@fw-x0itT6$sNHV`$hRXI@QK-9QY zXQ~{i`asnOsy#jm diff --git a/ACTIVITY_TIMELINE_DELIVERY.md b/docs/ACTIVITY_TIMELINE_DELIVERY.md similarity index 100% rename from ACTIVITY_TIMELINE_DELIVERY.md rename to docs/ACTIVITY_TIMELINE_DELIVERY.md diff --git a/ACTIVITY_TIMELINE_DESIGN.md b/docs/ACTIVITY_TIMELINE_DESIGN.md similarity index 100% rename from ACTIVITY_TIMELINE_DESIGN.md rename to docs/ACTIVITY_TIMELINE_DESIGN.md diff --git a/ACTIVITY_TIMELINE_PATTERNS.md b/docs/ACTIVITY_TIMELINE_PATTERNS.md similarity index 100% rename from ACTIVITY_TIMELINE_PATTERNS.md rename to docs/ACTIVITY_TIMELINE_PATTERNS.md diff --git a/COLORBLIND_OUTCOMES_IMPLEMENTATION.md b/docs/COLORBLIND_OUTCOMES_IMPLEMENTATION.md similarity index 100% rename from COLORBLIND_OUTCOMES_IMPLEMENTATION.md rename to docs/COLORBLIND_OUTCOMES_IMPLEMENTATION.md diff --git a/COLORBLIND_QUICK_REFERENCE.md b/docs/COLORBLIND_QUICK_REFERENCE.md similarity index 94% rename from COLORBLIND_QUICK_REFERENCE.md rename to docs/COLORBLIND_QUICK_REFERENCE.md index a31d715d..f09e1ea5 100644 --- a/COLORBLIND_QUICK_REFERENCE.md +++ b/docs/COLORBLIND_QUICK_REFERENCE.md @@ -225,17 +225,9 @@ npm run type-check ## Learn More -- **Full Implementation Guide:** `COLORBLIND_OUTCOMES_IMPLEMENTATION.md` -- **Issue Resolution:** `ISSUE_435_RESOLUTION_SUMMARY.md` -- **Design System:** `app/design-system/tokens.md` -- **Tests:** `components/ui/__tests__/OutcomeChip.test.tsx` - ---- - -**Quick Links:** -- Issue: #435 ✅ Resolved -- PR: [Link to PR] -- Review: Required before merge +- **Full Implementation Guide:** [COLORBLIND_OUTCOMES_IMPLEMENTATION.md](./COLORBLIND_OUTCOMES_IMPLEMENTATION.md) +- **Design System:** [tokens.md](../app/design-system/tokens.md) +- **Tests:** [OutcomeChip tests](../components/ui/__tests__/OutcomeChip.test.tsx) --- diff --git a/DESIGN_ACCESSIBILITY_CHECKLIST.md b/docs/DESIGN_ACCESSIBILITY_CHECKLIST.md similarity index 100% rename from DESIGN_ACCESSIBILITY_CHECKLIST.md rename to docs/DESIGN_ACCESSIBILITY_CHECKLIST.md diff --git a/DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md b/docs/DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md similarity index 100% rename from DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md rename to docs/DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md diff --git a/DESIGN_STICKY_ACTION_PANEL.md b/docs/DESIGN_STICKY_ACTION_PANEL.md similarity index 100% rename from DESIGN_STICKY_ACTION_PANEL.md rename to docs/DESIGN_STICKY_ACTION_PANEL.md diff --git a/Design.md b/docs/Design.md similarity index 100% rename from Design.md rename to docs/Design.md diff --git a/IMPLEMENTATION_CHECKLIST.md b/docs/IMPLEMENTATION_CHECKLIST.md similarity index 100% rename from IMPLEMENTATION_CHECKLIST.md rename to docs/IMPLEMENTATION_CHECKLIST.md diff --git a/docs/README.md b/docs/README.md index bd280965..202ff6aa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -268,6 +268,70 @@ See [infinite-scroll-ux.md#memory-budget--performance](./infinite-scroll-ux.md#m See [infinite-scroll-ux.md#accessibility](./infinite-scroll-ux.md#accessibility) for complete accessibility documentation. +## Complete Index + +Every retained document in this directory is listed below. + +- [Accessibility audit status](./a11y-status.md) +- [Activity timeline delivery notes](./ACTIVITY_TIMELINE_DELIVERY.md) +- [Activity timeline design patterns](./ACTIVITY_TIMELINE_DESIGN.md) +- [Activity timeline visual patterns](./ACTIVITY_TIMELINE_PATTERNS.md) +- [API integration guide](./API.md) +- [Architecture overview](./ARCHITECTURE.md) +- [Breadcrumbs](./BREADCRUMBS.md) +- [Button order](./BUTTON_ORDER.md) +- [Color-blind outcomes implementation](./COLORBLIND_OUTCOMES_IMPLEMENTATION.md) +- [Color-blind outcomes quick reference](./COLORBLIND_QUICK_REFERENCE.md) +- [Copy address](./COPY_ADDRESS.md) +- [Countdown reduced motion](./COUNTDOWN_REDUCED_MOTION.md) +- [Dashboard mobile layout](./DASHBOARD_MOBILE_LAYOUT.md) +- [Dashboard reduced motion](./DASHBOARD_REDUCED_MOTION.md) +- [Density](./density.md) +- [Design references](./Design.md) +- [Screen accessibility checklist](./DESIGN_ACCESSIBILITY_CHECKLIST.md) +- [Mobile portfolio quick actions](./DESIGN_MOBILE_PORTFOLIO_QUICK_ACTIONS.md) +- [Sticky action panel](./DESIGN_STICKY_ACTION_PANEL.md) +- [Document titles](./DOCUMENT_TITLES.md) +- [Events grid](./events-grid.md) +- [Events responsive layout](./EVENTS_RESPONSIVE_LAYOUT.md) +- [External links](./EXTERNAL_LINKS.md) +- [Heat strip](./HEAT_STRIP.md) +- [High-contrast theme](./HIGH_CONTRAST_THEME.md) +- [Implementation checklist](./IMPLEMENTATION_CHECKLIST.md) +- [Infinite scroll implementation summary](./IMPLEMENTATION_SUMMARY.md) +- [Infinite scroll UX](./infinite-scroll-ux.md) +- [Installation](./INSTALLATION.md) +- [Marketing cursor effects](./marketing-cursor-effects.md) +- [Market card mobile layout](./MARKET_CARD_MOBILE_LAYOUT.md) +- [Market detail tokens](./MARKET_DETAIL_TOKENS.md) +- [Market hero](./MARKET_HERO.md) +- [Market preview card](./MARKET_PREVIEW_CARD.md) +- [Wallet microcopy](./microcopy-wallet.md) +- [Notification digest](./notification-digest.md) +- [Onboarding tour](./ONBOARDING_TOUR.md) +- [Predictions empty state](./PREDICTIONS_EMPTY_STATE.md) +- [Prediction comments](./PREDICTION_COMMENTS.md) +- [Print receipt](./PRINT_RECEIPT.md) +- [Quickstart](./QUICKSTART.md) +- [Quiet hours](./quiet-hours.md) +- [Recently viewed](./RECENTLY_VIEWED.md) +- [Recommendation provenance and 404](./recommendation-provenance-and-404.md) +- [Recommendations](./RECOMMENDATIONS.md) +- [Reduced-motion patterns](./REDUCED_MOTION_PATTERNS.md) +- [Reduced-motion quick reference](./REDUCED_MOTION_QUICK_REFERENCE.md) +- [Search input](./SEARCH_INPUT.md) +- [Getting started checklist](./STARTED_CHECKLIST.md) +- [Success confetti](./SUCCESS_CONFETTI.md) +- [Tabs](./TABS.md) +- [Trending rail](./TRENDING_RAIL.md) +- [Typography system](./TYPOGRAPHY.md) +- [Typography implementation guide](./TYPOGRAPHY_IMPLEMENTATION.md) +- [Typography testing guide](./TYPOGRAPHY_TESTING.md) +- [Wallet integration](./WALLET.md) +- [Wallet reduced motion](./WALLET_REDUCED_MOTION.md) +- [What's new](./WHATS_NEW.md) +- [Infinite scroll screenshot guide](./screenshots/infinite-scroll/README.md) + ## 🐛 Troubleshooting ### Common Issues diff --git a/TYPOGRAPHY.md b/docs/TYPOGRAPHY.md similarity index 99% rename from TYPOGRAPHY.md rename to docs/TYPOGRAPHY.md index ac231c3d..bbe89293 100644 --- a/TYPOGRAPHY.md +++ b/docs/TYPOGRAPHY.md @@ -168,7 +168,7 @@ This document outlines the standardized typography hierarchy for Predictify. All > **Heads up:** numeric spans that DON'T use a stat token (e.g. a > percentage rendered with `text-body-sm` or `text-body-md`) must opt > in with the explicit `tabular-nums` class. See -> [MarketHero → Tabular numerals](docs/MARKET_HERO.md#tabular-numerals-issue-556). +> [MarketHero → Tabular numerals](./MARKET_HERO.md#tabular-numerals-issue-556). ### 5. Monospace (Code) diff --git a/TYPOGRAPHY_IMPLEMENTATION.md b/docs/TYPOGRAPHY_IMPLEMENTATION.md similarity index 100% rename from TYPOGRAPHY_IMPLEMENTATION.md rename to docs/TYPOGRAPHY_IMPLEMENTATION.md diff --git a/TYPOGRAPHY_TESTING.md b/docs/TYPOGRAPHY_TESTING.md similarity index 100% rename from TYPOGRAPHY_TESTING.md rename to docs/TYPOGRAPHY_TESTING.md diff --git a/generate-svgs.js b/scripts/generate-svgs.js similarity index 88% rename from generate-svgs.js rename to scripts/generate-svgs.js index 2cd65d2c..743a7765 100644 --- a/generate-svgs.js +++ b/scripts/generate-svgs.js @@ -8,8 +8,9 @@ const wallets = [ { id: 'rabet', file: 'rabet.webp', type: 'image/webp' } ]; -const sourceDir = path.join(__dirname, 'public/images'); -const targetDir = path.join(__dirname, 'public/assets/wallets'); +const rootDir = path.resolve(__dirname, '..'); +const sourceDir = path.join(rootDir, 'public/images'); +const targetDir = path.join(rootDir, 'public/assets/wallets'); if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true });