From bde29cdb823d155236e50aece7afb704602a20b6 Mon Sep 17 00:00:00 2001
From: Juan Cortes Ross <juan@bohem.io>
Date: Mon, 14 Jan 2019 22:13:44 +0100
Subject: [PATCH 1/8] Initial version

---
 src/components/CurrentAddress/index.js        |   3 +
 src/components/GenuineCheckModal.js           |  13 +-
 src/components/IsUnlocked.js                  |   4 +-
 src/components/ManagerPage/AppsList.js        | 197 +++++-----
 src/components/SettingsPage/CleanButton.js    |   3 +-
 .../SettingsPage/DisablePasswordModal.js      |  67 ++--
 .../SettingsPage/PasswordAutoLockSelect.js    |   8 +-
 src/components/SettingsPage/PasswordModal.js  |  50 +--
 .../SettingsPage/RepairDeviceButton.js        |   2 +-
 src/components/SettingsPage/ResetButton.js    |   3 +-
 .../SettingsPage/ResetFallbackModal.js        |   2 +-
 .../SettingsPage/sections/Display.js          |   4 +-
 .../SettingsPage/sections/Export.js           |  53 +--
 src/components/base/Modal/ConfirmModal.js     |  59 +--
 src/components/base/Modal/ModalBody.js        | 143 ++++----
 src/components/base/Modal/ModalContent.js     |  59 +++
 src/components/base/Modal/ModalFooter.js      |  18 +
 src/components/base/Modal/ModalHeader.js      |  93 +++++
 src/components/base/Modal/ModalTitle.js       |  75 ----
 src/components/base/Modal/RepairModal.js      |  95 ++---
 src/components/base/Modal/index.js            | 345 +++++++++---------
 src/components/base/Modal/stories.js          |  75 ++--
 src/components/base/Stepper/index.js          |  44 ++-
 .../modals/AccountSettingRenderBody.js        |  64 ++--
 src/components/modals/AddAccounts/index.js    |   2 +
 src/components/modals/Debug.js                |  32 +-
 src/components/modals/Disclaimer.js           |  49 ++-
 src/components/modals/OperationDetails.js     | 215 ++++++-----
 src/components/modals/Receive/index.js        |   5 +-
 .../modals/ReleaseNotes/ReleaseNotesBody.js   |  37 +-
 src/components/modals/ReleaseNotes/index.js   |   1 +
 src/components/modals/Send/index.js           |   1 +
 src/components/modals/SettingsAccount.js      |   5 +-
 src/components/modals/ShareAnalytics.js       |  62 ++--
 src/components/modals/TechnicalData.js        |  60 ++-
 .../modals/UpdateFirmware/Disclaimer.js       |  78 ++--
 src/components/modals/UpdateFirmware/index.js |   1 +
 src/index.ejs                                 |   1 +
 src/reducers/modals.js                        |   1 -
 39 files changed, 1114 insertions(+), 915 deletions(-)
 create mode 100644 src/components/base/Modal/ModalContent.js
 create mode 100644 src/components/base/Modal/ModalFooter.js
 create mode 100644 src/components/base/Modal/ModalHeader.js
 delete mode 100644 src/components/base/Modal/ModalTitle.js

diff --git a/src/components/CurrentAddress/index.js b/src/components/CurrentAddress/index.js
index 9b7c6dd6..fc8d4de3 100644
--- a/src/components/CurrentAddress/index.js
+++ b/src/components/CurrentAddress/index.js
@@ -145,8 +145,11 @@ class CurrentAddress extends PureComponent<Props, { copyFeedback: boolean }> {
 
   componentWillUnmount() {
     if (this._timeout) clearTimeout(this._timeout)
+    this._isUnmounted = true
   }
 
+  _isUnmounted = false
+
   renderCopy = copy => {
     const { t } = this.props
     return (
diff --git a/src/components/GenuineCheckModal.js b/src/components/GenuineCheckModal.js
index e70d17ec..d9f4f7a1 100644
--- a/src/components/GenuineCheckModal.js
+++ b/src/components/GenuineCheckModal.js
@@ -5,7 +5,7 @@ import { translate } from 'react-i18next'
 
 import type { T } from 'types/common'
 
-import Modal, { ModalBody, ModalTitle, ModalContent } from 'components/base/Modal'
+import Modal, { ModalBody } from 'components/base/Modal'
 import GenuineCheck from 'components/GenuineCheck'
 
 type Props = {
@@ -19,12 +19,13 @@ class GenuineCheckModal extends PureComponent<Props> {
   renderBody = ({ onClose }) => {
     const { t, onSuccess, onFail, onUnavailable } = this.props
     return (
-      <ModalBody onClose={onClose}>
-        <ModalTitle>{t('genuinecheck.modal.title')}</ModalTitle>
-        <ModalContent>
+      <ModalBody
+        onClose={onClose}
+        title={t('genuinecheck.modal.title')}
+        render={() => (
           <GenuineCheck onSuccess={onSuccess} onFail={onFail} onUnavailable={onUnavailable} />
-        </ModalContent>
-      </ModalBody>
+        )}
+      />
     )
   }
 
diff --git a/src/components/IsUnlocked.js b/src/components/IsUnlocked.js
index 997ee69f..35dfbdca 100644
--- a/src/components/IsUnlocked.js
+++ b/src/components/IsUnlocked.js
@@ -23,8 +23,8 @@ import Box from 'components/base/Box'
 import InputPassword from 'components/base/InputPassword'
 import LedgerLiveLogo from 'components/base/LedgerLiveLogo'
 import IconArrowRight from 'icons/ArrowRight'
-import Button from './base/Button/index'
-import ConfirmModal from './base/Modal/ConfirmModal'
+import Button from 'components/base/Button/index'
+import ConfirmModal from 'components/base/Modal/ConfirmModal'
 
 type InputValue = {
   password: string,
diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js
index 115c8904..390da5c6 100644
--- a/src/components/ManagerPage/AppsList.js
+++ b/src/components/ManagerPage/AppsList.js
@@ -16,7 +16,7 @@ import installApp from 'commands/installApp'
 import uninstallApp from 'commands/uninstallApp'
 import Box from 'components/base/Box'
 import Space from 'components/base/Space'
-import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
 import Tooltip from 'components/base/Tooltip'
 import Text from 'components/base/Text'
 import ProgressBar from 'components/ProgressBar'
@@ -32,6 +32,7 @@ import CheckCircle from 'icons/CheckCircle'
 import { FreezeDeviceChangeEvents } from './HookDeviceChange'
 import ManagerApp, { Container as FakeManagerAppContainer } from './ManagerApp'
 import AppSearchBar from './AppSearchBar'
+import ModalBody from '../base/Modal/ModalBody'
 
 const mapStateToProps = state => ({
   isDevMode: developerModeSelector(state),
@@ -150,108 +151,104 @@ class AppsList extends PureComponent<Props, State> {
 
   handleCloseModal = () => this.setState({ status: 'idle', mode: 'home' })
 
-  renderModal = () => {
+  renderBody = () => {
     const { t } = this.props
     const { app, status, error, mode, progress } = this.state
-    return (
-      <Modal
-        isOpened={status !== 'idle' && status !== 'loading'}
-        render={() => (
-          <ModalBody align="center" justify="center" style={{ height: 300 }}>
-            <FreezeDeviceChangeEvents />
-            {status === 'busy' || status === 'idle' ? (
-              <Fragment>
-                <ModalTitle>
-                  {mode === 'installing' ? (
-                    <Box color="grey">
-                      <Update size={30} />
-                    </Box>
-                  ) : (
-                    <Box color="grey">
-                      <Trash size={30} />
-                    </Box>
-                  )}
-                </ModalTitle>
-                <ModalContent>
-                  <Text ff="Museo Sans|Regular" fontSize={6} color="dark">
-                    {t(`manager.apps.${mode}`, { app })}
-                  </Text>
-                  <Box mt={6}>
-                    <ProgressBar width={150} progress={progress} />
-                  </Box>
-                </ModalContent>
-              </Fragment>
-            ) : status === 'error' ? (
-              <Fragment>
-                <TrackPage
-                  category="Manager"
-                  name="Error Modal"
-                  error={error && error.name}
-                  app={app}
-                />
-                <ModalContent grow align="center" justify="center" mt={5}>
-                  <Box color="alertRed">
-                    <ExclamationCircleThin size={44} />
-                  </Box>
-                  <Box
-                    color="dark"
-                    mt={4}
-                    fontSize={6}
-                    ff="Museo Sans|Regular"
-                    textAlign="center"
-                    style={{ maxWidth: 350 }}
-                  >
-                    <TranslatedError error={error} field="title" />
-                  </Box>
-                  <Box
-                    color="graphite"
-                    mt={2}
-                    fontSize={4}
-                    ff="Open Sans"
-                    textAlign="center"
-                    style={{ maxWidth: 350 }}
-                  >
-                    <TranslatedError error={error} field="description" />
-                  </Box>
-                </ModalContent>
-                <ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}>
-                  <Button primary onClick={this.handleCloseModal}>
-                    {t('common.close')}
-                  </Button>
-                </ModalFooter>
-              </Fragment>
-            ) : status === 'success' ? (
-              <Fragment>
-                <ModalContent grow align="center" justify="center" mt={5}>
-                  <Box color="positiveGreen">
-                    <CheckCircle size={44} />
-                  </Box>
-                  <Box
-                    color="dark"
-                    mt={4}
-                    fontSize={6}
-                    ff="Museo Sans|Regular"
-                    textAlign="center"
-                    style={{ maxWidth: 350 }}
-                  >
-                    {t(
-                      `manager.apps.${
-                        mode === 'installing' ? 'installSuccess' : 'uninstallSuccess'
-                      }`,
-                      { app },
-                    )}
-                  </Box>
-                </ModalContent>
-                <ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}>
-                  <Button primary onClick={this.handleCloseModal}>
-                    {t('common.close')}
-                  </Button>
-                </ModalFooter>
-              </Fragment>
-            ) : null}
-          </ModalBody>
+
+    return ['busy', 'idle'].includes(status) ? (
+      <Box grow align="center" justify="center">
+        {mode === 'installing' ? (
+          <Box color="grey" grow align="center" mb={5}>
+            <Update size={30} />
+          </Box>
+        ) : (
+          <Box color="grey" grow align="center" mb={5}>
+            <Trash size={30} />
+          </Box>
         )}
-      />
+        <Text ff="Museo Sans|Regular" fontSize={6} color="dark">
+          {t(`manager.apps.${mode}`, { app })}
+        </Text>
+        <Box mt={6}>
+          <ProgressBar width={150} progress={progress} />
+        </Box>
+      </Box>
+    ) : status === 'error' ? (
+      <Box>
+        <TrackPage category="Manager" name="Error Modal" error={error && error.name} app={app} />
+        <Box grow align="center" justify="center" mt={5}>
+          <Box color="alertRed">
+            <ExclamationCircleThin size={44} />
+          </Box>
+          <Box
+            color="dark"
+            mt={4}
+            fontSize={6}
+            ff="Museo Sans|Regular"
+            textAlign="center"
+            style={{ maxWidth: 350 }}
+          >
+            <TranslatedError error={error} field="title" />
+          </Box>
+          <Box
+            color="graphite"
+            mt={2}
+            fontSize={4}
+            ff="Open Sans"
+            textAlign="center"
+            style={{ maxWidth: 350 }}
+          >
+            <TranslatedError error={error} field="description" />
+          </Box>
+        </Box>
+      </Box>
+    ) : status === 'success' ? (
+      <Box grow align="center" justify="center" mt={5}>
+        <Box color="positiveGreen">
+          <CheckCircle size={44} />
+        </Box>
+        <Box
+          color="dark"
+          mt={4}
+          fontSize={6}
+          ff="Museo Sans|Regular"
+          textAlign="center"
+          style={{ maxWidth: 350 }}
+        >
+          {t(`manager.apps.${mode === 'installing' ? 'installSuccess' : 'uninstallSuccess'}`, {
+            app,
+          })}
+        </Box>
+      </Box>
+    ) : null
+  }
+
+  renderFooter = () => {
+    const { t } = this.props
+    const { status } = this.state
+    return ['error', 'success'].includes(status) ? (
+      <Box horizontal justifyContent="flex-end" style={{ width: '100%' }}>
+        <Button primary onClick={this.handleCloseModal}>
+          {t('common.close')}
+        </Button>
+      </Box>
+    ) : null
+  }
+
+  renderModal = () => {
+    const { status } = this.state
+    return (
+      <Modal isOpened={status !== 'idle' && status !== 'loading'}>
+        <ModalBody
+          align="center"
+          justify="center"
+          title={''}
+          render={this.renderBody}
+          renderFooter={this.renderFooter}
+        >
+          <FreezeDeviceChangeEvents />
+        </ModalBody>
+      </Modal>
     )
   }
 
diff --git a/src/components/SettingsPage/CleanButton.js b/src/components/SettingsPage/CleanButton.js
index 0f72d21f..8a3081ea 100644
--- a/src/components/SettingsPage/CleanButton.js
+++ b/src/components/SettingsPage/CleanButton.js
@@ -7,7 +7,7 @@ import logger from 'logger'
 import type { T } from 'types/common'
 import { cleanAccountsCache } from 'actions/accounts'
 import Button from 'components/base/Button'
-import { ConfirmModal } from 'components/base/Modal'
+import ConfirmModal from 'components/base/Modal/ConfirmModal'
 import { softReset } from 'helpers/reset'
 import ResetFallbackModal from './ResetFallbackModal'
 
@@ -60,6 +60,7 @@ class CleanButton extends PureComponent<Props, State> {
 
         <ConfirmModal
           analyticsName="CleanCache"
+          centered
           isOpened={opened}
           onClose={this.close}
           onReject={this.close}
diff --git a/src/components/SettingsPage/DisablePasswordModal.js b/src/components/SettingsPage/DisablePasswordModal.js
index b9613c42..89d04a01 100644
--- a/src/components/SettingsPage/DisablePasswordModal.js
+++ b/src/components/SettingsPage/DisablePasswordModal.js
@@ -8,7 +8,8 @@ import Box from 'components/base/Box'
 import Button from 'components/base/Button'
 import InputPassword from 'components/base/InputPassword'
 import Label from 'components/base/Label'
-import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
 
 import type { T } from 'types/common'
 
@@ -61,37 +62,33 @@ class DisablePasswordModal extends PureComponent<Props, State> {
     const { t, onClose, ...props } = this.props
     const { currentPassword, incorrectPassword } = this.state
     return (
-      <Modal
-        {...props}
-        onHide={this.handleReset}
-        onClose={onClose}
-        render={({ onClose }) => (
-          <form onSubmit={this.disablePassword}>
-            <ModalBody onClose={onClose}>
-              <ModalTitle data-e2e="disablePassword_modalTitle">
-                {t('password.disablePassword.title')}
-              </ModalTitle>
-              <ModalContent>
-                <Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
-                  {t('password.disablePassword.desc')}
-                  <Box px={7} mt={4} flow={3}>
-                    <Box flow={1}>
-                      <Label htmlFor="password">
-                        {t('password.inputFields.currentPassword.label')}
-                      </Label>
-                      <InputPassword
-                        autoFocus
-                        type="password"
-                        id="password"
-                        onChange={this.handleInputChange('currentPassword')}
-                        value={currentPassword}
-                        error={incorrectPassword}
-                      />
-                    </Box>
+      <Modal {...props} centered onHide={this.handleReset} onClose={onClose}>
+        <form onSubmit={this.disablePassword}>
+          <ModalBody
+            onClose={onClose}
+            title={t('password.disablePassword.title')}
+            render={() => (
+              <Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
+                {t('password.disablePassword.desc')}
+                <Box px={7} mt={4} flow={3}>
+                  <Box flow={1}>
+                    <Label htmlFor="password">
+                      {t('password.inputFields.currentPassword.label')}
+                    </Label>
+                    <InputPassword
+                      autoFocus
+                      type="password"
+                      id="password"
+                      onChange={this.handleInputChange('currentPassword')}
+                      value={currentPassword}
+                      error={incorrectPassword}
+                    />
                   </Box>
                 </Box>
-              </ModalContent>
-              <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
+              </Box>
+            )}
+            renderFooter={() => (
+              <Box horizontal align="center" justify="flex-end" flow={2}>
                 <Button small type="button" onClick={onClose}>
                   {t('common.cancel')}
                 </Button>
@@ -103,11 +100,11 @@ class DisablePasswordModal extends PureComponent<Props, State> {
                 >
                   {t('common.save')}
                 </Button>
-              </ModalFooter>
-            </ModalBody>
-          </form>
-        )}
-      />
+              </Box>
+            )}
+          />
+        </form>
+      </Modal>
     )
   }
 }
diff --git a/src/components/SettingsPage/PasswordAutoLockSelect.js b/src/components/SettingsPage/PasswordAutoLockSelect.js
index 556fa845..8b643caf 100644
--- a/src/components/SettingsPage/PasswordAutoLockSelect.js
+++ b/src/components/SettingsPage/PasswordAutoLockSelect.js
@@ -30,10 +30,10 @@ class PasswordAutoLockSelect extends PureComponent<Props> {
   }
 
   timeouts = [
-    { value: 1, label: `1 ${this.props.t('app:time.minute')}` },
-    { value: 10, label: `10 ${this.props.t('app:time.minute')}s` },
-    { value: 30, label: `30 ${this.props.t('app:time.minute')}s` },
-    { value: 60, label: `1 ${this.props.t('app:time.hour')}` },
+    { value: 1, label: `1 ${this.props.t('time.minute')}` },
+    { value: 10, label: `10 ${this.props.t('time.minute')}s` },
+    { value: 30, label: `30 ${this.props.t('time.minute')}s` },
+    { value: 60, label: `1 ${this.props.t('time.hour')}` },
     { value: -1, label: this.props.t(`app:common.never`) },
   ]
 
diff --git a/src/components/SettingsPage/PasswordModal.js b/src/components/SettingsPage/PasswordModal.js
index c55e4056..1b8c3909 100644
--- a/src/components/SettingsPage/PasswordModal.js
+++ b/src/components/SettingsPage/PasswordModal.js
@@ -1,6 +1,6 @@
 // @flow
 
-import React, { PureComponent } from 'react'
+import React, { Fragment, PureComponent } from 'react'
 
 import type { T } from 'types/common'
 
@@ -8,7 +8,7 @@ import db from 'helpers/db'
 import { PasswordIncorrectError } from '@ledgerhq/errors'
 import Box from 'components/base/Box'
 import Button from 'components/base/Button'
-import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal'
+import Modal, { ModalBody } from 'components/base/Modal'
 
 import PasswordForm from './PasswordForm'
 
@@ -17,6 +17,7 @@ type Props = {
   onClose: () => void,
   onChangePassword: (?string) => void,
   hasPassword: boolean,
+  isOpened: boolean,
 }
 
 type State = {
@@ -36,6 +37,13 @@ const INITIAL_STATE = {
 class PasswordModal extends PureComponent<Props, State> {
   state = INITIAL_STATE
 
+  componentWillReceiveProps(nextProps: Props) {
+    if (!nextProps.isOpened) {
+      // CLean the state?
+      this.setState(prevState => ({ ...prevState, ...INITIAL_STATE }))
+    }
+  }
+
   handleSave = (e: SyntheticEvent<HTMLFormElement>) => {
     const { currentPassword, newPassword } = this.state
 
@@ -73,23 +81,17 @@ class PasswordModal extends PureComponent<Props, State> {
   }
 
   render() {
-    const { t, hasPassword, onClose, ...props } = this.props
+    const { t, hasPassword, onClose, isOpened, ...props } = this.props
     const { currentPassword, newPassword, incorrectPassword, confirmPassword } = this.state
     return (
-      <Modal
-        {...props}
-        onHide={this.handleReset}
-        onClose={onClose}
-        render={({ onClose }) => (
-          <ModalBody onClose={onClose}>
-            {hasPassword ? (
-              <ModalTitle>{t('password.changePassword.title')}</ModalTitle>
-            ) : (
-              <ModalTitle data-e2e="enablePassword_modal">
-                {t('password.setPassword.title')}
-              </ModalTitle>
-            )}
-            <ModalContent>
+      <Modal isOpened={isOpened} centered>
+        <ModalBody
+          {...props}
+          title={hasPassword ? t('password.changePassword.title') : t('password.setPassword.title')}
+          onHide={this.handleReset}
+          onClose={onClose}
+          render={() => (
+            <Fragment>
               <Box
                 ff="Museo Sans|Regular"
                 color="dark"
@@ -116,8 +118,10 @@ class PasswordModal extends PureComponent<Props, State> {
                 onChange={this.handleInputChange}
                 t={t}
               />
-            </ModalContent>
-            <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
+            </Fragment>
+          )}
+          renderFooter={() => (
+            <Box horizontal align="center" justify="flex-end" flow={2}>
               <Button
                 small
                 type="button"
@@ -134,10 +138,10 @@ class PasswordModal extends PureComponent<Props, State> {
               >
                 {t('common.save')}
               </Button>
-            </ModalFooter>
-          </ModalBody>
-        )}
-      />
+            </Box>
+          )}
+        />
+      </Modal>
     )
   }
 }
diff --git a/src/components/SettingsPage/RepairDeviceButton.js b/src/components/SettingsPage/RepairDeviceButton.js
index 511bed6e..1a26d384 100644
--- a/src/components/SettingsPage/RepairDeviceButton.js
+++ b/src/components/SettingsPage/RepairDeviceButton.js
@@ -10,7 +10,7 @@ import { push } from 'react-router-redux'
 import type { T } from 'types/common'
 import firmwareRepair from 'commands/firmwareRepair'
 import Button from 'components/base/Button'
-import { RepairModal } from 'components/base/Modal'
+import RepairModal from 'components/base/Modal/RepairModal'
 
 type Props = {
   t: T,
diff --git a/src/components/SettingsPage/ResetButton.js b/src/components/SettingsPage/ResetButton.js
index ba6745b5..2708c75e 100644
--- a/src/components/SettingsPage/ResetButton.js
+++ b/src/components/SettingsPage/ResetButton.js
@@ -9,7 +9,7 @@ import type { T } from 'types/common'
 import { hardReset } from 'helpers/reset'
 import Box from 'components/base/Box'
 import Button from 'components/base/Button'
-import { ConfirmModal } from 'components/base/Modal'
+import ConfirmModal from 'components/base/Modal/ConfirmModal'
 import IconTriangleWarning from 'icons/TriangleWarning'
 import ResetFallbackModal from './ResetFallbackModal'
 
@@ -58,6 +58,7 @@ class ResetButton extends PureComponent<Props, State> {
         <ConfirmModal
           analyticsName="HardReset"
           isDanger
+          centered
           isLoading={pending}
           isOpened={opened}
           onClose={this.close}
diff --git a/src/components/SettingsPage/ResetFallbackModal.js b/src/components/SettingsPage/ResetFallbackModal.js
index fece2e66..7ada15a9 100644
--- a/src/components/SettingsPage/ResetFallbackModal.js
+++ b/src/components/SettingsPage/ResetFallbackModal.js
@@ -3,7 +3,7 @@
 import React, { PureComponent } from 'react'
 import { translate } from 'react-i18next'
 
-import { ConfirmModal } from 'components/base/Modal'
+import ConfirmModal from 'components/base/Modal/ConfirmModal'
 import { openUserDataFolderAndQuit } from 'helpers/reset'
 
 type Props = {
diff --git a/src/components/SettingsPage/sections/Display.js b/src/components/SettingsPage/sections/Display.js
index 0335c741..176cb629 100644
--- a/src/components/SettingsPage/sections/Display.js
+++ b/src/components/SettingsPage/sections/Display.js
@@ -91,8 +91,8 @@ class TabGeneral extends PureComponent<Props> {
           </Row>
           {hasPassword ? (
             <Row
-              title={t('app:settings.profile.passwordAutoLock')}
-              desc={t('app:settings.profile.passwordAutoLockDesc')}
+              title={t('settings.profile.passwordAutoLock')}
+              desc={t('settings.profile.passwordAutoLockDesc')}
             >
               <PasswordAutoLockSelect />
             </Row>
diff --git a/src/components/SettingsPage/sections/Export.js b/src/components/SettingsPage/sections/Export.js
index 1231b31a..7d7bc88b 100644
--- a/src/components/SettingsPage/sections/Export.js
+++ b/src/components/SettingsPage/sections/Export.js
@@ -10,7 +10,8 @@ import styled from 'styled-components'
 import { SettingsSection as Section, SettingsSectionHeader as Header } from '../SettingsSection'
 import IconShare from '../../../icons/Share'
 import Button from '../../base/Button'
-import Modal, { ModalBody, ModalContent, ModalFooter, ModalTitle } from '../../base/Modal'
+import Modal from '../../base/Modal'
+import ModalBody from '../../base/Modal/ModalBody'
 import Box from '../../base/Box'
 import QRCodeExporter from '../../QRCodeExporter'
 import { BulletRow } from '../../Onboarding/helperComponents'
@@ -97,27 +98,32 @@ class SectionExport extends PureComponent<Props, State> {
     ]
 
     return (
-      <ModalBody onClose={onClose}>
-        <ModalTitle>{t('settings.export.modal.title')}</ModalTitle>
-        <ModalContent flow={2} justify="center" align="center">
-          <Box flow={2}>
-            <QRCodeExporter size={330} />
-          </Box>
-          <Box shrink style={{ width: 330, fontSize: 13, marginTop: 20 }}>
-            <Text ff="Open Sans|SemiBold" color="dark">
-              {t('settings.export.modal.listTitle')}
-            </Text>
+      <ModalBody
+        onClose={onClose}
+        title={t('settings.export.modal.title')}
+        render={() => (
+          <Box justify="center" align="center">
+            <Box flow={2}>
+              <QRCodeExporter size={330} />
+            </Box>
+            <Box shrink style={{ width: 330, fontSize: 13, marginTop: 20 }}>
+              <Text ff="Open Sans|SemiBold" color="dark">
+                {t('settings.export.modal.listTitle')}
+              </Text>
+            </Box>
+            <Box style={{ width: 330 }}>
+              {stepsImportMobile.map(step => <BulletRow key={step.key} step={step} />)}
+            </Box>
           </Box>
-          <Box style={{ width: 330 }}>
-            {stepsImportMobile.map(step => <BulletRow key={step.key} step={step} />)}
+        )}
+        renderFooter={() => (
+          <Box>
+            <Button small onClick={onClose} primary>
+              {t('settings.export.modal.button')}
+            </Button>
           </Box>
-        </ModalContent>
-        <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
-          <Button small onClick={onClose} primary>
-            {t('settings.export.modal.button')}
-          </Button>
-        </ModalFooter>
-      </ModalBody>
+        )}
+      />
     )
   }
 
@@ -139,7 +145,12 @@ class SectionExport extends PureComponent<Props, State> {
             </Button>
           }
         />
-        <Modal isOpened={isModalOpened} onClose={this.onModalClose} render={this.renderModal} />
+        <Modal
+          isOpened={isModalOpened}
+          centered
+          onClose={this.onModalClose}
+          render={this.renderModal}
+        />
       </Section>
     )
   }
diff --git a/src/components/base/Modal/ConfirmModal.js b/src/components/base/Modal/ConfirmModal.js
index 0512a981..416eb5a7 100644
--- a/src/components/base/Modal/ConfirmModal.js
+++ b/src/components/base/Modal/ConfirmModal.js
@@ -9,7 +9,8 @@ import TrackPage from 'analytics/TrackPage'
 import Button from 'components/base/Button'
 import Box from 'components/base/Box'
 
-import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from './index'
+import Modal from './index'
+import ModalBody from './ModalBody'
 
 type Props = {
   isOpened: boolean,
@@ -21,11 +22,13 @@ type Props = {
   confirmText?: string,
   cancelText?: string,
   onReject: Function,
+  onClose?: Function,
   onConfirm: Function,
   t: T,
   isLoading?: boolean,
   analyticsName: string,
   cancellable?: boolean,
+  centered?: boolean,
 }
 
 class ConfirmModal extends PureComponent<Props> {
@@ -43,23 +46,38 @@ class ConfirmModal extends PureComponent<Props> {
       onConfirm,
       isLoading,
       renderIcon,
+      onClose,
       t,
       analyticsName,
+      centered,
       ...props
     } = this.props
 
     const realConfirmText = confirmText || t('common.confirm')
     const realCancelText = cancelText || t('common.cancel')
     return (
-      <Modal
-        isOpened={isOpened}
-        preventBackdropClick={isLoading}
-        {...props}
-        render={({ onClose }) => (
-          <ModalBody onClose={!cancellable && isLoading ? undefined : onClose}>
-            <TrackPage category="Modal" name={analyticsName} />
-            <ModalTitle>{title}</ModalTitle>
-            <ModalContent>
+      <Modal isOpened={isOpened} centered={centered}>
+        <ModalBody
+          preventBackdropClick={isLoading}
+          {...props}
+          onClose={!cancellable && isLoading ? undefined : onClose}
+          title={title}
+          renderFooter={() => (
+            <Box horizontal align="center" justify="flex-end" flow={2}>
+              {!isLoading && <Button onClick={onReject}>{realCancelText}</Button>}
+              <Button
+                onClick={onConfirm}
+                primary={!isDanger}
+                danger={isDanger}
+                isLoading={isLoading}
+                disabled={isLoading}
+              >
+                {realConfirmText}
+              </Button>
+            </Box>
+          )}
+          render={() => (
+            <Box>
               {subTitle && (
                 <Box ff="Museo Sans|Regular" color="dark" textAlign="center" mb={2} mt={3}>
                   {subTitle}
@@ -73,22 +91,11 @@ class ConfirmModal extends PureComponent<Props> {
               <Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center">
                 {desc}
               </Box>
-            </ModalContent>
-            <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
-              {!isLoading && <Button onClick={onReject}>{realCancelText}</Button>}
-              <Button
-                onClick={onConfirm}
-                primary={!isDanger}
-                danger={isDanger}
-                isLoading={isLoading}
-                disabled={isLoading}
-              >
-                {realConfirmText}
-              </Button>
-            </ModalFooter>
-          </ModalBody>
-        )}
-      />
+            </Box>
+          )}
+        />
+        <TrackPage category="Modal" name={analyticsName} />
+      </Modal>
     )
   }
 }
diff --git a/src/components/base/Modal/ModalBody.js b/src/components/base/Modal/ModalBody.js
index c0083590..363f10aa 100644
--- a/src/components/base/Modal/ModalBody.js
+++ b/src/components/base/Modal/ModalBody.js
@@ -1,95 +1,102 @@
 // @flow
 
-import React, { PureComponent } from 'react'
-import styled, { keyframes } from 'styled-components'
+import React, { PureComponent, Fragment } from 'react'
+import Animated from 'animated/lib/targets/react-dom'
+import { findDOMNode } from 'react-dom'
 
-import Box from 'components/base/Box'
-import IconCross from 'icons/Cross'
+import ModalContent from './ModalContent'
+import ModalHeader from './ModalHeader'
+import ModalFooter from './ModalFooter'
 
-export const Container = styled(Box).attrs({
-  px: 5,
-  pb: 5,
-})``
+import type { RenderProps } from './index'
 
 type Props = {
-  deferHeight?: number,
-  onClose?: Function,
-  children: any,
+  title: string,
+  onBack?: void => void,
+  onClose?: void => void,
+  render?: (?RenderProps) => any,
+  renderFooter?: (?RenderProps) => any,
+  renderProps?: RenderProps,
+  noScroll?: boolean,
+  refocusWhenChange?: any,
 }
 
 type State = {
-  isHidden: boolean,
+  animGradient: Animated.Value,
 }
 
 class ModalBody extends PureComponent<Props, State> {
-  static defaultProps = {
-    onClose: undefined,
+  state = {
+    animGradient: new Animated.Value(0),
   }
 
-  state = {
-    isHidden: true,
+  componentDidUpdate(prevProps: Props) {
+    const shouldFocus = prevProps.refocusWhenChange !== this.props.refocusWhenChange
+    if (shouldFocus) {
+      if (this._content) {
+        const node = findDOMNode(this._content) // eslint-disable-line react/no-find-dom-node
+        if (node) {
+          // $FlowFixMe
+          node.focus()
+        }
+      }
+    }
   }
 
-  componentDidMount() {
-    setTimeout(() => {
-      window.requestAnimationFrame(() => {
-        this.setState({ isHidden: false })
-      })
-    }, 150)
+  _content = null
+
+  animateGradient = (isScrollable: boolean) => {
+    const anim = {
+      duration: 150,
+      toValue: isScrollable ? 1 : 0,
+    }
+    Animated.timing(this.state.animGradient, anim).start()
   }
 
   render() {
-    const { children, onClose, deferHeight, ...props } = this.props
-    const { isHidden } = this.state
+    const { onBack, onClose, title, render, renderFooter, renderProps, noScroll } = this.props
+    const { animGradient } = this.state
+
+    const gradientStyle = {
+      ...GRADIENT_STYLE,
+      opacity: animGradient,
+    }
+
     return (
-      <Body
-        style={{ height: isHidden && deferHeight ? deferHeight : undefined }}
-        data-e2e="modalBody"
-      >
-        {onClose && (
-          <CloseContainer onClick={onClose}>
-            <IconCross size={16} />
-          </CloseContainer>
-        )}
-        {(!isHidden || !deferHeight) && <Inner {...props}>{children}</Inner>}
-      </Body>
+      <Fragment>
+        <ModalHeader onBack={onBack} onClose={onClose}>
+          {title}
+        </ModalHeader>
+        <ModalContent
+          tabIndex={0}
+          ref={n => (this._content = n)}
+          onIsScrollableChange={this.animateGradient}
+          noScroll={noScroll}
+        >
+          {render && render(renderProps)}
+        </ModalContent>
+        <div style={GRADIENT_WRAPPER_STYLE}>
+          <Animated.div style={gradientStyle} />
+        </div>
+        {renderFooter && <ModalFooter>{renderFooter(renderProps)}</ModalFooter>}
+      </Fragment>
     )
   }
 }
 
-const CloseContainer = styled(Box).attrs({
-  p: 4,
-  color: 'fog',
-})`
-  position: absolute;
-  top: 0;
-  right: 0;
-  z-index: 1;
-
-  &:hover {
-    color: ${p => p.theme.colors.grey};
-  }
-
-  &:active {
-    color: ${p => p.theme.colors.dark};
-  }
-`
-
-const Body = styled(Box).attrs({
-  bg: p => p.theme.colors.white,
-  relative: true,
-  borderRadius: 1,
-})`
-  box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.2);
-`
-
-const appear = keyframes`
-  from { opacity: 0; }
-  to { opacity: 1; }
-`
+const GRADIENT_STYLE = {
+  background: 'linear-gradient(rgba(255, 255, 255, 0), #ffffff)',
+  height: 40,
+  position: 'absolute',
+  bottom: 0,
+  left: 0,
+  right: 6,
+}
 
-const Inner = styled(Box)`
-  animation: ${appear} 80ms linear;
-`
+const GRADIENT_WRAPPER_STYLE = {
+  height: 0,
+  position: 'relative',
+  pointerEvents: 'none',
+}
 
 export default ModalBody
diff --git a/src/components/base/Modal/ModalContent.js b/src/components/base/Modal/ModalContent.js
new file mode 100644
index 00000000..7b74ddd1
--- /dev/null
+++ b/src/components/base/Modal/ModalContent.js
@@ -0,0 +1,59 @@
+// @flow
+
+/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
+
+import React, { PureComponent } from 'react'
+
+class ModalContent extends PureComponent<{
+  children: any,
+  onIsScrollableChange: boolean => void,
+  noScroll?: boolean,
+}> {
+  componentDidMount() {
+    window.requestAnimationFrame(() => {
+      if (this._isUnmounted) return
+      this.showHideGradient()
+      if (this._outer) {
+        const ro = new ResizeObserver(this.showHideGradient)
+        ro.observe(this._outer)
+      }
+    })
+  }
+
+  componentWillUnmount() {
+    this._isUnmounted = true
+  }
+
+  _outer = null
+  _isUnmounted = false
+
+  showHideGradient = () => {
+    if (!this._outer) return
+    const { onIsScrollableChange } = this.props
+    const isScrollable = this._outer.scrollHeight > this._outer.clientHeight
+    onIsScrollableChange(isScrollable)
+  }
+
+  render() {
+    const { children, noScroll } = this.props
+
+    const contentStyle = {
+      ...CONTENT_STYLE,
+      overflow: noScroll ? 'visible' : 'auto',
+    }
+
+    return (
+      <div style={contentStyle} ref={n => (this._outer = n)} tabIndex={0}>
+        {children}
+      </div>
+    )
+  }
+}
+
+const CONTENT_STYLE = {
+  flexShrink: 1,
+  padding: 20,
+  paddingBottom: 40,
+}
+
+export default ModalContent
diff --git a/src/components/base/Modal/ModalFooter.js b/src/components/base/Modal/ModalFooter.js
new file mode 100644
index 00000000..97f7c083
--- /dev/null
+++ b/src/components/base/Modal/ModalFooter.js
@@ -0,0 +1,18 @@
+// @flow
+
+import React from 'react'
+
+import { colors } from 'styles/theme'
+
+const MODAL_FOOTER_STYLE = {
+  display: 'flex',
+  justifyContent: 'flex-end',
+  borderTop: `2px solid ${colors.lightGrey}`,
+  padding: 20,
+}
+
+const ModalFooter = ({ children }: { children: any }) => (
+  <div style={MODAL_FOOTER_STYLE}>{children}</div>
+)
+
+export default ModalFooter
diff --git a/src/components/base/Modal/ModalHeader.js b/src/components/base/Modal/ModalHeader.js
new file mode 100644
index 00000000..e3078e8d
--- /dev/null
+++ b/src/components/base/Modal/ModalHeader.js
@@ -0,0 +1,93 @@
+// @flow
+
+import React from 'react'
+import styled from 'styled-components'
+import { translate } from 'react-i18next'
+
+import type { T } from 'types/common'
+
+import Box from 'components/base/Box'
+
+import IconAngleLeft from 'icons/AngleLeft'
+import IconCross from 'icons/Cross'
+
+const MODAL_HEADER_STYLE = {
+  position: 'relative',
+  display: 'flex',
+  alignItems: 'center',
+  justifyContent: 'center',
+  padding: 20,
+}
+
+const ModalTitle = styled(Box).attrs({
+  color: 'dark',
+  ff: 'Museo Sans|Regular',
+  fontSize: 6,
+  grow: true,
+  shrink: true,
+})`
+  text-align: center;
+  line-height: 1;
+`
+
+const iconAngleLeft = <IconAngleLeft size={16} />
+const iconCross = <IconCross size={16} />
+
+const ModalHeaderAction = styled(Box).attrs({
+  horizontal: true,
+  align: 'center',
+  fontSize: 3,
+  p: 4,
+  color: 'grey',
+})`
+  position: absolute;
+  top: 0;
+  left: ${p => (p.right ? 'auto' : 0)};
+  right: ${p => (p.right ? 0 : 'auto')};
+  line-height: 0;
+  cursor: pointer;
+
+  &:hover {
+    color: ${p => p.theme.colors.graphite};
+  }
+
+  &:active {
+    color: ${p => p.theme.colors.dark};
+  }
+
+  span {
+    border-bottom: 1px dashed transparent;
+  }
+  &:focus span {
+    border-bottom-color: inherit;
+  }
+`
+
+const ModalHeader = ({
+  children,
+  onBack,
+  onClose,
+  t,
+}: {
+  children: any,
+  onBack: void => void,
+  onClose: void => void,
+  t: T,
+}) => (
+  <div style={MODAL_HEADER_STYLE}>
+    {onBack && (
+      <ModalHeaderAction onClick={onBack}>
+        {iconAngleLeft}
+        <span>{t('common.back')}</span>
+      </ModalHeaderAction>
+    )}
+    <ModalTitle>{children}</ModalTitle>
+    {onClose && (
+      <ModalHeaderAction right color="fog" onClick={onClose}>
+        {iconCross}
+      </ModalHeaderAction>
+    )}
+  </div>
+)
+
+export default translate()(ModalHeader)
diff --git a/src/components/base/Modal/ModalTitle.js b/src/components/base/Modal/ModalTitle.js
deleted file mode 100644
index 55cf2fb4..00000000
--- a/src/components/base/Modal/ModalTitle.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// @flow
-
-import React from 'react'
-import styled from 'styled-components'
-import { translate } from 'react-i18next'
-
-import type { T } from 'types/common'
-
-import Box from 'components/base/Box'
-import IconAngleLeft from 'icons/AngleLeft'
-
-const Container = styled(Box).attrs({
-  alignItems: 'center',
-  color: 'dark',
-  ff: 'Museo Sans|Regular',
-  fontSize: 6,
-  justifyContent: 'center',
-  p: 5,
-  relative: true,
-})``
-
-const Back = styled(Box).attrs({
-  unstyled: true,
-  horizontal: true,
-  align: 'center',
-  color: 'grey',
-  ff: 'Open Sans',
-  fontSize: 3,
-  p: 4,
-})`
-  position: absolute;
-  line-height: 1;
-  top: 0;
-  left: 0;
-
-  &:hover {
-    color: ${p => p.theme.colors.graphite};
-  }
-
-  &:active {
-    color: ${p => p.theme.colors.dark};
-  }
-
-  span {
-    border-bottom: 1px dashed transparent;
-  }
-  &:focus span {
-    border-bottom-color: inherit;
-  }
-`
-
-function ModalTitle({
-  t,
-  onBack,
-  children,
-  ...props
-}: {
-  t: T,
-  onBack: any => void,
-  children: any,
-}) {
-  return (
-    <Container {...props} data-e2e="modal_title">
-      {onBack && (
-        <Back onClick={onBack}>
-          <IconAngleLeft size={16} />
-          <span>{t('common.back')}</span>
-        </Back>
-      )}
-      {children}
-    </Container>
-  )
-}
-
-export default translate()(ModalTitle)
diff --git a/src/components/base/Modal/RepairModal.js b/src/components/base/Modal/RepairModal.js
index a69d839c..bf01337e 100644
--- a/src/components/base/Modal/RepairModal.js
+++ b/src/components/base/Modal/RepairModal.js
@@ -17,7 +17,8 @@ import ProgressCircle from 'components/ProgressCircle'
 import TranslatedError from 'components/TranslatedError'
 import ExclamationCircleThin from 'icons/ExclamationCircleThin'
 
-import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from './index'
+import Modal from './index'
+import ModalBody from './ModalBody'
 
 const Container = styled(Box).attrs({
   alignItems: 'center',
@@ -39,18 +40,18 @@ const Separator = styled(Box).attrs({
 `
 
 const DisclaimerStep = ({ desc }: { desc?: string }) => (
-  <ModalContent>
+  <Box>
     {desc ? (
       <Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" mb={2}>
         {desc}
       </Box>
     ) : null}
-  </ModalContent>
+  </Box>
 )
 
 const FlashStep = ({ progress, t }: { progress: number, t: * }) =>
   progress === 0 ? (
-    <ModalContent>
+    <Box>
       <Box mx={7}>
         <Text ff="Open Sans|Regular" align="center" color="smoke">
           <Bullet>{'1.'}</Bullet>
@@ -74,9 +75,9 @@ const FlashStep = ({ progress, t }: { progress: number, t: * }) =>
           alt={t('manager.modal.mcuFirst')}
         />
       </Box>
-    </ModalContent>
+    </Box>
   ) : (
-    <ModalContent>
+    <Box>
       <Box mx={7} align="center">
         <ProgressCircle size={64} progress={progress} />
       </Box>
@@ -88,11 +89,11 @@ const FlashStep = ({ progress, t }: { progress: number, t: * }) =>
           {t('manager.modal.mcuPin')}
         </Text>
       </Box>
-    </ModalContent>
+    </Box>
   )
 
 const ErrorStep = ({ error }: { error: Error }) => (
-  <ModalContent>
+  <Box>
     <Container>
       <Box color="alertRed">
         <ExclamationCircleThin size={44} />
@@ -118,7 +119,7 @@ const ErrorStep = ({ error }: { error: Error }) => (
         <TranslatedError error={error} field="description" />
       </Box>
     </Container>
-  </ModalContent>
+  </Box>
 )
 
 type Props = {
@@ -177,38 +178,44 @@ class RepairModal extends PureComponent<Props, *> {
     return (
       <Modal
         isOpened={isOpened}
+        centered
         preventBackdropClick={isLoading}
+        onClose={!cancellable && isLoading ? undefined : onReject}
         {...props}
-        render={({ onClose }) => (
-          <ModalBody onClose={!cancellable && isLoading ? undefined : onClose}>
-            <TrackPage category="Modal" name={analyticsName} />
-            <ModalTitle>{title}</ModalTitle>
-            {error ? (
-              <ErrorStep error={error} />
-            ) : isLoading ? (
-              <FlashStep t={t} progress={progress} />
-            ) : (
-              <DisclaimerStep desc={desc} />
-            )}
-
-            {!isLoading && !error ? (
-              <Box py={2} px={5}>
-                <Select
-                  isSearchable={false}
-                  isClearable={false}
-                  value={selectedOption}
-                  onChange={this.onChange}
-                  autoFocus
-                  options={forceRepairChoices}
-                  renderOption={this.renderOption}
-                  renderValue={this.renderValue}
-                />
-              </Box>
-            ) : null}
-
-            {!isLoading ? (
-              <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
-                {error ? <Button onClick={onReject}>{t(`common.close`)}</Button> : null}
+      >
+        <TrackPage category="Modal" name={analyticsName} />
+        <ModalBody
+          title={title}
+          render={() => (
+            <Box>
+              {error ? (
+                <ErrorStep error={error} />
+              ) : isLoading ? (
+                <FlashStep t={t} progress={progress} />
+              ) : (
+                <DisclaimerStep desc={desc} />
+              )}
+
+              {!isLoading && !error ? (
+                <Box py={2} px={5}>
+                  <Select
+                    isSearchable={false}
+                    isClearable={false}
+                    value={selectedOption}
+                    onChange={this.onChange}
+                    autoFocus
+                    options={forceRepairChoices}
+                    renderOption={this.renderOption}
+                    renderValue={this.renderValue}
+                  />
+                </Box>
+              ) : null}
+            </Box>
+          )}
+          renderFooter={() =>
+            !isLoading ? (
+              <Box horizontal align="center" justify="flex-end" flow={2}>
+                <Button onClick={onReject}>{t(`common.${error ? 'close' : 'cancel'}`)}</Button>
                 {error ? null : (
                   <>
                     <Button
@@ -222,11 +229,11 @@ class RepairModal extends PureComponent<Props, *> {
                     </Button>
                   </>
                 )}
-              </ModalFooter>
-            ) : null}
-          </ModalBody>
-        )}
-      />
+              </Box>
+            ) : null
+          }
+        />
+      </Modal>
     )
   }
 }
diff --git a/src/components/base/Modal/index.js b/src/components/base/Modal/index.js
index cad43fda..ff0ae518 100644
--- a/src/components/base/Modal/index.js
+++ b/src/components/base/Modal/index.js
@@ -1,54 +1,28 @@
 // @flow
 
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable react/no-multi-comp */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
 
-import React, { Component } from 'react'
-import { findDOMNode } from 'react-dom'
+import React, { PureComponent, Fragment } from 'react'
+import { createPortal } from 'react-dom'
 import { connect } from 'react-redux'
-import Mortal from 'react-mortal'
-import styled from 'styled-components'
 import noop from 'lodash/noop'
-import { EXPERIMENTAL_CENTER_MODAL } from 'config/constants'
-
-import { rgba } from 'styles/helpers'
-import { radii } from 'styles/theme'
+import Animated from 'animated/lib/targets/react-dom'
+import Easing from 'animated/lib/Easing'
 
 import { closeModal, isModalOpened, getModalData } from 'reducers/modals'
-
-import Box from 'components/base/Box'
-import GrowScroll from 'components/base/GrowScroll'
+import { colors } from 'styles/theme'
 
 export { default as ModalBody } from './ModalBody'
-export { default as ConfirmModal } from './ConfirmModal'
-export { default as RepairModal } from './RepairModal'
-export { default as ModalTitle } from './ModalTitle'
 
-const springConfig = {
-  stiffness: 320,
+const animShowHide = {
+  duration: 200,
+  easing: Easing.bezier(0.3, 1.0, 0.5, 0.8),
 }
 
-type OwnProps = {
-  name?: string, // eslint-disable-line
-  isOpened?: boolean,
-  onBeforeOpen?: ({ data: * }) => *, // eslint-disable-line
-  onClose?: () => void,
-  onHide?: () => void,
-  preventBackdropClick?: boolean,
-  render: Function,
-  refocusWhenChange?: string,
-  width?: string,
-}
+const domNode = process.env.STORYBOOK_ENV ? document.body : document.getElementById('modals')
 
-type Props = OwnProps & {
-  isOpened?: boolean,
-  data?: any,
-} & {
-  onClose?: () => void,
-}
-
-const mapStateToProps = (state, { name, isOpened, onBeforeOpen }: OwnProps): * => {
+const mapStateToProps = (state, { name, isOpened, onBeforeOpen }: Props): * => {
   const data = getModalData(state, name || '')
   const modalOpened = isOpened || (name && isModalOpened(state, name))
 
@@ -62,7 +36,7 @@ const mapStateToProps = (state, { name, isOpened, onBeforeOpen }: OwnProps): * =
   }
 }
 
-const mapDispatchToProps = (dispatch: *, { name, onClose = noop }: OwnProps): * => ({
+const mapDispatchToProps = (dispatch: *, { name, onClose = noop }: Props): * => ({
   onClose: name
     ? () => {
         dispatch(closeModal(name))
@@ -71,178 +45,187 @@ const mapDispatchToProps = (dispatch: *, { name, onClose = noop }: OwnProps): *
     : onClose,
 })
 
-const Container = styled(Box).attrs({
-  color: 'grey',
-  sticky: true,
-  style: p => ({
-    pointerEvents: p.isVisible ? 'auto' : 'none',
-  }),
-})`
-  position: fixed;
-  z-index: 30;
-`
-
-const Backdrop = styled(Box).attrs({
-  bg: p => rgba(p.theme.colors.black, 0.4),
-  sticky: true,
-  style: p => ({
-    opacity: p.op,
-  }),
-})`
-  position: fixed;
-`
-
-const NonClickableHeadArea = styled.div`
-  position: fixed;
-  height: 48px;
-  width: 100%;
-  top: 0;
-  left: 0;
-  z-index: 1;
-`
-
-const Wrapper = styled(Box).attrs({
-  bg: 'transparent',
-  flow: 4,
-  style: p => ({
-    opacity: p.op,
-    transform: `scale3d(${p.scale}, ${p.scale}, ${p.scale})`,
-  }),
-})`
-  outline: none;
-  width: ${p => (p.width ? p.width : '500px')};
-  z-index: 2;
-`
-
-class Pure extends Component<any> {
-  shouldComponentUpdate(nextProps) {
-    if (nextProps.isAnimated) {
-      return false
-    }
-
-    return true
-  }
+export type RenderProps = {
+  onClose?: void => void,
+  data: any,
+}
 
-  render() {
-    const { data, onClose, render } = this.props
+type Props = {
+  isOpened?: boolean,
+  children?: any,
+  centered?: boolean,
+  onClose?: void => void,
+  onHide?: void => void,
+  render?: RenderProps => any,
+  data?: any,
+  preventBackdropClick?: boolean,
 
-    return render({ data, onClose })
-  }
+  name?: string, // eslint-disable-line
+  onBeforeOpen?: ({ data: * }) => *, // eslint-disable-line
 }
 
-function stopPropagation(e) {
-  e.stopPropagation()
+type State = {
+  animShowHide: Animated.Value,
+  isInDOM: boolean,
 }
 
-const wrap = EXPERIMENTAL_CENTER_MODAL
-  ? children => (
-      <Box alignItems="center" justifyContent="center" grow>
-        {children}
-      </Box>
-    )
-  : children => (
-      <GrowScroll alignItems="center" full pt={8}>
-        {children}
-      </GrowScroll>
-    )
+class Modal extends PureComponent<Props, State> {
+  state = {
+    animShowHide: new Animated.Value(0),
+    isInDOM: this.props.isOpened === true,
+  }
 
-export class Modal extends Component<Props> {
-  static defaultProps = {
-    isOpened: false,
-    onHide: noop,
-    preventBackdropClick: false,
+  static getDerivedStateFromProps(nextProps: Props) {
+    const patch = {}
+    if (nextProps.isOpened) {
+      patch.isInDOM = true
+    }
+    return patch
   }
 
-  shouldComponentUpdate(nextProps: Props) {
-    if (this.props.isOpened || nextProps.isOpened) {
-      return true
+  componentDidMount() {
+    if (this.props.isOpened) {
+      this.animateEnter()
     }
 
-    return false
+    this.state.animShowHide.addListener(({ value }) => {
+      if (value === 0) {
+        const { onHide } = this.props
+        this.setState({ isInDOM: false })
+        if (onHide) {
+          onHide()
+        }
+      }
+      if (value === 1) this.setState({ isInDOM: true })
+    })
+
+    document.addEventListener('keyup', this.handleKeyup)
   }
 
   componentDidUpdate(prevProps: Props) {
-    const didOpened = this.props.isOpened && !prevProps.isOpened
-    const didClose = !this.props.isOpened && prevProps.isOpened
-    const shouldFocus = didOpened || this.props.refocusWhenChange !== prevProps.refocusWhenChange
+    const didOpened = !prevProps.isOpened && this.props.isOpened
+    const didClosed = prevProps.isOpened && !this.props.isOpened
+
     if (didOpened) {
-      // Store a reference to the last active element, to restore it after
-      // modal close
-      this._lastFocusedElement = document.activeElement
-    }
-    if (shouldFocus) {
-      this.focusWrapper()
+      this.animateEnter()
     }
 
-    if (didClose) {
-      if (this._lastFocusedElement) {
-        this._lastFocusedElement.focus()
-      }
+    if (didClosed) {
+      this.animateLeave()
     }
   }
 
-  _wrapper = null
-  _lastFocusedElement = null
+  componentWillUnmount() {
+    document.removeEventListener('keyup', this.handleKeyup)
+  }
+
+  handleKeyup = (e: KeyboardEvent) => {
+    const { onClose, preventBackdropClick } = this.props
+    if (e.which === 27 && onClose && !preventBackdropClick) {
+      onClose()
+    }
+  }
 
-  focusWrapper = () => {
-    // Forced to use findDOMNode here, because innerRef is giving a proxied component
-    const domWrapper = findDOMNode(this._wrapper) // eslint-disable-line react/no-find-dom-node
-    if (domWrapper instanceof HTMLDivElement && !domWrapper.contains(this._lastFocusedElement)) {
-      domWrapper.focus()
+  handleClickOnBackdrop = () => {
+    const { preventBackdropClick, onClose } = this.props
+    if (!preventBackdropClick && onClose) {
+      onClose()
     }
   }
 
+  swallowClick = e => {
+    e.preventDefault()
+    e.stopPropagation()
+  }
+
+  animateEnter = () =>
+    Animated.timing(this.state.animShowHide, { ...animShowHide, toValue: 1 }).start()
+
+  animateLeave = () =>
+    Animated.timing(this.state.animShowHide, { ...animShowHide, toValue: 0 }).start()
+
   render() {
-    const { preventBackdropClick, isOpened, onHide, render, data, onClose, width } = this.props
-
-    return (
-      <Mortal
-        isOpened={isOpened}
-        onClose={onClose}
-        onHide={onHide}
-        closeOnEsc={!preventBackdropClick}
-        motionStyle={(spring, isVisible) => ({
-          opacity: spring(isVisible ? 1 : 0, springConfig),
-          scale: spring(isVisible ? 1 : 0.95, springConfig),
-        })}
-      >
-        {(m, isVisible, isAnimated) => (
-          <Container isVisible={isVisible} onClick={preventBackdropClick ? undefined : onClose}>
-            <Backdrop op={m.opacity} />
-            <NonClickableHeadArea onClick={stopPropagation} />
-            {wrap(
-              <Wrapper
-                tabIndex={-1}
-                op={m.opacity}
-                scale={m.scale}
-                innerRef={n => (this._wrapper = n)}
-                onClick={stopPropagation}
-                width={width}
-              >
-                <Pure isAnimated={isAnimated} render={render} data={data} onClose={onClose} />
-              </Wrapper>,
-            )}
-          </Container>
-        )}
-      </Mortal>
+    const { animShowHide, isInDOM } = this.state
+    const { children, render, centered, onClose, data, isOpened } = this.props
+
+    if (!isInDOM) {
+      return null
+    }
+
+    const backdropStyle = {
+      ...BACKDROP_STYLE,
+      opacity: animShowHide,
+    }
+
+    const containerStyle = {
+      ...CONTAINER_STYLE,
+      justifyContent: centered ? 'center' : 'flex-start',
+      pointerEvents: isOpened ? 'auto' : 'none',
+    }
+
+    const scale = animShowHide.interpolate({
+      inputRange: [0, 1],
+      outputRange: [1.1, 1],
+      clamp: true,
+    })
+
+    const bodyWrapperStyle = {
+      ...BODY_WRAPPER_STYLE,
+      opacity: animShowHide,
+      transform: [{ scale }],
+    }
+
+    const renderProps = {
+      onClose,
+      data,
+    }
+
+    const modal = (
+      <Fragment>
+        <Animated.div style={backdropStyle} />
+        <div style={containerStyle} onClick={this.handleClickOnBackdrop}>
+          <Animated.div style={bodyWrapperStyle} onClick={this.swallowClick}>
+            {render && render(renderProps)}
+            {children}
+          </Animated.div>
+        </div>
+      </Fragment>
     )
+
+    return domNode ? createPortal(modal, domNode) : null
   }
 }
 
-export const ModalFooter = styled(Box).attrs({
-  px: 5,
-  py: 3,
-})`
-  border-top: 2px solid ${p => p.theme.colors.lightGrey};
-  border-bottom-left-radius: ${radii[1]}px;
-  border-bottom-right-radius: ${radii[1]}px;
-`
-
-export const ModalContent = styled(Box).attrs({
-  px: 5,
-  pb: 5,
-  selectable: true,
-})``
+const BACKDROP_STYLE = {
+  pointerEvents: 'none',
+  position: 'fixed',
+  top: 0,
+  left: 0,
+  right: 0,
+  bottom: 0,
+  background: 'rgba(0, 0, 0, 0.4)',
+  zIndex: 100,
+}
+
+const CONTAINER_STYLE = {
+  ...BACKDROP_STYLE,
+  background: 'transparent',
+  padding: '60px 0 60px 0',
+  display: 'flex',
+  flexDirection: 'column',
+  alignItems: 'center',
+}
+
+const BODY_WRAPPER_STYLE = {
+  background: 'white',
+  width: 500,
+  borderRadius: 3,
+  boxShadow: 'box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.2)',
+  color: colors.smoke,
+  flexShrink: 1,
+  display: 'flex',
+  flexDirection: 'column',
+}
 
 export default connect(
   mapStateToProps,
diff --git a/src/components/base/Modal/stories.js b/src/components/base/Modal/stories.js
index 9e946800..2eb46bb4 100644
--- a/src/components/base/Modal/stories.js
+++ b/src/components/base/Modal/stories.js
@@ -2,50 +2,57 @@
 
 import React from 'react'
 import { storiesOf } from '@storybook/react'
-import { action } from '@storybook/addon-actions'
 import { boolean, text } from '@storybook/addon-knobs'
+import { action } from '@storybook/addon-actions'
 
-import {
-  Modal,
-  ModalBody,
-  ModalTitle,
-  ModalContent,
-  ModalFooter,
-  ConfirmModal,
-} from 'components/base/Modal'
+import Modal from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
+import Input from 'components/base/Input'
+import Label from 'components/base/Label'
 import Box from 'components/base/Box'
-import Button from 'components/base/Button'
 
 const stories = storiesOf('Components/base', module)
 
 stories.add('Modal', () => (
   <Modal
     isOpened={boolean('isOpened', true)}
+    centered={boolean('centered', true)}
+    onClose={action('onClose')}
     render={({ onClose }) => (
-      <ModalBody onClose={onClose}>
-        <ModalTitle>{'modal title'}</ModalTitle>
-        <ModalContent>{'this is the modal content'}</ModalContent>
-        <ModalFooter horizontal align="center">
-          <Box grow>{'modal footer'}</Box>
-          <Button primary>{'Next'}</Button>
-        </ModalFooter>
-      </ModalBody>
-    )}
-  />
-))
-
-stories.add('ConfirmModal', () => (
-  <ConfirmModal
-    categoryName=""
-    isOpened
-    isDanger={boolean('isDanger', false)}
-    title={text('title', 'Hard reset')}
-    subTitle={text('subTitle', 'Are you sure houston?')}
-    desc={text(
-      'desc',
-      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. In eget ipsum arcu donec finibus',
+      <ModalBody
+        onClose={onClose}
+        onBack={action('onBack')}
+        title={text('title', 'Send funds')}
+        render={() => (
+          <Box flow={4}>
+            <Box flow={2}>
+              <Label>{'first field'}</Label>
+              <Input autoFocus />
+            </Box>
+            <Box horizontal flow={4}>
+              <Box flow={2} flex={1}>
+                <Label>{'second field'}</Label>
+                <Input />
+              </Box>
+              <Box flow={2} flex={1}>
+                <Label>{'third field'}</Label>
+                <Input />
+              </Box>
+            </Box>
+            <Box horizontal flow={4}>
+              <Box flow={2} flex={1}>
+                <Label>{'second field'}</Label>
+                <Input />
+              </Box>
+              <Box flow={2} flex={1}>
+                <Label>{'third field'}</Label>
+                <Input />
+              </Box>
+            </Box>
+          </Box>
+        )}
+        renderFooter={() => 'footer'}
+      />
     )}
-    onConfirm={action('onConfirm')}
-    onReject={action('onReject')}
   />
 ))
diff --git a/src/components/base/Stepper/index.js b/src/components/base/Stepper/index.js
index 8daf4acb..73511549 100644
--- a/src/components/base/Stepper/index.js
+++ b/src/components/base/Stepper/index.js
@@ -1,12 +1,12 @@
 // @flow
 
-import React, { PureComponent } from 'react'
+import React, { PureComponent, Fragment } from 'react'
 import invariant from 'invariant'
 import { translate } from 'react-i18next'
 
 import type { T } from 'types/common'
 
-import { ModalContent, ModalTitle, ModalFooter, ModalBody } from 'components/base/Modal'
+import { ModalBody } from 'components/base/Modal'
 import Breadcrumb from 'components/Breadcrumb'
 
 type Props = {
@@ -29,6 +29,7 @@ export type Step = {
   shouldRenderFooter?: StepProps => boolean,
   shouldPreventClose?: boolean | (StepProps => boolean),
   onBack?: StepProps => void,
+  noScroll?: boolean,
 }
 
 type State = {
@@ -72,6 +73,7 @@ class Stepper extends PureComponent<Props, State> {
       onBack,
       shouldPreventClose,
       shouldRenderFooter,
+      noScroll,
     } = step
 
     const stepProps: StepProps = {
@@ -89,25 +91,27 @@ class Stepper extends PureComponent<Props, State> {
         : !!shouldPreventClose
 
     return (
-      <ModalBody onClose={preventClose ? undefined : onClose}>
-        <ModalTitle onBack={onBack ? () => onBack(stepProps) : undefined}>{title}</ModalTitle>
-        <ModalContent>
-          <Breadcrumb
-            mb={6}
-            currentStep={stepIndex}
-            items={steps}
-            stepsDisabled={disabledSteps}
-            stepsErrors={errorSteps}
-          />
-          <StepComponent {...stepProps} />
-          {children}
-        </ModalContent>
-        {renderFooter && (
-          <ModalFooter horizontal align="center" justify="flex-end">
-            <StepFooter {...stepProps} />
-          </ModalFooter>
+      <ModalBody
+        refocusWhenChange={stepId}
+        onClose={preventClose ? undefined : onClose}
+        onBack={onBack ? () => onBack(stepProps) : undefined}
+        title={title}
+        noScroll={noScroll}
+        render={() => (
+          <Fragment>
+            <Breadcrumb
+              mb={6}
+              currentStep={stepIndex}
+              items={steps}
+              stepsDisabled={disabledSteps}
+              stepsErrors={errorSteps}
+            />
+            <StepComponent {...stepProps} />
+            {children}
+          </Fragment>
         )}
-      </ModalBody>
+        renderFooter={renderFooter ? () => <StepFooter {...stepProps} /> : undefined}
+      />
     )
   }
 }
diff --git a/src/components/modals/AccountSettingRenderBody.js b/src/components/modals/AccountSettingRenderBody.js
index eb1e1d0d..552470bd 100644
--- a/src/components/modals/AccountSettingRenderBody.js
+++ b/src/components/modals/AccountSettingRenderBody.js
@@ -1,6 +1,6 @@
 // @flow
 
-import React, { PureComponent } from 'react'
+import React, { PureComponent, Fragment } from 'react'
 import styled from 'styled-components'
 import { connect } from 'react-redux'
 import { compose } from 'redux'
@@ -28,13 +28,8 @@ import Input from 'components/base/Input'
 import Select from 'components/base/Select'
 import SyncAgo from 'components/SyncAgo'
 
-import {
-  ModalBody,
-  ModalTitle,
-  ModalFooter,
-  ModalContent,
-  ConfirmModal,
-} from 'components/base/Modal'
+import ConfirmModal from 'components/base/Modal/ConfirmModal'
+import ModalBody from 'components/base/Modal/ModalBody'
 
 type State = {
   accountName: ?string,
@@ -74,7 +69,7 @@ const defaultState = {
   isRemoveAccountModalOpen: false,
 }
 
-class HelperComp extends PureComponent<Props, State> {
+class AccountSettingRenderBody extends PureComponent<Props, State> {
   state = {
     ...defaultState,
   }
@@ -84,7 +79,6 @@ class HelperComp extends PureComponent<Props, State> {
   }
 
   getAccount(data: Object): Account {
-    // FIXME this should be a selector
     const { accountName } = this.state
     const account = get(data, 'account', {})
 
@@ -132,7 +126,6 @@ class HelperComp extends PureComponent<Props, State> {
     e: SyntheticEvent<HTMLFormElement>,
   ) => {
     e.preventDefault()
-
     const { updateAccount, setDataModal } = this.props
     const { accountName, accountUnit, endpointConfig, endpointConfigError } = this.state
 
@@ -194,10 +187,10 @@ class HelperComp extends PureComponent<Props, State> {
       endpointConfigError,
     } = this.state
     const { t, onClose, data } = this.props
+    if (!data) return null
 
     const account = this.getAccount(data)
     const bridge = getBridgeForCurrency(account.currency)
-
     const usefulData = {
       xpub: account.xpub || undefined,
       index: account.index,
@@ -207,11 +200,12 @@ class HelperComp extends PureComponent<Props, State> {
     }
 
     return (
-      <ModalBody onClose={onClose}>
-        <form onSubmit={this.handleSubmit(account, onClose)}>
-          <TrackPage category="Modal" name="AccountSettings" />
-          <ModalTitle>{t('account.settings.title')}</ModalTitle>
-          <ModalContent mb={3}>
+      <ModalBody
+        onClose={onClose}
+        title={t('account.settings.title')}
+        render={() => (
+          <form onSubmit={this.handleSubmit(account, onClose)}>
+            <TrackPage category="Modal" name="AccountSettings" />
             <Container>
               <Box>
                 <OptionRowTitle>{t('account.settings.accountName.title')}</OptionRowTitle>
@@ -284,8 +278,21 @@ class HelperComp extends PureComponent<Props, State> {
                 value={JSON.stringify(usefulData, null, 2)}
               />
             </Spoiler>
-          </ModalContent>
-          <ModalFooter horizontal>
+            <ConfirmModal
+              analyticsName="RemoveAccount"
+              isDanger
+              isOpened={isRemoveAccountModalOpen}
+              onClose={this.handleCloseRemoveAccountModal}
+              onReject={this.handleCloseRemoveAccountModal}
+              onConfirm={() => this.handleRemoveAccount(account)}
+              title={t('settings.removeAccountModal.title')}
+              subTitle={t('common.areYouSure')}
+              desc={t('settings.removeAccountModal.desc')}
+            />
+          </form>
+        )}
+        renderFooter={() => (
+          <Fragment>
             <Button
               event="OpenAccountDelete"
               danger
@@ -297,20 +304,9 @@ class HelperComp extends PureComponent<Props, State> {
             <Button event="DoneEditingAccount" ml="auto" type="submit" primary>
               {t('common.apply')}
             </Button>
-          </ModalFooter>
-        </form>
-        <ConfirmModal
-          analyticsName="RemoveAccount"
-          isDanger
-          isOpened={isRemoveAccountModalOpen}
-          onClose={this.handleCloseRemoveAccountModal}
-          onReject={this.handleCloseRemoveAccountModal}
-          onConfirm={() => this.handleRemoveAccount(account)}
-          title={t('settings.removeAccountModal.title')}
-          subTitle={t('common.areYouSure')}
-          desc={t('settings.removeAccountModal.desc')}
-        />
-      </ModalBody>
+          </Fragment>
+        )}
+      />
     )
   }
 }
@@ -321,7 +317,7 @@ export default compose(
     mapDispatchToProps,
   ),
   translate(),
-)(HelperComp)
+)(AccountSettingRenderBody)
 
 export function InputLeft({ currency }: { currency: Currency }) {
   return (
diff --git a/src/components/modals/AddAccounts/index.js b/src/components/modals/AddAccounts/index.js
index e6edd600..0bd842cf 100644
--- a/src/components/modals/AddAccounts/index.js
+++ b/src/components/modals/AddAccounts/index.js
@@ -43,6 +43,7 @@ const createSteps = () => {
       footer: StepChooseCurrencyFooter,
       onBack: null,
       hideFooter: false,
+      noScroll: true,
     },
     {
       id: 'connectDevice',
@@ -241,6 +242,7 @@ class AddAccounts extends PureComponent<Props, State> {
 
     return (
       <Modal
+        centered
         name={MODAL_ADD_ACCOUNTS}
         refocusWhenChange={stepId}
         onHide={() => this.setState({ ...INITIAL_STATE })}
diff --git a/src/components/modals/Debug.js b/src/components/modals/Debug.js
index 8ed42391..66362152 100644
--- a/src/components/modals/Debug.js
+++ b/src/components/modals/Debug.js
@@ -1,11 +1,12 @@
 // @flow
 /* eslint-disable react/jsx-no-literals */
-import React, { Component } from 'react'
+import React, { Component, Fragment } from 'react'
 import { connect } from 'react-redux'
 import { createStructuredSelector } from 'reselect'
 import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/currencies'
 import { getDerivationScheme, runDerivationScheme } from '@ledgerhq/live-common/lib/derivation'
-import Modal, { ModalBody, ModalTitle, ModalContent } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
 import { getCurrentDevice } from 'reducers/devices'
 import Button from 'components/base/Button'
 import Box from 'components/base/Box'
@@ -127,14 +128,12 @@ class Debug extends Component<*, *> {
     const { device } = this.props
     const { logs } = this.state
     return (
-      <Modal
-        name="MODAL_DEBUG"
-        onHide={this.onHide}
-        render={({ onClose }: *) => (
-          <ModalBody onClose={onClose}>
-            <SyncSkipUnderPriority priority={99999999} />
-            <ModalTitle>developer internal tools</ModalTitle>
-            <ModalContent>
+      <Modal name="MODAL_DEBUG" centered onHide={this.onHide}>
+        <ModalBody
+          title="developer internal tools"
+          render={() => (
+            <Box>
+              <SyncSkipUnderPriority priority={99999999} />
               <Box style={{ height: 60, overflow: 'auto' }}>
                 {device && (
                   <Box horizontal style={{ padding: 10 }}>
@@ -191,6 +190,7 @@ class Debug extends Component<*, *> {
               >
                 {logs.map(log => (
                   <Box
+                    key={log.txt}
                     style={{
                       userSelect: 'all',
                       color: log.type === 'error' ? '#c22' : '#888',
@@ -200,6 +200,10 @@ class Debug extends Component<*, *> {
                   </Box>
                 ))}
               </Box>
+            </Box>
+          )}
+          renderFooter={() => (
+            <Fragment>
               <Button
                 style={{ position: 'absolute', right: 30, bottom: 28 }}
                 onClick={() => {
@@ -208,10 +212,10 @@ class Debug extends Component<*, *> {
               >
                 Clear
               </Button>
-            </ModalContent>
-          </ModalBody>
-        )}
-      />
+            </Fragment>
+          )}
+        />
+      </Modal>
     )
   }
 }
diff --git a/src/components/modals/Disclaimer.js b/src/components/modals/Disclaimer.js
index ce340847..7e73dc78 100644
--- a/src/components/modals/Disclaimer.js
+++ b/src/components/modals/Disclaimer.js
@@ -7,13 +7,21 @@ import type { T } from 'types/common'
 
 import { MODAL_DISCLAIMER } from 'config/constants'
 
-import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
 import Button from 'components/base/Button'
 import Box from 'components/base/Box'
 import { HandShield } from 'components/WarnBox'
+import { compose } from 'redux'
+import connect from 'react-redux/es/connect/connect'
+import { closeModal } from '../../reducers/modals'
 
 type Props = {
   t: T,
+  closeModal: string => void,
+}
+const mapDispatchToProps = {
+  closeModal,
 }
 
 class DisclaimerModal extends PureComponent<Props> {
@@ -21,28 +29,39 @@ class DisclaimerModal extends PureComponent<Props> {
     const { t } = this.props
 
     return (
-      <Modal
-        name={MODAL_DISCLAIMER}
-        render={({ onClose }) => (
-          <ModalBody onClose={onClose}>
-            <ModalTitle>{t('disclaimerModal.title')}</ModalTitle>
-            <ModalContent flow={4} ff="Open Sans|Regular" fontSize={4} color="smoke">
+      <Modal name={MODAL_DISCLAIMER} centered>
+        <ModalBody
+          title={t('disclaimerModal.title')}
+          render={() => (
+            <Box flow={4} ff="Open Sans|Regular" fontSize={4} color="smoke">
               <Box align="center" mt={4} pb={4}>
                 <HandShield size={55} />
               </Box>
               <p>{t('disclaimerModal.desc_1')}</p>
               <p>{t('disclaimerModal.desc_2')}</p>
-            </ModalContent>
-            <ModalFooter horizontal justifyContent="flex-end">
-              <Button data-e2e="continue_button" onClick={onClose} primary>
+            </Box>
+          )}
+          renderFooter={() => (
+            <Box horizontal justifyContent="flex-end">
+              <Button
+                data-e2e="continue_button"
+                onClick={() => this.props.closeModal(MODAL_DISCLAIMER)}
+                primary
+              >
                 {t('disclaimerModal.cta')}
               </Button>
-            </ModalFooter>
-          </ModalBody>
-        )}
-      />
+            </Box>
+          )}
+        />
+      </Modal>
     )
   }
 }
 
-export default translate()(DisclaimerModal)
+export default compose(
+  connect(
+    null,
+    mapDispatchToProps,
+  ),
+  translate(),
+)(DisclaimerModal)
diff --git a/src/components/modals/OperationDetails.js b/src/components/modals/OperationDetails.js
index bb77163f..b9f55c04 100644
--- a/src/components/modals/OperationDetails.js
+++ b/src/components/modals/OperationDetails.js
@@ -18,12 +18,10 @@ import { MODAL_OPERATION_DETAILS } from 'config/constants'
 import { getMarketColor } from 'styles/helpers'
 
 import Box from 'components/base/Box'
-import GradientBox from 'components/GradientBox'
-import GrowScroll from 'components/base/GrowScroll'
 import Button from 'components/base/Button'
 import Bar from 'components/base/Bar'
 import FormattedVal from 'components/base/FormattedVal'
-import Modal, { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal'
+import Modal, { ModalBody } from 'components/base/Modal'
 import Text from 'components/base/Text'
 import CopyWithFeedback from 'components/base/CopyWithFeedback'
 
@@ -130,122 +128,120 @@ const OperationDetails = connect(mapStateToProps)((props: Props) => {
   const uniqueSenders = uniq(senders)
 
   return (
-    <ModalBody onClose={onClose}>
-      <TrackPage category="Modal" name="OperationDetails" />
-      <ModalTitle>{t('operationDetails.title')}</ModalTitle>
-      <ModalContent relative style={{ height: 500 }} px={0} pb={0}>
-        <GrowScroll px={5} pt={1} pb={8}>
-          <Box flow={3}>
-            <Box alignItems="center" mt={1}>
-              <ConfirmationCheck
-                marketColor={marketColor}
-                isConfirmed={isConfirmed}
-                style={{
-                  transform: 'scale(1.5)',
-                }}
-                t={t}
-                type={type}
-                withTooltip={false}
-              />
-              <Box my={4} alignItems="center">
-                <Box>
-                  <FormattedVal
-                    color={amount.isNegative() ? 'smoke' : undefined}
-                    unit={unit}
-                    alwaysShowSign
-                    showCode
-                    val={amount}
-                    fontSize={7}
-                    disableRounding
-                  />
-                </Box>
-                <Box mt={1}>
-                  <CounterValue
-                    color="grey"
-                    fontSize={5}
-                    date={date}
-                    currency={currency}
-                    value={amount}
-                  />
-                </Box>
-              </Box>
-            </Box>
-            <Box horizontal flow={2}>
-              <Box flex={1}>
-                <OpDetailsTitle>{t('operationDetails.account')}</OpDetailsTitle>
-                <OpDetailsData>{name}</OpDetailsData>
+    <ModalBody
+      title={t('operationDetails.title')}
+      onClose={onClose}
+      render={() => (
+        <Box flow={3}>
+          <Box alignItems="center" mt={1}>
+            <ConfirmationCheck
+              marketColor={marketColor}
+              isConfirmed={isConfirmed}
+              style={{
+                transform: 'scale(1.5)',
+              }}
+              t={t}
+              type={type}
+              withTooltip={false}
+            />
+            <Box my={4} alignItems="center">
+              <Box>
+                <FormattedVal
+                  color={amount.isNegative() ? 'smoke' : undefined}
+                  unit={unit}
+                  alwaysShowSign
+                  showCode
+                  val={amount}
+                  fontSize={7}
+                  disableRounding
+                />
               </Box>
-              <Box flex={1}>
-                <OpDetailsTitle>{t('operationDetails.date')}</OpDetailsTitle>
-                <OpDetailsData>{moment(date).format('LLL')}</OpDetailsData>
+              <Box mt={1}>
+                <CounterValue
+                  color="grey"
+                  fontSize={5}
+                  date={date}
+                  currency={currency}
+                  value={amount}
+                />
               </Box>
             </Box>
-            <B />
-            <Box horizontal flow={2}>
-              <Box flex={1}>
-                <OpDetailsTitle>{t('operationDetails.fees')}</OpDetailsTitle>
-                {fee ? (
-                  <Fragment>
-                    <OpDetailsData>
-                      <FormattedVal unit={unit} showCode val={fee} color="smoke" />
-                    </OpDetailsData>
-                  </Fragment>
-                ) : (
-                  <OpDetailsData>{t('operationDetails.noFees')}</OpDetailsData>
-                )}
-              </Box>
-              <Box flex={1}>
-                <OpDetailsTitle>{t('operationDetails.status')}</OpDetailsTitle>
-                <OpDetailsData color={isConfirmed ? 'positiveGreen' : null} horizontal flow={1}>
-                  <Box>
-                    {isConfirmed
-                      ? t('operationDetails.confirmed')
-                      : t('operationDetails.notConfirmed')}
-                  </Box>
-                  <Box>{`(${confirmations})`}</Box>
-                </OpDetailsData>
-              </Box>
+          </Box>
+          <Box horizontal flow={2}>
+            <Box flex={1}>
+              <OpDetailsTitle>{t('operationDetails.account')}</OpDetailsTitle>
+              <OpDetailsData>{name}</OpDetailsData>
             </Box>
-            <B />
-            <Box>
-              <OpDetailsTitle>{t('operationDetails.identifier')}</OpDetailsTitle>
-              <OpDetailsData>
-                <Ellipsis canSelect>{hash}</Ellipsis>
-                <GradientHover>
-                  <CopyWithFeedback text={hash} />
-                </GradientHover>
-              </OpDetailsData>
+            <Box flex={1}>
+              <OpDetailsTitle>{t('operationDetails.date')}</OpDetailsTitle>
+              <OpDetailsData>{moment(date).format('LLL')}</OpDetailsData>
             </Box>
-            <B />
-            <Box>
-              <OpDetailsTitle>{t('operationDetails.from')}</OpDetailsTitle>
-              <DataList lines={uniqueSenders} t={t} />
+          </Box>
+          <B />
+          <Box horizontal flow={2}>
+            <Box flex={1}>
+              <OpDetailsTitle>{t('operationDetails.fees')}</OpDetailsTitle>
+              {fee ? (
+                <Fragment>
+                  <OpDetailsData>
+                    <FormattedVal unit={unit} showCode val={fee} color="smoke" />
+                  </OpDetailsData>
+                </Fragment>
+              ) : (
+                <OpDetailsData>{t('operationDetails.noFees')}</OpDetailsData>
+              )}
             </Box>
-            <B />
-            <Box>
-              <OpDetailsTitle>{t('operationDetails.to')}</OpDetailsTitle>
-              <DataList lines={recipients} t={t} />
+            <Box flex={1}>
+              <OpDetailsTitle>{t('operationDetails.status')}</OpDetailsTitle>
+              <OpDetailsData color={isConfirmed ? 'positiveGreen' : null} horizontal flow={1}>
+                <Box>
+                  {isConfirmed
+                    ? t('operationDetails.confirmed')
+                    : t('operationDetails.notConfirmed')}
+                </Box>
+                <Box>{`(${confirmations})`}</Box>
+              </OpDetailsData>
             </Box>
-            {Object.entries(extra).map(([key, value]) => (
-              <Box key={key}>
-                <OpDetailsTitle>
-                  <Trans i18nKey={`operationDetails.extra.${key}`} defaults={key} />
-                </OpDetailsTitle>
-                <OpDetailsData>{value}</OpDetailsData>
-              </Box>
-            ))}
           </Box>
-        </GrowScroll>
-        <GradientBox />
-      </ModalContent>
-
-      {url && (
-        <ModalFooter horizontal justify="flex-end" flow={2}>
+          <B />
+          <Box>
+            <OpDetailsTitle>{t('operationDetails.identifier')}</OpDetailsTitle>
+            <OpDetailsData>
+              <Ellipsis canSelect>{hash}</Ellipsis>
+              <GradientHover>
+                <CopyWithFeedback text={hash} />
+              </GradientHover>
+            </OpDetailsData>
+          </Box>
+          <B />
+          <Box>
+            <OpDetailsTitle>{t('operationDetails.from')}</OpDetailsTitle>
+            <DataList lines={uniqueSenders} t={t} />
+          </Box>
+          <B />
+          <Box>
+            <OpDetailsTitle>{t('operationDetails.to')}</OpDetailsTitle>
+            <DataList lines={recipients} t={t} />
+          </Box>
+          {Object.entries(extra).map(([key, value]) => (
+            <Box key={key}>
+              <OpDetailsTitle>
+                <Trans i18nKey={`operationDetails.extra.${key}`} defaults={key} />
+              </OpDetailsTitle>
+              <OpDetailsData>{value}</OpDetailsData>
+            </Box>
+          ))}
+        </Box>
+      )}
+      renderFooter={() =>
+        url && (
           <Button primary onClick={() => openURL(url)}>
             {t('operationDetails.viewOperation')}
           </Button>
-        </ModalFooter>
-      )}
+        )
+      }
+    >
+      <TrackPage category="Modal" name="OperationDetails" />
     </ModalBody>
   )
 })
@@ -255,12 +251,13 @@ type ModalRenderProps = {
     account: string,
     operation: string,
   },
-  onClose: Function,
+  onClose?: Function,
 }
 
 const OperationDetailsWrapper = ({ t }: { t: T }) => (
   <Modal
     name={MODAL_OPERATION_DETAILS}
+    centered
     render={(props: ModalRenderProps) => {
       const { data, onClose } = props
       return <OperationDetails t={t} {...data} onClose={onClose} />
diff --git a/src/components/modals/Receive/index.js b/src/components/modals/Receive/index.js
index c0beab10..5d73ec95 100644
--- a/src/components/modals/Receive/index.js
+++ b/src/components/modals/Receive/index.js
@@ -193,16 +193,17 @@ class ReceiveModal extends PureComponent<Props, State> {
     return (
       <Modal
         name={MODAL_RECEIVE}
+        centered
         refocusWhenChange={stepId}
         onHide={this.handleReset}
         preventBackdropClick={isModalLocked}
         onBeforeOpen={this.handleBeforeOpenModal}
-        render={({ onClose }) => (
+        render={() => (
           <Stepper
             title={t('receive.title')}
             initialStepId={stepId}
             onStepChange={this.handleStepChange}
-            onClose={onClose}
+            onClose={addtionnalProps.closeModal}
             steps={this.STEPS}
             disabledSteps={disabledSteps}
             errorSteps={errorSteps}
diff --git a/src/components/modals/ReleaseNotes/ReleaseNotesBody.js b/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
index 1549727f..67162fab 100644
--- a/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
+++ b/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
@@ -14,7 +14,7 @@ import GradientBox from 'components/GradientBox'
 import TranslatedError from 'components/TranslatedError'
 import TrackPage from 'analytics/TrackPage'
 import Markdown, { Notes } from 'components/base/Markdown'
-import { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
 
 import type { T } from 'types/common'
 
@@ -115,21 +115,26 @@ class ReleaseNotesBody extends PureComponent<Props, State> {
     const { onClose, t } = this.props
 
     return (
-      <ModalBody onClose={onClose}>
-        <TrackPage category="Modal" name="ReleaseNotes" />
-        <ModalTitle>{t('releaseNotes.title')}</ModalTitle>
-        <ModalContent relative style={{ height: 500 }} px={0} pb={0}>
-          <GrowScroll px={5} pb={8}>
-            {this.renderContent()}
-          </GrowScroll>
-          <GradientBox />
-        </ModalContent>
-        <ModalFooter horizontal justifyContent="flex-end">
-          <Button onClick={onClose} primary>
-            {t('common.continue')}
-          </Button>
-        </ModalFooter>
-      </ModalBody>
+      <ModalBody
+        onClose={onClose}
+        title={t('releaseNotes.title')}
+        render={() => (
+          <Box relative style={{ height: 500 }} px={0} pb={0}>
+            <TrackPage category="Modal" name="ReleaseNotes" />
+            <GrowScroll px={5} pb={8}>
+              {this.renderContent()}
+            </GrowScroll>
+            <GradientBox />
+          </Box>
+        )}
+        renderFooter={() => (
+          <Box horizontal justifyContent="flex-end">
+            <Button onClick={onClose} primary>
+              {t('common.continue')}
+            </Button>
+          </Box>
+        )}
+      />
     )
   }
 }
diff --git a/src/components/modals/ReleaseNotes/index.js b/src/components/modals/ReleaseNotes/index.js
index cf4a4b35..3cd2192d 100644
--- a/src/components/modals/ReleaseNotes/index.js
+++ b/src/components/modals/ReleaseNotes/index.js
@@ -9,6 +9,7 @@ import ReleaseNotesBody from './ReleaseNotesBody'
 const ReleaseNotesModal = () => (
   <Modal
     name={MODAL_RELEASES_NOTES}
+    centered
     render={({ data, onClose }) => <ReleaseNotesBody version={data} onClose={onClose} />}
   />
 )
diff --git a/src/components/modals/Send/index.js b/src/components/modals/Send/index.js
index 090ca4b0..50c56351 100644
--- a/src/components/modals/Send/index.js
+++ b/src/components/modals/Send/index.js
@@ -273,6 +273,7 @@ class SendModal extends PureComponent<Props, State<*>> {
     return (
       <Modal
         name={MODAL_SEND}
+        centered
         refocusWhenChange={stepId}
         onHide={this.handleReset}
         preventBackdropClick={isModalLocked}
diff --git a/src/components/modals/SettingsAccount.js b/src/components/modals/SettingsAccount.js
index af1d2f3a..108e7a54 100644
--- a/src/components/modals/SettingsAccount.js
+++ b/src/components/modals/SettingsAccount.js
@@ -11,7 +11,10 @@ export default class SettingsAccount extends PureComponent<*, *> {
     return (
       <Modal
         name={MODAL_SETTINGS_ACCOUNT}
-        render={({ data, onClose }) => <AccountSettingRenderBody data={data} onClose={onClose} />}
+        centered
+        render={({ data, onClose }) => (
+          <AccountSettingRenderBody {...this.props} data={data} onClose={onClose} />
+        )}
       />
     )
   }
diff --git a/src/components/modals/ShareAnalytics.js b/src/components/modals/ShareAnalytics.js
index 467b060d..c5f315fc 100644
--- a/src/components/modals/ShareAnalytics.js
+++ b/src/components/modals/ShareAnalytics.js
@@ -1,19 +1,28 @@
 // @flow
-import React, { PureComponent } from 'react'
+import React, { Fragment, PureComponent } from 'react'
 import { translate } from 'react-i18next'
 import styled from 'styled-components'
 
 import { MODAL_SHARE_ANALYTICS } from 'config/constants'
-import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
 
 import Button from 'components/base/Button'
 import Box from 'components/base/Box'
-
+import { connect } from 'react-redux'
+import { compose } from 'redux'
 import type { T } from 'types/common'
 
+import { closeModal } from '../../reducers/modals'
+import ModalBody from '../base/Modal/ModalBody'
+
 type Props = {
   t: T,
+  closeModal: string => void,
 }
+const mapDispatchToProps = {
+  closeModal,
+}
+
 class ShareAnalytics extends PureComponent<Props, *> {
   render() {
     const { t } = this.props
@@ -56,30 +65,41 @@ class ShareAnalytics extends PureComponent<Props, *> {
       },
     ]
     return (
-      <Modal
-        name={MODAL_SHARE_ANALYTICS}
-        render={({ onClose }) => (
-          <ModalBody onClose={onClose}>
-            <ModalTitle data-e2e="modal_title_shareAnalytics">
-              {t('onboarding.analytics.shareAnalytics.title')}
-            </ModalTitle>
-            <InlineDesc>{t('onboarding.analytics.shareAnalytics.desc')}</InlineDesc>
-            <ModalContent mx={5}>
-              <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
-            </ModalContent>
-            <ModalFooter horizontal justifyContent="flex-end">
-              <Button onClick={onClose} primary data-e2e="modal_buttonClose_shareAnalytics">
+      <Modal name={MODAL_SHARE_ANALYTICS} centered>
+        <ModalBody
+          title={t('onboarding.analytics.shareAnalytics.title')}
+          render={() => (
+            <Fragment>
+              <InlineDesc>{t('onboarding.analytics.shareAnalytics.desc')}</InlineDesc>
+              <Box mx={5}>
+                <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
+              </Box>
+            </Fragment>
+          )}
+          renderFooter={() => (
+            <Fragment>
+              <Button
+                onClick={() => this.props.closeModal(MODAL_SHARE_ANALYTICS)}
+                primary
+                data-e2e="modal_buttonClose_shareAnalytics"
+              >
                 {t('common.close')}
               </Button>
-            </ModalFooter>
-          </ModalBody>
-        )}
-      />
+            </Fragment>
+          )}
+        />
+      </Modal>
     )
   }
 }
 
-export default translate()(ShareAnalytics)
+export default compose(
+  connect(
+    null,
+    mapDispatchToProps,
+  ),
+  translate(),
+)(ShareAnalytics)
 
 export const Ul = styled.ul.attrs({
   ff: 'Open Sans|Regular',
diff --git a/src/components/modals/TechnicalData.js b/src/components/modals/TechnicalData.js
index 395cdf46..93f2c3ef 100644
--- a/src/components/modals/TechnicalData.js
+++ b/src/components/modals/TechnicalData.js
@@ -1,16 +1,25 @@
 // @flow
-import React, { PureComponent } from 'react'
+import React, { Fragment, PureComponent } from 'react'
 import { translate } from 'react-i18next'
 
 import { MODAL_TECHNICAL_DATA } from 'config/constants'
-import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
+import Modal, { ModalBody } from 'components/base/Modal'
 import Button from 'components/base/Button'
 
 import type { T } from 'types/common'
+import { connect } from 'react-redux'
+import { compose } from 'redux'
+import Box from 'components/base/Box'
 import { Ul, InlineDesc } from './ShareAnalytics'
+import { closeModal } from '../../reducers/modals'
 
 type Props = {
   t: T,
+  closeModal: string => void,
+}
+
+const mapDispatchToProps = {
+  closeModal,
 }
 
 class TechnicalData extends PureComponent<Props, *> {
@@ -33,27 +42,38 @@ class TechnicalData extends PureComponent<Props, *> {
     ]
 
     return (
-      <Modal
-        name={MODAL_TECHNICAL_DATA}
-        render={({ onClose }) => (
-          <ModalBody onClose={onClose}>
-            <ModalTitle data-e2e="modal_title_TechData">
-              {t('onboarding.analytics.technicalData.mandatoryContextual.title')}
-            </ModalTitle>
-            <InlineDesc>{t('onboarding.analytics.technicalData.desc')}</InlineDesc>
-            <ModalContent mx={5}>
-              <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
-            </ModalContent>
-            <ModalFooter horizontal justifyContent="flex-end">
-              <Button onClick={onClose} primary data-e2e="modal_buttonClose_techData">
+      <Modal name={MODAL_TECHNICAL_DATA} centered>
+        <ModalBody
+          title={t('onboarding.analytics.technicalData.mandatoryContextual.title')}
+          render={() => (
+            <Fragment>
+              <InlineDesc>{t('onboarding.analytics.technicalData.desc')}</InlineDesc>
+              <Box mx={5}>
+                <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
+              </Box>
+            </Fragment>
+          )}
+          renderFooter={() => (
+            <Fragment>
+              <Button
+                onClick={() => this.props.closeModal(MODAL_TECHNICAL_DATA)}
+                primary
+                data-e2e="modal_buttonClose_techData"
+              >
                 {t('common.close')}
               </Button>
-            </ModalFooter>
-          </ModalBody>
-        )}
-      />
+            </Fragment>
+          )}
+        />
+      </Modal>
     )
   }
 }
 
-export default translate()(TechnicalData)
+export default compose(
+  connect(
+    null,
+    mapDispatchToProps,
+  ),
+  translate(),
+)(TechnicalData)
diff --git a/src/components/modals/UpdateFirmware/Disclaimer.js b/src/components/modals/UpdateFirmware/Disclaimer.js
index 76d16fae..f18019e5 100644
--- a/src/components/modals/UpdateFirmware/Disclaimer.js
+++ b/src/components/modals/UpdateFirmware/Disclaimer.js
@@ -1,12 +1,13 @@
 // @flow
 /* eslint react/jsx-no-literals: 0 */
 
-import React, { PureComponent, Fragment } from 'react'
+import React, { PureComponent } from 'react'
 import { translate, Trans } from 'react-i18next'
 import type { OsuFirmware, FinalFirmware } from '@ledgerhq/live-common/lib/types/manager'
 import type { T } from 'types/common'
 
-import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal'
+import Modal from 'components/base/Modal'
+import ModalBody from 'components/base/Modal/ModalBody'
 import Text from 'components/base/Text'
 import Button from 'components/base/Button'
 import GrowScroll from 'components/base/GrowScroll'
@@ -17,6 +18,7 @@ import TrackPage from 'analytics/TrackPage'
 import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate'
 
 import { getCleanVersion } from 'components/ManagerPage/FirmwareUpdate'
+import Box from '../../base/Box/Box'
 
 type Props = {
   t: T,
@@ -35,49 +37,51 @@ class DisclaimerModal extends PureComponent<Props, State> {
   render(): React$Node {
     const { status, firmware, onClose, t, goToNextStep } = this.props
     return (
-      <Modal
-        isOpened={status === 'disclaimer'}
-        onClose={onClose}
-        render={({ onClose }) => (
-          <ModalBody onClose={onClose} grow align="center" justify="center" mt={3}>
-            <TrackPage category="Manager" name="DisclaimerModal" />
-            <Fragment>
-              <ModalTitle>{t('manager.firmware.update')}</ModalTitle>
-              <ModalContent>
-                <Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center">
-                  <Trans i18nKey="manager.firmware.disclaimerTitle">
-                    You are about to install
-                    <Text ff="Open Sans|SemiBold" color="dark">
-                      {`firmware version ${
-                        firmware && firmware.osu ? getCleanVersion(firmware.osu.name) : ''
-                      }`}
-                    </Text>
-                  </Trans>
-                </Text>
-                <Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center">
-                  {t('manager.firmware.disclaimerAppDelete')}
-                  {t('manager.firmware.disclaimerAppReinstall')}
-                </Text>
-              </ModalContent>
+      <Modal isOpened={status === 'disclaimer'} onClose={onClose}>
+        <TrackPage category="Manager" name="DisclaimerModal" />
+        <ModalBody
+          grow
+          align="center"
+          justify="center"
+          mt={3}
+          title={t('manager.firmware.update')}
+          render={() => (
+            <Box>
+              <Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center">
+                <Trans i18nKey="manager.firmware.disclaimerTitle">
+                  You are about to install
+                  <Text ff="Open Sans|SemiBold" color="dark">
+                    {`firmware version ${
+                      firmware && firmware.osu ? getCleanVersion(firmware.osu.name) : ''
+                    }`}
+                  </Text>
+                </Trans>
+              </Text>
+              <Text ff="Open Sans|Regular" fontSize={4} color="graphite" align="center">
+                {t('manager.firmware.disclaimerAppDelete')}
+                {t('manager.firmware.disclaimerAppReinstall')}
+              </Text>
               {firmware && firmware.osu ? (
-                <ModalContent relative pb={0} style={{ height: 250, width: '100%' }}>
+                <Box relative pb={0} style={{ height: 250, width: '100%' }}>
                   <GrowScroll pb={5}>
                     <Notes>
                       <Markdown>{firmware.osu.notes}</Markdown>
                     </Notes>
                   </GrowScroll>
                   <GradientBox />
-                </ModalContent>
+                </Box>
               ) : null}
-              <ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}>
-                <Button primary onClick={goToNextStep}>
-                  {t('common.continue')}
-                </Button>
-              </ModalFooter>
-            </Fragment>
-          </ModalBody>
-        )}
-      />
+            </Box>
+          )}
+          renderFooter={() => (
+            <Box horizontal justifyContent="flex-end">
+              <Button primary onClick={goToNextStep}>
+                {t('common.continue')}
+              </Button>
+            </Box>
+          )}
+        />
+      </Modal>
     )
   }
 }
diff --git a/src/components/modals/UpdateFirmware/index.js b/src/components/modals/UpdateFirmware/index.js
index 371909de..9d2ed400 100644
--- a/src/components/modals/UpdateFirmware/index.js
+++ b/src/components/modals/UpdateFirmware/index.js
@@ -103,6 +103,7 @@ class UpdateModal extends PureComponent<Props, State> {
     return (
       <Modal
         onClose={onClose}
+        centered
         onHide={this.handleReset}
         isOpened={status === 'install'}
         refocusWhenChange={stepId}
diff --git a/src/index.ejs b/src/index.ejs
index cc3c0c35..9426e338 100644
--- a/src/index.ejs
+++ b/src/index.ejs
@@ -75,6 +75,7 @@
       <img class="logo" src="<%= __DEV__ ? '.' : '../static' %>/images/ledgerlive-logo.svg" alt="" />
     </div>
     <div id="app"></div>
+    <div id="modals"></div>
     <script>
     const { remote } = require('electron')
 const { name } = remote.getCurrentWindow()
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index 26c6ca80..d4b6d644 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -44,7 +44,6 @@ const handlers = {
       ...state,
       [name]: {
         isOpened: false,
-        data: undefined,
       },
     }
   },

From b8cfb933167bce99ab21aedb991e36f411e686e0 Mon Sep 17 00:00:00 2001
From: meriadec <meriadec.pillet@gmail.com>
Date: Tue, 15 Jan 2019 13:38:52 +0100
Subject: [PATCH 2/8] Fix submit of account settings

---
 src/components/modals/AccountSettingRenderBody.js | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/components/modals/AccountSettingRenderBody.js b/src/components/modals/AccountSettingRenderBody.js
index 552470bd..ec5cc8d4 100644
--- a/src/components/modals/AccountSettingRenderBody.js
+++ b/src/components/modals/AccountSettingRenderBody.js
@@ -123,7 +123,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
     })
 
   handleSubmit = (account: Account, onClose: () => void) => (
-    e: SyntheticEvent<HTMLFormElement>,
+    e: SyntheticEvent<HTMLFormElement | HTMLInputElement>,
   ) => {
     e.preventDefault()
     const { updateAccount, setDataModal } = this.props
@@ -199,12 +199,14 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
       blockHeight: account.blockHeight,
     }
 
+    const onSubmit = this.handleSubmit(account, onClose)
+
     return (
       <ModalBody
         onClose={onClose}
         title={t('account.settings.title')}
         render={() => (
-          <form onSubmit={this.handleSubmit(account, onClose)}>
+          <Fragment>
             <TrackPage category="Modal" name="AccountSettings" />
             <Container>
               <Box>
@@ -218,6 +220,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
                   value={account.name}
                   maxLength={MAX_ACCOUNT_NAME_SIZE}
                   onChange={this.handleChangeName}
+                  onEnter={onSubmit}
                   onFocus={e => this.handleFocus(e, 'accountName')}
                   error={accountNameError}
                 />
@@ -289,7 +292,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
               subTitle={t('common.areYouSure')}
               desc={t('settings.removeAccountModal.desc')}
             />
-          </form>
+          </Fragment>
         )}
         renderFooter={() => (
           <Fragment>
@@ -301,7 +304,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
             >
               {t('common.delete')}
             </Button>
-            <Button event="DoneEditingAccount" ml="auto" type="submit" primary>
+            <Button event="DoneEditingAccount" ml="auto" onClick={onSubmit} primary>
               {t('common.apply')}
             </Button>
           </Fragment>

From dea7bfeb36d8a78e4b29e82e3e3b9dd255d24e77 Mon Sep 17 00:00:00 2001
From: meriadec <meriadec.pillet@gmail.com>
Date: Tue, 15 Jan 2019 13:39:07 +0100
Subject: [PATCH 3/8] Fix display issues in account settings modal

- disabled scroll because the unit select menu was not correctly
displayed (caused by the parent `overflow: scroll`)
- full size advanced account infos (dunno why it's called "advanced logs", lol)
---
 src/components/modals/AccountSettingRenderBody.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/components/modals/AccountSettingRenderBody.js b/src/components/modals/AccountSettingRenderBody.js
index ec5cc8d4..3b494e55 100644
--- a/src/components/modals/AccountSettingRenderBody.js
+++ b/src/components/modals/AccountSettingRenderBody.js
@@ -203,6 +203,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
 
     return (
       <ModalBody
+        noScroll
         onClose={onClose}
         title={t('account.settings.title')}
         render={() => (
@@ -277,6 +278,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
                   height: 200,
                   outline: 'none',
                   padding: '20px',
+                  width: '100%',
                 }}
                 value={JSON.stringify(usefulData, null, 2)}
               />

From b93f48064a588eaa859a4ff3abcd5e3b3179c9c4 Mon Sep 17 00:00:00 2001
From: Juan Cortes Ross <juan@bohem.io>
Date: Tue, 15 Jan 2019 17:56:54 +0100
Subject: [PATCH 4/8] Allow components inside modal body to overflow (ie
 dropdowns)

---
 src/components/SettingsPage/PasswordModal.js | 3 +--
 src/components/base/Modal/ModalContent.js    | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/components/SettingsPage/PasswordModal.js b/src/components/SettingsPage/PasswordModal.js
index 1b8c3909..5acaf9cf 100644
--- a/src/components/SettingsPage/PasswordModal.js
+++ b/src/components/SettingsPage/PasswordModal.js
@@ -39,8 +39,7 @@ class PasswordModal extends PureComponent<Props, State> {
 
   componentWillReceiveProps(nextProps: Props) {
     if (!nextProps.isOpened) {
-      // CLean the state?
-      this.setState(prevState => ({ ...prevState, ...INITIAL_STATE }))
+      this.setState(INITIAL_STATE)
     }
   }
 
diff --git a/src/components/base/Modal/ModalContent.js b/src/components/base/Modal/ModalContent.js
index 7b74ddd1..84986fde 100644
--- a/src/components/base/Modal/ModalContent.js
+++ b/src/components/base/Modal/ModalContent.js
@@ -39,7 +39,7 @@ class ModalContent extends PureComponent<{
 
     const contentStyle = {
       ...CONTENT_STYLE,
-      overflow: noScroll ? 'visible' : 'auto',
+      overflow: noScroll ? 'visible' : 'inherit',
     }
 
     return (

From 14498f1c9e929aff6e85aab38324cca09ed457ae Mon Sep 17 00:00:00 2001
From: Juan Cortes Ross <juan@bohem.io>
Date: Thu, 17 Jan 2019 18:48:19 +0100
Subject: [PATCH 5/8] Removes footer if no content visible on
 install/uninstall; Fixes inner scroll for operationdetails;

---
 src/components/ManagerPage/AppsList.js    | 10 +++++-----
 src/components/base/Modal/ModalContent.js |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js
index 390da5c6..b97fe08f 100644
--- a/src/components/ManagerPage/AppsList.js
+++ b/src/components/ManagerPage/AppsList.js
@@ -225,26 +225,25 @@ class AppsList extends PureComponent<Props, State> {
 
   renderFooter = () => {
     const { t } = this.props
-    const { status } = this.state
-    return ['error', 'success'].includes(status) ? (
+    return (
       <Box horizontal justifyContent="flex-end" style={{ width: '100%' }}>
         <Button primary onClick={this.handleCloseModal}>
           {t('common.close')}
         </Button>
       </Box>
-    ) : null
+    )
   }
 
   renderModal = () => {
     const { status } = this.state
     return (
-      <Modal isOpened={status !== 'idle' && status !== 'loading'}>
+      <Modal isOpened={status !== 'idle' && status !== 'loading'} centered>
         <ModalBody
           align="center"
           justify="center"
           title={''}
           render={this.renderBody}
-          renderFooter={this.renderFooter}
+          renderFooter={['error', 'success'].includes(status) ? this.renderFooter : undefined}
         >
           <FreezeDeviceChangeEvents />
         </ModalBody>
@@ -295,6 +294,7 @@ class AppsList extends PureComponent<Props, State> {
 
   render() {
     const { t } = this.props
+
     return (
       <Box flow={6}>
         <Box>
diff --git a/src/components/base/Modal/ModalContent.js b/src/components/base/Modal/ModalContent.js
index 84986fde..7b74ddd1 100644
--- a/src/components/base/Modal/ModalContent.js
+++ b/src/components/base/Modal/ModalContent.js
@@ -39,7 +39,7 @@ class ModalContent extends PureComponent<{
 
     const contentStyle = {
       ...CONTENT_STYLE,
-      overflow: noScroll ? 'visible' : 'inherit',
+      overflow: noScroll ? 'visible' : 'auto',
     }
 
     return (

From 0570dfacf8dd011d5bce19c5dc2e1379ab629a47 Mon Sep 17 00:00:00 2001
From: meriadec <meriadec.pillet@gmail.com>
Date: Mon, 4 Feb 2019 14:58:50 +0100
Subject: [PATCH 6/8] Various polishes on Modal refactoring

- use overlayScrollbar from electron blink features, to prevent
scrollbar taking space. as a side effect we can now scroll by holding
scrollbar with mouse left button. this is a native behavior that we
should not decide to remove for users
- update bottom white gradient to prevent overlapping scrollbar
- make account settings modal scrollable, but increase it's default
height so no weird Select triggering scroll when opening
- remove GrowScroll from release notes modal so we don't have two nested
scrolls (was producing really weird behaviour, scrollbar thumb not
indicating scroll % properly)
---
 src/components/base/Modal/ModalBody.js            |  2 +-
 src/components/modals/AccountSettingRenderBody.js | 15 +++++++++------
 .../modals/ReleaseNotes/ReleaseNotesBody.js       |  5 ++---
 src/main/app.js                                   |  1 +
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/components/base/Modal/ModalBody.js b/src/components/base/Modal/ModalBody.js
index 363f10aa..aa6642f1 100644
--- a/src/components/base/Modal/ModalBody.js
+++ b/src/components/base/Modal/ModalBody.js
@@ -90,7 +90,7 @@ const GRADIENT_STYLE = {
   position: 'absolute',
   bottom: 0,
   left: 0,
-  right: 6,
+  right: 20,
 }
 
 const GRADIENT_WRAPPER_STYLE = {
diff --git a/src/components/modals/AccountSettingRenderBody.js b/src/components/modals/AccountSettingRenderBody.js
index 3b494e55..71cba156 100644
--- a/src/components/modals/AccountSettingRenderBody.js
+++ b/src/components/modals/AccountSettingRenderBody.js
@@ -23,6 +23,7 @@ import TrackPage from 'analytics/TrackPage'
 import Spoiler from 'components/base/Spoiler'
 import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon'
 import Box from 'components/base/Box'
+import Space from 'components/base/Space'
 import Button from 'components/base/Button'
 import Input from 'components/base/Input'
 import Select from 'components/base/Select'
@@ -203,7 +204,6 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
 
     return (
       <ModalBody
-        noScroll
         onClose={onClose}
         title={t('account.settings.title')}
         render={() => (
@@ -266,8 +266,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
             ) : null}
             <Spoiler textTransform title={t('account.settings.advancedLogs')}>
               <SyncAgo date={account.lastSyncDate} />
-              <textarea
-                readOnly
+              <div
                 style={{
                   userSelect: 'text',
                   border: '1px dashed #f9f9f9',
@@ -275,13 +274,16 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
                   color: '#000',
                   fontFamily: 'monospace',
                   fontSize: '10px',
-                  height: 200,
                   outline: 'none',
                   padding: '20px',
                   width: '100%',
+                  whiteSpace: 'pre-wrap',
+                  wordWrap: 'break-word',
+                  overflow: 'auto',
                 }}
-                value={JSON.stringify(usefulData, null, 2)}
-              />
+              >
+                {JSON.stringify(usefulData, null, 2)}
+              </div>
             </Spoiler>
             <ConfirmModal
               analyticsName="RemoveAccount"
@@ -294,6 +296,7 @@ class AccountSettingRenderBody extends PureComponent<Props, State> {
               subTitle={t('common.areYouSure')}
               desc={t('settings.removeAccountModal.desc')}
             />
+            <Space of={20} />
           </Fragment>
         )}
         renderFooter={() => (
diff --git a/src/components/modals/ReleaseNotes/ReleaseNotesBody.js b/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
index 67162fab..61ff613d 100644
--- a/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
+++ b/src/components/modals/ReleaseNotes/ReleaseNotesBody.js
@@ -7,7 +7,6 @@ import network from 'api/network'
 
 import Button from 'components/base/Button'
 import Box from 'components/base/Box'
-import GrowScroll from 'components/base/GrowScroll'
 import Text from 'components/base/Text'
 import Spinner from 'components/base/Spinner'
 import GradientBox from 'components/GradientBox'
@@ -121,9 +120,9 @@ class ReleaseNotesBody extends PureComponent<Props, State> {
         render={() => (
           <Box relative style={{ height: 500 }} px={0} pb={0}>
             <TrackPage category="Modal" name="ReleaseNotes" />
-            <GrowScroll px={5} pb={8}>
+            <Box px={5} pb={8}>
               {this.renderContent()}
-            </GrowScroll>
+            </Box>
             <GradientBox />
           </Box>
         )}
diff --git a/src/main/app.js b/src/main/app.js
index 53d3ad9a..08385a54 100644
--- a/src/main/app.js
+++ b/src/main/app.js
@@ -84,6 +84,7 @@ const defaultWindowOptions = {
 
   backgroundColor: '#fff',
   webPreferences: {
+    blinkFeatures: 'OverlayScrollbars',
     devTools,
     // Enable, among other things, the ResizeObserver
     experimentalFeatures: true,

From 802492adaf1892ca39aaaefebd75639fd4ac9ec8 Mon Sep 17 00:00:00 2001
From: Juan Cortes Ross <juan@bohem.io>
Date: Thu, 7 Feb 2019 14:40:03 +0100
Subject: [PATCH 7/8] -Added enter key trigger for password modal -Added close
 buttons to technical data, share analytics, trade safely modals

---
 src/components/ManagerPage/AppsList.js      | 3 +--
 src/components/SettingsPage/PasswordForm.js | 1 +
 src/components/modals/Disclaimer.js         | 8 +++-----
 src/components/modals/ShareAnalytics.js     | 8 +++-----
 src/components/modals/TechnicalData.js      | 9 ++++-----
 5 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js
index 8d34ab3a..d2935f46 100644
--- a/src/components/ManagerPage/AppsList.js
+++ b/src/components/ManagerPage/AppsList.js
@@ -1,7 +1,7 @@
 // @flow
 /* eslint-disable react/jsx-no-literals */ // FIXME
 
-import React, { PureComponent, Fragment } from 'react'
+import React, { PureComponent } from 'react'
 import styled from 'styled-components'
 import { translate } from 'react-i18next'
 import { connect } from 'react-redux'
@@ -15,7 +15,6 @@ import { developerModeSelector } from 'reducers/settings'
 import installApp from 'commands/installApp'
 import uninstallApp from 'commands/uninstallApp'
 import Box from 'components/base/Box'
-import Space from 'components/base/Space'
 import Modal from 'components/base/Modal'
 import Tooltip from 'components/base/Tooltip'
 import Text from 'components/base/Text'
diff --git a/src/components/SettingsPage/PasswordForm.js b/src/components/SettingsPage/PasswordForm.js
index d0587fec..ff6a4a03 100644
--- a/src/components/SettingsPage/PasswordForm.js
+++ b/src/components/SettingsPage/PasswordForm.js
@@ -70,6 +70,7 @@ class PasswordForm extends PureComponent<Props> {
             </Label>
             <InputPassword
               style={{ width: 240 }}
+              onEnter={onSubmit}
               id="confirmPassword"
               onChange={onChange('confirmPassword')}
               value={confirmPassword}
diff --git a/src/components/modals/Disclaimer.js b/src/components/modals/Disclaimer.js
index 7e73dc78..a92dba1b 100644
--- a/src/components/modals/Disclaimer.js
+++ b/src/components/modals/Disclaimer.js
@@ -25,12 +25,14 @@ const mapDispatchToProps = {
 }
 
 class DisclaimerModal extends PureComponent<Props> {
+  onClose = () => this.props.closeModal(MODAL_DISCLAIMER)
   render() {
     const { t } = this.props
 
     return (
       <Modal name={MODAL_DISCLAIMER} centered>
         <ModalBody
+          onClose={this.onClose}
           title={t('disclaimerModal.title')}
           render={() => (
             <Box flow={4} ff="Open Sans|Regular" fontSize={4} color="smoke">
@@ -43,11 +45,7 @@ class DisclaimerModal extends PureComponent<Props> {
           )}
           renderFooter={() => (
             <Box horizontal justifyContent="flex-end">
-              <Button
-                data-e2e="continue_button"
-                onClick={() => this.props.closeModal(MODAL_DISCLAIMER)}
-                primary
-              >
+              <Button data-e2e="continue_button" onClick={this.onClose} primary>
                 {t('disclaimerModal.cta')}
               </Button>
             </Box>
diff --git a/src/components/modals/ShareAnalytics.js b/src/components/modals/ShareAnalytics.js
index c5f315fc..425e0711 100644
--- a/src/components/modals/ShareAnalytics.js
+++ b/src/components/modals/ShareAnalytics.js
@@ -24,6 +24,7 @@ const mapDispatchToProps = {
 }
 
 class ShareAnalytics extends PureComponent<Props, *> {
+  onClose = () => this.props.closeModal(MODAL_SHARE_ANALYTICS)
   render() {
     const { t } = this.props
     const items = [
@@ -67,6 +68,7 @@ class ShareAnalytics extends PureComponent<Props, *> {
     return (
       <Modal name={MODAL_SHARE_ANALYTICS} centered>
         <ModalBody
+          onClose={this.onClose}
           title={t('onboarding.analytics.shareAnalytics.title')}
           render={() => (
             <Fragment>
@@ -78,11 +80,7 @@ class ShareAnalytics extends PureComponent<Props, *> {
           )}
           renderFooter={() => (
             <Fragment>
-              <Button
-                onClick={() => this.props.closeModal(MODAL_SHARE_ANALYTICS)}
-                primary
-                data-e2e="modal_buttonClose_shareAnalytics"
-              >
+              <Button onClick={this.onClose} primary data-e2e="modal_buttonClose_shareAnalytics">
                 {t('common.close')}
               </Button>
             </Fragment>
diff --git a/src/components/modals/TechnicalData.js b/src/components/modals/TechnicalData.js
index 93f2c3ef..b975f6da 100644
--- a/src/components/modals/TechnicalData.js
+++ b/src/components/modals/TechnicalData.js
@@ -23,6 +23,8 @@ const mapDispatchToProps = {
 }
 
 class TechnicalData extends PureComponent<Props, *> {
+  onClose = () => this.props.closeModal(MODAL_TECHNICAL_DATA)
+
   render() {
     const { t } = this.props
 
@@ -44,6 +46,7 @@ class TechnicalData extends PureComponent<Props, *> {
     return (
       <Modal name={MODAL_TECHNICAL_DATA} centered>
         <ModalBody
+          onClose={this.onClose}
           title={t('onboarding.analytics.technicalData.mandatoryContextual.title')}
           render={() => (
             <Fragment>
@@ -55,11 +58,7 @@ class TechnicalData extends PureComponent<Props, *> {
           )}
           renderFooter={() => (
             <Fragment>
-              <Button
-                onClick={() => this.props.closeModal(MODAL_TECHNICAL_DATA)}
-                primary
-                data-e2e="modal_buttonClose_techData"
-              >
+              <Button onClick={this.onClose} primary data-e2e="modal_buttonClose_techData">
                 {t('common.close')}
               </Button>
             </Fragment>

From bcae62f5f7d0e0c2127341570ed48d9ae92b08a9 Mon Sep 17 00:00:00 2001
From: Juan Cortes Ross <juan@bohem.io>
Date: Thu, 7 Feb 2019 15:36:13 +0100
Subject: [PATCH 8/8] Reduced horizontal margin on shareanalytics/technicaldata
 modals

---
 src/components/modals/ShareAnalytics.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/modals/ShareAnalytics.js b/src/components/modals/ShareAnalytics.js
index 425e0711..76808988 100644
--- a/src/components/modals/ShareAnalytics.js
+++ b/src/components/modals/ShareAnalytics.js
@@ -111,5 +111,5 @@ export const InlineDesc = styled(Box).attrs({
   ff: 'Open Sans|SemiBold',
   fontSize: 4,
   color: 'dark',
-  mx: '45px',
+  mx: '15px',
 })``