---
estimated_steps: 10
estimated_files: 5
skills_used: []
---

# T01: Build font service with opentype.js, bundle fonts, and add unit tests

Create the fontService utility that loads .ttf fonts via fetch + opentype.parse(), caches parsed Font objects, and converts text to SVG path data. Bundle 3-5 OFL-licensed Google Fonts as .ttf files in app/public/fonts/. Add @font-face CSS declarations in App.css so Konva Text rendering matches the opentype.js fonts. Install opentype.js dependency. Write comprehensive unit tests for font loading, caching, and text-to-path conversion.

This is the riskiest piece of the slice — if opentype.js path extraction doesn't produce accurate SVG `d` attributes compatible with Konva's Path component, everything downstream breaks. Testing with real bundled font files proves the integration.

## Key Constraints
- opentype.js loads fonts from ArrayBuffer — must fetch() font files then call opentype.parse()
- Path.toPathData() needs consideration of coordinate systems (font Y-up vs canvas Y-down)
- Letter spacing is NOT built into getPath() — must implement per-character glyph positioning with manual x-advance
- Font files served from /fonts/ via Vite's public directory
- @font-face CSS must load before Konva renders Text nodes
- TypeScript strict mode with verbatimModuleSyntax — use `import type` for type-only imports
- Tests should mock fetch() to return real font file ArrayBuffers loaded from disk

## Inputs

- ``app/package.json` — add opentype.js dependency`
- ``app/src/App.css` — existing global styles, add @font-face declarations`

## Expected Output

- ``app/src/utils/fontService.ts` — font loading, caching, text-to-path conversion service`
- ``app/src/utils/__tests__/fontService.test.ts` — unit tests for fontService`
- ``app/public/fonts/Roboto-Regular.ttf` — bundled font file`
- ``app/public/fonts/OpenSans-Regular.ttf` — bundled font file`
- ``app/public/fonts/Lato-Regular.ttf` — bundled font file`
- ``app/package.json` — updated with opentype.js dependency`
- ``app/src/App.css` — updated with @font-face declarations`

## Verification

cd app && npx vitest run src/utils/__tests__/fontService.test.ts --reporter=verbose && npx tsc --noEmit && ls public/fonts/*.ttf | wc -l
