# Surface Level — Implementation Attack Plan **Status:** Proposed; send to Claude for audit before implementation. **Scope:** Surface Level only. Do not change Angle, Edge, ruler, or billing in this stage. ## Outcome Build a trustworthy two-axis surface-level tool for a phone lying flat, screen-up, on a surface. It must feel like a physical bullseye vial while giving clearer, more actionable information than a physical level. The user should be able to answer three questions at a glance or by sound: 1. Is this surface level? 2. How far off is it? 3. Which side/corner needs adjustment, and by roughly how much? ## Existing foundation to preserve - Unified device-frame world-up sensor contract. - Raw sensor -> stable measurement -> animated display separation. - Vector-space Surface calibration model and two-sample calibration math. - EMA smoothing, lock hysteresis/dwell/debounce, deadband, and current tests. - The current numeric Surface reading, pitch/roll values, and haptic lock hook. ## Product decisions to implement - Surface means the phone is intended to lie flat, screen-up, on the plane being measured. Its level-lock behavior is valid only in that geometry. - Numeric measurements are never hidden because the phone is steeply oriented. Outside the ideal Surface geometry, show the actual angle and a quiet placement hint; suppress level-lock feedback rather than replacing the reading with `—`. - The central visualization is a bullseye vial. It has a finite visual range: beyond that range the bubble rests at the rim, while numeric information remains full-range and authoritative. - Calibration corrects device/setup bias. It is not "make this desk level." A later relative-reference feature is separate and out of scope here. ## Work sequence ### 1. Make measurement behavior honest at every angle - Refactor Surface placement gating so it only controls the level-lock state, lock haptic, and geometry-specific guidance. - Keep primary angle, pitch, and roll visible at 0-90 degrees. - Add tests at flat, near level, 30 degrees, and near vertical proving numeric readings remain present and correct; verify invalid placement never locks. - Keep the existing lock tolerance semantics: a lock label states the tolerance rather than pretending any non-zero value is exactly flat. ### 2. Add the guided Surface calibration flow - Add a Surface Calibration route from the Level header. - Explain that the phone may be calibrated on any firm, stable surface; the surface itself does not need to be level. - Step 1: settle, sample for a short stable window, capture. - Step 2: rotate the phone exactly 180 degrees in the same plane, settle, capture. - Reject/retry if readings indicate motion or inconsistent placement. - Persist only the resulting Surface calibration; never alter Edge calibration. - State that the calibration applies to the current phone/case/contact setup. - On completion, show a concise success result and a way to clear/re-run it. ### 3. Build the tactile bullseye instrument - Use Compose Canvas (or an equivalent composable drawing layer) for a scalable circular vial, etched rings, crosshairs, target zone, and bubble. - Glass, fluid, and meniscus effects must improve depth/readability; avoid a decorative or excessively glossy treatment. - Bubble target position derives directly from stable calibrated pitch/roll. - Bubble movement uses a critically damped animation toward that real target: no random drift, autonomous wobble, or animation that contradicts the number. - Respect disabled system animations and the app's reduced-motion preference by minimizing or removing the display spring. - Show a large total tilt beside/below the vial, then Pitch and Roll below it. - At level lock, use the restrained lime state and an explicit text label. ### 4. Add actionable adjustment information - Derive a screen-relative high/low direction from calibrated Pitch and Roll. Use language such as `High: lower-left`; do not claim a compass direction. - Display slope as both degrees and a useful normalized rise/run value: millimetres per metre and/or inches per foot based on the selected unit system. - Treat exact board/counter dimensions and calculated shim/foot height as a later Adjustment Assist feature, not a requirement of this stage. - When the reading is moving, show a subtle `Settling` state and defer strong correction guidance until the stable measurement is trustworthy. ### 5. Add optional hands-free Audio Level Assist - Surface-only, off by default, explicitly user-enabled. - Use a soft sonar-like pulse with a gentle attack and naturally fading tail; never a harsh alarm or rapid smoke-detector cadence. - Silent while settling or materially outside the usable placement geometry. - Near level: occasional low-key proximity pulses. - Locked: one distinct soft lock ping; optionally provide a sparse repeat-while- locked preference so a user adjusting a large plank can hear that it remains level. - Reuse the existing lock dwell/hysteresis/debounce so sound cannot chatter. - Respect media volume, audio focus, system sound settings, app lifecycle, and the user's Audio Assist preference. ## Surface acceptance criteria - A stable phone on a known level plane achieves lock without repeated feedback. - A 180-degree calibration on a stable but non-level plane improves repeatability without zeroing that plane's real slope. - A screen-up phone at 30 and near 90 degrees still shows meaningful numbers; it does not falsely claim Surface lock. - Bubble direction agrees with Pitch/Roll and with the high/low instruction. - Bubble visual remains physically believable but never leads or disagrees with the stable numeric reading. - Audio can guide a user to lock without viewing the screen and stays quiet when disabled, settling, backgrounded, or outside the Surface geometry. - Manual checks cover phone-with-case, phone-without-case, a firm tabletop, and a large board adjusted by one person. ## Explicitly deferred - Angle-screen redesign and signed relative-angle semantics. - Edge/Plumb visual and geometry changes. - Saved measurements, target-angle alerts, screen ruler, and Play Billing. - Board dimension/shim calculator and automatic flat/edge switching. ## Questions for Claude's audit 1. Does the relaxed placement gate preserve truthful full-range Surface numbers while preventing false lock feedback? 2. Is the two-sample calibration flow mathematically and UX-wise safe for the stated use case, including phone cases and non-level calibration surfaces? 3. Is high/low mapping unambiguous and testable for all pitch/roll quadrants? 4. Does the bullseye animation remain derived from measurement truth and respect reduced-motion/system-animation settings? 5. Can the audio state machine reuse lock semantics without audio-focus, lifecycle, or repeated-feedback problems? 6. Is any proposed work outside this single-stage scope?