diff --git a/mo/web/auth.py b/mo/web/auth.py
index 4b6b0d9be57c4a36616680abfc1211c7978957c4..1b523a8a7f9f3785c1ecf329777f6114a3cb97aa 100644
--- a/mo/web/auth.py
+++ b/mo/web/auth.py
@@ -1,9 +1,11 @@
 import datetime
 
 from flask import render_template, request, g, redirect, url_for, session
+from flask.helpers import flash
 from flask_wtf import FlaskForm
 import werkzeug.exceptions
 import wtforms
+from wtforms.fields.html5 import EmailField
 import wtforms.validators as validators
 from sqlalchemy.orm import joinedload
 from typing import Optional
@@ -17,7 +19,7 @@ from mo.web import app, NeedLoginError
 
 class LoginForm(FlaskForm):
     next = wtforms.HiddenField()
-    email = wtforms.StringField('E-mail', validators=[validators.DataRequired()])
+    email = EmailField('E-mail', validators=[validators.DataRequired()])
     passwd = wtforms.PasswordField('Heslo')
     submit = wtforms.SubmitField('Přihlásit se')
     reset = wtforms.SubmitField('Obnovit heslo')
@@ -44,7 +46,7 @@ def login():
 
     if not user:
         app.logger.error('Login: Neznámý uživatel <%s>', email)
-        error = 'Neznámý uživatel.'
+        flash('Neznámý uživatel', 'danger')
     elif form.reset.data:
         app.logger.info('Login: Požadavek na reset hesla pro <%s>', email)
 
@@ -52,17 +54,17 @@ def login():
         now = datetime.datetime.now().astimezone()
         if (user.reset_at is not None
                 and now - user.reset_at < min_time_between_resets):
-            error = 'Poslední požadavek na obnovení hesla byl odeslán příliš nedávno.'
+            flash('Poslední požadavek na obnovení hesla byl odeslán příliš nedávno', 'danger')
         else:
             token = mo.users.ask_reset_password(user)
             db.get_session().commit()
 
             mo.util.send_password_reset_email(user, token)
-            return render_template('reset.html')
+            flash('Na uvedenou adresu byl odeslán e-mail s odkazem na obnovu hesla', 'success')
 
     elif not form.passwd.data or not mo.users.check_password(user, form.passwd.data):
         app.logger.error('Login: Špatné heslo pro uživatele <%s>', email)
-        error = 'Chybné heslo.'
+        flash('Chybné heslo', 'danger')
     else:
         app.logger.info('Login: Přihlásil se uživatel <%s>', email)
         mo.users.login(user)
@@ -70,7 +72,7 @@ def login():
         session['uid'] = user.user_id
         return after_login(user, form.next.data)
 
-    return render_template('login.html', form=form, error=error)
+    return render_template('login.html', form=form)
 
 
 @app.route('/auth/logout', methods=('POST',))
@@ -115,22 +117,20 @@ def handle_need_login(e):
 
 class ResetForm(FlaskForm):
     token = wtforms.HiddenField()
-    passwd = wtforms.PasswordField('Heslo')
+    passwd = wtforms.PasswordField('Nové heslo')
     submit = wtforms.SubmitField('Nastavit heslo')
     cancel = wtforms.SubmitField('Zrušit obnovu hesla')
 
 
 @app.route('/auth/reset', methods=('GET', 'POST'))
 def reset():
-    if request.args.get('done'):
-        return render_template('reset.html', okay='Heslo nastaveno.')
-
     form = ResetForm(token=request.args.get('token'))
 
     ok = form.validate_on_submit()
     user = mo.users.check_reset_password(form.token.data)
     if not user:
-        return render_template('reset.html', fatal='Neplatný požadavek na obnovu hesla.')
+        flash('Neplatný požadavek na obnovu hesla', 'danger')
+        return redirect(url_for('login'))
     if not ok:
         return render_template('reset.html', form=form)
 
@@ -138,13 +138,11 @@ def reset():
         mo.users.cancel_reset_password(user)
         app.logger.info('Login: Zrušen reset hesla pro uživatele <%s>', user.email)
         db.get_session().commit()
-        return render_template('reset.html', okay='Obnova hesla zrušena.')
+        flash('Obnova hesla zrušena', 'warning')
+        return redirect(url_for('login'))
     elif len(form.passwd.data) < 8:
-        return render_template(
-            'reset.html',
-            form=form,
-            error='Heslo musí být aspoň 8 znaků dlouhé.'
-        )
+        flash('Heslo musí být aspoň 8 znaků dlouhé', 'danger')
+        return render_template('reset.html', form=form)
     else:
         mo.users.do_reset_password(user)
         mo.users.set_password(user, form.passwd.data)
@@ -155,4 +153,5 @@ def reset():
             details={'action': 'reset-passwd'},
         )
         db.get_session().commit()
-        return redirect(url_for('reset', done=1))
+        flash('Nové heslo úspěšně nastaveno, nyní se můžete přihlásit', 'success')
+        return redirect(url_for('login'))
diff --git a/mo/web/templates/login.html b/mo/web/templates/login.html
index 8c1b01f319051a225647e9367d0367cbff773589..3489c22980058d717dc4a459b5c9d07165d91ba1 100644
--- a/mo/web/templates/login.html
+++ b/mo/web/templates/login.html
@@ -1,19 +1,17 @@
 {% extends "base.html" %}
+{% import "bootstrap/wtf.html" as wtf %}
 {% block body %}
 	<h2>Login</h2>
 
-	{% if error %}
-	<p class=error>{{ error }}
-	{% endif %}
-
-	<form method="POST" action="">
+	<form method="POST" class="form form-horizontal" action="">
 		{{ form.csrf_token }}
 		{{ form.next() }}
-		<table>
-			<tr><td>E-mail:<td>{{ form.email(size=32) }}
-			<tr><td>Heslo:<td>{{ form.passwd(size=32) }}
-			<tr><td colspan=2>{{ form.submit() }} {{ form.reset() }}
-		</table>
+		{{ wtf.form_field(form.email, form_type='horizontal') }}
+		{{ wtf.form_field(form.passwd, form_type='horizontal') }}
+		<div class="btn-group col-lg-offset-2">
+			{{ wtf.form_field(form.submit, class="btn btn-primary") }}
+			{{ wtf.form_field(form.reset) }}
+		</div>
 	</form>
 
 {% endblock %}
diff --git a/mo/web/templates/reset.html b/mo/web/templates/reset.html
index 71712e9f08bc348a154236e760190bf392bd430c..8ad0d831db46ccf0cb6b84518a97e390ae4de5cb 100644
--- a/mo/web/templates/reset.html
+++ b/mo/web/templates/reset.html
@@ -1,25 +1,16 @@
 {% extends "base.html" %}
+{% import "bootstrap/wtf.html" as wtf %}
 {% block body %}
-	<h2>Obnova hesla</h2>
+	<h2>Nastavení nového hesla</h2>
 
-{% if fatal %}
-	<p class=error>{{ fatal }}
-{% elif okay %}
-	<p class=okay>{{ okay }}
-	<p>Pokračujte <a href='{{ url_for('login') }}'>přihlášením do systému</a>.
-{% elif form %}
-	{% if error %}
-	<p class=error>{{ error }}
-	{% endif %}
-	<form method="POST" action="">
+	<form method="POST" class="form form-horizontal" action="">
 		{{ form.csrf_token }}
 		{{ form.token() }}
-		<table>
-			<tr><td>Heslo:<td>{{ form.passwd(size=32) }}
-			<tr><td colspan=2>{{ form.submit() }} {{ form.cancel() }}
-		</table>
+		{{ wtf.form_field(form.passwd, form_type='horizontal') }}
+		<div class="btn-group col-lg-offset-2">
+			{{ wtf.form_field(form.submit, class="btn btn-primary") }}
+			{{ wtf.form_field(form.cancel) }}
+		</div>
 	</form>
-{% else %}
-	<p>Na uvedenou adresu byl odeslán e-mail s odkazem na obnovu hesla.
-{% endif %}
+
 {% endblock %}