summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/res
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-04-23 23:10:11 +0000
committerClaude <noreply@anthropic.com>2026-04-23 23:10:11 +0000
commite1db9200e9d44c10450361cc8984a45b2eda87b7 (patch)
tree21bdfca02491e6ff4cde7a22673c821c0a03e108 /android-app/app/src/main/res
parent55509f579b4d074f01237dd90791b6d25aaec3cd (diff)
parenteb78d317c722234a7ef2c501c68c9aa730ec2758 (diff)
Merge origin/main — unite all work onto one branch
Brings in dev log (NavLogger), UnitPrefs, MapLayerManager, HUD views, conditions throttling, track save/load pipeline, improved ParticleWindView (antimeridian-aware, dynamic particle count), Snackbar error surfacing, and all other main-branch work from the prior session. Combined with master's hardware source flags, vessel registry, crew management, thermal alarm, CPA collision alerts, and track stats. Also documents primary branch policy in CLAUDE.md and .agent/config.md: all work merges to main, never master. https://claude.ai/code/session_011h2dXbgXg3PesQMmQUNTCW
Diffstat (limited to 'android-app/app/src/main/res')
-rw-r--r--android-app/app/src/main/res/drawable/ic_calendar.xml44
-rw-r--r--android-app/app/src/main/res/drawable/ic_crosshair.xml28
-rw-r--r--android-app/app/src/main/res/drawable/ic_layers.xml9
-rw-r--r--android-app/app/src/main/res/drawable/ic_learn.xml9
-rw-r--r--android-app/app/src/main/res/drawable/ic_open_in_new.xml30
-rw-r--r--android-app/app/src/main/res/layout/activity_main.xml169
-rw-r--r--android-app/app/src/main/res/layout/fragment_learn.xml205
-rw-r--r--android-app/app/src/main/res/layout/fragment_pretrip_report.xml324
-rw-r--r--android-app/app/src/main/res/layout/fragment_safety.xml20
-rw-r--r--android-app/app/src/main/res/layout/fragment_trip_report.xml114
-rw-r--r--android-app/app/src/main/res/layout/fragment_voice_log.xml150
-rw-r--r--android-app/app/src/main/res/layout/item_condition_column.xml44
-rw-r--r--android-app/app/src/main/res/layout/layout_instruments_sheet.xml375
-rw-r--r--android-app/app/src/main/res/layout/layout_layer_picker_sheet.xml310
-rw-r--r--android-app/app/src/main/res/layout/layout_nav_hud.xml164
-rw-r--r--android-app/app/src/main/res/layout/layout_track_summary_sheet.xml199
-rw-r--r--android-app/app/src/main/res/layout/sheet_dev_log.xml74
-rw-r--r--android-app/app/src/main/res/menu/bottom_nav_menu.xml10
-rw-r--r--android-app/app/src/main/res/values-night/colors.xml40
-rwxr-xr-xandroid-app/app/src/main/res/values/colors.xml42
-rwxr-xr-xandroid-app/app/src/main/res/values/dimens.xml10
-rwxr-xr-xandroid-app/app/src/main/res/values/themes.xml81
22 files changed, 2223 insertions, 228 deletions
diff --git a/android-app/app/src/main/res/drawable/ic_calendar.xml b/android-app/app/src/main/res/drawable/ic_calendar.xml
new file mode 100644
index 0000000..dd8030c
--- /dev/null
+++ b/android-app/app/src/main/res/drawable/ic_calendar.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <!-- Calendar outline -->
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M19,4H5C3.895,4 3,4.895 3,6v14c0,1.105 0.895,2 2,2h14c1.105,0 2,-0.895 2,-2V6C21,4.895 20.105,4 19,4z" />
+ <!-- Header bar -->
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:pathData="M3,10h18" />
+ <!-- Hanger lines -->
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:pathData="M8,2v4M16,2v4" />
+ <!-- Day dots (3 representative) -->
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M8,14m-1,0a1,1 0,1,0 2,0a1,1 0,1,0 -2,0" />
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,14m-1,0a1,1 0,1,0 2,0a1,1 0,1,0 -2,0" />
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M16,14m-1,0a1,1 0,1,0 2,0a1,1 0,1,0 -2,0" />
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M8,18m-1,0a1,1 0,1,0 2,0a1,1 0,1,0 -2,0" />
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,18m-1,0a1,1 0,1,0 2,0a1,1 0,1,0 -2,0" />
+</vector>
diff --git a/android-app/app/src/main/res/drawable/ic_crosshair.xml b/android-app/app/src/main/res/drawable/ic_crosshair.xml
new file mode 100644
index 0000000..609538e
--- /dev/null
+++ b/android-app/app/src/main/res/drawable/ic_crosshair.xml
@@ -0,0 +1,28 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+
+ <!-- Horizontal line -->
+ <path
+ android:pathData="M2,16 L13,16 M19,16 L30,16"
+ android:strokeColor="#CCFFFFFF"
+ android:strokeWidth="1.5"
+ android:strokeLineCap="round" />
+
+ <!-- Vertical line -->
+ <path
+ android:pathData="M16,2 L16,13 M16,19 L16,30"
+ android:strokeColor="#CCFFFFFF"
+ android:strokeWidth="1.5"
+ android:strokeLineCap="round" />
+
+ <!-- Center circle -->
+ <path
+ android:pathData="M16,16 m-2.5,0 a2.5,2.5 0 1,0 5,0 a2.5,2.5 0 1,0 -5,0"
+ android:strokeColor="#CCFFFFFF"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000" />
+
+</vector>
diff --git a/android-app/app/src/main/res/drawable/ic_layers.xml b/android-app/app/src/main/res/drawable/ic_layers.xml
new file mode 100644
index 0000000..f86f83a
--- /dev/null
+++ b/android-app/app/src/main/res/drawable/ic_layers.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?attr/colorOnSurface"
+ android:pathData="M11.99,18.54L4.62,12.81 3,14.07l9,7 9,-7-1.63,-1.27-8.38,5.74zM12,16l8.36,-6.54L22,8.07l-10,-7-10,7 1.63,1.39L12,16z"/>
+</vector>
diff --git a/android-app/app/src/main/res/drawable/ic_learn.xml b/android-app/app/src/main/res/drawable/ic_learn.xml
new file mode 100644
index 0000000..1574693
--- /dev/null
+++ b/android-app/app/src/main/res/drawable/ic_learn.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,3L1,9l11,6 9-4.91V17h2V9L12,3zM5,13.18v4L12,21l7-3.82v-4L12,17l-7-3.82z"/>
+</vector>
diff --git a/android-app/app/src/main/res/drawable/ic_open_in_new.xml b/android-app/app/src/main/res/drawable/ic_open_in_new.xml
new file mode 100644
index 0000000..4645522
--- /dev/null
+++ b/android-app/app/src/main/res/drawable/ic_open_in_new.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="18dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <!-- Box outline with open top-right corner -->
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M18,13v6a2,2 0,0 1,-2,2H5a2,2 0,0 1,-2,-2V8a2,2 0,0 1,2,-2h6" />
+ <!-- Arrow pointing top-right -->
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M15,3h6v6" />
+ <path
+ android:fillColor="@android:color/transparent"
+ android:strokeColor="#FF000000"
+ android:strokeWidth="2"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M10,14L21,3" />
+</vector>
diff --git a/android-app/app/src/main/res/layout/activity_main.xml b/android-app/app/src/main/res/layout/activity_main.xml
index a99a8cb..4150b2e 100644
--- a/android-app/app/src/main/res/layout/activity_main.xml
+++ b/android-app/app/src/main/res/layout/activity_main.xml
@@ -1,36 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:orientation="vertical"
tools:context=".MainActivity">
- <!-- Main Content Area -->
- <androidx.constraintlayout.widget.ConstraintLayout
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginBottom="56dp"> <!-- Space for BottomNav -->
+ android:layout_height="0dp"
+ android:layout_weight="1">
- <org.maplibre.android.maps.MapView
- android:id="@+id/mapView"
+ <!-- Main Content Area -->
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent">
- <org.terst.nav.ui.map.ParticleWindView
- android:id="@+id/particle_wind_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clickable="false"
- android:focusable="false" />
+ <org.maplibre.android.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <org.terst.nav.ui.map.ParticleWindView
+ android:id="@+id/particle_wind_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clickable="false"
+ android:focusable="false" />
+
+ <!-- Boat-instrument HUD strip — always on top of map -->
+ <include
+ android:id="@+id/nav_hud"
+ layout="@layout/layout_nav_hud"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ <!-- Crosshair — visible when not following (panning) -->
+ <ImageView
+ android:id="@+id/map_crosshair"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:src="@drawable/ic_crosshair"
+ android:visibility="gone"
+ android:clickable="false"
+ android:focusable="false"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ <!-- Overlay Fragment Container (for Log, Safety, Help) -->
+ <FrameLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:clickable="true"
+ android:focusable="true"
+ android:background="?attr/colorSurface" />
- <!-- Overlay Fragment Container (for Log, Safety, Help) -->
- <FrameLayout
- android:id="@+id/fragment_container"
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/fab_recenter"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:text="⊙ Recenter"
+ android:textSize="13sp"
+ android:paddingStart="20dp"
+ android:paddingEnd="20dp"
+ android:visibility="gone"
+ app:cornerRadius="20dp"
+ app:elevation="20dp"
+ app:layout_constraintTop_toBottomOf="@id/nav_hud"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ android:layout_marginTop="8dp" />
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <!-- Collapsible Instrument Bottom Sheet -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/instrument_bottom_sheet"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- android:background="?attr/colorSurface" />
+ android:layout_height="wrap_content"
+ app:behavior_hideable="false"
+ app:behavior_peekHeight="120dp"
+ app:cardElevation="16dp"
+ app:shapeAppearance="@style/ShapeAppearance.Nav.BottomSheet"
+ app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
+
+ <include
+ layout="@layout/layout_instruments_sheet"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </com.google.android.material.card.MaterialCardView>
<!-- Track stats bar — shown only while recording -->
<TextView
@@ -51,60 +118,28 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <!-- Collapsible Instrument Bottom Sheet -->
- <androidx.cardview.widget.CardView
- android:id="@+id/instrument_bottom_sheet"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:behavior_hideable="false"
- app:behavior_peekHeight="120dp"
- app:cardElevation="16dp"
- app:cardCornerRadius="24dp"
- app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
-
- <include
- layout="@layout/layout_instruments_sheet"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ <!-- Record Track Button -->
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab_record_track"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="16dp"
+ android:clickable="true"
+ android:focusable="true"
+ android:contentDescription="Record Track"
+ app:srcCompat="@drawable/ic_track_record"
+ app:elevation="20dp"
+ app:layout_anchor="@id/instrument_bottom_sheet"
+ app:layout_anchorGravity="top|end" />
- </androidx.cardview.widget.CardView>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- Bottom Navigation -->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="bottom"
android:background="?attr/colorSurface"
app:menu="@menu/bottom_nav_menu" />
- <!-- Persistent MOB Button (Crucial for safety, always on top) -->
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/fab_mob"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="16dp"
- android:clickable="true"
- android:focusable="true"
- android:contentDescription="Man Overboard"
- app:srcCompat="@android:drawable/ic_dialog_alert"
- app:backgroundTint="@color/mob_button_background"
- app:layout_anchor="@id/instrument_bottom_sheet"
- app:layout_anchorGravity="top|start" />
-
- <!-- Record Track Button -->
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/fab_record_track"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="16dp"
- android:clickable="true"
- android:focusable="true"
- android:contentDescription="Record Track"
- app:srcCompat="@drawable/ic_track_record"
- app:layout_anchor="@id/instrument_bottom_sheet"
- app:layout_anchorGravity="top|end" />
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+</LinearLayout>
diff --git a/android-app/app/src/main/res/layout/fragment_learn.xml b/android-app/app/src/main/res/layout/fragment_learn.xml
new file mode 100644
index 0000000..fa18c5d
--- /dev/null
+++ b/android-app/app/src/main/res/layout/fragment_learn.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/colorSurface">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="24dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Learn"
+ android:textSize="24sp"
+ android:textStyle="bold"
+ android:textColor="?attr/colorOnSurface"
+ android:layout_marginBottom="24dp" />
+
+ <!-- ── Migration Guides ─────────────────────────────────────── -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="MIGRATION GUIDES"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_migrate_navionics"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dp"
+ app:cardCornerRadius="12dp"
+ app:cardElevation="2dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center_vertical">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Migrating from Navionics"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="›"
+ android:textSize="20sp"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_migrate_seapeople"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="24dp"
+ app:cardCornerRadius="12dp"
+ app:cardElevation="2dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center_vertical">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Migrating from Sea People"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="›"
+ android:textSize="20sp"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Reference (offline) ──────────────────────────────────── -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="REFERENCE"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_colregs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dp"
+ app:cardCornerRadius="12dp"
+ app:cardElevation="2dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center_vertical">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ColRegs — Rules of the Road"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="International collision regulations, rules 1–38"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="›"
+ android:textSize="20sp"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_sailing_reference"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dp"
+ app:cardCornerRadius="12dp"
+ app:cardElevation="2dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center_vertical">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Sailing Quick Reference"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Points of sail, lights &amp; shapes, knots"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="›"
+ android:textSize="20sp"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ </LinearLayout>
+</ScrollView>
diff --git a/android-app/app/src/main/res/layout/fragment_pretrip_report.xml b/android-app/app/src/main/res/layout/fragment_pretrip_report.xml
new file mode 100644
index 0000000..8cb094a
--- /dev/null
+++ b/android-app/app/src/main/res/layout/fragment_pretrip_report.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/colorSurface">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <!-- ── Title ──────────────────────────────────────────────── -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Departure Briefing"
+ android:textAppearance="?attr/textAppearanceHeadlineSmall"
+ android:layout_marginBottom="16dp" />
+
+ <!-- ── Boat selector ──────────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="VESSEL"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_boats"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Departure time picker ──────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_departure"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="16dp"
+ android:gravity="center_vertical">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="DEPART"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="4dp" />
+
+ <TextView
+ android:id="@+id/tv_departure_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Now"
+ android:textAppearance="?attr/textAppearanceTitleMedium" />
+
+ </LinearLayout>
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_pick_departure"
+ style="@style/Widget.Material3.Button.IconButton.Outlined"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="Pick departure date and time"
+ app:icon="@drawable/ic_calendar" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Generate button + progress ─────────────────────────── -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="16dp">
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_generate_pretrip"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Refresh Briefing" />
+
+ <ProgressBar
+ android:id="@+id/progress_pretrip"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_marginStart="12dp"
+ android:visibility="gone" />
+ </LinearLayout>
+
+ <!-- ── Conditions window ───────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_conditions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:visibility="gone"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="CONDITIONS WINDOW"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="12dp" />
+
+ <!-- 4-column table built programmatically -->
+ <LinearLayout
+ android:id="@+id/conditions_table"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Route projection ────────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_route"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:visibility="gone"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ROUTE PROJECTION"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <TextView
+ android:id="@+id/tv_route"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceBodyMedium"
+ android:lineSpacingMultiplier="1.3" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Sail plan ───────────────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_sail_plan"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:visibility="gone"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SAIL PLAN"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <TextView
+ android:id="@+id/tv_sail_plan"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceBodyMedium"
+ android:lineSpacingMultiplier="1.4" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Watch list ──────────────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_watchlist"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:visibility="gone"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp"
+ app:strokeColor="?attr/colorError"
+ app:strokeWidth="1dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="WATCH FOR"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <TextView
+ android:id="@+id/tv_watchlist"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceBodyMedium"
+ android:lineSpacingMultiplier="1.5" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Similar trips ───────────────────────────────────────── -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_similar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:visibility="gone"
+ app:cardElevation="2dp"
+ app:cardCornerRadius="12dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SIMILAR TRIPS"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="8dp" />
+
+ <TextView
+ android:id="@+id/tv_similar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceBodyMedium"
+ android:lineSpacingMultiplier="1.3" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <!-- ── Error state ─────────────────────────────────────────── -->
+ <TextView
+ android:id="@+id/tv_error"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:textColor="?attr/colorError"
+ android:textAppearance="?attr/textAppearanceBodyMedium" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/android-app/app/src/main/res/layout/fragment_safety.xml b/android-app/app/src/main/res/layout/fragment_safety.xml
index 806598e..1072abe 100644
--- a/android-app/app/src/main/res/layout/fragment_safety.xml
+++ b/android-app/app/src/main/res/layout/fragment_safety.xml
@@ -246,4 +246,24 @@
</com.google.android.material.card.MaterialCardView>
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/button_plan_trip"
+ style="@style/Widget.Material3.Button.TonalButton"
+ android:layout_width="match_parent"
+ android:layout_height="60dp"
+ android:layout_marginTop="24dp"
+ android:text="PLAN TRIP (PRE-TRIP REPORT)"
+ app:layout_constraintTop_toBottomOf="@id/card_data_sources" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/button_quit"
+ style="@style/Widget.Material3.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Quit"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ app:icon="@drawable/ic_close"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/android-app/app/src/main/res/layout/fragment_trip_report.xml b/android-app/app/src/main/res/layout/fragment_trip_report.xml
new file mode 100644
index 0000000..1ce0bde
--- /dev/null
+++ b/android-app/app/src/main/res/layout/fragment_trip_report.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/colorSurface">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="24dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Trip Narrative"
+ android:textSize="24sp"
+ android:textStyle="bold"
+ android:layout_marginBottom="16dp" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Choose Narrative Style:"
+ android:textSize="14sp"
+ android:layout_marginBottom="8dp" />
+
+ <HorizontalScrollView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="24dp">
+
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_styles"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_professional"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Professional"
+ android:checked="true" />
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_adventurous"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Adventurous" />
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_journal"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Journal" />
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_pirate"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Pirate" />
+
+ </com.google.android.material.chip.ChipGroup>
+ </HorizontalScrollView>
+
+ <com.google.android.material.card.MaterialCardView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:cardCornerRadius="16dp"
+ app:cardElevation="4dp"
+ app:strokeWidth="1dp"
+ app:strokeColor="?attr/colorOutlineVariant">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/tv_narrative_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Generate a report to see your story..."
+ android:textSize="16sp"
+ android:lineSpacingExtra="4dp" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_refresh_report"
+ android:layout_width="match_parent"
+ android:layout_height="60dp"
+ android:layout_marginTop="24dp"
+ android:text="REFRESH REPORT" />
+
+ <ProgressBar
+ android:id="@+id/progress_report"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginTop="16dp"
+ android:visibility="gone" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/android-app/app/src/main/res/layout/fragment_voice_log.xml b/android-app/app/src/main/res/layout/fragment_voice_log.xml
index e5f864c..c1275a6 100644
--- a/android-app/app/src/main/res/layout/fragment_voice_log.xml
+++ b/android-app/app/src/main/res/layout/fragment_voice_log.xml
@@ -1,66 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:gravity="center"
- android:padding="24dp">
+ android:padding="20dp">
<TextView
- android:id="@+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Tap microphone to log"
- android:textSize="18sp"
- android:textAlignment="center"
+ android:text="Log Entry"
+ android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:layout_marginBottom="16dp" />
- <TextView
- android:id="@+id/tv_recognized"
+ <!-- Note text — voice fills this; user can also type directly -->
+ <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text=""
- android:textSize="16sp"
- android:textAlignment="center"
- android:padding="12dp"
- android:minHeight="80dp"
- android:background="#F5F5F5"
- android:layout_marginBottom="24dp" />
+ android:layout_marginBottom="12dp"
+ style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/et_note"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minLines="3"
+ android:maxLines="6"
+ android:gravity="top"
+ android:hint="Tap mic or type a note…"
+ android:inputType="textMultiLine|textCapSentences"
+ android:scrollbars="vertical" />
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <!-- Action row: mic, camera, gallery, status -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="12dp">
+
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab_mic"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:fabSize="mini"
+ android:src="@android:drawable/ic_btn_speak_now"
+ android:contentDescription="Start voice recognition"
+ android:layout_marginEnd="12dp" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_camera"
+ style="@style/Widget.Material3.Button.IconButton.Outlined"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="Take photo"
+ app:icon="@android:drawable/ic_menu_camera"
+ android:layout_marginEnd="8dp" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_gallery"
+ style="@style/Widget.Material3.Button.IconButton.Outlined"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="Attach photo from gallery"
+ app:icon="@android:drawable/ic_menu_gallery"
+ android:layout_marginEnd="12dp" />
+
+ <TextView
+ android:id="@+id/tv_status"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text=""
+ android:textSize="14sp"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ </LinearLayout>
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/fab_mic"
+ <!-- Photo thumbnail — hidden until a photo is attached -->
+ <FrameLayout
+ android:id="@+id/frame_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="Start voice recognition"
- android:src="@android:drawable/ic_btn_speak_now"
- android:layout_marginBottom="16dp" />
+ android:layout_marginBottom="12dp"
+ android:visibility="gone">
+
+ <ImageView
+ android:id="@+id/iv_photo"
+ android:layout_width="120dp"
+ android:layout_height="90dp"
+ android:scaleType="centerCrop"
+ android:contentDescription="Attached photo" />
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_remove_photo"
+ style="@style/Widget.Material3.Button.IconButton"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_gravity="top|end"
+ android:contentDescription="Remove photo"
+ app:icon="@drawable/ic_close" />
+
+ </FrameLayout>
+
+ <!-- Save / Clear row -->
<LinearLayout
- android:id="@+id/ll_confirm_buttons"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:visibility="gone">
+ android:gravity="center_vertical"
+ android:layout_marginBottom="12dp">
- <Button
+ <com.google.android.material.button.MaterialButton
android:id="@+id/btn_save"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:text="Save"
android:layout_marginEnd="8dp" />
- <Button
- android:id="@+id/btn_retry"
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_clear"
+ style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Retry" />
+ android:text="Clear" />
+
</LinearLayout>
+ <!-- Saved confirmation -->
<TextView
android:id="@+id/tv_saved_confirmation"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textSize="14sp"
- android:layout_marginTop="16dp" />
+ android:textColor="?attr/colorPrimary"
+ android:layout_marginBottom="24dp" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?attr/colorOutline"
+ android:layout_marginBottom="24dp" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_generate_report"
+ style="@style/Widget.Material3.Button.TonalButton"
+ android:layout_width="match_parent"
+ android:layout_height="60dp"
+ android:text="GENERATE TRIP REPORT" />
+
</LinearLayout>
diff --git a/android-app/app/src/main/res/layout/item_condition_column.xml b/android-app/app/src/main/res/layout/item_condition_column.xml
new file mode 100644
index 0000000..1ffcd55
--- /dev/null
+++ b/android-app/app/src/main/res/layout/item_condition_column.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:padding="4dp">
+
+ <TextView
+ android:id="@+id/col_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="10sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.08"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="4dp" />
+
+ <TextView
+ android:id="@+id/col_wind"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceTitleMedium"
+ android:layout_marginBottom="2dp" />
+
+ <TextView
+ android:id="@+id/col_wind_dir"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?attr/textAppearanceBodySmall"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginBottom="4dp" />
+
+ <TextView
+ android:id="@+id/col_sky"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="10sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:gravity="center" />
+
+</LinearLayout>
diff --git a/android-app/app/src/main/res/layout/layout_instruments_sheet.xml b/android-app/app/src/main/res/layout/layout_instruments_sheet.xml
index 0a84418..aa785e6 100644
--- a/android-app/app/src/main/res/layout/layout_instruments_sheet.xml
+++ b/android-app/app/src/main/res/layout/layout_instruments_sheet.xml
@@ -1,166 +1,343 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="16dp"
- android:background="?attr/colorSurface">
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:paddingBottom="16dp"
+ android:background="?attr/colorSurface"
+ android:clickable="true"
+ android:focusable="true">
+ <!-- Drag handle -->
<View
android:id="@+id/drag_handle"
- android:layout_width="40dp"
+ android:layout_width="36dp"
android:layout_height="4dp"
+ android:layout_marginTop="12dp"
android:background="@color/md_theme_outline"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
- <!-- Grid of Instruments -->
- <androidx.gridlayout.widget.GridLayout
- android:id="@+id/instrument_grid"
+ <!--
+ Area-conditions header row: Wind (kts + arrow) | Temp (°C) | Baro (hPa)
+ Always shows conditions for the current map center.
+ -->
+ <LinearLayout
+ android:id="@+id/conditions_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- app:columnCount="3"
- app:rowCount="3"
- app:layout_constraintTop_toBottomOf="@id/drag_handle">
+ android:orientation="horizontal"
+ android:layout_marginTop="12dp"
+ app:layout_constraintTop_toBottomOf="@id/drag_handle"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
- <!-- Wind: AWS -->
+ <!-- Wind -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="AWS" />
- <TextView android:id="@+id/value_aws" style="@style/InstrumentPrimaryValue" tools:text="12.5" />
+ <TextView style="@style/InstrumentLabel" android:text="Wind" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_tws"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="15.5" />
+ <TextView android:id="@+id/unit_tws" style="@style/InstrumentUnit" android:text="kt" />
+ <org.terst.nav.ui.DirectionArrowView
+ android:id="@+id/arrow_tws"
+ android:layout_width="14dp"
+ android:layout_height="14dp"
+ android:layout_marginStart="3dp"
+ android:layout_marginBottom="3dp"
+ android:layout_gravity="bottom" />
+ <ProgressBar
+ android:id="@+id/spinner_tws"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="?attr/colorOnSurfaceVariant"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
+ <TextView
+ android:id="@+id/bearing_tws"
+ style="@style/InstrumentLabel"
+ tools:text="270°" />
</LinearLayout>
- <!-- Compass: HDG -->
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_columnWeight="1"
- android:orientation="vertical"
- android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="HDG" />
- <TextView android:id="@+id/value_hdg" style="@style/InstrumentPrimaryValue" tools:text="225" />
- </LinearLayout>
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@color/md_theme_outline" />
- <!-- Performance: BSP -->
+ <!-- Temp -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="BSP" />
- <TextView android:id="@+id/value_bsp" style="@style/InstrumentPrimaryValue" tools:text="6.2" />
+ <TextView style="@style/InstrumentLabel" android:text="Temp" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_temp"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="18" />
+ <TextView android:id="@+id/unit_temp" style="@style/InstrumentUnit" android:text="°F" />
+ <ProgressBar
+ android:id="@+id/spinner_temp"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="?attr/colorOnSurfaceVariant"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
</LinearLayout>
- <!-- Wind: TWS -->
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_columnWeight="1"
- android:orientation="vertical"
- android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="TWS" />
- <TextView android:id="@+id/value_tws" style="@style/InstrumentPrimaryValue" tools:text="15.0" />
- </LinearLayout>
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@color/md_theme_outline" />
- <!-- Compass: COG -->
+ <!-- Baro -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="COG" />
- <TextView android:id="@+id/value_cog" style="@style/InstrumentPrimaryValue" tools:text="230" />
+ <TextView style="@style/InstrumentLabel" android:text="Baro" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_baro"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="1013" />
+ <TextView android:id="@+id/unit_baro" style="@style/InstrumentUnit" android:text="hPa" />
+ <ProgressBar
+ android:id="@+id/spinner_baro"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="?attr/colorOnSurfaceVariant"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
</LinearLayout>
- <!-- Performance: SOG -->
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- app:layout_columnWeight="1"
- android:orientation="vertical"
- android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="SOG" />
- <TextView android:id="@+id/value_sog" style="@style/InstrumentPrimaryValue" tools:text="6.5" />
- </LinearLayout>
+ </LinearLayout>
+
+ <!-- Animated wave divider — colors adapt via wave_sky/sea color resources -->
+ <org.terst.nav.ui.WaveView
+ android:id="@+id/wave_divider"
+ android:layout_width="match_parent"
+ android:layout_height="72dp"
+ android:layout_marginStart="-16dp"
+ android:layout_marginEnd="-16dp"
+ app:layout_constraintTop_toBottomOf="@id/conditions_header"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
- <!-- VMG -->
+ <!-- Forecast section (ocean — intentionally always dark, do not invert) -->
+ <LinearLayout
+ android:id="@+id/forecast_row"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:forceDarkAllowed="false"
+ android:background="#0D2137"
+ android:paddingTop="14dp"
+ android:paddingBottom="20dp"
+ android:layout_marginStart="-16dp"
+ android:layout_marginEnd="-16dp"
+ app:layout_constraintTop_toBottomOf="@id/wave_divider"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent">
+
+ <!-- Current -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="VMG" />
- <TextView android:id="@+id/value_vmg" style="@style/InstrumentPrimaryValue" tools:text="4.2" />
+ android:padding="4dp">
+ <TextView style="@style/ForecastLabel" android:text="Current" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_curr_spd"
+ style="@style/ForecastValue"
+ tools:text="0.8" />
+ <TextView android:id="@+id/unit_curr_spd" style="@style/ForecastUnit" android:text="kt" />
+ <ProgressBar
+ android:id="@+id/spinner_curr"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="#5B9EC2"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginTop="4dp">
+ <org.terst.nav.ui.DirectionArrowView
+ android:id="@+id/arrow_curr"
+ android:layout_width="14dp"
+ android:layout_height="14dp" />
+ <TextView
+ android:id="@+id/bearing_curr"
+ style="@style/ForecastBearing"
+ tools:text="185°" />
+ </LinearLayout>
</LinearLayout>
- <!-- Depth -->
+ <!-- Waves -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="Depth" />
- <TextView android:id="@+id/value_depth" style="@style/InstrumentPrimaryValue" tools:text="12.0" />
+ android:padding="4dp">
+ <TextView style="@style/ForecastLabel" android:text="Waves" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_wave_ht"
+ style="@style/ForecastValue"
+ tools:text="3.5" />
+ <TextView android:id="@+id/unit_wave_ht" style="@style/ForecastUnit" android:text="ft" />
+ <ProgressBar
+ android:id="@+id/spinner_waves"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="#5B9EC2"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginTop="4dp">
+ <org.terst.nav.ui.DirectionArrowView
+ android:id="@+id/arrow_waves"
+ android:layout_width="14dp"
+ android:layout_height="14dp" />
+ <TextView
+ android:id="@+id/bearing_waves"
+ style="@style/ForecastBearing"
+ tools:text="275°" />
+ </LinearLayout>
</LinearLayout>
- <!-- Polar % -->
+ <!-- Swell -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_columnWeight="1"
+ android:layout_weight="1"
android:orientation="vertical"
android:gravity="center"
- android:padding="8dp">
- <TextView style="@style/InstrumentLabel" android:text="Polar %" />
- <TextView android:id="@+id/value_polar_pct" style="@style/InstrumentPrimaryValue" tools:text="95%" />
+ android:padding="4dp">
+ <TextView style="@style/ForecastLabel" android:text="Swell" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/value_swell_ht"
+ style="@style/ForecastValue"
+ tools:text="5.2" />
+ <TextView android:id="@+id/unit_swell_ht" style="@style/ForecastUnit" android:text="ft" />
+ <ProgressBar
+ android:id="@+id/spinner_swell"
+ style="?android:attr/progressBarStyleSmall"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:indeterminate="true"
+ android:visibility="invisible"
+ android:alpha="0.5"
+ android:indeterminateTint="#5B9EC2"
+ android:layout_marginStart="4dp" />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginTop="4dp">
+ <org.terst.nav.ui.DirectionArrowView
+ android:id="@+id/arrow_swell"
+ android:layout_width="14dp"
+ android:layout_height="14dp" />
+ <TextView
+ android:id="@+id/bearing_swell"
+ style="@style/ForecastBearing"
+ tools:text="260°" />
+ <TextView
+ android:id="@+id/value_swell_per"
+ style="@style/ForecastPeriod"
+ tools:text="· 14s" />
+ </LinearLayout>
</LinearLayout>
- </androidx.gridlayout.widget.GridLayout>
-
- <!-- Additional Detail (Visible when expanded) -->
- <TextView
- android:id="@+id/label_baro"
- style="@style/InstrumentLabel"
- android:text="Barometer"
- android:layout_marginTop="24dp"
- app:layout_constraintTop_toBottomOf="@id/instrument_grid"
- app:layout_constraintStart_toStartOf="parent" />
-
- <TextView
- android:id="@+id/value_baro"
- style="@style/InstrumentPrimaryValue"
- tools:text="1013.2 hPa"
- app:layout_constraintTop_toBottomOf="@id/label_baro"
- app:layout_constraintStart_toStartOf="parent" />
-
- <org.terst.nav.PolarDiagramView
- android:id="@+id/polar_diagram_view"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="24dp"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toBottomOf="@id/value_baro"
- app:layout_constraintBottom_toBottomOf="parent" />
+ </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/android-app/app/src/main/res/layout/layout_layer_picker_sheet.xml b/android-app/app/src/main/res/layout/layout_layer_picker_sheet.xml
new file mode 100644
index 0000000..fdfbb7a
--- /dev/null
+++ b/android-app/app/src/main/res/layout/layout_layer_picker_sheet.xml
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/colorSurface">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
+ android:paddingBottom="40dp">
+
+ <View
+ android:layout_width="36dp"
+ android:layout_height="4dp"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="20dp"
+ android:background="@color/md_theme_outline" />
+
+ <!-- ── MAP LAYERS ──────────────────────────────────────────── -->
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:text="MAP LAYERS"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:fontFamily="sans-serif-light"
+ android:textColor="@color/instrument_text_secondary" />
+
+ <!-- Base map selection -->
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_base"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="20dp"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_satellite"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Satellite" />
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_charts"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Charts" />
+
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_hybrid"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hybrid" />
+
+ </com.google.android.material.chip.ChipGroup>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="16dp"
+ android:background="@color/md_theme_surfaceVariant" />
+
+ <!-- Wind overlay toggle -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="12dp">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Wind overlay"
+ android:textSize="15sp"
+ android:textColor="@color/instrument_text_normal" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Wind speed colour map"
+ android:textSize="12sp"
+ android:textColor="@color/instrument_text_secondary" />
+ </LinearLayout>
+
+ <com.google.android.material.switchmaterial.SwitchMaterial
+ android:id="@+id/switch_wind"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+ <!-- Wind particles toggle -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="8dp">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Wind particles"
+ android:textSize="15sp"
+ android:textColor="@color/instrument_text_normal" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Animated particle overlay"
+ android:textSize="12sp"
+ android:textColor="@color/instrument_text_secondary" />
+ </LinearLayout>
+
+ <com.google.android.material.switchmaterial.SwitchMaterial
+ android:id="@+id/switch_particles"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+ <!-- ── UNITS ───────────────────────────────────────────────── -->
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="16dp"
+ android:background="@color/md_theme_surfaceVariant" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:text="UNITS"
+ android:textSize="11sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:fontFamily="sans-serif-light"
+ android:textColor="@color/instrument_text_secondary" />
+
+ <!-- Temperature -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="10dp">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Temperature"
+ android:textSize="14sp"
+ android:textColor="@color/instrument_text_normal" />
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_temp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_fahrenheit"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="°F" />
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_celsius"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="°C" />
+ </com.google.android.material.chip.ChipGroup>
+ </LinearLayout>
+
+ <!-- Depth / height -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="10dp">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Depth / height"
+ android:textSize="14sp"
+ android:textColor="@color/instrument_text_normal" />
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_depth"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_feet"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ft" />
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_meters"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="m" />
+ </com.google.android.material.chip.ChipGroup>
+ </LinearLayout>
+
+ <!-- Pressure -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginBottom="10dp">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Pressure"
+ android:textSize="14sp"
+ android:textColor="@color/instrument_text_normal" />
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_pressure"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_hpa"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="hPa" />
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_inhg"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="inHg" />
+ </com.google.android.material.chip.ChipGroup>
+ </LinearLayout>
+
+ <!-- Speed -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Speed"
+ android:textSize="14sp"
+ android:textColor="@color/instrument_text_normal" />
+ <com.google.android.material.chip.ChipGroup
+ android:id="@+id/chip_group_speed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:singleSelection="true"
+ app:selectionRequired="true">
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_knots"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="kt" />
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_mph"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="mph" />
+ <com.google.android.material.chip.Chip
+ android:id="@+id/chip_kph"
+ style="@style/Widget.Material3.Chip.Filter"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="kph" />
+ </com.google.android.material.chip.ChipGroup>
+ </LinearLayout>
+
+ </LinearLayout>
+</ScrollView>
diff --git a/android-app/app/src/main/res/layout/layout_nav_hud.xml b/android-app/app/src/main/res/layout/layout_nav_hud.xml
new file mode 100644
index 0000000..90119fa
--- /dev/null
+++ b/android-app/app/src/main/res/layout/layout_nav_hud.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Persistent boat-instrument HUD strip.
+ Lives at the top of the map; always visible; shows dashes when NMEA unavailable.
+ Fields: SOG | COG | BSP | Depth
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:orientation="horizontal"
+ android:background="#CC000000">
+
+ <!-- SOG -->
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="SOG"
+ android:textSize="9sp"
+ android:textColor="#99FFFFFF"
+ android:letterSpacing="0.08" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/hud_sog"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textColor="#FFFFFF"
+ android:fontFamily="sans-serif-medium"
+ tools:text="7.1" />
+ <TextView
+ android:id="@+id/unit_hud_sog"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="kt"
+ android:textSize="10sp"
+ android:textColor="#99FFFFFF"
+ android:layout_marginStart="2dp" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#33FFFFFF" />
+
+ <!-- COG -->
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="COG"
+ android:textSize="9sp"
+ android:textColor="#99FFFFFF"
+ android:letterSpacing="0.08" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/hud_cog"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textColor="#FFFFFF"
+ android:fontFamily="sans-serif-medium"
+ tools:text="253°" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#33FFFFFF" />
+
+ <!-- BSP -->
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="BSP"
+ android:textSize="9sp"
+ android:textColor="#99FFFFFF"
+ android:letterSpacing="0.08" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/hud_bsp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textColor="#FFFFFF"
+ android:fontFamily="sans-serif-medium"
+ tools:text="6.8" />
+ <TextView
+ android:id="@+id/unit_hud_bsp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="kt"
+ android:textSize="10sp"
+ android:textColor="#99FFFFFF"
+ android:layout_marginStart="2dp" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <View android:layout_width="1dp" android:layout_height="match_parent" android:background="#33FFFFFF" />
+
+ <!-- Depth -->
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Depth"
+ android:textSize="9sp"
+ android:textColor="#99FFFFFF"
+ android:letterSpacing="0.08" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/hud_depth"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textColor="#FFFFFF"
+ android:fontFamily="sans-serif-medium"
+ tools:text="42.0" />
+ <TextView
+ android:id="@+id/unit_hud_depth"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ft"
+ android:textSize="10sp"
+ android:textColor="#99FFFFFF"
+ android:layout_marginStart="2dp" />
+ </LinearLayout>
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/android-app/app/src/main/res/layout/layout_track_summary_sheet.xml b/android-app/app/src/main/res/layout/layout_track_summary_sheet.xml
new file mode 100644
index 0000000..a26b76e
--- /dev/null
+++ b/android-app/app/src/main/res/layout/layout_track_summary_sheet.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
+ android:paddingBottom="32dp"
+ android:background="?attr/colorSurface">
+
+ <!-- Drag handle -->
+ <View
+ android:layout_width="36dp"
+ android:layout_height="4dp"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="20dp"
+ android:background="@color/md_theme_outline" />
+
+ <!-- Title -->
+ <TextView
+ android:id="@+id/summary_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="20dp"
+ android:textSize="13sp"
+ android:textAllCaps="true"
+ android:letterSpacing="0.12"
+ android:fontFamily="sans-serif-light"
+ android:textColor="@color/instrument_text_secondary"
+ tools:text="Track · 06 Apr 14:32" />
+
+ <!-- Distance + Duration row -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginBottom="16dp">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Distance" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/summary_distance"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="12.3" />
+ <TextView
+ style="@style/InstrumentUnit"
+ android:text="nm" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Duration" />
+ <TextView
+ android:id="@+id/summary_duration"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="2h 14m" />
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <!-- Speed row -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginBottom="16dp">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Max Speed" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/summary_max_sog"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="8.1" />
+ <TextView
+ style="@style/InstrumentUnit"
+ android:text="kt" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Avg Speed" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/summary_avg_sog"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="5.5" />
+ <TextView
+ style="@style/InstrumentUnit"
+ android:text="kt" />
+ </LinearLayout>
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <!-- Wind + Waves row (conditionally visible) -->
+ <LinearLayout
+ android:id="@+id/summary_conditions_row"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone"
+ tools:visibility="visible">
+
+ <LinearLayout
+ android:id="@+id/summary_wind_cell"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:visibility="gone"
+ tools:visibility="visible">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Avg Wind" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/summary_avg_wind"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="14" />
+ <TextView
+ style="@style/InstrumentUnit"
+ android:text="kt" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/summary_wave_cell"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:visibility="gone"
+ tools:visibility="visible">
+ <TextView
+ style="@style/InstrumentLabel"
+ android:text="Avg Waves" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+ <TextView
+ android:id="@+id/summary_avg_wave"
+ style="@style/InstrumentPrimaryValue"
+ tools:text="2.1" />
+ <TextView
+ style="@style/InstrumentUnit"
+ android:text="ft" />
+ </LinearLayout>
+ </LinearLayout>
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/android-app/app/src/main/res/layout/sheet_dev_log.xml b/android-app/app/src/main/res/layout/sheet_dev_log.xml
new file mode 100644
index 0000000..5464242
--- /dev/null
+++ b/android-app/app/src/main/res/layout/sheet_dev_log.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="?attr/colorSurface">
+
+ <!-- Header: title + action buttons -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingStart="16dp"
+ android:paddingEnd="8dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="8dp"
+ android:gravity="center_vertical">
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="Dev Log"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:textColor="?attr/colorOnSurface" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_clear"
+ style="@style/Widget.Material3.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Clear"
+ android:textColor="?attr/colorOnSurfaceVariant" />
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/btn_copy"
+ style="@style/Widget.Material3.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Copy" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?attr/colorOutline"
+ android:alpha="0.3" />
+
+ <ScrollView
+ android:id="@+id/scroll_view"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:paddingTop="10dp"
+ android:paddingBottom="24dp"
+ android:clipToPadding="false">
+
+ <TextView
+ android:id="@+id/log_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fontFamily="monospace"
+ android:textSize="11sp"
+ android:textColor="?attr/colorOnSurface"
+ android:lineSpacingMultiplier="1.35"
+ android:textIsSelectable="true" />
+
+ </ScrollView>
+
+</LinearLayout>
diff --git a/android-app/app/src/main/res/menu/bottom_nav_menu.xml b/android-app/app/src/main/res/menu/bottom_nav_menu.xml
index 5f444eb..5c6de7e 100644
--- a/android-app/app/src/main/res/menu/bottom_nav_menu.xml
+++ b/android-app/app/src/main/res/menu/bottom_nav_menu.xml
@@ -5,9 +5,9 @@
android:icon="@drawable/ic_map"
android:title="Map" />
<item
- android:id="@+id/nav_instruments"
- android:icon="@drawable/ic_instruments"
- android:title="Instruments" />
+ android:id="@+id/nav_layers"
+ android:icon="@drawable/ic_layers"
+ android:title="Layers" />
<item
android:id="@+id/nav_log"
android:icon="@drawable/ic_log"
@@ -20,4 +20,8 @@
android:id="@+id/nav_vessel"
android:icon="@drawable/ic_vessel"
android:title="Vessel" />
+ <item
+ android:id="@+id/nav_learn"
+ android:icon="@drawable/ic_learn"
+ android:title="Learn" />
</menu>
diff --git a/android-app/app/src/main/res/values-night/colors.xml b/android-app/app/src/main/res/values-night/colors.xml
new file mode 100644
index 0000000..b3f8669
--- /dev/null
+++ b/android-app/app/src/main/res/values-night/colors.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- M3 Dark Palette (night mode) -->
+ <color name="md_theme_primary">#A8C8FF</color>
+ <color name="md_theme_onPrimary">#00315E</color>
+ <color name="md_theme_primaryContainer">#004886</color>
+ <color name="md_theme_onPrimaryContainer">#D6E3FF</color>
+
+ <color name="md_theme_secondary">#BBC7DB</color>
+ <color name="md_theme_onSecondary">#253140</color>
+ <color name="md_theme_secondaryContainer">#3B4858</color>
+ <color name="md_theme_onSecondaryContainer">#DAE2F9</color>
+
+ <color name="md_theme_error">#FFB4AB</color>
+ <color name="md_theme_onError">#690005</color>
+ <color name="md_theme_errorContainer">#93000A</color>
+ <color name="md_theme_onErrorContainer">#FFDAD6</color>
+
+ <color name="md_theme_background">#1C1B1F</color>
+ <color name="md_theme_onBackground">#E6E1E5</color>
+ <color name="md_theme_surface">#1C1B1F</color>
+ <color name="md_theme_onSurface">#E6E1E5</color>
+ <color name="md_theme_surfaceVariant">#49454F</color>
+ <color name="md_theme_onSurfaceVariant">#CAC4D0</color>
+ <color name="md_theme_outline">#938F99</color>
+
+ <!-- Instrument: dark-mode values -->
+ <color name="instrument_text_normal">#E6E1E5</color>
+ <color name="instrument_text_secondary">#9A94A0</color>
+ <color name="instrument_background">#1C1B1F</color>
+ <color name="instrument_card_background">#2B2930</color>
+
+ <!-- WaveView — night: dark sky + midnight ocean -->
+ <color name="wave_sky_top">#1C1B1F</color>
+ <color name="wave_sky_bottom">#162433</color>
+ <color name="wave_sea_top">#0B3050</color>
+ <color name="wave_sea_bottom">#0D2137</color>
+ <color name="wave_shimmer">#4D6FC3E8</color>
+ <color name="wave_whitecap">#80FFFFFF</color>
+</resources>
diff --git a/android-app/app/src/main/res/values/colors.xml b/android-app/app/src/main/res/values/colors.xml
index b380d2d..2df4109 100755
--- a/android-app/app/src/main/res/values/colors.xml
+++ b/android-app/app/src/main/res/values/colors.xml
@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!-- M3 Color Palette -->
+ <!-- M3 Color Palette (light mode — dark mode overrides in values-night/colors.xml) -->
<color name="md_theme_primary">#005FB0</color>
<color name="md_theme_onPrimary">#FFFFFF</color>
<color name="md_theme_primaryContainer">#D6E3FF</color>
<color name="md_theme_onPrimaryContainer">#001B3E</color>
-
+
<color name="md_theme_secondary">#565F71</color>
<color name="md_theme_onSecondary">#FFFFFF</color>
<color name="md_theme_secondaryContainer">#DAE2F9</color>
<color name="md_theme_onSecondaryContainer">#131C2C</color>
-
+
<color name="md_theme_error">#BA1A1A</color>
<color name="md_theme_onError">#FFFFFF</color>
<color name="md_theme_errorContainer">#FFDAD6</color>
<color name="md_theme_onErrorContainer">#410002</color>
-
- <color name="md_theme_background">#FDFBFF</color>
- <color name="md_theme_onBackground">#1A1C1E</color>
- <color name="md_theme_surface">#FDFBFF</color>
- <color name="md_theme_onSurface">#1A1C1E</color>
- <color name="md_theme_surfaceVariant">#E0E2EC</color>
- <color name="md_theme_onSurfaceVariant">#44474E</color>
- <color name="md_theme_outline">#74777F</color>
+
+ <color name="md_theme_background">#FFFBFE</color>
+ <color name="md_theme_onBackground">#1C1B1F</color>
+ <color name="md_theme_surface">#FFFBFE</color>
+ <color name="md_theme_onSurface">#1C1B1F</color>
+ <color name="md_theme_surfaceVariant">#E7E0EB</color>
+ <color name="md_theme_onSurfaceVariant">#49454F</color>
+ <color name="md_theme_outline">#7A757F</color>
<!-- Legacy / Functional Colors -->
<color name="black">#FF000000</color>
@@ -31,13 +31,13 @@
<color name="primary_dark">#002171</color>
<color name="accent">#FF6D00</color>
- <!-- Instrument Specific -->
- <color name="instrument_text_normal">#1A1C1E</color>
- <color name="instrument_text_secondary">#44474E</color>
+ <!-- Instrument Specific (light-mode values; dark overrides in values-night/) -->
+ <color name="instrument_text_normal">#1C1B1F</color>
+ <color name="instrument_text_secondary">#6F6878</color>
<color name="instrument_text_alarm">#BA1A1A</color>
- <color name="instrument_text_stale">#74777F</color>
- <color name="instrument_background">#FDFBFF</color>
- <color name="instrument_card_background">#F1F4F9</color>
+ <color name="instrument_text_stale">#9A94A0</color>
+ <color name="instrument_background">#FFFBFE</color>
+ <color name="instrument_card_background">#F2EDF7</color>
<color name="mob_button_background">#BA1A1A</color>
<color name="anchor_button_background">#005FB0</color>
@@ -48,6 +48,14 @@
<color name="wind_medium">#FF9800</color>
<color name="wind_strong">#F44336</color>
+ <!-- WaveView — day: sunny sky + tropical deep-sea blue -->
+ <color name="wave_sky_top">#2B8FC4</color>
+ <color name="wave_sky_bottom">#87C8DF</color>
+ <color name="wave_sea_top">#0D7A9A</color>
+ <color name="wave_sea_bottom">#074B68</color>
+ <color name="wave_shimmer">#50FFFFFF</color>
+ <color name="wave_whitecap">#80FFFFFF</color>
+
<!-- Night Vision Mode (Stays Red) -->
<color name="night_red_primary">#FFFF0000</color>
<color name="night_red_variant">#FFBB0000</color>
diff --git a/android-app/app/src/main/res/values/dimens.xml b/android-app/app/src/main/res/values/dimens.xml
index 1b65ea9..21ff47a 100755
--- a/android-app/app/src/main/res/values/dimens.xml
+++ b/android-app/app/src/main/res/values/dimens.xml
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!-- Font sizes for instrument display -->
- <dimen name="text_size_instrument_primary">24sp</dimen>
- <dimen name="text_size_instrument_secondary">18sp</dimen>
- <dimen name="text_size_instrument_label">14sp</dimen>
+ <dimen name="text_size_instrument_primary">26sp</dimen>
+ <dimen name="text_size_instrument_label">10sp</dimen>
+ <dimen name="text_size_instrument_unit">10sp</dimen>
+ <dimen name="text_size_forecast_value">22sp</dimen>
+ <dimen name="text_size_forecast_label">10sp</dimen>
+ <dimen name="text_size_forecast_bearing">12sp</dimen>
<dimen name="instrument_margin">8dp</dimen>
<dimen name="instrument_padding">4dp</dimen>
</resources>
diff --git a/android-app/app/src/main/res/values/themes.xml b/android-app/app/src/main/res/values/themes.xml
index b18f4a8..93f5209 100755
--- a/android-app/app/src/main/res/values/themes.xml
+++ b/android-app/app/src/main/res/values/themes.xml
@@ -24,7 +24,7 @@
<item name="colorOnErrorContainer">@color/md_theme_onErrorContainer</item>
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorSurface</item>
- <item name="android:windowLightStatusBar">true</item>
+ <item name="android:windowLightStatusBar">false</item>
</style>
<!-- Night Vision Theme (Stays Dark and Red) -->
@@ -45,8 +45,9 @@
<item name="android:textColor">@color/instrument_text_secondary</item>
<item name="android:textSize">@dimen/text_size_instrument_label</item>
<item name="android:textAllCaps">true</item>
- <item name="android:letterSpacing">0.1</item>
- <item name="android:textStyle">bold</item>
+ <item name="android:letterSpacing">0.12</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:fontFamily">sans-serif-light</item>
</style>
<style name="InstrumentPrimaryValue" parent="android:Widget.TextView">
@@ -54,15 +55,79 @@
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">@color/instrument_text_normal</item>
<item name="android:textSize">@dimen/text_size_instrument_primary</item>
- <item name="android:textStyle">bold</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:fontFamily">sans-serif-light</item>
<item name="android:includeFontPadding">false</item>
</style>
- <style name="InstrumentSecondaryLabel" parent="android:Widget.TextView">
- <item name="android:textColor">@color/instrument_text_secondary</item>
- <item name="android:textSize">@dimen/text_size_instrument_secondary</item>
+ <style name="InstrumentUnit" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">?attr/colorOnSurfaceVariant</item>
+ <item name="android:textSize">@dimen/text_size_instrument_unit</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:layout_marginStart">2dp</item>
+ <item name="android:layout_marginBottom">3dp</item>
</style>
-
+
+ <style name="ForecastLabel" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">#5B9EC2</item>
+ <item name="android:textSize">@dimen/text_size_forecast_label</item>
+ <item name="android:textAllCaps">true</item>
+ <item name="android:letterSpacing">0.12</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:fontFamily">sans-serif-light</item>
+ </style>
+
+ <style name="ForecastValue" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">#CAE8FF</item>
+ <item name="android:textSize">@dimen/text_size_forecast_value</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:fontFamily">sans-serif-light</item>
+ <item name="android:includeFontPadding">false</item>
+ </style>
+
+ <style name="ForecastUnit" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">#3B6785</item>
+ <item name="android:textSize">@dimen/text_size_forecast_label</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:layout_marginStart">2dp</item>
+ <item name="android:layout_marginBottom">2dp</item>
+ </style>
+
+ <style name="ForecastBearing" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">#6FC3E8</item>
+ <item name="android:textSize">@dimen/text_size_forecast_bearing</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:layout_marginStart">4dp</item>
+ </style>
+
+ <style name="ForecastPeriod" parent="android:Widget.TextView">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:textColor">#4A7FA0</item>
+ <item name="android:textSize">@dimen/text_size_forecast_bearing</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:layout_marginStart">4dp</item>
+ </style>
+
+ <!-- Bottom sheet top-only rounded corners -->
+ <style name="ShapeAppearance.Nav.BottomSheet" parent="ShapeAppearance.Material3.Corner.None">
+ <item name="cornerFamily">rounded</item>
+ <item name="cornerSizeTopLeft">24dp</item>
+ <item name="cornerSizeTopRight">24dp</item>
+ <item name="cornerSizeBottomLeft">0dp</item>
+ <item name="cornerSizeBottomRight">0dp</item>
+ </style>
+
<style name="InstrumentCard" parent="Widget.Material3.CardView.Elevated">
<item name="cardBackgroundColor">@color/instrument_card_background</item>
<item name="cardCornerRadius">12dp</item>