# Instrument Sheet Visual Redesign **Date:** 2026-04-04 **Status:** Approved for implementation ## Overview Redesign `layout_instruments_sheet.xml` and supporting code to replace the plain divider between the instrument grid and forecast section with an animated water-state canvas, enhance typography, add direction indicators, use imperial units, and prevent touch-through to the map. --- ## 1. Animated Wave Divider Canvas Replace the static `View` divider (and `FORECAST` section header) with a `WaveView` — a custom `View` subclass that draws an animated ocean scene. **Visual behaviour:** - Height: ~72dp - Top half gradient: surface background colour (`#1C1B1F`) → dark transitional blue (`#162433`) - Bottom half gradient: ocean blue (`#0B3050`) → ocean section background (`#0D2137`) - Primary sine wave: amplitude driven by **swell height (ft)**, wavelength proportional to **swell period (s)** - Secondary high-frequency sine: amplitude driven by **wind wave height (ft)**, wavelength ~35% of swell wavelength - Whitecaps: short curved strokes at wind-wave crests when amplitude exceeds threshold - Surface shimmer: thin semi-transparent cyan stroke along the wave waterline - Animated via `ValueAnimator` / `postInvalidateOnAnimation()` loop; paused when view is not visible **Data inputs** (passed from `InstrumentHandler`): - `swellHeightFt: Float` - `swellPeriodSec: Float` - `windWaveHeightFt: Float` **File:** `android-app/app/src/main/kotlin/org/terst/nav/ui/WaveView.kt` --- ## 2. Typography Enhancements **Instrument values (grid + depth/baro):** - Value: `26sp`, weight `300` (light), colour `#E6E1E5` - Unit label: `10sp`, weight `400`, colour `#79747E` — baseline-aligned, small gap after value **Heading/COG special case:** - The `°` symbol is part of the value string, not a separate unit label (e.g. `"247°"` rendered in the value style) **Forecast values (ocean section):** - Value: `22sp`, weight `300`, colour `#CAE8FF` - Unit: `10sp`, colour `#3B6785` **Forecast labels:** - `10sp`, weight `500`, letter-spacing `1.2sp`, colour `#5B9EC2`, uppercase --- ## 3. Direction Indicators A single reusable SVG-style drawable approach: a `DirectionArrowView` (custom `View`, ~14dp × 14dp) that draws: - Thin circle outline (stroke only, no fill) - Chevron arrow (notched polygon) pointing in the given bearing - Rotated via `bearing` property setter **Instrument section style:** outline `#3A3640`, arrow fill `#9A94A0` **Forecast section style:** outline `#1E4A6E`, arrow fill `#6FC3E8` Applied to: - AWS, TWS (wind speed cells) — bearing = apparent/true wind direction - HDG, COG (heading/course cells) — bearing = heading value itself - Current, Waves, Swell (forecast cells) — bearing from forecast data Cells without a direction (BSP, SOG, Depth, Baro) have no arrow. **File:** `android-app/app/src/main/kotlin/org/terst/nav/ui/DirectionArrowView.kt` --- ## 4. Forecast Cell Layout Each forecast cell (Current, Waves, Swell) is two lines: ``` CURRENT ← forecast-label style 0.8 kts ← value + unit baseline-aligned [arrow] 185° ← DirectionArrowView + bearing text ``` Swell adds period to the direction line: ``` [arrow] 260° · 14s ``` `"Wave"` → `"Waves"`, `"Curr"` → `"Current"`. No section header ("FORECAST" label removed). --- ## 5. Units: Feet Instead of Metres All heights from the data layer are in metres and must be converted before display (`* 3.28084`): - `DepthData.depthMeters` — converted in `InstrumentHandler.updateDisplay()` - `MarineConditions.waveHeightM` — converted in `InstrumentHandler.updateConditions()` - `MarineConditions.swellHeightM` — converted in `InstrumentHandler.updateConditions()` The `WaveView` data inputs (`swellHeightFt`, `windWaveHeightFt`) therefore receive already-converted values. --- ## 6. Remove Reports Section Remove from `layout_instruments_sheet.xml`: - `reports_divider` View - `label_reports` TextView - `reports_row` LinearLayout (containing `btn_nav_pretrip` and `btn_nav_tripreport`) Remove corresponding wiring from `MainActivity` / wherever the button click listeners are set up. --- ## 7. Prevent Map Touch-Through The bottom sheet currently sits inside a `CoordinatorLayout`. Touch events on the sheet's non-interactive areas fall through to the `MapFragment` below. **Fix:** Set `android:clickable="true"` and `android:focusable="true"` on the root `ConstraintLayout` of `layout_instruments_sheet.xml`. This consumes all touch events on the sheet, preventing drag gestures from reaching the map. --- ## 8. Colour Palette Summary | Token | Value | Use | |---|---|---| | Surface | `#1C1B1F` | Instrument section background | | Outline dim | `#2B2930` | Subtle dividers within instrument grid | | Value | `#E6E1E5` | Instrument values | | Label | `#CAC4D0` | Instrument labels | | Unit | `#79747E` | Instrument unit labels | | Arrow outline (sky) | `#3A3640` | Arrow circle border in instrument section | | Arrow fill (sky) | `#9A94A0` | Arrow chevron in instrument section | | Ocean bg | `#0D2137` | Forecast section background | | Ocean value | `#CAE8FF` | Forecast values | | Ocean label | `#5B9EC2` | Forecast labels | | Ocean unit | `#3B6785` | Forecast unit labels | | Ocean arrow outline | `#1E4A6E` | Arrow circle border in forecast section | | Ocean arrow fill | `#6FC3E8` | Arrow chevron in forecast section | | Bearing text | `#6FC3E8` | Bearing degrees in forecast section | | Period text | `#4A7FA0` | Swell period in forecast section | --- ## Files Changed | File | Change | |---|---| | `layout_instruments_sheet.xml` | Major restructure: wave canvas, cell layout changes, remove reports | | `WaveView.kt` | New custom View | | `DirectionArrowView.kt` | New custom View | | `InstrumentHandler.kt` | Add `updateWave()`, `updateDirections()`, feet conversion for depth | | `MainActivity.kt` | Remove report button wiring | | `styles.xml` / `themes.xml` | Add/update `InstrumentLabel`, `InstrumentPrimaryValue` styles if needed |