Tasks 5-7: eval harness, FastAPI backend, Paper & Ink UI- src/eval/ β precision/recall/F1 harness with type-aware comparators,micro/macro F1, CSV + markdown reports, --model benchmark flag- src/api/ β FastAPI backend with /extract, /schemas, /health,request-ID middleware, typed error envelope, injectable extractor- ui/ β Vite + React + TS + Tailwind + Motion + React Three FiberPaper & Ink editorial UI with 3D paper hero, dark/light mode,confidence inkwell, wax-stamp metrics, kinetic typography- 95 passing tests (up from 54); UI is a separate npm workspace
557ab38 Ledger UI
The Paper & Ink frontend for the structured-data-extraction API.
Stack
- Vite + React + TypeScript β fast dev loop, small bundle.
- Tailwind β utility layout only. All colors, typography, and design
tokens live as CSS variables in
src/styles/theme.css, so dark/light mode is a single attribute flip on<html data-theme="...">. - Motion (
motion/react) β component-level animation. - React Three Fiber + drei + three β the 3D paper sheet in the hero.
- Google Fonts β Instrument Serif (display), Geist (UI), JetBrains Mono (code). All free.
Run locally
# 1. Install
cd ui
npm install
# 2. Point at the API (in another terminal, from the repo root):
uvicorn src.api.main:app --reload
# 3. Start the dev server
npm run dev
# open http://localhost:5173
Vite proxies /api/* to http://localhost:8000, so no CORS needed in dev.
Configuration
VITE_API_BASE(optional) β override the API origin for prod builds. Defaults to/api.
Design tokens
Everything visual is in src/styles/theme.css:
--bg,--surface,--surface-2,--ruleβ surfaces + dividers--ink,--ink-strong,--ink-soft,--ink-muteβ text weights--accent,--accent-hover,--accent-softβ coral--sage,--mustardβ confidence tiers + warnings
To try a color, edit the variable β both modes update simultaneously.
Project shape
ui/
βββ index.html # font preload + theme priming (no-flash)
βββ src/
β βββ main.tsx # ReactDOM render
β βββ App.tsx # page composition
β βββ styles/
β β βββ theme.css # design tokens (light + dark)
β β βββ globals.css # base + grain overlay + focus/cursor
β βββ components/
β β βββ TopNav.tsx # logo + theme toggle
β β βββ ThemeToggle.tsx # hand-drawn sun/moon
β β βββ CustomCursor.tsx # spring-lag ink dot
β β βββ Hero.tsx # kinetic headline + stats + 3D scene
β β βββ PaperScene.tsx # R3F: floating paper w/ mouse parallax
β β βββ ExtractSection.tsx # workbench (dropzone + results)
β β βββ Dropzone.tsx # drop + browse + doc-type + samples
β β βββ ResultsPanel.tsx # composes the below
β β βββ ConfidenceInkwell.tsx # confidence as an ink vessel
β β βββ MetricsStrip.tsx # cost/latency/tokens/model
β β βββ JsonView.tsx # syntax-highlighted JSON
β β βββ WarningsList.tsx # model-flagged concerns
β β βββ HowItWorks.tsx # three chapters
β β βββ Numbers.tsx # magazine-style data page
β β βββ Footer.tsx # signature line
β βββ hooks/
β β βββ useTheme.ts # dark/light + localStorage
β β βββ useExtract.ts # upload lifecycle
β βββ lib/
β β βββ api.ts # thin fetch client + typed error envelope
β β βββ samples.ts # committed sample docs
β βββ types.ts # mirrors src/schemas server-side
βββ public/samples/ # sample_receipt.png, sample_invoice.pdf