# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview eng-pad is an Android note-taking app built around notebooks with an EMR pen as the primary input method. Target devices are the Supernote Manta (Android 11) and Daylight DC-1 (Android 13). Minimum API level is Android 11 (API 30). ## Build Commands ```bash make all # lint → test → build make build # Compile debug + release APKs make test # Run unit tests make lint # Run Android Lint make clean # Clean build artifacts make run # Build, install, and launch on emulator (starts emulator if needed) make devrun # Build, install, and launch on connected USB device make run AVD=Medium_Phone_API_36.0 # Use a specific AVD # Run a single test class: make test-one CLASS=net.metacircular.engpad.data.StrokeBlobTest ``` ## Architecture - **Kotlin + Jetpack Compose** for UI chrome (screens, toolbar, dialogs) - **Custom View** (`PadCanvasView`) for the drawing canvas — Compose Canvas lacks `MotionEvent` access needed for stylus input - **Room** (SQLite) for persistence — notebooks, pages, strokes - **Single Activity** with Compose Navigation (three screens: notebook list → page list → editor) - **Coordinate system**: 300 DPI canonical points. Regular page = 2550×3300pt, large = 3300×5100pt. Scaled to 72 DPI (×0.24) for PDF export. - **Input dispatch**: `TOOL_TYPE_STYLUS` → draw/erase/select, `TOOL_TYPE_FINGER` → zoom/pan ## Project Documents - **DESIGN.md** — Full technical design (architecture, data model, rendering, source tree) - **PROJECT_PLAN.md** — All implementation steps with checkboxes. Check off steps as completed. - **PROGRESS.md** — What's been done, what's in progress, decisions made. Update after every step. **Keep PROJECT_PLAN.md and PROGRESS.md in sync.** When a step is completed, check it off in PROJECT_PLAN.md and log it in PROGRESS.md. When files are added, update the source tree in both DESIGN.md and this file. ## Source Tree ``` eng-pad/ ├── app/ │ ├── build.gradle.kts -- Module build config │ └── src/ │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── kotlin/net/metacircular/engpad/ │ │ │ ├── EngPadApp.kt -- Application class │ │ │ ├── MainActivity.kt -- Single activity, Compose NavHost │ │ │ ├── data/ │ │ │ │ ├── db/ -- Room database, DAOs, converters │ │ │ │ ├── model/ -- Entities: Notebook, Page, Stroke, PageSize │ │ │ │ └── repository/ -- NotebookRepository, PageRepository │ │ │ ├── ui/ │ │ │ │ ├── navigation/NavGraph.kt -- Route definitions │ │ │ │ ├── notebooks/ -- List screen + ViewModel │ │ │ │ ├── pages/ -- Page grid screen + ViewModel │ │ │ │ ├── editor/ -- PadCanvasView, EditorScreen, ViewModel │ │ │ │ ├── export/PdfExporter.kt -- PDF generation + sharing │ │ │ │ └── theme/Theme.kt -- Material3 theme │ │ │ └── undo/ -- UndoManager, UndoableAction │ │ └── res/ │ └── test/ -- Unit tests ├── build.gradle.kts -- Root build config ├── settings.gradle.kts -- Project settings (foojay JDK resolver) ├── gradle.properties ├── gradle/libs.versions.toml -- Version catalog ├── Makefile -- Build targets (build, test, lint, run, devrun) ├── CLAUDE.md -- This file ├── README.md ├── DESIGN.md -- Technical design ├── PROJECT_PLAN.md -- Implementation steps └── PROGRESS.md -- Completion tracking ``` ## Key Conventions - Stroke points are packed as little-endian float BLOBs: `[x0,y0,x1,y1,...]` - All coordinates are in canonical space (300 DPI). Screen transform via `Matrix`. - Grid drawn in **screen space** with pixel-snapped positions (not canonical space) for uniform squares. - Pen widths: 0.38mm = 4.49pt, 0.5mm = 5.91pt (at 300 DPI). - Anti-aliasing disabled on all paint objects for crisp e-ink rendering. - No backing bitmap — strokes draw directly as paths. - Viewport: page always fills screen, pan clamped to edges, dynamic min zoom. - Line snap: hold pen still 1.5s to snap to straight line (60pt movement threshold). - Hardware palm rejection only (EMR digitizer).