> ## Documentation Index
> Fetch the complete documentation index at: https://theteam-13fc7f49.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Frontend Clean-Up (Flutter)

> The full repository clean-up plan for LMS_Frontend — repo weight, the executed dead-code and asset deletions, the 2026-10-08 package bump with the complete installed-vs-latest table and why some packages are held back, the stale-package replacement plan, and the app speed suggestions.

Mirror of **`LMS_Frontend/clean_up.md`** (generated 27/09/2026, last updated 09/10/2026). Scope: why
the repo is slow to load/clone on GitHub, what should be gitignored, what files / assets / code are
unused, and how far the `pubspec.yaml` packages are from their latest release. Target platforms are
**web, Android, iOS** only.

**Status 28/09/2026 (commit `2b5a6e7`, pushed):** Sections **C** (template relocation) and **E**
(macos/linux removal) are ✅ DONE, plus `CLAUDE_old.md` from Section A and the 6 empty Dart files
from Section D. `flutter analyze` after the batch: **0 errors**.

**Status 28/09/2026 (later):** Section **B** is ✅ DONE — the 39 zero-reference assets were deleted
(see the asset audit at the bottom); `flutter analyze` after deletion: **0 errors**.

**Status 08/10/2026:** Section **G.2** is ✅ DONE — every package was bumped to the newest version
that resolves on **Flutter 3.44.6 / Dart 3.12.2** (commit `513bb83`). `flutter analyze` 0 errors;
the release web build and the Android debug build pass; 433 tests pass.

**Status 08/10/2026 (later, Fixes 1–6):** Section **D** ✅ DONE (the 50 remaining dead Dart files
plus the 11 assets only they referenced), **G.1** ✅ DONE (13 unused packages removed), the G.2 table
refreshed, a new **G.4** replacement table for the stale packages, and a new **App Speed
Suggestions** section at the end. After all of it: `flutter analyze` 0 errors (10 warnings,
unchanged), 433 tests pass, `flutter build web --release` OK.

**Status 08/10/2026 (evening):** `flip_card` removed — the review screens now swap answers and
explanation in place (G.4 ✅); `custom_sliding_segmented_control` held back at 1.8.5 after its 2.0
broke every call site (§G.2.1 point 5); the exam attempt review page re-sized for 11" / 13" / 15"
windows (App Speed → "Applied so far"). `flutter analyze` 0 errors, 433 tests pass.

**Status 23/10/2026 (commit `89da932`, frontend Update 145):** Section **D.2** ✅ DONE — the 10
newly orphaned files were deleted, together with 17 more orphans found by a full import-graph walk
(27 files, 5,950 lines). `flutter analyze` 0 errors.

**Still pending:** Section **A** (`.gitignore` / `graphify-out` untracking, `.DS_Store`s, stray
files), Section **F**, and the **G.4** replacements.

***

## Why GitHub is slow with this repo

The tracked tree is **\~68.8 MB across \~3,000 files**. The breakdown makes the culprit obvious:

| Tracked content | Size | Files | % of repo |
| - | -: | -: | -: |
| `graphify-out/` (knowledge-graph output + caches) | **45.7 MB** | **\~1,560** | **66%** |
| `assets/images/` | 6.9 MB | 60 | 10% |
| `lib/` | \~6.0 MB | 627 | 9% |
| `android/` + `ios/` | \~5.0 MB | 106 | 7% |
| `docs/api_samples/` (API response dumps) | 1.4 MB | 10 | 2% |
| everything else | \~3.8 MB | — | 6% |

* **`build/web` is NOT the problem** — `build/` is already gitignored and zero build artifacts are
  tracked.
* **`graphify-out/` IS the problem.** Its ignore rule exists in `.gitignore` but is commented out
  (`#graphify-out/`). \~1,560 small JSON cache files + a 9.9 MB `graph.json` are what make the
  GitHub file tree, clones and pushes slow. It's regenerable local tool output (`/graphify .`).
* 12 `.DS_Store` files are tracked (macOS Finder junk).

***

## A. Untrack + gitignore (biggest win, zero risk) — ⬜ pending

| Path | Size | Action |
| - | -: | - |
| `graphify-out/` (whole folder, 1,560 files) | 45.7 MB | Uncomment `graphify-out/` in `.gitignore`, `git rm -r --cached graphify-out` |
| `.DS_Store` ×12 (root, `.github/`, `android/`, `assets/`, `assets/images/`, `ios/`, `ios/Runner/`, `lib/`, `lib/core/`, `lib/ui/`, `macos/`, `macos/Runner/`) | \~0.1 MB | Add `.DS_Store` + `**/.DS_Store` to `.gitignore`, `git rm --cached` them |
| `save_settings.local_json.txt` | 21 KB | Local settings dump — remove from repo |
| `gitignore` (stray duplicate of `.gitignore`, no dot) | 10 KB | Remove — it does nothing |
| ~~`CLAUDE_old.md`~~ | 45 KB | ✅ **DONE** (`2b5a6e7`) — was superseded by `CLAUDE.md` |
| `docs/api_samples/` (incl. `student_fivermail/02_GET_auth_user.full.json`, 1.35 MB) | 1.4 MB | Dev-only API dumps. ⚠️ `GET_auth_user.full.json` looks like a **real user payload** — a privacy reason to remove it from a repo, not just a size one |

**Estimated saving: \~47 MB and \~1,575 files (≈68% of the repo).**

Suggested `.gitignore` additions:

```gitignore theme={null}
# macOS Finder junk
.DS_Store
**/.DS_Store

# graphify knowledge graph output (uncomment the existing line)
graphify-out/
```

***

## B. Unused assets — zero references anywhere (39 files, \~3.5 MB) — ✅ DONE (28/09/2026)

Every file in `assets/images`, `assets/icons`, `assets/svg` was scanned for its filename across
`lib/`, `web/`, `test/`, `integration_test/`, `pubspec.yaml`, `flutter_native_splash.yaml`,
translations and asset HTML. These had **zero hits** and were **all deleted on 28/09/2026**
(re-verified by the full asset audit first; `flutter analyze` → 0 errors after).

⚠️ These were also **shipped inside every app build** (the `pubspec.yaml` `assets:` globs include
their folders), so deleting them shrank the deployed web bundle and the APK/IPA too — not just the
git repo.

> [accordion] The 39 deleted assets, by size
>
> | Asset | Size |
> | - | -: |
> | `assets/images/Rectangle.png` | 1,141 KB |
> | `assets/images/training_details_holder.png` | 859 KB |
> | `assets/images/start_quiz.png` | 464 KB |
> | `assets/images/trainingPic3.png` | 124 KB |
> | `assets/images/trainingPic2.png` | 107 KB |
> | `assets/images/start_quiz.jpg` | 88 KB |
> | `assets/icons/avatar2.png` | 75 KB |
> | `assets/images/exam.jpg` | 67 KB |
> | `assets/images/forgot_password_img.png` | 54 KB |
> | `assets/images/certificate_enhanced.png` | 51 KB |
> | `assets/images/profilePlaceholder2.png` | 37 KB |
> | `assets/images/placeholder-image.png` | 33 KB |
> | `assets/images/discountTraining_2.png` | 27 KB |
> | `assets/images/discountTraining.png` | 26 KB |
> | `assets/images/price_tag.png` | 23 KB |
> | `assets/images/profilePlaceholder.png` | 22 KB |
> | `assets/images/classroom.png` | 20 KB |
> | `assets/images/linkedin.png` | 20 KB |
> | `assets/images/google.png` | 19 KB |
> | `assets/images/quizImage.png` | 17 KB |
> | `assets/images/facebook.png` | 15 KB |
> | `assets/images/emptyImagePlaceholder.png` | 14 KB |
> | `assets/images/landingPage.png` | 11 KB |
> | `assets/icons/azalaiLogo.png` | 9 KB |
> | `assets/images/quiz-image.png` | 4 KB |
> | `assets/images/bell.jpg` | 2 KB |
> | `assets/icons/appbar_icons/role-permissions.svg` | 1.9 KB |
> | `assets/icons/password.svg` | 1.7 KB |
> | `assets/svg/google-authenticator-logo.svg` | 1.5 KB |
> | `assets/svg/ellipse_12.svg` | 1.5 KB |
> | `assets/icons/cart_icon.svg` | 1.2 KB |
> | `assets/icons/cadeau_icon.svg` | 1.0 KB |
> | `assets/icons/cart-checked.svg` | 0.8 KB |
> | `assets/icons/moon.svg` | 0.6 KB |
> | `assets/icons/user.svg` | 0.5 KB |
> | `assets/icons/unban.svg` | 0.5 KB |
> | `assets/icons/filter_icon.svg` | 0.5 KB |
> | `assets/icons/filter.svg` | 0.5 KB |
> | `assets/icons/appbar_icons/reminder.svg` | 0.3 KB |

Fonts were already clean before this pass: only the 6 Poppins weights actually used are tracked,
and all 6 are declared in `pubspec.yaml` (the Update 33 trim). Nothing to do there.

***

## C. Design-template HTML shipped inside the app bundle — ✅ DONE (`2b5a6e7`)

`pubspec.yaml` declares `- assets/`, which bundles every file at the root of `assets/` into the
**web build, APK and IPA** — but the design templates were only referenced from Dart *comments*
(they're the visual source of truth, never loaded at runtime).

**Executed in `2b5a6e7`:** the 4 templates were `git mv`-ed from `assets/` to `docs/templates/`
(\~295 KB no longer ships in any build), every path reference was updated (`CLAUDE.md`,
`AGENTS.md`, `major_code_updates.md`, the clean-up file itself, and 8 Dart doc-comments), and the
3 stale `/assets/*template.html` `.gitignore` rules were dropped so the templates stay tracked as
documentation.

| File | Size | Status |
| - | -: | - |
| `docs/templates/strived_pages_mobile_template.html` | 133 KB | ✅ moved |
| `docs/templates/strived_pages_template.html` | 72 KB | ✅ moved |
| `docs/templates/theteam_onboarding_template.html` | \~50 KB | ✅ moved |
| `docs/templates/training_preview_page_template.html` | \~40 KB | ✅ moved |
| `assets/privacy_policy_{en,fr,ar}.html` | 3×\~70 KB | **KEPT in assets/** — loaded by `web_view_privacy_policy.dart` at runtime |

> `gridview_items_cards_designs_template.html` (referenced in docs but never committed — it was
> gitignored) had its doc references rewritten to `docs/templates/` too, so it lands there if ever
> restored.

***

## D. Dart files never imported anywhere (56 files, \~330 KB) — ✅ DONE (08/10/2026)

No `import` / `export` / `part` reference to these files existed in `lib/`, `test/` or
`integration_test/`. The 6 empty files (the whole `content_manager_pages/profile/` folder) went in
`2b5a6e7`; **the remaining 50 were deleted on 08/10/2026** (436 KB on disk).

Before deleting, every file was re-checked with an import-graph scan that resolves
`package:strived/…`, relative and `part` URIs **and the `if (dart.library.html) '…'` branches of
conditional imports** (that is why `url_strategy_web.dart` / `iframe_view_factory_web.dart` are
*not* dead although nothing names them directly). Four folders became empty and were removed:
`ui/widgets/exam/`, `ui/widgets/shared/stepper/`, `ui/widgets/side_menu_test_widget/`,
`ui/pages/admin_pages/plateform_config/widget/`. The 11 assets only these files referenced (see the
asset audit below) went with them. No package lost its last importer because of this batch.
`CLAUDE.md` §4 tree updated (`web_context_menu_wrapper.dart` removed, file count 707).
`flutter analyze` after the batch: 0 errors, 10 warnings (unchanged), infos 143 → 134.

Two known-issue side effects: deleting `profile_side_widget.dart` removes the dashboard
"Edit profile information" button that opened the shopping cart (known issue 20), and deleting
`lesson_content_screen.dart` removes the unused fourth HTML renderer mentioned in known issue 12.

> [accordion] The 56 deleted files, by size
>
> | File | Size |
> | - | -: |
> | `lib/ui/widgets/preview_voucher_widget.dart` | 24.5 KB |
> | `lib/ui/widgets/exam/featured_exams_widget.dart` | 23.2 KB |
> | `lib/ui/pages/student_pages/training/quiz/quiz_preview_widget/training_quiz_preview_side_menu_option.dart` | 17.2 KB |
> | `lib/ui/widgets/training/assing_training_widget/assign_training_widget.dart` | 17.0 KB |
> | `lib/ui/widgets/shared/stepper/stepper.dart` | 15.2 KB |
> | `lib/ui/widgets/training/training_assigned_students.dart` | 13.9 KB |
> | `lib/ui/widgets/leaderboard_card_dynamic.dart` | 12.6 KB |
> | `lib/ui/widgets/exam/details_exam_preview_widget.dart` | 12.0 KB |
> | `lib/ui/widgets/coupons_and_vouchers_widgets/select_discount_type_widget.dart` | 11.6 KB |
> | `lib/ui/widgets/coupons_and_vouchers_widgets/coupon_grid_item_widget.dart` | 11.0 KB |
> | `lib/ui/widgets/exam/preview_exam_landing_widget.dart` | 10.9 KB |
> | `lib/ui/pages/admin_pages/dashboard/last_three_orders.dart` | 10.9 KB |
> | `lib/ui/widgets/import_certif_config_dialog.dart` | 10.3 KB |
> | `lib/ui/widgets/paginated_user_autocomplete.dart` | 9.1 KB |
> | `lib/ui/widgets/training/training_reviews_widget.dart` | 8.9 KB |
> | `lib/ui/widgets/coupons_and_vouchers_widgets/admin_create_coupon_apply_details_widget.dart` | 8.1 KB |
> | `lib/ui/widgets/training/custom_details_training_pager.dart` | 7.4 KB |
> | `lib/ui/pages/student_pages/dashboard/widget/profile_side_widget.dart` | 7.0 KB |
> | `lib/ui/widgets/coupons_and_vouchers_widgets/voucher_grid_item_widget.dart` | 6.6 KB |
> | `lib/ui/widgets/exam/start_exam_widget.dart` | 6.0 KB |
> | `lib/ui/pages/admin_pages/coupons/display_coupon_widget.dart` | 6.0 KB |
> | `lib/ui/pages/admin_pages/plateform_config/widget/platfrom_acitivity_listtile.dart` | 5.7 KB |
> | `lib/ui/widgets/custom_alert_dialog_widget.dart` | 5.4 KB |
> | `lib/ui/widgets/side_menu_test_widget/filter_side.dart` | 5.3 KB |
> | `lib/ui/pages/admin_pages/dashboard/admin_dashboard_card.dart` | 4.2 KB |
> | `lib/ui/widgets/side_menu_test_widget/navigation_side.dart` | 4.2 KB |
> | `lib/ui/widgets/language_picker_dropdown.dart` | 4.1 KB |
> | `lib/ui/widgets/search_filter_widget.dart` | 4.1 KB |
> | `lib/ui/widgets/shared/custom_textfield_widget.dart` | 4.0 KB |
> | `lib/ui/widgets/quiz/custom_checkbox_listtile.dart` | 3.9 KB |
> | `lib/ui/widgets/coupons_and_vouchers_widgets/calendar_date_picker2_widget.dart` | 3.8 KB |
> | `lib/core/services/question_initialization_service.dart` | 3.8 KB |
> | `lib/ui/pages/student_pages/training/quiz/quiz_review_widget/training_quiz_review_listtile_widget.dart` | 3.6 KB |
> | `lib/ui/widgets/filter_status_radio_list.dart` | 3.5 KB |
> | `lib/ui/widgets/two_button_dialog_widget.dart` | 3.4 KB |
> | `lib/ui/pages/admin_pages/coupons/admin_coupon_details_popup.dart` | 2.6 KB |
> | `lib/ui/widgets/import_export_button.dart` | 2.4 KB |
> | `lib/ui/widgets/setting_listile_widget.dart` | 2.2 KB |
> | `lib/core/utils/resources/language_manager.dart` | 2.2 KB |
> | `lib/ui/pages/screen_size_error_page.dart` | 2.2 KB |
> | `lib/ui/pages/admin_pages/plateform_config/landing/widget/preview_landing_page_dialog.dart` | 2.0 KB |
> | `lib/ui/themes/zoom_utils.dart` | 1.8 KB |
> | `lib/ui/pages/student_pages/training/lesson_content_screen.dart` | 1.3 KB |
> | `lib/config/web_context_menu_wrapper.dart` | 1.3 KB |
> | `lib/ui/widgets/quiz/curved_line.dart` | 1.0 KB |
> | `lib/ui/widgets/training/certificate_container_widget.dart` | 0.9 KB |
> | `lib/ui/widgets/counter_animated_text.dart` | 0.9 KB |
> | `lib/core/data/response_type/exam_import_response.dart` | 0.8 KB |
> | `lib/ui/widgets/custom_scaffold.dart` | 0.4 KB |
> | `lib/core/model/mobile_setting_item_model.dart` | 0.3 KB |
> | ~~`lib/ui/widgets/student/mobile/bottom_bar_widget.dart`~~ | ✅ `2b5a6e7` (was empty) |
> | ~~`lib/ui/pages/content_manager_pages/profile/contentManager_work_experience.dart`~~ | ✅ `2b5a6e7` (was empty) |
> | ~~`lib/ui/pages/content_manager_pages/profile/contentManager_public_profile.dart`~~ | ✅ `2b5a6e7` (was empty) |
> | ~~`lib/ui/pages/content_manager_pages/profile/contentManager_education.dart`~~ | ✅ `2b5a6e7` (was empty) |
> | ~~`lib/ui/pages/content_manager_pages/profile/contentManager_edit_profile_home_main.dart`~~ | ✅ `2b5a6e7` (was empty) |
> | ~~`lib/ui/pages/content_manager_pages/profile/contentManager_certificate.dart`~~ | ✅ `2b5a6e7` (was empty) |

### D.2 Newly orphaned since 28/09/2026 (10 files, \~120 KB) — ✅ DONE (23/10/2026)

The same scan on 08/10/2026 found 10 more files that nothing imports any more (they lost their
last importer in Updates 30–92, or were missed by the first grep). They were outside the list the
clean-up was asked for, so they were left in place for a decision, then **deleted on 23/10/2026**
(commit `89da932`, frontend Update 145) after a fresh import-graph walk from `main.dart` + the tests
(imports / exports / parts, conditional imports included) confirmed nothing reachable used them.
The `ExamSimulatorBanner` note in the frontend `CLAUDE.md` §3 was trimmed to match (31/10/2026).

The same commit removed **17 more orphans** the walk found; every reference to them came from
inside the orphan group itself:

* the admin coupon / voucher detail widgets: `admin_pages/coupons/admin_view_coupon_details_widget.dart`,
  `admin_pages/vouchers/admin_view_voucher_details_widget.dart`,
  `coupons_and_vouchers_widgets/admin_view_coupon_details_widget.dart`,
  `coupons_and_vouchers_widgets/coupon/dynamic_ticket_widget.dart`;
* the rest of the old reminders dialog stack: `reminders/dropdown_data_widget.dart`,
  `reminders/custom_dropdown_widget.dart` (superseded by `notification_sender_view`);
* the 5 `src/` files left in the vendored `ui/widgets/shared/stepper/` folder (its `stepper.dart`
  went in Section D);
* the old training-content stack: `training/training_content_widget.dart`,
  `quiz/quiz_chapter_widget.dart`, `quiz/quiz_training_widget.dart`, `quiz/card_details_widget.dart`;
* the iframe view-factory pair `plateform_config/landing/widget/iframe_view_factory.dart` /
  `iframe_view_factory_web.dart`. Nothing reachable imports the pair any more, so the Section D note
  that kept `iframe_view_factory_web.dart` alive through a conditional import no longer applies
  (`url_strategy_web.dart` is still in use).

| File | Size |
| - | -: |
| `lib/ui/pages/admin_pages/reminders/send_notification_dialog.dart` | 37.9 KB |
| `lib/ui/pages/student_pages/cart/shopping_cart_validation_page.dart` | 16.5 KB |
| `lib/ui/pages/theme_settings.dart` | 14.5 KB |
| `lib/ui/widgets/training/assing_training_widget/assign_learners.dart` | 12.2 KB |
| `lib/ui/widgets/shopping_cart_widgets/quizz_item_shopping_cart_widget.dart` | 9.9 KB |
| `lib/ui/pages/student_pages/dashboard/widget/exam_simulator_banner.dart` | 9.4 KB |
| `lib/ui/widgets/training/assing_training_widget/unassign_learners.dart` | 8.8 KB |
| `lib/ui/widgets/shopping_cart_widgets/top_container_widget.dart` | 7.7 KB |
| `lib/ui/widgets/elevated_button_widget.dart` | 2.7 KB |
| `lib/ui/widgets/coupons_and_vouchers_widgets/reusable_text_for_fields_widget.dart` | 0.7 KB |

***

## E. Unsupported-platform shells — ✅ DONE (`2b5a6e7`)

| Path | Files | Note |
| - | -: | - |
| ~~`macos/`~~ | 30 | ✅ **REMOVED** + `/macos/` gitignored. Regenerable with `flutter create --platforms=macos .` if ever needed |
| ~~`linux/`~~ | 5 | ✅ **REMOVED** + `/linux/` gitignored. Regenerable likewise |
| `third_party/quill_native_bridge_windows/` | 15 | **KEPT** — it's a `dependency_overrides:` path in `pubspec.yaml`; deleting it breaks `flutter pub get` on every platform (see §G.2.1 point 3 for when it can go) |

`CLAUDE.md` / `AGENTS.md` project tree + the Update-28 macOS note were updated to match.

***

## F. Root-level notes clutter — ⬜ pending (optional, tiny — tidiness only)

| File | Suggestion |
| - | - |
| `authed_user_and_attempts.md` | Move to `docs/` |
| `README_changes_resume.md` | Move to `docs/` or merge into `major_code_updates.md` |
| `readme_progress_calculation_suggestion.md` | Move to `docs/` |
| `Old_Notes.md`, `major_code_updates.md`, `AGENTS.md`, `CLAUDE.md`, `README.md` | **Keep at root** — referenced by CLAUDE.md / agent onboarding |

***

## G. pubspec.yaml package audit (added 28/09/2026, versions bumped 08/10/2026)

### G.1 Unused packages — ✅ DONE (08/10/2026)

Every `package:<name>/` import was grepped across `lib/`, `test/`, `integration_test/`, plus
usage-without-import checks (`CupertinoIcons.`, `GoogleFonts`, `LoggingIntegration`,
`FlutterNativeSplash`). These 11 had **zero** hits:

| Package | Declared | Why it was unused |
| - | - | - |
| `cupertino_icons` | `^1.0.9` | 0 uses of `CupertinoIcons.` anywhere |
| `google_fonts` | `^8.2.1` | 0 uses — Poppins is bundled locally in `assets/fonts/` |
| `logger` | `^2.8.0` | 0 imports, 0 `Logger(` calls |
| `uuid` | `^4.6.0` | 0 imports |
| `quiver` | `^3.2.2` | 0 imports |
| `progress_stepper` | `^3.1.0` | 0 imports — the app used its own `lib/ui/widgets/shared/stepper/` (itself dead, Section D) |
| `mime_type` | `^1.0.1` | 0 imports |
| `infinite_scroll_pagination` | `^5.1.1` | 0 imports |
| `path_provider` | `^2.1.6` | 0 direct imports (plugins that need it pull it in transitively) |
| `sentry_logging` | `^9.30.1` | 0 imports — no `LoggingIntegration` is registered in `main.dart` |
| `logging` | `^1.3.0` | 0 imports — only existed to feed `sentry_logging` |

**Removed from `pubspec.yaml` on 08/10/2026 — 13 packages in total.** The re-audit run after
Section D (this time covering the `flutter_*` names the first grep skipped) found two more with
zero imports: **`flutter_rating_bar`** (its only mentions are commented-out `RatingBarIndicator`
blocks in `trainings_filters_widget.dart`) and **`super_banners`** — both removed too, and
`progress_stepper` was already commented out. `pubspec.lock` lost 9 packages
(`flutter_rating_bar`, `google_fonts`, `infinite_scroll_pagination`, `logger`, `mime_type`,
`sentry_logging`, `super_banners` + the transitive `flutter_staggered_grid_view`, `sliver_tools`).
`cupertino_icons`, `uuid`, `quiver`, `path_provider` and `logging` are still in the lock file as
**transitive** dependencies of other packages (`chewie`, `dropdown_search`, Syncfusion,
`flutter_quill`, plugins…), so the app no longer declares them but they still ship — nothing to do
about that. `flutter analyze` after the removal: 0 errors, the same 10 warnings; 433 tests pass;
`flutter build web --release` OK.

**Not removable despite looking idle:**

| Package | Keep because |
| - | - |
| `font_awesome_flutter` | Only 1 import (the `fa_compat.dart` shim) but it **ships the FA glyph fonts** every `FontAwesomeIcons.*` const points at (CLAUDE.md §3) |
| `flutter_native_splash` | No Dart import, but the splash is generated from `flutter_native_splash.yaml` via its CLI (Update 28). Could move to `dev_dependencies` since no runtime API (`preserve()`) is called |
| `syncfusion_flutter_core` / `syncfusion_localizations` | Required peers / localization delegates of the Syncfusion widgets |
| `flutter_web_plugins` | Used by `lib/config/url_strategy_web.dart` (hash-URL removal) |
| `http` | 2 real imports alongside dio |
| dependency\_overrides (`quill_native_bridge_windows` path) | Vendored `win32` 5 copy required for `flutter pub get` to resolve (§G.2.1 point 3). The `image_cropper_platform_interface` and `flutter_lints ^4` overrides were Flutter 3.27 leftovers, removed 08/10/2026 |

### G.2 Version freshness — installed vs latest on pub.dev

**Refreshed 08/10/2026, after the version bump** (first snapshot: 28/09/2026). Toolchain:
**Flutter 3.44.6 / Dart 3.12.2**. Every package was moved to the newest version that resolves on
that toolchain. "Installed" is the resolved version in `pubspec.lock`; **bold (was x)** marks what
the bump changed. "Latest" is the newest stable release on pub.dev, and its date tells you when the
developers last shipped. Each name links to the package's versions page.

Status: ✅ on the latest release · 🔒 on the newest version this toolchain can use (the cell says
what blocks the next one; details in §G.2.1). Totals: **54 ✅ · 21 🔒** (70 dependencies + 5 dev
dependencies). The 13 🗑️ **UNUSED** rows of the first snapshot were removed from `pubspec.yaml`
on 08/10/2026 (§G.1), `flip_card` was replaced the same day (§G.4), and
`custom_sliding_segmented_control` went back to 1.8.5 after its 2.0 broke the app (§G.2.1 point 5).

> [accordion] The full dependency table (70 packages)
>
> | Package | Constraint | Installed | Installed release date | Latest | Latest release (dev's last update) | Status |
> | - | - | - | - | - | - | - |
> | [provider](https://pub.dev/packages/provider/versions) | `^6.1.5+1` | 6.1.5+1 | 2025-08-19 (1y 2mo ago) | 6.1.5+1 | 2025-08-19 (1y 2mo ago) | ✅ latest |
> | [get\_it](https://pub.dev/packages/get_it/versions) | `^9.3.0` | **9.3.0** (was 8.3.0) | 2026-09-19 (19d ago) | 9.3.0 | 2026-09-19 (19d ago) | ✅ latest |
> | [dio](https://pub.dev/packages/dio/versions) | `^5.11.1` | 5.11.1 | 2026-09-04 (1mo ago) | 5.11.1 | 2026-09-04 (1mo ago) | ✅ latest |
> | [retrofit](https://pub.dev/packages/retrofit/versions) | `^4.10.0` | **4.10.0** (was 4.8.0) | 2026-08-13 (2mo ago) | 4.10.0 | 2026-08-13 (2mo ago) | ✅ latest |
> | [http](https://pub.dev/packages/http/versions) | `^1.6.0` | 1.6.0 | 2025-11-10 (11mo ago) | 1.6.0 | 2025-11-10 (11mo ago) | ✅ latest |
> | [shared\_preferences](https://pub.dev/packages/shared_preferences/versions) | `^2.5.6` | **2.5.6** (was 2.5.5) | 2026-10-05 (3d ago) | 2.5.6 | 2026-10-05 (3d ago) | ✅ latest |
> | [font\_awesome\_flutter](https://pub.dev/packages/font_awesome_flutter/versions) | `^11.0.0` | 11.0.0 | 2026-03-09 (7mo ago) | 11.0.0 | 2026-03-09 (7mo ago) | ✅ latest |
> | [flutter\_svg](https://pub.dev/packages/flutter_svg/versions) | `^2.3.0` | 2.3.0 | 2026-05-08 (5mo ago) | 2.3.0 | 2026-05-08 (5mo ago) | ✅ latest |
> | [lottie](https://pub.dev/packages/lottie/versions) | `^3.6.1` | 3.6.1 | 2026-09-18 (20d ago) | 3.6.1 | 2026-09-18 (20d ago) | ✅ latest |
> | [animations](https://pub.dev/packages/animations/versions) | `^3.0.0` | **3.0.0** (was 2.2.0) | 2026-08-19 (2mo ago) | 3.0.0 | 2026-08-19 (2mo ago) | ✅ latest |
> | [auto\_size\_text](https://pub.dev/packages/auto_size_text/versions) | `^3.0.0` | 3.0.0 | 2021-10-27 (4y 11mo ago) | 3.0.0 | 2021-10-27 (4y 11mo ago) | ✅ latest |
> | [dotted\_border](https://pub.dev/packages/dotted_border/versions) | `^3.1.0` | **3.1.0** (was 2.1.0) | 2025-06-29 (1y 3mo ago) | 3.1.0 | 2025-06-29 (1y 3mo ago) | ✅ latest |
> | [syncfusion\_flutter\_core](https://pub.dev/packages/syncfusion_flutter_core/versions) | `^33.2.15` | **33.2.15** (was 28.2.12) | 2026-06-24 (3mo ago) | 35.1.39 | 2026-10-07 (1d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [syncfusion\_localizations](https://pub.dev/packages/syncfusion_localizations/versions) | `^33.2.15` | **33.2.15** (was 28.2.12) | 2026-06-24 (3mo ago) | 35.1.39 | 2026-10-07 (1d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [syncfusion\_flutter\_datagrid](https://pub.dev/packages/syncfusion_flutter_datagrid/versions) | `^33.2.15` | **33.2.15** (was 28.2.12) | 2026-06-24 (3mo ago) | 35.1.39 | 2026-10-07 (1d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [chewie](https://pub.dev/packages/chewie/versions) | `^1.13.1` | 1.13.1 | 2026-04-14 (6mo ago) | 1.17.2 | 2026-09-16 (22d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [video\_player](https://pub.dev/packages/video_player/versions) | `^2.14.1` | **2.14.1** (was 2.14.0) | 2026-10-02 (6d ago) | 2.14.1 | 2026-10-02 (6d ago) | ✅ latest |
> | [youtube\_player\_iframe](https://pub.dev/packages/youtube_player_iframe/versions) | `^6.0.2` | **6.0.2** (was 5.2.2) | 2026-05-30 (4mo ago) | 6.0.2 | 2026-05-30 (4mo ago) | ✅ latest |
> | [image\_picker](https://pub.dev/packages/image_picker/versions) | `^1.2.4` | **1.2.4** (was 1.2.3) | 2026-10-06 (2d ago) | 1.2.4 | 2026-10-06 (2d ago) | ✅ latest |
> | [file\_picker](https://pub.dev/packages/file_picker/versions) | `^10.3.10` | 10.3.10 | 2026-01-28 (8mo ago) | 13.1.0 | 2026-09-15 (23d ago) | 🔒 `html_editor_enhanced` needs ^10 |
> | [easy\_localization](https://pub.dev/packages/easy_localization/versions) | `^3.0.8` | 3.0.8 | 2025-07-24 (1y 2mo ago) | 3.0.8 | 2025-07-24 (1y 2mo ago) | ✅ latest |
> | [intl](https://pub.dev/packages/intl/versions) | `^0.20.2` | 0.20.2 | 2025-01-24 (1y 8mo ago) | 0.20.3 | 2026-06-25 (3mo ago) | 🔒 Flutter SDK pin (`flutter_localizations`) |
> | [json\_annotation](https://pub.dev/packages/json_annotation/versions) | `^4.12.0` | **4.12.0** (was 4.9.0) | 2026-05-15 (5mo ago) | 4.12.0 | 2026-05-15 (5mo ago) | ✅ latest |
> | [collection](https://pub.dev/packages/collection/versions) | `^1.19.1` | 1.19.1 | 2024-10-21 (2y 0mo ago) | 1.19.1 | 2024-10-21 (2y 0mo ago) | ✅ latest |
> | [expandable](https://pub.dev/packages/expandable/versions) | `^5.0.1` | 5.0.1 | 2021-03-16 (5y 7mo ago) | 5.0.1 | 2021-03-16 (5y 7mo ago) | ✅ latest |
> | [percent\_indicator](https://pub.dev/packages/percent_indicator/versions) | `^4.2.5` | 4.2.5 | 2025-04-08 (1y 6mo ago) | 4.2.5 | 2025-04-08 (1y 6mo ago) | ✅ latest |
> | [modal\_side\_sheet](https://pub.dev/packages/modal_side_sheet/versions) | `^0.0.1` | 0.0.1 | 2021-08-17 (5y 2mo ago) | 0.0.1 | 2021-08-17 (5y 2mo ago) | ✅ latest |
> | [cached\_network\_image](https://pub.dev/packages/cached_network_image/versions) | `^4.0.3` | **4.0.3** (was 3.4.1) | 2026-09-29 (9d ago) | 4.0.4 | 2026-09-30 (8d ago) | 🔒 4.0.4 needs `material_ui` 1.3 (SDK pins 1.2.0) |
> | [custom\_sliding\_segmented\_control](https://pub.dev/packages/custom_sliding_segmented_control/versions) | `^1.8.5` | 1.8.5 | 2025-01-09 (1y 9mo ago) | 2.0.0 | 2026-09-03 (1mo ago) | 🔒 2.0 moved to `material_ui` (§G.2.1 point 5) |
> | [flutter\_form\_builder](https://pub.dev/packages/flutter_form_builder/versions) | `^10.3.0+2` | 10.3.0+2 | 2026-02-14 (8mo ago) | 11.0.0 | 2026-08-15 (2mo ago) | 🔒 11.x needs Flutter ≥ 3.47 |
> | [form\_builder\_validators](https://pub.dev/packages/form_builder_validators/versions) | `^11.3.0` | 11.3.0 | 2026-02-03 (8mo ago) | 11.3.0 | 2026-02-03 (8mo ago) | ✅ latest |
> | [image\_cropper](https://pub.dev/packages/image_cropper/versions) | `^12.2.1` | **12.2.1** (was 9.0.0) | 2026-04-15 (6mo ago) | 12.2.1 | 2026-04-15 (6mo ago) | ✅ latest |
> | [connectivity\_plus](https://pub.dev/packages/connectivity_plus/versions) | `^7.3.1` | **7.3.1** (was 6.1.5) | 2026-07-23 (3mo ago) | 7.3.2 | 2026-10-01 (7d ago) | 🔒 7.3.2 needs `dbus` 0.8 (`file_picker` 10 holds 0.7) |
> | [device\_info\_plus](https://pub.dev/packages/device_info_plus/versions) | `^12.4.0` | **12.4.0** (was 11.5.0) | 2026-03-30 (6mo ago) | 13.3.0 | 2026-10-01 (7d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [go\_router](https://pub.dev/packages/go_router/versions) | `^18.0.2` | **18.0.2** (was 16.3.0) | 2026-09-28 (10d ago) | 18.0.2 | 2026-09-28 (10d ago) | ✅ latest |
> | [tuple](https://pub.dev/packages/tuple/versions) | `^2.0.2` | 2.0.2 | 2023-06-12 (3y 4mo ago) | 2.0.2 | 2023-06-12 (3y 4mo ago) | ✅ latest |
> | [dropdown\_search](https://pub.dev/packages/dropdown_search/versions) | `^7.0.0` | **7.0.0** (was 6.0.2) | 2026-04-03 (6mo ago) | 8.1.0 | 2026-09-28 (10d ago) | 🔒 8.x needs `material_ui` 1.4 (SDK pins 1.2.0) |
> | [universal\_html](https://pub.dev/packages/universal_html/versions) | `^2.3.0` | 2.3.0 | 2025-11-16 (11mo ago) | 2.3.0 | 2025-11-16 (11mo ago) | ✅ latest |
> | [fluid\_dialog](https://pub.dev/packages/fluid_dialog/versions) | `^2.0.0` | 2.0.0 | 2023-06-29 (3y 3mo ago) | 2.0.0 | 2023-06-29 (3y 3mo ago) | ✅ latest |
> | [flutter\_side\_menu](https://pub.dev/packages/flutter_side_menu/versions) | `^0.5.41` | 0.5.41 | 2024-10-15 (2y 0mo ago) | 0.5.41 | 2024-10-15 (2y 0mo ago) | ✅ latest |
> | [styled\_divider](https://pub.dev/packages/styled_divider/versions) | `^1.0.5` | 1.0.5 | 2023-05-13 (3y 5mo ago) | 1.0.5 | 2023-05-13 (3y 5mo ago) | ✅ latest |
> | [fl\_chart](https://pub.dev/packages/fl_chart/versions) | `^1.2.0` | **1.2.0** (was 0.70.2) | 2026-03-13 (7mo ago) | 1.2.0 | 2026-03-13 (7mo ago) | ✅ latest |
> | [flex\_color\_picker](https://pub.dev/packages/flex_color_picker/versions) | `^3.8.0` | 3.8.0 | 2025-11-26 (10mo ago) | 4.0.0 | 2026-08-30 (1mo ago) | 🔒 4.x needs Flutter ≥ 3.47 |
> | [pointer\_interceptor](https://pub.dev/packages/pointer_interceptor/versions) | `^0.10.1+3` | 0.10.1+3 | 2026-09-15 (23d ago) | 0.10.1+3 | 2026-09-15 (23d ago) | ✅ latest |
> | [flutter\_widget\_from\_html](https://pub.dev/packages/flutter_widget_from_html/versions) | `^0.17.4` | **0.17.4** (was 0.15.3) | 2026-09-08 (30d ago) | 0.17.4 | 2026-09-08 (30d ago) | ✅ latest |
> | [markdown](https://pub.dev/packages/markdown/versions) | `^7.3.1` | 7.3.1 | 2026-03-18 (7mo ago) | 7.3.1 | 2026-03-18 (7mo ago) | ✅ latest |
> | [url\_launcher](https://pub.dev/packages/url_launcher/versions) | `^6.3.3` | **6.3.3** (was 6.3.2) | 2026-10-02 (6d ago) | 6.3.3 | 2026-10-02 (6d ago) | ✅ latest |
> | [animated\_toggle\_switch](https://pub.dev/packages/animated_toggle_switch/versions) | `^0.8.7` | 0.8.7 | 2026-01-09 (9mo ago) | 0.8.7 | 2026-01-09 (9mo ago) | ✅ latest |
> | [html\_editor\_enhanced](https://pub.dev/packages/html_editor_enhanced/versions) | `^2.7.1` | 2.7.1 | 2025-07-12 (1y 3mo ago) | 2.7.1 | 2025-07-12 (1y 3mo ago) | ✅ latest |
> | [circle\_progress\_bar](https://pub.dev/packages/circle_progress_bar/versions) | `^0.1.4` | 0.1.4 | 2026-06-05 (4mo ago) | 0.1.4 | 2026-06-05 (4mo ago) | ✅ latest |
> | [webview\_flutter](https://pub.dev/packages/webview_flutter/versions) | `^4.14.1` | 4.14.1 | 2026-07-07 (3mo ago) | 4.14.1 | 2026-07-07 (3mo ago) | ✅ latest |
> | [webview\_flutter\_android](https://pub.dev/packages/webview_flutter_android/versions) | `^4.14.1` | 4.14.1 | 2026-08-28 (1mo ago) | 4.14.1 | 2026-08-28 (1mo ago) | ✅ latest |
> | [webview\_flutter\_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/versions) | `^3.26.2` | 3.26.2 | 2026-09-29 (9d ago) | 3.27.0 | 2026-10-01 (7d ago) | 🔒 3.27 needs Flutter ≥ 3.47 |
> | [flutter\_secure\_storage](https://pub.dev/packages/flutter_secure_storage/versions) | `^10.3.4` | **10.3.4** (was 9.2.4) | 2026-09-13 (25d ago) | 11.2.0 | 2026-09-16 (22d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [flutter\_native\_splash](https://pub.dev/packages/flutter_native_splash/versions) | `^2.4.8` | 2.4.8 | 2026-05-29 (4mo ago) | 2.4.8 | 2026-05-29 (4mo ago) | ✅ latest |
> | [flutter\_quill](https://pub.dev/packages/flutter_quill/versions) | `^11.6.0` | 11.6.0 | 2026-09-16 (22d ago) | 11.6.0 | 2026-09-16 (22d ago) | ✅ latest |
> | [flutter\_quill\_extensions](https://pub.dev/packages/flutter_quill_extensions/versions) | `^11.0.0` | 11.0.0 | 2025-02-17 (1y 8mo ago) | 11.0.0 | 2025-02-17 (1y 8mo ago) | ✅ latest |
> | [heroicons](https://pub.dev/packages/heroicons/versions) | `^0.11.0` | 0.11.0 | 2024-12-15 (1y 10mo ago) | 0.11.0 | 2024-12-15 (1y 10mo ago) | ✅ latest |
> | [permission\_handler](https://pub.dev/packages/permission_handler/versions) | `^12.0.3` | **12.0.3** (was 11.4.0) | 2026-06-01 (4mo ago) | 13.0.2 | 2026-09-04 (1mo ago) | 🔒 13.x needs Android compileSdk 37 (§G.2.1) |
> | [flutter\_local\_notifications](https://pub.dev/packages/flutter_local_notifications/versions) | `^22.3.1` | **22.3.1** (was 18.0.1) | 2026-09-13 (25d ago) | 22.3.1 | 2026-09-13 (25d ago) | ✅ latest |
> | [open\_file](https://pub.dev/packages/open_file/versions) | `^4.0.0` | **4.0.0** (was 3.5.11) | 2026-06-10 (4mo ago) | 4.0.0 | 2026-06-10 (4mo ago) | ✅ latest |
> | [qr\_flutter](https://pub.dev/packages/qr_flutter/versions) | `^4.1.0` | 4.1.0 | 2023-05-14 (3y 5mo ago) | 4.1.0 | 2023-05-14 (3y 5mo ago) | ✅ latest |
> | [file\_saver](https://pub.dev/packages/file_saver/versions) | `^0.4.0` | **0.4.0** (was 0.2.14) | 2026-05-10 (5mo ago) | 0.7.0 | 2026-10-06 (2d ago) | 🔒 0.5+ needs `meta` 1.19 (SDK pins 1.18.0) |
> | [cloudflare\_turnstile](https://pub.dev/packages/cloudflare_turnstile/versions) | `^3.8.1` | 3.8.1 | 2026-07-29 (2mo ago) | 3.8.1 | 2026-07-29 (2mo ago) | ✅ latest |
> | [syncfusion\_flutter\_pdfviewer](https://pub.dev/packages/syncfusion_flutter_pdfviewer/versions) | `^33.2.13` | **33.2.13** (was 28.2.12) | 2026-06-16 (4mo ago) | 35.1.39 | 2026-10-07 (1d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [shimmer](https://pub.dev/packages/shimmer/versions) | `^4.0.0` | **4.0.0** (was 3.0.0) | 2026-08-21 (2mo ago) | 4.0.0 | 2026-08-21 (2mo ago) | ✅ latest |
> | [fleather](https://pub.dev/packages/fleather/versions) | `^1.28.0` | 1.28.0 | 2026-08-24 (1mo ago) | 1.28.0 | 2026-08-24 (1mo ago) | ✅ latest |
> | [syncfusion\_flutter\_datepicker](https://pub.dev/packages/syncfusion_flutter_datepicker/versions) | `^33.2.15` | **33.2.15** (was 28.2.12) | 2026-06-24 (3mo ago) | 35.1.39 | 2026-10-07 (1d ago) | 🔒 `win32` 5 chain (§G.2.1) |
> | [showcaseview](https://pub.dev/packages/showcaseview/versions) | `^5.1.0` | 5.1.0 | 2026-06-17 (4mo ago) | 5.1.0 | 2026-06-17 (4mo ago) | ✅ latest |
> | [sentry\_flutter](https://pub.dev/packages/sentry_flutter/versions) | `^9.30.1` | 9.30.1 | 2026-09-22 (16d ago) | 9.30.1 | 2026-09-22 (16d ago) | ✅ latest |
>
> **Dev dependencies (build tools — not shipped in the app):**
>
> | Package | Constraint | Installed | Installed release date | Latest | Latest release (dev's last update) | Status |
> | - | - | - | - | - | - | - |
> | [flutter\_lints](https://pub.dev/packages/flutter_lints/versions) | `^6.0.0` | **6.0.0** (was 4.0.0) | 2025-05-27 (1y 4mo ago) | 6.0.0 | 2025-05-27 (1y 4mo ago) | ✅ latest |
> | [retrofit\_generator](https://pub.dev/packages/retrofit_generator/versions) | `^10.2.9` | **10.2.9** (was 9.7.0) | 2026-08-19 (2mo ago) | 10.2.11 | 2026-09-04 (1mo ago) | 🔒 10.2.10+ needs `analyzer` ≥ 13.3 → `meta` 1.18.3 (SDK pins 1.18.0) |
> | [build\_runner](https://pub.dev/packages/build_runner/versions) | `^2.15.1` | **2.15.1** (was 2.5.4) | 2026-07-08 (3mo ago) | 2.16.2 | 2026-10-07 (1d ago) | 🔒 2.16 needs `analyzer` ≥ 13.3 → `meta` 1.18.3 (SDK pins 1.18.0) |
> | [json\_serializable](https://pub.dev/packages/json_serializable/versions) | `^6.14.1` | **6.14.1** (was 6.9.5) | 2026-07-30 (2mo ago) | 6.14.1 | 2026-07-30 (2mo ago) | ✅ latest |
> | [flutter\_launcher\_icons](https://pub.dev/packages/flutter_launcher_icons/versions) | `^0.14.4` | 0.14.4 | 2025-06-10 (1y 4mo ago) | 0.14.4 | 2025-06-10 (1y 4mo ago) | ✅ latest |

#### G.2.1 Why some packages are not on the latest release

Five things hold packages back. None of them can be fixed by editing `pubspec.yaml` alone:

1. **Versions pinned by the Flutter 3.44 SDK.** The SDK fixes `intl` 0.20.2 (through
   `flutter_localizations`), `meta` 1.18.0, `material_ui` 1.2.0 and `cupertino_ui` 1.0.2.
   Releases that need newer copies can't resolve: `intl` 0.20.3, `file_saver` 0.5+ (`meta` 1.19),
   `dropdown_search` 8 (`material_ui` 1.4), `cached_network_image` 4.0.4 (`material_ui` 1.3),
   `build_runner` 2.16 and `retrofit_generator` 10.2.10+ (they need `analyzer` ≥ 13.3, which needs
   `meta` 1.18.3).
2. **Releases that already require Flutter ≥ 3.47 / Dart ≥ 3.13:** `flutter_form_builder` 11,
   `flex_color_picker` 4, `google_fonts` 9, `webview_flutter_wkwebview` 3.27. These unlock with
   the next Flutter upgrade.
3. **The `win32` 5 chain.** `html_editor_enhanced` 2.7.1 (its latest, last release 2025-07-12)
   requires `file_picker ^10`, and `file_picker` 10 requires `win32 ^5` and `dbus ^0.7`. The
   vendored `third_party/quill_native_bridge_windows` (0.0.2, `win32 ^5`) exists for the same
   reason: `flutter_quill` pulls `quill_native_bridge` 11.2, which wants the published 0.1.x on
   `win32 ^6`, and the override swaps it for the old copy so both can resolve. Every package whose
   next release moved to `win32` 6 therefore stays on its last `win32` 5 line:
   `device_info_plus` 12 (13 needs `win32` 6), `flutter_secure_storage` 10 (11's Windows plugin
   needs `win32` 6), `chewie` 1.13 (1.14+ needs `wakelock_plus` 1.6+, which needs `win32` 6 and
   `package_info_plus` 10), the five `syncfusion_*` packages on 33 (`syncfusion_flutter_pdfviewer`
   33.2.15+ needs `device_info_plus` ^13.1, and the other four follow `syncfusion_flutter_core`), and
   `connectivity_plus` 7.3.2 (needs `dbus` 0.8). The chain only comes from Windows desktop code,
   which the app doesn't ship, but pub resolves every platform. It clears when `html_editor_enhanced`
   allows `file_picker` ≥ 11 (or is replaced, see §G.4). Then delete the `quill_native_bridge_windows`
   override and its `third_party/` folder, and re-run this bump.
4. **Android toolchain.** `permission_handler` 13 compiles its Android plugin against **compileSdk
   37**. With the project's AGP 8.11.1 (`android/settings.gradle`) the build fails with
   `Failed to find target with hash string 'android-37'` (tried 08/10/2026; Gradle did install
   SDK Platform 37 as `platforms/android-37.0`, but this AGP can't use it), so it stays on 12.0.3.
   To take 13: raise AGP to a version that supports API 37 and set `compileSdk = 37` in
   `android/app/build.gradle`. (`connectivity_plus` 7 / `device_info_plus` 12 also list
   "AGP ≥ 8.12.1, Gradle ≥ 8.13, Kotlin 2.2.0" in their changelogs, but they build fine on 8.11.1.)
5. **`material_ui` is not Flutter's Material (yet).** Several 2026 releases "migrate to
   `material_ui`", the standalone package the Flutter team is carving the Material library into
   (SDK-pinned to 1.2.0 on Flutter 3.44). But `package:flutter` 3.44 does **not** depend on it and
   `package:flutter/material.dart` still ships its own classes, so `material_ui`'s `Material`,
   `InkWell`, `Scaffold`… are *different types* from the app's. A widget from such a package that
   needs a Material ancestor (`InkWell` → `debugCheckHasMaterial`) can never find the app's Flutter
   `Scaffold` and asserts `No Material widget found` — that is what broke the exam attempt review
   (`CustomSlidingSegmentedControl` in `quiz_review_side_menu_option.dart`, found 08/10/2026) and
   would have broken its other 10 call sites. `custom_sliding_segmented_control` is therefore held
   at **1.8.5**. The other bumped packages that moved to `material_ui` are safe because nothing in
   them looks for a Material ancestor: `go_router` 18 (pages render), `animations` 3 (the app only
   uses `FadeScaleTransition`), `cached_network_image` 4, `shimmer` 4. Re-check this whenever a
   changelog says "migrates to material\_ui"; the hold clears once `package:flutter/material.dart`
   itself re-exports `material_ui` (a future Flutter release).

Also on purpose: `sentry_flutter` stays on 9.30.1, the latest **stable**; pub would otherwise offer
the `10.0.0-rc.2` pre-release.

#### G.2.2 What the bump changed besides `pubspec.yaml` (08/10/2026)

| Package | Change in the code |
| - | - |
| `dotted_border` 2 → 3 | Style arguments moved into `options: RoundedRectDottedBorderOptions(...)` (same defaults, so same look). 21 call sites in 7 files: the 4 drag-and-drop question widgets, `basic_info_screen.dart`, `certification_config_screen.dart`, `lessons_importer_widget.dart`. |
| `flutter_local_notifications` 18 → 22 | `initialize(settings: …)` and `show(id:, title:, body:, notificationDetails:)` now take named arguments. Since v19 the plugin also has a real **web** side: `initialize()` registers its own service worker in place of the app's, and `show()` throws without notification permission. It used to do nothing on web, so `main.dart` now initializes it on mobile only, and the web certificate download no longer calls `show()` (its dialog already tells the user). Android needs `desugar_jdk_libs` ≥ 2.1.4 → bumped from 2.0.3 in `android/app/build.gradle`. |
| `file_saver` 0.2 → 0.4 | `ext:` renamed `fileExtension:` (2FA recovery-codes download, `two_factor_auth_provider.dart`). Same file name produced. |
| `dropdown_search` 6 → 7 | `onChanged:` renamed `onSelected:` (same `ValueChanged<T?>`): order status, user role, question type dropdowns. |
| `youtube_player_iframe` 5 → 6 | `FullscreenYoutubePlayer` was removed and `YoutubePlayerScaffold` deprecated: `YoutubePlayer` now does fullscreen itself, in an overlay with the same video and position. `web_youtube_player.dart` renders `YoutubePlayer` directly and keeps the listener only for its state and orientation reset. v6 also embeds through `youtube-nocookie.com` by default (`privacyEnhancedMode`). |
| `flutter_secure_storage` 9 → 10 | Removed the deprecated `encryptedSharedPreferences: true` (`secure_storage.dart`). On Android, tokens saved by v9 are migrated to the new ciphers on first read (`migrateOnAlgorithmChange`, on by default, checked in the plugin source), so nobody is logged out. iOS and web are unaffected. |
| `image_cropper` 9 → 12 | The exact `9.0.0` pin and the `image_cropper_platform_interface: 7.0.0` override were Flutter 3.27 workarounds (interface 8 needs Flutter ≥ 3.28): both removed. The crop call compiles unchanged. |
| `retrofit` / `retrofit_generator` | The `<4.9.0` cap from the 3.27 → 3.44 upgrade (README) is gone: retrofit 4.10 + retrofit\_generator 10 now resolve. Clients regenerated with `build_runner`; no source change. |
| `flutter_lints` 4 → 6 | The `flutter_lints: ^4.0.0` override was removed. Lints 6 adds `strict_top_level_inference` (see §G.2.3). One doc comment in `preview_training.dart` got backticks for `unintended_html_in_doc_comment`. |

No code change was needed for the other majors: `get_it` 9, `go_router` 18 (17.0 makes `ShellRoute`
navigation notify GoRouter observers; the app registers none), `animations` 3,
`cached_network_image` 4 and `shimmer` 4 (these moved to `material_ui` without needing a Material
ancestor), `fl_chart` 1.2, `flutter_widget_from_html` 0.17, `connectivity_plus` 7,
`device_info_plus` 12 (dropped `serialNumber`, unused here), `open_file` 4, `permission_handler` 12
(the app already uses the `request()` result, as the new docs ask), Syncfusion 33 (theme renames
for chat/AI widgets the app doesn't use; the PDF viewer's `pageNumber` timing, unused).

#### G.2.3 Verification (08/10/2026)

| Check | Result |
| - | - |
| `flutter pub get` | ✅ resolves |
| `dart run build_runner build` | ✅ 230 outputs. Two notices: build\_runner 2.15 ignores `-d` / `--delete-conflicting-outputs` (removed option, harmless), and json\_serializable 6.14 asks for language version ^3.8.0 while `environment: sdk: ^3.6.0` gives 3.6. Generated code compiles; it would only break if a model used `includeIfNull: false` (json\_serializable then emits Dart 3.8 null-aware elements). `sdk:` was **not** raised: that changes the language version (tall `dart format` style, wildcard `_`). |
| `flutter analyze` | ✅ 0 errors (before: 0). Warnings 10 (same 10 as before). Infos 90 → 143: the 75 deprecations and 13 `use_build_context_synchronously` are unchanged; **+53 `strict_top_level_inference`** from lints 6 (members without a declared type, mostly in providers such as `chapter_provider.dart` ×17). Info level only. |
| `flutter test` | ✅ 433 passed. The only failure is `test/widget_test.dart`, which has been fully commented out since the first commit ("Missing definition of `main` method"); not related to the bump. |
| `flutter build web --release` | ✅ built (CanvasKit). |
| `flutter build apk --debug` | ✅ built, after holding `permission_handler` on 12 and raising `desugar_jdk_libs` to 2.1.4. |

After Section D + G.1 (08/10/2026, later): `flutter analyze` 0 errors / 10 warnings / 134 infos;
433 tests pass (same single pre-existing `widget_test.dart` load failure); `flutter build web --release` OK, `main.dart.js` unchanged at 12.2 MB (dead code was already tree-shaken; the
bundle only shrinks with code splitting, see App Speed Suggestions #1).

After the `flip_card` removal, the segmented-control hold and the review re-size (08/10/2026,
evening): `flutter analyze` 0 errors / 10 warnings / 134 infos; 433 tests pass (same
`widget_test.dart`); the review page was rendered through the widget-test harness at 1280, 1440
and 1728px before and after (it used to force a 1516px-wide page).

Not yet done: an iOS build (`pod install` will pick up the new plugin pods) and a manual pass on the
screens touched above (drag-and-drop questions, training basic info uploads, YouTube fullscreen on
web, 2FA recovery-codes download, the three dropdowns, certificate download on Android).

### G.3 Reading the table — highlights

* **Abandoned-looking packages the app depends on** (developer's last release 3+ years ago, as of
  08/10/2026): `expandable` (5y 7mo), `modal_side_sheet` (5y 2mo), `auto_size_text` (4y 11mo),
  `qr_flutter` / `styled_divider` (3y 5mo), `tuple` (3y 4mo), `fluid_dialog` (3y 3mo). They still
  work on Flutter 3.44 today, but nobody is maintaining them — candidates to replace or vendor if
  they ever break (`super_banners`, `flutter_rating_bar` and `flip_card`, also on that list, are
  gone since 08/10/2026).
* **`html_editor_enhanced` is now the main blocker**: it alone keeps the `win32` 5 chain alive
  (§G.2.1 point 3), which holds back Syncfusion (33 → 35), `file_picker` (10 → 13),
  `flutter_secure_storage` (10 → 11), `device_info_plus` (12 → 13) and `chewie` (1.13 → 1.17).
* **Waiting on Flutter ≥ 3.47**: `flutter_form_builder` 11, `flex_color_picker` 4,
  `webview_flutter_wkwebview` 3.27, plus the SDK-pinned ones (`intl`, `file_saver`,
  `dropdown_search` 8, `build_runner` 2.16). Re-run `flutter pub outdated` after the next Flutter
  upgrade.
* **Waiting on the Android toolchain**: `permission_handler` 13 (an AGP that supports compileSdk 37).
* ✅ **Bump done 08/10/2026.** The earlier note ("this table is the map, not an instruction to
  upgrade") is resolved: every package is on its newest compatible version, and the code changes
  are listed in §G.2.2.

### G.4 Stale packages — where they are used and what to replace them with (added 08/10/2026)

Built from the G.3 list. "Where" comes from a grep of the importing files after Section D;
"replace with" prefers what ships in the Flutter / Dart SDK or a package that is **already** in
`pubspec.yaml`, in line with the no-new-dependencies rule. The "gain" column is honest: most of
these are tiny and only buy dependency hygiene — the two that matter for speed are
`html_editor_enhanced` and `auto_size_text`.

| Package | Dev's last release | Where it is used (files → widgets) | Replace with (SDK / existing dependency first) | Effort | Performance / loading gain |
| - | - | - | - | - | - |
| `html_editor_enhanced` | 2025-07 (1y 3mo) | 3 files: the **lesson content editor** (`admin_pages/trainings/lessons/add_lessons_content.dart`) and the **classroom content editor** (`admin_pages/classrooms/widget/classroom_content_widget.dart`, `classroom_provider.dart`) — `HtmlEditor` ×2, `HtmlEditorController` ×4. It embeds **Summernote** (jQuery + its CSS, 336 KB of package assets) in an `<iframe>` on web and in `flutter_inappwebview` on mobile. | **Fleather** (already a dependency, pure Flutter): its `parchment` package ships `ParchmentHtmlCodec` (`package:parchment/codecs.dart`), so the editor can open the existing lesson HTML and save HTML back — no backend change. (`flutter_quill` is also already here but has no Delta → HTML encoder without adding a package.) | Medium: rebuild the toolbar (bold / lists / link / image / video embed), reuse the existing image-upload hook, and test the HTML round-trip on real lessons (the codec keeps standard tags, drops unknown inline styles). | **Biggest of the table.** No iframe / WebView and no jQuery + Summernote download each time an editor opens; native text layout. It is also the package behind the whole `win32` 5 chain (§G.2.1 point 3): replacing it unlocks `file_picker` 13, Syncfusion 35, `flutter_secure_storage` 11, `device_info_plus` 13, `chewie` 1.17 and lets `third_party/quill_native_bridge_windows` + its override go. |
| `auto_size_text` | 2021-10 (4y 11mo) | 40 files, 75 `AutoSizeText` (the exam review side panel's one became a `Text` + ellipsis on 08/10/2026): quiz preview / review nav bars and side menus (web + mobile, exam + training), both dashboards, instructor dashboard & earnings card, `sidebar_widget.dart`, `custom_snackbar.dart`, assign dialogs, payment pages. | `Text(maxLines: n, overflow: TextOverflow.ellipsis)` where truncating is fine; `FittedBox(fit: BoxFit.scaleDown, child: Text(…))` where a one-line label must fit its box. Both SDK. | Low per site (start with nav bars, side menus and grid cells; leave dialogs). | Real: `AutoSizeText` lays the text out up to \~10 times per build (binary search over font sizes); `FittedBox` is one layout plus a scale. Adds up in the quiz screens, which rebuild on every answer. |
| `tuple` | 2023-06 (3y 4mo) | 40 files, 93 uses (`Tuple2` ×53, `Tuple3` ×16, `Tuple4` ×12, `Tuple6` ×8, `Tuple5` ×2, `Tuple7` ×2); 35 of them are `Selector<Provider, TupleN<…>>` — `app.dart` (`Tuple3<bool, ThemeData, ThemeData>` around `MaterialApp`), `training_details_screen.dart` (`Tuple7`), the filters widgets, both app bars, the statefulshells. | **Dart 3 records** — `(bool, ThemeData, ThemeData)`: part of the language, value equality so `Selector` keeps skipping unchanged values. `Tuple2(a, b)` → `(a, b)`, `.item1` → `.$1`. | Low, mechanical (40 files; the analyzer catches every miss). | None at runtime (records are the same cost); one 3-year-old dependency fewer on the hottest rebuild path of the app. |
| `expandable` | 2021-03 (5y 7mo) | 11 files: the **course content tree** (`course_content_tree.dart` ← `StudentTrainingProvider.expandableControllers`, 50 `ExpandableController` refs, inverted `expanded` semantics documented in `CLAUDE.md` §3), the chapters editor (`add_trainings_page_two.dart`, `chapter_provider.dart`), landing config (`landing_categories/footer/partners.dart` — controllers stored inside `footer_model.dart` / `landing_item.dart`), profile analytics tiles (`exam_/training_analytics_listtile.dart`). | SDK `ExpansionTile` + `ExpansibleController` (Flutter 3.32+) for the simple panels; for the course tree a `Set<int> openChapterIds` in the provider rendered with `AnimatedSize` + `ClipRect`. | Medium: controllers live in models and providers, and the tree's inverted flag must be swapped carefully (existing `course_player` tests guard it). | Same frame cost (both animate a size change). The gain is removing a 5½-year-old package from the most used student screen. |
| `modal_side_sheet` | 2021-08 (5y 2mo) | 3 files: `BodyWithSideSheet(show: context.select(… showSideSheetTraining))` = the **filter side panel** of the Trainings, Exams and Instructors catalogue pages. | `Scaffold.endDrawer` (SDK), or a `Stack` with `AnimatedSlide` / `AnimatedPositioned` for the sheet only. | Low. | Small but real: `BodyWithSideSheet` wraps the **whole page body** in an `AnimatedContainer`, so toggling the filters re-lays out the catalogue grid during the animation; animating only the sheet avoids that. |
| `flip_card` | 2023-01 (3y 9mo) | *Was* 6 files: `FlipCard` in the four quiz-review screens (web / mobile × exam / training), `FlipCardController` / `cardKey` held in `quiz_provider.dart` and `training_quiz_provider.dart`. | ✅ **Replaced on 08/10/2026** by `lib/ui/widgets/quiz/explanation_swap.dart`: `ExplanationSwap`, a `ValueListenableBuilder<bool>` that builds *either* the answers *or* the explanation — the "static swap": one build, one paint, no animation — and `ExplanationToggleButton`, a text + icon pill (💡 "See Explanation" / ☑ "Back to answers' review") in place of the 50px circle-with-tooltip. The providers keep a `ValueNotifier<bool> explanationVisible` instead of the `GlobalKey<FlipCardState>`; `updateQuestionIndex()` resets it, so Previous / Next / the side panel no longer need their flip-back blocks. | Done. | The 500 ms 3-D rotation (a rebuild per frame with both faces mounted) is gone; a toggle rebuilds only the swapped card, not every `QuizProvider` listener. Package removed from `pubspec.yaml`. |
| `fluid_dialog` | 2023-06 (3y 3mo) | 4 files: the admin **create / update user wizard** — `users_screen.dart`, `users_data_source.dart`, `create_update_user_widget.dart`, `DialogNavigator` ×5 in `user_provider.dart`. | `showDialog` + `AnimatedSize` / `AnimatedSwitcher` driven by a `step` field in `UserProvider`, or a nested `Navigator` inside a `Dialog`. | Low–medium. | Same; one dependency fewer. |
| `styled_divider` | 2023-05 (3y 5mo) | 1 file: one dashed `StyledDivider` in `admin_view_coupon_details_widget.dart`. | `DottedBorder` (already a dependency) with `RectDottedBorderOptions` around a 1 px high `SizedBox`, or a 15-line `CustomPainter`. | Trivial. | None; one dependency fewer. |
| `qr_flutter` | 2023-05 (3y 5mo) | 1 file: `QrImageView` ×2 in `shared/settings/two_factor_auth.dart` (TOTP enrolment QR). | **Keep.** Pure Dart `CustomPainter` over the maintained `qr` encoder (a transitive dependency anyway), no platform code — nothing to gain by rewriting. | — | — |
| `super_banners`, `flutter_rating_bar` | 2022-05 (4y 5mo) | Nowhere — zero imports (`RatingBarIndicator` only in commented-out code). | — | — | ✅ Removed on 08/10/2026 (§G.1). |

Suggested order: `tuple` (mechanical, touches the hottest `Selector`s), then `auto_size_text` in
the quiz screens, then `html_editor_enhanced` → Fleather (the one that unlocks the `win32` chain),
then the small ones whenever their screen is next touched.

***

## Execution order

1. ⬜ `.gitignore` additions, then `git rm -r --cached graphify-out` + `git rm --cached` the
   `.DS_Store`s (Section A) — **\~47 MB / \~1,575 files gone, zero functional risk.**
2. 🔶 Delete the Section A stray files — `CLAUDE_old.md` ✅ done (`2b5a6e7`); `gitignore`,
   `save_settings.local_json.txt`, `docs/api_samples/` (⚠️ check the auth\_user dump) still pending.
3. ✅ Section B unused assets — done (28/09/2026): 39 files deleted, `flutter analyze` 0 errors.
   Remaining: run the web app once to visually confirm no broken images.
4. ✅ Section C templates moved out of `assets/` + CLAUDE.md paths updated — done (`2b5a6e7`).
5. ✅ Section D dead Dart files — the 6 empty files (`2b5a6e7`) + the remaining 50 and their 11
   dead-only assets (08/10/2026); the 10 newly orphaned files of D.2 + 17 more orphans
   (23/10/2026, `89da932`).
6. 🔶 Section E ✅ done (`2b5a6e7`: macos/ + linux/ removed & gitignored); Section F still pending.
7. ✅ Section G — versions bumped (`513bb83`) and the 13 unused packages removed (08/10/2026).
   Next: the G.4 replacements, starting with `tuple` → records.

Since `LMS_Frontend` was reset to a single commit, doing this cleanup **before** the next
force-push (or as commit #2) keeps the new repo permanently light — files removed later still live
in pack history otherwise.

***

## Full asset audit (`assets/`, re-scanned 28/09/2026)

Every asset filename was grepped across `lib/`, `web/`, `test/`, `integration_test/`,
`pubspec.yaml`, `flutter_native_splash.yaml`, `ios/`, `android/` (generated `*.g.dart` excluded).
No dynamically-built asset paths exist, so filename matching is reliable. **142 asset files total**
before the Section B deletion (excluding `.DS_Store`); 103 after it, 92 after the 08/10/2026
dead-code batch.

### ✅ Used — keep (92 files)

> [accordion] The full used-asset table with every referencing file
>
> | Asset | Size | Referenced by |
> | - | -: | - |
> | `assets/fonts/poppins/Poppins-Bold.ttf` | 152 KB | `pubspec.yaml` (fonts) |
> | `assets/fonts/poppins/Poppins-ExtraBold.ttf` | 152 KB | `pubspec.yaml` (fonts) |
> | `assets/fonts/poppins/Poppins-Light.ttf` | 160 KB | `pubspec.yaml` (fonts) |
> | `assets/fonts/poppins/Poppins-Medium.ttf` | 156 KB | `pubspec.yaml` (fonts) |
> | `assets/fonts/poppins/Poppins-Regular.ttf` | 156 KB | `pubspec.yaml` (fonts) |
> | `assets/fonts/poppins/Poppins-SemiBold.ttf` | 152 KB | `pubspec.yaml` (fonts) |
> | `assets/translations/en.json` | 128 KB | `main.dart` — `EasyLocalization(path: 'assets/translations')` (loaded by folder) |
> | `assets/translations/fr.json` | 144 KB | idem |
> | `assets/translations/ar.json` | 164 KB | idem |
> | `assets/privacy_policy_en.html` | 72 KB | `web_view_privacy_policy.dart` |
> | `assets/privacy_policy_fr.html` | 76 KB | idem |
> | `assets/privacy_policy_ar.html` | 80 KB | idem |
> | `assets/icons/add_cart.svg` | 4 KB | `exam_list_item_widget.dart`, `training_list_item_widget.dart` |
> | `assets/icons/appbar_icons/categories.svg` | 4 KB | `admin_home_main.dart`, `content_manager_home_main.dart`, `basic_info_screen.dart` |
> | `assets/icons/appbar_icons/classroom.svg` | 4 KB | admin / instructor / content-manager `*_home_main.dart` |
> | `assets/icons/appbar_icons/company.svg` | 4 KB | `super_admin_home_main.dart` |
> | `assets/icons/appbar_icons/config.svg` | 4 KB | `admin_home_main.dart` |
> | `assets/icons/appbar_icons/crescent.svg` | 4 KB | `appbar_popup_menu.dart`, `theme_mode_switcher.dart` |
> | `assets/icons/appbar_icons/customers.svg` | 4 KB | `admin_home_main.dart`, `super_admin_home_main.dart`, landing `preview_dialog.dart` |
> | `assets/icons/appbar_icons/dashboard.svg` | 4 KB | admin / instructor / content-manager `*_home_main.dart` |
> | `assets/icons/appbar_icons/discount.svg` | 4 KB | `admin_home_main.dart` |
> | `assets/icons/appbar_icons/import_export.svg` | 4 KB | `super_admin_home_main.dart` |
> | `assets/icons/appbar_icons/logout.svg` | 4 KB | `appbar_popup_menu.dart` |
> | `assets/icons/appbar_icons/orders.svg` | 4 KB | `admin_home_main.dart`, `order_screen.dart` |
> | `assets/icons/appbar_icons/profile.svg` | 4 KB | `instructor_home_main.dart` |
> | `assets/icons/appbar_icons/quizzes.svg` | 4 KB | admin / instructor / content-manager `*_home_main.dart` |
> | `assets/icons/appbar_icons/role_permissions.svg` | 4 KB | `super_admin_home_main.dart` |
> | `assets/icons/appbar_icons/settings.svg` | 4 KB | admin / instructor / content-manager `*_home_main.dart` |
> | `assets/icons/appbar_icons/sun.svg` | 4 KB | `theme_mode_switcher.dart` |
> | `assets/icons/appbar_icons/tags.svg` | 4 KB | `admin_home_main.dart`, `basic_info_screen.dart`, `tags_category_dialog_widget.dart` |
> | `assets/icons/appbar_icons/trainings.svg` | 4 KB | `*_home_main.dart` (3 roles), `instructor_public_profile.dart` |
> | `assets/icons/archive.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/avatar.png` | 292 KB | `constants.dart` (`avatarHolder`), `assign_learners.dart`, `unassign_learners.dart` |
> | `assets/icons/ban.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/bell.svg` | 4 KB | `admin_home_main.dart`, `notifier_dialog_widget.dart`, `send_notification_dialog.dart` |
> | `assets/icons/csv.png` | 4 KB | `constants.dart` (`csvIcon`) |
> | `assets/icons/difficulty.svg` | 4 KB | `basic_info_screen.dart` |
> | `assets/icons/eye.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/google-authenticator-logo.png` | 36 KB | `two_factor_auth.dart` |
> | `assets/icons/google_icon.png` | 4 KB | `login_screen.dart` |
> | `assets/icons/inCart.svg` | 4 KB | `exam_list_item_widget.dart`, `training_list_item_widget.dart` |
> | `assets/icons/json.png` | 4 KB | `constants.dart` (`jsonIcon`) |
> | `assets/icons/mail.svg` | 4 KB | `voucher_send_email_widget.dart`, `popup_menu_widget.dart` |
> | `assets/icons/order.svg` | 4 KB | `shopping_cart_widgets/top_container_widget.dart` |
> | `assets/icons/pdf.png` | 4 KB | `constants.dart` (`pdfIcon`) |
> | `assets/icons/pen.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/restore.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/sandTime.svg` | 8 KB | `loading_progress_dialog.dart` |
> | `assets/icons/shopingCart.svg` | 4 KB | `student_appbar_widget.dart` |
> | `assets/icons/translate.svg` | 4 KB | `landing_theme.dart` |
> | `assets/icons/trash.svg` | 4 KB | `popup_menu_widget.dart` |
> | `assets/icons/userMinus.svg` | 4 KB | `training_data_source.dart`, `quiz_data_source.dart` |
> | `assets/icons/userPlus.svg` | 4 KB | `training_data_source.dart`, `basic_info_screen.dart`, `create_update_user_widget.dart` |
> | `assets/icons/verified.svg` | 4 KB | `instructor_card_widget.dart`, `instructor_public_profile*.dart` |
> | `assets/icons/zip.png` | 4 KB | `constants.dart` (`zipIcon`) |
> | `assets/images/Icon.svg` | 4 KB | `student_trainings_page.dart` |
> | `assets/images/arabic.png` | 64 KB | `constants.dart` (`arabicFlag`) |
> | `assets/images/authBackground.jpg` | 192 KB | `constants.dart` (`authBackground`) |
> | `assets/images/certificate.png` | 8 KB | `certificates_screen.dart` |
> | `assets/images/certificate_dark.png` | 8 KB | `certificates_screen.dart` |
> | `assets/images/classroom_svg.svg` | 8 KB | `classroom_anaylitcs_listtile.dart` |
> | `assets/images/emptyImage.png` | 84 KB | `constants.dart` (`emptyPlaceHolder`) |
> | `assets/images/empty_holder.png` | 16 KB | `overview_screen.dart` (+ mobile), `instructor_dashboard_screen.dart` |
> | `assets/images/english.png` | 104 KB | `constants.dart` (`englishFlag`) |
> | `assets/images/fail_quiz.png` | 16 KB | `quiz_review_dialog_widget.dart` |
> | `assets/images/french.png` | 16 KB | `constants.dart` (`frenchFlag`) |
> | `assets/images/front_view_young.png` | 92 KB | `overview_screen.dart` |
> | `assets/images/image_women_1.png` | 124 KB | `overview_screen.dart` |
> | `assets/images/landing_item_preview.png` | 12 KB | landing `preview_dialog.dart` |
> | `assets/images/onboarding/badge_cbap.png` | 16 KB | `onboarding_screen.dart` |
> | `assets/images/onboarding/badge_pmi_acp.png` | 16 KB | `onboarding_screen.dart` |
> | `assets/images/onboarding/badge_pmp.png` | 16 KB | `onboarding_screen.dart` |
> | `assets/images/onboarding/badge_psm_ii.png` | 12 KB | `onboarding_screen.dart` |
> | `assets/images/onboarding/badge_pspo_ii.png` | 16 KB | `onboarding_screen.dart` |
> | `assets/images/payment_img/cc_img.png` | 152 KB | `payment_success_page.dart`, `payment_failed_page.dart` |
> | `assets/images/payment_img/payment_design_down.png` | 12 KB | `payment_success_page.dart`, `payment_failed_page.dart` |
> | `assets/images/payment_img/payment_design_up.png` | 12 KB | `payment_success_page.dart`, `payment_failed_page.dart` |
> | `assets/images/payment_img/payment_fail.svg` | 4 KB | `payment_failed_page.dart` |
> | `assets/images/payment_img/payment_success.svg` | 4 KB | `payment_success_page.dart` (desktop) |
> | `assets/images/quiz.png` | 132 KB | `quiz_review_dialog_widget.dart` |
> | `assets/images/readyforQuiz.png` | 20 KB | `preview_lessons_and_quiz.dart` |
> | `assets/images/splash_android12_strived.png` | 244 KB | `flutter_native_splash.yaml` |
> | `assets/images/splash_bg_indigo.png` | 164 KB | `flutter_native_splash.yaml` |
> | `assets/images/splash_logo_strived.png` | 360 KB | `flutter_native_splash.yaml` |
> | `assets/images/success_quiz.png` | 16 KB | `quiz_review_dialog_widget.dart` |
> | `assets/images/the_team.png` | 12 KB | `flutter_native_splash.yaml` |
> | `assets/images/user_holder.png` | 672 KB | `constants.dart` (`avatarHolder2`), `assign_items_data.dart` |
> | `assets/svg/Subtract.svg` | 60 KB | `overview_screen.dart`, `help_screen.dart` |
> | `assets/svg/Subtract1.svg` | 28 KB | `overview_screen.dart`, `shopping_cart_items_screen.dart`, `setting_home_main_mobile.dart` |
> | `assets/svg/earth-africa.svg` | 4 KB | `translate_widget.dart` |
> | `assets/svg/exam-illustration.svg` | 4 KB | `exam_preview_page.dart` |
> | `assets/svg/payment_success.svg` | 8 KB | `payment_success_mobile_page.dart` (mobile — the `payment_img/` twin is the desktop one; both are used) |

### ⚠️ Referenced ONLY by dead Dart code (11 files, \~1.2 MB) — ✅ DELETED (08/10/2026)

Their *only* references were files in **Section D**. Deleted on 08/10/2026 together with those
files, after a repo-wide grep (`lib/`, `web/`, `test/`, `pubspec.yaml`, `android/`, `ios/`)
confirmed zero references outside the deleted code. `build/web/assets/assets` shrank from
6,120 KB to 4,884 KB.

| Asset | Size | Only referenced by (Section D file) |
| - | -: | - |
| `assets/images/medium_shot_woman.png` | 744 KB | `preview_exam_landing_widget.dart` |
| `assets/images/jeune_tendre.png` | 320 KB | `start_exam_widget.dart` |
| `assets/images/trainingPic1.png` | 124 KB | `preview_voucher_widget.dart` |
| `assets/svg/create_activities.svg` | 8 KB | `platfrom_acitivity_listtile.dart` |
| `assets/svg/delete_activities.svg` | 8 KB | `platfrom_acitivity_listtile.dart` |
| `assets/svg/update_activities.svg` | 8 KB | `platfrom_acitivity_listtile.dart` |
| `assets/svg/unknown_activities.svg` | 8 KB | `platfrom_acitivity_listtile.dart` |
| `assets/svg/medal.svg` | 4 KB | `leaderboard_card_dynamic.dart` |
| `assets/svg/trophy-star.svg` | 4 KB | `leaderboard_card_dynamic.dart` |
| `assets/icons/star.svg` | 4 KB | `leaderboard_card_dynamic.dart` |
| `assets/icons/discount_icon.svg` | 4 KB | `select_discount_type_widget.dart` |

### 🚩 Near-miss lookalikes — don't delete the wrong twin

* `assets/icons/appbar_icons/role_permissions.svg` (underscore) is USED;
  `role-permissions.svg` (hyphen) was not.
* `assets/icons/google-authenticator-logo.png` is USED; the `.svg` in `assets/svg/` was not.
* `assets/icons/bell.svg` is USED; `assets/images/bell.jpg` was not.
* `assets/icons/appbar_icons/classroom.svg` + `assets/images/classroom_svg.svg` are USED;
  `assets/images/classroom.png` was not.
* `assets/icons/avatar.png` is USED (`Constants.avatarHolder`); `avatar2.png` was not.
* Both `payment_success.svg` copies (in `assets/svg/` and `assets/images/payment_img/`) are USED
  (mobile vs desktop page).

After any further deletion: `flutter analyze`, then run the web app and click through login,
dashboards, cart/payment, quiz review and onboarding to confirm no broken images.

***

## App Speed Suggestions

Added 08/10/2026. Measured on that day's release build (Flutter 3.44.6, CanvasKit):
`main.dart.js` **12.2 MB (3.2 MB gzipped)**, `canvaskit/` 37 MB on disk (the browser downloads
only the variant it needs), `assets/` 13.1 MB (fetched on demand, not at startup). Counts are
`grep` counts over `lib/`. Nothing here is about wasm — these are things in the app's own code,
HTML shell and server that make the web app (and the phones) faster. Ordered by expected impact.

| # | Area | What the code does today (measured) | Suggestion | Expected gain | Effort |
| - | - | - | - | - | - |
| 1 | **Code splitting by role** | `deferred as` is used **0** times. Every visitor downloads the admin, super-admin, instructor and content-manager pages (Syncfusion DataGrid, `fl_chart`, Quill / Fleather, the PDF viewer, the image cropper, the config screens…) inside the single 12.2 MB `main.dart.js`, even a student who will never open them. | Import each role shell lazily — `import 'core/routes/statefulshells/admin_statefulshell.dart' deferred as admin;` — and `await admin.loadLibrary()` in the GoRouter redirect / branch for that role (Flutter web emits one `.part.js` per deferred library, loaded on first use). Do the same for single-screen heavy libraries: `syncfusion_flutter_pdfviewer`, `fl_chart`, `image_cropper`, the editors. | **Largest first-load win available**: a student stops downloading the staff half of the bundle; staff only pay for their role. | Medium (one deferred import + one `loadLibrary()` per role; test the role redirects). |
| 2 ✅ (payload, Update 125) | **First paint waits for the network** | `app.dart` `initState → _fetchAuthData() → authUserAndRole()`: until the `/auth-user` round-trip returns, the user only sees `LoadingProgressWidget`. That payload embeds `orders[].trainings` and `orders[].quizzes` **with full question lists** (`CLAUDE.md` §3 — `myExams` come from the login payload; the locked-lesson-content leak is the same issue), so it is big to download **and** to parse on every boot. | Render the shell immediately from the cached user (token + last user JSON in `SharedPrefs`) and refresh in the background; load *My Trainings* / *My Exams* / *Attempts* with their own calls when the tab opens (they already have refresh methods). Backend side: slim `/auth-user` to ids + counters (note for `LMS_Backend`). | Time-to-interactive drops by one full API round-trip after the JS has loaded; less JSON parsed on the main thread at boot. | Medium (frontend) + a backend change. |
| 3 | **`UniqueKey()` on routed pages** (the "rebuilt twice" one) | 59 uses. `student_statefulshell.dart` lines 76 / 167 / 222 wrap routed pages in `PopScope(key: UniqueKey())`: a fresh key on every build means the page is **unmounted and recreated** (`initState` again, data refetched, scroll lost) whenever the shell rebuilds — on a locale change, a theme change, a provider tick. `CLAUDE.md` already forbids it for My Content and the mobile shell. | Drop the key, or use `state.pageKey` / `ValueKey(routeName)`. Grep the other uses: `quiz_provider.dart`'s `UniqueKey().hashCode` as an id is harmless; keys on widgets inside `build` are the ones to fix. | Removes whole-page rebuilds that cost a network call each. | Low. |
| 4 | **Rebuild granularity** (the other "don't rebuild twice") | 582 `notifyListeners()` sites and 92 `context.watch<…>()`. `basic_info_screen.dart` alone calls `context.watch<TrainingProvider>()` **12 times** in one `build`, so every notify rebuilds the whole 76 KB screen; many provider methods set several fields and notify after each one (3 rebuilds for 1 change). | Read single fields with `context.select((TrainingProvider p) => p.isPickedVideo)` or `Selector` (there are already 182 of those — keep going); split the big screens into small `const` leaf widgets so unchanged subtrees are skipped; in providers mutate first and call `notifyListeners()` **once** at the end, and not at all when the value did not change. | Direct CPU savings on forms, tables and the quiz editor; fewer dropped frames while typing. | Low–medium, incremental (do it screen by screen). |
| 5 | **Image decode size** | 59 `CachedNetworkImage`, 12 `Image.network`, 33 `Image.asset` — and **0** `memCacheWidth` / `cacheWidth`. A 1920 px training cover is decoded at full size to be drawn at 290 px (≈ 40× the pixels, and the full texture is uploaded to the GPU for every card). Largest bundled image: `user_holder.png` 671 KB. | `memCacheWidth: (width * MediaQuery.devicePixelRatioOf(context)).round()` on card / avatar images, `cacheWidth` on assets; serve resized variants from R2 (Cloudflare image resizing) for thumbnails; shrink / convert the big PNGs to WebP. | Smoother catalogue and grid scrolling; far less memory on phones (the usual cause of "the app got slow after scrolling"). | Low. |
| 6 | **Logging in release** | 598 `debugPrint` (487 in providers) + 19 `print`. `debugPrint` is **not** removed in release builds, and the interpolated strings (often whole responses) are built on every call. `web/index.html` also sets `localStorage.debug = '*'`. | In `main()`: `if (kReleaseMode) debugPrint = (String? m, {int? wrapWidth}) {};` — one line, no call-site changes; route new logs through a `kDebugMode`-guarded helper; delete the `localStorage.debug` line. | Small CPU, no console spam, and no API response bodies in the browser console of production. | Trivial. |
| 7 | **Sentry tracing at 100 %** | `tracesSampleRate = 1.0` in `main.dart`: in prod every HTTP request, route change and slow frame is traced and sent. | `tracesSampleRate: 0.1` (errors stay at 100 %). | Fewer Sentry envelopes per screen; less main-thread work on every request. | Trivial. |
| 8 | **`heroicons` ships 1,288 SVG files** | The package bundles every icon (**5.1 MB** in `build/web/assets/packages/heroicons`) while the app uses 71 of them (137 `HeroIcon(`). Each one is an SVG parsed by `flutter_svg` on first paint, and all 1,288 paths sit in the asset manifest the app downloads at startup (`AssetManifest.bin.json` = 208 KB). | Use the Material icon font equivalents (`Icons.*`, already loaded and tree-shaken to 43 KB), or copy the 71 used SVGs into `assets/icons/` and drop the package. | Smaller startup manifest, faster first paint of icon bars, 5 MB less to deploy. | Low–medium. |
| 9 | **Non-lazy lists** | 166 `SingleChildScrollView`, 33 `ListView(children: …)`, 48 `shrinkWrap: true` vs 27 `ListView.builder`. `shrinkWrap` / `children:` lists build and lay out **every** row, on screen or not. | `ListView.builder` / `SliverList` for anything that can exceed \~20 rows (classroom members, attempts, orders, notifications); `CustomScrollView` + slivers instead of a scroll view nested in another one with `shrinkWrap`. | Scroll smoothness and faster first layout on long pages. | Medium. |
| 10 | **Timers that rebuild whole screens** | Six `Timer.periodic(1 s)` (quiz, training quiz, course player, coupon / voucher countdowns) call `notifyListeners()` every tick, so whatever watches that provider — often the whole exam screen — rebuilds **once a second for the entire attempt**. | Expose the clock as a `ValueNotifier<Duration>` and wrap only the time `Text` in a `ValueListenableBuilder`. | Removes a 1 Hz full-screen rebuild during exams. | Low. |
| 11 | **`AutoSizeText` ×78** | Up to \~10 text layouts per widget per build (see G.4). | `FittedBox(fit: BoxFit.scaleDown)` / `Text` with ellipsis in nav bars and grid cells. | Fewer layout passes in the quiz screens and dashboards. | Low. |
| 12 | **`Opacity` ×15** | `Opacity` (e.g. `course_player_header.dart:459`, `course_player_tokens.dart:177`) makes CanvasKit render the subtree into an offscreen layer every frame. | Static alpha: tint the child's own colors with `.withValues(alpha:)`; animated: `FadeTransition` / `AnimatedOpacity`. | Fewer offscreen layers per frame in the course player. | Trivial. |
| 13 | **Repaint isolation** | 3 `RepaintBoundary` in the whole app. The custom-painted art (`ExamQcmBanner`, `_HeroArtPainter`, `ClassroomEducationBanner`, the glass cards) is re-rasterized whenever anything in the same layer changes — a hover, a spinner, a scroll. | Wrap each painted banner / card and the DataGrid in a `RepaintBoundary`; verify with DevTools → *Highlight repaints*. | Lower paint cost while scrolling the catalogues. | Trivial. |
| 14 | **`IntrinsicHeight` rows in `GlassCardGrid`** | Each catalogue row is laid out twice (intrinsic pass + real pass) to equalise card heights — deliberate (`CLAUDE.md` §3), but it is the most expensive layout widget in Flutter and runs for every row on every rebuild. | Give the cards a fixed height per breakpoint from `StudentWebLayout` so rows need no intrinsic pass. | Faster layout on pages with dozens of cards. | Low–medium. |
| 15 | **Cache headers on the web server** | The test server already compresses (`content-encoding: gzip` / `br` ✅) but sends **no `Cache-Control`** on `main.dart.js`, `flutter_bootstrap.js`, `canvaskit/*` or `assets/*`, so each browser guesses. | Plesk → nginx directives (same place as the `/storage/` CORS fix): `index.html`, `flutter_bootstrap.js`, `main.dart.js` → `Cache-Control: no-cache` (ETag revalidation, 304 when unchanged); `canvaskit/*`, `assets/fonts/*`, `assets/packages/*` → `max-age=604800`; confirm `flutter_service_worker.js` is registered in the browser (it caches everything by content hash, offline-first). | Repeat visits stop re-downloading 3+ MB. | Trivial. |
| 16 | **Startup HTML** | `web/index.html` loads `cropper.min.js` from cdnjs for everyone (needed only by `image_cropper`'s web UI in the admin question-image dialog), and the 6 Poppins weights (928 KB) are fetched on first use. | Self-host cropper.js and inject it when the cropper dialog opens; `<link rel="preload" as="font">` for Poppins Regular / Medium; drop a weight if a design pass allows. | Small; removes a third-party CDN from the critical path. | Low. |

**Applied so far (08/10/2026):** the four review screens' `FlipCard` became a static swap
(`ExplanationSwap`, §G.4) — a toggle now costs one build and one paint instead of \~30 frames of
3-D rotation with both faces mounted, and only the card rebuilds, not every provider listener. The
exam attempt review page (`/student-my-content/attempts`) takes its sizes from the new
`StudentWebLayout.review*` tokens (nav bar 60–72px instead of 100, side panel 300–390px instead
of 450, 13.5–15px body text instead of the theme's 18px default, numbered tabs 34–40px instead of
45\) and lays out from 960px instead of forcing a 1516px-wide page, so 11" / 13" / 14" windows no
longer scroll sideways to reach the question panel. The training review twins
(`training_quiz_review_*`) still use the old fixed sizes — same tokens, next pass.

**Already in good shape — keep doing this:** gzip / brotli on the server; translations compiled
in with `CodegenLoader` (no JSON fetch at boot); icon fonts tree-shaken by the build (MaterialIcons
1.6 MB → 43 KB, Font Awesome −92 to −99 %); `AppNavigation` created once (`??=`); the glass cards use
`ImageFiltered` on their own cover and never `BackdropFilter` (1 use in the whole app); the changelog
is parsed off the UI thread with `compute()`; `SystemDisplayGuard` only applies its `FittedBox` on
native; `Selector` already outnumbers `context.watch` 2 : 1.

***

## Extra reference links (kept on purpose)

* [shadcn\_flutter](https://pub.dev/packages/shadcn_flutter)
* [flutter\_quill](https://pub.dev/packages/flutter_quill)
* [quill\_native\_bridge](https://pub.dev/packages/quill_native_bridge)
* [flutter\_local\_notifications](https://pub.dev/packages/flutter_local_notifications)
* [shadcnstudio.com/illustrations](https://shadcnstudio.com/illustrations)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.