721fccd5ce27764759ab92bed375770f43f65028
Driven by on-device iteration on a Galaxy S24+ (live ADB install/ screenshot loop), gated by a real-device motion pass at animator scale 1x and frame stats (p95 8ms, 0.85% legacy jank). Motion (Codex): X/Y axes animate in independent concurrent effects. The prior sequential animateTo calls starved Y under ~50Hz retargeting - diagonal movement traced an L and the second axis caught up seconds late. Reduced-motion/system-disabled paths snap both axes. Instrument (Claude, on Codex's base): - Fluorescent yellow-green fluid (matches real spirit-level dye); amber retained for guidance text. - Bubble as a true void: borderless symmetric gradient orb, translucent interior (marks read through it), soft bright refraction band, contact shadow, fluorescent halo, window-style reflection + glint. Velocity-squash experiment tried and removed - shape fidelity beats the flourish. - Bubble (0.12R) nests inside the 1-degree target ring; ring turns lime on VISUAL containment of the drawn bubble (lock label/pulse/ haptic remain on LockDetector truth). - Machined bezel, etched cardinal/45 ticks, per-ring degree labels via the same SurfaceGuidance mapping. dp-scaled strokes replace raw-pixel hairlines; contrast lifted for real screens. - Red center target dot beneath the translucent bubble (Codex). Text hierarchy: guidance suppressed while locked (no correction advice under a 'Flat within' verdict), demoted to titleLarge, and raised into the empty status line's slot. Primary readout optically dead-centered via an invisible leading degree twin; degree symbol .55em at TextDim with cap-height baseline shift (.38 - metrics pair, resize together). 59 tests passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On the Level
Offline-first Android pocket toolset: a trustworthy level, angle meter, and calibrated screen ruler (Pro). Kotlin + Jetpack Compose, single module, no backend.
- BRIEF.md — the authoritative v1 product & technical brief
- AUDIT.md — audit of the brief; the amendments it lists are incorporated
- resources/ — concept board (visual direction)
Building
Open in Android Studio, or:
./gradlew assembleDebug # build
./gradlew testDebugUnitTest # measurement-math unit tests
Scaffold status
The project skeleton follows BRIEF.md §Sensor and measurement architecture. Implemented and tested:
core/sensors— sensor selection (game rotation vector → gravity → low-passed accelerometer), device-frame gravity stream, and the pure measurement math: orientation mapping, two-sample per-mode calibration (derived in angle space, applied in vector space so it stays correct away from zero), EMA smoothing, lock hysteresis/dwell/debounce, display deadband, placement validity, and the sensor-vector contract (all sources emit device-frame world-up; flat = +9.81 on Z, pinned bySensorContractTest). All unit-tested.core/settings— DataStore preferences and per-mode calibration persistence.core/billing— entitlement interface with a stub (free-tier) implementation.feature/level,feature/angle— live numeric scaffolds wired to the real sensor pipeline, with manual Surface|Edge selection, placement-validity hints, lock state (locked label states the tolerance so it can never contradict the rounded readout), and directional hold-to-zero (vector reference, not magnitude subtraction).feature/ruler,feature/tools— static placeholders.
Not yet implemented (deliberately — see TODO markers):
- The tactile vial visuals and the spring-animated display value (value 3 of 3 in the brief); scaffold screens render the deadbanded stable value directly.
- Guided calibration flow UI (math and persistence are done).
- Edge-mode readout counter-rotation on the portrait-locked activity.
- Play Billing implementation of
ProEntitlementRepository. - Screen ruler measurement UI and per-display scale persistence.
- Audio cue, reduced-motion behaviors, preferences UI.
Description
Languages
Kotlin
83.9%
HTML
16.1%