diff --git a/src/application/templates/bootstrap-3/components/post.twig b/src/application/templates/bootstrap-3/components/post.twig
new file mode 100644
index 0000000..ac969c0
--- /dev/null
+++ b/src/application/templates/bootstrap-3/components/post.twig
@@ -0,0 +1,168 @@
+{%- set fileAttachments = attachments|filter(a => not (a.mimeType starts with "image/" or a.mimeType starts with "video/")) -%}
+{%- set imageAttachments = attachments|filter(a => a.mimeType starts with "image/" or a.mimeType starts with "video/") -%}
+
+{%- set canReply =
+ not post.deleted
+ and not topic.isLocked
+ and currentUser is not null
+ and currentUser.hasPermission(permission("CREATE_OWN_POST"))
+-%}
+
+{%- set canEdit =
+ not post.deleted
+ and not topic.isLocked
+ and currentUser is not null
+ and (
+ (
+ postAuthor is not null
+ and postAuthor.hasPermission(permission("EDIT_OWN_POST"))
+ )
+ or currentUser.hasPermission(permission("EDIT_OTHER_POST"))
+ ) -%}
+
+{%- set canDelete =
+ not post.deleted
+ and currentUser is not null
+ and (
+ (
+ postAuthor is not null
+ and postAuthor.id == currentUser.id
+ and postAuthor.hasPermission(permission("DELETE_OWN_POST"))
+ )
+ or currentUser.hasPermission(permission("DELETE_OTHER_POST"))
+ ) -%}
+
+{%- set canViewAttachments = currentUser is not null -%}
+
+{%- set your_are_the_author =
+ currentUser is not null
+ and postAuthor is not null
+ and currentUser.id == postAuthor.id
+-%}
+
+{%- set is_op =
+ topicAuthor is not null
+ and postAuthor is not null
+ and postAuthor.id == topicAuthor.id
+-%}
+
+{% if post.deleted %}
+
diff --git a/src/application/templates/bootstrap-3/delete_post.twig b/src/application/templates/bootstrap-3/delete_post.twig
new file mode 100644
index 0000000..90eaf09
--- /dev/null
+++ b/src/application/templates/bootstrap-3/delete_post.twig
@@ -0,0 +1,36 @@
+{% set title = __("Delete post") %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
+
{{ __("Do you want to delete this post?") }}
+
+
+ {{ __("Are you sure you want to delete the following post:") }}
+ {% include "components/post.twig" with {
+ post: ctx.post,
+ postAuthor: ctx.postAuthor,
+ attachments: ctx.attachments,
+ hide_actions: true,
+ } %}
+
+ {{ __("Are you sure you want to delete the topic %topic% including all posts and attachments?", {
+ "topic": ctx.topic.title|e("html"),
+ }) }}
+
+
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/error_page.twig b/src/application/templates/bootstrap-3/error_page.twig
new file mode 100644
index 0000000..dde4057
--- /dev/null
+++ b/src/application/templates/bootstrap-3/error_page.twig
@@ -0,0 +1,12 @@
+{% set title = __("Error") %}
+{% extends "base.twig" %}
+
+{% block navbar %}
+ {% if not ctx.skipLoginCheck %}
+ {{ parent() }}
+ {% endif %}
+{% endblock %}
+
+{% block content %}
+ {% include "components/alert_error.twig" with { message: ctx.message } %}
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/info_page.twig b/src/application/templates/bootstrap-3/info_page.twig
new file mode 100644
index 0000000..e243b36
--- /dev/null
+++ b/src/application/templates/bootstrap-3/info_page.twig
@@ -0,0 +1,12 @@
+{% set title = __("Information") %}
+{% extends "base.twig" %}
+
+{% block navbar %}
+ {% if not ctx.skipLoginCheck %}
+ {{ parent() }}
+ {% endif %}
+{% endblock %}
+
+{% block content %}
+ {% include "components/alert_info.twig" with { message: ctx.message } %}
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/login.twig b/src/application/templates/bootstrap-3/login.twig
new file mode 100644
index 0000000..63b9867
--- /dev/null
+++ b/src/application/templates/bootstrap-3/login.twig
@@ -0,0 +1,50 @@
+{% set title = __("Log in") %}
+{% set formId = "login" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("Log in") }}
+
+
+
+
+
+ {% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+ {% endif %}
+
+
+
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/new_password.twig b/src/application/templates/bootstrap-3/new_password.twig
new file mode 100644
index 0000000..55a4b79
--- /dev/null
+++ b/src/application/templates/bootstrap-3/new_password.twig
@@ -0,0 +1,42 @@
+{% set title = __("Reset password") %}
+{% set formId = "pwnew" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("Reset password") }}
+
+
+
+
+
+ {% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+ {% endif %}
+
+
+
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/new_topic.twig b/src/application/templates/bootstrap-3/new_topic.twig
new file mode 100644
index 0000000..74be156
--- /dev/null
+++ b/src/application/templates/bootstrap-3/new_topic.twig
@@ -0,0 +1,58 @@
+{% set title = __("New topic") %}
+{% set formId = "newtopic" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("New topic") }}
+
+
+{% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/password_reset.twig b/src/application/templates/bootstrap-3/password_reset.twig
new file mode 100644
index 0000000..f633106
--- /dev/null
+++ b/src/application/templates/bootstrap-3/password_reset.twig
@@ -0,0 +1,42 @@
+{% set title = __("Reset password") %}
+{% set formId = "pwreset" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("Reset password") }}
+
+
+
+
+
+ {% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+ {% endif %}
+
+
+
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/register.twig b/src/application/templates/bootstrap-3/register.twig
new file mode 100644
index 0000000..1e4cd92
--- /dev/null
+++ b/src/application/templates/bootstrap-3/register.twig
@@ -0,0 +1,89 @@
+{% set title = __("Register") %}
+{% set formId = "register" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("Register") }}
+
+
+
+
+
+ {% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+ {% endif %}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/search.twig b/src/application/templates/bootstrap-3/search.twig
new file mode 100644
index 0000000..c8f6315
--- /dev/null
+++ b/src/application/templates/bootstrap-3/search.twig
@@ -0,0 +1,63 @@
+{% set title = __("Search") %}
+{% set formId = "search" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+
+
{{ __("Search") }}
+
+
+{% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+
+
+
+{% if g.get.query is defined and g.get.query is not null and g.get.query != "" %}
+ {% if ctx.posts|length > 0 %}
+
+ {% endif %}
+{% endif %}
+
+{% endblock %}
diff --git a/src/application/templates/bootstrap-3/view_topic.twig b/src/application/templates/bootstrap-3/view_topic.twig
new file mode 100644
index 0000000..008c336
--- /dev/null
+++ b/src/application/templates/bootstrap-3/view_topic.twig
@@ -0,0 +1,353 @@
+{% set canReply =
+ not ctx.topic.isLocked
+ and currentUser is not null
+ and currentUser.hasPermission(permission("CREATE_OWN_POST")) %}
+
+{% set canEdit =
+ currentUser is not null and (
+ (
+ ctx.topicAuthor is not null
+ and currentUser.id == ctx.topicAuthor.id
+ and ctx.topicAuthor.hasPermission(permission("EDIT_OWN_TOPIC"))
+ )
+ or currentUser.hasPermission(permission("EDIT_OTHER_TOPIC"))
+ ) %}
+
+{% set canDelete =
+ currentUser is not null and (
+ (
+ ctx.topicAuthor is not null
+ and currentUser.id == ctx.topicAuthor.id
+ and ctx.topicAuthor.hasPermission(permission("DELETE_OWN_TOPIC"))
+ )
+ or currentUser.hasPermission(permission("DELETE_OTHER_TOPIC"))
+ ) %}
+
+{% set title = ctx.topic.title %}
+{% extends "base.twig" %}
+
+{% block content %}
+
+{% if canEdit %}
+
+
+
+{% endif %}
+{% if currentUser is null %}
+
+
+
+
+
{{ __("Permission denied") }}
+
+
+ {{ __("You must be logged in to view attachments") }}
+
+
+
+
+
+
+{% else %}
+
+
+
+
+
+
{{ __("Attachment") }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ __("Attachment") }}
+
+
+
+
+
+
+
+
+
+{% endif %}
+
+{% set formError = getAndClearFormError("updateTopic") %}
+{% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+{% set formError = getAndClearFormError("lockTopic") %}
+{% if formError %}
+ {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+{% set formError = null %}
+
+