diff --git a/frontend/assets/icons/logo.svg b/frontend/assets/icons/logo.svg
deleted file mode 100644
index cca97ca..0000000
--- a/frontend/assets/icons/logo.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/frontend/assets/icons/splash.png b/frontend/assets/icons/splash.png
deleted file mode 100644
index f034796..0000000
Binary files a/frontend/assets/icons/splash.png and /dev/null differ
diff --git a/frontend/assets/icons/splash_orb.png b/frontend/assets/icons/splash_mark.png
similarity index 100%
rename from frontend/assets/icons/splash_orb.png
rename to frontend/assets/icons/splash_mark.png
diff --git a/frontend/lib/Grounded/designs/scene/SceneArt.dart b/frontend/lib/Grounded/designs/scene/SceneArt.dart
index c806341..74e3500 100644
--- a/frontend/lib/Grounded/designs/scene/SceneArt.dart
+++ b/frontend/lib/Grounded/designs/scene/SceneArt.dart
@@ -26,6 +26,9 @@ class SceneArt extends StatelessWidget {
/// Darkens the lower half so white type laid over it stays legible.
final bool shade;
+ /// Lowers the sun behind the ridges; animate it for a sunrise.
+ final double sunLift;
+
const SceneArt({
super.key,
required this.palette,
@@ -34,6 +37,7 @@ class SceneArt extends StatelessWidget {
this.figureScale = 0.5,
this.figureAlignment = const Alignment(0.35, 0.15),
this.shade = false,
+ this.sunLift = 1,
});
@override
@@ -50,7 +54,8 @@ class SceneArt extends StatelessWidget {
child: Stack(
fit: StackFit.expand,
children: [
- CustomPaint(painter: ScenePainter(palette, seed)),
+ CustomPaint(
+ painter: ScenePainter(palette, seed, sunLift: sunLift)),
if (figure != null)
Align(
alignment: figureAlignment,
diff --git a/frontend/lib/Grounded/designs/scene/ScenePainter.dart b/frontend/lib/Grounded/designs/scene/ScenePainter.dart
index 47653ac..107ff8d 100644
--- a/frontend/lib/Grounded/designs/scene/ScenePainter.dart
+++ b/frontend/lib/Grounded/designs/scene/ScenePainter.dart
@@ -11,7 +11,10 @@ class ScenePainter extends CustomPainter {
final int seed;
- ScenePainter(this.palette, this.seed);
+ /// 1 → the sun sits in its place; 0 → it is down behind the ridges.
+ final double sunLift;
+
+ ScenePainter(this.palette, this.seed, {this.sunLift = 1});
@override
void paint(Canvas canvas, Size size) {
@@ -36,7 +39,7 @@ class ScenePainter extends CustomPainter {
final double radius = math.min(w, h) * (0.13 + random.nextDouble() * 0.05);
final Offset sun = Offset(
w * (0.18 + random.nextDouble() * 0.64),
- h * (0.26 + random.nextDouble() * 0.12),
+ h * (0.26 + random.nextDouble() * 0.12) + h * 0.5 * (1 - sunLift),
);
canvas.drawCircle(
sun,
@@ -109,6 +112,8 @@ class ScenePainter extends CustomPainter {
@override
bool shouldRepaint(covariant ScenePainter oldDelegate) {
- return oldDelegate.seed != seed || oldDelegate.palette != palette;
+ return oldDelegate.seed != seed ||
+ oldDelegate.palette != palette ||
+ oldDelegate.sunLift != sunLift;
}
}
diff --git a/frontend/lib/Grounded/see/splash/SplashState.dart b/frontend/lib/Grounded/see/splash/SplashState.dart
index 6c13738..c8b5117 100644
--- a/frontend/lib/Grounded/see/splash/SplashState.dart
+++ b/frontend/lib/Grounded/see/splash/SplashState.dart
@@ -1,11 +1,13 @@
import 'dart:async';
+import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:stacked/stacked.dart';
import '../../about/internal/application/MeDescription.dart';
import '../../about/internal/application/NavigatorType.dart';
+import '../../about/internal/application/RoutineKind.dart';
import '../../about/internal/application/TextType.dart';
import '../../configs/Navigator.dart';
import '../../designs/AmbientBackground.dart';
@@ -15,6 +17,7 @@ import '../../designs/Responsive.dart';
import '../../designs/scene/SceneArt.dart';
import '../../designs/text/Text.dart';
import '../../utils/Colors.dart';
+import '../../utils/CommonUtils.dart';
import '../home/Home.dart';
import '../login/Login.dart';
import 'ConnectSplash.dart';
@@ -24,6 +27,28 @@ import 'ViewSplash.dart';
class SplashState extends State implements ConnectSplash {
ViewSplash? _model;
+ Timer? _statusTimer;
+
+ int _status = 0;
+
+ /// Set once the session check has been asked for, so a tap and the timer
+ /// never both fire it.
+ bool _launched = false;
+
+ /// What the loader says while it fills — the app's three jobs, in order.
+ static const List _statuses = [
+ "Loading your plan",
+ "Checking what's overdue",
+ "Lining up today's routines",
+ "Ready",
+ ];
+
+ @override
+ void dispose() {
+ _statusTimer?.cancel();
+ super.dispose();
+ }
+
@override
Widget build(BuildContext context) {
return ViewModelBuilder.reactive(
@@ -51,136 +76,329 @@ class SplashState extends State implements ConnectSplash {
}
Future _initiate() async {
- // Long enough for the mark to land and take one breath, then the session
- // decides where we land.
- await Future.delayed(const Duration(milliseconds: 2200));
+ _statusTimer = Timer.periodic(
+ const Duration(milliseconds: 1000), _onStatusTick);
+
+ // Long enough to watch the sun come up and read the screen once; a tap
+ // skips straight on.
+ await Future.delayed(const Duration(milliseconds: 4200));
+ _launch();
+ }
+
+ void _onStatusTick(Timer timer) {
+ if (!mounted) {
+ return;
+ }
+ setState(() {
+ _status = (_status + 1).clamp(0, _statuses.length - 1);
+ });
+ }
+
+ void _onSkip() {
+ _launch();
+ }
+
+ void _launch() {
+ if (_launched || !mounted) {
+ return;
+ }
+ _launched = true;
+ _statusTimer?.cancel();
_model?.initialize();
}
+ String _greeting() {
+ final int hour = DateTime.now().hour;
+ if (hour < 5) {
+ return "Still up";
+ }
+ if (hour < 12) {
+ return "Good morning";
+ }
+ if (hour < 18) {
+ return "Good afternoon";
+ }
+ return "Good evening";
+ }
+
Widget _mobileView(BoxConstraints constraints) {
- return AmbientBackground(
- child: Stack(
- children: [
- // The landscape rising from the bottom edge — the same painted world
- // the routine cards live in.
- Positioned(
- left: 0,
- right: 0,
- bottom: 0,
- height: constraints.maxHeight * 0.34,
- child: ShaderMask(
- shaderCallback: (Rect bounds) => const LinearGradient(
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- colors: [Color(0x00000000), Color(0xFF000000)],
- stops: [0.0, 0.45],
- ).createShader(bounds),
- blendMode: BlendMode.dstIn,
- child: const SceneArt(palette: sceneWorkout, seed: 11),
- )
- .animate()
- .fadeIn(duration: 1200.ms, curve: Curves.easeOut)
- .slideY(begin: 0.25, end: 0, duration: 1400.ms,
- curve: Curves.easeOutCubic),
- ),
- SafeArea(
- child: Padding(
- padding: const EdgeInsets.fromLTRB(28, 18, 28, 32),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- text("Grounded", 17, TextType.Regular, color: colorInk),
- text("Daily discipline", 17, TextType.Regular,
- color: colorInkSoft),
- ],
- ).animate().fadeIn(duration: 600.ms, delay: 200.ms),
- const Spacer(flex: 3),
- Center(child: _mark()),
- const SizedBox(height: 40),
- _wordmark(),
- const Spacer(flex: 4),
- _loader(),
- ],
+ return GestureDetector(
+ onTap: _onSkip,
+ behavior: HitTestBehavior.opaque,
+ child: AmbientBackground(
+ child: Stack(
+ children: [
+ _landscape(constraints),
+ ..._motes(constraints),
+ SafeArea(
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(24, 14, 24, 22),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ _topRow(),
+ const Spacer(flex: 2),
+ _hero(),
+ const SizedBox(height: 26),
+ _wordmark(),
+ const Spacer(flex: 2),
+ _howItWorks(),
+ const Spacer(flex: 1),
+ _loader(),
+ ],
+ ),
),
),
- ),
- ],
+ ],
+ ),
),
);
}
- /// The mark on glass, inside rings that breathe outward.
- Widget _mark() {
+ /// The painted valley rising from the bottom edge while its sun comes up.
+ Widget _landscape(BoxConstraints constraints) {
+ return Positioned(
+ left: 0,
+ right: 0,
+ bottom: 0,
+ height: constraints.maxHeight * 0.42,
+ child: ShaderMask(
+ shaderCallback: (Rect bounds) => const LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [Color(0x00000000), Color(0xFF000000)],
+ stops: [0.0, 0.4],
+ ).createShader(bounds),
+ blendMode: BlendMode.dstIn,
+ child: TweenAnimationBuilder(
+ tween: Tween(begin: 0, end: 1),
+ duration: const Duration(milliseconds: 3200),
+ curve: Curves.easeOutCubic,
+ builder: (context, lift, child) => SceneArt(
+ palette: sceneWorkout,
+ seed: 11,
+ sunLift: lift,
+ ),
+ ),
+ )
+ .animate()
+ .fadeIn(duration: 900.ms)
+ .slideY(begin: 0.3, end: 0, duration: 1400.ms,
+ curve: Curves.easeOutCubic),
+ );
+ }
+
+ /// Specks of light drifting up out of the valley.
+ List _motes(BoxConstraints constraints) {
+ const List xs = [0.12, 0.27, 0.41, 0.58, 0.7, 0.84, 0.93];
+
+ return List.generate(xs.length, (index) {
+ final double size = 4.0 + (index % 3) * 2;
+
+ return Positioned(
+ left: constraints.maxWidth * xs[index],
+ bottom: constraints.maxHeight * (0.08 + (index % 4) * 0.05),
+ child: IgnorePointer(
+ child: Container(
+ width: size,
+ height: size,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: colorWhite,
+ boxShadow: [
+ BoxShadow(
+ color: colorWhite.withValues(alpha: 0.8), blurRadius: 8),
+ ],
+ ),
+ )
+ .animate(onPlay: (controller) => controller.repeat())
+ .fadeIn(duration: 600.ms, delay: (index * 260).ms)
+ .moveY(
+ begin: 0,
+ end: -140 - index * 12.0,
+ duration: (2600 + index * 240).ms,
+ delay: (index * 260).ms,
+ curve: Curves.easeOut,
+ )
+ .fadeOut(
+ duration: 900.ms, delay: (2000 + index * 240).ms),
+ ),
+ );
+ });
+ }
+
+ Widget _topRow() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ const GroundedMark(size: 26),
+ const SizedBox(width: 8),
+ text("Grounded", 16, TextType.Medium, color: colorInk),
+ ],
+ ),
+ GlassSurface(
+ radius: BorderRadius.circular(99),
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 7),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Icon(CupertinoIcons.sun_max_fill,
+ size: 13, color: colorStandingWarned),
+ const SizedBox(width: 6),
+ text(_greeting(), 12, TextType.Medium, color: colorInk),
+ ],
+ ),
+ ),
+ ],
+ ).animate().fadeIn(duration: 600.ms, delay: 150.ms).slideY(
+ begin: -0.4, end: 0, duration: 600.ms, delay: 150.ms);
+ }
+
+ /// The mark in breathing rings, with the four things the app holds you to
+ /// floating around it.
+ Widget _hero() {
return SizedBox(
- width: 230,
- height: 230,
+ height: 270,
child: Stack(
alignment: Alignment.center,
children: [
for (int ring = 0; ring < 3; ring++)
Container(
- width: 120,
- height: 120,
+ width: 140,
+ height: 140,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
- color: colorWhite.withValues(alpha: 0.9), width: 1.4),
+ color: colorWhite.withValues(alpha: 0.95), width: 1.4),
),
)
.animate(onPlay: (controller) => controller.repeat())
.scale(
begin: const Offset(1, 1),
- end: const Offset(1.9, 1.9),
- duration: 2400.ms,
- delay: (ring * 800).ms,
+ end: const Offset(1.85, 1.85),
+ duration: 2700.ms,
+ delay: (ring * 900).ms,
curve: Curves.easeOutCubic,
)
- .fadeOut(duration: 2400.ms, delay: (ring * 800).ms),
- GlassSurface(
- radius: BorderRadius.circular(44),
- padding: const EdgeInsets.all(10),
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(32),
- boxShadow: [
- BoxShadow(
- color: colorPrimary.withValues(alpha: 0.35),
- blurRadius: 40,
- offset: const Offset(0, 16),
- ),
- ],
- ),
- // The sun rises out of the ground line, then the arcs light.
- child: TweenAnimationBuilder(
- tween: Tween(begin: 0, end: 1),
- duration: const Duration(milliseconds: 1700),
- builder: (context, t, child) => GroundedMark(
- size: 132,
- rise: Curves.easeOutCubic
- .transform((t / 0.6).clamp(0.0, 1.0)),
- arcs: Curves.easeOut
- .transform(((t - 0.45) / 0.55).clamp(0.0, 1.0)),
- ),
- ),
- ),
- )
- .animate()
- .scale(
- begin: const Offset(0.6, 0.6),
- end: const Offset(1, 1),
- duration: 900.ms,
- curve: Curves.easeOutBack,
- )
- .fadeIn(duration: 500.ms),
+ .fadeOut(duration: 2700.ms, delay: (ring * 900).ms),
+ _mark(),
+ _chip(const Alignment(-1, -1), sceneWorkout,
+ kindIcon(RoutineKind.Workout), "Workout routines", 0),
+ _chip(const Alignment(1, -0.62), sceneMeditation,
+ kindIcon(RoutineKind.Meditation), "Breathing sessions", 1),
+ _chip(const Alignment(-1, 0.62), sceneMustDo,
+ kindIcon(RoutineKind.MustDo), "Must-do chains", 2),
+ _chip(const Alignment(1, 1), goalScene(goalAccents[4]),
+ CupertinoIcons.flag_fill, "Goals with deadlines", 3),
],
),
);
}
- /// Two-tone, like the greeting on the home screen.
+ Widget _mark() {
+ return GlassSurface(
+ radius: BorderRadius.circular(46),
+ padding: const EdgeInsets.all(10),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(34),
+ boxShadow: [
+ BoxShadow(
+ color: colorPrimary.withValues(alpha: 0.4),
+ blurRadius: 40,
+ offset: const Offset(0, 16),
+ ),
+ ],
+ ),
+ // The sun rises out of the ground line, then the arcs light.
+ child: TweenAnimationBuilder(
+ tween: Tween(begin: 0, end: 1),
+ duration: const Duration(milliseconds: 1800),
+ builder: (context, t, child) => GroundedMark(
+ size: 128,
+ rise: Curves.easeOutCubic.transform((t / 0.6).clamp(0.0, 1.0)),
+ arcs: Curves.easeOut
+ .transform(((t - 0.45) / 0.55).clamp(0.0, 1.0)),
+ ),
+ ),
+ ),
+ )
+ .animate()
+ .scale(
+ begin: const Offset(0.6, 0.6),
+ end: const Offset(1, 1),
+ duration: 900.ms,
+ curve: Curves.easeOutBack,
+ )
+ .fadeIn(duration: 500.ms);
+ }
+
+ /// A frosted chip with a painted thumbnail. It drifts in, then bobs.
+ Widget _chip(Alignment alignment, List palette, IconData icon,
+ String label, int index) {
+ return Align(
+ alignment: alignment,
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(99),
+ boxShadow: const [
+ BoxShadow(
+ color: Color(0x142A3A30),
+ blurRadius: 16,
+ offset: Offset(0, 6),
+ ),
+ ],
+ ),
+ child: GlassSurface(
+ radius: BorderRadius.circular(99),
+ tint: colorGlassStrong,
+ padding: const EdgeInsets.fromLTRB(4, 4, 12, 4),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(
+ width: 28,
+ height: 28,
+ child: ClipOval(
+ child: SceneArt(
+ palette: palette,
+ seed: 5 + index * 9,
+ figure: icon,
+ figureScale: 0.52,
+ figureAlignment: const Alignment(0, 0.2),
+ ),
+ ),
+ ),
+ const SizedBox(width: 8),
+ text(label, 12, TextType.Medium, color: colorInk),
+ ],
+ ),
+ ),
+ )
+ .animate()
+ .fadeIn(duration: 500.ms, delay: (900 + index * 180).ms)
+ .slideX(
+ begin: alignment.x < 0 ? -0.3 : 0.3,
+ end: 0,
+ duration: 600.ms,
+ delay: (900 + index * 180).ms,
+ curve: Curves.easeOutCubic,
+ )
+ .then()
+ .animate(onPlay: (controller) => controller.repeat(reverse: true))
+ .moveY(
+ begin: -3,
+ end: 3,
+ duration: (1800 + index * 260).ms,
+ curve: Curves.easeInOut,
+ ),
+ );
+ }
+
+ /// Two tones, like the greeting on the home screen; the name catches the
+ /// light once as it lands.
Widget _wordmark() {
return Column(
children: [
@@ -189,9 +407,11 @@ class SplashState extends State implements ConnectSplash {
.animate()
.fadeIn(duration: 700.ms, delay: 350.ms)
.slideY(begin: 0.3, end: 0, duration: 700.ms, delay: 350.ms,
- curve: Curves.easeOutCubic),
- const SizedBox(height: 10),
- text("A to-do app that\ndoesn't believe you.", 22, TextType.Light,
+ curve: Curves.easeOutCubic)
+ .then(delay: 300.ms)
+ .shimmer(duration: 1200.ms, color: colorLime),
+ const SizedBox(height: 8),
+ text("A to-do app that\ndoesn't believe you.", 21, TextType.Regular,
color: colorInkSoft, align: TextAlign.center, height: 1.3)
.animate()
.fadeIn(duration: 700.ms, delay: 650.ms)
@@ -201,7 +421,80 @@ class SplashState extends State implements ConnectSplash {
);
}
- /// A glass capsule that fills while the session resolves.
+ /// The whole idea in three beats, on glass over the valley.
+ Widget _howItWorks() {
+ return GlassSurface(
+ radius: BorderRadius.circular(24),
+ tint: colorGlassStrong,
+ padding: const EdgeInsets.fromLTRB(14, 14, 14, 14),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ child: _beat(CupertinoIcons.hand_raised_fill, "Commit",
+ "Say it and set a window", 0)),
+ _beatArrow(0),
+ Expanded(
+ child: _beat(CupertinoIcons.timer, "Do it",
+ "Inside the window, with proof", 1)),
+ _beatArrow(1),
+ Expanded(
+ child: _beat(CupertinoIcons.exclamationmark_triangle_fill,
+ "Or owe it", "Misses turn into debt", 2)),
+ ],
+ ),
+ ).animate().fadeIn(duration: 600.ms, delay: 1500.ms).slideY(
+ begin: 0.25, end: 0, duration: 700.ms, delay: 1500.ms,
+ curve: Curves.easeOutCubic);
+ }
+
+ Widget _beat(IconData icon, String title, String caption, int index) {
+ final List tones = [
+ colorPrimary,
+ colorKindMeditation,
+ colorStandingGrounded,
+ ];
+
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: 36,
+ height: 36,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: tones[index].withValues(alpha: 0.12),
+ ),
+ child: Icon(icon, size: 16, color: tones[index]),
+ )
+ .animate()
+ .scale(
+ begin: const Offset(0.4, 0.4),
+ end: const Offset(1, 1),
+ duration: 500.ms,
+ delay: (1700 + index * 250).ms,
+ curve: Curves.easeOutBack,
+ ),
+ const SizedBox(height: 8),
+ text(title, 13, TextType.Medium, color: colorInk),
+ const SizedBox(height: 2),
+ text(caption, 10, TextType.Regular,
+ color: colorInkSoft, align: TextAlign.center, maxLines: 2),
+ ],
+ );
+ }
+
+ Widget _beatArrow(int index) {
+ return Padding(
+ padding: const EdgeInsets.only(top: 12),
+ child: Icon(CupertinoIcons.chevron_right, size: 12, color: colorInkSoft)
+ .animate()
+ .fadeIn(duration: 400.ms, delay: (1900 + index * 250).ms),
+ );
+ }
+
+ /// A glass capsule that fills while the session resolves, and a status
+ /// line that walks through what is being checked.
Widget _loader() {
return Column(
children: [
@@ -209,33 +502,50 @@ class SplashState extends State implements ConnectSplash {
radius: BorderRadius.circular(99),
padding: const EdgeInsets.all(3),
child: SizedBox(
- width: 140,
+ width: 150,
height: 6,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
- width: 140,
+ width: 150,
decoration: BoxDecoration(
color: colorNight,
borderRadius: BorderRadius.circular(99),
),
- )
- .animate()
- .scaleX(
+ ).animate().scaleX(
begin: 0.04,
end: 1,
alignment: Alignment.centerLeft,
- duration: 2000.ms,
+ duration: 4000.ms,
curve: Curves.easeInOutCubic,
),
),
),
),
- const SizedBox(height: 12),
- text("Checking what you promised", 12, TextType.Regular,
- color: colorWhite.withValues(alpha: 0.9)),
+ const SizedBox(height: 10),
+ AnimatedSwitcher(
+ duration: const Duration(milliseconds: 300),
+ transitionBuilder: (child, animation) => FadeTransition(
+ opacity: animation,
+ child: SlideTransition(
+ position: Tween(
+ begin: const Offset(0, 0.4),
+ end: Offset.zero,
+ ).animate(animation),
+ child: child,
+ ),
+ ),
+ child: KeyedSubtree(
+ key: ValueKey(_status),
+ child: text(_statuses[_status], 12, TextType.Medium,
+ color: colorWhite),
+ ),
+ ),
+ const SizedBox(height: 4),
+ text("Tap anywhere to skip", 10, TextType.Regular,
+ color: colorWhite.withValues(alpha: 0.7)),
],
- ).animate().fadeIn(duration: 500.ms, delay: 900.ms);
+ ).animate().fadeIn(duration: 500.ms, delay: 600.ms);
}
@override
diff --git a/frontend/lib/Grounded/utils/Images.dart b/frontend/lib/Grounded/utils/Images.dart
index 108789a..774f3c0 100644
--- a/frontend/lib/Grounded/utils/Images.dart
+++ b/frontend/lib/Grounded/utils/Images.dart
@@ -3,7 +3,7 @@ const String imagePath = "assets/images";
const String iconPath = "assets/icons";
/// The mark on a night disc, as the native splash shows it.
-const String splashMark = "$iconPath/splash_orb.png";
+const String splashMark = "$iconPath/splash_mark.png";
const String logoMark = "$iconPath/icon.png";
diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml
index dfd45e3..60484de 100644
--- a/frontend/pubspec.yaml
+++ b/frontend/pubspec.yaml
@@ -122,10 +122,10 @@ flutter_launcher_icons:
# the OS screen to the app is invisible.
flutter_native_splash:
color: "#EAEFE6"
- image: "assets/icons/splash_orb.png"
+ image: "assets/icons/splash_mark.png"
android_12:
color: "#EAEFE6"
- image: "assets/icons/splash_orb.png"
+ image: "assets/icons/splash_mark.png"
icon_background_color: "#EAEFE6"
android: true
ios: true
diff --git a/frontend/web/index.html b/frontend/web/index.html
index e54d59a..f2e3b1f 100644
--- a/frontend/web/index.html
+++ b/frontend/web/index.html
@@ -34,6 +34,8 @@
+
+