diff --git a/.gitignore b/.gitignore
index a3430b3..355b7d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,5 @@ __pycache__/
venv/
*.pyc
-/freepost/static/css/
/database.sqlite
/settings.production.yaml
diff --git a/freepost/static/css/freepost.css b/freepost/static/css/freepost.css
new file mode 100644
index 0000000..d5b641b
--- /dev/null
+++ b/freepost/static/css/freepost.css
@@ -0,0 +1,825 @@
+* {
+ margin: 0;
+ padding: 0;
+ font-family: sans-serif;
+
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+a, a:hover, a:visited {
+ background: transparent;
+ color: #337ab7;
+ text-decoration: none;
+}
+
+blockquote {
+ background-color: #f8f8f8;
+ border-left: 5px solid #e9e9e9;
+ font-size: .85em;
+ margin: 1em 0;
+ padding: .5em 1em;
+}
+
+blockquote cite {
+ color: #999;
+ display: block;
+ font-size: .8em;
+ margin-top: 1em;
+}
+
+blockquote cite:before {
+ content: "\2014 \2009";
+}
+
+h3 {
+ font-size: 1.5em;
+ font-weight: normal;
+ margin: 1em 0 .5em 0;
+}
+
+p {
+ margin: 0 0 10px 0;
+}
+
+.bg-green {
+ background-color: #d9ffca;
+ border-radius: 4px;
+ padding: .5em 1em;
+}
+
+.bg-red {
+ background-color: #f2dede;
+ border-radius: 4px;
+ padding: .5em 1em;
+}
+
+.bg-blue {
+ background-color: #337ab7;
+ border-radius: 4px;
+ padding: .5em 1em;
+}
+
+.bg-light-blue {
+ background-color: #d9edf7;
+ border-radius: 4px;
+ padding: .5em 1em;
+}
+
+/* Some styles for buttons */
+.button {
+ border: 0px;
+ border-radius: 4px;
+ cursor: pointer;
+ display: inline-block;
+ padding: .5em 1em;
+ text-align: center;
+}
+
+@media only screen and (max-width: 800px) {
+ .button {
+ font-size: 1.2rem;
+ padding: .5em 1em;
+ width: 100%;
+ }
+}
+
+.button_transparent, /* Green */
+.button_transparent:hover,
+.button_transparent:visited {
+ background-color: transparent;
+ border: 0;
+ color: black;
+}
+
+.button_ok, /* Green */
+.button_ok:hover,
+.button_ok:visited {
+ background-color: #4caf50;
+ color: #fff;
+}
+
+.button_info, /* Blue */
+.button_info:hover,
+.button_info:visited {
+ background-color: #008cba;
+ color: #fff;
+}
+
+.button_alert, /* Red */
+.button_alert:hover,
+.button_alert:visited {
+ background-color: #f44336;
+ color: #fff;
+}
+
+.button_default, /* Gray */
+.button_default:hover,
+.button_default:visited {
+ background-color: #e7e7e7;
+ color: #000;
+}
+
+.button_default1, /* Black */
+.button_default1:hover,
+.button_default1:visited {
+ background-color: #555;
+ color: #fff;
+}
+
+img {
+ /* Prevent images from taking up too much space in comments */
+ max-width: 100%;
+}
+
+label {
+ cursor: pointer;
+ font-weight: normal;
+}
+
+/* Add light blue shadow to form controls */
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
+}
+
+.form-control {
+ display: block;
+ padding: .5em 1em;
+ line-height: 1.42857143;
+ color: #555;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ width: 100%;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
+ -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
+}
+
+.form-control-inline {
+ display: inline;
+ width: auto;
+}
+
+textarea.form-control {
+ height: 8rem;
+}
+
+.pagination {}
+
+ .pagination > form {
+ display: inline-block;
+ }
+
+ .pagination > .page_number {
+ font-size: .7rem;
+ font-weight: bold;
+ margin: 0 1rem;
+ }
+
+/* When users vote, this is used as target, such that
+ * the page is not reloaded
+ */
+.vote_sink {
+ height: 1px;
+ left: -10px;
+ position: fixed;
+ top: -10px;
+ width: 1px;
+}
+
+html, body {
+ background-color: #fff;
+ font-size: 1em;
+ height: 100%;
+ line-height: 1em;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+
+pre {
+ background-color: #efefef;
+ font-family: "Courier 10 Pitch", Courier, monospace;
+ font-size: 95%;
+ line-height: 140%;
+ margin: 1rem 0;
+ padding: 1rem;
+ white-space: pre;
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap;
+ white-space: -o-pre-wrap;
+}
+
+ pre code {
+ font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
+ font-size: 95%;
+ line-height: 140%;
+ white-space: pre;
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap;
+ white-space: -o-pre-wrap;
+ }
+
+/* Monospace
to write some nice ASCII art in frontpage */
+pre.new_year {
+ background-color: transparent;
+ color: #BF0000;
+ font-family: monospace;
+ font-size: .8rem;
+ font-webkit: bold;
+ margin: 0 0 2em 0;
+ text-align: center;
+ white-space: pre;
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap;
+ white-space: -o-pre-wrap;
+}
+
+/* Inline code */
+:not(pre) > code {
+ background-color: #efefef;
+ border-radius: 3px;
+ display: inline-block;
+ font-family: monospace, sans-serif;
+ font-size: 85%;
+ line-height: 140%;
+ margin: 0 .2em;
+ padding: .2em;
+ white-space: pre;
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap;
+ white-space: -o-pre-wrap;
+}
+
+/* A that respects \n without converting to
*/
+div.pre {
+ white-space: pre;
+}
+
+select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background: transparent;
+ border: 0;
+ cursor: pointer;
+}
+
+ul, ol {
+ margin: 1.2em 2em;
+}
+
+/* Burger menu icon
+ *
+ * How to use:
+ *
+ */
+.burger-icon {
+ display: inline-block;
+ cursor: pointer;
+ position: relative;
+}
+
+ .burger-icon > .line1,
+ .burger-icon > .line2,
+ .burger-icon > .line3 {
+ background-color: #000;
+ height: 4px;
+ margin: 4px 0;
+ transition: .5s;
+ width: 36px;
+ }
+
+ .burger-icon.open > .line1 {
+ transform: rotate(-45deg) translate(-0px, 11px);
+ }
+
+ .burger-icon.open > .line2 {
+ opacity: 0;
+ }
+
+ .burger-icon.open > .line3 {
+ transform: rotate(45deg) translate(-0px, -11px);
+ }
+
+ .burger-icon.notify > .line1,
+ .burger-icon.notify > .line2,
+ .burger-icon.notify > .line3 {
+ background-color: #f00;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* A class used for displaying URLs domain (under post tile) */
+.netloc {
+ color: #828282;
+ font-size: 1rem;
+ font-style: italic;
+}
+
+.monkey {
+ height: 1.5em;
+ margin: 0 1em;
+ vertical-align: middle;
+}
+
+a.topic,
+a.topic:hover,
+a.topic:visited {
+ color: rgba(200,0,100,.8);
+ font-size: 1rem;
+ padding: 0 .2rem;
+ text-decoration: none;
+}
+
+/* Text icon near the title, to display the post content */
+.text_preview {
+ height: .8rem;
+ margin: 0 .5rem;
+ vertical-align: middle;
+}
+
+/* Logo text */
+a.logo,
+a.logo:hover,
+a.logo:visited {
+ color: #000;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+/* List of posts, for example in the homepage */
+.posts {}
+
+ .posts > .menu {
+ border-bottom: 0px transparent;
+ font-size: .8rem;
+ margin-bottom: 1rem;
+ }
+
+ .posts > .menu > a {
+ padding: .2rem;
+ }
+
+ /* A singe post */
+ .posts > .post {
+ display: grid;
+ grid-template-columns: min-content auto;
+ grid-column-gap: 1.5rem;
+
+ margin-bottom: 2rem;
+ }
+
+ /* Show numbered position in the list */
+ .posts > .post > .position {
+ color: #555;
+ font-style: italic;
+ line-height: 1.9rem;
+ text-align: right;
+ }
+
+ .posts > .post > .info > .title > a {
+ color: #000;
+ font-size: 1.6rem;
+ }
+
+ /* Some post info showed below the title */
+ .posts > .post > .info > .about {
+ color: #666;
+ margin: .5rem 0 0 0;
+ }
+
+ .posts > .pagination > form {
+ width: 100%;
+ }
+
+.container {
+ margin: auto;
+ max-width: 90%;
+}
+
+
+ /**************************************************************************
+ * Page header
+ *************************************************************************/
+
+
+ .container > .header {
+ margin-top: 1rem;
+ }
+
+ @media only screen and (max-width: 800px) {
+ .container > .header {
+ display: grid;
+ grid-template-columns: auto;
+ }
+
+ .container > .header > .title-large {
+ display: none;
+ }
+
+ .container > .header > .title-small {
+ display: grid;
+ grid-template-columns: auto max-content;
+ }
+ }
+
+ @media only screen and (min-width: 800px) {
+ .container > .header {
+ display: grid;
+ grid-template-columns: max-content auto;
+ }
+
+ .container > .header > .title-small {
+ display: none;
+ }
+ }
+
+ /* Menu under the logo */
+ @media only screen and (max-width: 800px) {
+ .burger-icon {
+ display: inline-block;
+ }
+
+ .menu {
+ border-bottom: 2px dashed #aaa;
+ display: none;
+ padding: 1rem 0;
+ }
+
+ /* This class is toggled when the burger icon is clicked */
+ .menu.visible {
+ display: block;
+ }
+
+ /* Every menu item */
+ .menu.visible a {
+ border: 0;
+ color: #000;
+ display: block;
+ margin: 0;
+ padding: .8rem 0;
+ text-align: left;
+ text-decoration: none;
+ }
+
+ /* Highlight menu item of the current active page (Hot/New/Submit/...) */
+ .menu.visible .active_page {
+ font-weight: bold;
+ text-decoration: underline dotted;
+ text-transform: uppercase;
+ }
+
+ /* Highlight username if there are unread messages */
+ .menu.visible .new_messages {
+ background-color: rgb(255, 175, 50);
+ color: #fff;
+ font-weight: bold;
+ padding-left: 1rem;
+ }
+ }
+
+ @media only screen and (min-width: 800px) {
+ .burger-icon {
+ display: none;
+ }
+
+ .menu {
+ border-bottom: 1px solid transparent;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ align-content: flex-start;
+ align-items: flex-end;
+ }
+
+ .menu > .flex-item {
+ flex: 0 1 auto;
+ align-self: auto;
+ order: 0;
+
+ border: 0;
+ border-bottom: 3px solid transparent;
+ color: #000;
+ margin: 0;
+ padding: 0 .5rem .5rem .5rem;
+ }
+
+ /* Highlight menu item of the current active page (Hot/New/Submit/...) */
+ .menu > .active_page {
+ border-bottom: 3px solid #000;
+ }
+
+ /* Highlight username if there are unread messages */
+ .menu .new_messages {
+ background-color: rgb(255, 175, 50);
+ border: 0;
+ border-radius: 4px;
+ color: #fff;
+ font-weight: bold;
+ margin: 0;
+ padding: .5em .5em;
+ text-decoration: none;
+ }
+ }
+
+
+ /**************************************************************************
+ * Page content
+ *************************************************************************/
+
+
+ .container > .content {
+ padding: 1em 0;
+ line-height: 1.5em;
+ }
+
+ .container > .content .vote {
+ margin: 0 1rem 0 0;
+ padding: 0 .5rem;
+ }
+
+ .container > .content .vote > form {
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ }
+
+ .container > .content .vote > form > button {
+ background: transparent;
+ border: 0;
+ cursor: pointer;
+ display: inline-block;
+ height: 1rem;
+ margin: 0;
+ overflow: hidden;
+ padding: 0;
+ text-decoration: none;
+ vertical-align: middle;
+ width: 1rem;
+ }
+
+ /* Votes counter */
+ .container > .content .vote > .count {
+ margin: 0 .5rem;
+ }
+
+ .container > .content .vote.upvoted {
+ background-color: #d1ffd5;
+ border: 1px dashed;
+ border-color: #00e313;
+ border-radius: .5rem;
+ color: #00a200;
+ font-weight: bolder;
+ }
+
+ .container > .content .vote.downvoted {
+ background-color: #ffd9d9;
+ border: 1px dashed;
+ border-color: #ff7171;
+ border-radius: .5rem;
+ color: #f00;
+ font-weight: bolder;
+ }
+
+ /* Community page */
+ .container > .content > .community {
+
+ }
+
+ .container > .content > .community > .about {
+ border-left: 1px solid #aaa;
+ float: right;
+ font-size: .9rem;
+ margin: 0 0 5% 5%;
+ padding: 0 5%;
+ width: 40%;
+ }
+
+ /* New submission page */
+ .container > .content > form.submit {
+ width: 100%;
+ }
+
+ /* Page for a post */
+ .container > .content > .post {
+ }
+
+ /* Style used to format Markdown tables */
+ .container > .content > .post table {
+ background: #fff;
+ border-collapse: collapse;
+ text-align: left;
+ }
+
+ .container > .content > .post table > th {
+ border-bottom: 2px solid #6678b1;
+ color: #039;
+ font-weight: normal;
+ padding: 0 1em;
+ }
+
+ .container > .content > .post table > td {
+ border-bottom: 1px solid #ccc;
+ color: #669;
+ padding: .5em 1em;
+ }
+
+ /* The post title */
+ .container > .content > .post > .title {
+ font-size: 1.5em;
+ }
+
+ /* Info below post title */
+ .container > .content > .post > .info {
+ margin: 1em 0;
+ }
+
+ .container > .content > .post > .info > .username {
+ margin-left: 1rem;
+ }
+
+ /* Post text */
+ .container > .content > .post > .text {
+ margin: 2rem 0;
+ word-wrap: break-word;
+ }
+
+ /* The "new comment" form for this post page */
+ .container > .content > .post .new_comment > input[type=submit] {
+ margin: 1em 0;
+ }
+
+ /* Comments tree for the Post page */
+ .container > .content > .post > .comments {
+ margin: 5em 0 0 0;
+ }
+
+ /* A single comment in the tree */
+ .container > .content > .post > .comments > .comment {
+ margin: 0 0 1rem 0;
+ overflow: hidden;
+ }
+
+ /* Some info about this comment */
+ .container > .content > .post > .comments > .comment > .info {
+ display: inline-block;
+ font-size: .9rem;
+ }
+
+ .container > .content > .post > .comments > .comment > .info > .username {
+ display: inline-block;
+ margin: 0 1rem;
+ }
+
+ .container > .content > .post > .comments > .comment .info a,
+ .container > .content > .post > .comments > .comment .info a:hover,
+ .container > .content > .post > .comments > .comment .info a:visited {
+ display: inline-block;
+ text-decoration: none;
+ }
+
+ .container > .content > .post > .comments > .comment > .info > .op {
+ background-color: rgb(255, 175, 50);
+ border-radius: 4px;
+ font-weight: bold;
+ padding: 0 1rem;
+ }
+
+ .container > .content > .post > .comments > .comment > .info > .op a,
+ .container > .content > .post > .comments > .comment > .info > .op a:hover,
+ .container > .content > .post > .comments > .comment > .info > .op a:visited {
+ color: #fff;
+ }
+
+ /* The comment text */
+ .container > .content > .post > .comments > .comment > .text {
+ word-wrap: break-word;
+ }
+
+ /* Give the comment that's linked to in the URL location hash a lightyellow background color */
+ .container > .content > .post > .comments > .comment:target {
+ background-color: lightyellow;
+ }
+
+ .container > .content > .search {
+ margin-bottom: 3rem;
+ }
+
+ /* User home page */
+ .container > .content > form > .user {
+ display: grid;
+ grid-column-gap: 3rem;
+ grid-row-gap: 1rem;
+ grid-template-columns max-content: auto;
+ }
+
+ /* User activity */
+ .container > .content > .user_activity > * {
+ margin: 0 0 2em 0;
+ }
+
+ /* Login page */
+ .container > .content > .login {
+ margin: auto;
+ max-width: fit-content;
+ }
+
+ .container > .content > .login form > div {
+ margin: 1rem 0;
+ }
+
+ /* Page to edit a post or a comment */
+ .container > .content > .edit
+ {
+ }
+
+ /* Page to reply to a comment */
+ .container > .content > .reply
+ {
+ }
+
+ /* About page */
+ .container > .content > .about {}
+
+ .container > .content > .about > h3 {
+ margin: 1em 0 .5em 0;
+ }
+
+ .container > .content > .about > p {
+ line-height: 1.5em;
+ }
+
+
+ /**************************************************************************
+ * Page footer
+ *************************************************************************/
+
+
+ .container > footer {
+ margin: 0;
+ padding: 2em 0;
+ text-align: center;
+ }
+
+ .container > footer img {
+ height: 1.2em;
+ margin: 0 .5em 0 0;
+ vertical-align: middle;
+ }
+
+ .container > footer > .monkey {
+ height: auto;
+ margin: 0 0 3rem 0;
+ width: 3%;
+ }
+
+ .container > footer > ul {
+ list-style: none;
+ margin: auto;
+ overflow: hidden;
+ padding: 0;
+ width: fit-content;
+ }
+
+ .container > footer > ul > li {
+ float: left;
+ margin: 0 2em 0 0;
+
+ @media only screen and (max-width: 1024px) {
+ float: none;
+ margin: 1rem 0;
+ }
+ }