Files
jamshalat-diary/TASKLIST.md
dwindown faadc1865d feat: Murattal player enhancements & prayer schedule auto-scroll
- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist]
- Murattal: Animated 7-bar equalizer visualization in player circle
- Murattal: Unsplash API background with frosted glass player overlay
- Murattal: Transparent AppBar with backdrop blur
- Murattal: Surah playlist bottom sheet with full 114 Surah list
- Murattal: Auto-play disabled on screen open, enabled on navigation
- Murattal: Shuffle mode for random Surah playback
- Murattal: Photographer attribution per Unsplash guidelines
- Dashboard: Auto-scroll prayer schedule to next active prayer
- Fix: setState lifecycle errors on Reading & Murattal screens
- Setup: flutter_dotenv, cached_network_image, url_launcher deps
2026-03-13 15:42:17 +07:00

24 KiB
Raw Blame History

Jamshalat Diary — Phase-Based Implementation Tasklist

Project: Jamshalat Diary Flutter App
PRD Reference: PRD.md
Design Reference: stitch/ folder (18 screens)
Last Updated: March 2026


How to Use This Document

  • Status legend: [ ] Not started · [~] In progress · [x] Done · [-] Skipped/deferred
  • Dependency notation: Tasks marked with ⚠️ depends on: [task ref] must not start until that task is complete
  • Assignable units: Each task is atomic enough to delegate to a single agent/developer
  • Phase gates: Do not start a phase until all [x] required tasks in the previous phase are complete

Phase 1 — Foundation

Goal: Runnable Flutter app with navigation shell, design system, and theme engine wired up.
Gate to Phase 2: App boots, bottom nav switches tabs, light/dark toggle works.

1.1 Project Bootstrap

  • 1.1.1 Create Flutter project: flutter create jamshalat_diary --org com.jamshalat --platforms android,ios
  • 1.1.2 Add all dependencies to pubspec.yaml (see PRD §8 — Third-Party Dependencies)
  • 1.1.3 Run flutter pub get and verify zero conflicts
  • 1.1.4 Configure analysis_options.yaml with strict linting rules (flutter_lints + prefer_const_constructors)
  • 1.1.5 Set up folder structure as defined in PRD §4.1 (create all lib/ directories and placeholder files)
  • 1.1.6 Add font assets to pubspec.yaml: Google Fonts (Plus Jakarta Sans via google_fonts package) + Amiri (bundled TTF in assets/fonts/)
  • 1.1.7 Add asset directories to pubspec.yaml: assets/fonts/, assets/quran/, assets/dzikir/, assets/images/
  • 1.1.8 Configure Android minSdkVersion: 21, targetSdkVersion: 34 in android/app/build.gradle
  • 1.1.9 Configure iOS deployment target: 13.0 in ios/Podfile

1.2 Design System

  • 1.2.1 Create lib/app/theme/app_colors.dart — all color tokens from PRD §3.1 (light + dark values as static consts)
  • 1.2.2 Create lib/app/theme/app_text_styles.dart — full TextTheme from PRD §3.2 (Plus Jakarta Sans weights, Amiri definitions)
  • 1.2.3 Create lib/app/theme/app_theme.dartThemeData for light and dark using tokens from 1.2.1 + 1.2.2; Material 3 enabled
  • 1.2.4 Create lib/core/widgets/ios_toggle.dart — custom iOS-style toggle widget (51×31dp, animated thumb, AnimatedContainer + GestureDetector) per PRD §6.9
  • 1.2.5 Create lib/core/widgets/section_header.dart — reusable section label widget (uppercase, tracking-wider, sage color)
  • 1.2.6 Create lib/core/widgets/progress_bar.dart — reusable linear progress bar (primary fill, configurable height + borderRadius)
  • 1.2.7 Verify AppColors against all 18 stitch screens — no hardcoded colors in any widget

1.3 Navigation Shell

  • 1.3.1 Add go_router and set up lib/app/router.dart with ShellRoute for bottom nav tabs
  • 1.3.2 Define all routes from PRD §5.2 in router.dart (top-level + nested)
  • 1.3.3 Create lib/core/widgets/bottom_nav_bar.dart — 5-tab nav bar per PRD §5.1 spec (active/inactive states, Material Symbols filled/outlined)
  • 1.3.4 Create stub screens for all 9 features (empty Scaffold + AppBar with feature name) so routing is testable
  • 1.3.5 Create lib/app/app.dartMaterialApp.router wired to router.dart + themeMode from Riverpod provider

1.4 Theme Engine

  • 1.4.1 Create lib/core/providers/theme_provider.dartStateProvider<ThemeMode> initialized from Hive settings
  • 1.4.2 Wrap MaterialApp in ProviderScope; consume themeProvider for themeMode
  • 1.4.3 Verify light ↔ dark toggle visually applies instantly on all stub screens
  • 1.4.4 Create lib/main.dart — initializes Hive, runs ProviderScope + App

Phase 2 — Core Data Layer

Goal: All services and local storage ready. Features can read/write data.
Gate to Phase 3: Prayer times calculate correctly for Jakarta coords, Hive boxes open without errors, notifications schedule in emulator.
⚠️ Depends on: Phase 1 complete

2.1 Hive Setup

  • 2.1.1 Create all 6 Hive @HiveType model classes from PRD §7.1: AppSettings, ChecklistItem, DailyWorshipLog, DzikirCounter, QuranBookmark, CachedPrayerTimes
  • 2.1.2 Run build_runner to generate Hive TypeAdapter files (*.g.dart)
  • 2.1.3 Create lib/data/local/hive_boxes.dart — box name constants + initHive() function that opens all boxes
  • 2.1.4 Call initHive() in main.dart before runApp()
  • 2.1.5 Seed default AppSettings on first launch (if settings box is empty)
  • 2.1.6 Seed default 10 ChecklistItem entries on first launch (per PRD §6.3 default items table)

2.2 Prayer Time Service

  • 2.2.1 Create lib/data/services/prayer_service.dart using adhan package
    • Method: PrayerTimes getPrayerTimes(double lat, double lng, DateTime date)
    • Calculation method: Muslim World League (default), configurable in settings
    • Returns: Fajr, Sunrise, Dhuhr, Asr, Maghrib, Isha as DateTime
  • 2.2.2 Implement cache logic: before calculating, check CachedPrayerTimes Hive box for existing lat_lng_date key; write result to box after calculation
  • 2.2.3 Create lib/features/dashboard/data/prayer_times_provider.dartAsyncNotifierProvider that fetches location then returns today's PrayerTimes
  • 2.2.4 Unit test: getPrayerTimes(lat: -6.2088, lng: 106.8456, date: 2026-03-06) → verify Maghrib ≈ 18:05 WIB

2.3 Location Service

  • 2.3.1 Create lib/data/services/location_service.dart
    • Method: Future<Position?> getCurrentLocation() — requests permission, gets GPS fix
    • Method: Position? getLastKnownLocation() — reads from AppSettings Hive box
    • Method: Future<String> getCityName(double lat, double lng) — reverse geocode via geocoding package
  • 2.3.2 Implement fallback chain: GPS → last saved → manual city picker
  • 2.3.3 Save successful GPS fix to AppSettings (lat, lng, cityName) after each successful fetch
  • 2.3.4 Add ACCESS_FINE_LOCATION permission to Android AndroidManifest.xml
  • 2.3.5 Add NSLocationWhenInUseUsageDescription to iOS Info.plist

2.4 Notification Service

  • 2.4.1 Create lib/data/services/notification_service.dart using flutter_local_notifications
    • Method: Future<void> init() — initializes channels (Android: high-priority Adhan channel)
    • Method: Future<void> scheduleAdhan(Prayer prayer, DateTime time) — schedules exact alarm
    • Method: Future<void> scheduleIqamah(Prayer prayer, DateTime adhanTime, int offsetMinutes) — schedules iqamah reminder
    • Method: Future<void> cancelAll() — cancels all pending notifications
    • Method: Future<void> rescheduleAll(PrayerTimes times, AppSettings settings) — cancels + re-schedules based on current settings
  • 2.4.2 Add SCHEDULE_EXACT_ALARM + POST_NOTIFICATIONS permissions to Android manifest
  • 2.4.3 Add iOS background modes for notifications in Info.plist
  • 2.4.4 Call rescheduleAll() on app start and whenever settings or location changes
  • 2.4.5 Manual test: enable Fajr notification in settings → verify notification fires at correct time in emulator

2.5 Quran Data Service

  • 2.5.1 Source or create assets/quran/quran_id.json — 114 Surahs, each entry: { id, nameArabic, nameLatin, verseCount, juzStart, verses: [{id, arabic, transliteration, translation_id}] }
  • 2.5.2 Create lib/data/services/quran_service.dart
    • Method: Future<List<Surah>> getAllSurahs() — loads + parses JSON asset (cached in memory after first load)
    • Method: Future<Surah> getSurah(int id) — returns single surah with all verses
  • 2.5.3 Verify JSON loads correctly; log verse count for Surah 2 (Al-Baqarah) = 286 verses

2.6 Dzikir Data Service

  • 2.6.1 Create assets/dzikir/dzikir_pagi.json and assets/dzikir/dzikir_petang.json — each entry: { id, arabic, transliteration, translation, target_count, source }
  • 2.6.2 Create lib/data/services/dzikir_service.dart
    • Method: Future<List<DzikirItem>> getDzikir(DzikirType type) — loads from JSON asset
    • Method: Map<String, int> getCountersForDate(String date) — reads from Hive dzikir_counters box
    • Method: void increment(String dzikirId, String date) — writes to Hive

Phase 3 — Dashboard & Prayer Calendar

Goal: The two primary daily-use screens are fully functional.
Gate to Phase 4: Dashboard shows live countdown, correct prayer times, checklist summary. Imsakiyah shows full monthly table.
⚠️ Depends on: Phase 2 complete

3.1 Dashboard Screen

  • 3.1.1 Build DashboardScreen sticky header: avatar + greeting + notification bell (taps → Settings)
  • 3.1.2 Build Next Prayer Hero Card: bg-primary card, prayer name+time (displayLarge), live countdown timer widget
    • Countdown: StreamBuilder on Stream.periodic(Duration(seconds: 1)) computing time to next prayer
  • 3.1.3 Build Adhan/Iqamah badge: notification bell icon absolutely positioned on active prayer card (shown when Adhan has been called, hidden otherwise)
  • 3.1.4 Build "View Qibla" button on hero card → navigates to /tools/qibla
  • 3.1.5 Build Prayer Times horizontal scroll: ListView.builder horizontal, 5 prayer cards (FajrIsha), active card highlighted
  • 3.1.6 Build Today's Checklist Summary Card: circular SVG progress + 2 preview items + "View Full Checklist" CTA
  • 3.1.7 Build Weekly Progress bar chart: 7 bars (MonSun), data from worship_logs Hive box
  • 3.1.8 Wire prayer_times_provider to all prayer time displays
  • 3.1.9 Wire checklist summary to today's DailyWorshipLog from Hive
  • 3.1.10 Verify screen matches stitch/dashboard_active_nav/screen.png visually

3.2 Prayer Calendar (Imsakiyah) Screen

  • 3.2.1 Build Imsakiyah screen header: back + "Prayer Calendar" + more_vert
  • 3.2.2 Build Hijri month selector: horizontal scroll chip row; compute current + surrounding Hijri months
  • 3.2.3 Build location card: shows current city name + expand_more tapping opens city search bottom sheet
  • 3.2.4 Build city search bottom sheet: TextField + ListView of bundled Indonesian cities (local JSON asset)
  • 3.2.5 Build prayer times table: GridView 7-column, header row, data rows for all days of selected Hijri month
  • 3.2.6 Highlight today's row with primary/5 background
  • 3.2.7 Wire month selector + location to PrayerService — recalculate on change
  • 3.2.8 Auto-scroll to today's row on screen open
  • 3.2.9 Verify screen matches stitch/imsakiyah_active_nav/screen.png visually

Phase 4 — Worship Tracking

Goal: Checklist, Dzikir, and Reports fully functional with persistent data.
Gate to Phase 5: Checklist persists across restarts, Dzikir counter works, Reports chart renders from real log data.
⚠️ Depends on: Phase 2 complete (data layer), Phase 3 (worship_logs written by Dashboard)

4.1 Daily Checklist Screen

  • 4.1.1 Build Checklist header: "Daily Worship" + date string + calendar icon (date picker for viewing past days)
  • 4.1.2 Build Progress Card: dark bg, auto_awesome decoration, percentage text, progress bar, motivational quote
  • 4.1.3 Build task list: ListView of ChecklistItem widgets with custom checkbox
  • 4.1.4 Implement custom checkbox widget: 24dp, primary border, animated check SVG on tap
  • 4.1.5 Wire tap → update DailyWorshipLog in Hive → Riverpod provider invalidate → progress card updates reactively
  • 4.1.6 Implement daily reset: on date change, create new empty DailyWorshipLog for new date
  • 4.1.7 Write completion data to worship_logs box (for Reports feature to consume)
  • 4.1.8 Verify screen matches stitch/checklist_active_nav/screen.png and stitch/checklist_dark_mode/screen.png

4.2 Dzikir Screen

  • 4.2.1 Build Dzikir header: back + "Dzikir Pagi & Petang" + info button (bottom sheet explanation)
  • 4.2.2 Build Pagi/Petang tab bar with animated underline indicator
  • 4.2.3 Build hero banner: gradient bg + title + subtitle
  • 4.2.4 Build Dzikir card: Arabic text (Amiri, RTL, 24sp), transliteration (italic), translation, counter row
  • 4.2.5 Implement tap counter: + button → increments count in Hive → rebuilds counter row reactively
  • 4.2.6 Implement completion state: when count >= target, button becomes check_circle, card shows subtle primary glow
  • 4.2.7 Implement smart tab pre-selection: Pagi between FajrDhuhr, Petang between MaghribIsha
  • 4.2.8 Verify Arabic text renders correctly RTL, no overflow, no visual glitches
  • 4.2.9 Verify screen matches stitch/dzikir_active_nav/screen.png and stitch/dzikir_dark_mode/screen.png

4.3 Reports (Laporan) Screen

  • 4.3.1 Build Reports header: back + "Worship Quality Report" + share button
  • 4.3.2 Build Weekly/Monthly/Yearly tab bar
  • 4.3.3 Build main chart card: analytics badge + completion % + trend chip
  • 4.3.4 Build bar chart widget: custom CustomPainter or Column+Expanded bars, proportional heights from log data
  • 4.3.5 Implement tap-on-bar tooltip: OverlayEntry or Tooltip showing date + exact % on tap
  • 4.3.6 Build summary stats row: Best streak, Average %, Total completed
  • 4.3.7 Implement streak calculation: consecutive days with completion > 0% from worship_logs
  • 4.3.8 Implement share button: generate shareable text summary (no image generation in v1.0)
  • 4.3.9 Build empty state: illustration + "Start tracking to see your progress" when no logs exist
  • 4.3.10 Verify screen matches stitch/laporan_active_nav/screen.png and stitch/laporan_dark_mode/screen.png

Phase 5 — Islamic Tools

Goal: Qibla, Quran Reader, and Murattal player fully functional.
Gate to Phase 6: Qibla compass rotates with device, Quran displays all 114 Surahs, audio plays in background.
⚠️ Depends on: Phase 2 complete (data layer)

5.1 Qibla Finder Screen

  • 5.1.1 Build Qibla header: back + "Qibla Finder" + my_location button
  • 5.1.2 Build location + degree display: city name + "{n}°} from North" label
  • 5.1.3 Build compass widget: circular ring with N/S/E/W labels, AnimatedRotation driven by flutter_compass stream
  • 5.1.4 Build Qibla arrow: overlaid pointer that stays fixed to calculated Qibla bearing while compass ring rotates
  • 5.1.5 Build mosque silhouette overlay: ShaderMask with gradient mask (fade-to-transparent at top)
  • 5.1.6 Build accuracy indicator: "High accuracy" / "Low accuracy" label based on sensor data
  • 5.1.7 Build permission-denied state: explanation card + "Open Settings" button
  • 5.1.8 Verify compass direction is correct for Jakarta coordinates (Qibla ≈ 295° from North)

5.2 Quran List Screen

  • 5.2.1 Build Quran list screen header: search bar at top
  • 5.2.2 Build Surah list: ListView.builder of 114 items
    • Each item: number badge (primary/10 bg) + Arabic name (Amiri) + Latin name + verse count + Juz
  • 5.2.3 Implement search filter: filters by Latin name or Surah number in real time

5.3 Quran Reading Screen

  • 5.3.1 Build reading screen sticky header: back + Surah name (Arabic, Amiri) + Juz info + more_vert
  • 5.3.2 Build Bismillah banner (shown for all Surahs except Surah 9 — At-Tawbah)
  • 5.3.3 Build verse card: verse number badge + Arabic text (Amiri, 28sp, RTL) + transliteration + translation
  • 5.3.4 Build verse action row: bookmark, share, play icons per verse
  • 5.3.5 Implement bookmarking: tap bookmark icon → save QuranBookmark to Hive → icon toggles to filled
  • 5.3.6 Implement reading position persistence: save last scroll position (verse index) to Hive per Surah
  • 5.3.7 Wire play icon on verse → navigate to /tools/quran/:surahId/murattal starting at that verse
  • 5.3.8 Verify Arabic text is RTL, no clipping, line-height comfortable (2.2 per PRD)
  • 5.3.9 Verify screen matches stitch/quran_reading_active_nav/screen.png and stitch/quran_dark_mode/screen.png

5.4 Quran Murattal Screen

  • 5.4.1 Initialize just_audio player + audio_service for background playback
  • 5.4.2 Build Murattal screen: inherits Quran Reading layout + adds audio player panel at bottom
  • 5.4.3 Build audio player panel: reciter name + progress slider + transport controls (skip_previous, replay_10, play/pause, forward_10, skip_next)
  • 5.4.4 Build playback speed selector: 0.75x / 1x / 1.25x / 1.5x chips
  • 5.4.5 Implement verse highlight sync: highlight current verse based on audio position (timed segments per Surah)
  • 5.4.6 Implement auto-scroll: ScrollController scrolls to current verse during playback
  • 5.4.7 Configure background audio: audio_service handler, system media controls in notification tray
  • 5.4.8 Bundle short Surahs (Juz Amma: Surah 78114) as local MP3 assets
  • 5.4.9 Implement streaming fallback for longer Surahs (mp3quran.net API)
  • 5.4.10 Build offline fallback state for streamed Surahs: "Connect to internet to play this Surah"
  • 5.4.11 Verify screen matches stitch/quran_murattal_active_nav/screen.png

Phase 6 — Settings & System Polish

Goal: Settings screen complete, all toggles wired, notifications working end-to-end, dark mode seamless.
Gate to Phase 7: All settings persist, dark mode switches instantly, Adhan notification fires correctly, no hardcoded colors remain.
⚠️ Depends on: Phase 4 + Phase 5 complete

6.1 Settings Screen

  • 6.1.1 Build Settings header: back + "Settings" title
  • 6.1.2 Build Profile section: avatar + name + email + edit button (inline editing)
  • 6.1.3 Build Notifications group: per-prayer Adhan toggles (5 prayers) using IosToggle widget
  • 6.1.4 Build Iqamah offset row: per-prayer minute offset picker (stepper, default 10 min)
  • 6.1.5 Build Daily Checklist Reminder row: time picker, default 9:00 AM
  • 6.1.6 Build Display group: Dark Mode 3-way control (Light/Dark/Auto), Font Size selector, Language selector
  • 6.1.7 Build About group: App Version, Privacy Policy (in-app WebView), Rate App link, Feedback
  • 6.1.8 Wire all toggles → write to AppSettings Hive box → trigger side effects (notification reschedule, theme change)
  • 6.1.9 Verify screen matches stitch/settings_with_dark_mode_option/screen.png and stitch/settings_dark_mode/screen.png

6.2 Dark Mode Polish

  • 6.2.1 Audit ALL screens in dark mode against stitch/*_dark_mode/screen.png — fix any color token mismatches
  • 6.2.2 Verify no hardcoded Colors.white, Colors.black, or raw hex strings remain in widget code (grep codebase)
  • 6.2.3 Verify AnimatedTheme transition is smooth (no flash/jank on toggle)
  • 6.2.4 Test system auto mode: app follows device dark mode setting correctly

6.3 Notification End-to-End

  • 6.3.1 Verify Adhan notifications fire at correct prayer times on Android emulator (API 34)
  • 6.3.2 Verify Adhan notifications fire correctly on iOS simulator (iOS 16+)
  • 6.3.3 Verify notifications are cancelled when prayer toggle is turned off in Settings
  • 6.3.4 Verify Iqamah notification fires n minutes after Adhan (configurable offset)
  • 6.3.5 Verify notifications reschedule correctly after location changes (new prayer times → cancel old → schedule new)
  • 6.3.6 Verify tapping notification → opens app on Dashboard screen

6.4 Accessibility Pass

  • 6.4.1 Audit all IconButtons and small tap targets: minimum 48×48dp (add SizedBox wrappers where needed)
  • 6.4.2 Add Semantics(label: ...) to all icon-only buttons across all screens
  • 6.4.3 Verify all Arabic text has explicit textDirection: TextDirection.rtl
  • 6.4.4 Verify contrast ratios for all text on primary bg (#70df20 background with dark text = check)
  • 6.4.5 Test with TalkBack (Android) and VoiceOver (iOS) — all interactive elements must be reachable

6.5 Localization

  • 6.5.1 Set up flutter_localizations + intl in pubspec.yaml
  • 6.5.2 Create lib/l10n/app_id.arb (Indonesian) and lib/l10n/app_en.arb (English) with all UI strings
  • 6.5.3 Replace all hardcoded Indonesian strings in widgets with AppLocalizations.of(context).*
  • 6.5.4 Verify language switch in Settings changes all UI strings (no restart required)

Phase 7 — QA & Release Prep

Goal: App is production-ready. All screens verified, performance validated, store assets ready.
Gate to ship: Zero critical bugs, performance targets met, store listing complete.
⚠️ Depends on: Phase 6 complete

7.1 Integration Testing

  • 7.1.1 Write integration test: full checklist flow (open app → check 5 items → verify progress = 50% → restart → verify persisted)
  • 7.1.2 Write integration test: prayer time accuracy for 5 major Indonesian cities (Jakarta, Surabaya, Medan, Makassar, Denpasar)
  • 7.1.3 Write integration test: dark mode toggle persists across app restart
  • 7.1.4 Write integration test: Dzikir counter increments and resets on next day
  • 7.1.5 Manual test: Quran reads all 114 Surahs without crash (test Surah 2 — largest Surah)
  • 7.1.6 Manual test: Murattal audio plays + background playback continues when screen locked

7.2 Performance Audit

  • 7.2.1 Profile cold start time on mid-range Android device — must be < 2 seconds
  • 7.2.2 Profile bottom nav tab switches — must be < 150ms
  • 7.2.3 Profile Quran Surah 2 scroll (286 verses) — must maintain 60fps
  • 7.2.4 Run flutter analyze — zero warnings, zero errors
  • 7.2.5 Run flutter test — all unit tests pass

7.3 App Assets & Store Prep

  • 7.3.1 Create app icon (1024×1024px): mosque/compass motif with #70df20 primary color
  • 7.3.2 Apply app icon via flutter_launcher_icons package (all densities, adaptive icon for Android)
  • 7.3.3 Create splash screen via flutter_native_splash package (white/dark bg, centered logo)
  • 7.3.4 Set app name: "Jamshalat Diary" in AndroidManifest.xml and Info.plist
  • 7.3.5 Set bundle ID: com.jamshalat.diary on both platforms
  • 7.3.6 Configure release signing (Android keystore, iOS certificates) — document in private README
  • 7.3.7 Build release APK: flutter build apk --release — verify no build errors
  • 7.3.8 Build iOS release: flutter build ipa --release — verify no build errors
  • 7.3.9 Write Play Store listing: app description (Indonesian + English), screenshots (1 per key screen), tags
  • 7.3.10 Write App Store listing: same content, App Store Connect metadata

Progress Tracker

Phase Total Tasks Done Remaining Status
Phase 1 — Foundation 22 0 22 Not started
Phase 2 — Data Layer 21 0 21 Not started
Phase 3 — Dashboard & Calendar 18 0 18 Not started
Phase 4 — Worship Tracking 28 0 28 Not started
Phase 5 — Islamic Tools 27 0 27 Not started
Phase 6 — Settings & Polish 22 0 22 Not started
Phase 7 — QA & Release 20 0 20 Not started
TOTAL 158 0 158 🔴 Not started

Quick Reference — Key Files

File Purpose
PRD.md Full product requirements — source of truth
stitch/*/screen.png Visual reference for each screen
stitch/*/code.html HTML implementation reference for each screen
TASKLIST.md This document — execution plan

TASKLIST v1.0 — Jamshalat Diary — March 2026