diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8b026..94e516f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## 2.5.5 + +- FIX: Fixed issue with router routing to the wrong page when the theme is toggled when navigating back from a different page. (Temporary fix for when the route is popped.) +- FIX: Fixed spacing issue in the home header banner. +- REVISED: Updated the home header banner subtitle to cycle through a list rather than just two. + +## 2.5.4 + +- FIX: Fixed issue with the local video player restarting when the media browser is opened or closed. + +## 2.5.3 + +- FIX: Fixed issue with current route not being updated when navigating to a new route. (Added a temporary fix for when the route is popped.) + ## 2.5.2 - FIX: Fixed social media icons not displaying due to case sensitivity in the file path. diff --git a/README.md b/README.md index 13b715c..84f9206 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This web app is a portfolio of my work, projects, and research.
You can find relevant publications, documents, source code, images, videos, and more here. -It is a static web app built using the [Flutter framework](https://flutter.dev/) and hosted on [GitHub Pages](https://pages.github.com/).
+It is a static web app built using the [Flutter framework](https://flutter.dev/), written in [Dart](https://dart.dev/), and hosted on [GitHub Pages](https://pages.github.com/).
You can access the web app here: [https://plguerradesigns.github.io/portfolio](https://plguerradesigns.github.io/portfolio) @@ -39,8 +39,8 @@ Try Flutter directly in your browser using [DartPad](https://dartpad.dev/?id=5c0 - my social media accounts - relevant institutions/organizations/companies - the source code of the web app - - the project issue tracker - - the project change log + - the app's issue tracker + - the app's change log - A contact button that opens an email client with my email address ## Showcase @@ -58,26 +58,26 @@ Try Flutter directly in your browser using [DartPad](https://dartpad.dev/?id=5c0 - Home (Dark Mode) + Home - Home Drawer (Dark Mode) + Home - Professional Experience (Dark Mode) + Professional Experience - Professional Experience (Dark Mode) + Professional Experience - Details (Dark Mode) + Details - Details (Dark Mode) + Details @@ -94,26 +94,26 @@ Try Flutter directly in your browser using [DartPad](https://dartpad.dev/?id=5c0 - Home (Light Mode) + Home - Home (Light Mode) + Home - Projects (Light Mode) + Projects - Projects (Light Mode) + Projects - Details (Light Mode) + Details - Details (Light Mode) + Details @@ -171,14 +171,6 @@ Try Flutter directly in your browser using [DartPad](https://dartpad.dev/?id=5c0 Projects - - - Projects Details - - - Home Drawer - - Contact @@ -198,6 +190,32 @@ Try Flutter directly in your browser using [DartPad](https://dartpad.dev/?id=5c0 +## Design Notes + +The web app is designed using the [Material Design](https://material.io/design) guidelines.
+ +[![Material Design UI Example](https://lh3.googleusercontent.com/kqa_LNBbbacJHfLL5ADPfJIcqHAeVIz3KMqy2PFGFHqQz5ir51Ww0APxKJt5J7EfRehqidtv4kxSlvmx5Je3A5jmH_y_jXbHWGIwsGyTINBP=s0)](https://m3.material.io/) + +Try out the Material 3 Demo here: [https://flutter.github.io/samples/web/material_3_demo/](https://flutter.github.io/samples/web/material_3_demo/) + +### Color Scheme + +The color scheme was chosen by using the online tool [Coolors](https://coolors.co/) to generate a palette of my preference. + +[![Coolors](https://res.cloudinary.com/coolors/image/upload/v1575544084/zendesk/generator_screen.png)](https://coolors.co/) + +The color codes were then entered into the [Material Theme Builder Plugin](https://www.figma.com/community/plugin/1034969338659738588/material-theme-builder), for Figma, to generate a Material Theme that was exported to Dart code. + +[![Material Theme Builder](https://s3-alpha-sig.figma.com/plugins/1034969338659738588/88380/6192b9f77bb59605a942d2a2efdebb6d974a0e02-cover?Expires=1724025600&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=hZ4LNZRwvYZ0Ng-y8arJ3lSTRISquMJHaJ0nvt5NDYXQchQyGALBBS2Gu-3Qk3JzA0iMzj5jybdb9bug1UdqUnBBaThT1pCbBy-5L0gjumzOCdC~RCbUiFAyc1qxUogIK-7~tbPREu22rBp2U1HqbGVPrajMIFx1Oqa2tPCIDrU8lsSV7S9V8km~zub9WiZK-xy-8hq3h0UFWFtiSPox8NR6RmIDrVhY4C-YgeriXGruvip-6NEffbXu-ehb4uqoAz0j0d7UbCSrjJ568ARrW8RUma-EeILu3m-YqWBSOAL9HV0vGZXriQ2EtNJON9ODmb608wUUCImnJWVJ6grQkA__)](https://www.figma.com/community/plugin/1034969338659738588/material-theme-builder) + +### Fonts and Icons + +The font used is [Roboto](https://fonts.google.com/specimen/Roboto) and the icons are from [Material Icons](https://fonts.google.com/icons). + +[![Material Design Typography](https://lh3.googleusercontent.com/q88EBZbgu7lTffRRfgJmCXT9WCK_HzM23PlqBYQXMHolDawHK6WuD7gEGTzpoX1zDUoxr8lTrBdYAzZeB2mbwh6KkMlQTNZh7wIR6kKYMsE=s0)](https://fonts.google.com/specimen/Roboto) + +[![Material Design Icons](https://firebasestorage.googleapis.com/v0/b/design-spec/o/projects%2Fm3%2Fimages%2Fl1dsjbqv-hero_7_weights.gif?alt=media&token=5ab64691-8cbb-4420-a176-a258ccd63d76)](https://fonts.google.com/icons) + ## Development Notes [![Build and Release](https://github.com/plguerradesigns/portfolio/actions/workflows/main.yml/badge.svg)](https://github.com/PLGuerraDesigns/portfolio/actions/workflows/main.yml) @@ -212,13 +230,15 @@ There are three main branches in this repository: - `master`: The master branch is the default branch and is protected. It contains the latest stable version of the web app. - `dev`: The development branch is where new features are added and tested. It is merged into the master branch after testing. -- `published`: The published branch contains the latest build of the web app. This branch is used to host the web app on GitHub Pages. +- `published`: The published branch contains the build artifacts of the web app and is deployed to GitHub Pages. + +[![git-kraken.png](https://i.postimg.cc/fTrTzny9/git-kraken.png)](https://www.gitkraken.com/) The CI/CD pipeline is implemented using [GitHub Actions](https://github.com/features/actions). The pipeline consists of the following stages: - Build: The Flutter web app is built using the `flutter build web` command. -- Release: The build artifacts are pushed to the `published` branch. -- Deploy: The `published` branch is deployed to GitHub Pages. +- Release: The build artifacts are merged into the `published` branch. +- Deploy: The latest build artifacts are deployed to GitHub Pages. The pipeline is triggered automatically on every commit to the master branch. diff --git a/assets/json/projects.json b/assets/json/projects.json index 45d30fd..b851cbf 100644 --- a/assets/json/projects.json +++ b/assets/json/projects.json @@ -628,9 +628,9 @@ "source": "thumbnail.webp" }, { - "type": "localVideo", + "type": "youTubeVideo", "caption": "F1 Sim Engineer Demo", - "source": "video_1.mp4" + "source": "4ROWmlwLq6M" } ], "externalLinks": [ diff --git a/lib/common/routing/app_router.dart b/lib/common/routing/app_router.dart index 61d7904..0f92a7a 100644 --- a/lib/common/routing/app_router.dart +++ b/lib/common/routing/app_router.dart @@ -101,6 +101,8 @@ class AppRouter { final String location = state.uri.toString(); final String goto = location.split('/').last; + appState.currentRoute = location; + final bool isAtProfessionalDetails = location.contains(Routes.professional) && location.contains(Routes.details); diff --git a/lib/common/strings.dart b/lib/common/strings.dart index ba5057e..bd08071 100644 --- a/lib/common/strings.dart +++ b/lib/common/strings.dart @@ -5,11 +5,14 @@ class Strings { static const String currentLocation = 'VA, USA'; static const String lastUpdated = 'Updated AUG 2024'; + static const List headerSubtitles = [ + 'Software Engineer • Innovator • Technologist', + 'Give me a lever long enough and a fulcrum on which to place it, and I shall move the world. ~Archimedes', + 'Men for Others' + ]; + static const String appName = 'PLG Portfolio'; static const String name = 'Pablo L. Guerra'; - static const String subtitle = - 'Software Engineer • Innovator • Technologist'; - static const String motto = 'Men for Others'; static const String explore = 'Explore'; static const String expand = 'Expand'; static const String collapse = 'Collapse'; diff --git a/lib/main.dart b/lib/main.dart index 6f66074..1551d32 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'common/routing/app_router.dart'; +import 'common/routing/routes.dart'; import 'common/strings.dart'; import 'common/theming/theme_notifier.dart'; import 'models/app_state.dart'; @@ -31,6 +32,10 @@ class _PortfolioAppState extends State { // Listen to theme changes and rebuild the application. themeNotifier.addListener(() { + // ! This should be handled in AppRouter but redirect isn't being called + // ! on pop, so we're handling it here until it's fixed in GoRouter. + _appState.currentRoute = Routes.home; + setState(() {}); }); } diff --git a/lib/pages/details/details.controller.dart b/lib/pages/details/details.controller.dart index 7dc6316..6b80c21 100644 --- a/lib/pages/details/details.controller.dart +++ b/lib/pages/details/details.controller.dart @@ -87,4 +87,11 @@ class DetailsController extends ChangeNotifier { context.go(route); } + + @override + void dispose() { + screenScrollController.dispose(); + mediaController.dispose(); + super.dispose(); + } } diff --git a/lib/pages/details/details.screen.dart b/lib/pages/details/details.screen.dart index e5bffc3..46bc8c1 100644 --- a/lib/pages/details/details.screen.dart +++ b/lib/pages/details/details.screen.dart @@ -186,6 +186,12 @@ class DetailsScreenState extends State { ); } + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return MultiProvider( diff --git a/lib/pages/details/widgets/media_player/local_video_player.dart b/lib/pages/details/widgets/media_player/local_video_player.dart index 9ca7181..5aa98ed 100644 --- a/lib/pages/details/widgets/media_player/local_video_player.dart +++ b/lib/pages/details/widgets/media_player/local_video_player.dart @@ -12,25 +12,28 @@ class LocalVideoPlayer extends StatelessWidget { }); /// The controller for the video player. - final VideoPlayerController videoPlayerController; + final VideoPlayerController? videoPlayerController; @override Widget build(BuildContext context) { - return FutureBuilder( - future: videoPlayerController.initialize(), - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return Chewie( - controller: ChewieController( - autoPlay: true, - aspectRatio: 16 / 9, - autoInitialize: true, - videoPlayerController: videoPlayerController, - ), - ); - } - return const Spinner(); - }, + if (videoPlayerController == null) { + return const Spinner(); + } + return Chewie( + controller: ChewieController( + videoPlayerController: videoPlayerController!, + autoPlay: true, + aspectRatio: 16 / 9, + autoInitialize: true, + zoomAndPan: true, + showControlsOnInitialize: false, + hideControlsTimer: const Duration(milliseconds: 1500), + materialProgressColors: ChewieProgressColors( + backgroundColor: Colors.white10, + bufferedColor: Colors.white24, + playedColor: Colors.white38, + ), + ), ); } } diff --git a/lib/pages/details/widgets/media_player/media_viewer.dart b/lib/pages/details/widgets/media_player/media_viewer.dart index 9135977..97ab071 100644 --- a/lib/pages/details/widgets/media_player/media_viewer.dart +++ b/lib/pages/details/widgets/media_player/media_viewer.dart @@ -17,6 +17,7 @@ class MediaViewer extends StatelessWidget { required this.mediaItems, required this.totalMediaCount, required this.imagePageController, + required this.videoPlayerController, }); /// The axis of the media player and browser. @@ -31,6 +32,9 @@ class MediaViewer extends StatelessWidget { /// The controller for the image gallery. final PageController imagePageController; + /// The controller for the video player. + final VideoPlayerController? videoPlayerController; + /// Returns the media widget based on the media type. Widget _media(MediaItem mediaItem) { final MediaType mediaType = mediaItem.type; @@ -38,9 +42,7 @@ class MediaViewer extends StatelessWidget { case MediaType.youTubeVideo: return CustomYouTubePlayer(videoId: mediaItem.source); case MediaType.localVideo: - return LocalVideoPlayer( - videoPlayerController: VideoPlayerController.asset(mediaItem.source), - ); + return LocalVideoPlayer(videoPlayerController: videoPlayerController); case MediaType.localImage: return ImageViewer( imageProvider: AssetImage(mediaItem.source), diff --git a/lib/pages/details/widgets/media_player/multi_media_player.controller.dart b/lib/pages/details/widgets/media_player/multi_media_player.controller.dart index 4cac4e0..9ca068a 100644 --- a/lib/pages/details/widgets/media_player/multi_media_player.controller.dart +++ b/lib/pages/details/widgets/media_player/multi_media_player.controller.dart @@ -40,11 +40,30 @@ class MultiMediaPlayerController extends ChangeNotifier { late PageController imagePageController; /// The controller for the video player. - VideoPlayerController? videoPlayerController; + VideoPlayerController? _videoPlayerController; /// The function to call to toggle the media browser. late Function() _updateMediaBrowserVisibilityState; + /// The video player controller. + VideoPlayerController? get videoPlayerController { + if (_videoPlayerController?.dataSource != currentMediaItem.source) { + _disposeVideoPlayerController(); + } + + if (currentMediaItem.type == MediaType.localVideo && + _videoPlayerController != null) { + return _videoPlayerController; + } else if (currentMediaItem.type == MediaType.localVideo && + _videoPlayerController == null) { + _videoPlayerController = VideoPlayerController.asset( + currentMediaItem.source, + ); + return _videoPlayerController; + } + return _videoPlayerController; + } + /// Toggle the media browser. void toggleMediaBrowser() { _updateMediaBrowserVisibilityState(); @@ -59,7 +78,8 @@ class MultiMediaPlayerController extends ChangeNotifier { previousIndex = totalMediaCount - 1; imagePageController.jumpToPage(previousIndex); } else { - if (mediaItems[currentIndex].type == MediaType.youTubeVideo) { + if ([MediaType.youTubeVideo, MediaType.localVideo] + .contains(mediaItems[currentIndex].type)) { imagePageController.jumpToPage(previousIndex); } else { await imagePageController.animateToPage( @@ -80,7 +100,8 @@ class MultiMediaPlayerController extends ChangeNotifier { nextIndex = 0; imagePageController.jumpToPage(nextIndex); } else { - if (mediaItems[currentIndex].type == MediaType.youTubeVideo) { + if ([MediaType.youTubeVideo, MediaType.localVideo] + .contains(mediaItems[currentIndex].type)) { imagePageController.jumpToPage(nextIndex); } else { await imagePageController.animateToPage( @@ -101,12 +122,16 @@ class MultiMediaPlayerController extends ChangeNotifier { notifyListeners(); } + /// Dispose of the video player controller. + void _disposeVideoPlayerController() { + _videoPlayerController?.dispose(); + _videoPlayerController = null; + } + @override void dispose() { imagePageController.dispose(); - if (videoPlayerController != null) { - videoPlayerController!.dispose(); - } + _disposeVideoPlayerController(); super.dispose(); } } diff --git a/lib/pages/details/widgets/media_player/multi_media_player.dart b/lib/pages/details/widgets/media_player/multi_media_player.dart index ec20650..7311c2a 100644 --- a/lib/pages/details/widgets/media_player/multi_media_player.dart +++ b/lib/pages/details/widgets/media_player/multi_media_player.dart @@ -92,6 +92,7 @@ class MultiMediaPlayerState extends State { mediaItems: controller.mediaItems, totalMediaCount: controller.totalMediaCount, imagePageController: controller.imagePageController, + videoPlayerController: controller.videoPlayerController, ), ), PlayerBanner( diff --git a/lib/pages/home/widgets/header.dart b/lib/pages/home/widgets/header.dart index 200abe8..d1fcf5d 100644 --- a/lib/pages/home/widgets/header.dart +++ b/lib/pages/home/widgets/header.dart @@ -51,24 +51,25 @@ class Header extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - DefaultTextStyle( - style: compact - ? Theme.of(context).textTheme.labelSmall! - : Theme.of(context).textTheme.titleMedium!, - textAlign: TextAlign.left, - child: AnimatedTextKit( - repeatForever: true, - pause: const Duration(milliseconds: 250), - animatedTexts: [ - RotateAnimatedText( - Strings.subtitle, - duration: const Duration(seconds: 7), - ), - RotateAnimatedText( - Strings.motto, - duration: const Duration(seconds: 7), - ), - ], + Flexible( + child: DefaultTextStyle( + style: compact + ? Theme.of(context).textTheme.labelSmall! + : Theme.of(context).textTheme.titleMedium!, + maxLines: 2, + child: AnimatedTextKit( + repeatForever: true, + pause: const Duration(milliseconds: 250), + animatedTexts: Strings.headerSubtitles.map( + (String text) { + return RotateAnimatedText( + text, + alignment: Alignment.centerLeft, + duration: const Duration(seconds: 7), + ); + }, + ).toList(), + ), ), ), SizedBox( @@ -107,6 +108,7 @@ class Header extends StatelessWidget { child: Row( children: [ _profilePicture(context), + const SizedBox(width: 12.0), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/pages/personal_projects/widgets/projects_menu.dart b/lib/pages/personal_projects/widgets/projects_menu.dart index 286bc8a..f6bbd37 100644 --- a/lib/pages/personal_projects/widgets/projects_menu.dart +++ b/lib/pages/personal_projects/widgets/projects_menu.dart @@ -63,6 +63,12 @@ class ProjectsMenu extends StatelessWidget { builder: (BuildContext context, Orientation orientation) { return Consumer( builder: (BuildContext context, AppState appState, Widget? child) { + // ! This should be handled in AppRouter but redirect isn't being called + // ! on pop, so we're handling it here until it's fixed in GoRouter. + if (appState.currentRoute != Routes.personalProjects) { + appState.currentRoute = Routes.personalProjects; + } + return FrostedContainer( padding: EdgeInsets.zero, child: FutureBuilder( diff --git a/lib/pages/professional_experiences/widgets/prof_exp_menu.dart b/lib/pages/professional_experiences/widgets/prof_exp_menu.dart index 3cde724..9f6ca52 100644 --- a/lib/pages/professional_experiences/widgets/prof_exp_menu.dart +++ b/lib/pages/professional_experiences/widgets/prof_exp_menu.dart @@ -49,10 +49,16 @@ class ProfessionalExpMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return Consumer( - builder: (BuildContext context, AppState appState, Widget? child) { - return OrientationBuilder( - builder: (BuildContext context, Orientation orientation) { + return OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + return Consumer( + builder: (BuildContext context, AppState appState, Widget? child) { + // ! This should be handled in AppRouter but redirect isn't being called + // ! on pop, so we're handling it here until it's fixed in GoRouter. + if (appState.currentRoute != Routes.professionalExperiences) { + appState.currentRoute = Routes.professionalExperiences; + } + return FrostedContainer( padding: EdgeInsets.zero, child: FutureBuilder( diff --git a/pubspec.lock b/pubspec.lock index c3bc939..bbd4eb7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: "direct main" description: name: chewie - sha256: "8bc4ac4cf3f316e50a25958c0f5eb9bb12cf7e8308bb1d74a43b230da2cfc144" + sha256: "2243e41e79e865d426d9dd9c1a9624aa33c4ad11de2d0cd680f826e2cd30e879" url: "https://pub.dev" source: hosted - version: "1.7.5" + version: "1.8.3" clock: dependency: transitive description: @@ -156,10 +156,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: b465e99ce64ba75e61c8c0ce3d87b66d8ac07f0b35d0a7e0263fcfc10f99e836 + sha256: ddc16d34b0d74cb313986918c0f0885a7ba2fc24d8fb8419de75f0015144ccfe url: "https://pub.dev" source: hosted - version: "13.2.5" + version: "14.2.3" google_fonts: dependency: "direct main" description: @@ -208,14 +208,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" - source: hosted - version: "0.7.1" leak_tracker: dependency: transitive description: @@ -292,18 +284,18 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "8.0.2" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" path: dependency: transitive description: @@ -665,10 +657,10 @@ packages: dependency: transitive description: name: wakelock_plus - sha256: "26ebc8b5e0037c15e2a1b661dcec8a475cb7205befcce8a33f545ae8c86b367c" + sha256: "4fa83a128b4127619e385f686b4f080a5d2de46cff8e8c94eccac5fcf76550e5" url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "1.2.7" wakelock_plus_platform_interface: dependency: transitive description: @@ -681,10 +673,10 @@ packages: dependency: transitive description: name: web - sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "0.5.1" webview_flutter: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0a03c8a..9295457 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: plg_portfolio description: Pablo L. Guerra's web-app portfolio powered by Flutter. publish_to: "none" -version: 2.5.2+56 +version: 2.5.4+58 environment: sdk: ">=3.1.1 <4.0.0" @@ -14,10 +14,10 @@ dependencies: provider: ^6.1.2 url_launcher: ^6.2.5 intl: ^0.19.0 - chewie: ^1.7.5 + chewie: ^1.8.3 video_player: ^2.8.3 youtube_player_iframe: ^4.0.4 - go_router: ^13.2.1 + go_router: ^14.2.3 url_strategy: ^0.2.0 unorm_dart: ^0.3.0 shimmer: ^3.0.0 @@ -25,7 +25,7 @@ dependencies: animated_text_kit: ^4.2.2 pinch_zoom: ^2.0.0 flutter_spinkit: ^5.2.1 - package_info_plus: ^4.2.0 + package_info_plus: ^8.0.2 dev_dependencies: flutter_test: diff --git a/showcase/v2.5.0/mobile/dark/details.webp b/showcase/v2.5.0/mobile/dark/details.webp index b35f210..ed9c400 100644 Binary files a/showcase/v2.5.0/mobile/dark/details.webp and b/showcase/v2.5.0/mobile/dark/details.webp differ diff --git a/showcase/v2.5.0/mobile/dark/home.webp b/showcase/v2.5.0/mobile/dark/home.webp new file mode 100644 index 0000000..4c58566 Binary files /dev/null and b/showcase/v2.5.0/mobile/dark/home.webp differ diff --git a/showcase/v2.5.0/mobile/dark/home_drawer.webp b/showcase/v2.5.0/mobile/dark/home_drawer.webp deleted file mode 100644 index 2f8d5da..0000000 Binary files a/showcase/v2.5.0/mobile/dark/home_drawer.webp and /dev/null differ diff --git a/showcase/v2.5.0/mobile/dark/professional_experience.webp b/showcase/v2.5.0/mobile/dark/professional_experience.webp index 578479d..8b82e97 100644 Binary files a/showcase/v2.5.0/mobile/dark/professional_experience.webp and b/showcase/v2.5.0/mobile/dark/professional_experience.webp differ diff --git a/showcase/v2.5.0/mobile/light/details.webp b/showcase/v2.5.0/mobile/light/details.webp index 9898071..d8008c0 100644 Binary files a/showcase/v2.5.0/mobile/light/details.webp and b/showcase/v2.5.0/mobile/light/details.webp differ diff --git a/showcase/v2.5.0/mobile/light/home.webp b/showcase/v2.5.0/mobile/light/home.webp index 53492a0..4c6f4e4 100644 Binary files a/showcase/v2.5.0/mobile/light/home.webp and b/showcase/v2.5.0/mobile/light/home.webp differ diff --git a/showcase/v2.5.0/mobile/light/projects.webp b/showcase/v2.5.0/mobile/light/projects.webp index 6411a9c..a32cbee 100644 Binary files a/showcase/v2.5.0/mobile/light/projects.webp and b/showcase/v2.5.0/mobile/light/projects.webp differ