Files
on_the_level/BRIEF.md
T

8.0 KiB
Raw Blame History

On the Level — v1 Product & Technical Brief

Status: Ready for final Claude review before implementation
Date: 2026-07-11
Companion audit: AUDIT.md

Product decision

On the Level is an offline-first Android pocket-tool app for quick, trustworthy level and angle work. It should feel like a responsive physical instrument—not a novelty simulation—while keeping displayed measurements stable and honest.

v1 is deliberately small: a level, an angle meter, a calibrated screen ruler, and the settings necessary to make them dependable. There is no account, backend, advertising, camera/AR measurement, cloud sync, analytics dependency, or subscription in v1.

Audience and promise

For everyday DIY, hanging pictures, shelving, small home jobs, and quick rough measurements. The app is not a substitute for a certified or safety-critical instrument. Screen-ruler copy must state that it is for short, rough measurements only.

Navigation and layout

Use a simple three-destination bottom navigation: Level, Angle, and Tools. The app is portrait-locked in v1. The UI is edge-to-edge and must correctly handle system insets and back gestures.

1. Level — default destination

  • Header: LEVEL, live/calibrated status, calibration/settings action.
  • Explicit mode selector: Surface | Edge. Do not auto-switch modes in v1; unexpected switching undermines confidence while positioning the phone.
  • Surface: phone lying screen-up on a surface; use a two-axis cross-vial visualization with meaningful pitch and roll readings.
  • Edge: phone held upright on its long edge against a wall, shelf, or picture frame; use a single, prominent vial/readout for that plane.
  • The central visual is tactile: its bubble has restrained spring/damping, settles naturally, and responds immediately to device movement.
  • A locked state is a brief, accessible success reaction with a debounced system-respecting haptic/audio cue. It is not the persistent normal UI.
  • Keep the screen on while this destination is visible.

2. Angle

  • Large primary angle readout.
  • Secondary pitch, roll, and percent-grade readings.
  • Hold to zero sets a relative reference and is always free.
  • Percent grade is tan(pitch) × 100; define a sensible cap or infinity presentation near a vertical surface.
  • Target-angle alerts and saved named references are Pro features.

3. Tools

  • Screen Ruler: a Pro tool with a clear preview and calm, intentional paywall—not an interruption in the free level/angle flow.
  • Calibration entry point.
  • Units, haptic/audio, and motion/accessibility preferences.

Visual and interaction direction

Use the concept board's deep graphite base, warm amber bubble, and lime level lock as direction rather than a literal spec. Numeric measurements remain near-white and must be readable in bright conditions. Never convey accuracy, state, or purchase status by color alone.

The visual vial may be expressive, but it must never contradict the numeric reading. Provide an in-app reduced-motion option and respect disabled system animations. Respect device haptic settings; do not force vibration.

Measurement modes and calibration

Only promise calibration for the two physical orientations explicitly supported in v1:

  1. Surface — screen-up, flat contact plane.
  2. Long Edge — upright, long-edge contact plane.

Store a reference orientation for each supported mode—not a scalar angle offset. The calibration flow uses two samples: place the device, record; rotate it 180° on the same plane, record; derive the reference/bias from both samples. This reduces fixed device bias without requiring the user to start on a known-level surface. Calibration UI must give exact, mode-specific placement instructions.

Screen-ruler calibration is separate from sensor calibration. Offer calibration against a standard credit-card width (85.60 mm) and a conventional ruler option. Store scale with the active display/configuration characteristics and request recalibration whenever a material display change makes the prior scale suspect.

Sensor and measurement architecture

Use a small native Android/Kotlin Compose application. Keep one app module for v1, with a manual application container rather than premature modularization or Hilt.

app/
  core/design/       theme, typography, tactile animation primitives
  core/sensors/      sensor source, device-axis mapping, measurement math
  core/settings/     DataStore preferences and calibration persistence
  core/billing/      entitlement abstraction and Play Billing implementation
  feature/level/     state and UI for Surface / Edge level modes
  feature/angle/     relative-zero logic and UI
  feature/ruler/     ruler calibration and UI
  feature/tools/     tools and settings UI

Require an accelerometer in the manifest. Select sensors in this order:

  1. TYPE_GAME_ROTATION_VECTOR
  2. TYPE_GRAVITY
  3. A low-pass-filtered TYPE_ACCELEROMETER

The app does not need north/heading. Map device-frame sensor values explicitly for the portrait-locked UI and for each measurement mode. Handle unavailable sensors with a clear unsupported-device state.

Maintain three distinct values:

  1. Raw sensor value — received from the selected sensor source.
  2. Stable calibrated measurement — reference-orientation calibration plus a defined EMA/low-pass filter. This is the sole input to numeric readouts and level-lock detection.
  3. Animated display value — a critically damped spring derived from the stable value and used only to move the vial/bubble.

Readouts use 0.1° resolution and a display deadband to prevent flickering. Lock behavior starts at no more than 0.2°, exits at at least 0.35°, has a short dwell time, and has a multi-second haptic debounce. Exact constants remain tunable, but lock and readout must always use the same stable calibrated measurement.

Register sensors only while a relevant screen is foregrounded; unregister them when backgrounded.

Monetization

Use one permanent, non-consumable On the Level Pro Google Play product. Do not use a subscription. The free product is complete:

  • Surface and Edge level modes
  • Angle measurement, pitch/roll, degree/grade display
  • Hold-to-zero
  • Calibration and basic feedback/unit preferences

Pro adds deliberate, additive measurement tools:

  • Calibrated Screen Ruler
  • Target-angle haptic/audio alerts
  • Saved and named angle references

Expose entitlement as StateFlow<Entitlement> from core/billing. Billing initialization must be asynchronous/lazy: free tools render immediately and never block on Play services. Cache a previously Play-confirmed entitlement for offline job-site use, refresh owned purchases when possible (including resume), and never grant from an arbitrary preference value or a pending purchase.

Testability and release gates

Keep all math—device-axis mapping, calibration, smoothing, hysteresis, grade, and lock transitions—in pure Kotlin. Place sensor I/O behind an injected SensorSource so tests can use synthetic and recorded real-device traces.

Before release, verify:

  • Surface and Edge readings across supported orientations and screen rotation conditions.
  • Two-sample calibration improves repeatability and remains isolated per mode.
  • Numeric readings, vial animation, and lock feedback stay consistent.
  • Haptic debounce, system haptic settings, reduced motion, and bright-light readability.
  • Sensor absence, app backgrounding, and screen wake behavior.
  • Pro purchase, restore, pending purchase, offline cached entitlement, and billing-unavailable behavior without degrading free tools.
  • Ruler calibration, display/configuration changes, and honest rough-measure wording.

Explicitly out of scope for v1

  • Camera-assisted or AR distance measurement
  • Accounts, server verification, cloud storage, sharing, or collaboration
  • Ads, subscription plans, consumable credits, or trial metering
  • Automatic flat/edge mode switching
  • Support claims for every device edge, case, or external/foldable display