Skip to content

Latest commit

 

History

History
333 lines (304 loc) · 25.4 KB

File metadata and controls

333 lines (304 loc) · 25.4 KB

Changelog

[Unreleased]

Fixed

  • Tab-switch auto-pause now shows an explanatory toast ("⏸ Paused — you switched tabs") and a resume nudge on return
  • Eye Focus mode now shows an exit hint ("Tap 👁 or Esc to exit") on enter, matching regular Focus mode behaviour
  • Burger menu coach mark after onboarding now persists until first content is loaded (was: auto-dismissed after 8s)

Added

  • Adaptive speed suggestion now persists as a tappable badge (⚡ N WPM) in the session strip until acted on or overridden by manual WPM change
  • Post-onboarding empty screen: Upload and Paste buttons highlighted with accent glow to guide first content load
  • WPM pill: faint "tap to set" micro-hint indicates the number is directly editable
  • Session strip: "↕ jump" affordance hint on the word-position button
  • Fine-tune settings: description line beneath each toggle/control explaining its effect
  • Onboarding demo: speed ramps from 150 WPM to 250 WPM over first 10 words (was: fixed 250 WPM cold start)

[2.4.0] — Gap fix · tagline · viewport nav · empty state · default text · session strip · footer

Fixed

  • Black gap below footer — added min-height: 100dvh to .appShell so the shell always fills the screen
  • Tagline breakpoint.topBarTagline now hides at max-width: 340px (was 380px) so it stays visible on more phones
  • Word nav overlay hidden.wordNavOverlay is now display: none; word count lives in the session strip in the controls dock
  • Page nav pill wider.pagePillOverlay resized to 26px height with better padding, letter-spacing, and --text-muted colour for readability
  • Page nav buttons larger.pageNavBtn is now 26×26px (was 22×22px)
  • Day-theme nav overrides — slightly more opaque backgrounds and explicit color: var(--text) on hover for contrast
  • Empty state spacious.emptyState now uses gap: 1rem, padding: 2rem 1.5rem, transparent background; heading is 1.4rem with tracking and centred; emptyActionBtn uses --radius-lg and taller padding
  • Viewport expands when empty.viewportEmpty modifier added; .readingMain:has(.viewportEmpty) stretches to fill available height
  • Session strip minimum 1%pct now uses Math.max(1, ...) so a loaded document never shows "0%"
  • Large word-count truncation — documents ≥ 10 000 words show as e.g. "32.3k" in the session strip
  • Welcome text on first visitWELCOME_TEXT loaded automatically when no history exists; returning users see their last state
  • Footer visual weight.footer is opacity: 0.5 at rest, full opacity on hover

[2.3.0] — Top bar: tagline visible, ThemeToggle restored, help circle button, sign-in moved to burger Account section

Fixed

  • Tagline visibility — removed display: flex; flex-direction: column; align-items: flex-start from .topBarTitle; these flex properties made the title a column container that consumed all height, leaving zero space for the sibling tagline span
  • ThemeToggle restored — added ThemeToggle import and component back into topBarActions in App.tsx
  • Help circle button — added ? button to topBarActions wired to setShowHelp(true); restyled .helpBtn from 44px square to 36px circle (border-radius: 50%)
  • Sign-in moved to burger — unauthenticated UserAvatar now returns null (clean top bar); burger menu gains an Account section with "Sign in to sync reading" button (only when Supabase is configured) and name + sign-out when authenticated

[2.2.0] — Fix: burger portal (iOS backdrop-filter trap), obsidian topBar visible, contextStrip gap removed

Fixed

  • Burger overlay (iOS portal fix) — wrapped {open && (...)} block in createPortal(…, document.body) in BurgerMenu.tsx; iOS Safari WebKit bug #224093 traps position:fixed descendants inside an ancestor with backdrop-filter — portaling to document.body escapes all ancestor compositing layers so the full-screen overlay now covers the entire viewport on iOS
  • Obsidian topBar — added [data-theme='obsidian'] .topBar override with rgba(28,28,28,0.95) background; the previous value rgba(10,10,10,0.80) was visually indistinguishable from the #000 page background; also added explicit midnight and warm overrides for completeness
  • contextStrip gap — removed padding-bottom: calc(0.5rem + 2.75rem) from .contextStrip; the 2.75rem was intended to prevent footer overlap but instead created a visible black gap below the collapsed preview panel

[2.1.0] — UX polish: burger fix, tagline contrast, sign-in button, duplicate word count removed, preview label

Fixed

  • Burger menu overlay — removed backdrop-filter from .inner in Controls.module.css; iOS WebKit compositing bug caused the controls panel to paint above the burger menu fixed overlay regardless of z-index; replaced glass blur with solid --bg-panel background
  • Tagline contrast.topBarTagline changed from var(--text-faint) to var(--text-muted) for all four themes (text-faint was near-invisible on day + obsidian themes); also removed leftover .topBarTitle::after CSS pseudo-element (now that TSX has the real span it was rendering the tagline twice)
  • Duplicate word count.wordCountOverlay inside the reading viewport hidden (display: none) — session strip in the controls dock is the single source of truth for reading position

Changed

  • Sign in buttonUserAvatar unauthenticated state replaced emoji 👤 placeholder with a proper "Sign in" ghost pill button that calls signInWithGoogle; styled with --border-input, --radius-full, hover/focus/active states
  • ContextPreview label — "Page Preview" → "Preview" (never wraps on any screen width)

[2.0.0] — Full UI/UX Facelift Part 2: viewport active glow, progress bar wired, top bar tagline TSX, controls 3-layer dock TSX, word-jump, help keyboard shortcut

Changed

  • Reading viewport — simplified box-shadow (explicit border: 1px solid + inset 0 0 60px vignette + 0 4px 24px depth); new .viewportActive glow state: border-color: --color-accent-30, 0 0 0 1px --color-accent-22 outer ring applied when isPlaying === true
  • Top bar — TSX restructure: <span className="topBarTitle"> replaced with <div className="topBarBrandText"> containing title + tagline "Read faster, Understand Better"; SyncStatusIndicator, ThemeToggle, and help ? button removed from topBarActions (theme accessible via BurgerMenu drawer; help opens via ? keyboard shortcut)
  • Controls dock — full 3-layer TSX restructure: Layer 1 = session strip (pct%, word position, reset icon); Layer 2 = action row (Upload+Paste cluster | circular play | Back+Next cluster); Layer 3 = WPM stepper pill; resetRow removed, merged into session strip
  • Controls contextcurrentWordIndex and goToWord added to context destructure

Added

  • Word jump — session strip pct% label is now a tappable button that opens an inline input; supports both word number (234) and percentage (47%) formats; focus auto-set on open
  • Reading progress bar<div className="readingProgressBar"> wired in App.tsx with currentWordIndex / words.length width calculation
  • ? keyboard shortcut — pressing ? toggles the HelpModal (replaces the removed top-bar ? button)

[1.9.0] — Full UI/UX Facelift Part 1: reading progress bar, glass top bar with tagline, controls v3 dock, burger menu z-index fix, ContextPreview glass card

Changed

  • Top barwill-change: backdrop-filter for stable composite layer; opacity raised to 0.80; transition: opacity 0.15s ease; day-theme and @supports fallbacks updated
  • Top bar brand — tagline "Read faster, Understand Better" injected via CSS ::after (no TSX changes); topBarBrandText and topBarTagline classes added for Part 2 TSX update; title scaled to clamp(0.9rem, 2.5vw, 1.1rem) / weight 700
  • Top bar icon buttons — ghost border (transparent by default), text-faint color, simplified hover with state-hover bg; removed box-shadow and extra transitions
  • Controls dock — full v3 redesign: isolation: isolate removed from .controls (was causing burger menu backdrop to paint behind glass panels on WebKit/iOS Safari); .inner uses overflow: hidden and --shadow-md token with no z-index; new layer classes .sessionStrip, .btnCluster, .wpmRow ready for Part 2 TSX update; backward-compat .resetRow/.resetRowBtn preserved
  • Burger menu backdropz-index: 600 → 1200 (above all backdrop-filter compositing layers); top: env(safe-area-inset-top) → top: 0; added isolation: isolate and -webkit-backdrop-filter
  • ContextPreview.preview glass card (rgba(--bg-panel-rgb, 0.75) + backdrop-filter: blur(12px)); .headerRow minimal dark strip with rgba borders; .content font-size 0.85rem, line-height 1.75

Added

  • Reading progress bar.readingProgressBar (position: fixed, z-index: 2000, above burger backdrop) + .readingProgressFill (accent color, glow via --color-accent-30) ready for TSX wiring in Part 2

[1.8.0] — Visual redesign: circular play button, viewport vignette, glass controls panel, glass top bar, premium WPM pill

Changed

  • Play button — redesigned as circular hero element (64 px diameter). Glow ring via box-shadow (--color-accent-12 halo + depth shadow). :hover expands glow; :active scales to 0.93. Label hidden — icon only.
  • Reading viewport — inner vignette (inset 0 0 80px rgba(0,0,0,0.6)) focuses the eye on the ORP word. Outer depth shadow grounds the canvas. Border replaced with box-shadow 0 0 0 1px technique for smoother appearance. Day-theme lighter overrides added.
  • Controls panel — glass treatment: background: rgba(var(--bg-panel-rgb), 0.85) + backdrop-filter: blur(16px) saturate(1.1). Elevation via box-shadow: 0 -4px 24px. Day-theme and @supports not (backdrop-filter) fallbacks included.
  • Top bar — glass navigation header: background: rgba(var(--bg-panel-rgb), 0.75) + backdrop-filter: blur(20px) saturate(1.2). border-bottom uses rgba(255,255,255,0.06) for subtlety. Day-theme and @supports fallbacks included.
  • WPM pill — height fixed to 44px (was inconsistent 38/44 mix). border-radius: var(--radius-full) pill shape. border-color: var(--border-input). Elevated box-shadow. +/− buttons widened to 44px. Value display: font-size: 1rem, font-weight: 600, min-width: 96px, letter-spacing: -0.01em. Unit text now uses var(--color-accent) at 0.7 opacity.
  • Control buttons — corner radius upgraded from --radius-sm (8px) to --radius-md (10px). Hover adds box-shadow: 0 2px 8px. Active scales to 0.94.
  • Focal tick marks — changed from hardcoded #666/#999 to var(--color-accent) at 0.35 opacity. Now theme-synchronized across all four themes.

Added

  • Shadow/elevation token scale (--shadow-sm, --shadow-md, --shadow-lg, --shadow-xl) in :root; lighter overrides in [data-theme="day"]
  • Transition timing tokens (--transition-fast: 100ms ease, --transition-base: 150ms ease, --transition-slow: 250ms ease, --transition-spring) in :root
  • --bg-panel-rgb token in all four theme blocks (midnight, warm, day, obsidian) for future rgba() usage
  • Inter Variable font via @fontsource-variable/inter; imported as very first line of main.tsx
  • font-family: 'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif set on :root and all theme blocks
  • -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale on body
  • Micro-interaction layer across all interactive surfaces:
    • .controlBtn, .playBtn — multi-property transitions, @media (hover: hover) hover with box-shadow, :active scale, :focus-visible ring
    • .topBarIconBtn, .helpBtn — upgraded to @media (hover: hover), :active scale, :focus-visible ring
    • .cta in InputPanel — proper hover (background + glow ring), :active scale, :focus-visible ring
    • .burgerBtn, .linkBtn, .profileBtn, .themeBtn, .sectionActionBtn in BurgerMenu — full interaction pattern
    • .presetTile, .customTile, .wizardTile in ReadingModes — full interaction pattern
    • .wpmStepBtn@media (hover: hover) hover, :active scale
  • .inner in Controls — grounding box-shadow: var(--shadow-sm) (structural panel)
  • .panel in BurgerMenu — box-shadow: var(--shadow-lg)

Changed

  • All raw 0.15s, 0.12s, 0.2s transition values in modified files replaced with design tokens (var(--transition-base), var(--transition-fast), var(--transition-slow))
  • .cta font-weight changed from 700600 (correct Inter weight for CTAs)
  • .titleInput transition now includes box-shadow for the focus ring

Known Issues

  • WPM stepper buttons (.wpmStepBtn) are 26×26 px — below the 44 px touch target minimum. To be addressed in a separate task.

Changed

  • Fine-tune menu reordered into 5 logical groups with thin dividers
  • Labels renamed to plain language (Reading anchor, Focus guides, Dim side words, Dim level, Group into phrases, Side word size)
  • Side word controls hidden entirely when Words shown = 1
  • Context word size changed from checkbox to dropdown (Same as main / Small / Medium / Normal / Large / X-Large / Huge)
  • Side word dimming now uses CSS opacity (not a separate color token); --vp-text-peripheral tokens removed from all themes
  • Wizard restructured: 15 steps, new order (words → phrases → speed → layout → word size → side word size → anchor → colour → guides → dim → dim level → punctuation → long words → confirm)
  • Wizard auto-skips side-word steps when Words shown = 1
  • Wizard auto-skips ORP colour step when Reading anchor is off
  • Wizard auto-skips Dim level step when Dim side words is off
  • Layout and Word size steps added to wizard

Migration

  • fastread_context_same_size (boolean) → fastread_context_font_size (number)
  • Existing saved custom modes with old field migrated automatically

v1.3.2

  • fix(pdf): Approach C diagram detection false positive rate reduced from 83% to 3.5%
    • isDiagramSymbol() excludes prose typography (smart quotes, dashes, footnote markers)
    • ZONE_EXPAND_GAP 30→40pt: captures labels adjacent to diagram anchor rows
    • X_SPREAD_MIN 60→75pt: eliminates marginal prose band overlap

[1.5.0]

Changed

  • Onboarding redesigned — 4 steps (was 5): Demo → Pick mode → Pick theme → Load content. Burger menu callout step removed entirely. Step 1 is now a vertical stack of 3 tappable mode tiles (Sprint / Focus / Flow) with emoji, WPM range, description, and a "Recommended" badge on Focus. Step 2 is a 2×2 theme grid (Midnight / Warm / Obsidian / Day) — better thumb reach than the single row of 4. Step 3 keeps the original load-content cards unchanged.
  • Button layout fixed — Back is now a small chevron icon in a top nav row alongside the progress dots and a Replay button (step 0 only). Primary action is full-width at the bottom so it never moves between steps. Skip is a small text link below the primary button.
  • Post-onboarding empty state — the reading viewport now shows two large tappable cards ("Upload file" and "Paste text") when no document is loaded, replacing the plain text placeholder. Cards show icons, labels, and format hints.
  • Post-onboarding coach mark — a single tooltip anchored to the burger menu appears 3 s after onboarding completes ("Settings & history live here") and auto-dismisses after 5 s or on any click. Replaces the previous scatter of help-button pulse, burger-button pulse, and upload-button pulse.

Removed

  • Burger menu callout step from onboarding overlay.
  • pulseHelp, pulseBurger, pulseUpload, showPostOnboardingHint states and all related CSS (helpBtnPulse, @keyframes helpPulse, postOnboardingHint, @keyframes hintBarFade).
  • pulseBurger prop from BurgerMenuProps.
  • pulseUpload prop from ControlsProps.

Added

  • Context word size toggle — new setting contextWordSameSize (default: true). When enabled, context words render at the same font size as the main word. When disabled, they use a smaller size (clamp(1.1rem, 5vw, 1.8rem)) to create visual hierarchy. Persisted in fastread_context_same_size.
  • Dim amount slider — new setting contextWordOpacity (default: 0.65, range 0.20–1.00, step 0.05). Controls the opacity of context words when peripheralFade is on. When peripheralFade is off, context words always render at full opacity. Persisted in fastread_context_opacity.
  • Wizard 1–5 word count — Step 1 of the Save Mode Wizard now offers all five window sizes (1–5) instead of the previous 1–3.
  • Wizard Step 6: Context word size — new Yes/No step asking whether context words should match the main word size.
  • Wizard Step 7: Dim amount — new stepper step to configure context word opacity, applied when dimming is enabled.
  • Wizard keyboard navigation — press / or Enter to move between steps, Y/N on Yes/No steps, 15 on the word-count step, Escape to close.
  • Wizard keyboard hint — small hint line below the progress bar shows available keyboard shortcuts.
  • Burger menu closes on Resume — clicking "Resume" in the Session Analytics panel now closes the burger menu before resuming the session.

Changed

  • getSlotOpacity signature updated: the windowSize parameter is replaced by contextWordOpacity: number, which is used as the fade value when peripheralFade is true (previously hard-coded to 0.45).
  • All three presets (speed, focus, read) updated with contextWordSameSize: true and contextWordOpacity: 0.65.

[1.4.1]

Fixed

  • Eye focus button unclickable — the base .overlayBar rule carries pointer-events: none (so the transparent overlay doesn't swallow word-area taps). Child clusters (.pageNavOverlay, .wordNavOverlay) individually restore pointer-events: all, but the .eyeBtn rule was missing the same restoration. Added pointer-events: all to the base .eyeBtn rule in ReaderViewport.module.css so the eye button is always clickable regardless of eye-focus state.

[1.4.0]

Fixed

  • WPM resets to 238 on refresh — the adaptive speed system (finalizeSession) was calling setWpm(newBaseline) which overwrote fastread_wpm in localStorage with the adjusted value. On every subsequent refresh the app would initialise to 238 (250 × 0.95) instead of the user's saved preference. Fix: removed setWpm(newBaseline) entirely — finalizeSession still runs to track rewinds and store its baseline in fastread_adaptive_wpm, but the user's WPM preference is never overwritten. Adaptive toast message updated to "Suggested speed for next session" to match the new non-mutating behaviour.

Changed

  • WPM badge removed — the WPM number that appeared inside the reading area during fullscreen focus mode has been removed. The Controls bar WPM stepper remains unchanged. Removed .focusWpmBadge and .focusWpmUnit CSS classes.
  • Eye focus mode rearchitectedisFocusMode local state removed from ReaderViewport; replaced with isEyeFocus prop driven from App. Eye focus now borrows appShellFocused to hide the top bar and controls bar (same as the existing maximize button), and hides page nav, word nav, source label, and focal ticks within the viewport. The word display is completely unchanged in eye focus — same size, same position, same color. Eye button lives inside the overlayBar between the page nav and word nav clusters. Pressing Escape exits eye focus mode.

v1.3.2 (in progress)

Added

  • Progress % in word panel — percentage now prepended before the "W" label ([XX%] W [current] / [total]). Calculated as Math.round((currentWordIndex / totalWords) * 100) with a 0% guard when no document is loaded. Uses muted --text-faint token so it recedes behind the word count without a badge or border.
  • Source label — small, non-interactive overlay at the top-left of the reading viewport showing the loaded filename (files) or session title / first line (pasted text), truncated to 28 characters with a trailing ellipsis. Renders null when no source is loaded. Hides in focus mode.
  • Paste text resume — pasted and URL-fetched content now reliably creates an IndexedDB entry so sessions resume from the correct word position on next visit. Fixed a pruning-race bug where the pruneTextCacheToNames call ran with a stale records snapshot that did not yet include the newly created session, causing the just-saved entry to be immediately deleted.

v1.3.1 (in progress)

Added

  • InputPanel now wires urlParser.ts for URL inputs (CORS-aware, honest error on blocked sites)
  • Reset to Beginning shows a 5s undo toast — position fully recoverable
  • Sign-in prompt fires only at ≥95% document completion, not on every pause
  • Post-onboarding: hint bar fades in above viewport + Upload button pulses for 4s
  • What's New converted from blocking modal to collapsible bottom banner
  • Burger menu pulse delayed 2s and extended to 6s post-onboarding
  • F key toggles focus mode
  • Focus mode entry/exit uses staggered fade transitions; "Esc or F to exit" hint fades in for 3s
  • WPM pill flashes accent briefly on every speed change
  • iOS back-swipe conflict fixed: left 20px excluded from swipe detection
  • Screen reader: aria-live="polite" region announces words at ≤300 WPM, silent above
  • Toasts include ARIA role="status" for screen reader announcement
  • Peripheral word contrast uses --vp-text-peripheral token (≥4.5:1 per theme) not opacity
  • HelpModal: F key + touch gesture documentation added
  • ContextPreview: "↩ current" button filled accent + appear animation when detached
  • Adaptive speed adjustments now show a toast explaining the change
  • InputPanel: optional session title auto-populated from first sentence of pasted text

[1.3.0]

Fixed

  • Page Preview jitter eliminated: active word now uses threshold-based instant scroll (snaps when past 75% of container) instead of competing smooth-scroll animations
  • Page Preview text reflow fixed: .word and .activeWord both use font-weight: 600; active state is differentiated by color only, preventing width-change reflow
  • Top bar page number chip (topBarReadPos) removed — redundant with viewport overlay and Page Preview header

Added

  • "↩ current" return button in Page Preview header — appears when user has browsed away from the reading position (isDetached); clicking snaps view back to current reading page and clears detached state

[1.0.6]

Changed

  • All control buttons unified into one visual system matching +/- style
  • Progress bar removed — word count and page pill remain
  • Info row and page navigation merged into one compact row
  • PLAY/PAUSE is visually primary — accent filled, slightly larger
  • RESET is visually muted — faint color, no accent hover
  • Icon + small label below on all action buttons
  • Controls area reorganised from 3 rows to 2 main rows (info + actions + slim WPM row)

[1.0.5]

Changed

  • ORP coloring is now a separate toggle from ORP alignment — "Highlight key letter"
  • ORP color picker replaced with 4 researched science-backed options per theme
  • All buttons and icon fills now use var(--color-accent) — theme-synchronized
  • "Words" select removed from burger menu display section (redundant with Custom tab)
  • Focus mode always enables focal line — removable only in Custom mode
  • DESIGN_SYSTEM.md updated: color rules, token audit, icon guidelines

[1.0.4]

Added

  • 3 app themes: Midnight (default), Warm, Day
  • Theme switcher in burger menu (replaces day/night toggle)

Changed

  • Peripheral fade is now uniform across all context slots (0.45 when ON, 0.65 when OFF)
  • Mode tiles: emoji stacked above label — 2-line compact layout, no overflow
  • "Word Window" label removed — unified as "Words" everywhere
  • All accent colors unified to var(--color-accent) — progress bar, icons, wizard
  • Custom mode wizard updated: max 3 words, uniform fade, correct defaults
  • Default startup: focalLine ON, peripheral fade ON, 250 WPM, Focus mode, 1 word

[1.0.3]

Changed

  • Maximum word window reduced from 5 to 3
  • Word layout redesigned: ORP character always aligned with tick marks
  • Pre-ORP column fixed at 3 character widths — accommodates any English word
  • Tick position derived from font metrics, identical in 1-word and multi-word mode
  • Both modes share same left edge and ORP anchor point

[1.0.2]

Fixed

  • Single-word mode now left-aligned — same starting X as multi-word mode
  • Tick marks completely static — never move between words in either mode
  • Tick position computed once from font metrics, only updates on font size change
  • Context words flow at natural width — no equal-width columns, no mid-word clipping
  • Empty trailing slots removed from DOM (null), no layout gaps
  • Focal ticks hidden when no document loaded
  • focalLine new-user default corrected to false

[1.0.1]

Fixed

  • Ellipsis shown only on last context word slot
  • Focal tick marks restored in multi-word mode via ORP position measurement
  • Empty trailing slots invisible and take no space
  • Context panel collapsed by default, tap to expand
  • focalLine always colors ORP regardless of orpEnabled toggle
  • Viewport vertically centered, words no longer float
  • Context word font size increased for mobile readability
  • Punctuation pause: sentence-end only (1.25×), minor punctuation removed