Index: ow/mail.py
===================================================================
--- ow/mail.py	(revision 07f51900c2e61e3cd65c7cd7968809a2834d3187)
+++ ow/mail.py	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -39,10 +39,17 @@
 def send_verification_email(request, user):
     subject = _('Welcome to OpenWorkouts')
-    template = 'ow:templates/mail_verify_account.pt'
+    txt_template = 'ow:templates/mail_verify_account_txt.pt'
+    html_template = 'ow:templates/mail_verify_account_html.pt'
     verify_link = request.resource_url(user, 'verify', user.verification_token)
     context = {'user': user, 'verify_link': verify_link}
     mailer = get_mailer(request)
-    body = render(template, context, request)
-    message = Message(subject=subject, recipients=[user.email], body=body)
+    txt_body = render(txt_template, context, request)
+    html_body = render(html_template, context, request)
+    message = Message(
+        subject=subject,
+        recipients=[user.email],
+        body=txt_body,
+        html=html_body
+    )
     message = idna_encode_recipients(message)
     mailer.send_to_queue(message)
Index: ow/static/css/main.css
===================================================================
--- ow/static/css/main.css	(revision 07f51900c2e61e3cd65c7cd7968809a2834d3187)
+++ ow/static/css/main.css	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -1486,2 +1486,39 @@
   font-size: 0.8125rem;
 }
+.verify-account-content {
+  background-position: center;
+  background-size: cover;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-height: calc(100vh - 98px);
+  padding: 1em 0;
+  color: #e1e1e1;
+}
+.verify-account-content .info {
+  max-width: 580px;
+  background-color: rgba(21, 21, 21, 0.6);
+  border-radius: 6px;
+  padding: 2em 1.5em;
+}
+.verify-account-content .info div {
+  margin-bottom: 1.5em;
+}
+.verify-account-content a {
+  color: #e1e1e1;
+  font-size: 13px;
+  text-decoration: none;
+  margin-right: 0.75em;
+}
+.verify-account-content a:hover {
+  color: white;
+}
+.verify-account-content .button {
+  transition: all 500ms ease-in-out;
+  background-color: #EE4056;
+  color: white;
+  text-transform: uppercase;
+}
+.verify-account-content .button:hover {
+  background-color: #e6152f;
+}
Index: ow/static/less/main.less
===================================================================
--- ow/static/less/main.less	(revision 07f51900c2e61e3cd65c7cd7968809a2834d3187)
+++ ow/static/less/main.less	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -32,2 +32,3 @@
 @import "pages/login.less";
 @import "pages/profile.less";
+@import "pages/verify_account.less";
Index: ow/static/less/pages/verify_account.less
===================================================================
--- ow/static/less/pages/verify_account.less	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
+++ ow/static/less/pages/verify_account.less	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -0,0 +1,41 @@
+.verify-account-content {
+    background-position: center;
+    background-size: cover;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    min-height: calc(100vh - 98px);
+    padding: 1em 0;
+    color: @color-main-light;
+
+    .info {
+        max-width: 580px;
+        background-color: fadeout(@color-main, 40%);
+        border-radius: 6px;
+        padding: 2em  1.5em;
+        div {
+            margin-bottom: 1.5em;
+        }
+    }
+
+    a {
+        color: @color-main-light;
+        font-size: 13px;
+        text-decoration: none;
+        margin-right: .75em;
+        &:hover {
+            color: white;
+        }
+    }
+
+    .button {
+        transition: all 500ms ease-in-out;
+        background-color: @color-app;
+        color: white;
+        text-transform: uppercase;
+        &:hover {
+            background-color: darken(@color-app, 10%);
+        }
+    }
+
+}
Index: templates/mail_verify_account.pt
===================================================================
--- ow/templates/mail_verify_account.pt	(revision 07f51900c2e61e3cd65c7cd7968809a2834d3187)
+++ 	(revision )
@@ -1,26 +1,0 @@
-<html tal:omit-tag=""
-      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
-      i18n:domain="OpenWorkouts">
-
-  <tal:t i18n:translate="">Welcome to OpenWorkouts</tal:t>
-  <tal:user tal:content="user.fullname"></tal:user>
-
-  <tal:t i18n:translate="">
-    You have joined the OpenWorkouts community successfully,
-    now please verify your account.
-  </tal:t>
-
-  <tal:t i18n:translate="">
-    Click on the following link, or copy and paste it in your browser
-    navigation bar to verify your account:
-  </tal:t>
-
-  <tal:link tal:content="verify_link"></tal:link>
-
-  <tal:t i18n:translate>
-    Thank you for joining us.
-
-    Best regards from the OpenWorkouts team.
-  </tal:t>
-
-</html>
Index: ow/templates/mail_verify_account_html.pt
===================================================================
--- ow/templates/mail_verify_account_html.pt	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
+++ ow/templates/mail_verify_account_html.pt	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -0,0 +1,57 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xml:lang="en"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      i18n:domain="OpenWorkouts"
+      metal:use-macro="load: base_anonymous.pt"
+      tal:attributes="lang request.locale_name">
+
+  <metal:content metal:fill-slot="content">
+
+    <div class="verify-account-content">
+
+      <div class="info">
+
+        <h1>
+          <tal:t i18n:translate="">Welcome</tal:t> <tal:user tal:content="user.fullname"></tal:user>
+        </h1>
+
+        <p>
+          <tal:t i18n:translate="">
+            You have joined the OpenWorkouts community successfully,
+            now please verify your account.
+          </tal:t>
+        </p>
+
+        <p>
+          <a href="" class="button button-action"
+             tal:attributes="href verify_link"
+             i18n:translate="">Verify my account (*)</a>
+        </p>
+
+        <p>
+          <tal:t i18n:translate>
+            Thank you for joining us.
+          </tal:t>
+          <tal:t i18n:translate>
+            Best regards from the OpenWorkouts team.
+          </tal:t>
+        </p>
+
+        <p>
+          <small i18n:translate="">
+            (*) If clicking on the button does not work, you can copy this link and paste it on your browser navigation bar:
+          </small>
+        </p>
+        <p>
+          <small tal:content="verify_link"></small>
+        </p>
+
+      </div>
+
+    </div>
+
+  </metal:content>
+
+</html>
Index: ow/templates/mail_verify_account_txt.pt
===================================================================
--- ow/templates/mail_verify_account_txt.pt	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
+++ ow/templates/mail_verify_account_txt.pt	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -0,0 +1,26 @@
+<html tal:omit-tag=""
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      i18n:domain="OpenWorkouts">
+
+  <tal:t i18n:translate="">Welcome to OpenWorkouts</tal:t>
+  <tal:user tal:content="user.fullname"></tal:user>
+
+  <tal:t i18n:translate="">
+    You have joined the OpenWorkouts community successfully,
+    now please verify your account.
+  </tal:t>
+
+  <tal:t i18n:translate="">
+    Click on the following link, or copy and paste it in your browser
+    navigation bar to verify your account:
+  </tal:t>
+
+  <tal:link tal:content="verify_link"></tal:link>
+
+  <tal:t i18n:translate>
+    Thank you for joining us.
+
+    Best regards from the OpenWorkouts team.
+  </tal:t>
+
+</html>
Index: ow/tests/test_mail.py
===================================================================
--- ow/tests/test_mail.py	(revision 07f51900c2e61e3cd65c7cd7968809a2834d3187)
+++ ow/tests/test_mail.py	(revision b8ef4ab22259f82e18e64afb6e8095b277393241)
@@ -41,6 +41,9 @@
         message.recipients = ['user@example.net']
         m.return_value = message
-        body = Mock()
-        r.return_value = body
+
+        txt_body = Mock()
+        html_body = Mock()
+        r.side_effect = [txt_body, html_body]
+
         request = DummyRequest()
         request.root = root
@@ -49,11 +52,25 @@
         verify_link = request.resource_url(
             user, 'verify', user.verification_token)
-        r.assert_called_once_with(
-            'ow:templates/mail_verify_account.pt',
-            {'user': user, 'verify_link': verify_link},
-            request
-        )
+
+        # two render calls
+        assert r.call_count == 2
+
+        # first call renders the text version of the email
+        assert r.call_args_list[0][0][0] == (
+            'ow:templates/mail_verify_account_txt.pt')
+        assert r.call_args_list[0][0][1] == (
+            {'user': user, 'verify_link': verify_link})
+        assert r.call_args_list[0][0][2] == request
+
+        # second call renders the html version of the email
+        assert r.call_args_list[1][0][0] == (
+            'ow:templates/mail_verify_account_html.pt')
+        assert r.call_args_list[1][0][1] == (
+            {'user': user, 'verify_link': verify_link})
+        assert r.call_args_list[1][0][2] == request
+
         m.assert_called_once
         m.call_args_list[0][1]['recipients'] == user.email
-        m.call_args_list[0][1]['body'] == body
+        m.call_args_list[0][1]['body'] == txt_body
+        m.call_args_list[0][1]['html'] == html_body
         mailer.send_to_queue.assert_called_once_with(message)
