diff --git a/api/src/main/kotlin/de/chaosdorf/mete/model/DrinkModel.kt b/api/src/main/kotlin/de/chaosdorf/mete/model/DrinkModel.kt
index 5019a19205bd5416866be4e26a76769886d1167c..f63a8e9187bf0503aadd044601418bd9143a3b68 100644
--- a/api/src/main/kotlin/de/chaosdorf/mete/model/DrinkModel.kt
+++ b/api/src/main/kotlin/de/chaosdorf/mete/model/DrinkModel.kt
@@ -33,5 +33,5 @@ interface DrinkModel {
   val volume: BigDecimal
   val caffeine: Int?
   val price: BigDecimal
-  val logoUrl: String
+  val logoUrl: String?
 }
diff --git a/api/src/main/kotlin/de/chaosdorf/mete/model/UserModel.kt b/api/src/main/kotlin/de/chaosdorf/mete/model/UserModel.kt
index 6d46048b5dce582564c39cf671f0470adbf8de16..aa51899d8941c94fdb4f926d77bcc76b8f55af93 100644
--- a/api/src/main/kotlin/de/chaosdorf/mete/model/UserModel.kt
+++ b/api/src/main/kotlin/de/chaosdorf/mete/model/UserModel.kt
@@ -30,7 +30,7 @@ interface UserModel {
   val userId: UserId
   val active: Boolean
   val name: String
-  val email: String
+  val email: String?
   val balance: BigDecimal
   val audit: Boolean
   val redirect: Boolean
diff --git a/api/src/main/kotlin/de/chaosdorf/mete/v1/DrinkModelV1.kt b/api/src/main/kotlin/de/chaosdorf/mete/v1/DrinkModelV1.kt
index 30755a7165cd70c49500a8ba095f09acd4d9025f..d6027fb5fb06a8e72ccc8e08051c0acabe35a285 100644
--- a/api/src/main/kotlin/de/chaosdorf/mete/v1/DrinkModelV1.kt
+++ b/api/src/main/kotlin/de/chaosdorf/mete/v1/DrinkModelV1.kt
@@ -49,17 +49,17 @@ internal data class DrinkModelV1(
   @Serializable(with = BigDecimalSerializer::class)
   override val price: BigDecimal,
   @SerialName("logo_file_name")
-  val logoFileName: String,
+  val logoFileName: String?,
   @SerialName("created_at")
   val createdAt: Instant,
   @SerialName("updated_at")
   val updatedAt: Instant,
   @SerialName("logo_content_type")
-  val logoContentType: String,
+  val logoContentType: String?,
   @SerialName("logo_file_size")
-  val logoFileSize: Long,
+  val logoFileSize: Long?,
   @SerialName("logo_updated_at")
-  val logoUpdatedAt: Instant,
+  val logoUpdatedAt: Instant?,
   @SerialName("logo_url")
-  override val logoUrl: String,
+  override val logoUrl: String?,
 ) : DrinkModel
diff --git a/api/src/main/kotlin/de/chaosdorf/mete/v1/UserModelV1.kt b/api/src/main/kotlin/de/chaosdorf/mete/v1/UserModelV1.kt
index 75d6edccca00a13fd028679787d40cfcd4bdb27d..9f6d420e253cfbaa94507df221d7e2a0993fc848 100644
--- a/api/src/main/kotlin/de/chaosdorf/mete/v1/UserModelV1.kt
+++ b/api/src/main/kotlin/de/chaosdorf/mete/v1/UserModelV1.kt
@@ -39,7 +39,7 @@ internal data class UserModelV1(
   @SerialName("name")
   override val name: String,
   @SerialName("email")
-  override val email: String,
+  override val email: String?,
   @SerialName("balance")
   @Serializable(with = BigDecimalSerializer::class)
   override val balance: BigDecimal,
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
index a43e4cacfbe397ee8d31dbbb00124f66e9fa41eb..8dadcc4530733e3152e9307c031e47f9ced33d4f 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
@@ -43,7 +43,6 @@ import androidx.navigation.compose.NavHost
 import androidx.navigation.compose.composable
 import androidx.navigation.compose.navigation
 import androidx.navigation.compose.rememberNavController
-import de.chaosdorf.meteroid.ui.transactions.TransactionListScreen
 import de.chaosdorf.meteroid.ui.drinks.DrinkListScreen
 import de.chaosdorf.meteroid.ui.drinks.DrinkListViewModel
 import de.chaosdorf.meteroid.ui.money.MoneyListScreen
@@ -51,8 +50,11 @@ import de.chaosdorf.meteroid.ui.money.MoneyListViewModel
 import de.chaosdorf.meteroid.ui.navigation.Routes
 import de.chaosdorf.meteroid.ui.servers.AddServerScreen
 import de.chaosdorf.meteroid.ui.servers.ServerListScreen
+import de.chaosdorf.meteroid.ui.transactions.TransactionListScreen
 import de.chaosdorf.meteroid.ui.transactions.TransactionViewModel
 import de.chaosdorf.meteroid.ui.users.UserListScreen
+import de.chaosdorf.meteroid.ui.wrapped.WrappedScreen
+import de.chaosdorf.meteroid.ui.wrapped.WrappedViewModel
 import kotlinx.coroutines.launch
 
 @Composable
@@ -158,6 +160,10 @@ fun AppRouter(viewModel: AppViewModel = viewModel()) {
         val transactionViewModel = hiltViewModel<TransactionViewModel>()
         TransactionListScreen(transactionViewModel, navController::navigate)
       }
+      composable(Routes.Home.Wrapped) { _ ->
+        val wrappedViewModel = hiltViewModel<WrappedViewModel>()
+        WrappedScreen(wrappedViewModel, navController::navigate)
+      }
     }
   }
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
index 6604ee78fe352e078c380428d6f8cd801d340fad..73332041878de24c291c4343ed23f66cdfa85e4f 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
@@ -49,6 +49,10 @@ import de.chaosdorf.meteroid.ui.navigation.HomeSections
 import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
 import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
 import de.chaosdorf.meteroid.ui.navigation.Routes
+import kotlinx.datetime.Clock
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+import java.time.Month
 
 @OptIn(ExperimentalLayoutApi::class)
 @Composable
@@ -86,6 +90,8 @@ fun DrinkListScreen(
       MeteroidBottomBar(
         currentRoute = HomeSections.PURCHASE,
         historyEnabled = account?.user?.audit == true,
+        wrappedEnabled = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
+          .month.let { it == Month.NOVEMBER || it == Month.DECEMBER },
         navigateTo = onNavigate
       )
     },
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkTile.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkTile.kt
index 7c141b9503ddef01638d7deeedb333a2707852e5..ab9b07c052f48a4d853fb4d05e6d68e4def8b967 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkTile.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkTile.kt
@@ -68,7 +68,7 @@ fun DrinkTile(
     item.logoUrl
   )
   val drinkPainter = rememberAsyncImagePainter(
-    item.logoUrl.replace("/thumb/", "/original/"),
+    item.originalLogoUrl,
     error = thumbPainter
   )
 
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
index d553e02dfc60f6fd7dc0b8983647fb9dfe73c956..c6e9dfc4e96a5a74af47b94152e9d7951a888a17 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
@@ -47,6 +47,10 @@ import de.chaosdorf.meteroid.ui.navigation.HomeSections
 import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
 import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
 import de.chaosdorf.meteroid.ui.navigation.Routes
+import kotlinx.datetime.Clock
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+import java.time.Month
 
 @Composable
 fun MoneyListScreen(
@@ -81,6 +85,8 @@ fun MoneyListScreen(
       MeteroidBottomBar(
         currentRoute = HomeSections.DEPOSIT,
         historyEnabled = account?.user?.audit == true,
+        wrappedEnabled = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
+          .month.let { it == Month.NOVEMBER || it == Month.DECEMBER },
         navigateTo = onNavigate
       )
     },
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/HomeSections.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/HomeSections.kt
index c0879743211d72fca287405f5dbd5243784856c1..08f21ccad6a3ed5ba7644442bbb5c4599c4e9936 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/HomeSections.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/HomeSections.kt
@@ -25,18 +25,25 @@
 package de.chaosdorf.meteroid.ui.navigation
 
 import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Celebration
+import androidx.compose.material.icons.outlined.History
+import androidx.compose.material.icons.outlined.LocalAtm
+import androidx.compose.material.icons.twotone.Celebration
 import androidx.compose.material.icons.twotone.History
 import androidx.compose.material.icons.twotone.LocalAtm
 import androidx.compose.ui.graphics.vector.ImageVector
 import de.chaosdorf.meteroid.icons.MeteroidIcons
+import de.chaosdorf.meteroid.icons.outlined.WaterFull
 import de.chaosdorf.meteroid.icons.twotone.WaterFull
 
 enum class HomeSections(
   override val title: String,
   override val icon: ImageVector,
+  override val iconActive: ImageVector,
   override val route: String
 ) : MeteroidNavSection {
-  PURCHASE("Drinks", MeteroidIcons.TwoTone.WaterFull, Routes.Home.Purchase),
-  DEPOSIT("Money", Icons.TwoTone.LocalAtm, Routes.Home.Deposit),
-  HISTORY("History", Icons.TwoTone.History, Routes.Home.History);
+  PURCHASE("Drinks", MeteroidIcons.Outlined.WaterFull, MeteroidIcons.TwoTone.WaterFull, Routes.Home.Purchase),
+  DEPOSIT("Money", Icons.Outlined.LocalAtm, Icons.TwoTone.LocalAtm, Routes.Home.Deposit),
+  HISTORY("History", Icons.Outlined.History, Icons.TwoTone.History, Routes.Home.History),
+  WRAPPED("Wrapped", Icons.Outlined.Celebration, Icons.TwoTone.Celebration, Routes.Home.Wrapped);
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidBottomBar.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidBottomBar.kt
index 18238c82faec1b9d23fe0113c896108a5b8f8155..760314f3b1ddb5c5684d1c73e526fcb667739afb 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidBottomBar.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidBottomBar.kt
@@ -37,25 +37,33 @@ fun <T : MeteroidNavSection> MeteroidBottomBar(
   currentRoute: T,
   navigateTo: (String, NavOptions) -> Unit,
   historyEnabled: Boolean,
+  wrappedEnabled: Boolean,
   modifier: Modifier = Modifier
 ) {
   NavigationBar {
     for (route in HomeSections.entries) {
-      NavigationBarItem(
-        icon = { Icon(route.icon, contentDescription = route.title) },
-        label = { Text(route.title) },
-        selected = route == currentRoute,
-        onClick = {
-          navigateTo(
-            route.route,
-            NavOptions.Builder()
-              .setPopUpTo(Routes.Home.Root, true)
-              .build()
-          )
-        },
-        modifier = modifier,
-        enabled = route != HomeSections.HISTORY || historyEnabled
-      )
+      if (wrappedEnabled || route != HomeSections.WRAPPED) {
+        NavigationBarItem(
+          icon = {
+            Icon(
+              if (route == currentRoute) route.iconActive else route.icon,
+              contentDescription = route.title
+            )
+          },
+          label = { Text(route.title) },
+          selected = route == currentRoute,
+          onClick = {
+            navigateTo(
+              route.route,
+              NavOptions.Builder()
+                .setPopUpTo(Routes.Home.Root, true)
+                .build()
+            )
+          },
+          modifier = modifier,
+          enabled = route != HomeSections.HISTORY || historyEnabled
+        )
+      }
     }
   }
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidNavSection.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidNavSection.kt
index f89144fcbf37f8c13f75dc011de5c305e8bf85f4..d56b347cb8b721e072530335fbc2ec6773f331ee 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidNavSection.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidNavSection.kt
@@ -29,5 +29,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
 interface MeteroidNavSection {
   val title: String
   val icon: ImageVector
+  val iconActive: ImageVector
   val route: String
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/Routes.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/Routes.kt
index f9938c462ca77b3fdf2ee291a48d3394cbeb68fe..a475733f3df74271439259ce2c0132709ba32cf6 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/Routes.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/Routes.kt
@@ -44,5 +44,6 @@ object Routes {
     const val Deposit = "$Root/deposit"
     const val Purchase = "$Root/purchase"
     const val History = "$Root/history"
+    const val Wrapped = "$Root/wrapped"
   }
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListItem.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListItem.kt
index 5b5c6682244098d71a4154223e682a1b4b8ed50b..7376c6d1ca56052a378411dd2570ad4823c27199 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListItem.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListItem.kt
@@ -89,7 +89,7 @@ fun TransactionListItem(
             drink.logoUrl
           )
           val originalPainter = rememberAsyncImagePainter(
-            drink.logoUrl.replace("/thumb/", "/original/"),
+            drink.originalLogoUrl,
             error = thumbPainter
           )
 
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
index bc1eefc70d93302aca1e1e7942d61f382fca37ee..ee0a63947b72a16fd9b80b457bb967ec0af5a41a 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
@@ -40,6 +40,10 @@ import androidx.navigation.NavOptions
 import de.chaosdorf.meteroid.ui.navigation.HomeSections
 import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
 import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
+import kotlinx.datetime.Clock
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+import java.time.Month
 
 @Composable
 fun TransactionListScreen(
@@ -67,6 +71,8 @@ fun TransactionListScreen(
       MeteroidBottomBar(
         currentRoute = HomeSections.HISTORY,
         historyEnabled = account?.user?.audit == true,
+        wrappedEnabled = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
+          .month.let { it == Month.NOVEMBER || it == Month.DECEMBER },
         navigateTo = onNavigate
       )
     },
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedScreen.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b36cf87a8460da6361bb2ef208f04f0e154bfedc
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedScreen.kt
@@ -0,0 +1,188 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2023 Chaosdorf e.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package de.chaosdorf.meteroid.ui.wrapped
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.ListItem
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import androidx.navigation.NavOptions
+import coil.compose.rememberAsyncImagePainter
+import de.chaosdorf.meteroid.R
+import de.chaosdorf.meteroid.ui.navigation.HomeSections
+import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
+import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
+import kotlinx.datetime.Clock
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+import java.time.Month
+import java.time.format.TextStyle
+
+@Composable
+fun WrappedScreen(
+  viewModel: WrappedViewModel,
+  onNavigate: (String, NavOptions) -> Unit
+) {
+  val account by viewModel.account.collectAsState()
+  val slides by viewModel.slides.collectAsState()
+  val snackbarHostState = remember { SnackbarHostState() }
+
+  LaunchedEffect(account) {
+    val offline = viewModel.checkOffline(account?.server)
+    snackbarHostState.currentSnackbarData?.dismiss()
+    if (offline) {
+      snackbarHostState.showSnackbar(
+        message = "Unable to connect to server",
+        duration = SnackbarDuration.Indefinite
+      )
+    }
+  }
+
+  Scaffold(
+    topBar = { MeteroidTopBar(account, onNavigate, viewModel::togglePin) },
+    bottomBar = {
+      MeteroidBottomBar(
+        currentRoute = HomeSections.WRAPPED,
+        historyEnabled = account?.user?.audit == true,
+        wrappedEnabled = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
+          .month.let { it == Month.NOVEMBER || it == Month.DECEMBER },
+        navigateTo = onNavigate
+      )
+    },
+    snackbarHost = {
+      SnackbarHost(hostState = snackbarHostState)
+    }
+  ) { paddingValues: PaddingValues ->
+    LazyColumn(contentPadding = paddingValues) {
+      items(slides) { slide ->
+        when (slide) {
+          is WrappedSlide.MostBoughtDrink ->
+            ListItem(
+              headlineContent = {
+                Text("Your favorite drink is ${slide.drink.name}")
+              },
+              supportingContent = {
+                Text("At least you enjoyed it ${slide.count} times this year.")
+              },
+              leadingContent = {
+                val thumbPainter = rememberAsyncImagePainter(
+                  slide.drink.logoUrl
+                )
+                val drinkPainter = rememberAsyncImagePainter(
+                  slide.drink.originalLogoUrl,
+                  error = thumbPainter
+                )
+
+                Image(
+                  drinkPainter,
+                  contentDescription = null,
+                  contentScale = ContentScale.Fit,
+                  modifier = Modifier.size(72.dp)
+                )
+              }
+            )
+
+          is WrappedSlide.Caffeine ->
+            ListItem(
+              headlineContent = {
+                Text("You consumed ${slide.total} mg of caffeine this year.")
+              },
+              supportingContent = {
+                slide.wouldKill?.let { animal ->
+                  Text("This could kill a medium-weight ${animal.name}. Glad you're still here.")
+                }
+              },
+              leadingContent = {
+                val painter = painterResource(
+                  when (slide.wouldKill) {
+                    WrappedSlide.Caffeine.Animal.Squirrel -> R.drawable.wrapped_squirrel
+                    WrappedSlide.Caffeine.Animal.Rat -> R.drawable.wrapped_rat
+                    WrappedSlide.Caffeine.Animal.Cat -> R.drawable.wrapped_cat
+                    WrappedSlide.Caffeine.Animal.Koala -> R.drawable.wrapped_koala
+                    WrappedSlide.Caffeine.Animal.Lynx -> R.drawable.wrapped_lynx
+                    WrappedSlide.Caffeine.Animal.Jaguar -> R.drawable.wrapped_jaguar
+                    WrappedSlide.Caffeine.Animal.Reindeer -> R.drawable.wrapped_reindeer
+                    WrappedSlide.Caffeine.Animal.Gorilla -> R.drawable.wrapped_gorilla
+                    WrappedSlide.Caffeine.Animal.Lion -> R.drawable.wrapped_lion
+                    WrappedSlide.Caffeine.Animal.Bear -> R.drawable.wrapped_bear
+                    WrappedSlide.Caffeine.Animal.Moose -> R.drawable.wrapped_moose
+                    else -> R.drawable.wrapped_coffee_beans
+                  }
+                )
+
+                Image(
+                  painter,
+                  contentDescription = null,
+                  contentScale = ContentScale.Fit,
+                  modifier = Modifier.size(72.dp)
+                )
+              }
+            )
+
+          is WrappedSlide.MostActive ->
+            ListItem(
+              headlineContent = {
+                Text(
+                  "You were most active on ${
+                    slide.weekday.getDisplayName(
+                      TextStyle.FULL,
+                      LocalConfiguration.current.locale
+                    )
+                  }s at ${slide.hour} o'clock."
+                )
+              },
+              leadingContent = {
+                val painter = painterResource(R.drawable.wrapped_clock)
+
+                Image(
+                  painter,
+                  contentDescription = null,
+                  contentScale = ContentScale.Fit,
+                  modifier = Modifier.size(72.dp)
+                )
+              }
+            )
+        }
+      }
+    }
+  }
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedSlide.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedSlide.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4899c2ecda023e56684a4cdaa1d58fe2f90f8953
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedSlide.kt
@@ -0,0 +1,123 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2023 Chaosdorf e.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package de.chaosdorf.meteroid.ui.wrapped
+
+import de.chaosdorf.mete.model.DrinkId
+import de.chaosdorf.meteroid.model.Drink
+import de.chaosdorf.meteroid.model.Transaction
+import kotlinx.datetime.DayOfWeek
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+
+sealed class WrappedSlide {
+  interface Factory {
+    fun create(
+        transactions: List<Transaction>,
+        drinks: Map<DrinkId, Drink>
+    ): WrappedSlide?
+  }
+
+  data class MostBoughtDrink(
+      val drink: Drink,
+      val count: Int,
+  ) : WrappedSlide() {
+    companion object : Factory {
+      override fun create(
+          transactions: List<Transaction>,
+          drinks: Map<DrinkId, Drink>
+      ): WrappedSlide? = transactions
+        .mapNotNull { drinks[it.drinkId] }
+        .groupingBy { it }
+        .eachCount()
+        .maxByOrNull { it.value }
+        ?.let { (mostBoughtDrink, count) ->
+          MostBoughtDrink(mostBoughtDrink, count)
+        }
+    }
+  }
+
+  data class Caffeine(
+    val total: Double,
+    val wouldKill: Animal?,
+  ) : WrappedSlide() {
+    enum class Animal(val lethalDosage: Double) {
+      Hamster(0.25),
+      Squirrel(0.3),
+      Rat(0.4),
+      GuineaPig(0.9),
+      Lemur(2.5),
+      Cat(5.0),
+      Koala(9.0),
+      Coyote(13.0),
+      Lynx(23.0),
+      Capybara(55.0),
+      Jaguar(81.0),
+      Reindeer(101.0),
+      Gorilla(140.0),
+      Lion(175.0),
+      Bear(278.0),
+      Moose(368.0),
+      Bison(540.0)
+    }
+
+    companion object : Factory {
+      override fun create(
+          transactions: List<Transaction>,
+          drinks: Map<DrinkId, Drink>
+      ): WrappedSlide = transactions
+        .mapNotNull { drinks[it.drinkId] }
+        .mapNotNull { drink -> drink.caffeine?.let { it * drink.volume.toDouble() * 10 } }
+        .sum()
+        .let { dosage ->
+          Caffeine(
+            dosage,
+            Animal.values()
+              .sortedBy(Animal::lethalDosage)
+              .firstOrNull { it.lethalDosage < dosage }
+          )
+        }
+    }
+  }
+
+  data class MostActive(
+      val weekday: DayOfWeek,
+      val hour: Int,
+  ) : WrappedSlide() {
+    companion object : Factory {
+      override fun create(
+          transactions: List<Transaction>,
+          drinks: Map<DrinkId, Drink>
+      ): WrappedSlide = transactions
+        .map { it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault()) }
+        .groupingBy { Pair(it.dayOfWeek, it.hour) }
+        .eachCount()
+        .maxBy { it.value }
+        .key
+        .let { (dayOfWeek, hour) ->
+          MostActive(dayOfWeek, hour)
+        }
+    }
+  }
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..722226a4dfc8c7c0b7f2bfde6c43e20b096cee1c
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/wrapped/WrappedViewModel.kt
@@ -0,0 +1,117 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2023 Chaosdorf e.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package de.chaosdorf.meteroid.ui.wrapped
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.lifecycle.HiltViewModel
+import de.chaosdorf.mete.model.DrinkId
+import de.chaosdorf.meteroid.model.AccountInfo
+import de.chaosdorf.meteroid.model.Drink
+import de.chaosdorf.meteroid.model.DrinkRepository
+import de.chaosdorf.meteroid.model.Server
+import de.chaosdorf.meteroid.model.TransactionRepository
+import de.chaosdorf.meteroid.sync.AccountProvider
+import de.chaosdorf.meteroid.sync.SyncManager
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import kotlinx.datetime.Clock
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.Month
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toInstant
+import kotlinx.datetime.toLocalDateTime
+import javax.inject.Inject
+
+@HiltViewModel
+class WrappedViewModel @Inject constructor(
+  private val accountProvider: AccountProvider,
+  repository: TransactionRepository,
+  drinkRepository: DrinkRepository,
+  private val syncManager: SyncManager
+) : ViewModel() {
+  val account: StateFlow<AccountInfo?> = accountProvider.account
+    .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
+  val slides: StateFlow<List<WrappedSlide>> = accountProvider.account
+    .flatMapLatest { account ->
+      account?.let { (server, maybeUser) ->
+        maybeUser?.let { user ->
+          combine(
+            repository.getAllFlow(server.serverId, user.userId),
+            drinkRepository.getAllFlow(server.serverId)
+          ) { transactions, drinks ->
+            val drinkMap: Map<DrinkId, Drink> = drinks.associateBy(Drink::drinkId)
+            val factories = listOf(
+              WrappedSlide.MostBoughtDrink,
+              WrappedSlide.Caffeine,
+              WrappedSlide.MostActive
+            )
+            val timeZone = TimeZone.currentSystemDefault()
+            val now = Clock.System.now().toLocalDateTime(timeZone)
+            val yearBegin = LocalDateTime(
+              year = now.year,
+              month = Month.JANUARY,
+              dayOfMonth =  1,
+              hour = 0,
+              minute = 0,
+              second = 0
+            ).toInstant(timeZone)
+            val yearEnd = LocalDateTime(
+              year = now.year + 1,
+              month = Month.JANUARY,
+              dayOfMonth =  1,
+              hour = 0,
+              minute = 0,
+              second = 0
+            ).toInstant(timeZone)
+            val thisYear = transactions.filter {
+              it.timestamp in yearBegin..yearEnd
+            }
+            factories.mapNotNull { it.create(thisYear, drinkMap) }
+          }
+        }
+      } ?: flowOf(emptyList())
+    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
+
+  fun togglePin() {
+    account.value?.let { account ->
+      account.user?.let { user ->
+        viewModelScope.launch {
+          accountProvider.togglePin(account.server.serverId, user.userId)
+        }
+      }
+    }
+  }
+
+  suspend fun checkOffline(server: Server?): Boolean =
+    if (server == null) true
+    else syncManager.checkOffline(server)
+}
diff --git a/app/src/main/res/drawable-nodpi/wrapped_bear.png b/app/src/main/res/drawable-nodpi/wrapped_bear.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd2eaa74f3bbcfac66295c78dd24cb14e2cb369f
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_bear.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_cat.png b/app/src/main/res/drawable-nodpi/wrapped_cat.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd61bfabbb9adf46ca3e9e101108af9b4c511016
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_cat.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_clock.png b/app/src/main/res/drawable-nodpi/wrapped_clock.png
new file mode 100644
index 0000000000000000000000000000000000000000..665761506811fc156a35c72acdf21e6ab301cdb7
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_clock.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_coffee_beans.png b/app/src/main/res/drawable-nodpi/wrapped_coffee_beans.png
new file mode 100644
index 0000000000000000000000000000000000000000..6851bc699bb711b9d8ece400561b4bf19e48d10b
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_coffee_beans.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_gorilla.png b/app/src/main/res/drawable-nodpi/wrapped_gorilla.png
new file mode 100644
index 0000000000000000000000000000000000000000..36bd7eacdca5ab950962662d77025a929bcf6e13
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_gorilla.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_jaguar.png b/app/src/main/res/drawable-nodpi/wrapped_jaguar.png
new file mode 100644
index 0000000000000000000000000000000000000000..13478112412447063fd3bccdaf17fcd04e03a5c5
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_jaguar.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_koala.png b/app/src/main/res/drawable-nodpi/wrapped_koala.png
new file mode 100644
index 0000000000000000000000000000000000000000..caf71732522b5aa321780ace30e7a3bdd625e7be
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_koala.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_lion.png b/app/src/main/res/drawable-nodpi/wrapped_lion.png
new file mode 100644
index 0000000000000000000000000000000000000000..b92bd4816e520119e75cec2c4bea807355fef877
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_lion.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_lynx.png b/app/src/main/res/drawable-nodpi/wrapped_lynx.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6e93ff24b72d058252f814f454b7fb8ca46077a
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_lynx.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_moose.png b/app/src/main/res/drawable-nodpi/wrapped_moose.png
new file mode 100644
index 0000000000000000000000000000000000000000..e25310389cb1804e368d8a0c7e4b20c3f1f5cf24
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_moose.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_rat.png b/app/src/main/res/drawable-nodpi/wrapped_rat.png
new file mode 100644
index 0000000000000000000000000000000000000000..7aaf3239adc21c7f346f16522dea64fd974970de
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_rat.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_reindeer.png b/app/src/main/res/drawable-nodpi/wrapped_reindeer.png
new file mode 100644
index 0000000000000000000000000000000000000000..52e6d5976e43714c99794d94b58c6344eb4664d6
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_reindeer.png differ
diff --git a/app/src/main/res/drawable-nodpi/wrapped_squirrel.png b/app/src/main/res/drawable-nodpi/wrapped_squirrel.png
new file mode 100644
index 0000000000000000000000000000000000000000..14a1b1d96a5aef442cd785498fef3701475532ea
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/wrapped_squirrel.png differ
diff --git a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
index 315971c57694c8ba40ca571ae15663f067952a65..92efcbbdb205fafdea4788b4f830b585852e13a6 100644
--- a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
+++ b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
@@ -2,11 +2,11 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "f794acceadd9ed28da1b218972b5e530",
+    "identityHash": "e26316f758271c58bc953e756fc16e7d",
     "entities": [
       {
         "tableName": "Drink",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT NOT NULL, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
         "fields": [
           {
             "fieldPath": "serverId",
@@ -54,7 +54,7 @@
             "fieldPath": "logoUrl",
             "columnName": "logoUrl",
             "affinity": "TEXT",
-            "notNull": true
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -119,7 +119,7 @@
       },
       {
         "tableName": "User",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
         "fields": [
           {
             "fieldPath": "serverId",
@@ -149,7 +149,7 @@
             "fieldPath": "email",
             "columnName": "email",
             "affinity": "TEXT",
-            "notNull": true
+            "notNull": false
           },
           {
             "fieldPath": "balance",
@@ -358,7 +358,7 @@
     "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f794acceadd9ed28da1b218972b5e530')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e26316f758271c58bc953e756fc16e7d')"
     ]
   }
 }
\ No newline at end of file
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
index fe82de5c3c428098d6ae2c2bc708ac28eeee1e25..18d5a79f78d29eb6b0b19fb5bec93f657aeb6244 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
@@ -50,8 +50,11 @@ data class Drink(
   val volume: BigDecimal,
   val caffeine: Int?,
   val price: BigDecimal,
-  val logoUrl: String,
+  val logoUrl: String?,
 ) {
+  val originalLogoUrl
+    get() = logoUrl?.replace("/thumb/", "/original/")
+
   companion object {
     fun fromModel(server: Server, value: DrinkModel) = Drink(
       server.serverId,
@@ -61,7 +64,9 @@ data class Drink(
       value.volume,
       value.caffeine,
       value.price,
-      URI.create(server.url).resolve(value.logoUrl).toString()
+      value.logoUrl?.let {
+        URI.create(server.url).resolve(it).toString()
+      }
     )
   }
 }
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
index 8d06a2d44f5738eb2664688b399b365fa79cbe8c..8052cde69ea1e8741709c690ae36726743b5c3fa 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
@@ -48,18 +48,20 @@ data class User(
   val userId: UserId,
   val active: Boolean,
   val name: String,
-  val email: String,
+  val email: String?,
   val balance: BigDecimal,
   val audit: Boolean,
   val redirect: Boolean,
 ) {
   @OptIn(ExperimentalStdlibApi::class)
-  val gravatarUrl: String by lazy {
-    val normalised: String = email.lowercase(Locale.ROOT)
-    val binaryData: ByteArray = normalised.toByteArray(Charsets.UTF_8)
-    val binaryHash: ByteArray = MessageDigest.getInstance("MD5").digest(binaryData)
-    val hash: String = binaryHash.toHexString()
-    "https://www.gravatar.com/avatar/$hash?d=404&s=640"
+  val gravatarUrl: String? by lazy {
+    email?.let {
+      val normalised: String = it.lowercase(Locale.ROOT)
+      val binaryData: ByteArray = normalised.toByteArray(Charsets.UTF_8)
+      val binaryHash: ByteArray = MessageDigest.getInstance("MD5").digest(binaryData)
+      val hash: String = binaryHash.toHexString()
+      "https://www.gravatar.com/avatar/$hash?d=404&s=640"
+    }
   }
 
   companion object {