diff --git a/offlineu_core.py b/offlineu_core.py index 779095a..842a1ee 100644 --- a/offlineu_core.py +++ b/offlineu_core.py @@ -1833,7 +1833,8 @@ def index(): library_stats=format_library_stats(scan), stale_courses=format_stale_courses(scan), activity_heatmap=format_activity_heatmap(scan), - next_up=get_next_up_courses()) + next_up=get_next_up_courses(), + active_tab='home') # Apply progress data to tree ProgressTracker.apply_progress_to_tree(current_course) @@ -1854,7 +1855,8 @@ def index(): recent_views=recent_views, has_note=bool(course_has_any_notes(current_course)), is_queued=os.path.abspath(current_course.path) in get_next_up_paths(), - resume_lesson=resume_lesson) + resume_lesson=resume_lesson, + active_tab='home') @app.route('/browse') @@ -2252,6 +2254,7 @@ def settings_page(): density_choices=['comfortable', 'compact'], card_style_choices=['flat', 'elevated', 'bordered'], corner_radius_choices=['sharp', 'rounded', 'pill'], + active_tab='settings', ) @@ -2383,13 +2386,13 @@ def open_recent(): @app.route('/help') def help_page(): """Static help page: how to use the app, supported file types.""" - return render_template('help.html') + return render_template('help.html', active_tab='help') @app.route('/notes') def notes_hub(): """Every lesson note across the whole library in one place.""" - return render_template('notes_hub.html', notes=get_all_notes()) + return render_template('notes_hub.html', notes=get_all_notes(), active_tab='notes') @app.route('/library/search-transcripts') diff --git a/templates/course_dashboard.html b/templates/course_dashboard.html index c3ceaa8..56a2824 100644 --- a/templates/course_dashboard.html +++ b/templates/course_dashboard.html @@ -70,6 +70,7 @@ } .page-content { flex: 1; + padding-bottom: 70px; } .container { @@ -144,45 +145,35 @@ word-break: break-word; } - .app-footer { + .bottom-tab-bar { + position: fixed; + left: 0; + right: 0; + bottom: 0; + z-index: 9000; + display: flex; background: var(--bg-secondary); border-top: 1px solid var(--border-color); - margin-top: 40px; - padding: 18px 0; + box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.2); + padding-bottom: env(safe-area-inset-bottom, 0px); } - - .app-footer .container { + .tab-item { + flex: 1; display: flex; + flex-direction: column; align-items: center; - justify-content: space-between; - gap: 15px; - flex-wrap: wrap; - } - - .footer-brand { - color: var(--text-muted); - font-size: 0.9em; - display: flex; - align-items: center; - gap: 8px; - } - - .footer-links { - display: flex; - gap: 20px; - } - - .footer-links a { + gap: 2px; + padding: 8px 4px; color: var(--text-muted); text-decoration: none; - font-size: 0.9em; - display: flex; - align-items: center; - gap: 6px; + font-size: 0.72em; transition: color 0.2s; } - - .footer-links a:hover { + .tab-item .tab-icon { + font-size: 1.3em; + } + .tab-item:hover, + .tab-item.active { color: var(--accent); } @@ -735,6 +726,17 @@ object-fit: cover; display: block; } + .grid-card-initial { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 1.6em; + font-weight: 700; + font-family: var(--font-family); + } .grid-card-name { font-size: 0.9em; font-weight: 500; @@ -1079,7 +1081,44 @@
🎲 Surprise Me
+ {% endif %} +
+
+

Your Courses

+
+ + +
+ + +
+ +
+ + +

+
+
+
+
+ + {% if library_stats and library_stats.total_courses %}

πŸ“Š Library Stats

@@ -1196,55 +1235,23 @@
{% endif %} -
-
-

Your Courses

-
- - -
- - -
- -
- - -

-
-
-
-
{% endif %} - + diff --git a/templates/notes_hub.html b/templates/notes_hub.html index cc7e17d..42eacec 100644 --- a/templates/notes_hub.html +++ b/templates/notes_hub.html @@ -57,6 +57,7 @@ .page-content { flex: 1; padding: 20px; + padding-bottom: 70px; } .app-header { background: linear-gradient(135deg, var(--bg-secondary), var(--bg-tertiary)); @@ -79,32 +80,36 @@ font-weight: 600; letter-spacing: 0.5px; } - .app-footer { + .bottom-tab-bar { + position: fixed; + left: 0; + right: 0; + bottom: 0; + z-index: 9000; + display: flex; background: var(--bg-secondary); border-top: 1px solid var(--border-color); - padding: 18px 0; + box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.2); + padding-bottom: env(safe-area-inset-bottom, 0px); } - .app-footer .footer-inner { - max-width: 800px; - margin: 0 auto; + .tab-item { + flex: 1; display: flex; + flex-direction: column; align-items: center; - justify-content: space-between; - gap: 15px; - flex-wrap: wrap; - } - .footer-brand { + gap: 2px; + padding: 8px 4px; color: var(--text-muted); - font-size: 0.9em; - display: flex; - align-items: center; - gap: 8px; - } - .footer-links { display: flex; gap: 20px; } - .footer-links a { - color: var(--accent); text-decoration: none; - font-size: 0.9em; + font-size: 0.72em; + transition: color 0.2s; + } + .tab-item .tab-icon { + font-size: 1.3em; + } + .tab-item:hover, + .tab-item.active { + color: var(--accent); } .container { max-width: 800px; @@ -255,16 +260,20 @@ - +