Convert the eager typographySettingsStore singleton to getTypographySettingsStore()
(+ __resetTypographySettingsStore for tests) and update barrels and consumers
(TypographyMenu, FontSampler, SampleList, ComparisonView Line/SliderArea,
comparisonStore + its mock).
Fix a latent leak while here: the store ran $effect.root and discarded the
returned cleanup, so its storage-sync effects outlived every instance. Capture
the disposer and expose destroy(), which __reset now calls.
Mirror the font-catalog change in ComparisonView: expose getComparisonStore()
(plus __resetComparisonStore for tests) instead of an eager comparisonStore
singleton, and consume getFontCatalog() internally. Update the model barrel and
all UI consumers (Sidebar, FontList, Header, Line, SliderArea); Character no
longer needs the store and reads everything from props.
Update both specs to the accessor: comparisonStore.test mocks getFontCatalog
with a writable stub (the real store's fonts is getter-only) and resets the
catalog between cases; Sidebar.svelte.test resolves the store via the accessor.
Also document Character's props.
Extract findSplitIndex; computeLineRenderModel now takes the split index
as a primitive. Line derives its model from `split`, so the $derived
short-circuits on value equality and skips recomputation on spring ticks
that don't move the split (previously every tick rebuilt the model and
re-rendered the line).
Lay the three regions out as inline boxes on a shared baseline. fontA and
fontB now align on the typographic baseline despite differing metrics,
and an always-present overflow:hidden strut pins the line-box baseline so
the line no longer jumps when a bulk run mounts/unmounts or the last
window char morphs to a font of different ascent.
Rewrite Line.svelte to render leftText / windowChars / rightText regions
from a LineRenderModel. Bulk regions render as native shaped text runs so
the browser applies kerning and ligatures; per-char DOM is reserved for
the N-char crossfade window straddling the slider.
Slim Character.svelte: drop the unused proximity prop and the redundant
font-size/font-weight/letter-spacing styles now inherited from the line
container.
Switch SliderArea.svelte to instantiate DualFontLayout and derive each
line's render model via computeLineRenderModel(line, sliderPos,
containerWidth, WINDOW_SIZE).
Structural:
- Merge factory + singleton from lib/settingsManager and model/state into
one model/store/typographySettingsStore/ slice
- Drop now-empty lib/ and model/state/ directories
Semantic:
- Rename feature SetupFont -> AdjustTypography (the feature owns
continuous typography adjustment, not one-time font setup)
- Drop "Manager" from TypographySettingsManager -> TypographySettingsStore
(class + factory); singleton typographySettingsStore unchanged
All consumers (Character, Line, SampleList, SliderArea, FontSampler,
comparisonStore) updated. Public barrel signature changed: now exports
createTypographySettingsStore and type TypographySettingsStore.