Files
biblical-guide.com/FOCUS_MODE_ENHANCED_PLAN.md
Andrei 9b5c0ed8bb build: production build with Phase 1 2025 Bible Reader implementation complete
Includes all Phase 1 features:
- Search-first navigation with auto-complete
- Responsive reading interface (desktop/tablet/mobile)
- 4 customization presets + full fine-tuning controls
- Layered details panel with notes, bookmarks, highlights
- Smart offline caching with IndexedDB and auto-sync
- Full accessibility (WCAG 2.1 AA)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 20:38:01 +00:00

30 KiB

Focus Mode Enhanced - Implementation Plan

📋 Overview

Focus Mode Enhanced builds upon the existing distraction-free reading mode to provide advanced concentration aids and reading tools that help users maintain focus and improve reading comprehension.

Status: Planning Phase Priority: Medium Estimated Time: 1 week (40 hours) Target Completion: TBD


🎯 Goals & Objectives

Primary Goals

  1. Reduce eye strain and improve reading comfort
  2. Help users maintain focus during extended reading sessions
  3. Accommodate different reading styles and preferences
  4. Improve reading comprehension through guided techniques
  5. Provide accessibility features for users with reading difficulties

User Value Proposition

  • For students/scholars: Enhanced focus during deep Bible study
  • For users with ADHD/dyslexia: Guided reading aids
  • For elderly users: Reduced eye strain with reading guides
  • For speed readers: Tools to maintain pace and rhythm

Feature Specifications

1. Dimming/Masking Surrounding Text

Description: Reduce visual clutter by dimming text that isn't currently in focus.

Modes:

  • Paragraph Spotlight: Highlight only the current paragraph
  • Sentence Spotlight: Highlight only the current sentence
  • Verse Spotlight: Highlight only the current verse
  • Custom Range: Highlight N lines above and below cursor

Implementation Details:

interface DimmingConfig {
  enabled: boolean
  mode: 'paragraph' | 'sentence' | 'verse' | 'custom'
  intensity: number // 0-100% opacity for dimmed text
  customLinesAbove: number
  customLinesBelow: number
  blurAmount: number // 0-10px blur for dimmed text
}

Visual Behavior:

  • Active text: 100% opacity, sharp
  • Dimmed text: 20-60% opacity (user adjustable)
  • Optional: 0-5px blur on dimmed text
  • Smooth transitions (300ms) when focus changes

2. Guided Reading Line

Description: A horizontal line or overlay that follows the user's reading position.

Types:

  • Static Line: Fixed position on screen, text scrolls beneath
  • Following Line: Moves with scroll to track reading position
  • Reading Ruler: Semi-transparent bar that highlights current line
  • Dual Lines: Top and bottom lines create a reading window

Implementation Details:

interface ReadingLineConfig {
  enabled: boolean
  type: 'static' | 'following' | 'ruler' | 'dual'
  position: number // 0-100% from top of viewport
  color: string
  thickness: number // 1-5px
  opacity: number // 0-100%
  windowHeight: number // For ruler/dual mode (lines of text)
}

Visual Examples:

Static Line (position: 33%):
┌─────────────────┐
│ verse text...   │
│ verse text...   │
├═════════════════┤ ← Reading line
│ verse text...   │
│ verse text...   │
└─────────────────┘

Reading Ruler:
┌─────────────────┐
│ verse text...   │
┌═════════════════┐ ← Top border
│█ verse text... █│ ← Highlighted
└═════════════════┘ ← Bottom border
│ verse text...   │
└─────────────────┘

3. Spotlight Mode

Description: Highlight the current paragraph/verse with visual emphasis.

Effects:

  • Background Highlight: Colored background behind active text
  • Border Highlight: Subtle border around active element
  • Shadow Effect: Drop shadow on active text
  • Scale Effect: Slightly enlarge active text (1.05x)
  • Glow Effect: Soft glow around active text

Implementation Details:

interface SpotlightConfig {
  enabled: boolean
  effect: 'background' | 'border' | 'shadow' | 'scale' | 'glow' | 'combined'
  backgroundColor: string
  borderColor: string
  borderWidth: number
  shadowIntensity: number
  scaleAmount: number // 1.0 - 1.1
  glowColor: string
  transitionSpeed: number // 100-500ms
}

CSS Implementation:

.verse-spotlight {
  background-color: var(--spotlight-bg);
  box-shadow: 0 0 20px var(--spotlight-glow);
  border-left: 4px solid var(--spotlight-border);
  padding: 8px 12px;
  margin: 4px -12px;
  border-radius: 4px;
  transform: scale(1.02);
  transition: all 0.3s ease;
}

4. Reading Ruler Overlay

Description: A semi-transparent overlay that creates a focused reading window.

Features:

  • Top and bottom masks that darken text above/below
  • Adjustable window height (1-5 lines)
  • Follows scroll automatically
  • Keyboard shortcuts to move window up/down
  • Touch gestures to adjust window size

Implementation Details:

interface ReadingRulerConfig {
  enabled: boolean
  windowHeight: number // lines of text (1-5)
  maskOpacity: number // 0-90%
  maskColor: string
  autoFollow: boolean // Follow scroll
  smoothTracking: boolean
}

DOM Structure:

<div class="reading-ruler-overlay">
  <div class="ruler-mask ruler-mask-top"></div>
  <div class="ruler-window">
    <!-- Active reading area (transparent) -->
  </div>
  <div class="ruler-mask ruler-mask-bottom"></div>
</div>

5. Auto-Scroll with Adjustable Speed

Description: Automatic scrolling at a consistent pace to maintain reading rhythm.

Features:

  • Speed control: 10-300 words per minute
  • Pause/resume with spacebar
  • Visual indicator of scroll progress
  • Speed adjustment while scrolling (arrow keys)
  • Auto-pause at chapter end
  • Remembers speed preference per user

Implementation Details:

interface AutoScrollConfig {
  enabled: boolean
  wordsPerMinute: number // 10-300
  isPaused: boolean
  smoothness: 'linear' | 'ease' | 'ease-in-out'
  showProgressBar: boolean
  pauseAtChapterEnd: boolean
}

class AutoScroller {
  private scrollInterval: number | null
  private currentSpeed: number

  start(config: AutoScrollConfig): void
  pause(): void
  resume(): void
  adjustSpeed(delta: number): void
  stop(): void
}

Controls:

  • Play/Pause button (spacebar)
  • Speed slider (10-300 WPM)
  • +/- buttons (adjust by 10 WPM)
  • Progress indicator
  • Keyboard shortcuts:
    • Space: Pause/Resume
    • Up Arrow: +10 WPM
    • Down Arrow: -10 WPM
    • Escape: Stop

6. Bionic Reading Format

Description: Bold the first few letters of each word to guide eye movement.

Algorithm:

function bionicFormat(word: string): string {
  const length = word.length
  if (length <= 1) return word

  // Bold first 40-60% of letters
  const boldCount = Math.ceil(length * 0.5)
  const bold = word.substring(0, boldCount)
  const regular = word.substring(boldCount)

  return `<strong>${bold}</strong>${regular}`
}

// Example:
// "reading" → "<strong>read</strong>ing"
// "Bible" → "<strong>Bib</strong>le"

Implementation Details:

interface BionicReadingConfig {
  enabled: boolean
  intensity: number // 30-70% of word to bold
  fontWeight: number // 400-700
  applyToVerseNumbers: boolean
  preserveExistingFormatting: boolean
}

Visual Example:

Normal:
In the beginning God created the heaven and the earth.

Bionic:
In th**e** beg**inn**ing G**od** cre**at**ed th**e** hea**v**en a**nd** th**e** ea**rth**.

7. Sentence-by-Sentence Mode

Description: Display one sentence at a time, advancing with user input.

Features:

  • Show current sentence in full opacity
  • Hide/fade other sentences
  • Advance with click, tap, or arrow key
  • Show sentence counter (1/15)
  • Option to show N sentences at a time
  • Smooth transitions between sentences

Implementation Details:

interface SentenceModeConfig {
  enabled: boolean
  sentencesVisible: number // 1-3
  advanceMethod: 'click' | 'tap' | 'key' | 'auto'
  autoAdvanceDelay: number // ms (for auto mode)
  showCounter: boolean
  fadeTransition: boolean
}

class SentenceNavigator {
  private sentences: string[]
  private currentIndex: number

  next(): void
  previous(): void
  jumpTo(index: number): void
  getCurrentSentence(): string
  getTotalSentences(): number
}

8. Breathing Reminders

Description: Periodic gentle reminders to take breaks and breathe.

Features:

  • Configurable interval (5-60 minutes)
  • Subtle visual cue (pulsing icon or border)
  • Optional sound notification
  • Guided breathing animation (4-7-8 technique)
  • Auto-pause reading during reminder
  • "I'm ready" button to resume

Implementation Details:

interface BreathingReminderConfig {
  enabled: boolean
  intervalMinutes: number // 5-60
  visualCue: 'pulse' | 'fade' | 'border' | 'icon'
  soundEnabled: boolean
  showGuidedBreathing: boolean
  autoPauseReading: boolean
}

class BreathingReminder {
  private timer: NodeJS.Timeout | null

  start(config: BreathingReminderConfig): void
  stop(): void
  reset(): void
  showReminder(): void
  hideReminder(): void
}

Guided Breathing Animation:

┌─────────────────────┐
│                     │
│    ◉ Breathe In     │ ← Expanding circle
│      (4 seconds)    │
│                     │
└─────────────────────┘

┌─────────────────────┐
│                     │
│    ◉ Hold           │ ← Static circle
│      (7 seconds)    │
│                     │
└─────────────────────┘

┌─────────────────────┐
│                     │
│    ◉ Breathe Out    │ ← Contracting circle
│      (8 seconds)    │
│                     │
└─────────────────────┘

🎨 UI/UX Design

Settings Panel Location

Add "Focus Mode" tab to existing Reading Settings panel:

┌─────────────────────────┐
│ Reading Settings        │
├─────────────────────────┤
│ ▸ Typography            │
│ ▸ Theme                 │
│ ▾ Focus Mode ← NEW      │
│   ├─ Dimming            │
│   ├─ Reading Line       │
│   ├─ Spotlight          │
│   ├─ Auto-Scroll        │
│   ├─ Bionic Reading     │
│   ├─ Sentence Mode      │
│   └─ Breathing Reminders│
└─────────────────────────┘

Controls UI

// Focus Mode Quick Toggle Bar
<Box className="focus-mode-controls">
  <IconButton
    title="Enable Focus Mode"
    onClick={toggleFocusMode}
  >
    <VisibilityIcon />
  </IconButton>

  {focusModeEnabled && (
    <>
      <Divider orientation="vertical" />

      {/* Dimming Toggle */}
      <ToggleButton value="dimming" selected={dimming.enabled}>
        <OpacityIcon />
      </ToggleButton>

      {/* Reading Line Toggle */}
      <ToggleButton value="line" selected={readingLine.enabled}>
        <LinearScaleIcon />
      </ToggleButton>

      {/* Auto-Scroll */}
      <ToggleButton value="scroll" selected={autoScroll.enabled}>
        <PlayArrowIcon />
      </ToggleButton>

      {/* Speed Control (when auto-scroll active) */}
      {autoScroll.enabled && (
        <>
          <IconButton size="small" onClick={decreaseSpeed}>
            <RemoveIcon />
          </IconButton>
          <Typography variant="caption">
            {autoScroll.wordsPerMinute} WPM
          </Typography>
          <IconButton size="small" onClick={increaseSpeed}>
            <AddIcon />
          </IconButton>
        </>
      )}

      {/* Settings Menu */}
      <IconButton onClick={openFocusSettings}>
        <SettingsIcon />
      </IconButton>
    </>
  )}
</Box>

Mobile Considerations

  • Floating toolbar (bottom of screen)
  • Swipe gestures:
    • Swipe up: Show settings
    • Swipe down: Hide controls
    • Pinch: Adjust dimming intensity
  • Touch and hold: Quick access to reading line

🏗️ Technical Implementation

File Structure

/components/bible-reader/
├── focus-mode/
│   ├── FocusModeProvider.tsx         # Context provider
│   ├── FocusModeControls.tsx         # Control toolbar
│   ├── FocusModeSettings.tsx         # Settings panel
│   ├── DimmingOverlay.tsx            # Dimming effect
│   ├── ReadingLine.tsx               # Reading line/ruler
│   ├── SpotlightEffect.tsx           # Spotlight highlighting
│   ├── AutoScroller.tsx              # Auto-scroll logic
│   ├── BionicFormatter.tsx           # Bionic reading formatter
│   ├── SentenceNavigator.tsx         # Sentence-by-sentence
│   ├── BreathingReminder.tsx         # Breathing reminders
│   └── hooks/
│       ├── useFocusMode.ts           # Main hook
│       ├── useAutoScroll.ts          # Auto-scroll hook
│       ├── useSentenceDetection.ts   # Sentence parsing
│       └── useReadingPosition.ts     # Track reading position
└── reader.tsx                         # Updated main reader

Context Provider

// FocusModeProvider.tsx
interface FocusModeContextType {
  // State
  enabled: boolean
  dimming: DimmingConfig
  readingLine: ReadingLineConfig
  spotlight: SpotlightConfig
  readingRuler: ReadingRulerConfig
  autoScroll: AutoScrollConfig
  bionicReading: BionicReadingConfig
  sentenceMode: SentenceModeConfig
  breathingReminder: BreathingReminderConfig

  // Actions
  toggleFocusMode: () => void
  updateDimming: (config: Partial<DimmingConfig>) => void
  updateReadingLine: (config: Partial<ReadingLineConfig>) => void
  updateSpotlight: (config: Partial<SpotlightConfig>) => void
  updateAutoScroll: (config: Partial<AutoScrollConfig>) => void
  updateBionicReading: (config: Partial<BionicReadingConfig>) => void
  updateSentenceMode: (config: Partial<SentenceModeConfig>) => void
  updateBreathingReminder: (config: Partial<BreathingReminderConfig>) => void

  // Reading position
  currentElement: HTMLElement | null
  setCurrentElement: (el: HTMLElement | null) => void
}

export const FocusModeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [enabled, setEnabled] = useState(false)
  const [dimming, setDimming] = useState<DimmingConfig>(defaultDimmingConfig)
  // ... other state

  // Load from localStorage on mount
  useEffect(() => {
    const saved = localStorage.getItem('focusModeConfig')
    if (saved) {
      const config = JSON.parse(saved)
      // Apply saved config
    }
  }, [])

  // Save to localStorage on change
  useEffect(() => {
    localStorage.setItem('focusModeConfig', JSON.stringify({
      enabled,
      dimming,
      readingLine,
      spotlight,
      // ... all configs
    }))
  }, [enabled, dimming, readingLine, spotlight, /* ... */])

  return (
    <FocusModeContext.Provider value={{ /* ... */ }}>
      {children}
    </FocusModeContext.Provider>
  )
}

Dimming Implementation

// DimmingOverlay.tsx
export const DimmingOverlay: React.FC = () => {
  const { dimming, currentElement } = useFocusMode()
  const [activeRangeIds, setActiveRangeIds] = useState<string[]>([])

  useEffect(() => {
    if (!dimming.enabled || !currentElement) return

    // Determine which elements to keep visible
    const getActiveElements = () => {
      switch (dimming.mode) {
        case 'paragraph':
          return [currentElement.id]

        case 'sentence':
          // Find sentence boundaries
          return [findCurrentSentence(currentElement)]

        case 'verse':
          return [currentElement.closest('.verse')?.id]

        case 'custom':
          return getCustomRange(
            currentElement,
            dimming.customLinesAbove,
            dimming.customLinesBelow
          )
      }
    }

    setActiveRangeIds(getActiveElements())
  }, [currentElement, dimming])

  // Apply dimming via CSS classes
  useEffect(() => {
    const verses = document.querySelectorAll('.verse')
    verses.forEach(verse => {
      if (activeRangeIds.includes(verse.id)) {
        verse.classList.remove('dimmed')
        verse.classList.add('active')
      } else {
        verse.classList.add('dimmed')
        verse.classList.remove('active')
      }
    })
  }, [activeRangeIds])

  return null // Pure effect component
}

// CSS
.verse {
  transition: opacity 0.3s ease, filter 0.3s ease;
}

.verse.dimmed {
  opacity: var(--dimming-opacity);
  filter: blur(var(--dimming-blur));
}

.verse.active {
  opacity: 1;
  filter: none;
}

Reading Line Implementation

// ReadingLine.tsx
export const ReadingLine: React.FC = () => {
  const { readingLine } = useFocusMode()
  const [position, setPosition] = useState(0)
  const lineRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!readingLine.enabled) return

    if (readingLine.type === 'static') {
      // Fixed position on screen
      setPosition(readingLine.position)
    } else if (readingLine.type === 'following') {
      // Follow scroll position
      const handleScroll = () => {
        const scrollY = window.scrollY
        const viewportHeight = window.innerHeight
        const linePosition = scrollY + (viewportHeight * readingLine.position / 100)
        setPosition(linePosition)
      }

      window.addEventListener('scroll', handleScroll, { passive: true })
      return () => window.removeEventListener('scroll', handleScroll)
    }
  }, [readingLine])

  if (!readingLine.enabled) return null

  const styles = {
    position: readingLine.type === 'static' ? 'fixed' : 'absolute',
    top: readingLine.type === 'static'
      ? `${readingLine.position}%`
      : `${position}px`,
    left: 0,
    right: 0,
    height: `${readingLine.thickness}px`,
    backgroundColor: readingLine.color,
    opacity: readingLine.opacity / 100,
    zIndex: 1000,
    pointerEvents: 'none',
    transition: 'top 0.1s ease-out'
  }

  return <div ref={lineRef} style={styles} className="reading-line" />
}

Auto-Scroll Implementation

// useAutoScroll.ts
export const useAutoScroll = (config: AutoScrollConfig) => {
  const [isActive, setIsActive] = useState(false)
  const intervalRef = useRef<NodeJS.Timeout | null>(null)

  const calculateScrollAmount = () => {
    // Average word length: 5 characters
    // Average line: 60-80 characters = 12-16 words
    // Assume 14 words per line on average
    const wordsPerLine = 14
    const linesPerMinute = config.wordsPerMinute / wordsPerLine
    const pixelsPerLine = 24 // line height
    const pixelsPerMinute = linesPerMinute * pixelsPerLine
    const pixelsPerInterval = pixelsPerMinute / (60000 / 50) // 50ms intervals

    return pixelsPerInterval
  }

  const start = () => {
    if (intervalRef.current) return

    setIsActive(true)
    const scrollAmount = calculateScrollAmount()

    intervalRef.current = setInterval(() => {
      window.scrollBy({
        top: scrollAmount,
        behavior: config.smoothness === 'linear' ? 'auto' : 'smooth'
      })

      // Check if at bottom
      const atBottom = (window.innerHeight + window.scrollY) >= document.body.offsetHeight
      if (atBottom && config.pauseAtChapterEnd) {
        pause()
      }
    }, 50) // 20 FPS
  }

  const pause = () => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current)
      intervalRef.current = null
    }
    setIsActive(false)
  }

  const adjustSpeed = (delta: number) => {
    const newSpeed = Math.max(10, Math.min(300, config.wordsPerMinute + delta))
    // Update config through context
  }

  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.code === 'Space' && config.enabled) {
        e.preventDefault()
        isActive ? pause() : start()
      } else if (e.code === 'ArrowUp' && isActive) {
        e.preventDefault()
        adjustSpeed(10)
      } else if (e.code === 'ArrowDown' && isActive) {
        e.preventDefault()
        adjustSpeed(-10)
      } else if (e.code === 'Escape' && isActive) {
        pause()
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [isActive, config.enabled])

  return { isActive, start, pause, adjustSpeed }
}

Bionic Reading Implementation

// BionicFormatter.tsx
export const formatTextBionic = (text: string, intensity: number): string => {
  const words = text.split(/(\s+)/)

  return words.map(word => {
    // Skip whitespace and punctuation-only
    if (/^\s+$/.test(word) || /^[^\w]+$/.test(word)) {
      return word
    }

    // Extract leading punctuation
    const leadMatch = word.match(/^([^\w]*)(.*)$/)
    const leadPunct = leadMatch?.[1] || ''
    const remaining = leadMatch?.[2] || word

    // Extract trailing punctuation
    const trailMatch = remaining.match(/^(.*?)([^\w]*)$/)
    const core = trailMatch?.[1] || remaining
    const trailPunct = trailMatch?.[2] || ''

    if (!core) return word

    // Calculate bold count based on intensity
    const boldCount = Math.max(1, Math.ceil(core.length * (intensity / 100)))
    const boldPart = core.substring(0, boldCount)
    const regularPart = core.substring(boldCount)

    return `${leadPunct}<strong>${boldPart}</strong>${regularPart}${trailPunct}`
  }).join('')
}

// Apply to verse content
export const BionicFormatter: React.FC<{ children: string }> = ({ children }) => {
  const { bionicReading } = useFocusMode()

  if (!bionicReading.enabled) {
    return <>{children}</>
  }

  const formatted = formatTextBionic(children, bionicReading.intensity)

  return (
    <span
      dangerouslySetInnerHTML={{ __html: formatted }}
      style={{ fontWeight: bionicReading.fontWeight }}
    />
  )
}

💾 Data Persistence

LocalStorage Schema

interface FocusModeStorage {
  version: number // Schema version
  enabled: boolean
  lastUsed: string // ISO timestamp

  dimming: DimmingConfig
  readingLine: ReadingLineConfig
  spotlight: SpotlightConfig
  readingRuler: ReadingRulerConfig
  autoScroll: AutoScrollConfig
  bionicReading: BionicReadingConfig
  sentenceMode: SentenceModeConfig
  breathingReminder: BreathingReminderConfig

  // Usage stats
  stats: {
    totalTimeUsed: number // seconds
    sessionsCount: number
    favoriteMode: string
  }
}

// Key: 'bible-reader:focus-mode'

User Preferences API (Optional)

For logged-in users, sync settings to database:

// Add to UserPreference model in Prisma
model UserPreference {
  // ... existing fields
  focusModeConfig Json? // Store entire focus mode config
}

// API endpoint
POST /api/user/preferences/focus-mode
Body: FocusModeStorage
Response: { success: boolean }

🧪 Testing Strategy

Unit Tests

// __tests__/focus-mode/bionic-formatter.test.ts
describe('BionicFormatter', () => {
  it('should bold first 50% of word by default', () => {
    expect(formatTextBionic('reading', 50)).toBe('<strong>read</strong>ing')
  })

  it('should handle punctuation correctly', () => {
    expect(formatTextBionic('Hello,', 50)).toBe('<strong>Hel</strong>lo,')
  })

  it('should preserve whitespace', () => {
    expect(formatTextBionic('word  word', 50)).toContain('  ')
  })
})

// __tests__/focus-mode/auto-scroll.test.ts
describe('AutoScroller', () => {
  it('should calculate correct scroll speed', () => {
    const scroller = new AutoScroller({ wordsPerMinute: 200 })
    expect(scroller.getScrollSpeed()).toBeCloseTo(5.71, 2)
  })

  it('should pause at chapter end', () => {
    // Mock scroll position at bottom
    // Verify pause is called
  })
})

Integration Tests

// __tests__/focus-mode/integration.test.tsx
describe('Focus Mode Integration', () => {
  it('should activate all features together', () => {
    render(
      <FocusModeProvider>
        <BibleReader />
      </FocusModeProvider>
    )

    // Enable focus mode
    // Verify dimming is applied
    // Verify reading line appears
    // Verify spotlight works
  })
})

Manual Testing Checklist

  • Dimming works in all 4 modes
  • Reading line follows scroll smoothly
  • Spotlight highlights correct element
  • Auto-scroll maintains consistent speed
  • Bionic reading formats correctly
  • Sentence mode advances properly
  • Breathing reminders appear on schedule
  • Settings persist across sessions
  • Mobile gestures work correctly
  • Keyboard shortcuts function properly
  • Performance is smooth (60 FPS)
  • Works with all themes (light/dark/sepia)
  • Accessibility preserved (screen readers)

📊 Success Metrics

Quantitative Metrics

  • Engagement: Average reading session time increases by 20%
  • Adoption: 30% of users try focus mode within first month
  • Retention: 60% of users who try it use it regularly
  • Performance: No impact on page load time (<100ms overhead)
  • Error Rate: <0.1% JavaScript errors related to focus mode

Qualitative Metrics

  • User feedback surveys (focus mode helpfulness rating)
  • Support ticket volume (should not increase)
  • Accessibility audit (maintain WCAG AAA)

Analytics Events to Track

// Analytics events
track('focus_mode_enabled', {
  features_enabled: ['dimming', 'reading_line', 'auto_scroll'],
  session_duration: 1234, // seconds
})

track('focus_mode_setting_changed', {
  setting: 'dimming.mode',
  old_value: 'paragraph',
  new_value: 'sentence'
})

track('auto_scroll_used', {
  duration: 600, // seconds
  average_wpm: 180,
  speed_adjustments: 3
})

📅 Implementation Timeline

Phase 1: Core Infrastructure (Day 1-2)

  • Create focus mode context provider
  • Set up file structure
  • Implement settings panel UI
  • Add localStorage persistence
  • Implement quick toggle controls

Deliverable: Basic focus mode on/off toggle working

Phase 2: Dimming & Spotlight (Day 2-3)

  • Implement dimming overlay
  • Add all 4 dimming modes
  • Implement spotlight effects
  • Add smooth transitions
  • Test with different themes

Deliverable: Dimming and spotlight features complete

Phase 3: Reading Line & Ruler (Day 3-4)

  • Implement static reading line
  • Implement following reading line
  • Implement reading ruler overlay
  • Add position controls
  • Test scroll performance

Deliverable: Reading line and ruler working smoothly

Phase 4: Auto-Scroll (Day 4-5)

  • Implement auto-scroll logic
  • Add speed controls
  • Implement keyboard shortcuts
  • Add progress indicator
  • Test with different speeds

Deliverable: Auto-scroll feature complete

Phase 5: Advanced Features (Day 5-6)

  • Implement bionic reading formatter
  • Implement sentence-by-sentence mode
  • Add breathing reminders
  • Test all features together

Deliverable: All features implemented

Phase 6: Polish & Testing (Day 6-7)

  • Mobile optimization
  • Accessibility audit
  • Performance optimization
  • Bug fixes
  • Documentation
  • User testing

Deliverable: Production-ready feature


🚀 Deployment Plan

Pre-Launch Checklist

  • All unit tests passing
  • Integration tests passing
  • Manual QA complete
  • Accessibility audit passed
  • Performance benchmarks met
  • Documentation updated
  • Analytics events configured

Rollout Strategy

  1. Beta Release (Week 1)

    • Deploy to 10% of users
    • Monitor error rates and performance
    • Collect initial feedback
  2. Staged Rollout (Week 2)

    • Increase to 50% of users
    • Continue monitoring
    • Make adjustments based on feedback
  3. Full Release (Week 3)

    • Deploy to 100% of users
    • Announce feature in newsletter
    • Create tutorial/help content

Monitoring Plan

  • Real-time error tracking (Sentry)
  • Performance monitoring (Web Vitals)
  • Usage analytics (custom events)
  • User feedback collection (in-app survey)

📚 Documentation

User Documentation

Create help articles:

  1. "Introduction to Focus Mode"
  2. "Using Dimming and Spotlight Effects"
  3. "Reading Line and Auto-Scroll Guide"
  4. "Bionic Reading: What and Why"
  5. "Focus Mode Keyboard Shortcuts"

Developer Documentation

Update technical docs:

  • docs/components/focus-mode.md
  • API reference for focus mode hooks
  • Architecture decision records (ADR)
  • Performance optimization notes

🔄 Future Enhancements

Phase 2 Additions (Future)

  • Custom color schemes for focus mode
  • Focus mode profiles (save multiple configurations)
  • AI-powered reading pace recommendations
  • Eye-tracking integration (for supported devices)
  • Collaborative focus sessions (sync with study groups)
  • Reading comprehension quizzes (test focus effectiveness)
  • Advanced analytics (heatmaps of focus patterns)
  • Voice commands for hands-free control
  • Integration with reading plans (auto-enable for daily readings)

📝 Notes & Considerations

Performance Considerations

  • Use will-change CSS property sparingly
  • Implement throttling/debouncing for scroll events
  • Use requestAnimationFrame for smooth animations
  • Consider virtual scrolling for very long chapters
  • Profile with Chrome DevTools Performance tab

Accessibility Considerations

  • Ensure focus mode doesn't interfere with screen readers
  • Maintain keyboard navigation
  • Provide alternatives for color-dependent features
  • Test with screen readers (NVDA, JAWS, VoiceOver)
  • Add ARIA labels where appropriate

Browser Compatibility

  • Test on Chrome, Firefox, Safari, Edge
  • Provide fallbacks for unsupported features
  • Consider mobile browser limitations
  • Test on iOS Safari (webkit-specific issues)

User Privacy

  • Focus mode settings stored locally by default
  • Option to sync to account (opt-in)
  • No tracking of reading content
  • Clear data on logout (if user prefers)

Document Version: 1.0 Last Updated: 2025-10-13 Owner: Development Team Status: Ready for Implementation