diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..d9f5985b38a1a7bed21654eb1178b3412c73106f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,30 @@
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+[{*.mod, *.dtd, *.ent, *.elt}]
+indent_style = space
+indent_size = 2
+
+[{*.jhm, *.rng, *.wsdl, *.fxml, *.xslt, *.jrxml, *.ant, *.xul, *.xsl, *.xsd, *.tld, *.jnlp, *.xml}]
+indent_style = space
+indent_size = 2
+
+[*.json]
+indent_style = space
+indent_size = 2
+
+[*.java]
+indent_style = space
+indent_size = 2
+
+[{*.kts, *.kt}]
+indent_style = space
+indent_size = 2
+
+[{*.yml, *.yaml}]
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..49ca4c228ed79f9d56056083a5bfcf559e1cd597
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/signing.properties
+/.idea/*
+!/.idea/copyright/
+.DS_Store
+/captures
+build/
+/reports/
+/persistence/schemas/
diff --git a/.idea/copyright/Meteroid.xml b/.idea/copyright/Meteroid.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c001aa9bcba024220020420b214f24d4739c0806
--- /dev/null
+++ b/.idea/copyright/Meteroid.xml
@@ -0,0 +1,6 @@
+<component name="CopyrightManager">
+  <copyright>
+    <option name="notice" value="The MIT License (MIT)&#10;&#10;Copyright (c) 2013-&amp;#36;today.year Chaosdorf e.V.&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." />
+    <option name="myName" value="Meteroid" />
+  </copyright>
+</component>
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8d2824032d1dd63380b995551a3ebbc3358406a5
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="Meteroid" />
+</component>
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d57404abbccc91b1cefa46bb6e469e4b17c12228
--- /dev/null
+++ b/README.md
@@ -0,0 +1,62 @@
+[![Build Status](https://travis-ci.org/chaosdorf/meteroid.svg?branch=master)](https://travis-ci.org/chaosdorf/meteroid)
+
+![logo](/metadata/en-US/images/featureGraphic.png)
+
+### What
+Small Android application to use with mete, the Matekasse of Chaosdorf.
+
+### Where
+* [Chaosdorf Wiki](https://wiki.chaosdorf.de/Meteroid)
+* [Google Play](https://play.google.com/store/apps/details?id=de.chaosdorf.meteroid2)
+* [F-Droid](https://f-droid.org/repository/browse/?fdid=de.chaosdorf.meteroid)
+* [apk](https://github.com/chaosdorf/meteroid/releases/)
+
+### How does it look?
+
+![the main screen](/metadata/en-US/images/phoneScreenshots/1.png)
+
+![adding an account](/metadata/en-US/images/phoneScreenshots/2.png)
+
+![your logs](/metadata/en-US/images/phoneScreenshots/3.png)
+
+### License
+The MIT License (MIT)
+
+Copyright (c) 2013-2016 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.
+
+### Privacy
+
+The meteroid app stores a few things permanently on your device
+("permanently" meaning, until you uninstall the app or clear its data):
+* the URL of your chosen mete instance
+* your user ID (just a number that identifies you)
+* your last five used items
+
+Additionally, some data may be cached temporarily:
+* your avatar
+* the avatars of other users
+* the images of drinks
+
+The rest of the data is kept in your mete instance. Please check its terms
+and make sure you trust its operators:
+* your chosen name (this can just be a nickname)
+* your e-mail address (optional)
+* your usage history (optional)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..18766b3e1bb6a0a59472ababca79ebd2992fb872
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,84 @@
+@file:Suppress("UnstableApiUsage")
+
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Mareike Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+plugins {
+  id("justjanne.android.app")
+}
+
+android {
+  namespace = "de.chaosdorf.meteroid"
+
+  buildTypes {
+    getByName("release") {
+      isMinifyEnabled = true
+      isShrinkResources = true
+
+      proguardFiles(
+        getDefaultProguardFile("proguard-android.txt"),
+        "proguard-rules.pro"
+      )
+    }
+
+    getByName("debug") {
+      applicationIdSuffix = ".debug"
+    }
+  }
+
+  buildFeatures {
+    compose = true
+  }
+
+  composeOptions {
+    kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
+  }
+}
+
+dependencies {
+  implementation(libs.kotlin.stdlib)
+
+  implementation(libs.kotlinx.coroutines.android)
+  testImplementation(libs.kotlinx.coroutines.test)
+
+  testImplementation(libs.kotlin.test)
+  testImplementation(libs.junit.api)
+  testImplementation(libs.junit.params)
+  testRuntimeOnly(libs.junit.engine)
+
+  implementation(libs.androidx.appcompat)
+  implementation(libs.androidx.appcompat.resources)
+
+  implementation(libs.androidx.activity)
+  implementation(libs.androidx.activity.compose)
+
+  implementation(libs.androidx.compose.animation)
+  implementation(libs.androidx.compose.compiler)
+  implementation(libs.androidx.compose.foundation)
+  implementation(libs.androidx.compose.material)
+  implementation(libs.androidx.compose.material.icons)
+  implementation(libs.androidx.compose.runtime)
+  implementation(libs.androidx.compose.ui.tooling)
+
+  implementation(libs.androidx.navigation.compose)
+
+  debugImplementation(libs.androidx.compose.ui.tooling)
+  implementation(libs.androidx.compose.ui.preview)
+  testImplementation(libs.androidx.compose.ui.test)
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..690a4be68db285dea8841626be81fa215a589a84
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,54 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/lib/android-sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.kts.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
+# The project is open source anyway, obfuscation is useless.
+-dontobfuscate
+
+# remove unnecessary warnings
+# Android HTTP Libs
+-dontnote android.net.http.**
+-dontnote org.apache.http.**
+# Kotlin stuff
+-dontnote kotlin.**
+# Gson
+-dontnote com.google.gson.**
+# Dagger
+-dontwarn com.google.errorprone.annotations.*
+# Retrofit
+-dontwarn retrofit2.**
+# Annotation used by Retrofit on Java 8 VMs
+-dontwarn javax.annotation.Nullable
+-dontwarn javax.annotation.ParametersAreNonnullByDefault
+-dontwarn javax.annotation.concurrent.GuardedBy
+# Retain generic type information for use by reflection by converters and adapters.
+-keepattributes Signature
+# Retain declared checked exceptions for use by a Proxy instance.
+-keepattributes Exceptions
+# Okio
+-dontwarn okio.**
+-dontwarn org.conscrypt.**
+# OkHttp3
+-dontwarn okhttp3.**
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..efe8d657816b3b46d6ad728f9cffb60bde054343
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="de.chaosdorf.meteroid">
+
+  <uses-permission android:name="android.permission.INTERNET" />
+
+  <application
+    android:allowBackup="true"
+    android:icon="@mipmap/ic_launcher"
+    android:label="@string/application_name"
+    android:supportsRtl="true"
+    android:theme="@style/Theme.Meteroid"
+    android:usesCleartextTraffic="true">
+    <activity
+      android:name=".MainActivity"
+      android:exported="true"
+      android:label="@string/application_name"
+      android:theme="@style/Theme.Meteroid">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <action android:name="android.intent.action.VIEW" />
+
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+
+</manifest>
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/MainActivity.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/MainActivity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3a62e2bdfc769330ccb6228cb4ab802a9e4bec12
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/MainActivity.kt
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Scaffold
+import androidx.compose.ui.Modifier
+import androidx.navigation.compose.rememberNavController
+import de.chaosdorf.meteroid.ui.MeteroidBottomBar
+import de.chaosdorf.meteroid.ui.MeteroidRouter
+import de.chaosdorf.meteroid.ui.theme.MeteroidTheme
+
+
+class MainActivity : ComponentActivity() {
+  override fun onCreate(savedInstanceState: Bundle?) {
+    super.onCreate(savedInstanceState)
+    setContent {
+      val navController = rememberNavController()
+
+      MeteroidTheme {
+        Scaffold(
+          bottomBar = { MeteroidBottomBar(navController) }
+        ) { padding: PaddingValues ->
+          MeteroidRouter(
+            navController,
+            modifier = Modifier.padding(padding)
+          )
+        }
+      }
+    }
+  }
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/icons/MeteroidIcons.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/MeteroidIcons.kt
new file mode 100644
index 0000000000000000000000000000000000000000..35ad107d1bf6d809bedde55c329bcb7b409d75c1
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/MeteroidIcons.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.icons
+
+object MeteroidIcons {
+  object Outlined
+  object Filled
+  object TwoTone
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/icons/filled/WaterFull.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/filled/WaterFull.kt
new file mode 100644
index 0000000000000000000000000000000000000000..138d742bad8077c5b177675560f3978e86c83e8b
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/filled/WaterFull.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.icons.filled
+
+import androidx.compose.material.icons.materialPath
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import de.chaosdorf.meteroid.icons.MeteroidIcons
+
+public val MeteroidIcons.Filled.WaterFull: ImageVector
+  get() {
+    if (_waterFull != null) {
+      return _waterFull!!
+    }
+    _waterFull = ImageVector.Builder(
+      name = "Filled.WaterFull",
+      defaultWidth = 24f.dp,
+      defaultHeight = 24f.dp,
+      viewportWidth = 960f,
+      viewportHeight = 960f
+    ).apply {
+      materialPath {
+        moveTo(211f, 357f)
+        quadTo(262f, 325f, 322.5f, 308f)
+        quadTo(383f, 291f, 444f, 290f)
+        quadTo(474f, 290f, 503.5f, 294f)
+        quadTo(533f, 298f, 560f, 306f)
+        quadTo(611.13f, 320f, 638.23f, 325f)
+        quadTo(665.32f, 330f, 696f, 330f)
+        lineTo(752f, 330f)
+        lineTo(773f, 140f)
+        lineTo(187f, 140f)
+        lineTo(211f, 357f)
+        close()
+
+        moveTo(262f, 880f)
+        quadTo(238.75f, 880f, 221.5f, 865.07f)
+        quadTo(204.25f, 850.14f, 202f, 827f)
+        lineTo(120f, 80f)
+        lineTo(840f, 80f)
+        lineTo(758f, 827f)
+        quadTo(755.75f, 850.14f, 738.5f, 865.07f)
+        quadTo(721.25f, 880f, 698f, 880f)
+        lineTo(262f, 880f)
+        close()
+
+        moveTo(444f, 820f)
+        quadTo(470f, 820f, 494.5f, 820f)
+        quadTo(519f, 820f, 544f, 820f)
+        quadTo(598f, 820f, 629f, 820f)
+        quadTo(660f, 820f, 697f, 820f)
+        lineTo(697f, 820f)
+        lineTo(697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(262f, 820f)
+        quadTo(277.67f, 820f, 330.83f, 820f)
+        quadTo(384f, 820f, 444f, 820f)
+        close()
+      }
+    }.build()
+    return _waterFull!!
+  }
+
+private var _waterFull: ImageVector? = null
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/icons/outlined/WaterFull.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/outlined/WaterFull.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8f3d07520c90fd97f0f0d25e04fc382d5bd791cf
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/outlined/WaterFull.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.icons.outlined
+
+import androidx.compose.material.icons.materialPath
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import de.chaosdorf.meteroid.icons.MeteroidIcons
+
+public val MeteroidIcons.Outlined.WaterFull: ImageVector
+  get() {
+    if (_waterFull != null) {
+      return _waterFull!!
+    }
+    _waterFull = ImageVector.Builder(
+      name = "Outlined.WaterFull",
+      defaultWidth = 24f.dp,
+      defaultHeight = 24f.dp,
+      viewportWidth = 960f,
+      viewportHeight = 960f
+    ).apply {
+      materialPath {
+        moveTo(444f, 350f)
+        quadTo(384f, 350f, 325f, 369.5f)
+        quadTo(266f, 389f, 218f, 424f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        lineTo(745f, 390f)
+        lineTo(697f, 390f)
+        quadTo(659.75f, 390f, 628.88f, 384.5f)
+        quadTo(598f, 379f, 544f, 364f)
+        quadTo(519f, 357f, 494.5f, 353.5f)
+        quadTo(470f, 350f, 444f, 350f)
+        close()
+
+        moveTo(211f, 357f)
+        quadTo(262f, 325f, 322.5f, 308f)
+        quadTo(383f, 291f, 444f, 290f)
+        quadTo(474f, 290f, 503.5f, 294f)
+        quadTo(533f, 298f, 560f, 306f)
+        quadTo(611.13f, 320f, 638.23f, 325f)
+        quadTo(665.32f, 330f, 696f, 330f)
+        lineTo(752f, 330f)
+        lineTo(773f, 140f)
+        lineTo(187f, 140f)
+        lineTo(211f, 357f)
+        close()
+
+        moveTo(262f, 880f)
+        quadTo(238.75f, 880f, 221.5f, 865.07f)
+        quadTo(204.25f, 850.14f, 202f, 827f)
+        lineTo(120f, 80f)
+        lineTo(840f, 80f)
+        lineTo(758f, 827f)
+        quadTo(755.75f, 850.14f, 738.5f, 865.07f)
+        quadTo(721.25f, 880f, 698f, 880f)
+        lineTo(262f, 880f)
+        close()
+
+        moveTo(444f, 820f)
+        quadTo(470f, 820f, 494.5f, 820f)
+        quadTo(519f, 820f, 544f, 820f)
+        quadTo(598f, 820f, 629f, 820f)
+        quadTo(660f, 820f, 697f, 820f)
+        lineTo(697f, 820f)
+        lineTo(697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(262f, 820f)
+        quadTo(277.67f, 820f, 330.83f, 820f)
+        quadTo(384f, 820f, 444f, 820f)
+        close()
+      }
+    }.build()
+    return _waterFull!!
+  }
+
+private var _waterFull: ImageVector? = null
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/icons/twotone/WaterFull.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/twotone/WaterFull.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d3eef3891ede3bf5de46246711ed4167c0594efb
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/icons/twotone/WaterFull.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.icons.twotone
+
+import androidx.compose.material.icons.materialPath
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.dp
+import de.chaosdorf.meteroid.icons.MeteroidIcons
+
+public val MeteroidIcons.TwoTone.WaterFull: ImageVector
+  get() {
+    if (_waterFull != null) {
+      return _waterFull!!
+    }
+    _waterFull = ImageVector.Builder(
+      name = "TwoTone.WaterFull",
+      defaultWidth = 24f.dp,
+      defaultHeight = 24f.dp,
+      viewportWidth = 960f,
+      viewportHeight = 960f
+    ).apply {
+      materialPath {
+        moveTo(444f, 350f)
+        quadTo(384f, 350f, 325f, 369.5f)
+        quadTo(266f, 389f, 218f, 424f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        lineTo(745f, 390f)
+        lineTo(697f, 390f)
+        quadTo(659.75f, 390f, 628.88f, 384.5f)
+        quadTo(598f, 379f, 544f, 364f)
+        quadTo(519f, 357f, 494.5f, 353.5f)
+        quadTo(470f, 350f, 444f, 350f)
+        close()
+
+        moveTo(211f, 357f)
+        quadTo(262f, 325f, 322.5f, 308f)
+        quadTo(383f, 291f, 444f, 290f)
+        quadTo(474f, 290f, 503.5f, 294f)
+        quadTo(533f, 298f, 560f, 306f)
+        quadTo(611.13f, 320f, 638.23f, 325f)
+        quadTo(665.32f, 330f, 696f, 330f)
+        lineTo(752f, 330f)
+        lineTo(773f, 140f)
+        lineTo(187f, 140f)
+        lineTo(211f, 357f)
+        close()
+
+        moveTo(262f, 880f)
+        quadTo(238.75f, 880f, 221.5f, 865.07f)
+        quadTo(204.25f, 850.14f, 202f, 827f)
+        lineTo(120f, 80f)
+        lineTo(840f, 80f)
+        lineTo(758f, 827f)
+        quadTo(755.75f, 850.14f, 738.5f, 865.07f)
+        quadTo(721.25f, 880f, 698f, 880f)
+        lineTo(262f, 880f)
+        close()
+
+        moveTo(444f, 820f)
+        quadTo(470f, 820f, 494.5f, 820f)
+        quadTo(519f, 820f, 544f, 820f)
+        quadTo(598f, 820f, 629f, 820f)
+        quadTo(660f, 820f, 697f, 820f)
+        lineTo(697f, 820f)
+        lineTo(697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        quadTo(697f, 820f, 697f, 820f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(262f, 820f)
+        quadTo(277.67f, 820f, 330.83f, 820f)
+        quadTo(384f, 820f, 444f, 820f)
+        close()
+      }
+
+      materialPath(fillAlpha = 0.3f, strokeAlpha = 0.3f) {
+        moveTo(444f, 350f)
+        quadTo(384f, 350f, 325f, 369.5f)
+        quadTo(266f, 389f, 218f, 424f)
+        lineTo(262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        quadTo(262f, 820f, 262f, 820f)
+        lineTo(698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        quadTo(698f, 820f, 698f, 820f)
+        lineTo(745f, 390f)
+        lineTo(697f, 390f)
+        quadTo(659.75f, 390f, 628.88f, 384.5f)
+        quadTo(598f, 379f, 544f, 364f)
+        quadTo(519f, 357f, 494.5f, 353.5f)
+        quadTo(470f, 350f, 444f, 350f)
+        close()
+      }
+    }.build()
+    return _waterFull!!
+  }
+
+private var _waterFull: ImageVector? = null
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidBottomBar.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidBottomBar.kt
new file mode 100644
index 0000000000000000000000000000000000000000..146dd7f75bc512ac2f6bfd83a899dec7d52a94e2
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidBottomBar.kt
@@ -0,0 +1,78 @@
+/*
+ * 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
+
+import androidx.compose.material3.Icon
+import androidx.compose.material3.NavigationBar
+import androidx.compose.material3.NavigationBarItem
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.navigation.NavController
+import androidx.navigation.NavDestination.Companion.hierarchy
+import androidx.navigation.NavGraph.Companion.findStartDestination
+import androidx.navigation.compose.currentBackStackEntryAsState
+
+@Composable
+fun MeteroidBottomBar(navController: NavController) {
+  val screens = listOf(Screen.Drinks, Screen.Users)
+  val navBackStackEntry by navController.currentBackStackEntryAsState()
+  val currentDestination = navBackStackEntry?.destination
+
+    NavigationBar {
+        for (screen in screens) {
+            val selected = currentDestination?.hierarchy?.any {
+                it.route == screen.route
+            } == true
+
+            NavigationBarItem(
+                label = { Text(screen.label) },
+                icon = {
+                    Icon(
+                        if (selected) screen.selectedIcon
+                        else screen.icon,
+                        screen.label
+                    )
+                },
+                selected = selected,
+                onClick = {
+                    navController.navigate(screen.route) {
+                        // Pop up to the start destination of the graph to
+                        // avoid building up a large stack of destinations
+                        // on the back stack as users select items
+                        popUpTo(navController.graph.findStartDestination().id) {
+                            saveState = true
+                        }
+                        // Avoid multiple copies of the same destination when
+                        // reselecting the same item
+                        launchSingleTop = true
+                        // Restore state when reselecting a previously selected item
+                        restoreState = true
+                    }
+                }
+            )
+        }
+    }
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidRouter.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidRouter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b69b7ec8608fbbecfb9685ce3508b54d3a66588c
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/MeteroidRouter.kt
@@ -0,0 +1,47 @@
+/*
+ * 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
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+
+@Composable
+fun MeteroidRouter(
+  navController: NavHostController,
+  modifier: Modifier = Modifier
+) {
+  NavHost(
+    navController,
+    modifier = modifier,
+    startDestination = Screen.Drinks.route,
+  ) {
+    composable(Screen.Users.route) { Text("Userlist") }
+    composable(Screen.Drinks.route) { Text("Drinklist") }
+  }
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/Screen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/Screen.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1563705d5d29fdc2215887481e9f7fe7dd09fd86
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/Screen.kt
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Person
+import androidx.compose.material.icons.twotone.Person
+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
+
+sealed class Screen(
+    val label: String,
+    val route: String,
+    val icon: ImageVector,
+    val selectedIcon: ImageVector = icon
+) {
+  object Drinks : Screen(
+    "Drinks",
+    "drinks",
+    MeteroidIcons.Outlined.WaterFull,
+    MeteroidIcons.TwoTone.WaterFull
+  )
+
+  object Users : Screen(
+    "Users",
+    "users",
+    Icons.Outlined.Person,
+    Icons.TwoTone.Person
+  )
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Color.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Color.kt
new file mode 100644
index 0000000000000000000000000000000000000000..33ce00f53c2e829afa1fe854b6d8f58f57f0bc08
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Color.kt
@@ -0,0 +1,11 @@
+package de.chaosdorf.meteroid.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val Purple40 = Color(0xFF6650a4)
+val PurpleGrey40 = Color(0xFF625b71)
+val Pink40 = Color(0xFF7D5260)
\ No newline at end of file
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Theme.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Theme.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dbc712cf33722d47815b41e6d6941a80fedb26c8
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Theme.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.theme
+
+import android.app.Activity
+import android.os.Build
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalView
+import androidx.core.view.WindowCompat
+
+private val DarkColorScheme = darkColorScheme(
+    primary = Purple80,
+    secondary = PurpleGrey80,
+    tertiary = Pink80
+)
+
+private val LightColorScheme = lightColorScheme(
+    primary = Purple40,
+    secondary = PurpleGrey40,
+    tertiary = Pink40
+
+    /* Other default colors to override
+    background = Color(0xFFFFFBFE),
+    surface = Color(0xFFFFFBFE),
+    onPrimary = Color.White,
+    onSecondary = Color.White,
+    onTertiary = Color.White,
+    onBackground = Color(0xFF1C1B1F),
+    onSurface = Color(0xFF1C1B1F),
+    */
+)
+
+@Composable
+fun MeteroidTheme(
+    darkTheme: Boolean = isSystemInDarkTheme(),
+    // Dynamic color is available on Android 12+
+    dynamicColor: Boolean = true,
+    content: @Composable () -> Unit
+) {
+    val colorScheme = when {
+        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
+            val context = LocalContext.current
+            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
+        }
+
+        darkTheme -> DarkColorScheme
+        else -> LightColorScheme
+    }
+    val view = LocalView.current
+    if (!view.isInEditMode) {
+        SideEffect {
+            val window = (view.context as Activity).window
+            window.statusBarColor = colorScheme.primary.toArgb()
+            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
+        }
+    }
+
+    MaterialTheme(
+        colorScheme = colorScheme,
+        typography = Typography,
+        content = content
+    )
+}
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Type.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Type.kt
new file mode 100644
index 0000000000000000000000000000000000000000..31e4b39550b391efd9b29299c351e1bec7f83cf8
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/theme/Type.kt
@@ -0,0 +1,34 @@
+package de.chaosdorf.meteroid.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.sp
+
+// Set of Material typography styles to start with
+val Typography = Typography(
+    bodyLarge = TextStyle(
+        fontFamily = FontFamily.Default,
+        fontWeight = FontWeight.Normal,
+        fontSize = 16.sp,
+        lineHeight = 24.sp,
+        letterSpacing = 0.5.sp
+    )
+    /* Other default text styles to override
+    titleLarge = TextStyle(
+        fontFamily = FontFamily.Default,
+        fontWeight = FontWeight.Normal,
+        fontSize = 22.sp,
+        lineHeight = 28.sp,
+        letterSpacing = 0.sp
+    ),
+    labelSmall = TextStyle(
+        fontFamily = FontFamily.Default,
+        fontWeight = FontWeight.Medium,
+        fontSize = 11.sp,
+        lineHeight = 16.sp,
+        letterSpacing = 0.5.sp
+    )
+    */
+)
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b6c4512da56438e2b5145882b4e74cf572649f3
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be7b46ab25ee168fcf368cf7c7daf2ada7607b9b
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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.
+  -->
+
+<resources>
+    <string name="application_name">Meteroid</string>
+</resources>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a30012cd0ce22a2aa64c1094647dfa0b45aa9868
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+  <style name="Theme.Meteroid" parent="Theme.Material.DayNight.NoActionBar">
+    <item name="android:colorPrimary">#ff9800</item>
+    <item name="android:colorAccent">#3a3f44</item>
+    <item name="android:statusBarColor">@android:color/transparent</item>
+    <item name="android:navigationBarColor">@android:color/transparent</item>
+    <item name="android:dialogTheme">@style/Theme.DialogFullScreen</item>
+  </style>
+
+  <style name="Theme.Material.DayNight.NoActionBar" parent="@android:style/Theme.Material.Light.NoActionBar" />
+
+  <style name="Theme.DialogFullScreen" parent="Theme.Material.DayNight.NoActionBar">
+    <item name="android:windowMinWidthMajor">100%</item>
+    <item name="android:windowMinWidthMinor">100%</item>
+  </style>
+</resources>
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..6c489d0d6e8930fae68bee7deed61dfb24ff31a8
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,14 @@
+group = "de.chaosdorf"
+
+buildscript {
+  repositories {
+    google()
+    mavenCentral()
+  }
+}
+
+plugins {
+  alias(libs.plugins.android.application) apply false
+  alias(libs.plugins.kotlin.jvm) apply false
+  alias(libs.plugins.kotlin.serialization) apply false
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..de22634d32d2c6b737ec4a7481c65d653f5e0053
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,33 @@
+# Quasseldroid - Quassel client for Android
+#
+# Copyright (c) 2019 Janne Mareike Koschinski
+# Copyright (c) 2019 The Quassel Project
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3 as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+#org.gradle.parallel=true
+# Enable gradle build cache
+#org.gradle.caching=true
+# Enable AndroidX
+android.useAndroidX=true
diff --git a/gradle/convention/build.gradle.kts b/gradle/convention/build.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..5039b124e68adbd03fc09bf01043bef7cbe3e458
--- /dev/null
+++ b/gradle/convention/build.gradle.kts
@@ -0,0 +1,41 @@
+plugins {
+  `kotlin-dsl`
+}
+
+repositories {
+  gradlePluginPortal()
+  mavenCentral()
+  google()
+}
+
+dependencies {
+  compileOnly(libs.android.gradlePlugin)
+  compileOnly(libs.kotlin.gradlePlugin)
+}
+
+gradlePlugin {
+  plugins {
+    register("androidApplication") {
+      id = "justjanne.android.app"
+      implementationClass = "AndroidApplicationConvention"
+    }
+    register("androidLibrary") {
+      id = "justjanne.android.library"
+      implementationClass = "AndroidLibraryConvention"
+    }
+    register("kotlinAndroid") {
+      id = "justjanne.kotlin.android"
+      implementationClass = "KotlinAndroidConvention"
+    }
+    register("kotlin") {
+      id = "justjanne.kotlin"
+      implementationClass = "KotlinConvention"
+    }
+  }
+}
+
+configure<JavaPluginExtension> {
+  toolchain {
+    languageVersion.set(JavaLanguageVersion.of(17))
+  }
+}
diff --git a/gradle/convention/gradle.properties b/gradle/convention/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c6cd2a7e2f146d9ed89db0cb1f4de21ac673e9fd
--- /dev/null
+++ b/gradle/convention/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.parallel=true
+org.gradle.caching=true
+org.gradle.configureondemand=true
diff --git a/gradle/convention/gradle/wrapper/gradle-wrapper.jar b/gradle/convention/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7454180f2ae8848c63b8b4dea2cb829da983f2fa
Binary files /dev/null and b/gradle/convention/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/convention/gradle/wrapper/gradle-wrapper.properties b/gradle/convention/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5c589deb54eaeb18ec08ccb25adc5d971dc2303f
--- /dev/null
+++ b/gradle/convention/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
+distributionSha256Szm=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradle/convention/settings.gradle.kts b/gradle/convention/settings.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..5bdbcb21ed98f2b66d965a5f9164aa2181ef0b71
--- /dev/null
+++ b/gradle/convention/settings.gradle.kts
@@ -0,0 +1,15 @@
+@file:Suppress("UnstableApiUsage")
+
+rootProject.name = "convention"
+
+dependencyResolutionManagement {
+  repositories {
+    google()
+    mavenCentral()
+  }
+  versionCatalogs {
+    create("libs") {
+      from(files("../libs.versions.toml"))
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt b/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..683e704d3b3a3e93193cb727732272a40aaf0756
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/AndroidApplicationConvention.kt
@@ -0,0 +1,64 @@
+import com.android.build.api.dsl.ApplicationExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import util.cmd
+import util.properties
+import java.util.*
+
+class AndroidApplicationConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("com.android.application")
+        apply("justjanne.kotlin.android")
+      }
+
+      extensions.configure<ApplicationExtension> {
+        compileSdk = 33
+
+        defaultConfig {
+          minSdk = 21
+          targetSdk = 33
+
+          applicationId = "${rootProject.group}.${rootProject.name.lowercase(Locale.ROOT)}"
+          versionCode = cmd("git", "rev-list", "--count", "HEAD")?.toIntOrNull() ?: 1
+          versionName = cmd("git", "describe", "--always", "--tags", "HEAD") ?: "1.0.0"
+
+          signingConfig = signingConfigs.findByName("default")
+
+          setProperty("archivesBaseName", "${rootProject.name}-$versionName")
+
+          // Disable test runner analytics
+          testInstrumentationRunnerArguments["disableAnalytics"] = "true"
+        }
+
+        signingConfigs {
+          SigningData.of(project.rootProject.properties("signing.properties"))?.let {
+            create("default") {
+              storeFile = file(it.storeFile)
+              storePassword = it.storePassword
+              keyAlias = it.keyAlias
+              keyPassword = it.keyPassword
+            }
+          }
+        }
+
+        compileOptions {
+          sourceCompatibility = JavaVersion.VERSION_17
+          targetCompatibility = JavaVersion.VERSION_17
+        }
+
+        testOptions {
+          unitTests.isIncludeAndroidResources = true
+        }
+
+        lint {
+          warningsAsErrors = true
+          lintConfig = file("../lint.xml")
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt b/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..feafcc4950807c8f5d8fe30d5239fbae86020caa
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/AndroidLibraryConvention.kt
@@ -0,0 +1,34 @@
+import com.android.build.api.dsl.LibraryExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import java.util.*
+
+class AndroidLibraryConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("com.android.library")
+        apply("justjanne.kotlin.android")
+      }
+
+      extensions.configure<LibraryExtension> {
+        compileSdk = 33
+
+        defaultConfig {
+          minSdk = 21
+
+          consumerProguardFiles("proguard-rules.pro")
+
+          // Disable test runner analytics
+          testInstrumentationRunnerArguments["disableAnalytics"] = "true"
+        }
+
+        lint {
+          warningsAsErrors = true
+          lintConfig = file("../lint.xml")
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt b/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dbbe81b8fa8dbe87369a75269b16f5c87be27a60
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/KotlinAndroidConvention.kt
@@ -0,0 +1,46 @@
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.withType
+import util.kotlinOptions
+
+@Suppress("UnstableApiUsage")
+class KotlinAndroidConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("org.jetbrains.kotlin.android")
+      }
+
+      extensions.configure<BaseExtension> {
+        kotlinOptions {
+          freeCompilerArgs = freeCompilerArgs + listOf(
+            "-opt-in=kotlin.RequiresOptIn",
+            // Enable experimental coroutines APIs, including Flow
+            "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
+            "-opt-in=kotlinx.coroutines.FlowPreview",
+            "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
+            "-opt-in=kotlin.ExperimentalUnsignedTypes",
+          )
+
+          jvmTarget = JavaVersion.VERSION_17.toString()
+        }
+      }
+
+      tasks.withType<Test> {
+        useJUnitPlatform()
+      }
+
+      configure<JavaPluginExtension> {
+        toolchain {
+          languageVersion.set(JavaLanguageVersion.of(17))
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/KotlinConvention.kt b/gradle/convention/src/main/kotlin/KotlinConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9b364add5f645e899a1c890959a00d2475fbbdfa
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/KotlinConvention.kt
@@ -0,0 +1,44 @@
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.kotlin
+import org.gradle.kotlin.dsl.withType
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+
+class KotlinConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("org.jetbrains.kotlin.jvm")
+      }
+
+      extensions.configure<KotlinJvmOptions> {
+        freeCompilerArgs = freeCompilerArgs + listOf(
+          "-opt-in=kotlin.RequiresOptIn",
+          // Enable experimental coroutines APIs, including Flow
+          "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
+          "-opt-in=kotlinx.coroutines.FlowPreview",
+          "-opt-in=kotlin.Experimental",
+          "-opt-in=kotlin.ExperimentalUnsignedTypes",
+        )
+
+        jvmTarget = JavaVersion.VERSION_17.toString()
+      }
+
+      tasks.withType<Test> {
+        useJUnitPlatform()
+      }
+
+      configure<JavaPluginExtension> {
+        toolchain {
+          languageVersion.set(JavaLanguageVersion.of(17))
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/SigningData.kt b/gradle/convention/src/main/kotlin/SigningData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..606738eecbb111455e19e9b5d03d2eb1bcba617e
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/SigningData.kt
@@ -0,0 +1,21 @@
+import java.util.*
+
+data class SigningData(
+  val storeFile: String,
+  val storePassword: String,
+  val keyAlias: String,
+  val keyPassword: String
+) {
+  companion object {
+    fun of(properties: Properties?): SigningData? {
+      if (properties == null) return null
+
+      val storeFile = properties.getProperty("storeFile") ?: return null
+      val storePassword = properties.getProperty("storePassword") ?: return null
+      val keyAlias = properties.getProperty("keyAlias") ?: return null
+      val keyPassword = properties.getProperty("keyPassword") ?: return null
+
+      return SigningData(storeFile, storePassword, keyAlias, keyPassword)
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt b/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..667f8dac0c5f3e58641f887081bd7af00ca9b388
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/util/BaseExtensionExtensions.kt
@@ -0,0 +1,8 @@
+package util
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.plugins.ExtensionAware
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+
+fun BaseExtension.kotlinOptions(configure: KotlinJvmOptions.() -> Unit): Unit =
+  (this as ExtensionAware).extensions.configure("kotlinOptions", configure)
diff --git a/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9ab40febbebc72d5631e5771626939ccef16e4a9
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
@@ -0,0 +1,26 @@
+package util
+
+import org.gradle.api.Project
+import java.io.ByteArrayOutputStream
+import java.util.Properties
+
+fun Project.cmd(vararg command: String) = try {
+  val stdOut = ByteArrayOutputStream()
+  exec {
+    commandLine(*command)
+    standardOutput = stdOut
+  }
+  stdOut.toString(Charsets.UTF_8.name()).trim()
+} catch (e: Throwable) {
+  e.printStackTrace()
+  null
+}
+
+fun Project.properties(fileName: String): Properties? {
+  val file = file(fileName)
+  if (!file.exists())
+    return null
+  val props = Properties()
+  props.load(file.inputStream())
+  return props
+}
diff --git a/gradle/init.gradle.kts b/gradle/init.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..7f161bac4f5349cc190dad7a4fa818f30d51da63
--- /dev/null
+++ b/gradle/init.gradle.kts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+val ktlintVersion = "0.48.1"
+
+initscript {
+  val spotlessVersion = "6.13.0"
+
+  repositories {
+    mavenCentral()
+  }
+
+  dependencies {
+    classpath("com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion")
+  }
+}
+
+rootProject {
+  subprojects {
+    apply<com.diffplug.gradle.spotless.SpotlessPlugin>()
+    extensions.configure<com.diffplug.gradle.spotless.SpotlessExtension> {
+      kotlin {
+        target("**/*.kt")
+        targetExclude("**/build/**/*.kt")
+        ktlint(ktlintVersion).userData(mapOf("android" to "true"))
+        licenseHeaderFile(rootProject.file("gradle/spotless/copyright.kt"))
+      }
+      format("kts") {
+        target("**/*.kts")
+        targetExclude("**/build/**/*.kts")
+        // Look for the first line that doesn't have a block comment (assumed to be the license)
+        licenseHeaderFile(rootProject.file("gradle/spotless/copyright.kts"), "(^(?![\\/ ]\\*).*$)")
+      }
+      format("xml") {
+        target("**/*.xml")
+        targetExclude("**/build/**/*.xml")
+        // Look for the first XML tag that isn't a comment (<!--) or the xml declaration (<?xml)
+        licenseHeaderFile(rootProject.file("gradle/spotless/copyright.xml"), "(<[^!?])")
+      }
+    }
+  }
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000000000000000000000000000000000000..77c021b6017d8087d59a5c892a7b8d7710fb053e
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,64 @@
+[versions]
+androidGradlePlugin = "8.0.1"
+androidx-activity = "1.7.1"
+androidx-appcompat = "1.6.1"
+androidx-compose-bom = "2023.05.01"
+androidx-compose-compiler = "1.4.7"
+androidx-compose-material = "1.5.0-alpha04"
+androidx-compose-material3 = "1.2.0-alpha01"
+androidx-compose-runtimetracing = "1.0.0-alpha03"
+androidx-compose-tooling = "1.5.0-alpha04"
+androidx-navigation = "2.6.0-rc01"
+kotlin = "1.8.21"
+kotlinxCoroutines = "1.7.1"
+kotlinxDatetime = "0.4.0"
+kotlinxSerializationJson = "1.5.1"
+junit = "5.9.3"
+
+[libraries]
+androidx-activity = { module = "androidx.activity:activity-ktx", version.ref = "androidx-activity" }
+androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
+
+androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
+androidx-appcompat-resources = { module = "androidx.appcompat:appcompat-resources", version.ref = "androidx-appcompat" }
+
+androidx-compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "androidx-compose-compiler" }
+androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidx-compose-bom" }
+androidx-compose-animation = { group = "androidx.compose.animation", name = "animation" }
+androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
+androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" }
+androidx-compose-material-icons = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "androidx-compose-material3" }
+androidx-compose-material = { group = "androidx.compose.material3", name = "material3", version.ref = "androidx-compose-material3" }
+androidx-compose-material-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class", version.ref = "androidx-compose-material3" }
+androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
+androidx-compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata" }
+androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidx-compose-runtimetracing" }
+androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test" }
+androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
+androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "androidx-compose-tooling" }
+androidx-compose-ui-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "androidx-compose-tooling" }
+androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" }
+
+androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidx-navigation" }
+
+junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" }
+junit-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit" }
+junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine" }
+
+kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
+kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit5", version.ref = "kotlin" }
+kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
+kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
+kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" }
+kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
+
+# Dependencies of the included build-logic
+android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
+kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
+android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
+android-test = { id = "com.android.test", version.ref = "androidGradlePlugin" }
+kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
diff --git a/gradle/spotless/copyright.kt b/gradle/spotless/copyright.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cc357e57ccfd48837c7436bd410605601f2200c4
--- /dev/null
+++ b/gradle/spotless/copyright.kt
@@ -0,0 +1,23 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-$YEAR 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.
+ */
diff --git a/gradle/spotless/copyright.kts b/gradle/spotless/copyright.kts
new file mode 100644
index 0000000000000000000000000000000000000000..cc357e57ccfd48837c7436bd410605601f2200c4
--- /dev/null
+++ b/gradle/spotless/copyright.kts
@@ -0,0 +1,23 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-$YEAR 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.
+ */
diff --git a/gradle/spotless/copyright.xml b/gradle/spotless/copyright.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c59cbaeeab079c0254e5cc4df972b333efa8204
--- /dev/null
+++ b/gradle/spotless/copyright.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    The MIT License (MIT)
+
+    Copyright (c) 2013-$YEAR 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.
+-->
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000000000000000000000000000000000..7454180f2ae8848c63b8b4dea2cb829da983f2fa
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5c589deb54eaeb18ec08ccb25adc5d971dc2303f
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
+distributionSha256Szm=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000000000000000000000000000000000000..4f906e0c811fc9e230eb44819f509cd0627f2600
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..107acd32c4e687021ef32db511e8a206129b88ec
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lint.xml b/lint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eab67bd5e6f29d10e42082945d8a9195c76e4777
--- /dev/null
+++ b/lint.xml
@@ -0,0 +1,53 @@
+<!--
+  Quasseldroid - Quassel client for Android
+
+  Copyright (c) 2019 Janne Mareike Koschinski
+  Copyright (c) 2019 The Quassel Project
+
+  This program is free software: you can redistribute it and/or modify it
+  under the terms of the GNU General Public License version 3 as published
+  by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along
+  with this program. If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<lint>
+  <issue id="NewerVersionAvailable" severity="error" />
+
+  <!-- Because of course paging and room have incompatible versions -->
+  <issue id="GradleCompatible" severity="ignore" />
+
+  <!-- Because these are entirely broken -->
+  <issue id="ResourceType" severity="ignore" />
+  <issue id="UnusedResources" severity="ignore" />
+  <issue id="ObsoleteLintCustomCheck" severity="ignore" />
+  <issue id="UnusedAttribute" severity="informational" />
+
+  <!-- Because this doesn’t work when using splash themes -->
+  <issue id="Overdraw" severity="ignore" />
+
+  <!-- Can’t request a translation without a release, can’t release without translation -->
+  <issue id="MissingTranslation" severity="informational" />
+  <!-- Because we don’t use app bundles and never will use them -->
+  <issue id="AppBundleLocaleChanges" severity="informational" />
+  <!-- Because this tries to apply english orthography to other locales -->
+  <issue id="Typos" severity="ignore" />
+
+  <!-- Because Autofill isn’t a priority at the moment -->
+  <issue id="Autofill" severity="informational" />
+
+  <!-- We’re not using AGP 5 yet, and once we are, we’ll use compose anyway -->
+  <issue id="NonConstantResourceId" severity="informational" />
+
+  <!-- It’s only used for testing -->
+  <issue id="TrustAllX509TrustManager" severity="informational" />
+
+  <!-- TODO for the future -->
+  <issue id="DataExtractionRules" severity="informational" />
+</lint>
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..93ea07d3ee2d36769abbeebcfdf6b213b6035445
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+@file:Suppress("UnstableApiUsage")
+
+rootProject.name = "Meteroid"
+
+pluginManagement {
+  includeBuild("gradle/convention")
+  repositories {
+    google()
+    mavenCentral()
+    gradlePluginPortal()
+  }
+}
+
+dependencyResolutionManagement {
+  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+  repositories {
+    google()
+    mavenCentral()
+  }
+}
+
+include(":app")