diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/RATProfileSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/RATProfileSettings.kt
index a9169309856e9b587dcf33eda9217066c637d026..c432743863efcaa82a5a02e6ee639e9c6babf88d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/RATProfileSettings.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/RATProfileSettings.kt
@@ -1,10 +1,10 @@
 package de.rki.coronawarnapp.coronatest.antigen.profile
 
 import android.content.Context
+import androidx.core.content.edit
 import com.google.gson.Gson
 import dagger.Reusable
 import de.rki.coronawarnapp.util.di.AppContext
-import de.rki.coronawarnapp.util.preferences.clearAndNotify
 import de.rki.coronawarnapp.util.preferences.createFlowPreference
 import de.rki.coronawarnapp.util.serialization.BaseGson
 import de.rki.coronawarnapp.util.serialization.fromJson
@@ -35,9 +35,17 @@ class RATProfileSettings @Inject constructor(
         }
     )
 
-    fun clear() = prefs.clearAndNotify()
+    val onboarded = prefs.createFlowPreference(
+        key = PREFS_KEY_ONBOARDED,
+        defaultValue = false
+    )
+
+    fun deleteProfile() = prefs.edit(commit = true) {
+        remove(PREFS_KEY_PROFILE)
+    }
 
     companion object {
         private const val PREFS_KEY_PROFILE = "ratprofile.settings.profile"
+        private const val PREFS_KEY_ONBOARDED = "ratprofile.settings.onboarded"
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCard.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCard.kt
new file mode 100644
index 0000000000000000000000000000000000000000..619587bd95a11a71a285a4095499c1a5d1af4bf5
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCard.kt
@@ -0,0 +1,51 @@
+package de.rki.coronawarnapp.coronatest.antigen.profile
+
+import dagger.Reusable
+import de.rki.coronawarnapp.util.TimeStamper
+import org.joda.time.format.ISODateTimeFormat
+import javax.inject.Inject
+
+@Reusable
+class VCard @Inject constructor(
+    private val timeStamper: TimeStamper
+) {
+
+    /**
+     * Return V-Card format for [RATProfile]
+     * @return [String]
+     */
+    fun create(ratProfile: RATProfile): String = ratProfile.run {
+        val lastName = lastName.escapeAll()
+        val firstName = firstName.escapeAll()
+        val fullName = buildString {
+            append(firstName)
+            if (lastName.isNotBlank()) {
+                append(" $lastName")
+            }
+        }
+        val city = city.escapeAll()
+        val street = street.escapeAll()
+        val zipCode = zipCode.escapeAll()
+        val phone = phone.escapeAll()
+        val email = email.escapeAll()
+        val birthDate = birthDate?.toString(ISODateTimeFormat.basicDate()).orEmpty()
+        val rev = timeStamper.nowUTC.toString(ISODateTimeFormat.basicDateTimeNoMillis()) // Time the vCard was updated
+        """
+            BEGIN:VCARD
+            VERSION:4.0
+            N:$lastName;$firstName;;;
+            FN:$fullName
+            BDAY:$birthDate
+            EMAIL;TYPE=home:$email
+            TEL;TYPE="cell,home":$phone
+            ADR;TYPE=home:;;$street;$city;;$zipCode
+            REV:$rev
+            END:VCARD
+        """.trimIndent()
+    }
+
+    private fun String.escapeAll(): String = replace("\n", "")
+        .replace("\\", "\\\\")
+        .replace(",", "\\,")
+        .replace(";", "\\;")
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/RATProfileUIModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/RATProfileUIModule.kt
index 21a76225622d3fe5375e956e10c0bd7507114bb4..61208100d9be7ddcd09c80be0639ca7773fda25b 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/RATProfileUIModule.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/RATProfileUIModule.kt
@@ -4,10 +4,20 @@ import dagger.Module
 import dagger.android.ContributesAndroidInjector
 import de.rki.coronawarnapp.ui.coronatest.rat.profile.create.RATProfileCreateFragment
 import de.rki.coronawarnapp.ui.coronatest.rat.profile.create.RATProfileCreateFragmentModule
+import de.rki.coronawarnapp.ui.coronatest.rat.profile.onboarding.RATProfileOnboardingFragment
+import de.rki.coronawarnapp.ui.coronatest.rat.profile.onboarding.RATProfileOnboardingFragmentModule
+import de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode.RATProfileQrCodeFragment
+import de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode.RATProfileQrCodeFragmentModule
 
 @Module
 internal abstract class RATProfileUIModule {
 
     @ContributesAndroidInjector(modules = [RATProfileCreateFragmentModule::class])
     abstract fun ratProfileCreateFragment(): RATProfileCreateFragment
+
+    @ContributesAndroidInjector(modules = [RATProfileQrCodeFragmentModule::class])
+    abstract fun ratProfileQrCodeFragment(): RATProfileQrCodeFragment
+
+    @ContributesAndroidInjector(modules = [RATProfileOnboardingFragmentModule::class])
+    abstract fun ratProfileOnboardingFragment(): RATProfileOnboardingFragment
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragment.kt
index 8d32df661e7f5e6e1d971edf6c3c842de2e9b356..2ef3dcaca4e697d9a5cdcfa6f27bbc309cea85eb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragment.kt
@@ -40,6 +40,11 @@ class RATProfileCreateFragment : Fragment(R.layout.rat_profile_create_fragment),
 
             // Birth date
             birthDateInputEdit.setOnClickListener { openDatePicker() }
+            birthDateInputEdit.doAfterTextChanged {
+                if (it.toString().isBlank()) {
+                    viewModel.birthDateChanged(null)
+                }
+            }
 
             // Address
             streetInputEdit.doAfterTextChanged { viewModel.streetChanged(it.toString()) }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragmentViewModel.kt
index 36ca71e288a1a5d80f7ae3fc88c57e7161ca3473..27861b540f066645e23703f9d8a43c8c6c3ca957 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragmentViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/create/RATProfileCreateFragmentViewModel.kt
@@ -41,7 +41,7 @@ class RATProfileCreateFragmentViewModel @AssistedInject constructor(
         }
     }
 
-    fun birthDateChanged(birthDate: LocalDate) {
+    fun birthDateChanged(birthDate: LocalDate?) {
         profileData.apply {
             value = value?.copy(birthDate = birthDate)
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragment.kt
index 62643cefb5f6d43906269e05f998ac422ad25a2d..bf3e0cb317ce6a714a2680a1b90f5282b3c18821 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragment.kt
@@ -5,18 +5,27 @@ import android.view.View
 import androidx.fragment.app.Fragment
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.RatProfileOnboardingFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
 import de.rki.coronawarnapp.util.ui.doNavigate
 import de.rki.coronawarnapp.util.ui.popBackStack
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
 
-class RATProfileOnboardingFragment : Fragment(R.layout.rat_profile_onboarding_fragment) {
+class RATProfileOnboardingFragment : Fragment(R.layout.rat_profile_onboarding_fragment), AutoInject {
 
     private val binding: RatProfileOnboardingFragmentBinding by viewBindingLazy()
 
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+
+    private val viewModel: RATProfileOnboardingFragmentViewModel by cwaViewModels { viewModelFactory }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) =
         with(binding) {
             toolbar.setNavigationOnClickListener { popBackStack() }
             nextButton.setOnClickListener {
+                viewModel.onNext()
                 doNavigate(
                     RATProfileOnboardingFragmentDirections
                         .actionRatProfileOnboardingFragmentToRatProfileCreateFragment()
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1b2bdad689f7a2064187143ab0a38b478dd51dbc
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.ui.coronatest.rat.profile.onboarding
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class RATProfileOnboardingFragmentModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(RATProfileOnboardingFragmentViewModel::class)
+    abstract fun ratProfileOnboardingFragment(
+        factory: RATProfileOnboardingFragmentViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0160a51dc00649b821b570ef84af638e5063de50
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/onboarding/RATProfileOnboardingFragmentViewModel.kt
@@ -0,0 +1,19 @@
+package de.rki.coronawarnapp.ui.coronatest.rat.profile.onboarding
+
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfileSettings
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+
+class RATProfileOnboardingFragmentViewModel @AssistedInject constructor(
+    private val ratProfileSettings: RATProfileSettings,
+) : CWAViewModel() {
+
+    fun onNext() {
+        ratProfileSettings.onboarded.update { true }
+    }
+
+    @AssistedFactory
+    interface Factory : SimpleCWAViewModelFactory<RATProfileOnboardingFragmentViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/ProfileQrCodeNavigation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/ProfileQrCodeNavigation.kt
new file mode 100644
index 0000000000000000000000000000000000000000..030aa4d4a7b6e8d06c5aca636d7f9b12c224250d
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/ProfileQrCodeNavigation.kt
@@ -0,0 +1,6 @@
+package de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode
+
+sealed class ProfileQrCodeNavigation {
+    object Back : ProfileQrCodeNavigation()
+    object SubmissionConsent : ProfileQrCodeNavigation()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragment.kt
index 4bc5b2120fed99eae14aca2a4a0458e45357461a..cedefa8d72b7ed4319d2c6d1bcda846703dc9931 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragment.kt
@@ -2,18 +2,106 @@ package de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode
 
 import android.os.Bundle
 import android.view.View
+import android.widget.LinearLayout
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.text.bold
+import androidx.core.text.buildSpannedString
 import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
+import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfile
 import de.rki.coronawarnapp.databinding.RatProfileQrCodeFragmentBinding
+import de.rki.coronawarnapp.util.di.AutoInject
+import de.rki.coronawarnapp.util.joinToSpannable
 import de.rki.coronawarnapp.util.ui.popBackStack
 import de.rki.coronawarnapp.util.ui.viewBindingLazy
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
+import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
+import javax.inject.Inject
+import kotlin.math.abs
 
-class RATProfileQrCodeFragment : Fragment(R.layout.rat_profile_qr_code_fragment) {
+class RATProfileQrCodeFragment : Fragment(R.layout.rat_profile_qr_code_fragment), AutoInject {
 
+    @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
+
+    private val viewModel: RATProfileQrCodeFragmentViewModel by cwaViewModels { viewModelFactory }
     private val binding: RatProfileQrCodeFragmentBinding by viewBindingLazy()
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        setToolbarOverlay()
+        binding.apply {
+            appBarLayout.addOnOffsetChangedListener(
+                AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
+                    val alpha = 1.0f - abs(verticalOffset / (appBarLayout.totalScrollRange.toFloat() * 0.5f))
+                    title.alpha = alpha
+                }
+            )
+
+            nextButton.setOnClickListener { viewModel.onNext() }
+            toolbar.setNavigationOnClickListener { viewModel.onClose() }
+            toolbar.setOnMenuItemClickListener {
+                confirmDeletionDialog()
+                true
+            }
+        }
+        viewModel.profile.observe(viewLifecycleOwner) { personProfile ->
+            with(binding) {
+                progressBar.hide()
+                personProfile.profile?.let { bindPersonInfo(it) }
+                qrCodeImage.setImageBitmap(personProfile.bitmap)
+            }
+        }
+
+        viewModel.events.observe(viewLifecycleOwner) {
+            when (it) {
+                ProfileQrCodeNavigation.Back -> popBackStack()
+                ProfileQrCodeNavigation.SubmissionConsent ->
+                    findNavController().navigate(R.id.submissionConsentFragment)
+            }
+        }
+    }
+
+    private fun confirmDeletionDialog() {
+        MaterialAlertDialogBuilder(requireContext())
+            .setTitle(getString(R.string.rat_qr_code_profile_dialog_title))
+            .setMessage(getString(R.string.rat_qr_code_profile_dialog_message))
+            .setPositiveButton(getString(R.string.rat_qr_code_profile_dialog_positive_button)) { _, _ ->
+                viewModel.deleteProfile()
+            }
+            .setNegativeButton(getString(R.string.rat_qr_code_profile_dialog_negative_button)) { _, _ ->
+                // No-Op
+            }
+            .show()
+    }
+
+    private fun bindPersonInfo(ratProfile: RATProfile) = with(ratProfile) {
+        val name = buildSpannedString { bold { append("$firstName $lastName") } }
+        val birthDate = birthDate?.let {
+            getString(
+                R.string.rat_qr_code_profile_birth_date,
+                birthDate.toString("dd.MM.yyyy").orEmpty()
+            )
+        }.orEmpty()
+
+        val address = "$zipCode $city"
+        binding.profileInfo.text = arrayOf(name, birthDate, street, address, phone, email)
+            .filter { it.isNotBlank() }
+            .joinToSpannable("\n")
+    }
+
+    private fun setToolbarOverlay() {
+        val width = requireContext().resources.displayMetrics.widthPixels
+
+        val params: CoordinatorLayout.LayoutParams = binding.nestedScrollView.layoutParams
+            as (CoordinatorLayout.LayoutParams)
+
+        val textParams = binding.title.layoutParams as (LinearLayout.LayoutParams)
+        textParams.bottomMargin = (width / 2) - 24 /* 24 is space between screen border and QrCode */
+        binding.title.requestLayout() /* 24 is space between screen border and QrCode */
 
-        binding.closeButton.setOnClickListener { popBackStack() }
+        val behavior: AppBarLayout.ScrollingViewBehavior = params.behavior as (AppBarLayout.ScrollingViewBehavior)
+        behavior.overlayTop = (width / 2) - 24
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b35a9dbd0d30474b9cc7f5a70f7ed867e4eb4c3c
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentModule.kt
@@ -0,0 +1,18 @@
+package de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
+
+@Module
+abstract class RATProfileQrCodeFragmentModule {
+    @Binds
+    @IntoMap
+    @CWAViewModelKey(RATProfileQrCodeFragmentViewModel::class)
+    abstract fun ratProfileQrCodeFragmentViewModel(
+        factory: RATProfileQrCodeFragmentViewModel.Factory
+    ): CWAViewModelFactory<out CWAViewModel>
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fad1095b4c4fffbf13b19fec30be729de5101e5d
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/coronatest/rat/profile/qrcode/RATProfileQrCodeFragmentViewModel.kt
@@ -0,0 +1,72 @@
+package de.rki.coronawarnapp.ui.coronatest.rat.profile.qrcode
+
+import android.graphics.Bitmap
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.asLiveData
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfile
+import de.rki.coronawarnapp.coronatest.antigen.profile.RATProfileSettings
+import de.rki.coronawarnapp.coronatest.antigen.profile.VCard
+import de.rki.coronawarnapp.presencetracing.checkins.qrcode.QrCodeGenerator
+import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
+import de.rki.coronawarnapp.util.ui.SingleLiveEvent
+import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
+import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
+import kotlinx.coroutines.flow.map
+import timber.log.Timber
+
+class RATProfileQrCodeFragmentViewModel @AssistedInject constructor(
+    private val ratProfileSettings: RATProfileSettings,
+    private val qrCodeGenerator: QrCodeGenerator,
+    private val vCard: VCard,
+    dispatcherProvider: DispatcherProvider,
+) : CWAViewModel() {
+
+    val profile: LiveData<PersonProfile> = ratProfileSettings.profile.flow
+        .map { profile ->
+            PersonProfile(
+                profile,
+                profile.qrCode()
+            )
+        }.asLiveData(context = dispatcherProvider.Default)
+
+    val events = SingleLiveEvent<ProfileQrCodeNavigation>()
+
+    fun deleteProfile() {
+        Timber.d("deleteProfile")
+        ratProfileSettings.deleteProfile()
+        events.postValue(ProfileQrCodeNavigation.Back)
+    }
+
+    fun onClose() {
+        Timber.d("onClose")
+        events.postValue(ProfileQrCodeNavigation.Back)
+    }
+
+    fun onNext() {
+        Timber.d("onNext")
+        events.postValue(ProfileQrCodeNavigation.SubmissionConsent)
+    }
+
+    private suspend fun RATProfile?.qrCode(): Bitmap? =
+        try {
+            if (this != null) {
+                qrCodeGenerator.createQrCode(vCard.create(this))
+            } else {
+                Timber.d("No Profile available")
+                null
+            }
+        } catch (e: Exception) {
+            Timber.e(e, "Failed to generate profile Qr Code")
+            null
+        }
+
+    @AssistedFactory
+    interface Factory : SimpleCWAViewModelFactory<RATProfileQrCodeFragmentViewModel>
+}
+
+data class PersonProfile(
+    val profile: RATProfile?,
+    val bitmap: Bitmap?
+)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt
index 3b16c6f61832089e3e981cf1d006eee4ad428890..11f7585630af3e8e2d67608088233528a34872d7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/fragment/SubmissionDispatcherFragment.kt
@@ -48,11 +48,17 @@ class SubmissionDispatcherFragment : Fragment(R.layout.fragment_submission_dispa
                         SubmissionDispatcherFragmentDirections
                             .actionSubmissionDispatcherFragmentToSubmissionConsentFragment()
                     )
-                is SubmissionNavigationEvents.NavigateToCreateProfile ->
+                is SubmissionNavigationEvents.NavigateToCreateProfile -> {
+                    val ratGraph = findNavController().graph.findNode(R.id.rapid_test_profile_nav_graph) as NavGraph
+                    ratGraph.startDestination = if (it.onboarded)
+                        R.id.ratProfileCreateFragment
+                    else R.id.ratProfileOnboardingFragment
+
                     doNavigate(
                         SubmissionDispatcherFragmentDirections
                             .actionSubmissionDispatcherFragmentToRapidTestProfileNavGraph()
                     )
+                }
 
                 is SubmissionNavigationEvents.NavigateToOpenProfile -> {
                     val ratGraph = findNavController().graph.findNode(R.id.rapid_test_profile_nav_graph) as NavGraph
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionDispatcherViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionDispatcherViewModel.kt
index c558190977261129100283f195602654df04c75f..09cffe765938860b3133b292988fee6779e76405 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionDispatcherViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionDispatcherViewModel.kt
@@ -48,7 +48,7 @@ class SubmissionDispatcherViewModel @AssistedInject constructor(
         val event = if (ratProfileSettings.profile.value != null) {
             SubmissionNavigationEvents.NavigateToOpenProfile
         } else {
-            SubmissionNavigationEvents.NavigateToCreateProfile
+            SubmissionNavigationEvents.NavigateToCreateProfile(ratProfileSettings.onboarded.value)
         }
         routeToScreen.postValue(event)
     }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionNavigationEvents.kt
index c9efab9912d83ee93da4bdb596965750dee6cbef..789a64d889cf8358ceb601e7694cb881073c22b3 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionNavigationEvents.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/viewmodel/SubmissionNavigationEvents.kt
@@ -21,9 +21,11 @@ sealed class SubmissionNavigationEvents {
         val coronaTestQRCode: CoronaTestQRCode,
         val consentGiven: Boolean
     ) : SubmissionNavigationEvents()
+
     data class NavigateToDeletionWarningFragmentFromTan(val coronaTestTan: CoronaTestTAN, val consentGiven: Boolean) :
         SubmissionNavigationEvents()
-    object NavigateToCreateProfile : SubmissionNavigationEvents()
+
+    data class NavigateToCreateProfile(val onboarded: Boolean = false) : SubmissionNavigationEvents()
     object NavigateToOpenProfile : SubmissionNavigationEvents()
     data class ResolvePlayServicesException(val exception: ApiException) : SubmissionNavigationEvents()
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/SpannableStringBuilder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/SpannableStringBuilder.kt
index 61c9b2698cb6e8d8a9177579ac5b843890111c94..576047ca22cf24f014ac205a98a159576a453bd9 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/SpannableStringBuilder.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/SpannableStringBuilder.kt
@@ -1,10 +1,40 @@
 package de.rki.coronawarnapp.util
 
+import android.text.Spannable
 import android.text.SpannableStringBuilder
 import android.text.Spanned
 import android.text.style.URLSpan
+import androidx.core.text.toSpannable
 
 fun SpannableStringBuilder.urlSpan(start: Int, end: Int, value: String): SpannableStringBuilder {
     setSpan(URLSpan(value), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
     return this
 }
+
+/**
+ * Creates a [Spannable] from all the elements separated using [separator]
+ * and using the given [prefix] and [postfix] if supplied.
+ *
+ * If the collection could be huge, you can specify a non-negative value of [limit],
+ * in which case only the first [limit]
+ * elements will be appended, followed by the [truncated] string (which defaults to "...").
+ **/
+@Suppress("LongParameterList")
+fun <T> Iterable<T>.joinToSpannable(
+    separator: CharSequence = ", ",
+    prefix: CharSequence = "",
+    postfix: CharSequence = "",
+    limit: Int = -1,
+    truncated: CharSequence = "...",
+    transform: ((T) -> CharSequence)? = null
+): Spannable {
+    return joinTo(
+        SpannableStringBuilder(),
+        separator,
+        prefix,
+        postfix,
+        limit,
+        truncated,
+        transform
+    ).toSpannable()
+}
diff --git a/Corona-Warn-App/src/main/res/drawable/rat_profile_gradient.xml b/Corona-Warn-App/src/main/res/drawable/rat_profile_gradient.xml
new file mode 100644
index 0000000000000000000000000000000000000000..85fdf590f418b7008036246cbbc244b07b29de9a
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/rat_profile_gradient.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:angle="135"
+        android:endColor="#599BC4"
+        android:startColor="#29689B" />
+</shape>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/drawable/trace_location_qr_code_background.xml b/Corona-Warn-App/src/main/res/drawable/rounded_white_background.xml
similarity index 100%
rename from Corona-Warn-App/src/main/res/drawable/trace_location_qr_code_background.xml
rename to Corona-Warn-App/src/main/res/drawable/rounded_white_background.xml
diff --git a/Corona-Warn-App/src/main/res/layout/rat_profile_qr_code_fragment.xml b/Corona-Warn-App/src/main/res/layout/rat_profile_qr_code_fragment.xml
index b1467f8500be0855d3ac060e51f2163500da632c..3c990f83bc78fdc54fd39988a01e1aff7c8adcd6 100644
--- a/Corona-Warn-App/src/main/res/layout/rat_profile_qr_code_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/rat_profile_qr_code_fragment.xml
@@ -1,26 +1,198 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<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/content_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context=".ui.coronatest.rat.profile.qrcode.RATProfileQrCodeFragment">
+    android:background="@drawable/trace_location_gradient_background"
+    android:contentDescription="@string/trace_location_event_detail_title_accessibility">
 
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:text="🚧 Profile Screen"
-        android:textSize="40sp" />
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
+        android:id="@+id/coordinator_layout"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginBottom="12dp"
+        android:nestedScrollingEnabled="true"
+        app:layout_constraintBottom_toTopOf="@id/next_button"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:context=".CollapsingToolbar">
+
+        <com.google.android.material.appbar.AppBarLayout
+            android:id="@+id/appBarLayout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <com.google.android.material.appbar.CollapsingToolbarLayout
+                android:id="@+id/collapsing_toolbar_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:nestedScrollingEnabled="true"
+                app:layout_scrollFlags="scroll|exitUntilCollapsed">
+
+                <ImageView
+                    android:id="@+id/expandedImage"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    app:layout_collapseMode="parallax"
+                    app:srcCompat="@drawable/rat_profile_gradient" />
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    app:layout_collapseMode="parallax">
+
+                    <TextView
+                        android:id="@+id/title"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginHorizontal="24dp"
+                        android:layout_marginTop="90dp"
+                        android:layout_marginBottom="12dp"
+                        android:gravity="center"
+                        android:text="@string/rat_profile_create_title"
+                        android:textColor="@android:color/white"
+                        android:textSize="20sp"
+                        android:textStyle="bold" />
+
+                </LinearLayout>
+
+                <com.google.android.material.appbar.MaterialToolbar
+                    android:id="@+id/toolbar"
+                    android:layout_width="match_parent"
+                    android:layout_height="?attr/actionBarSize"
+                    android:theme="@style/CWAToolbar.Theme"
+                    app:layout_collapseMode="pin"
+                    app:layout_scrollFlags="scroll|enterAlways"
+                    app:menu="@menu/menu_rat_qr_code_profile"
+                    app:navigationIcon="@drawable/ic_close"
+                    app:navigationIconTint="@android:color/white">
+
+                    <FrameLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginEnd="24dp">
+                        <ImageView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="center"
+                            android:importantForAccessibility="no"
+                            android:scaleType="center"
+                            app:srcCompat="@drawable/ic_cwa_logo_white" />
+                    </FrameLayout>
+
+                </com.google.android.material.appbar.MaterialToolbar>
+
+            </com.google.android.material.appbar.CollapsingToolbarLayout>
+
+        </com.google.android.material.appbar.AppBarLayout>
+
+        <androidx.core.widget.NestedScrollView
+            android:id="@+id/nested_scroll_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:animateLayoutChanges="true">
+
+                <ImageView
+                    android:id="@+id/qrCodeImage"
+                    android:layout_width="0dp"
+                    android:layout_height="0dp"
+                    android:layout_marginHorizontal="24dp"
+                    android:layout_marginVertical="12dp"
+                    android:layout_marginTop="16dp"
+                    android:background="@drawable/rounded_white_background"
+                    android:contentDescription="@string/trace_location_event_detail_qr_code_accessibility"
+                    app:layout_constraintDimensionRatio="H,1:1"
+                    app:layout_constraintLeft_toLeftOf="parent"
+                    app:layout_constraintRight_toRightOf="parent"
+                    app:layout_constraintTop_toTopOf="parent"
+                    tools:src="@drawable/ic_qrcode"
+                    tools:tint="@android:color/black" />
+
+                <com.google.android.material.progressindicator.LinearProgressIndicator
+                    android:id="@+id/progress_bar"
+                    android:layout_width="150dp"
+                    android:layout_height="wrap_content"
+                    android:indeterminate="true"
+                    app:hideAnimationBehavior="inward"
+                    app:indicatorColor="@color/colorAccent"
+                    app:layout_constraintBottom_toBottomOf="@id/qrCodeImage"
+                    app:layout_constraintEnd_toEndOf="@id/qrCodeImage"
+                    app:layout_constraintStart_toStartOf="@id/qrCodeImage"
+                    app:layout_constraintTop_toTopOf="@id/qrCodeImage" />
+
+                <LinearLayout
+                    android:id="@+id/info_box"
+                    style="@style/Card.NoElevation"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="24dp"
+                    android:layout_marginTop="8dp"
+                    android:orientation="vertical"
+                    android:padding="16dp"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/qrCodeImage"
+                    app:layout_constraintVertical_chainStyle="packed">
+
+                    <TextView
+                        style="@style/body2"
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:layout_marginTop="8dp"
+                        android:text="@string/rat_qr_code_profile_description" />
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/person_data"
+                    style="@style/Card.NoElevation"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="24dp"
+                    android:layout_marginTop="8dp"
+                    android:orientation="vertical"
+                    android:padding="16dp"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/info_box"
+                    app:layout_constraintVertical_chainStyle="packed">
+
+                    <TextView
+                        android:id="@+id/profile_info"
+                        style="@style/materialSubtitleSixteen"
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:lineSpacingExtra="8dp"
+                        tools:text="Max Mustermann\ngeboren 17.11.1990\nLange Straße 51\n4471 Potsdam\n0151123456789\nmaxmustermann@web.de" />
+
+                </LinearLayout>
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+        </androidx.core.widget.NestedScrollView>
 
+    </androidx.coordinatorlayout.widget.CoordinatorLayout>
 
     <Button
-        android:id="@+id/closeButton"
+        android:id="@+id/next_button"
         style="@style/buttonPrimary"
-        android:layout_width="match_parent"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_gravity="bottom|center"
-        android:layout_marginHorizontal="24dp"
-        android:layout_marginBottom="24dp"
-        android:text="Weiter" />
+        android:layout_marginStart="@dimen/spacing_normal"
+        android:layout_marginEnd="@dimen/spacing_normal"
+        android:layout_marginBottom="8dp"
+        android:text="@string/rat_qr_code_profile_next_button"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
 
-</FrameLayout>
\ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
index 36589681fc501f9e38582a7790969b2071e1dab8..8ffc939f6e8957cdb5d1c5923692cc43418eb0f0 100644
--- a/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
+++ b/Corona-Warn-App/src/main/res/layout/trace_location_organizer_qr_code_detail_fragment.xml
@@ -122,7 +122,7 @@
                     android:layout_marginHorizontal="24dp"
                     android:layout_marginVertical="12dp"
                     android:layout_marginTop="16dp"
-                    android:background="@drawable/trace_location_qr_code_background"
+                    android:background="@drawable/rounded_white_background"
                     android:contentDescription="@string/trace_location_event_detail_qr_code_accessibility"
                     app:layout_constraintDimensionRatio="H,1:1"
                     app:layout_constraintLeft_toLeftOf="parent"
diff --git a/Corona-Warn-App/src/main/res/menu/menu_rat_qr_code_profile.xml b/Corona-Warn-App/src/main/res/menu/menu_rat_qr_code_profile.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7ee450aee57a945098e8e29ce8ffaf3a4cfa7612
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/menu/menu_rat_qr_code_profile.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:title="@string/rat_qr_code_profile_delete_item"
+        app:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/navigation/rapid_antigen_test_profile_nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/rapid_antigen_test_profile_nav_graph.xml
index 8aae017026d6ffc20a3b66626ff26ab28a886610..09d3bd47f25919ae4124271e1b47b91f0eeb93e6 100644
--- a/Corona-Warn-App/src/main/res/navigation/rapid_antigen_test_profile_nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/rapid_antigen_test_profile_nav_graph.xml
@@ -12,7 +12,9 @@
         tools:layout="@layout/rat_profile_onboarding_fragment">
         <action
             android:id="@+id/action_ratProfileOnboardingFragment_to_ratProfileCreateFragment"
-            app:destination="@id/ratProfileCreateFragment" />
+            app:destination="@id/ratProfileCreateFragment"
+            app:popUpTo="@id/rapid_test_profile_nav_graph"
+            app:popUpToInclusive="false" />
         <action
             android:id="@+id/action_ratProfileOnboardingFragment_to_privacyFragment"
             app:destination="@id/privacyFragment" />
diff --git a/Corona-Warn-App/src/main/res/values-de/antigen_strings.xml b/Corona-Warn-App/src/main/res/values-de/antigen_strings.xml
index 0696cdf0c652ae2a38f623747588a5f92176ce8d..fee399d51a3ac30964ad7ff56e9bba103c8e4bf9 100644
--- a/Corona-Warn-App/src/main/res/values-de/antigen_strings.xml
+++ b/Corona-Warn-App/src/main/res/values-de/antigen_strings.xml
@@ -181,4 +181,20 @@
     <string name="rat_profile_onboarding_next">Weiter</string>
     <!-- XTXT: Create RAT profile onboarding privacy -->
     <string name="rat_profile_onboarding_privacy">Ausführliche Informationen zur Datenverarbeitung und Ihrem Einverständnis.</string>
+    <!-- XTXT: Create RAT Qr code profile description-->
+    <string name="rat_qr_code_profile_description">Bitte zeigen Sie diesen QR-Code an der Teststelle vor, um Ihre persönlichen Daten schnell erfassen zu lassen. Bitte halten zusätzlich Sie Ihren Personalausweis bereit.</string>
+    <!-- XTXT: Create RAT Qr code profile birth date-->
+    <string name="rat_qr_code_profile_birth_date">geboren %1$s</string>
+    <!-- XBUT: Create RAT Qr code profile next button-->
+    <string name="rat_qr_code_profile_next_button">Weiter</string>
+    <!-- XTXT: Create RAT Qr code profile delete item-->
+    <string name="rat_qr_code_profile_delete_item">Entfernen</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog title-->
+    <string name="rat_qr_code_profile_dialog_title">Wollen Sie das Schnelltest-Profil wirklich entfernen?</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog message-->
+    <string name="rat_qr_code_profile_dialog_message">Bitte denken Sie daran, dass der QR-Code danach nicht mehr zum Registrieren verwendet werden kann.</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog positive button-->
+    <string name="rat_qr_code_profile_dialog_positive_button">Löschen</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog negative button-->
+    <string name="rat_qr_code_profile_dialog_negative_button">Abbrechen</string>
 </resources>
diff --git a/Corona-Warn-App/src/main/res/values/antigen_strings.xml b/Corona-Warn-App/src/main/res/values/antigen_strings.xml
index 1cd6f7682a8f13640dde151163ae19d68880cb93..00ff0072b458eb6408ecd1b5312108a9b6d00779 100644
--- a/Corona-Warn-App/src/main/res/values/antigen_strings.xml
+++ b/Corona-Warn-App/src/main/res/values/antigen_strings.xml
@@ -181,4 +181,20 @@
     <string name="rat_profile_onboarding_next">Weiter</string>
     <!-- XTXT: Create RAT profile onboarding privacy -->
     <string name="rat_profile_onboarding_privacy">Ausführliche Informationen zur Datenverarbeitung und Ihrem Einverständnis.</string>
+    <!-- XTXT: Create RAT Qr code profile description-->
+    <string name="rat_qr_code_profile_description">Bitte zeigen Sie diesen QR-Code an der Teststelle vor, um Ihre persönlichen Daten schnell erfassen zu lassen. Bitte halten zusätzlich Sie Ihren Personalausweis bereit.</string>
+    <!-- XTXT: Create RAT Qr code profile birth date-->
+    <string name="rat_qr_code_profile_birth_date">geboren %1$s</string>
+    <!-- XBUT: Create RAT Qr code profile next button-->
+    <string name="rat_qr_code_profile_next_button">Weiter</string>
+    <!-- XTXT: Create RAT Qr code profile delete item-->
+    <string name="rat_qr_code_profile_delete_item">Entfernen</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog title-->
+    <string name="rat_qr_code_profile_dialog_title">Wollen Sie das Schnelltest-Profil wirklich entfernen?</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog message-->
+    <string name="rat_qr_code_profile_dialog_message">Bitte denken Sie daran, dass der QR-Code danach nicht mehr zum Registrieren verwendet werden kann.</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog positive button-->
+    <string name="rat_qr_code_profile_dialog_positive_button">Löschen</string>
+    <!-- XTXT: Create RAT Qr code profile delete dialog negative button-->
+    <string name="rat_qr_code_profile_dialog_negative_button">Abbrechen</string>
 </resources>
diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml
index be7743ea4251a325806bf29993af49ddbaaeba5d..bc944522a40b87e9ab633b51e85237ac0e981cb3 100644
--- a/Corona-Warn-App/src/main/res/values/styles.xml
+++ b/Corona-Warn-App/src/main/res/values/styles.xml
@@ -83,6 +83,14 @@
         <item name="android:background">@color/colorTransparent</item>
     </style>
 
+    <style name="CWAToolbar.Theme" parent="Widget.AppCompat.ActionBar">
+        <item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
+    </style>
+
+    <style name="OverflowButtonStyle" parent="Widget.AppCompat.Light.ActionButton.Overflow">
+        <item name="android:tint">@android:color/white</item>
+    </style>
+
     <!-- Dialog Theme-->
     <style name="DialogTheme" parent="Theme.MaterialComponents.DayNight.Dialog.Alert">
         <item name="buttonBarPositiveButtonStyle">@style/DialogButtonTheme</item>
@@ -283,6 +291,7 @@
     <style name="headline4" parent="@style/TextAppearance.MaterialComponents.Headline4">
         <item name="android:textColor">@color/colorTextPrimary1</item>
     </style>
+
     <style name="headline4Bold" parent="@style/headline4">
         <item name="android:textStyle">bold</item>
     </style>
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCardTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCardTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9d8c91141da23d079fa53a580d3d6c369d1aaaa0
--- /dev/null
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/coronatest/antigen/profile/VCardTest.kt
@@ -0,0 +1,133 @@
+package de.rki.coronawarnapp.coronatest.antigen.profile
+
+import de.rki.coronawarnapp.util.TimeStamper
+import io.kotest.matchers.shouldBe
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.impl.annotations.MockK
+import org.joda.time.Instant
+import org.joda.time.format.ISODateTimeFormat
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.BeforeEach
+import testhelpers.BaseTest
+
+class VCardTest : BaseTest() {
+
+    @MockK lateinit var timeStamper: TimeStamper
+
+    @BeforeEach
+    fun setup() {
+        MockKAnnotations.init(this)
+
+        every { timeStamper.nowUTC } returns Instant.parse("1995-10-31T22:27:10Z")
+    }
+
+    @Test
+    fun `Case 1`() {
+        val profile = RATProfile(
+            firstName = "Max",
+            lastName = "Mustermann",
+            birthDate = ISODateTimeFormat.basicDate().parseLocalDate("19800625"),
+            street = "Musterstrasse 14",
+            zipCode = "51466",
+            city = "Musterstadt",
+            phone = "0190 1234567",
+            email = "max@mustermann.de"
+        )
+        VCard(timeStamper).create(profile) shouldBe
+            """
+            BEGIN:VCARD
+            VERSION:4.0
+            N:Mustermann;Max;;;
+            FN:Max Mustermann
+            BDAY:19800625
+            EMAIL;TYPE=home:max@mustermann.de
+            TEL;TYPE="cell,home":0190 1234567
+            ADR;TYPE=home:;;Musterstrasse 14;Musterstadt;;51466
+            REV:19951031T222710Z
+            END:VCARD
+            """.trimIndent()
+    }
+
+    @Test
+    fun `Case 2`() {
+        val profile = RATProfile(
+            firstName = "",
+            lastName = "",
+            birthDate = null,
+            street = "",
+            zipCode = "",
+            city = "",
+            phone = "",
+            email = ""
+        )
+        VCard(timeStamper).create(profile) shouldBe
+            """
+            BEGIN:VCARD
+            VERSION:4.0
+            N:;;;;
+            FN:
+            BDAY:
+            EMAIL;TYPE=home:
+            TEL;TYPE="cell,home":
+            ADR;TYPE=home:;;;;;
+            REV:19951031T222710Z
+            END:VCARD
+            """.trimIndent()
+    }
+
+    @Test
+    fun `Case 3`() {
+        val profile = RATProfile(
+            firstName = "Max",
+            lastName = "Mustermann",
+            birthDate = ISODateTimeFormat.basicDate().parseLocalDate("19800625"),
+            street = "Mu\\ster;stra,sse 14",
+            zipCode = "51466",
+            city = "Musterstadt",
+            phone = "0190 1234567",
+            email = "max@mustermann.de"
+        )
+        VCard(timeStamper).create(profile) shouldBe
+            """
+            BEGIN:VCARD
+            VERSION:4.0
+            N:Mustermann;Max;;;
+            FN:Max Mustermann
+            BDAY:19800625
+            EMAIL;TYPE=home:max@mustermann.de
+            TEL;TYPE="cell,home":0190 1234567
+            ADR;TYPE=home:;;Mu\\ster\;stra\,sse 14;Musterstadt;;51466
+            REV:19951031T222710Z
+            END:VCARD
+            """.trimIndent()
+    }
+
+    @Test
+    fun `Case 4`() {
+        val profile = RATProfile(
+            firstName = "Max,",
+            lastName = "Mustermann;",
+            birthDate = ISODateTimeFormat.basicDate().parseLocalDate("19800625"),
+            street = "Mu\\\\ster;stra,sse 14\nA",
+            zipCode = "51466",
+            city = "Muster city \n Upper \\county, DC ; US",
+            phone = "0190 \\1234567",
+            email = "max@mustermann,;\\.de"
+        )
+        VCard(timeStamper).create(profile) shouldBe
+            """
+            BEGIN:VCARD
+            VERSION:4.0
+            N:Mustermann\;;Max\,;;;
+            FN:Max\, Mustermann\;
+            BDAY:19800625
+            EMAIL;TYPE=home:max@mustermann\,\;\\.de
+            TEL;TYPE="cell,home":0190 \\1234567
+            ADR;TYPE=home:;;Mu\\\\ster\;stra\,sse 14A;Muster city  Upper \\county\, DC \; US;;51466
+            REV:19951031T222710Z
+            END:VCARD
+            """.trimIndent()
+    }
+}