diff --git a/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.swift b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.swift
new file mode 100644
index 000000000..73961e2eb
--- /dev/null
+++ b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.swift
@@ -0,0 +1,157 @@
+/*
+ Copyright 2020 New Vector Ltd
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+import UIKit
+import Reusable
+
+final class SecureKeyBackupSetupIntroCell: UIView, NibOwnerLoadable, Themable {
+
+ // MARK: - Constants
+
+ private enum ImageAlpha {
+ static let highlighted: CGFloat = 0.3
+ }
+
+ // MARK: - Properties
+
+ // MARK: Outlets
+
+ @IBOutlet private weak var backgroundView: UIView!
+ @IBOutlet private weak var imageView: UIImageView!
+ @IBOutlet private weak var titleLabel: UILabel!
+ @IBOutlet private weak var informationLabel: UILabel!
+ @IBOutlet private weak var accessoryImageView: UIImageView!
+ @IBOutlet private weak var separatorView: UIView!
+
+ // MARK: Private
+
+ private var theme: Theme?
+
+ private var isHighlighted: Bool = false {
+ didSet {
+ self.updateView()
+ }
+ }
+
+ // MARK: Public
+
+ var action: (() -> Void)?
+
+ // MARK: Setup
+
+ private func commonInit() {
+ self.setupGestureRecognizer()
+
+ let accessoryTemplateImage = Asset.Images.disclosureIcon.image.withRenderingMode(.alwaysTemplate)
+ self.accessoryImageView.image = accessoryTemplateImage
+ self.accessoryImageView.highlightedImage = accessoryTemplateImage.vc_withAlpha(ImageAlpha.highlighted)
+ }
+
+ convenience init() {
+ self.init(frame: CGRect.zero)
+ self.commonInit()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ self.loadNibContent()
+ self.commonInit()
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ self.loadNibContent()
+ self.commonInit()
+ }
+
+ // MARK: - Public
+
+ func update(theme: Theme) {
+ self.theme = theme
+
+ self.backgroundView.backgroundColor = theme.backgroundColor
+ self.imageView.tintColor = theme.textPrimaryColor
+ self.titleLabel.textColor = theme.tintColor
+ self.informationLabel.textColor = theme.textSecondaryColor
+ self.accessoryImageView.tintColor = theme.textSecondaryColor
+ self.separatorView.backgroundColor = theme.lineBreakColor
+
+ self.updateView()
+ }
+
+ func fill(title: String, information: String, image: UIImage) {
+ let templateImage = image.withRenderingMode(.alwaysTemplate)
+
+ self.imageView.image = templateImage
+ self.imageView.highlightedImage = templateImage.vc_withAlpha(ImageAlpha.highlighted)
+
+ self.titleLabel.text = title
+ self.informationLabel.text = information
+
+ self.setupAccessibility(title: title, isEnabled: true)
+ self.updateView()
+ }
+
+ // MARK: - Private
+
+ private func setupAccessibility(title: String, isEnabled: Bool) {
+ self.isAccessibilityElement = true
+ self.accessibilityLabel = title
+ self.accessibilityTraits = .button
+ if !isEnabled {
+ self.accessibilityTraits.insert(.notEnabled)
+ }
+ }
+
+ private func setupGestureRecognizer() {
+ let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(buttonAction(_:)))
+ gestureRecognizer.minimumPressDuration = 0
+ self.addGestureRecognizer(gestureRecognizer)
+ }
+
+ private func updateView() {
+
+ if let theme = self.theme {
+ self.backgroundView.backgroundColor = self.isHighlighted ? theme.overlayBackgroundColor : theme.backgroundColor
+ }
+
+ self.imageView.isHighlighted = self.isHighlighted
+ self.accessoryImageView.isHighlighted = self.isHighlighted
+ }
+
+ // MARK: - Actions
+
+ @objc private func buttonAction(_ sender: UILongPressGestureRecognizer) {
+
+ let isBackgroundViewTouched = sender.vc_isTouchingInside()
+
+ switch sender.state {
+ case .began, .changed:
+ self.isHighlighted = isBackgroundViewTouched
+ case .ended:
+ self.isHighlighted = false
+
+ if isBackgroundViewTouched {
+ self.action?()
+ }
+ case .cancelled:
+ self.isHighlighted = false
+ default:
+ break
+ }
+ }
+
+}
diff --git a/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.xib b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.xib
new file mode 100644
index 000000000..3b29fac64
--- /dev/null
+++ b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroCell.xib
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.storyboard b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.storyboard
new file mode 100644
index 000000000..0f6dd3102
--- /dev/null
+++ b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.storyboard
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.swift b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.swift
new file mode 100644
index 000000000..9213b3024
--- /dev/null
+++ b/Riot/Modules/KeyBackup/SecureSetup/Intro/SecureKeyBackupSetupIntroViewController.swift
@@ -0,0 +1,133 @@
+/*
+ Copyright 2020 New Vector Ltd
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+import UIKit
+
+protocol SecureKeyBackupSetupIntroViewControllerDelegate: class {
+ func secureKeyBackupSetupIntroViewControllerDidTapUseKey(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
+ func secureKeyBackupSetupIntroViewControllerDidTapUsePassphrase(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
+ func secureKeyBackupSetupIntroViewControllerDidCancel(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
+}
+
+@objcMembers
+final class SecureKeyBackupSetupIntroViewController: UIViewController {
+
+ // MARK: - Properties
+
+ // MARK: Outlets
+
+ @IBOutlet private weak var informationLabel: UILabel!
+
+ @IBOutlet private weak var topSeparatorView: UIView!
+ @IBOutlet private weak var secureKeyCell: SecureKeyBackupSetupIntroCell!
+ @IBOutlet private weak var securePassphraseCell: SecureKeyBackupSetupIntroCell!
+
+ // MARK: Private
+
+ private var theme: Theme!
+
+ // MARK: Public
+
+ weak var delegate: SecureKeyBackupSetupIntroViewControllerDelegate?
+
+ // MARK: - Setup
+
+ class func instantiate() -> SecureKeyBackupSetupIntroViewController {
+ let viewController = StoryboardScene.SecureKeyBackupSetupIntroViewController.initialScene.instantiate()
+ viewController.theme = ThemeService.shared().theme
+ return viewController
+ }
+
+ // MARK: - Life cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // Do any additional setup after loading the view.
+
+ self.vc_removeBackTitle()
+
+ self.setupViews()
+ self.registerThemeServiceDidChangeThemeNotification()
+ self.update(theme: self.theme)
+ }
+
+ override var preferredStatusBarStyle: UIStatusBarStyle {
+ return self.theme.statusBarStyle
+ }
+
+ // MARK: - Private
+
+ private func setupViews() {
+ let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
+ guard let self = self else {
+ return
+ }
+ self.delegate?.secureKeyBackupSetupIntroViewControllerDidCancel(self)
+ }
+ self.navigationItem.rightBarButtonItem = cancelBarButtonItem
+
+ self.title = VectorL10n.secureKeyBackupSetupIntroTitle
+
+ self.informationLabel.text = VectorL10n.secureKeyBackupSetupIntroInfo
+
+ self.secureKeyCell.fill(title: VectorL10n.secureKeyBackupSetupIntroUseSecurityKeyTitle,
+ information: VectorL10n.secureKeyBackupSetupIntroUseSecurityKeyInfo,
+ image: Asset.Images.secretsSetupKey.image)
+
+ self.secureKeyCell.action = { [weak self] in
+ guard let self = self else {
+ return
+ }
+ self.delegate?.secureKeyBackupSetupIntroViewControllerDidTapUseKey(self)
+ }
+
+ self.securePassphraseCell.fill(title: VectorL10n.secureKeyBackupSetupIntroUseSecurityPassphraseTitle,
+ information: VectorL10n.secureKeyBackupSetupIntroUseSecurityPassphraseInfo,
+ image: Asset.Images.secretsSetupPassphrase.image)
+
+ self.securePassphraseCell.action = { [weak self] in
+ guard let self = self else {
+ return
+ }
+ self.delegate?.secureKeyBackupSetupIntroViewControllerDidTapUsePassphrase(self)
+ }
+ }
+
+ private func update(theme: Theme) {
+ self.theme = theme
+
+ self.view.backgroundColor = theme.headerBackgroundColor
+
+ if let navigationBar = self.navigationController?.navigationBar {
+ theme.applyStyle(onNavigationBar: navigationBar)
+ }
+
+ self.informationLabel.textColor = theme.textPrimaryColor
+
+ self.topSeparatorView.backgroundColor = theme.lineBreakColor
+ self.secureKeyCell.update(theme: theme)
+ self.securePassphraseCell.update(theme: theme)
+ }
+
+ private func registerThemeServiceDidChangeThemeNotification() {
+ NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
+ }
+
+ @objc private func themeDidChange() {
+ self.update(theme: ThemeService.shared().theme)
+ }
+}