summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-04-10 22:47:27 +0000
committerClaude <noreply@anthropic.com>2026-04-10 22:47:27 +0000
commitfc7192288109fc3542670cbeeaebe0de2a75eb74 (patch)
treed78d33ad92fb32e6a57ea3df0ebf327540597d0e
parentb01a638674a313355664cc387e7da0d77a9c32d0 (diff)
Add Learn tab; move quit to Safety; remove persistent MOB FAB
UI cleanup: - Remove always-visible MOB FAB — Safety screen button is sufficient - Remove floating quit button; move to bottom of Safety screen - fragment_container is now clickable/focusable, blocking map touch-through for all overlays (trip reports, log, safety) - Record Track FAB hidden while any overlay is shown, visible on map tab New Learn tab (5th nav item): - Migration guides for Navionics and Sea People (local markdown via DocFragment) - ASA Course Catalog, ASA Online Learning, ColRegs, Sailing Flashcards (open in browser) - Remove blanket assets/ .gitignore so markdown docs are tracked https://claude.ai/code/session_01HXPjBsogsJVRwCiekDGkJX
-rw-r--r--android-app/.gitignore4
-rw-r--r--android-app/app/src/main/assets/docs/migrate_navionics.md56
-rw-r--r--android-app/app/src/main/assets/docs/migrate_sea_people.md59
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt20
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt56
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/safety/SafetyFragment.kt5
-rw-r--r--android-app/app/src/main/res/drawable/ic_learn.xml9
-rw-r--r--android-app/app/src/main/res/layout/activity_main.xml35
-rw-r--r--android-app/app/src/main/res/layout/fragment_learn.xml235
-rw-r--r--android-app/app/src/main/res/layout/fragment_safety.xml11
-rw-r--r--android-app/app/src/main/res/menu/bottom_nav_menu.xml4
11 files changed, 450 insertions, 44 deletions
diff --git a/android-app/.gitignore b/android-app/.gitignore
index 7db1cd2..acd3de6 100644
--- a/android-app/.gitignore
+++ b/android-app/.gitignore
@@ -11,8 +11,8 @@ build/
*.iws
local.properties
-# Generated files
-app/src/main/assets/
+# Generated assets (add specific patterns here if needed)
+# app/src/main/assets/ — removed blanket ignore; docs are tracked
# Keystore
*.jks
diff --git a/android-app/app/src/main/assets/docs/migrate_navionics.md b/android-app/app/src/main/assets/docs/migrate_navionics.md
new file mode 100644
index 0000000..83b28fa
--- /dev/null
+++ b/android-app/app/src/main/assets/docs/migrate_navionics.md
@@ -0,0 +1,56 @@
+# Migrating from Navionics
+
+Welcome to Nav. This guide covers the key differences and how to move your data over.
+
+---
+
+## What's Different
+
+| Feature | Navionics | Nav |
+|---|---|---|
+| Charts | Navionics SonarChart + Raster | OpenFreeMap vector tiles |
+| Track recording | In-app GPX | GPX saved to Documents/Nav/ |
+| Trip log | Voyage log | Voice log (transcribed) |
+| Departure planning | None | Pre-trip briefing with sail plan |
+| Wind overlay | Basic | Wind particles + hourly forecast |
+
+---
+
+## Exporting Your Tracks from Navionics
+
+1. Open Navionics on your phone or tablet
+2. Go to **My Charts → Tracks**
+3. Tap a track → **Share → Export GPX**
+4. Save or AirDrop the `.gpx` file to your device
+
+---
+
+## Importing Tracks into Nav
+
+Nav automatically reads GPX files from the **Documents/Nav/** folder on your device.
+
+1. Move your exported `.gpx` files to `Documents/Nav/` using the Files app
+2. Re-open Nav — tracks are loaded on startup
+3. Similar-conditions trip comparison in the Pre-Trip Briefing will use these tracks
+
+---
+
+## Waypoints
+
+Nav does not currently manage waypoints. Use Navionics or a dedicated chart plotter for waypoint routing. Nav focuses on departure briefing, track recording, and the sail log.
+
+---
+
+## Charts
+
+Nav uses **OpenFreeMap** vector tiles. These are free, fast, and work well for coastal cruising. They do not include depth contours or hazard overlays — continue using Navionics or a NOAA chart app for navigation in unfamiliar waters.
+
+---
+
+## Daily Workflow
+
+**Before you sail:** Open the **Safety → Plan Trip** screen for your departure briefing — sail plan, heading recommendation, watch items, and a look at how conditions will change over your trip window.
+
+**On the water:** Tap **Log** to dictate voice notes. The GPS track records automatically when you tap the record button.
+
+**After you return:** The post-trip report summarises distance, duration, and max SOG.
diff --git a/android-app/app/src/main/assets/docs/migrate_sea_people.md b/android-app/app/src/main/assets/docs/migrate_sea_people.md
new file mode 100644
index 0000000..b1920b4
--- /dev/null
+++ b/android-app/app/src/main/assets/docs/migrate_sea_people.md
@@ -0,0 +1,59 @@
+# Migrating from Sea People
+
+Welcome to Nav. This guide covers what transfers over and what works differently.
+
+---
+
+## What's Different
+
+| Feature | Sea People | Nav |
+|---|---|---|
+| Social feed | Community posts | Not applicable — Nav is single-user |
+| Trip log | Text entries + photos | Voice log (transcribed audio) |
+| Boat profiles | Basic boat card | Detailed sail inventory with reef points |
+| Weather | Integrated forecast | Open-Meteo hourly + NOAA marine |
+| Departure planning | Manual notes | Pre-trip briefing with sail plan & route |
+
+---
+
+## Exporting Your Log from Sea People
+
+1. Open Sea People → **Profile → My Logs**
+2. Use the **Export** option (CSV or PDF depending on your version)
+3. Save entries you want to keep for reference
+
+Nav's voice log works differently — entries are dictated on the water and transcribed. You won't be able to import Sea People entries directly, but you can review them alongside Nav going forward.
+
+---
+
+## Boat Profiles
+
+Nav stores a detailed boat profile with your sail inventory:
+
+- **Headsails** with wind range for each (e.g. 155% Genoa ≤ 13 kt, 100% Jib 10–21 kt, 65% Blade 18+ kt)
+- **Main reef points**
+- **Hull length** (used for hull-speed estimates in the departure briefing)
+
+Your boats are pre-seeded on first launch. Profiles are stored locally and used in the **Pre-Trip Briefing** to give sail recommendations specific to your boat.
+
+---
+
+## Trip Log Workflow
+
+**On the water:** Tap the **Log** tab and use the microphone button to dictate a note. Notes are timestamped with your GPS position.
+
+**Voice notes work well for:**
+- Sea state observations ("1.5m swell, 10s period, comfortable")
+- Traffic ("fishing vessel on starboard, gave way")
+- Sail changes ("reefed main at 18 kt")
+- Time stamps ("rounded the point, heading west")
+
+---
+
+## Daily Workflow
+
+**Before you sail:** Safety → Plan Trip for your departure briefing.
+
+**On the water:** Log tab for voice notes; tap the record FAB to start the GPS track.
+
+**After you return:** The post-trip report generates a narrative summary you can save or share.
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
index 86dd531..996892e 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
@@ -54,9 +54,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
private lateinit var bottomSheetBehavior: BottomSheetBehavior<View>
private lateinit var fragmentContainer: FrameLayout
private lateinit var fabRecordTrack: FloatingActionButton
- private lateinit var fabMob: FloatingActionButton
private lateinit var fabRecenter: MaterialButton
- private lateinit var btnQuit: MaterialButton
private lateinit var bottomSheet: CardView
private lateinit var bottomNav: BottomNavigationView
private lateinit var mapCrosshair: View
@@ -117,9 +115,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
private fun initializeUI() {
fragmentContainer = findViewById(R.id.fragment_container)
fabRecordTrack = findViewById(R.id.fab_record_track)
- fabMob = findViewById(R.id.fab_mob)
fabRecenter = findViewById(R.id.fab_recenter)
- btnQuit = findViewById(R.id.btn_quit)
bottomSheet = findViewById(R.id.instrument_bottom_sheet)
bottomNav = findViewById(R.id.bottom_navigation)
mapCrosshair = findViewById(R.id.map_crosshair)
@@ -166,9 +162,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
} else false
}
- fabMob.setOnClickListener { onActivateMob() }
fabRecenter.setOnClickListener { mapHandler?.recenter() }
- btnQuit.setOnClickListener { onQuitRequested() }
lifecycleScope.launch {
viewModel.isRecording.collect { recording ->
@@ -280,6 +274,12 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
true
}
+ R.id.nav_learn -> {
+ showOverlay(org.terst.nav.ui.learn.LearnFragment())
+ bottomSheetBehavior.isHideable = true
+ bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
+ true
+ }
else -> false
}
}
@@ -287,6 +287,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
private fun showOverlay(fragment: androidx.fragment.app.Fragment) {
fragmentContainer.visibility = View.VISIBLE
+ fabRecordTrack.visibility = View.GONE
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit()
@@ -294,9 +295,10 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
private fun hideOverlays() {
fragmentContainer.visibility = View.GONE
+ fabRecordTrack.visibility = View.VISIBLE
}
- private fun onQuitRequested() {
+ override fun onQuitRequested() {
if (viewModel.isRecording.value) {
androidx.appcompat.app.AlertDialog.Builder(this)
.setMessage("Recording in progress. Quit and discard the current track?")
@@ -405,9 +407,9 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
mapCrosshair.visibility = if (following) View.GONE else View.VISIBLE
if (following) {
fadeOut(fabRecenter, gone = true)
- fadeIn(bottomNav, fabMob, fabRecordTrack)
+ fadeIn(bottomNav, fabRecordTrack)
} else {
- fadeOut(bottomNav, fabMob, fabRecordTrack, gone = true)
+ fadeOut(bottomNav, fabRecordTrack, gone = true)
fadeIn(fabRecenter)
}
}
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt
new file mode 100644
index 0000000..8440edb
--- /dev/null
+++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/learn/LearnFragment.kt
@@ -0,0 +1,56 @@
+package org.terst.nav.ui.learn
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.google.android.material.card.MaterialCardView
+import org.terst.nav.R
+import org.terst.nav.ui.doc.DocFragment
+
+class LearnFragment : Fragment() {
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? = inflater.inflate(R.layout.fragment_learn, container, false)
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ // Migration guides — open local markdown docs
+ view.findViewById<MaterialCardView>(R.id.card_migrate_navionics).setOnClickListener {
+ openDoc("docs/migrate_navionics.md")
+ }
+ view.findViewById<MaterialCardView>(R.id.card_migrate_seapeople).setOnClickListener {
+ openDoc("docs/migrate_sea_people.md")
+ }
+
+ // ASA / external links — open in browser
+ view.findViewById<MaterialCardView>(R.id.card_asa_courses).setOnClickListener {
+ openUrl("https://www.asa.com/courses/")
+ }
+ view.findViewById<MaterialCardView>(R.id.card_asa_online).setOnClickListener {
+ openUrl("https://www.asa.com/online-courses/")
+ }
+ view.findViewById<MaterialCardView>(R.id.card_colregs).setOnClickListener {
+ openUrl("https://www.navcen.uscg.gov/international-regulations-for-preventing-collisions-at-sea")
+ }
+ view.findViewById<MaterialCardView>(R.id.card_flashcards).setOnClickListener {
+ openUrl("https://quizlet.com/subject/sailing/")
+ }
+ }
+
+ private fun openDoc(path: String) {
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.fragment_container, DocFragment.newInstance(path))
+ .addToBackStack(null)
+ .commit()
+ }
+
+ private fun openUrl(url: String) {
+ startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
+ }
+}
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/safety/SafetyFragment.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/safety/SafetyFragment.kt
index 4bc0c7a..6dd7411 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/ui/safety/SafetyFragment.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/safety/SafetyFragment.kt
@@ -15,6 +15,7 @@ class SafetyFragment : Fragment() {
interface SafetyListener {
fun onActivateMob()
fun onConfigureAnchor()
+ fun onQuitRequested()
}
private var listener: SafetyListener? = null
@@ -55,6 +56,10 @@ class SafetyFragment : Fragment() {
.addToBackStack(null)
.commit()
}
+
+ view.findViewById<MaterialButton>(R.id.button_quit).setOnClickListener {
+ listener?.onQuitRequested()
+ }
}
fun updateAnchorStatus(statusText: String) {
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/layout/activity_main.xml b/android-app/app/src/main/res/layout/activity_main.xml
index 5943949..1bb88b3 100644
--- a/android-app/app/src/main/res/layout/activity_main.xml
+++ b/android-app/app/src/main/res/layout/activity_main.xml
@@ -59,26 +59,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
+ android:clickable="true"
+ android:focusable="true"
android:background="?attr/colorSurface" />
- <!-- Quit button — stops all services and exits -->
- <com.google.android.material.button.MaterialButton
- android:id="@+id/btn_quit"
- style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
- android:layout_width="40dp"
- android:layout_height="40dp"
- android:alpha="0.7"
- app:icon="@drawable/ic_close"
- app:iconSize="18dp"
- app:iconGravity="textStart"
- app:iconPadding="0dp"
- app:cornerRadius="20dp"
- app:elevation="4dp"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- android:layout_marginTop="16dp"
- android:layout_marginEnd="16dp" />
-
<com.google.android.material.button.MaterialButton
android:id="@+id/fab_recenter"
android:layout_width="wrap_content"
@@ -115,21 +99,6 @@
</androidx.cardview.widget.CardView>
- <!-- 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:elevation="20dp"
- 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"
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..f41e577
--- /dev/null
+++ b/android-app/app/src/main/res/layout/fragment_learn.xml
@@ -0,0 +1,235 @@
+<?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>
+
+ <!-- ── ASA Training & Practice ──────────────────────────────── -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ASA TRAINING &amp; PRACTICE"
+ 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_asa_courses"
+ 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="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ASA Course Catalog"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ASA 101–114: keelboat through offshore passagemaking"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_asa_online"
+ 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="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="ASA Online Learning"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Self-paced online courses and study guides"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <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="vertical"
+ android:padding="16dp">
+
+ <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="USCG international collision regulations reference"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/card_flashcards"
+ 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="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Sailing Flashcards"
+ android:textAppearance="?attr/textAppearanceTitleSmall" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Quizlet decks for knots, rules, lights &amp; signals"
+ android:textSize="12sp"
+ android:textColor="?attr/colorOnSurfaceVariant"
+ android:layout_marginTop="2dp" />
+
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+
+ </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 f90420e..60ea1aa 100644
--- a/android-app/app/src/main/res/layout/fragment_safety.xml
+++ b/android-app/app/src/main/res/layout/fragment_safety.xml
@@ -113,4 +113,15 @@
android:text="PLAN TRIP (PRE-TRIP REPORT)"
app:layout_constraintTop_toBottomOf="@id/card_anchor" />
+ <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/menu/bottom_nav_menu.xml b/android-app/app/src/main/res/menu/bottom_nav_menu.xml
index e7fc15d..3037b7e 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
@@ -16,4 +16,8 @@
android:id="@+id/nav_safety"
android:icon="@drawable/ic_safety"
android:title="Safety" />
+ <item
+ android:id="@+id/nav_learn"
+ android:icon="@drawable/ic_learn"
+ android:title="Learn" />
</menu>