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 | /** | |
| * WarningsList β model-flagged concerns rendered as marginalia strokes. | |
| * Info/warning/error rendered with different left-border colors so the reader | |
| * can scan severity without reading. | |
| */ | |
| import type { ExtractionWarning } from "@/types"; | |
| interface Props { | |
| warnings: ExtractionWarning[]; | |
| } | |
| const COLORS: Record<ExtractionWarning["severity"], string> = { | |
| info: "var(--ink-mute)", | |
| warning: "var(--mustard)", | |
| error: "var(--accent)", | |
| }; | |
| export function WarningsList({ warnings }: Props) { | |
| if (!warnings.length) { | |
| return ( | |
| <p className="text-[13px] italic text-[var(--ink-mute)]"> | |
| No warnings β model reported no concerns. | |
| </p> | |
| ); | |
| } | |
| return ( | |
| <ul className="flex flex-col gap-2"> | |
| {warnings.map((w, i) => ( | |
| <li | |
| key={i} | |
| className="border-l-2 py-1.5 pl-4 text-[13px] leading-[1.6] text-[var(--ink-soft)]" | |
| style={{ borderLeftColor: COLORS[w.severity] }} | |
| > | |
| {w.field && ( | |
| <span className="mr-2 font-mono text-[12px] text-[var(--ink-mute)]"> | |
| {w.field} | |
| </span> | |
| )} | |
| {w.message} | |
| </li> | |
| ))} | |
| </ul> | |
| ); | |
| } | |