* phase 0: token foundation
* phase 1: motion language
* phase 2: primitives and semantic tokens
* phase 3: depth and rhythm polish
* phase 4: enforce design system lint rules
* phase 5: split ui primitives into modules
* phase 7: refactor app surfaces to ui layer
* phase 9: enforce ui architecture imports
* phase 10: add ui system harness
* fix compact reader auth control
* fix pdf loader flash
* Converge sidebar and reader controls
* refactor: remove initial loader state and related logic from PDFViewerPage
* Remove legacy UI shim imports
* Converge modal and drawer frames
* Migrate secondary modals to shared frame
* Move settings modal onto shared frame
* Use shared cards in audiobook settings
* Converge choice and popover surfaces
* Converge reader navigation buttons
* Refactor UI components to use consistent button and icon styles across the application
* refactor(ui): unify button usage in settings, admin, and doclist components
Replace native button elements with shared Button, ChoiceTile, and IconButton
components for consistent UI behavior and styling. Update classNames and
props to match new component APIs. Adjust FinderSidebar to use utility
function for conditional class merging.
* feat(ui): introduce shared Listbox components for unified select and dropdown styling
Replace direct usage of Headless UI Listbox primitives with new SharedListboxButton,
SharedListboxOption, and SharedListboxOptions components across AudiobookExportModal,
FinderToolbar, VoicesControlBase, and select UI. Refactor related imports and classNames
to centralize dropdown styling and logic. Simplify UserMenu button markup for improved
consistency.
This change consolidates dropdown/select UI patterns, reduces duplication, and
improves maintainability by providing a single source of truth for Listbox styling
and behavior.
* refactor(ui): consolidate button, menu, popover, and range primitives for unified usage
Remove legacy UI harness and dev/demo files. Replace scattered button, menu, popover, and range input utilities with shared, composable primitives: Button, ButtonLink, ButtonAnchor, MenuActionItem, MenuItemsSurface, PopoverSurface, PopoverTrigger, and RangeInput. Update all usages across app, admin, player, and document components to use these new primitives, eliminating duplicated class logic and improving consistency. Remove obsolete utility files and class exports. This change streamlines UI code, centralizes styling, and reduces maintenance overhead.
* feat(ui): redesign range input with dynamic progress styling and improved accessibility
Revamp the range input component to support dynamic progress indication using CSS custom properties and linear gradients. Add logic to compute and set the progress percentage based on current value, min, and max. Refine focus and disabled states for better accessibility and usability. Update styling for both WebKit and Mozilla engines to ensure consistent appearance. This change enhances visual feedback and modernizes the range slider UI.
* style(ui): update range input to use secondary accent color for progress
Switch range input progress styling from primary to secondary accent color
for both WebKit and Mozilla engines. Remove drop shadow from slider thumb
for a cleaner appearance. This change aligns the component with the updated
design palette and simplifies visual effects.
* refactor(app): remove unused Link imports from public pages and components
Eliminate redundant imports of the Link component from Next.js in several
public-facing pages and components. These imports were no longer in use
after recent UI refactoring and consolidation of navigation elements.
This cleanup reduces bundle size and improves code clarity.
* chore(ui): remove unused export of segmented control classes from select component
Eliminate unnecessary export statements for segmentedButtonClass and
segmentedGroupClass in the select component to streamline the module's
public API and reduce potential confusion.
* test(accessibility): improve confirm dialog test coverage and refactor media state helper
Expand accessibility tests for ConfirmDialog to assert dialog semantics,
ARIA attributes, and visible destructive actions using test IDs. Refactor
expectMediaState helper to check both UI control state and underlying
media signals for more robust playback state detection.
* refactor(ui): improve segmented control accessibility and update danger color tokens
Update SegmentedControl to support full keyboard navigation and focus management,
enhancing accessibility. Replace string indicator in Select with icon, and update
button danger variant to use new --danger-strong variable for hover states. Add
danger-strong token to Tailwind config and globals. Refine dropzone disabled
behavior, adjust focus ring for better contrast, and apply minor UI consistency
tweaks across components.
* feat(ui): convert SidebarNavLink to forwardRef component
Refactor SidebarNavLink to use React.forwardRef, enabling parent components
to access the underlying anchor element's ref. Update prop typing and
function signature accordingly for improved composability and integration
with higher-order components.
Move all button-related class utilities and types from formPrimitives to a new
ui/buttonPrimitives module. Update all component imports to reference the new
location, ensuring consistent button styling and easier future maintenance.
Remove redundant button code from formPrimitives and re-export as needed for
admin UI compatibility. Add public.css for landing and privacy layout styles.
Eliminate the deprecated "columns" view mode from the document list, toolbar,
icons, and skeleton components. Update all related types and logic to only
support "icons", "list", and "gallery" views. Standardize user-facing labels
from "HTML" to "Text" for improved clarity across the sidebar, segment
locator labels, and document counts. Clean up associated code and types to
reflect these changes.
Introduce clearSegmentCaches to TTS context for explicit cache invalidation after segment clearing. Enhance SegmentsSidebar scroll logic to better distinguish user-initiated and programmatic scrolls, improving UX during segment updates.
Update TTS segment prefetching logic to handle arrays of CanonicalTtsSourceUnit for upcoming and next locations, enabling more precise TTS segment mapping. Expand cache key construction to include providerType and instructions, improving cache differentiation for TTS requests. Adjust related types and usages to support richer segment metadata propagation.
Introduce sentence and word highlighting for HTML/TXT/MD documents, including new config options (`htmlHighlightEnabled`, `htmlWordHighlightEnabled`) and synced user preferences. Update the HTML viewer to support these highlights using custom spans, and add corresponding CSS styles. Extend document settings to allow toggling these features. Implement block-level locator sorting and display improvements. Add audiobook export support for HTML documents, including adapter and pipeline integration.
- Add `htmlHighlightEnabled` and `htmlWordHighlightEnabled` to config, user state, and Dexie storage
- Update HTML viewer to apply and manage highlights for sentences and words
- Add CSS for HTML highlight classes and scroll margin
- Extend document settings UI for HTML highlight toggles
- Support HTML audiobook export in modal and pipeline
- Improve block locator sorting and sidebar display for HTML
- Add HTML audiobook adapter and block parsing utilities
Update multiple UI panels to use skeleton components instead of loading text or spinners.
Standardize loading states in AudiobookExportModal, AdminFeaturesPanel, AdminProvidersPanel,
DocumentSelectionModal, and SegmentsSidebar for improved visual consistency and user feedback.
Integrate @tanstack/react-query in SettingsModal to cache and prefetch library
documents, improving import modal responsiveness. Refactor SegmentsSidebar to
use infiniteQuery for TTS segments manifest, enabling pagination, cache
invalidation, and consistent data fetching. Remove legacy fetch state logic in
favor of react-query state management.
Adopt new layout files for app, epub, html, and pdf routes to standardize
Next.js nested layout structure. Refactor SegmentsSidebar to accept an explicit
epubBookRef prop, decoupling it from internal context. Enhance EPUB resize hook
to ignore initial baseline rect and avoid unnecessary TTS interruptions on load.
Simplify Providers by removing legacy context nesting and conditional logic.
Transition all TTS-related logic, types, and UI to use the new providerRef/providerType model in place of legacy ttsProvider fields. Introduce a centralized tts-provider-policy module to encapsulate provider/model capability checks, default value resolution, and compatibility logic. Update all API routes, contexts, hooks, components, and tests to use providerRef and providerType, ensuring consistent handling of built-in and shared TTS providers. Remove legacy defaultTtsModel config in favor of per-provider defaults and shared provider admin control. Add the showAllProviderModels runtime flag to restrict users to provider default models when desired.
BREAKING CHANGE: ttsProvider fields are replaced by providerRef/providerType throughout the codebase; defaultTtsModel config is removed in favor of per-provider defaults.
Move `epub-word-highlight`, `tts-epub-handoff`, and `tts-epub-preload` from shared to client/epub to clarify their usage and improve bundling. Update all imports to use new client paths. Extend TTS and sidebar logic to support HTML document progress tracking and restoration, introducing a new location format for HTML and consistent handling for non-EPUB readers.
BREAKING CHANGE: EPUB TTS utilities relocated to `lib/client/epub`; update import paths. HTML progress persistence now uses a new format incompatible with previous versions.
Redesign TTS segment storage by decomposing the `tts_segments` table into two normalized tables: `tts_segment_entries` for unique segment identity and locator projection, and `tts_segment_variants` for per-settings audio variants. Update schema, queries, and API routes to use the new structure, including manifest pagination and segment resolution logic. Refactor segment locator handling to use stable projections and manifest cursors. Migrate tests and data cleanup utilities to support the new model.
BREAKING CHANGE: Database schema for TTS segments is now split into entry and variant tables; all code and consumers must use the new structure. Persisted data and APIs relying on the old `tts_segments` table are incompatible.
Implement strict validation for EPUB TTS segment locators, requiring stable spine coordinates (`spineHref`, `spineIndex`, `charOffset`) and rejecting legacy CFI-only locators. Introduce `segmentKey` as a normalized identity derived from segment text, used for robust merging and deduplication of synthesized and persisted segments. Update database schemas, API routes, and manifest logic to support the new locator format and segmentKey. Add helpers for locator resolution and segmentKey construction, with comprehensive unit tests for identity, normalization, and manifest grouping.
BREAKING CHANGE: Persisted EPUB TTS segment locators must now include stable spine coordinates; legacy CFI-only locators are no longer accepted. Consumers must handle the new `segmentKey` field for segment identity and merging.
Refactor TTS segment identification to support canonical segment keys, decoupling segment IDs from locator and index for more robust deduplication and handoff. Add `segmentKey` to segment types, manifest, and ensure route. Implement natural sorting for EPUB CFI locations and segment locators using new comparison utilities. Update sidebar and manifest helpers to use locator-aware sorting. Add foundational modules for EPUB word highlighting, TTS segment planning, and EPUB handoff logic. Expand types and tests to cover new canonical segment and locator behaviors.
BREAKING CHANGE: TTS segment IDs now support canonical segment keys; APIs and manifest consumers must handle `segmentKey` and updated locator comparison logic.
Introduce configurable segment preloading depth, sentence lookahead, and TTS segment max block length for both PDF and EPUB readers. Add new settings to user preferences, config context, and document settings UI. Refactor TTS segment splitting logic to support per-user max block length and propagate these options through PDF/EPUB adapters and TTS segment generation. Update API, manifest pagination, and segment deduplication for improved performance and correctness. Add tests for new NLP options and manifest logic.
BREAKING CHANGE: TTS segment splitting and manifest APIs now require max block length and preloading parameters; user config schema updated.
Update segment manifest API to group segments by both index and locator
attributes, ensuring distinct segment variants are not merged incorrectly.
Adjust SegmentsSidebar logic to select the most relevant segment per index
based on locator match and recency, improving sidebar accuracy when
multiple locator variants exist for a segment.
Introduce SegmentsSidebar component and supporting reader UI for segment-level
navigation and inspection. Add TTS segments manifest and clear API endpoints to
enable efficient retrieval and management of segment variants. Update TTS
segment schema to include settings_hash for improved lookup and indexing,
and adjust indexes to use settings_hash instead of settings_json. Update
contexts and types to support segment variant display and interaction.
This enhances document navigation and TTS segment management for end users.