File size: 3,380 Bytes
557ab38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 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

```bash
# 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
```