diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 8fe6b1f8cbd1c0e3ed3657a079a63b702130ea7e..279d637d306ec5a712dc1926ce90ef108089289c 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="deploymentTargetDropDown">
-    <runningDeviceTargetSelectedWithDropDown>
+    <targetSelectedWithDropDown>
       <Target>
-        <type value="RUNNING_DEVICE_TARGET" />
+        <type value="QUICK_BOOT_TARGET" />
         <deviceKey>
           <Key>
-            <type value="SERIAL_NUMBER" />
-            <value value="BH901SF58Z" />
+            <type value="VIRTUAL_DEVICE_PATH" />
+            <value value="$USER_HOME$/.android/avd/Pixel_4_API_30.avd" />
           </Key>
         </deviceKey>
       </Target>
-    </runningDeviceTargetSelectedWithDropDown>
-    <timeTargetWasSelectedWithDropDown value="2021-12-14T14:31:07.475808Z" />
+    </targetSelectedWithDropDown>
+    <timeTargetWasSelectedWithDropDown value="2021-12-19T13:56:45.956907Z" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 974d01916b38447562616854a09e5863c8bd6f05..8de1e05005ee4b57ed32e8fe3389ca81be8ba418 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -26,8 +26,23 @@
         <entry key="../../../../layout/compose-model-1638879424123.xml" value="0.15625" />
         <entry key="../../../../layout/compose-model-1638892987664.xml" value="0.1570945945945946" />
         <entry key="../../../../layout/compose-model-1638894001064.xml" value="0.165" />
-        <entry key="../../../../layout/compose-model-1639493007794.xml" value="0.45692567567567566" />
-        <entry key="../../../../layout/compose-model-1639493742130.xml" value="0.22596153846153846" />
+        <entry key="../../../../layout/compose-model-1639090066256.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1639500336802.xml" value="0.1570945945945946" />
+        <entry key="../../../../layout/compose-model-1639508366252.xml" value="0.25" />
+        <entry key="../../../../layout/compose-model-1639671880070.xml" value="0.1492776886035313" />
+        <entry key="../../../../layout/compose-model-1639732824378.xml" value="0.1570945945945946" />
+        <entry key="../../../../layout/compose-model-1639733405340.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1639735315421.xml" value="0.15625" />
+        <entry key="../../../../layout/compose-model-1639735659789.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1639736217744.xml" value="0.165" />
+        <entry key="../../../../layout/compose-model-1639736217747.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1639758756856.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1639950739064.xml" value="0.165" />
+        <entry key="../../../../layout/compose-model-1639950739400.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1640168674266.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1640171994534.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1640172762520.xml" value="0.1" />
+        <entry key="../../../../layout/compose-model-1640173242456.xml" value="0.1" />
         <entry key="app/src/main/res/layout/activity_create_character.xml" value="0.16510416666666666" />
         <entry key="app/src/main/res/layout/activity_main.xml" value="0.16510416666666666" />
         <entry key="app/src/main/res/layout/activity_profile.xml" value="0.165" />
diff --git a/app/build.gradle b/app/build.gradle
index c1f2f0b725892d15df2b34a1e86741dba0809ad0..e47c944b16c64702095fc1f4e36ad00b4ceffee5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,6 +3,7 @@ plugins {
     id 'kotlin-android'
     id 'kotlin-kapt'
     id "kotlinx-serialization"
+    id 'com.google.gms.google-services'
 }
 
 android {
@@ -62,12 +63,13 @@ dependencies {
     implementation 'com.google.android.material:material:1.4.0'
     implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
     implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
-    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
+    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1'
     implementation 'androidx.activity:activity-compose:1.4.0'
     implementation "androidx.compose.ui:ui:$compose_version"
     implementation "androidx.compose.material:material:$compose_version"
     implementation "androidx.compose.material3:material3:1.0.0-alpha02"
     implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
+    implementation 'com.google.firebase:firebase-analytics:17.2.2'
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
@@ -75,7 +77,7 @@ dependencies {
     androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
     debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
 
-    def room_version = '2.3.0'
+    def room_version = '2.4.0'
     implementation "androidx.room:room-runtime:$room_version"
     kapt "androidx.room:room-compiler:$room_version"
 
@@ -86,4 +88,8 @@ dependencies {
     implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
     // Coroutine
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
+
+    // Firebase
+    implementation platform('com.google.firebase:firebase-bom:29.0.3')
+    implementation 'com.google.firebase:firebase-analytics-ktx'
 }
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000000000000000000000000000000000000..ce3e93a12325bc7726c7dd6ca2fa9c52d5b4f300
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,39 @@
+{
+  "project_info": {
+    "project_number": "853904020533",
+    "project_id": "dnd-spell-book-df615",
+    "storage_bucket": "dnd-spell-book-df615.appspot.com"
+  },
+  "client": [
+    {
+      "client_info": {
+        "mobilesdk_app_id": "1:853904020533:android:d64c8a502392471e8dcd7c",
+        "android_client_info": {
+          "package_name": "com.flyinpancake.dndspells"
+        }
+      },
+      "oauth_client": [
+        {
+          "client_id": "853904020533-cf632uohsm9ui5doluo72m1umu3j6ion.apps.googleusercontent.com",
+          "client_type": 3
+        }
+      ],
+      "api_key": [
+        {
+          "current_key": "AIzaSyARZa97pugpKQF6S6wC8Umwbn1vu8Mti0M"
+        }
+      ],
+      "services": {
+        "appinvite_service": {
+          "other_platform_oauth_client": [
+            {
+              "client_id": "853904020533-cf632uohsm9ui5doluo72m1umu3j6ion.apps.googleusercontent.com",
+              "client_type": 3
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 70a3f85114735e9b35eccc132ab16665de304e6f..2ca54a6b0b059744ece2e94f56730e8d00040c39 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,11 +13,6 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/Theme.DndSpells">
-        <activity
-            android:name=".RuinableActivity"
-            android:exported="false"
-            android:label="@string/title_activity_ruinable"
-            android:theme="@style/Theme.DndSpells.NoActionBar" />
         <activity
             android:name=".SelectSpellsActivity"
             android:exported="false"
@@ -38,9 +33,6 @@
             android:exported="false"
             android:label="@string/title_activity_create_character"
             android:theme="@style/Theme.DndSpells.NoActionBar" />
-        <activity
-            android:name=".ProfileActivity"
-            android:exported="false" />
         <activity
             android:name=".MainActivity"
             android:exported="true">
diff --git a/app/src/main/java/com/flyinpancake/dndspells/CharacterDetailsActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/CharacterDetailsActivity.kt
index f56cfff858aba2555e63ccc633542926134fa9db..eb0970cb8da50d7073f95990ddaa7967b54cb341 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/CharacterDetailsActivity.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/CharacterDetailsActivity.kt
@@ -5,10 +5,7 @@ import android.content.Intent
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.material.*
@@ -16,23 +13,38 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Add
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.ViewModelProvider
 import com.flyinpancake.dndspells.CharacterDetailsActivity.Companion.KEY_NAME
 import com.flyinpancake.dndspells.model.DndCharacter
 import com.flyinpancake.dndspells.model.Spell
+import com.flyinpancake.dndspells.ui.components.DndTopBar
+import com.flyinpancake.dndspells.ui.components.SpellContent
 import com.flyinpancake.dndspells.ui.theme.DndSpellsTheme
 import com.flyinpancake.dndspells.viewmodel.CharacterViewModel
 import com.flyinpancake.dndspells.viewmodel.SpellViewModel
+import kotlinx.coroutines.launch
 import kotlinx.serialization.ExperimentalSerializationApi
-import kotlinx.serialization.encodeToString
-import kotlinx.serialization.json.Json
-import java.util.*
+import kotlin.random.Random
 
 
+fun roll(rollText: String): String {
+    var sum = 0
+    val diceCount = rollText.split("d")[0].toInt()
+    val diceSides = rollText.split("d")[1].toInt()
+
+    for (ii in 1..diceCount)
+        sum += Random.nextInt(from = 1, until = diceSides+1 )
+
+    return sum.toString()
+}
+
 class CharacterDetailsActivity : ComponentActivity() {
     companion object {
         const val KEY_NAME = "KEY_NAME"
@@ -62,6 +74,9 @@ class CharacterDetailsActivity : ComponentActivity() {
 fun CharacterDetailContent(character: DndCharacter = DndCharacter(), spells: List<Spell> = listOf()) {
     val activity = (LocalContext.current as? Activity)
 
+    val scaffoldState = rememberScaffoldState()
+    val coroutineScope = rememberCoroutineScope()
+
     Scaffold(
         topBar = { DndTopBar(character.name) },
         floatingActionButton = {
@@ -77,18 +92,33 @@ fun CharacterDetailContent(character: DndCharacter = DndCharacter(), spells: Lis
                 }
             )
         },
+        scaffoldState = scaffoldState,
     ) {
-        CharacterSpellList(spells = spells, character = character, onItemClick = { spell ->
-            val intent = Intent(activity, SpellDetailsActivity::class.java)
-            intent.putExtra(SpellDetailsActivity.KEY_SPELLNAME, Json.encodeToString(spell))
-            activity?.startActivity(intent)
-        })
+        val youRolled = stringResource(R.string.you_rolled)
+        CharacterSpellList(
+            spells = spells,
+            character = character,
+            onItemClick = { spell ->
+                val intent = Intent(activity, SpellDetailsActivity::class.java)
+                intent.putExtra(SpellDetailsActivity.KEY_SPELL_NAME, spell.name)
+                activity?.startActivity(intent)
+            },
+            onRoll = { spell ->
+                coroutineScope.launch {
+                    scaffoldState.snackbarHostState.showSnackbar(youRolled + roll(spell.roll!!.trim()))
+                }
+            }
+        )
     }
 }
 
 @OptIn(ExperimentalMaterialApi::class)
 @Composable
-fun SpellListItem(spell: Spell, onItemClick: (Spell) -> Unit = {}) {
+fun SpellListItem(
+    spell: Spell,
+    onItemClick: (Spell) -> Unit = {},
+    onRoll: (Spell) -> Unit = {},
+){
     Card(
         modifier = Modifier
             .fillMaxWidth()
@@ -99,17 +129,34 @@ fun SpellListItem(spell: Spell, onItemClick: (Spell) -> Unit = {}) {
             Modifier
                 .fillMaxSize()
                 .padding(10.dp),
+            horizontalArrangement = Arrangement.SpaceBetween
         ) {
+            spell.roll?.let {
+                IconButton(
+                    onClick = { onRoll(spell) },
+                    Modifier.padding(end = 2.dp)
+                ) {
+                    Icon(
+                        painter = painterResource(id = R.drawable.dice_5_outline),
+                        contentDescription = "Roll",
+                    )
+                }
+            }
             SpellContent(spell = spell)
         }
     }
 }
 
 @Composable
-fun CharacterSpellList(character: DndCharacter, spells: List<Spell>, onItemClick: (Spell) -> Unit = {} ) {
-    LazyColumn() {
+fun CharacterSpellList(
+    character: DndCharacter,
+    spells: List<Spell>,
+    onItemClick: (Spell) -> Unit = {},
+    onRoll: (Spell) -> Unit = {},
+) {
+    LazyColumn {
         items(spells.filter { character.spellList.contains(it.name) }) {
-            SpellListItem(it, onItemClick)
+            SpellListItem(it, onItemClick, onRoll)
         }
     }
 }
@@ -118,6 +165,6 @@ fun CharacterSpellList(character: DndCharacter, spells: List<Spell>, onItemClick
 @Composable
 fun CharacterDetailPreview() {
     DndSpellsTheme {
-        CharacterDetailContent(sampleCharacter, samplespells)
+        CharacterDetailContent(sampleCharacter, sampleSpells)
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt
index 69f9456ee18f16f4f468a55b0f4ba6fdf75186a5..74f825d73ae3bc8f3cbbc7158f3c49a3581b59bc 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt
@@ -8,19 +8,23 @@ import androidx.compose.foundation.layout.*
 import androidx.compose.material.*
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Add
-import androidx.compose.material.icons.outlined.ArrowBack
+import androidx.compose.material.icons.outlined.Delete
 import androidx.compose.material.icons.outlined.Edit
 import androidx.compose.runtime.*
 import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
+import androidx.lifecycle.LiveData
 import androidx.lifecycle.ViewModelProvider
-import androidx.navigation.findNavController
 import com.flyinpancake.dndspells.model.DndCharacter
+import com.flyinpancake.dndspells.model.DndClass
+import com.flyinpancake.dndspells.ui.components.ClassSelector
+import com.flyinpancake.dndspells.ui.components.DndTopBar
+import com.flyinpancake.dndspells.ui.components.LevelSelector
 import com.flyinpancake.dndspells.ui.theme.DndSpellsTheme
 import com.flyinpancake.dndspells.viewmodel.CharacterViewModel
 import kotlinx.coroutines.CoroutineScope
@@ -32,37 +36,62 @@ fun addNewCharacter(character: DndCharacter) {
     characterViewModel.insert(character)
 }
 
-fun updateCharacter(character: DndCharacter) {
-    characterViewModel.update(character)
-}
-
 
-@ExperimentalMaterialApi
 class CreateCharacterActivity : ComponentActivity() {
 
     companion object {
-        val KEY_CHARACTER_NAME = "KEY_CHARACTER_NAME"
+        const val KEY_CHARACTER_NAME = "KEY_CHARACTER_NAME"
     }
 
+    private var characterLiveData: LiveData<DndCharacter>? = null
+
+    @OptIn(ExperimentalMaterialApi::class)
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        characterViewModel = ViewModelProvider(this).get(CharacterViewModel::class.java)
+        characterViewModel = ViewModelProvider(this)[CharacterViewModel::class.java]
         val characterName = intent.getStringExtra(KEY_CHARACTER_NAME)
-
+        val isCreateMode = characterName.isNullOrBlank()
 
         setContent {
-            var dndCharacter = characterName?.let { characterViewModel.get(it).observeAsState(DndCharacter()).value } ?: DndCharacter()
-            val editMode = dndCharacter.name.isBlank()
-
             MyApp {
-                CreateCharacterScreenContent(
-                    editMode,
-                    character = dndCharacter,
-                    onChangeDndCharacter = { dndCharacter = it }
-                )
+                var dndCharacter: DndCharacter? by remember { mutableStateOf(null)}
+                characterLiveData = characterName?.let { characterViewModel.get(it) }
+                val originalCharacter = characterLiveData?.observeAsState()
+
+                if (dndCharacter == null)
+                dndCharacter = if (!isCreateMode && originalCharacter != null) {
+                    originalCharacter.value
+                } else {
+                    DndCharacter()
+                }
+
+                if (dndCharacter == null)
+                    Column(
+                        horizontalAlignment = Alignment.CenterHorizontally,
+                        modifier = Modifier.fillMaxWidth()
+                    ) {
+                        CircularProgressIndicator()
+                    }
+                else
+                    CreateCharacterScreenContent(
+                        isCreateMode,
+                        character = dndCharacter!!,
+                        onChangeDndCharacter = { dndCharacter = it }
+                    )
             }
         }
     }
+
+    fun updateCharacter(character: DndCharacter) {
+        characterLiveData?.removeObservers(this)
+        characterViewModel.update(character)
+    }
+
+    fun deleteCharacter(character: DndCharacter) {
+        characterLiveData?.removeObservers(this)
+        characterViewModel.delete(character)
+        finish()
+    }
 }
 
 @ExperimentalMaterialApi
@@ -70,32 +99,40 @@ class CreateCharacterActivity : ComponentActivity() {
 fun CreateCharacterScreenContent(
     isCreateMode: Boolean = true,
     character: DndCharacter = DndCharacter(),
-    onChangeDndCharacter: (DndCharacter) -> Unit = {}
+    onChangeDndCharacter: (DndCharacter) -> Unit = {},
 ) {
 
     val scope = rememberCoroutineScope()
     val scaffoldState = rememberScaffoldState()
-    val activity = (LocalContext.current as? Activity)
+    val activity = LocalContext.current as? CreateCharacterActivity
 
-    val topText: String = when (isCreateMode) {
+    val topText = when (isCreateMode) {
         true -> "Create Your Character"
         false -> "Modify Your Character"
     }
 
-
     Scaffold(
         scaffoldState = scaffoldState,
         modifier = Modifier.fillMaxSize(),
         topBar = {
-            DndTopBar(topText)
+            DndTopBar(
+                topText,
+                actions = {
+                    if (!isCreateMode) {
+                        IconButton(onClick = { activity?.deleteCharacter(character) }) {
+                            Icon(Icons.Outlined.Delete, "delet character")
+                        }
+                    }
+                }
+            )
         },
         content = {
             Column {
                 CharacterDetailList(
                     dndCharacter = character,
                     onChangeDndCharacter = {
-                        onChangeDndCharacter(it)
-                    }
+                        onChangeDndCharacter(it.copy())
+                    },
                 )
             }
         },
@@ -116,56 +153,56 @@ fun CreateCharacterScreenContent(
                 )
             }
         }
-
-
     )
 }
 
 @Composable
-fun EditCharacterFloatingActionButton(dndCharacter: DndCharacter, activity: Activity?, scope: CoroutineScope, scaffoldState: ScaffoldState) {
+fun EditCharacterFloatingActionButton(
+    dndCharacter: DndCharacter,
+    activity: CreateCharacterActivity?,
+    scope: CoroutineScope,
+    scaffoldState: ScaffoldState
+) {
     val characterErrorText = stringResource(R.string.character_error)
 
     ExtendedFloatingActionButton(
-        text = {
-            Text(stringResource(R.string.modify_character))
-        },
+        text = { Text(stringResource(R.string.modify_character)) },
         onClick = {
             val validation = validateCharacter(dndCharacter)
             if (validation){
-                updateCharacter(dndCharacter)
+                activity?.updateCharacter(dndCharacter)
                 activity?.finish()
-            }
+            } else
             scope.launch {
                 scaffoldState.snackbarHostState.showSnackbar(characterErrorText)
             }
         },
-        icon = {
-            Icon(Icons.Outlined.Edit, contentDescription = null)
-        }
+        icon = { Icon(Icons.Outlined.Edit, contentDescription = null) },
     )
 }
 
 @Composable
-fun CreateCharacterFloatingActionButton(dndCharacter: DndCharacter, activity: Activity?, scope: CoroutineScope, scaffoldState: ScaffoldState) {
+fun CreateCharacterFloatingActionButton(
+    dndCharacter: DndCharacter,
+    activity: Activity?,
+    scope: CoroutineScope,
+    scaffoldState: ScaffoldState
+) {
     val characterErrorText = stringResource(R.string.character_error)
 
     ExtendedFloatingActionButton(
-        text = {
-            Text(stringResource(R.string.add_new_character))
-        },
+        text = { Text(stringResource(R.string.add_new_character)) },
         onClick = {
             val validation = validateCharacter(dndCharacter)
             if (validation){
                 addNewCharacter(dndCharacter)
                 activity?.finish()
-            }
+            } else
             scope.launch {
                 scaffoldState.snackbarHostState.showSnackbar(characterErrorText)
             }
         },
-        icon = {
-            Icon(Icons.Outlined.Add, contentDescription = null)
-        }
+        icon = { Icon(Icons.Outlined.Add, contentDescription = null) }
     )
 }
 
@@ -174,21 +211,11 @@ fun validateCharacter(dndCharacter: DndCharacter): Boolean {
 
     if (dndCharacter.name.isEmpty())
         return false
-    if (dndCharacter.dndClass == DndCharacter.DndClass.None)
+    if (dndCharacter.dndClass == DndClass.None)
         return false
     if (dndCharacter.level > 20 || dndCharacter.level < 0)
         return false
 
-    //
-    val subclassCasters = listOf(
-        DndCharacter.DndClass.ArcaneTrickster,
-        DndCharacter.DndClass.EldritchKnight,
-        DndCharacter.DndClass.Ranger
-    )
-
-    if (subclassCasters.contains(dndCharacter.dndClass) && dndCharacter.level < 3)
-        return false
-
     return true
 }
 
@@ -199,19 +226,13 @@ fun CharacterDetailList(
     dndCharacter: DndCharacter,
     onChangeDndCharacter: (DndCharacter) -> Unit
 ) {
-    val ddoptions = DndCharacter.DndClass.values().toList().subList(0, 11)
-
-    var characterClass by remember { mutableStateOf(dndCharacter.dndClass)}
-    var characterLevel by remember { mutableStateOf(dndCharacter.level) }
-
-    var level by remember { mutableStateOf(dndCharacter.level) }
+    val classList = DndClass.values().toList().subList(0, 11)
 
     Column {
         OutlinedTextField(
             value = dndCharacter.name,
             onValueChange = {
-                dndCharacter.name = it
-                onChangeDndCharacter(dndCharacter)
+                onChangeDndCharacter(dndCharacter.copy(name = it))
             },
             modifier = modifier
                 .fillMaxWidth()
@@ -222,127 +243,26 @@ fun CharacterDetailList(
             modifier
                 .fillMaxWidth()
                 .padding(top = 10.dp, start = 25.dp, end = 25.dp, bottom = 15.dp),
-            ddoptions = ddoptions,
+            allClasses = classList,
             onClassChange = {
-                dndCharacter.dndClass = it
-                onChangeDndCharacter(dndCharacter)
+                onChangeDndCharacter(dndCharacter.copy(dndClass = it))
             },
             starterClass = dndCharacter.dndClass
         )
 
-        LevelSlider(
+        LevelSelector(
             modifier = modifier
                 .fillMaxWidth()
                 .padding(horizontal = 25.dp, vertical = 0.dp),
-            level = characterLevel,
+            level = dndCharacter.level,
             onLevelChange = {
-                characterLevel = it
-                dndCharacter.level = it
-                onChangeDndCharacter(dndCharacter)
+                onChangeDndCharacter(dndCharacter.copy(level = it))
             },
         )
     }
 }
 
 
-@Composable
-fun LevelSlider(
-    modifier: Modifier,
-    level: Int,
-    onLevelChange: (Int) -> Unit,
-) {
-    Row(
-        horizontalArrangement = Arrangement.SpaceBetween,
-        modifier = modifier
-            .padding(start = 5.dp, top = 5.dp, end = 5.dp)
-    ) {
-        Text(
-            text = stringResource(id = R.string.character_level),
-            style = MaterialTheme.typography.body1
-        )
-        Text(
-            text = level.toString(),
-            style = MaterialTheme.typography.body1
-        )
-    }
-    LevelSlider {
-        onLevelChange(it)
-    }
-}
-
-@Composable
-fun LevelSlider(onValueChange: (Int) -> Unit ) {
-    var sliderPosition by remember { mutableStateOf(0f) }
-
-    Slider(
-        value = sliderPosition,
-        onValueChange = {
-            sliderPosition = it
-            onValueChange((sliderPosition * 20f ).toInt())
-        },
-        modifier = Modifier
-            .padding(horizontal = 35.dp)
-    )
-}
-
-
-@ExperimentalMaterialApi
-@Composable
-fun ClassSelector(
-    modifier: Modifier,
-    ddoptions: List<DndCharacter.DndClass>,
-    onClassChange: (DndCharacter.DndClass) -> Unit,
-    starterClass: DndCharacter.DndClass
-) {
-    var expandedState by remember { mutableStateOf(false) }
-    var selectedOption by remember { mutableStateOf(starterClass) }
-
-    ExposedDropdownMenuBox(
-        expanded = expandedState,
-        onExpandedChange = {
-            expandedState = !expandedState
-        },
-        modifier = modifier
-
-    ) {
-        OutlinedTextField(
-            readOnly = true,
-            value = selectedOption.legibleName,
-            onValueChange = {},
-            label = { Text("Class") },
-            trailingIcon = {
-                ExposedDropdownMenuDefaults.TrailingIcon(
-                    expanded = expandedState
-                )
-            },
-            modifier = Modifier.fillMaxWidth()
-        )
-
-        ExposedDropdownMenu(
-            expanded = expandedState,
-            onDismissRequest = {
-                expandedState = false
-            },
-//            modifier = Modifier
-//                .fillMaxWidth(),
-        ) {
-
-            ddoptions.forEach {
-                DropdownMenuItem(
-                    onClick = {
-                        onClassChange(it)
-                        selectedOption = it
-                        expandedState = false
-                    },
-                    modifier = Modifier.fillMaxWidth()
-                ) {
-                    Text(text = it.legibleName)
-                }
-            }
-        }
-    }
-}
-
 @Composable
 fun MyApp(component: @Composable () -> Unit) {
     DndSpellsTheme {
@@ -353,48 +273,24 @@ fun MyApp(component: @Composable () -> Unit) {
     }
 }
 
+@ExperimentalMaterialApi
+@Preview(showBackground = true)
 @Composable
-fun Title(
-    titleText: String,
-    modifier: Modifier = Modifier
-) {
-    Text(
-        text = titleText,
-        fontSize = MaterialTheme.typography.h4.fontSize,
-        modifier = modifier
-            .fillMaxWidth(),
-        textAlign = TextAlign.Center
-    )
-}
-
-@Composable
-fun DndTopBar(titleText: String? = null) {
-    val activity = (LocalContext.current as? Activity)
-
-    TopAppBar(
-        title = {
-            Text(
-                text = titleText?:stringResource(id = R.string.app_name)
-            )
-        },
-        elevation = 0.dp,
-        backgroundColor = MaterialTheme.colors.primary,
-        navigationIcon = {
-            IconButton(onClick = { activity?.onBackPressed() }) {
-                Icon(
-                    Icons.Outlined.ArrowBack,
-                    ""
-                )
-            }
+fun CreateCharacterPreview() {
+    DndSpellsTheme {
+        Surface {
+            CreateCharacterScreenContent()
         }
-    )
+    }
 }
 
 @ExperimentalMaterialApi
 @Preview(showBackground = true)
 @Composable
-fun CreateCharacterPreview() {
-    MyApp {
-        CreateCharacterScreenContent()
+fun CreateCharacterDarkPreview() {
+    DndSpellsTheme(darkTheme = true) {
+        Surface(color = MaterialTheme.colors.background) {
+            CreateCharacterScreenContent()
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt
index a0d05446a67de70441a125458203303373c66271..6051f0e79d12412bd422408f547a4e9016ab9f9a 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt
@@ -49,9 +49,9 @@ class MainActivity : AppCompatActivity(), MainMenuRecyclerViewAdapter.SpellListI
         setContentView(binding.root)
 
         setSupportActionBar(binding.toolbar)
-        binding.toolbar.title = title
+//        binding.toolbar.title = title
 
-        characterViewModel = ViewModelProvider(this).get(CharacterViewModel::class.java)
+        characterViewModel = ViewModelProvider(this)[CharacterViewModel::class.java]
         characterViewModel.allCharacters.observe(this ,{ characters ->
             recyclerViewAdapter.submitList(characters)
         })
@@ -69,21 +69,13 @@ class MainActivity : AppCompatActivity(), MainMenuRecyclerViewAdapter.SpellListI
 
     override fun onItemClick(character: DndCharacter, binding: RecyclerviewMainMenuRowBinding) {
         val intent = Intent(this, CharacterDetailsActivity::class.java)
-        intent.putExtra(ProfileActivity.KEY_NAME, character.name)
-
-        val option = ActivityOptionsCompat.makeSceneTransitionAnimation(
-            this,
-            binding.tvCharacterName,
-            "character_name"
-        )
-        startActivity(intent, option.toBundle())
+        intent.putExtra(CharacterDetailsActivity.KEY_NAME, character.name)
+        startActivity(intent)
     }
 
-    @OptIn(ExperimentalMaterialApi::class)
     override fun onItemLongClick(character: DndCharacter, binding: RecyclerviewMainMenuRowBinding) {
         val intent = Intent(this, CreateCharacterActivity::class.java)
         intent.putExtra(CreateCharacterActivity.KEY_CHARACTER_NAME, character.name)
-
         startActivity(intent)
     }
 
@@ -92,8 +84,6 @@ class MainActivity : AppCompatActivity(), MainMenuRecyclerViewAdapter.SpellListI
         return super.onCreateOptionsMenu(menu)
     }
 
-
-    @OptIn(ExperimentalMaterialApi::class)
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.import_xml -> {
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ProfileActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/ProfileActivity.kt
deleted file mode 100644
index a1520c2248c788a8cbf2bdb2748d80fba9bcda44..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/flyinpancake/dndspells/ProfileActivity.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.flyinpancake.dndspells
-
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.ViewModelProvider
-import androidx.recyclerview.widget.LinearLayoutManager
-import com.flyinpancake.dndspells.adapter.ProfileSpellRecyclerViewAdapter
-import com.flyinpancake.dndspells.databinding.ActivityProfileBinding
-import com.flyinpancake.dndspells.databinding.RecyclerviewSpellRowBinding
-import com.flyinpancake.dndspells.model.Spell
-import com.flyinpancake.dndspells.viewmodel.SpellViewModel
-
-class ProfileActivity : AppCompatActivity(), ProfileSpellRecyclerViewAdapter.SpellListItemClickListener {
-    companion object {
-        const val KEY_NAME = "KEY_NAME"
-    }
-    private lateinit var binding : ActivityProfileBinding
-    private lateinit var spellListViewModel : SpellViewModel
-    private val recyclerViewAdapter = ProfileSpellRecyclerViewAdapter()
-    override fun onCreate(savedInstanceState: Bundle?) {
-        binding = ActivityProfileBinding.inflate(this.layoutInflater)
-        super.onCreate(savedInstanceState)
-        setContentView(binding.root)
-        binding.tvCharacterName.text = intent.getStringExtra(KEY_NAME)!!
-
-        spellListViewModel =  ViewModelProvider(this).get(SpellViewModel::class.java)
-        recyclerViewAdapter.itemClickListener = this
-
-        setupSpellList()
-    }
-
-
-
-    private fun setupSpellList() {
-        spellListViewModel.allSpells.observe(this,{ spells ->
-            recyclerViewAdapter.submitList(spells)
-        })
-        binding.rvSpellList.adapter = recyclerViewAdapter
-        binding.rvSpellList.layoutManager = LinearLayoutManager(this)
-    }
-
-    override fun onItemClick(spell: Spell, binding: RecyclerviewSpellRowBinding) {
-//        val intent = Intent(this, SpellDetailsActivity::class.java)
-//        intent.putExtra(SpellDetailsActivity.KEY_SPELLNAME, Json.encodeToString(spell))
-//        startActivity(intent)
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/SelectSpellsActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/SelectSpellsActivity.kt
index 5de552b501d27a333effdb5d5467396603a761c4..3798ac63500fe4eb6bcb0bc3f5f8561af6e9af29 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/SelectSpellsActivity.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/SelectSpellsActivity.kt
@@ -7,8 +7,11 @@ import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Info
 import androidx.compose.runtime.*
 import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextOverflow
@@ -17,10 +20,16 @@ import androidx.compose.ui.unit.dp
 import androidx.lifecycle.ViewModelProvider
 import com.flyinpancake.dndspells.CharacterDetailsActivity.Companion.KEY_NAME
 import com.flyinpancake.dndspells.model.DndCharacter
+import com.flyinpancake.dndspells.model.DndClass
 import com.flyinpancake.dndspells.model.Spell
+import com.flyinpancake.dndspells.ui.components.DndTopBar
+import com.flyinpancake.dndspells.ui.components.SpellContent
+import com.flyinpancake.dndspells.ui.components.SpellFilterComponent
+import com.flyinpancake.dndspells.ui.logic.SpellFilter
 import com.flyinpancake.dndspells.ui.theme.DndSpellsTheme
 import com.flyinpancake.dndspells.viewmodel.CharacterViewModel
 import com.flyinpancake.dndspells.viewmodel.SpellViewModel
+import kotlinx.coroutines.launch
 
 
 class SelectSpellsActivity : ComponentActivity() {
@@ -45,38 +54,73 @@ class SelectSpellsActivity : ComponentActivity() {
     }
 }
 
+@OptIn(ExperimentalMaterialApi::class)
 @Composable
 fun SelectSpellsContent(
     spells: List<Spell>,
     character: DndCharacter,
     updateCharacter: (DndCharacter) -> Unit = {}
 ) {
-    Scaffold(
-        topBar = { DndTopBar(character.name + stringResource(R.string.select_spells)) }
+    val scope = rememberCoroutineScope()
+    val scaffoldState = rememberBottomSheetScaffoldState()
+
+    var spellFilter by remember { mutableStateOf(SpellFilter(classFilter = character.dndClass)) }
+
+    BottomSheetScaffold(
+        topBar = { DndTopBar(character.name + " " + stringResource(R.string.select_spells)) },
+        sheetPeekHeight = 64.dp,
+        sheetContent = {
+            Box(
+                Modifier
+                    .fillMaxWidth()
+                    .height(64.dp),
+                contentAlignment = Alignment.Center
+            ) {
+                Column {
+                    Text(
+                        text = "Swipe to Filter Spells",
+                        style = MaterialTheme.typography.body1
+                    )
+                }
+            }
+
+            SpellFilterComponent(
+                spellFilter = spellFilter,
+                onSpellFilterChanged = {spellFilter = it}
+            )
+        },
+        scaffoldState = scaffoldState,
+        floatingActionButton = {
+            FloatingActionButton(onClick = {
+                scope.launch {
+                    if (scaffoldState.bottomSheetState.isCollapsed)
+                        scaffoldState.bottomSheetState.expand()
+                    else if (scaffoldState.bottomSheetState.isExpanded)
+                        scaffoldState.bottomSheetState.collapse()
+                }
+            }) {
+                Icon(Icons.Outlined.Info, "filter")
+            }
+        }
     ) {
         LazyColumn {
             items(
-                items = spells.toList(),
+                items = spellFilter.filterSpells(spells),
                 itemContent = { spell ->
-                    var selectedState by remember { mutableStateOf( character.spellList.contains(spell.name)) }
                     SpellCardWithCheckBox(
                         spell = spell,
-                        checked = selectedState,
+                        checked = character.spellList.contains(spell.name),
                         onCheck = { newContains ->
                             val newSpellList = character.spellList.toMutableList()
                             if (newContains && !newSpellList.contains(spell.name)) {
                                 newSpellList.add(spell.name)
-                            } else if (newSpellList.contains(spell.name)){
+                            } else if (newSpellList.contains(spell.name)) {
                                 newSpellList.remove(spell.name)
                             }
-                            selectedState = !selectedState
-                            character.spellList = newSpellList
-                            updateCharacter(character)
+                            updateCharacter(character.copy(spellList = newSpellList))
                         })
                 })
         }
-
-
     }
 }
 
@@ -95,8 +139,7 @@ private fun SpellCardWithCheckBox(
             Modifier
                 .fillMaxSize()
                 .padding(10.dp),
-
-            ) {
+        ) {
             Checkbox(
                 checked = checked,
                 onCheckedChange = { onCheck(it) },
@@ -107,54 +150,7 @@ private fun SpellCardWithCheckBox(
     }
 }
 
-@Composable
-fun SpellContent(spell: Spell) {
-    val textPadding = Modifier.padding(horizontal = 5.dp)
-    Column(
-        Modifier.fillMaxSize(),
-        verticalArrangement = Arrangement.Center,
-    ) {
-        Row(
-            Modifier.fillMaxSize(),
-            horizontalArrangement = Arrangement.SpaceBetween
-        ) {
-            Text(
-                text = spell.name,
-                modifier = textPadding,
-                maxLines = 1,
-                overflow = TextOverflow.Ellipsis,
-                style = MaterialTheme.typography.h6
-            )
-            Text(
-                text = "Level ${spell.level}",
-                modifier = textPadding,
-                maxLines = 1,
-                style = MaterialTheme.typography.h6
-            )
-        }
-        Row(
-            Modifier.fillMaxSize(),
-            horizontalArrangement = Arrangement.SpaceBetween
-        ) {
-            Text(text = spell.range, modifier = textPadding, style = MaterialTheme.typography.body1)
-            Text(text = spell.time, modifier = textPadding, style = MaterialTheme.typography.body1)
-            Text(
-                text = spell.components,
-                style = MaterialTheme.typography.body1,
-                modifier = textPadding,
-                maxLines = 1,
-                overflow = TextOverflow.Ellipsis
-            )
-        }
-    }
-}
-
-@Composable
-private fun SelectableSpellList(spells: List<Spell>, character: DndCharacter) {
-
-}
-
-val samplespells = listOf(
+val sampleSpells = listOf(
     Spell(
         name = "Power Word Kill",
         level = 9,
@@ -165,31 +161,32 @@ val samplespells = listOf(
         range = "240 ft",
         ritual = false,
         school = "E",
-        time = "instantanius"
+        time = "instantaneous",
+        roll = "10d6"
     )
 )
 
 val sampleCharacter = DndCharacter(
     name = "Ba'luk",
     level = 4,
-    dndClass = DndCharacter.DndClass.Druid,
+    dndClass = DndClass.Druid,
     spellList = listOf("Power Word Kill")
 )
 
 @Preview(showBackground = true)
 @Composable
-fun DefaultPreview() {
+fun SpellSelectPreview() {
 
     DndSpellsTheme {
-        SelectSpellsContent(spells = samplespells, character = sampleCharacter)
+        SelectSpellsContent(spells = sampleSpells, character = sampleCharacter)
     }
 }
 
 @Preview(showBackground = true)
 @Composable
-fun DefaultDarkPreview() {
+fun SpellSelectDarkPreview() {
 
-    DndSpellsTheme (darkTheme = true) {
-        SelectSpellsContent(spells = samplespells, character = sampleCharacter)
+    DndSpellsTheme(darkTheme = true) {
+        SelectSpellsContent(spells = sampleSpells, character = sampleCharacter)
     }
 }
diff --git a/app/src/main/java/com/flyinpancake/dndspells/SpellDetailsActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/SpellDetailsActivity.kt
index 492c7599c1f73a8899d7511e54b29585c80a3ba7..2ef10fdfbf0e7c00b4c71e1622331809b8229af3 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/SpellDetailsActivity.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/SpellDetailsActivity.kt
@@ -3,74 +3,89 @@ package com.flyinpancake.dndspells
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
-import androidx.compose.foundation.gestures.scrollable
 import androidx.compose.foundation.layout.*
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
+import androidx.compose.material.*
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.ViewModelProvider
 import com.flyinpancake.dndspells.model.Spell
+import com.flyinpancake.dndspells.ui.components.DndTopBar
 import com.flyinpancake.dndspells.ui.theme.DndSpellsTheme
 import com.flyinpancake.dndspells.viewmodel.SpellViewModel
+import kotlinx.coroutines.launch
 import kotlinx.serialization.ExperimentalSerializationApi
-import kotlinx.serialization.decodeFromString
-import kotlinx.serialization.json.Json
-
-lateinit var spellViewModel: SpellViewModel
 
 class SpellDetailsActivity : ComponentActivity() {
-    private lateinit var spell: Spell
-
     companion object{
-        val KEY_SPELLNAME = "KEY_SPELLNAME"
+        const val KEY_SPELL_NAME = "KEY_SPELL_NAME"
     }
+
     @OptIn(ExperimentalSerializationApi::class)
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        val spellJson = intent.getStringExtra(KEY_SPELLNAME)?: ""
-        spell = Json.decodeFromString(spellJson)
-
+        val spellName = intent.getStringExtra(KEY_SPELL_NAME)?: ""
 
         setContent {
+            val spell = ViewModelProvider(this)[SpellViewModel::class.java]
+                .get(spellName)
+                .observeAsState(Spell())
+                .value
+
             DndSpellsTheme {
                 // A surface container using the 'background' color from the theme
                 Surface(color = MaterialTheme.colors.background) {
-                    SpellDetails(spell)
+                    SpellDetails(spell = spell)
                 }
             }
         }
     }
 }
 
-
-
 @Composable
-fun SpellDetails(spell: Spell) {
+fun SpellDetails(
+    spell: Spell,
+) {
+    val scope = rememberCoroutineScope()
+    val scaffoldState = rememberScaffoldState()
+
+    val youRolled = stringResource(id = R.string.you_rolled)
     
     Scaffold(
         modifier = Modifier
             .fillMaxSize(),
-        topBar = { DndTopBar() }
-    ) {
+        topBar = { DndTopBar(spell.name) },
+        floatingActionButton = {
+            spell.roll?.let { roll ->
+                ExtendedFloatingActionButton(
+                    text = { Text("Cast Spell") },
+                    onClick = {
+                        scope.launch {
+                            scaffoldState.snackbarHostState.showSnackbar(youRolled + roll(roll.trim()))
+                        }
+                    },
+                    icon = { Icon(painterResource(id = R.drawable.dice_5_outline), null) }
+                )
+            }
+        },
+        scaffoldState = scaffoldState,
+        ) {
         Column(
             Modifier
                 .verticalScroll(rememberScrollState())
         ) {
-            Title(titleText = spell.name)
             SpellAttributes(spell)
             SpellDescription(spell)
         }
-
     }
-    
 }
 
 @Composable
@@ -107,7 +122,7 @@ fun SpellAttributes(spell: Spell) {
 @Composable
 fun SpellDescription(spell: Spell){
     Text(
-        text = spell.desc,
+        text = spell.desc.replace("\n\t",""),
         modifier = Modifier
             .padding(25.dp)
             .fillMaxSize(),
@@ -119,6 +134,6 @@ fun SpellDescription(spell: Spell){
 @Composable
 fun DefaultPreview2() {
     DndSpellsTheme {
-//        SpellDetails()
+        SpellDetails(Spell())
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt b/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt
index c12a8449e2e92010881f666c82a2aa3a526bed69..7af0e55adcab21479d8b77c3c180aeb9b0d8c544 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt
@@ -10,9 +10,9 @@ import com.flyinpancake.dndspells.databinding.RecyclerviewMainMenuRowBinding
 import com.flyinpancake.dndspells.model.DndCharacter
 
 class MainMenuRecyclerViewAdapter :
-    ListAdapter<DndCharacter, MainMenuRecyclerViewAdapter.MainMenuViewHolder>(itemCallback) {
+    ListAdapter<DndCharacter, MainMenuRecyclerViewAdapter.MainMenuViewHolder>(ItemCallback) {
     companion object {
-        object itemCallback: DiffUtil.ItemCallback<DndCharacter>() {
+        object ItemCallback: DiffUtil.ItemCallback<DndCharacter>() {
             override fun areItemsTheSame(oldItem: DndCharacter, newItem: DndCharacter): Boolean {
                 return newItem == oldItem
             }
@@ -57,4 +57,4 @@ class MainMenuRecyclerViewAdapter :
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = MainMenuViewHolder(
         RecyclerviewMainMenuRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
     )
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/adapter/ProfileSpellRecyclerViewAdapter.kt b/app/src/main/java/com/flyinpancake/dndspells/adapter/ProfileSpellRecyclerViewAdapter.kt
deleted file mode 100644
index 5f92d1273ef4f7dac6100ed1248a73b0b46d89bc..0000000000000000000000000000000000000000
--- a/app/src/main/java/com/flyinpancake/dndspells/adapter/ProfileSpellRecyclerViewAdapter.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.flyinpancake.dndspells.adapter
-
-import android.os.Parcel
-import android.os.Parcelable
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import com.flyinpancake.dndspells.model.Spell
-import com.flyinpancake.dndspells.databinding.RecyclerviewSpellRowBinding
-
-class ProfileSpellRecyclerViewAdapter : ListAdapter<Spell, ProfileSpellRecyclerViewAdapter.ViewHolder>(itemCallback) {
-
-    companion object {
-        object itemCallback: DiffUtil.ItemCallback<Spell>() {
-            override fun areItemsTheSame(oldItem: Spell, newItem: Spell): Boolean {
-                return oldItem == newItem
-            }
-
-            override fun areContentsTheSame(oldItem: Spell, newItem: Spell): Boolean {
-                return newItem.name == oldItem.name
-            }
-        }
-    }
-
-    inner class ViewHolder(val binding: RecyclerviewSpellRowBinding) :
-         RecyclerView.ViewHolder(binding.root) {
-        var spell: Spell? = null
-
-        init {
-            itemView.setOnClickListener {
-                spell?.let { spell -> itemClickListener?.onItemClick(spell, binding) }
-            }
-        }
-    }
-
-    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
-        RecyclerviewSpellRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
-    )
-
-    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
-        val spell = this.getItem(position)
-
-        holder.binding.SpellComponents.text = spell.components
-        holder.binding.SpellLevel.text = "${spell.level}"
-        holder.binding.SpellSchool.text = spell.school
-        holder.binding.tvSpellName.text = spell.name
-        holder.spell = spell
-    }
-
-    var itemClickListener: SpellListItemClickListener? = null
-
-    interface SpellListItemClickListener {
-        fun onItemClick(spell: Spell, binding: RecyclerviewSpellRowBinding)
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDao.kt b/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDao.kt
index 0d78df4726409775c9c92400e699a9173bd99e2b..2d970acf207a66e03b52b3ba7a3b428c2bef870b 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDao.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDao.kt
@@ -11,6 +11,9 @@ interface CharacterDao {
     @Query("SELECT * FROM characters")
     fun getAllCharacters(): LiveData<List<RoomCharacter>>
 
+    @Query("SELECT * FROM characters WHERE id == :id")
+    fun getCharacter(id: Int): RoomCharacter?
+
     @Query("SELECT * FROM characters WHERE name == :name")
     fun getCharacterByName(name: String): RoomCharacter?
 
@@ -24,6 +27,4 @@ interface CharacterDao {
     fun deleteCharacter(
         character: RoomCharacter
     )
-
-
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDatabase.kt b/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDatabase.kt
index 7c419e3a86dfedbe03fd99390299f5c3a4a0a62d..6858ee5966a7240b590060f887e4cbaaba08ce03 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDatabase.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/CharacterDatabase.kt
@@ -10,4 +10,4 @@ import androidx.room.RoomDatabase
 )
 abstract class CharacterDatabase : RoomDatabase() {
     abstract fun characterDao(): CharacterDao
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/RoomCharacter.kt b/app/src/main/java/com/flyinpancake/dndspells/database/RoomCharacter.kt
index fdcb1e83d010dd771fe0065c3ed34851e93e1327..4ec8df730ba004ed89deaf7d0e4f30315494edee 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/RoomCharacter.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/RoomCharacter.kt
@@ -1,15 +1,14 @@
 package com.flyinpancake.dndspells.database
 
 import androidx.room.Entity
-import androidx.room.Index
 import androidx.room.PrimaryKey
 
-@Entity(tableName = "characters", indices = [Index(value = ["name"], unique = true)])
+@Entity(tableName = "characters")
 class RoomCharacter(
     @PrimaryKey(autoGenerate = true)
     val id: Int = 0,
-    var name: String,
-    var level: Int,
-    var dndClass: String,
+    val name: String,
+    val level: Int,
+    val dndClass: String,
     val spellNameList: String,
 )
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/RoomSpell.kt b/app/src/main/java/com/flyinpancake/dndspells/database/RoomSpell.kt
index 89320472b4b62af3e60e4d9bc509976bf4b7271b..d9fe258ddb4c8135022eee5f61982fe4abc91efd 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/RoomSpell.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/RoomSpell.kt
@@ -19,4 +19,5 @@ data class RoomSpell(
     val ritual: Boolean,
     val duration: String,
     val classes: String,
+    val roll: String?
 )
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/SpellDao.kt b/app/src/main/java/com/flyinpancake/dndspells/database/SpellDao.kt
index 3e1804194075543c760ae6f725d2691be347f545..67c4df154dfbf03d755d756081929d0e03e2bb6e 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/SpellDao.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/SpellDao.kt
@@ -18,6 +18,9 @@ interface SpellDao {
     @Query("SELECT * FROM spells WHERE name == :name")
     fun getSpellByName(name: String): RoomSpell?
 
+    @Query("SELECT * FROM spells WHERE name == :name")
+    fun getSpellLiveByName(name: String): LiveData<RoomSpell>
+
     @Delete
     fun deleteSpell(spell: RoomSpell)
 
diff --git a/app/src/main/java/com/flyinpancake/dndspells/database/SpellDatabase.kt b/app/src/main/java/com/flyinpancake/dndspells/database/SpellDatabase.kt
index b20de39c775cf2bf38c78e24151039b92afe7575..b834f43166c270cf4570539f65b0d827a4f008e3 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/database/SpellDatabase.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/database/SpellDatabase.kt
@@ -2,8 +2,6 @@ package com.flyinpancake.dndspells.database
 
 import androidx.room.Database
 import androidx.room.RoomDatabase
-import androidx.room.TypeConverters
-
 
 @Database(
     version = 1,
diff --git a/app/src/main/java/com/flyinpancake/dndspells/model/DndCharacter.kt b/app/src/main/java/com/flyinpancake/dndspells/model/DndCharacter.kt
index 05f6a41903dc051218067d3f8d82257136374834..de16a896d9ea1a7db0691f7477c73c84d210cfba 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/model/DndCharacter.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/model/DndCharacter.kt
@@ -1,31 +1,18 @@
 package com.flyinpancake.dndspells.model
 
 data class DndCharacter(
-    var id: Int = 0,
-    var name: String,
-    var level: Int,
-    var dndClass: DndClass,
-    var spellList: List<String>,
+    val id: Int = 0,
+    val name: String,
+    val level: Int,
+    val dndClass: DndClass,
+    val spellList: List<String>,
 
     ) {
 
     constructor() :this(name = "" , level = 0, dndClass = DndClass.None, spellList = listOf())
     constructor(name: String, level: Int, dndClass: DndClass) :this(name = name, level = level, dndClass = dndClass, spellList = listOf())
 
-    enum class DndClass(val legibleName: String) {
-
-
-        ArcaneTrickster("Rouge (Arcane Trickster)"),
-        Artificer("Artificer"),
-        Bard("Bard"),
-        Cleric("Cleric"),
-        Druid("Druid"),
-        EldritchKnight("Fighter (Eldritch Knight)"),
-        Paladin("Paladin"),
-        Ranger("Ranger"),
-        Sorcerer("Sorcerer"),
-        Warlock("Warlock"),
-        Wizard("Wizard"),
-        None("None"),;
+    override fun toString(): String {
+        return "${name}, level:${level}, class:${dndClass.legibleName}"
     }
 }
diff --git a/app/src/main/java/com/flyinpancake/dndspells/model/DndClass.kt b/app/src/main/java/com/flyinpancake/dndspells/model/DndClass.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f2283cdd7cbe6cfe2f5f4ffcffe2688497bcad3d
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/model/DndClass.kt
@@ -0,0 +1,16 @@
+package com.flyinpancake.dndspells.model
+
+enum class DndClass(val legibleName: String) {
+    Artificer("Artificer"),
+    Bard("Bard"),
+    Cleric("Cleric"),
+    Druid("Druid"),
+    Fighter("Fighter"),
+    Paladin("Paladin"),
+    Ranger("Ranger"),
+    Rouge("Rouge"),
+    Sorcerer("Sorcerer"),
+    Warlock("Warlock"),
+    Wizard("Wizard"),
+    None("None"),;
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/model/DndSubclass.kt b/app/src/main/java/com/flyinpancake/dndspells/model/DndSubclass.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9ea0484fa261dd0a31a1562ef10e8e7370dc71c8
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/model/DndSubclass.kt
@@ -0,0 +1,4 @@
+package com.flyinpancake.dndspells.model
+
+class DndSubclass {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/model/Spell.kt b/app/src/main/java/com/flyinpancake/dndspells/model/Spell.kt
index c7521a7457cace575bc5968c8a2c77eec1337277..c0d350436af62b64314a4a3f0c49590000f1b8bc 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/model/Spell.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/model/Spell.kt
@@ -14,4 +14,19 @@ data class Spell (
     val ritual: Boolean,
     val duration: String,
     val classes: String,
-)
+    val roll: String?
+) {
+    constructor() : this(
+        name = "",
+        desc = "",
+        level = 0,
+        components = "",
+        range = "",
+        time = "",
+        school = "",
+        ritual = false,
+        duration = "",
+        classes = "",
+        roll = null
+    )
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/model/SpellImporter.kt b/app/src/main/java/com/flyinpancake/dndspells/model/SpellImporter.kt
index 77d940a2509ea6446858cd768428f5f626ca89b7..a4c9150cd28d69322635858c984e6a9d6d600c13 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/model/SpellImporter.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/model/SpellImporter.kt
@@ -65,6 +65,7 @@ class SpellImporter {
         var ritual: Boolean? = null
         var duration: String? = null
         var classes: String? = null
+        var roll: String? = null
 
 
         while (parser.next() != XmlPullParser.END_TAG) {
@@ -81,6 +82,7 @@ class SpellImporter {
                 "duration" -> duration = readDuration(parser)
                 "classes" -> classes = readClasses(parser)
                 "text" -> desc += readText(parser)
+                "roll" -> roll = readRoll(parser)
                 else -> skip(parser)
             }
         }
@@ -97,7 +99,8 @@ class SpellImporter {
             school ?: "",
             ritual ?: false,
             duration ?: "",
-            classes?: "Any"
+            classes?: "Any",
+            roll
         )
     }
 
@@ -114,6 +117,11 @@ class SpellImporter {
         return readInsideTags(parser, "classes")
     }
 
+    @Throws(IOException::class, XmlPullParserException::class)
+    private fun readRoll(parser: XmlPullParser): String {
+        return readInsideTags(parser, "roll")
+    }
+
     @Throws(IOException::class, XmlPullParserException::class)
     private fun readText(parser: XmlPullParser): String {
         var text = readInsideTags(parser, "text")
diff --git a/app/src/main/java/com/flyinpancake/dndspells/repository/CharacterRepository.kt b/app/src/main/java/com/flyinpancake/dndspells/repository/CharacterRepository.kt
index 34ba87746f9b6b623b6ce6d05eb01e416b178403..300df0bc43a189d6ff7874431de065ef86b45fea 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/repository/CharacterRepository.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/repository/CharacterRepository.kt
@@ -2,10 +2,10 @@ package com.flyinpancake.dndspells.repository
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.map
-import com.flyinpancake.dndspells.DndApplication
 import com.flyinpancake.dndspells.database.CharacterDao
 import com.flyinpancake.dndspells.database.RoomCharacter
 import com.flyinpancake.dndspells.model.DndCharacter
+import com.flyinpancake.dndspells.model.DndClass
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 
@@ -24,7 +24,7 @@ class CharacterRepository(
     }
 
     suspend fun delete(character: DndCharacter) = withContext(Dispatchers.IO) {
-        val roomCharacter = characterDao.getCharacterByName(character.name)
+        val roomCharacter = characterDao.getCharacter(character.id)
         roomCharacter?.let { characterDao.deleteCharacter(roomCharacter) }
     }
 
@@ -55,16 +55,17 @@ private fun DndCharacter.toRoomDomain(): RoomCharacter {
 }
 
 private fun RoomCharacter.toDomainModel(): DndCharacter {
-    val dndCharacter = DndCharacter()
-    dndCharacter.name = name
-    dndCharacter.level = level
-    dndCharacter.id = id
-    if (spellNameList.isNotEmpty())
-    dndCharacter.spellList = spellNameList.split('\n')
-    DndCharacter.DndClass.values().forEach { dndClass ->
-        if (dndClass.legibleName == this.dndClass)
-            dndCharacter.dndClass = dndClass
+    var characterClass: DndClass = DndClass.None
+    DndClass.values().forEach {
+        if (it.legibleName == dndClass){
+            characterClass = it
+        }
     }
-
-    return dndCharacter
+    return DndCharacter(
+        name = name,
+        level = level,
+        id = id,
+        spellList = spellNameList.split('\n'),
+        dndClass = characterClass
+    )
 }
diff --git a/app/src/main/java/com/flyinpancake/dndspells/repository/SpellRepository.kt b/app/src/main/java/com/flyinpancake/dndspells/repository/SpellRepository.kt
index a87c181a60350ea3b7a06ed14fc96b583b50f946..4c4eea9a7360f979d0ed5a6d5d50d8c529e544f9 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/repository/SpellRepository.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/repository/SpellRepository.kt
@@ -29,6 +29,10 @@ class SpellRepository(private val spellDao: SpellDao) {
         spellDao.nukeSpells()
     }
 
+    fun getSpellByName(spellName: String): LiveData<Spell> {
+        return spellDao.getSpellLiveByName(spellName).map { it.toDomainModel() }
+    }
+
 
 }
 
@@ -43,13 +47,14 @@ private fun Spell.toRoomModel(): RoomSpell {
         range = range,
         ritual = ritual,
         school = school,
-        time = time
+        time = time,
+        roll = roll
     )
 }
 
 
 fun RoomSpell.toDomainModel(): Spell {
-    return Spell(name, desc, level, components, range, time, school, ritual, duration, classes)
+    return Spell(name, desc, level, components, range, time, school, ritual, duration, classes, roll)
 }
 
 
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/ClassSelector.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/ClassSelector.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ce0de67b087c200cc7498d4bd370813b83a6ca53
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/ClassSelector.kt
@@ -0,0 +1,63 @@
+package com.flyinpancake.dndspells.ui.components
+
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import com.flyinpancake.dndspells.model.DndCharacter
+import com.flyinpancake.dndspells.model.DndClass
+
+@ExperimentalMaterialApi
+@Composable
+fun ClassSelector(
+    modifier: Modifier,
+    allClasses: List<DndClass>,
+    onClassChange: (DndClass) -> Unit,
+    starterClass: DndClass
+) {
+    var expandedState by remember { mutableStateOf(false) }
+    var selectedOption by remember { mutableStateOf(starterClass) }
+
+    ExposedDropdownMenuBox(
+        expanded = expandedState,
+        onExpandedChange = {
+            expandedState = !expandedState
+        },
+        modifier = modifier
+
+    ) {
+        OutlinedTextField(
+            readOnly = true,
+            value = selectedOption.legibleName,
+            onValueChange = {},
+            label = { Text("Class") },
+            trailingIcon = {
+                ExposedDropdownMenuDefaults.TrailingIcon(
+                    expanded = expandedState
+                )
+            },
+            modifier = Modifier.fillMaxWidth()
+        )
+
+        ExposedDropdownMenu(
+            expanded = expandedState,
+            onDismissRequest = {
+                expandedState = false
+            },
+        ) {
+
+            allClasses.forEach {
+                DropdownMenuItem(
+                    onClick = {
+                        onClassChange(it)
+                        selectedOption = it
+                        expandedState = false
+                    },
+                    modifier = Modifier.fillMaxWidth()
+                ) {
+                    Text(text = it.legibleName)
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/DndTopBar.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/DndTopBar.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dd2e573726593fa7b310ac6694cab59093ed1c0d
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/DndTopBar.kt
@@ -0,0 +1,35 @@
+package com.flyinpancake.dndspells.ui.components
+
+import android.app.Activity
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.material.*
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.flyinpancake.dndspells.R
+
+@Composable
+fun DndTopBar(
+    titleText: String? = null,
+    actions: @Composable RowScope.() -> Unit = {}
+) {
+    val activity = (LocalContext.current as? Activity)
+
+    TopAppBar(
+        title = { Text(text = titleText?: stringResource(id = R.string.app_name)) },
+        elevation = 0.dp,
+        backgroundColor = MaterialTheme.colors.primary,
+        navigationIcon = {
+            IconButton(onClick = { activity?.onBackPressed() }) {
+                Icon(
+                    imageVector = Icons.Outlined.ArrowBack,
+                    contentDescription = "back arrow"
+                )
+            }
+        },
+        actions = actions,
+    )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/LevelSelector.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/LevelSelector.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4efd253231b0cc7109ca5c16580c4416661c93a5
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/LevelSelector.kt
@@ -0,0 +1,53 @@
+package com.flyinpancake.dndspells.ui.components
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Slider
+import androidx.compose.material.Text
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.flyinpancake.dndspells.R
+
+@Composable
+fun LevelSelector(
+    modifier: Modifier,
+    level: Int,
+    onLevelChange: (Int) -> Unit,
+) {
+    Row(
+        horizontalArrangement = Arrangement.SpaceBetween,
+        modifier = modifier
+            .padding(start = 5.dp, top = 5.dp, end = 5.dp)
+    ) {
+        Text(
+            text = stringResource(id = R.string.character_level),
+            style = MaterialTheme.typography.body1
+        )
+        Text(text = "$level", style = MaterialTheme.typography.body1)
+    }
+    LevelSlider (level) {
+        onLevelChange(it)
+    }
+}
+
+@Composable
+private fun LevelSlider(
+    starterValue: Int,
+    onValueChange: (Int) -> Unit
+) {
+    var sliderPosition by remember { mutableStateOf(starterValue / 20f) }
+
+    Slider(
+        value = sliderPosition,
+        onValueChange = {
+            sliderPosition = it
+            onValueChange((sliderPosition * 20f ).toInt())
+        },
+        modifier = Modifier
+            .padding(horizontal = 35.dp)
+    )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellContent.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..82edc0cc054abf3697104b22b3a4e491d5376ba2
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellContent.kt
@@ -0,0 +1,64 @@
+package com.flyinpancake.dndspells.ui.components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import com.flyinpancake.dndspells.model.Spell
+
+@Composable
+fun SpellContent(spell: Spell) {
+    val textPadding = Modifier.padding(horizontal = 5.dp)
+    Column(
+        Modifier.fillMaxWidth(),
+        verticalArrangement = Arrangement.Center,
+    ) {
+        Row(
+            Modifier.fillMaxWidth(),
+            horizontalArrangement = Arrangement.SpaceBetween
+        ) {
+            Text(
+                text = spell.name,
+                modifier = textPadding,
+                maxLines = 1,
+                overflow = TextOverflow.Ellipsis,
+                style = MaterialTheme.typography.h6
+            )
+            Text(
+                text = "Level ${spell.level}",
+                modifier = textPadding,
+                maxLines = 1,
+                style = MaterialTheme.typography.h6
+            )
+        }
+        Row(
+            Modifier.fillMaxWidth(),
+            horizontalArrangement = Arrangement.SpaceBetween
+        ) {
+            Text(
+                text = spell.range,
+                modifier = textPadding,
+                style = MaterialTheme.typography.body1,
+                maxLines = 1,
+                overflow = TextOverflow.Ellipsis
+            )
+            Text(
+                text = spell.time,
+                modifier = textPadding,
+                style = MaterialTheme.typography.body1,
+                maxLines = 1,
+                overflow = TextOverflow.Ellipsis
+            )
+            Text(
+                text = spell.components,
+                style = MaterialTheme.typography.body1,
+                modifier = textPadding,
+                maxLines = 1,
+                overflow = TextOverflow.Ellipsis
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellFilterComponent.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellFilterComponent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..29b2ac186df24812fc120e029a0999afee8b8fd4
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SpellFilterComponent.kt
@@ -0,0 +1,100 @@
+package com.flyinpancake.dndspells.ui.components
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.*
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.flyinpancake.dndspells.ui.logic.SpellFilter
+import com.flyinpancake.dndspells.R
+
+@Composable
+fun SpellFilterComponent(
+    spellFilter: SpellFilter,
+    onSpellFilterChanged: (SpellFilter) -> Unit,
+) {
+    Column(
+        Modifier
+            .fillMaxWidth()
+            .padding(32.dp),
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        OutlinedTextField(
+            value = spellFilter.nameFilter,
+            onValueChange = { onSpellFilterChanged(spellFilter.copy(nameFilter = it)) },
+            label = {
+                Text(stringResource(R.string.spell_name))
+            },
+            modifier = Modifier.fillMaxWidth(),
+        )
+
+        Divider(
+            Modifier.padding(vertical = 20.dp)
+        )
+
+        Row(
+            horizontalArrangement = Arrangement.SpaceBetween,
+            modifier = Modifier.fillMaxWidth(),
+            verticalAlignment = Alignment.CenterVertically
+        ) {
+            Row(verticalAlignment = Alignment.CenterVertically) {
+                Switch(
+                    checked = spellFilter.levelFilterEnabled,
+                    onCheckedChange = { onSpellFilterChanged(spellFilter.copy(levelFilterEnabled = it)) },
+                    Modifier.padding(end = 20.dp),
+                )
+                Text(stringResource(R.string.filter_spell_level))
+            }
+
+            Text("Level " + spellFilter.levelFilter.toInt())
+        }
+        Slider(
+            value = spellFilter.levelFilter / 9,
+            onValueChange = { onSpellFilterChanged(spellFilter.copy(levelFilter = it * 9))},
+            enabled = spellFilter.levelFilterEnabled
+        )
+
+        Divider(
+            Modifier.padding(vertical = 20.dp)
+        )
+
+        Row(
+            Modifier
+                .fillMaxWidth()
+                .padding(vertical = 15.dp),
+            horizontalArrangement = Arrangement.SpaceBetween,
+            verticalAlignment = Alignment.CenterVertically
+        ) {
+            Switch(
+                checked = spellFilter.componentFilterEnabled,
+                onCheckedChange = { onSpellFilterChanged(spellFilter.copy(componentFilterEnabled = it)) },
+                Modifier.padding(end = 20.dp)
+            )
+            OutlinedTextField(
+                value = spellFilter.componentFilter,
+                onValueChange = { onSpellFilterChanged(spellFilter.copy(componentFilter = it)) },
+                label = { Text(stringResource(R.string.filter_components)) },
+                enabled = spellFilter.componentFilterEnabled
+            )
+        }
+
+        Divider(
+            Modifier.padding(vertical = 20.dp)
+        )
+
+        Row(
+            Modifier.fillMaxWidth(),
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.SpaceBetween
+        ) {
+            Switch(
+                checked = spellFilter.classFilterEnabled,
+                onCheckedChange = { onSpellFilterChanged(spellFilter.copy(classFilterEnabled = it)) })
+            Text(
+                text = "Show spells only for own class"
+            )
+        }
+    }
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/components/SubclassSelector.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SubclassSelector.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7618e0173ff6ea551e7c76484a6c99af80275710
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/components/SubclassSelector.kt
@@ -0,0 +1,8 @@
+package com.flyinpancake.dndspells.ui.components
+
+import androidx.compose.runtime.Composable
+
+@Composable
+fun SubclassSelector(){
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/ui/logic/SpellFilter.kt b/app/src/main/java/com/flyinpancake/dndspells/ui/logic/SpellFilter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1708f1fa489d4a09e1e76234bfb7589e2efe2d6f
--- /dev/null
+++ b/app/src/main/java/com/flyinpancake/dndspells/ui/logic/SpellFilter.kt
@@ -0,0 +1,29 @@
+package com.flyinpancake.dndspells.ui.logic
+
+import com.flyinpancake.dndspells.model.DndCharacter
+import com.flyinpancake.dndspells.model.DndClass
+import com.flyinpancake.dndspells.model.Spell
+
+data class SpellFilter (
+    val nameFilter: String = "",
+    val levelFilter: Float = 0f,
+    val levelFilterEnabled: Boolean = false,
+    val componentFilter: String = "",
+    val componentFilterEnabled: Boolean = false,
+    val classFilter: DndClass,
+    val classFilterEnabled: Boolean = false,
+) {
+    fun filterSpells(spells: List<Spell>): List<Spell> {
+        return spells.filter { spell ->
+            nameFilter.isBlank() || spell.name.contains(nameFilter.trim(), ignoreCase = true)
+        }.filter { spell ->
+            !levelFilterEnabled || spell.level == levelFilter.toInt()
+        }.filter { spell ->
+            !componentFilterEnabled || componentFilter.all { char -> spell.components.contains(char)}
+        }.filter { spell ->
+            !classFilterEnabled || spell.classes.split(",").any {
+                it.contains(classFilter.legibleName.split(" ")[0])
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/flyinpancake/dndspells/viewmodel/CharacterViewModel.kt b/app/src/main/java/com/flyinpancake/dndspells/viewmodel/CharacterViewModel.kt
index 009e4c40145b425a19ab28abf57c78109a3278e8..a35dbb744efdc27ea66d76e1fd418053b4fe1fca 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/viewmodel/CharacterViewModel.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/viewmodel/CharacterViewModel.kt
@@ -34,4 +34,4 @@ class CharacterViewModel: ViewModel() {
     fun update(character: DndCharacter) = viewModelScope.launch {
         repo.update(character)
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/flyinpancake/dndspells/viewmodel/SpellViewModel.kt b/app/src/main/java/com/flyinpancake/dndspells/viewmodel/SpellViewModel.kt
index 13182f3d289ebf7c5b4fb8ce03e0a067958703a9..332009e242efa6ee6a2ed2c08bf2d2690863df26 100644
--- a/app/src/main/java/com/flyinpancake/dndspells/viewmodel/SpellViewModel.kt
+++ b/app/src/main/java/com/flyinpancake/dndspells/viewmodel/SpellViewModel.kt
@@ -30,4 +30,8 @@ class SpellViewModel: ViewModel() {
     fun nuke() = viewModelScope.launch {
         repo.nuke()
     }
+
+    fun get(spellName: String): LiveData<Spell> {
+        return repo.getSpellByName(spellName)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_18dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..37a13ed84edbae649c486f3a79ec6d836c5bd3e6
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ad3e5cf6cbc147ca3607b2819e13d0c99c3be8e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_36dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..60d08dbb6964ead8e0b04e20e80b0076ad092b1d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..15b263d6a9da827f6e56862dd3e514ba57a6f07d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_black_48dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_18dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..520ef271b057fa8c57690b71b4d66d62e3077d45
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_24dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbef1c912f88dac2b45f28f988c19e288eb22606
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_36dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8acb444883d8c4ee39e2d26f332640f5c0d1f4d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_48dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb87f9035d56ee97a5d0e4f02df9863a3cf1e1dc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_18dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2c024eb2a7b75d42c90d7877939d92d6df77ae2
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..1af6cf1af5b21ccc38852a2e890e644b3518353d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_36dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..83b6af1cfb4c6f8289ec4219bf35ea566d61d495
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_48dp.png b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..10c889b99c7ebbf92c45759f0112a777ddae9113
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_dice_5_outline_white_48dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_black_18dp.png b/app/src/main/res/drawable-hdpi/ic_plus_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..79c410e196380cb5d58b1d8bcc015c95aa9af310
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_black_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_plus_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3e4b1d09cbf8caa2e8390a1c54bd895111a823d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_black_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_black_36dp.png b/app/src/main/res/drawable-hdpi/ic_plus_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fd546fc71f91922d9e9e3d96203215b64acb685
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_black_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_plus_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a027972b1b6ceb2c3d8902476a6a1545cbb67940
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_black_48dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_grey600_18dp.png b/app/src/main/res/drawable-hdpi/ic_plus_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..8443f1e45755f57c7058020331445c9ad3c51f72
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_grey600_24dp.png b/app/src/main/res/drawable-hdpi/ic_plus_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..222a87061ce8a06a1875e0cb26658a74ce7e66ce
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_grey600_36dp.png b/app/src/main/res/drawable-hdpi/ic_plus_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e97e48b0f74eb2bc742bdcc7587ace2581940691
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_grey600_48dp.png b/app/src/main/res/drawable-hdpi/ic_plus_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e391e38dc6738841ff37559cce352e77f64b9dc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_white_18dp.png b/app/src/main/res/drawable-hdpi/ic_plus_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3810a02c45693167cf843b1e72487e731ac222e4
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_white_18dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_plus_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0526ce66b1960939a0ed283d4a42689253a8714
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_white_36dp.png b/app/src/main/res/drawable-hdpi/ic_plus_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..65d18bd42979510158242b204df745bbc292ae98
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_white_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_plus_white_48dp.png b/app/src/main/res/drawable-hdpi/ic_plus_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..05025234025a38251a45b800ed5ad293e118c9d9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_plus_white_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_18dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..6396e98533d41fa58b94cdf2ab7d2466aa18e104
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b18a76c4db21c72ab6dcc30094c05bb49f107e1f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_36dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ad3e5cf6cbc147ca3607b2819e13d0c99c3be8e
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_48dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..17ac4e4611345e1d4f4ec653ab56e2ab7c589c0d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_black_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_18dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..31b6452e3ab9eb7582ecf032db4b25e1eb9b41e4
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_24dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b50a64d15b5480b310a1d4ee610364d97796fb93
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_36dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbef1c912f88dac2b45f28f988c19e288eb22606
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_48dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d10123ffacb7b88f8b9040aeecb6845960a6f89
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_18dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f1d18784d9b753d57e4331b145791bdc7b331bf
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bd05c46dd698de335bb0b02796343f1a4797614
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..1af6cf1af5b21ccc38852a2e890e644b3518353d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_48dp.png b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..67ac4cbff302cf607e4615ebdd70ae6eb4ff6f0b
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_dice_5_outline_white_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_black_18dp.png b/app/src/main/res/drawable-mdpi/ic_plus_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..02918f5fe0635a979fcafa29c97ffa3d766e7893
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_black_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_plus_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8e9e935ffbdaf3800d1aeb208cb47742e0e345d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_black_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_black_36dp.png b/app/src/main/res/drawable-mdpi/ic_plus_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3e4b1d09cbf8caa2e8390a1c54bd895111a823d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_black_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_black_48dp.png b/app/src/main/res/drawable-mdpi/ic_plus_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..514840e66bd21232d6f28aa5a6ed9468fe8ef220
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_black_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_grey600_18dp.png b/app/src/main/res/drawable-mdpi/ic_plus_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..802d737d4b7a2d8d31c079e4672aa15181d69611
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_grey600_24dp.png b/app/src/main/res/drawable-mdpi/ic_plus_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..91feaa13ddd2452a76e21ad6b0605ed8d5ab853a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_grey600_36dp.png b/app/src/main/res/drawable-mdpi/ic_plus_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..222a87061ce8a06a1875e0cb26658a74ce7e66ce
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_grey600_48dp.png b/app/src/main/res/drawable-mdpi/ic_plus_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d1896db6d15c1d0f1b7211914f2398ec1001964
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_white_18dp.png b/app/src/main/res/drawable-mdpi/ic_plus_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a724b4bcd78d131f7d75b9d14ec8b3760739a10
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_white_18dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_plus_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3e9ee77773abc7cff10944972c489ae2314e4d2
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_plus_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0526ce66b1960939a0ed283d4a42689253a8714
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_white_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_plus_white_48dp.png b/app/src/main/res/drawable-mdpi/ic_plus_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3eadc0c888b4fc4865a9b1bf5e26c915e3d0e4d8
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_plus_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_18dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ad3e5cf6cbc147ca3607b2819e13d0c99c3be8e
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..17ac4e4611345e1d4f4ec653ab56e2ab7c589c0d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_36dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..15b263d6a9da827f6e56862dd3e514ba57a6f07d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a6216b56472768ef3b0f0227707621a1889d913
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_18dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbef1c912f88dac2b45f28f988c19e288eb22606
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_24dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d10123ffacb7b88f8b9040aeecb6845960a6f89
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_36dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb87f9035d56ee97a5d0e4f02df9863a3cf1e1dc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_48dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0653a4d588dc7820e3425064c3e4d047f276884a
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_18dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..1af6cf1af5b21ccc38852a2e890e644b3518353d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..67ac4cbff302cf607e4615ebdd70ae6eb4ff6f0b
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..10c889b99c7ebbf92c45759f0112a777ddae9113
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_48dp.png b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c6a7b61c2721614272fa5a728f8b60aa975c098
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_dice_5_outline_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_black_18dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3e4b1d09cbf8caa2e8390a1c54bd895111a823d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..514840e66bd21232d6f28aa5a6ed9468fe8ef220
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_black_36dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a027972b1b6ceb2c3d8902476a6a1545cbb67940
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39991c3d99f579c5700497721133f5ef114e574
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_grey600_18dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..222a87061ce8a06a1875e0cb26658a74ce7e66ce
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_grey600_24dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d1896db6d15c1d0f1b7211914f2398ec1001964
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_grey600_36dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e391e38dc6738841ff37559cce352e77f64b9dc
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_grey600_48dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e723f8343634b19c4bc14a6b0d7a6840c248944c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_white_18dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0526ce66b1960939a0ed283d4a42689253a8714
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3eadc0c888b4fc4865a9b1bf5e26c915e3d0e4d8
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..05025234025a38251a45b800ed5ad293e118c9d9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_plus_white_48dp.png b/app/src/main/res/drawable-xhdpi/ic_plus_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4db8ecf23448ff52e568c44355249d2de719f4c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_plus_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..60d08dbb6964ead8e0b04e20e80b0076ad092b1d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..15b263d6a9da827f6e56862dd3e514ba57a6f07d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c55bf9a4c468b8a998bcf3cc8e8032246b5634a5
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b7831b8745b81e4b8223576af556223803da9a0
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8acb444883d8c4ee39e2d26f332640f5c0d1f4d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb87f9035d56ee97a5d0e4f02df9863a3cf1e1dc
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..862e83e0407903c5b77c124fb16430d01f7d805a
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0e8c18d7cc75021d4d9a367378b79f967a04cb0
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..83b6af1cfb4c6f8289ec4219bf35ea566d61d495
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..10c889b99c7ebbf92c45759f0112a777ddae9113
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..dadeaf892f544def35aac4860d1526c75d03ad38
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4a19052325ff1c2d375e9bde3cd30aef28226e2
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_dice_5_outline_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_black_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fd546fc71f91922d9e9e3d96203215b64acb685
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a027972b1b6ceb2c3d8902476a6a1545cbb67940
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_black_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..6344724836028776d6cb8e3a4cea701f53bf0a79
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_black_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..8187b4d1221936b976956df25b7cc89e37358a54
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e97e48b0f74eb2bc742bdcc7587ace2581940691
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e391e38dc6738841ff37559cce352e77f64b9dc
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..193dc2e9747d1e5dfe554129683e471ca6d29fd3
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e993a737774a3ad1724d366bb85875d255914499
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_white_18dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..65d18bd42979510158242b204df745bbc292ae98
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..05025234025a38251a45b800ed5ad293e118c9d9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bac3f0dc301330e9e715ad5ac6c7cb9ab0c3b8b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_plus_white_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_plus_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9d19a15a7b628f1cd4034e8f477629de32db5ca
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_plus_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..15b263d6a9da827f6e56862dd3e514ba57a6f07d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0a6216b56472768ef3b0f0227707621a1889d913
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b7831b8745b81e4b8223576af556223803da9a0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd7f49a21d873300b15b906008533bf2c931a697
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb87f9035d56ee97a5d0e4f02df9863a3cf1e1dc
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0653a4d588dc7820e3425064c3e4d047f276884a
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0e8c18d7cc75021d4d9a367378b79f967a04cb0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..74b95fd60a27d81c852a65b72b9d4410c45941c8
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..10c889b99c7ebbf92c45759f0112a777ddae9113
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c6a7b61c2721614272fa5a728f8b60aa975c098
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4a19052325ff1c2d375e9bde3cd30aef28226e2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..010284f895ff271fd5d1543027bccc7decf54048
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_dice_5_outline_white_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_black_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a027972b1b6ceb2c3d8902476a6a1545cbb67940
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39991c3d99f579c5700497721133f5ef114e574
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_black_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..71ee250ff0ccfb1a0a2c4c4bfaafc75efd6449ee
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..684fcfc01a325077ebb759becbab6bd897e0e123
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_black_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e391e38dc6738841ff37559cce352e77f64b9dc
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..e723f8343634b19c4bc14a6b0d7a6840c248944c
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c023f8c802f65f4637b81bed90488a68b68dd26
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..728998eb0394ae234e43c633f0dbf651f46dd593
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_grey600_48dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_white_18dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_18dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..05025234025a38251a45b800ed5ad293e118c9d9
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_18dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_24dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..b336422c271970456f2b6f09d65ebadfdc2fffae
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_36dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0326d233396df678291041e2e598bed8b851d0e2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_plus_white_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..0495b97f867045cd5fdca680a6df7e94de00c4a0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_plus_white_48dp.png differ
diff --git a/app/src/main/res/drawable/dice_5_outline.xml b/app/src/main/res/drawable/dice_5_outline.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a8bbbd90aff92f41ef2be2abfac8f4223758c663
--- /dev/null
+++ b/app/src/main/res/drawable/dice_5_outline.xml
@@ -0,0 +1,8 @@
+<!-- drawable/dice-5-outline.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#000" android:pathData="M19 5V19H5V5H19M19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3M7.5 6C6.7 6 6 6.7 6 7.5S6.7 9 7.5 9 9 8.3 9 7.5 8.3 6 7.5 6M16.5 15C15.7 15 15 15.7 15 16.5C15 17.3 15.7 18 16.5 18C17.3 18 18 17.3 18 16.5C18 15.7 17.3 15 16.5 15M16.5 6C15.7 6 15 6.7 15 7.5S15.7 9 16.5 9C17.3 9 18 8.3 18 7.5S17.3 6 16.5 6M12 10.5C11.2 10.5 10.5 11.2 10.5 12S11.2 13.5 12 13.5 13.5 12.8 13.5 12 12.8 10.5 12 10.5M7.5 15C6.7 15 6 15.7 6 16.5C6 17.3 6.7 18 7.5 18S9 17.3 9 16.5C9 15.7 8.3 15 7.5 15Z" />
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/plus.xml b/app/src/main/res/drawable/plus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe500883a43e8551442e7c9282d6a2538de1f13f
--- /dev/null
+++ b/app/src/main/res/drawable/plus.xml
@@ -0,0 +1,8 @@
+<!-- drawable/plus.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path android:fillColor="#000" android:pathData="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 367b4f3779cb75b882922249f116c6b53d9936cc..62456f373621490da5a2005475dbaa42831852fd 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -4,6 +4,7 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/fabAddCharacter"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".MainActivity">
@@ -18,31 +19,21 @@
             android:id="@+id/toolbar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            app:popupTheme="@style/Theme.DndSpells.PopupOverlay"/>
+            app:title="@string/select_your_character"
+            app:popupTheme="@style/Theme.DndSpells.PopupOverlay" />
 
     </com.google.android.material.appbar.AppBarLayout>
 
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/select_your_character"
-        android:textSize="32sp"
-        app:layout_constraintBottom_toTopOf="@+id/rvCharacterList"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
     <androidx.recyclerview.widget.RecyclerView
 
         android:id="@+id/rvCharacterList"
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:layout_marginTop="150dp"
+        app:layoutManager="LinearLayoutManager"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layoutManager="LinearLayoutManager">
+        app:layout_constraintTop_toBottomOf="@+id/main_appbar">
 
     </androidx.recyclerview.widget.RecyclerView>
 
diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml
deleted file mode 100644
index aedecc2e041970bb0cb195f8a451a724d820cc26..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/activity_profile.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".ProfileActivity">
-
-    <TextView
-        android:id="@+id/tvCharacterName"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        tools:text="Klattic"
-        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
-        android:transitionName="character_name"
-        app:layout_constraintBottom_toBottomOf="@+id/imCharacterArt"
-        app:layout_constraintEnd_toStartOf="@+id/imCharacterArt"
-        app:layout_constraintHorizontal_bias="0.465"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/imCharacterArt" />
-
-    <ImageView
-        android:id="@+id/imCharacterArt"
-        android:transitionName="character_art"
-
-        android:layout_width="106dp"
-        android:layout_height="104dp"
-        android:layout_marginTop="24dp"
-        android:layout_marginEnd="24dp"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:srcCompat="@drawable/dnd_logo" />
-
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/rvSpellList"
-        android:layout_width="409dp"
-        android:layout_height="601dp"
-        android:layout_marginStart="16dp"
-        android:layout_marginTop="24dp"
-        android:layout_marginEnd="16dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/imCharacterArt" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/recyclerview_main_menu_row.xml b/app/src/main/res/layout/recyclerview_main_menu_row.xml
index efa6c1bb1214ccfd98a36488a4a3884f4eec8ff3..14880c6dc364f37284c164e2abb61fbd1bf1877c 100644
--- a/app/src/main/res/layout/recyclerview_main_menu_row.xml
+++ b/app/src/main/res/layout/recyclerview_main_menu_row.xml
@@ -26,22 +26,8 @@
         android:layout_height="wrap_content"
         android:layout_marginStart="32dp"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/imCharacterArt"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/tvCharacterName"
         tools:text="level 6 paladin" />
 
-    <ImageView
-        android:id="@+id/imCharacterArt"
-        android:layout_width="150dp"
-        android:layout_height="0dp"
-        android:layout_marginEnd="16dp"
-        android:transitionName="character_art"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-
-        android:contentDescription="@string/character_avatar_of"
-        tools:srcCompat="@drawable/dnd_logo" />
-
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/recyclerview_spell_row.xml b/app/src/main/res/layout/recyclerview_spell_row.xml
deleted file mode 100644
index 63b2a8d6af31675c4ce371c91785565f43ee5431..0000000000000000000000000000000000000000
--- a/app/src/main/res/layout/recyclerview_spell_row.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <TextView
-        android:id="@+id/tvSpellName"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="32dp"
-        android:layout_marginTop="16dp"
-        android:textSize="28sp"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:text="Power word kill" />
-
-    <TextView
-        android:id="@+id/SpellLevel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="32dp"
-        android:textSize="28sp"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/tvSpellName"
-        tools:text="Level 9" />
-
-
-    <TextView
-        android:id="@+id/SpellSchool"
-        android:layout_width="wrap_content"
-        android:layout_height="27dp"
-        android:layout_marginStart="32dp"
-        android:layout_marginTop="8dp"
-        android:layout_marginBottom="8dp"
-        android:textSize="20sp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/tvSpellName"
-        app:layout_constraintVertical_bias="1.0"
-        tools:text="school" />
-
-    <TextView
-        android:id="@+id/SpellComponents"
-        android:layout_width="0dp"
-        android:layout_height="19dp"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="32dp"
-        android:layout_marginBottom="16dp"
-        android:ellipsize="end"
-        android:maxLines="1"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toEndOf="@id/SpellSchool"
-        app:layout_constraintTop_toBottomOf="@+id/SpellLevel"
-        app:layout_constraintVertical_bias="1.0"
-        tools:text="ComponentsComponentsComponentsComponentsComponents" />
-
-
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/readme.txt b/app/src/main/res/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f8a80f65331f4c868cc8b09626137168ecb06490
--- /dev/null
+++ b/app/src/main/res/readme.txt
@@ -0,0 +1,5 @@
+Thanks for visiting MaterialDesignIcons.com
+Check back often for new icons and follow @MaterialIcons for updates.
+
+Icon: dice-5-outline
+By: Michael Irigoyen
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cedd03aad4eb3bf3ee03b28d4ab0f27808c6660c..ef08bb79d779b3b63558f628b96f91ce854abe84 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,7 +17,11 @@
     <string name="add_new_character">Add New Character</string>
     <string name="title_activity_character_details">CharacterDetailsActivity</string>
     <string name="title_activity_select_spells">SelectSpellsActivity</string>
-    <string name="select_spells">\" - select spells\"</string>
+    <string name="select_spells">- select spells</string>
     <string name="title_activity_ruinable">RuinableActivity</string>
     <string name="modify_character">Modify Character</string>
+    <string name="filter_components">Filter Components</string>
+    <string name="filter_spell_level">Filter Spell Level</string>
+    <string name="spell_name">Spell Name</string>
+    <string name="you_rolled">You rolled:</string>
 </resources>
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 910dc1b231d7db66fda085ab792ef47c7a73cd00..3af8e665a749899c24b8a67c0535d89e2be373c4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,8 @@
 buildscript {
     ext {
         kotlin_version = '1.6.0'
-        compose_version = '1.1.0-beta04'
+        compose_version = '1.1.0-rc01'
+        agp_version = '7.0.4'
     }
 
     repositories {
@@ -11,7 +12,8 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.0.4'
+        classpath "com.android.tools.build:gradle:$agp_version"
+        classpath "com.google.gms:google-services:4.3.10"
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
         classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
 
diff --git a/changes.md b/changes.md
new file mode 100644
index 0000000000000000000000000000000000000000..cb1fdf2f7b83e798f3c7bee224f08c8e2ca3d512
--- /dev/null
+++ b/changes.md
@@ -0,0 +1,9 @@
+- ne json serialize
+- szürcs
+  - level
+  - név
+- slotok
+- roll
+- character edit
+- doksi (szkrínsot, meg ilyenek, funkciók használata)
+- permission helyes kezelése
\ No newline at end of file
diff --git a/doc/Screenshots/Screenshot_20211217_140502.png b/doc/Screenshots/Screenshot_20211217_140502.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7d91824ab1432b871c9e222d1de146cc42c911a
Binary files /dev/null and b/doc/Screenshots/Screenshot_20211217_140502.png differ
diff --git a/doc/Screenshots/Screenshot_20211217_142305.png b/doc/Screenshots/Screenshot_20211217_142305.png
new file mode 100644
index 0000000000000000000000000000000000000000..4465b5acdb392c76f3ff7554f398455eb6a70ae2
Binary files /dev/null and b/doc/Screenshots/Screenshot_20211217_142305.png differ
diff --git a/doc/Screenshots/Screenshot_20211217_145142.png b/doc/Screenshots/Screenshot_20211217_145142.png
new file mode 100644
index 0000000000000000000000000000000000000000..37cac1ba9585cabc8237616233373118fd4f8fc6
Binary files /dev/null and b/doc/Screenshots/Screenshot_20211217_145142.png differ
diff --git a/doc/Screenshots/characterscreen.jpg b/doc/Screenshots/characterscreen.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b3890f6a24855cfb7b5729737ef9f27f2f0e9acd
Binary files /dev/null and b/doc/Screenshots/characterscreen.jpg differ
diff --git a/doc/Screenshots/selectscreen.jpg b/doc/Screenshots/selectscreen.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..8f119e94399d4f35be65615f12a7c619a1a3a89b
Binary files /dev/null and b/doc/Screenshots/selectscreen.jpg differ
diff --git a/doc/Screenshots/spellscreen.jpg b/doc/Screenshots/spellscreen.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a3164f51cf651fc8e5817beb58e686605af35bd7
Binary files /dev/null and b/doc/Screenshots/spellscreen.jpg differ
diff --git a/doc/android-doc.org b/doc/android-doc.org
new file mode 100644
index 0000000000000000000000000000000000000000..973b1e2e30ed4fcd9a68c7ef87175426189758e0
--- /dev/null
+++ b/doc/android-doc.org
@@ -0,0 +1,87 @@
+#+TITLE: D&D Spellbook Alkalmazás Dokimentáció
+#+author: Pálvölgyi Domonkos (FBYGH3)
+#+date: 2021-12-17
+#+LATEX_HEADER: \usepackage{placeins}
+
+* Röviden az alkalmazásról
+
+A play storeon van már néhány alkalmazás ami a Dungeons & Dragaons játékosok életét könnyebbíti meg, viszont ezek nagy része a funkciók java részét előfizetés mögé zárja.
+
+Az én alkalmazásom nagyon egyszerű, átlátható és nem utolsó sorban natív teljesítménnyel fog bírni.
+
+Az alkalmazást olyanoknak szánom, akik:
+ 1. Nem szeretnek előfizetéses modellben gondolkodni.
+ 2. Kis méretű és komplexitású programot szeretnének használni.
+ 3. Preferálják a FOSS alkalmazásokat.
+
+* Specifikáció
+1. Az alkalmazásban karaktereket táolunk és hozzájuk kapcsolódó spelleket, illetve egy nagy listát az összes elérhető.
+2. A spellek importálhatóak XML formátumból (kompatibilis a FightClub alkalmazás formátumával).
+3. Karakterekhez spelleket tudunk renelni.
+4. Ha a spellhez tartozik kockadobás, azt el tudjuk végezni.
+5. Amikor egy karakterhez hozzárendelünk spelleket, tudunk keresni és osztály illetve komponensek alapján szűrni is.
+6. Az alkalmazás támogatja az Android Light/Dark témáját.
+
+* Bemutatás
+** Főképernyő
+*** Karakterek listája
+#+caption: Főképernyő
+#+ATTR_LATEX: :height 0.4\textwidth
+[[./Screenshots/Screenshot_20211217_140502.png]]
+
+A főképernyőn a karakterek vannak kilistázva, akiket a felhasználó felvett.
+Ha a karakterre kattintunk, megnyitja a details nézetét, ami hozzá tartozik, és ahol a spelleket lehet nézni.
+Ha a kakakteren hosszan kattintunk, akkor a karaktermódosító képernyő jelenik meg.
+\FloatBarrier
+*** Menü
+#+caption: Főképernyőn lévő menü
+#+ATTR_LATEX: :height 0.4\textwidth
+[[./Screenshots/Screenshot_20211217_142305.png]]
+
+\FloatBarrier
+A főképernyőn lévő menübpl lehet új karaktert létrehozni és a spellek listáját importálni.
+** Karakter hozzáadása, módisítása
+#+caption: Karakterkészítési képernyő
+#+ATTR_LATEX: :height 0.4\textwidth
+[[./Screenshots/Screenshot_20211217_145142.png]]
+
+\FloatBarrier
+A karakter hozzáadás képernyőn hozzáadhatunk az adatbázishoz egy új karaktert, névvel, classzal és szinttel.
+
+A FloatingActionButton megnyomásakor az alkalmazás ellenőrzi hogy érvényes-e a karakter.
+Ha a karakter nem érvényes, akkor egy üzenetben jelzi ezt a felhasználónak.
+
+Ha módosításként nyitottuk meg a képernyőt akkor amelyik értéket megváltoztatjuk, csak az fog megváltozni a kakakteren.
+** Karakterképernyő
+#+caption: Karakterképernyő
+#+ATTR_LATEX: :height 0.4\textwidth
+[[./Screenshots/characterscreen.jpg]]
+
+\FloatBarrier
+A karakterképernyőn láthatjuk a karakterhez tartozó spelleket.
+A bal oldalon a karakterhez még nem vettünk fel semmit, a jobb oldalon viszont már felvettüjk 2 db hármas szintű varázslatot.
+
+Az egyik spell neve mellett van egy dobókocka. Ez azt jelenti, hogy a spellhez tartozik kockadobás is.
+A kocka ikonra kattintva kidobhatjuk ennek az értékét.
+
+** Spell képernyő
+#+caption: 2 különböző spell képernyő
+#+attr_latex: :height 0.4\textwidth
+[[./Screenshots/spellscreen.jpg]]
+
+\FloatBarrier
+Az előbbi 2 spell részletező képernyőji.
+Hasonló elven, mivel a Call Lightning spell tartalmaz kockadobást, itt is el tudjuk dobni a kockát, aminek az eredménye ugyan olyan snackbarban jelenik meg.
+** Spell kereső képernyő
+
+#+caption: Spellkereső
+#+attr_latex: :height 0.4\textwidth
+[[./Screenshots/selectscreen.jpg]]
+
+\FloatBarrier
+Az add spells képernyőn keresketünk és szűrhetünk spelleket, majd hozzá is adhatjuk a karakterünkhöz.
+
+A kereső tud:
+- keresni a spell nevére
+- szűrni a spell szintjére
+- szűrni a spell komponenseire
diff --git a/doc/android-doc.pdf b/doc/android-doc.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..95c7296293bd4ee45ea70513f81ef5a5606cfc5d
Binary files /dev/null and b/doc/android-doc.pdf differ
diff --git a/doc/android-doc.tex b/doc/android-doc.tex
new file mode 100644
index 0000000000000000000000000000000000000000..7c4bf2928e0b61024c5121732e516965dba746d8
--- /dev/null
+++ b/doc/android-doc.tex
@@ -0,0 +1,142 @@
+% Created 2021-12-17 Fri 15:34
+% Intended LaTeX compiler: pdflatex
+\documentclass[11pt]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{graphicx}
+\usepackage{longtable}
+\usepackage{wrapfig}
+\usepackage{rotating}
+\usepackage[normalem]{ulem}
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{capt-of}
+\usepackage{hyperref}
+\usepackage{placeins}
+\author{Pálvölgyi Domonkos (FBYGH3)}
+\date{2021-12-17}
+\title{D\&D Spellbook Alkalmazás Dokimentáció}
+\hypersetup{
+ pdfauthor={Pálvölgyi Domonkos (FBYGH3)},
+ pdftitle={D\&D Spellbook Alkalmazás Dokimentáció},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 27.2 (Org mode 9.6)}, 
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+\tableofcontents
+
+
+\section{Röviden az alkalmazásról}
+\label{sec:org8561d27}
+
+A play storeon van már néhány alkalmazás ami a Dungeons \& Dragaons játékosok életét könnyebbíti meg, viszont ezek nagy része a funkciók java részét előfizetés mögé zárja.
+
+Az én alkalmazásom nagyon egyszerű, átlátható és nem utolsó sorban natív teljesítménnyel fog bírni.
+
+Az alkalmazást olyanoknak szánom, akik:
+\begin{enumerate}
+\item Nem szeretnek előfizetéses modellben gondolkodni.
+\item Kis méretű és komplexitású programot szeretnének használni.
+\item Preferálják a FOSS alkalmazásokat.
+\end{enumerate}
+
+\section{Specifikáció}
+\label{sec:orgfb557ae}
+\begin{enumerate}
+\item Az alkalmazásban karaktereket táolunk és hozzájuk kapcsolódó spelleket, illetve egy nagy listát az összes elérhető.
+\item A spellek importálhatóak XML formátumból (kompatibilis a FightClub alkalmazás formátumával).
+\item Karakterekhez spelleket tudunk renelni.
+\item Ha a spellhez tartozik kockadobás, azt el tudjuk végezni.
+\item Amikor egy karakterhez hozzárendelünk spelleket, tudunk keresni és osztály illetve komponensek alapján szűrni is.
+\item Az alkalmazás támogatja az Android Light/Dark témáját.
+\end{enumerate}
+
+\section{Bemutatás}
+\label{sec:org1c4121f}
+\subsection{Főképernyő}
+\label{sec:orgf51912f}
+\subsubsection{Karakterek listája}
+\label{sec:org7688390}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/Screenshot_20211217_140502.png}
+\caption{Főképernyő}
+\end{figure}
+
+A főképernyőn a karakterek vannak kilistázva, akiket a felhasználó felvett.
+Ha a karakterre kattintunk, megnyitja a details nézetét, ami hozzá tartozik, és ahol a spelleket lehet nézni.
+Ha a kakakteren hosszan kattintunk, akkor a karaktermódosító képernyő jelenik meg.
+\FloatBarrier
+\subsubsection{Menü}
+\label{sec:orgdbc40de}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/Screenshot_20211217_142305.png}
+\caption{Főképernyőn lévő menü}
+\end{figure}
+
+\FloatBarrier
+A főképernyőn lévő menübpl lehet új karaktert létrehozni és a spellek listáját importálni.
+\subsection{Karakter hozzáadása, módisítása}
+\label{sec:org71d9680}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/Screenshot_20211217_145142.png}
+\caption{Karakterkészítési képernyő}
+\end{figure}
+
+\FloatBarrier
+A karakter hozzáadás képernyőn hozzáadhatunk az adatbázishoz egy új karaktert, névvel, classzal és szinttel.
+
+A FloatingActionButton megnyomásakor az alkalmazás ellenőrzi hogy érvényes-e a karakter.
+Ha a karakter nem érvényes, akkor egy üzenetben jelzi ezt a felhasználónak.
+
+Ha módosításként nyitottuk meg a képernyőt akkor amelyik értéket megváltoztatjuk, csak az fog megváltozni a kakakteren.
+\subsection{Karakterképernyő}
+\label{sec:org55447fb}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/characterscreen.jpg}
+\caption{Karakterképernyő}
+\end{figure}
+
+\FloatBarrier
+A karakterképernyőn láthatjuk a karakterhez tartozó spelleket.
+A bal oldalon a karakterhez még nem vettünk fel semmit, a jobb oldalon viszont már felvettüjk 2 db hármas szintű varázslatot.
+
+Az egyik spell neve mellett van egy dobókocka. Ez azt jelenti, hogy a spellhez tartozik kockadobás is.
+A kocka ikonra kattintva kidobhatjuk ennek az értékét.
+
+\subsection{Spell képernyő}
+\label{sec:orgc7255f2}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/spellscreen.jpg}
+\caption{2 különböző spell képernyő}
+\end{figure}
+
+\FloatBarrier
+Az előbbi 2 spell részletező képernyőji.
+Hasonló elven, mivel a Call Lightning spell tartalmaz kockadobást, itt is el tudjuk dobni a kockát, aminek az eredménye ugyan olyan snackbarban jelenik meg.
+\subsection{Spell kereső képernyő}
+\label{sec:org3ed6803}
+
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=0.4\textwidth]{./Screenshots/selectscreen.jpg}
+\caption{Spellkereső}
+\end{figure}
+
+\FloatBarrier
+Az add spells képernyőn keresketünk és szűrhetünk spelleket, majd hozzá is adhatjuk a karakterünkhöz.
+
+A kereső tud:
+\begin{itemize}
+\item keresni a spell nevére
+\item szűrni a spell szintjére
+\item szűrni a spell komponenseire
+\end{itemize}
+\end{document}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 10f8d6bf3c743680ef41ef0ea73774722edcb1be..fa44eebf7e962f01625aa762de71cdc4175015f9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Nov 07 11:54:24 CET 2021
+#Sun Dec 19 23:09:51 CET 2021
 distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip
 distributionPath=wrapper/dists
 zipStorePath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME