diff --git a/.gitignore b/.gitignore index cdcfc757..58a19f09 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ docker-compose.yml tags.* !tags.rs search_index +main.css diff --git a/Cargo.lock b/Cargo.lock index 17828a1c..e3f75843 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1590,6 +1590,15 @@ dependencies = [ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num-rational" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.2.6" @@ -1813,6 +1822,7 @@ dependencies = [ "rocket_csrf 0.1.0 (git+https://github.com/fdb-hiroshima/rocket_csrf?rev=4a72ea2ec716cb0b26188fb00bccf2ef7d1e031c)", "rocket_i18n 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rsass 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", "ructe 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1883,7 +1893,7 @@ dependencies = [ "guid-create 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", "plume-api 0.1.0", "plume-common 0.2.0", @@ -2258,6 +2268,18 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rsass" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ructe" version = "0.5.4" @@ -3404,6 +3426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a" "checksum notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "873ecfd8c174964ae30f401329d140142312c8e5590719cf1199d5f1717d8078" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" @@ -3465,6 +3488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rocket_http 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba9d4f2ce5bba6e1b6d3100493bbad63879e99bbf6b4365d61e6f781daab324d" "checksum rocket_i18n 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f10dc7394c8c400d20a86d25b8d6f6f8066cadd5e849ceed611bc6c28e1aaac5" "checksum rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37473170aedbe66ffa3ad3726939ba677d83c646ad4fd99e5b4bc38712f45ec" +"checksum rsass 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a389c30b2f7b43b64cbb489b7cce51b672845fee3cd14ba69f9dfdcb3b38873e" "checksum ructe 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "da9fece3121ef196658db041025d757eebbe9d08c8c09a5808cb4380d83dadc8" "checksum rust-stemmers 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbf06149ec391025664a5634200ced1afb489f0f3f8a140d515ebc0eb04b4bc0" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" diff --git a/Cargo.toml b/Cargo.toml index 992ababb..10646593 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ rev = "4a72ea2ec716cb0b26188fb00bccf2ef7d1e031c" [build-dependencies] ructe = "0.5.4" rocket_i18n = { version = "0.3.1", features = ["build"] } +rsass = "0.9" [features] default = ["postgres"] diff --git a/build.rs b/build.rs index 8b2dd6f2..7302219c 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,8 @@ extern crate ructe; extern crate rocket_i18n; +extern crate rsass; use ructe::*; -use std::{env, path::PathBuf}; +use std::{env, fs::File, io::Write, path::PathBuf}; fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); @@ -12,4 +13,11 @@ fn main() { println!("cargo:rerun-if-changed=po"); rocket_i18n::update_po("plume", &["de", "en", "fr", "gl", "it", "ja", "nb", "pl", "ru"]); rocket_i18n::compile_po("plume", &["de", "en", "fr", "gl", "it", "ja", "nb", "pl", "ru"]); + + println!("cargo:rerun-if-changed=static/css"); + let mut out = File::create("static/css/main.css").expect("Couldn't create main.css"); + out.write_all( + &rsass::compile_scss_file("static/css/main.scss".as_ref(), rsass::OutputStyle::Compressed) + .expect("Error during SCSS compilation") + ).expect("Couldn't write CSS output"); } diff --git a/static/css/_article.scss b/static/css/_article.scss new file mode 100644 index 00000000..ef194e33 --- /dev/null +++ b/static/css/_article.scss @@ -0,0 +1,266 @@ +// Heading +main .article-info { + max-width: 40rem; + margin: 0 auto 3em; + font-size: 0.95em; + font-weight: 400; + + .author, .author a { + font-weight: 600; + } +} + +// The article itself +main article { + max-width: 40rem; + margin: 2.5em auto; + font-family: $lora; + font-size: 1.2em; + line-height: 1.7em; + + a:hover { + text-decoration: underline; + } + + img { + display: block; + margin: 3em auto; + max-width: 100%; + } + + pre { + padding: 1em; + background: $lightgray; + overflow: auto; + border-radius: 5px; + } +} + +// Metadata under the article +main .article-meta, main .article-meta button { + padding: 0; + font-size: 1.1em; + margin-top: 10%; +} + +main .article-meta { + + > * { + margin: 0 20%; + } + + > p { + margin: 2em 20%; + font-size: 0.9em; + } + + // Tags + .tags { + list-style: none; + display: inline-block; + padding: 0px; + margin-bottom: 2em; + + li { + display: inline-block; + background: $lightgray; + padding: 0px; + margin: 0px 10px 10px 0px; + border-radius: 3px; + transition: all 0.2s ease-in; + + a { + display: inline-block; + padding: 10px 20px; + color: $black; + } + + &:hover { + background: mix($black, $lightgray, 10%); + } + } + } + + // Likes & Boosts + .actions { + display: flex; + flex-direction: row; + justify-content: space-around; + } + + .likes, .reshares { + display: flex; + flex-direction: column; + align-items: center; + padding: 0.5em 0; + + p { + font-size: 1.5em; + display: inline-block; + margin: 0; + } + + .action { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin: 0; + padding: 0; + background: none; + color: $black; + border: none; + font-size: 1.1em; + + svg.feather { + transition: background 0.1s ease-in; + display: flex; + align-items: center; + justify-content: center; + + margin: 0.5em 0; + width: 2.5em; + height: 2.5em; + + border-radius: 50%; + } + + &.reshared, &.liked { + svg.feather { + color: $white; + font-weight: 900; + } + } + } + } + + .likes { + p, .action:hover { color: $red; } + + .action svg.feather { + padding: 0.7em; + box-sizing: border-box; + color: $red; + fill: none; + border: solid $red thin; + } + + .action:hover svg.feather { + background: transparentize($red, 0.85); + } + + .action.liked svg.feather { + background: $red; + fill: currentColor; + } + .action.liked:hover svg.feather { + background: transparentize($red, 0.75) + color: $red; + } + } + + .reshares { + p, .action:hover { color: $purple; } + + .action svg.feather { + padding: 0.7em; + box-sizing: border-box; + color: $purple; + border: solid $purple thin; + font-weight: 600; + } + + .action:hover svg.feather { + background: transparentize($purple, 0.85); + } + + .action.reshared svg.feather { + background: $purple; + } + .action.reshared:hover svg.feather { + background: transparentize($purple, 0.75) + color: $purple; + } + } + + // Comments + .comments { + margin: 0; + > * { + margin-left: 20%; + margin-right: 20%; + } + + h2 { + color: $purple; + font-size: 1.5em; + font-weight: 600; + } + + summary { + cursor: pointer; + } + + // New comment form + form input[type="submit"] { + font-size: 1em; + } + + // Response button + a.button { + display: inline-block; + padding: 0; + background: none; + color: $black; + border: none; + + &::before { + color: $purple; + padding-right: 0.5em; + } + + &:hover { color: $purple; } + } + + .list { + display: grid; + margin: 0 0 -5em; + padding: 0 20%; + background: $lightgray; + } + + .comment { + padding: 2em; + font-size: 1em; + border: none; + + .author { + display: flex; + flex-direction: row; + align-items: center; + align-content: center; + + * { + transition: all 0.1s ease-in; + } + + .display-name { + color: $black; + } + + &:hover { + .display-name { color: $purple; } + small { opacity: 1; } + } + } + + .text { + padding: 1.25em 0; + font-family: $lora; + font-size: 1.1em; + line-height: 1.4em; + text-align: left; + } + } + } +} diff --git a/static/css/_forms.scss b/static/css/_forms.scss new file mode 100644 index 00000000..742478b8 --- /dev/null +++ b/static/css/_forms.scss @@ -0,0 +1,131 @@ +label { + display: block; + margin: 2em auto 1em; + font-size: 1.2em; + max-width: 40rem; +} +input, textarea, select { + transition: all 0.1s ease-in; + display: block; + width: 100%; + max-width: 40rem; + margin: auto; + padding: 1em; + box-sizing: border-box; + + background: $white; + color: $black; + border: none; + border: solid $lightgray thin; + border-radius: 0.5em; + + font-size: 1.2em; + font-weight: 400; + + &:focus { + background: $white; + border-color: $purple; + } +} +form input[type="submit"] { margin: 2em auto; } + +textarea { + resize: vertical; + + font-family: $lora; + font-size: 1.1em; + line-height: 1.5em; +} + +input[type="checkbox"] { + display: inline; + margin: initial; + min-width: initial; + width: initial; +} + +/** Inline forms (containing only CSRF token and a , for protected links) **/ + +form.inline { + display: inline; + margin: 0px; + padding: 0px; + width: auto; + + input[type="submit"] { + display: inline-block; + color: $purple; + cursor: pointer; + font-size: 1em; + width: auto; + + &:not(.button) { + margin: 0; + padding: 0; + border: none; + background: transparent; + color: $purple; + } + } +} + +.button, input[type="submit"], button { + transition: all 0.1s ease-in; + display: inline-block; + + border-radius: 0.5em; + margin: 0.5em auto; + padding: 0.75em 1em; + + background: transparent; + color: $purple; + border: 1px solid $purple; + + cursor: pointer; + + &:hover { + background: transparentize($purple, 0.6); + color: white; + } + + &.destructive { + color: $red; + border-color: $red; + + &:hover { + background: transparentize($red, 0.6); + color: $white; + } + } +} +input[type="submit"] { display: block; } + +// Writing page +form.new-post { + .title { + margin: 0 auto; + padding: 0.75em 0; + + background: none; + border: none; + + font-family: $playfair; + font-size: 2em; + text-align: left; + } + textarea { + min-height: 20em; + overflow-y: hidden; + resize: none; + box-sizing: content-box; + } + input[type="submit"] { + background: $lightgray; + color: $black; + border: none; + + font-family: $playfair; + font-size: 1.5em; + } + input[type="submit"]:hover { background: $lightgray; } +} diff --git a/static/css/_global.scss b/static/css/_global.scss new file mode 100644 index 00000000..a4f8f242 --- /dev/null +++ b/static/css/_global.scss @@ -0,0 +1,344 @@ +html, body { + margin: 0; + padding: 0; + background: $background; + color: $black; + font-family: $route159; +} + +a, a:visited { + color: $purple; + text-decoration: none; +} + +small { + margin-left: 1em; + color: transparentize($black, 0.6); + font-size: 0.75em; + word-wrap: break-word; + word-break: break-all; +} + +.center { + text-align: center; + font-weight: bold; + opacity: 0.6; + padding: 5em; +} + +.spaced { + margin: 4rem 0; +} + +.cards.spaced { + margin: 1rem 0 5rem; +} + +.banner { + background: $gray; + padding-top: 2em; + padding-bottom: 1em; + margin: 3em 0px; +} + +.hidden { + display: none; +} + +/// Main +body > main > *, .h-feed > * { + padding: 0 20%; +} + +body > main > .h-entry, .h-feed { + padding: 0; +} + +main { + h1 { + font-family: $route159; + font-size: 2.5em; + font-weight: 300; + + &.article { + max-width: 40rem; + margin: 1em auto 0.5em; + font-family: $playfair; + font-size: 2.5em; + font-weight: normal; + } + } + + h2 { + font-family: $route159; + font-size: 1.75em; + font-weight: 300; + + &.article { + max-width: 40rem; + margin: auto; + font-size: 1.25em; + margin-bottom: 0.5em; + } + } + + .cover { + padding: 0px; + margin: 0px; + width: auto; + min-height: 50vh; + background-position: center; + background-size: cover; + overflow: hidden; + } +} + +/// Errors +p.error { + color: $red; + font-weight: bold; + max-width: 40rem; + margin: 1em auto; +} + +/// User page +.user h1 { + display: flex; + flex-direction: row; + align-items: center; + margin: 0px; +} + +.badge { + margin-right: 1em; + padding: 0.35em 1em; + + background: $white; + color: $purple; + border: 1px solid $purple; + border-radius: 1em; + + font-size: 1rem; +} + +.user-summary { + margin: 2em 0px; +} + +/// Cards +.cards { + display: flex; + flex-direction: row; + flex-wrap: wrap; + padding: 0 5%; +} +.card { + flex: 1; + display: flex; + flex-direction: column; + + min-width: 20em; + min-height: 20em; + margin: 1em; + box-sizing: border-box; + + background: $gray; + + text-overflow: ellipsis; + + > * { + margin: 20px; + } + + .cover { + min-height: 10em; + background-position: center; + background-size: cover; + margin: 0px; + } + + h3 { + margin: 0.75em 20px; + font-family: $playfair; + font-size: 1.75em; + font-weight: normal; + a { + transition: color 0.1s ease-in; + color: $black; + + &:hover { color: $purple; } + } + } + + main { + flex: 1; + + font-family: $lora; + font-size: 1em; + line-height: 1.25em; + text-align: left; + overflow: hidden; + } +} +.list .card { + /* TODO */ + background: 0; + margin: 2em 0; + padding: 0; + min-height: 0; +} + +/// Instance presentation +.presentation > h2, .presentation > a { + text-align: center; +} +.presentation > a { + font-size: 1.2em; + margin: 1em; +} + +// Stats +.stats { + display: flex; + justify-content: space-around; + margin: 2em; + + > div { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + p { + text-align: center; + } + + em { + font-weight: bold; + display: block; + margin: 1em 0; + } +} + +/// Pagination +.pagination { + display: flex; + justify-content: space-evenly; + + > * { + padding: 2em; + } +} + +/// Flex boxes +.flex { + display: flex; + flex-direction: row; + align-items: center; + + &.vertical { + flex-direction: column; + justify-content: space-around; + align-items: flex-start; + + small { + margin: initial; + } + } + + .grow { + flex: 1; + } +} + +.left-icon { + align-self: center; + padding: 1em; + background: $lightgray; + border-radius: 50px; + margin: 1em; + margin-right: 2em; +} + +/// Footer +body > footer { + display: flex; + align-content: center; + justify-content: space-between; + background: $lightgray; + padding: 0 20%; + margin-top: 5em; + + * { + margin: 5em 0; + } +} + +/// Media +figure { + text-align: center; + margin: 2em; + max-width: 100%; + width: auto; + height: auto; + + > * { + max-width: 100%; + } + + figcaption { + padding: 1em; + } +} + +.preview { + display: block; + max-width: 100px; + max-height: 100px; + width: auto; + height: auto; + margin-right: 20px; +} + +/// Avatars +.avatar { + background-position: center; + background-size: cover; + border-radius: 100%; + + &.small { + width: 50px; + height: 50px; + } + + &.medium { + width: 100px; + height: 100px; + margin: 20px; + } + + &.padded { + margin-right: 2rem; + } +} + +/// Tabs +.tabs { + border-bottom: 1px solid $lightgray; + padding: 0px; + margin: auto 20% 2em; + overflow: auto; + display: flex; + + a { + display: inline-block; + color: $black; + padding: 1em; + + &.selected { + color: $purple; + border-bottom: 1px solid $purple; + } + } +} diff --git a/static/css/_header.scss b/static/css/_header.scss new file mode 100644 index 00000000..6ea4069e --- /dev/null +++ b/static/css/_header.scss @@ -0,0 +1,106 @@ +header { + background: $lightgray; + + #content { + display: flex; + align-content: center; + justify-content: space-between; + } + + nav#menu { + position: relative; + display: none; + transform: skewX(-15deg); + left: -1em; + padding: 1em 1em 1em 2em; + background: $purple; + align-self: flex-start; + + a { + transform: skewX(15deg); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 1.4em; + height: 1.4em; + margin: 0; + padding: 0; + color: $lightgray; + font-size: 1.33em; + } + } + + nav { + display: flex; + flex-direction: row; + align-items: center; + + hr { + height: 100%; + width: 0.2em; + background: $purple; + border: none; + transform: skewX(-15deg); + } + a { + display: flex; + align-items: center; + position: relative; + align-self: stretch; + margin: 0; + padding: 0 2em; + font-size: 1em; + + i { font-size: 1.2em; } + + &.title { + margin: 0; + text-align: center; + padding: 0.5em 1em; + font-size: 1.75em; + + img { + height: 1.75em; + width: 1.75em; + } + + p { + margin: 0; + padding-left: 0.5em; + } + } + } + } +} + +// Only enable label animations on normal screens +@media screen and (min-width: 900px) { + header nav a { + i { + transition: all 0.2s ease; + margin: 0; + } + + .mobile-label { + transition: all 0.2s ease; + display: block; + position: absolute; + left: 50%; + transform: translate(-50%, 0); + opacity: 0; + font-size: 0.9em; + white-space: nowrap; + } + + img + .mobile-label { display: none; } + + &:hover { + i { margin-bottom: 0.75em; } + .mobile-label { + opacity: 1; + transform: translate(-50%, 80%); + } + } + } +} diff --git a/static/css/_variables.scss b/static/css/_variables.scss new file mode 100644 index 00000000..77d093f7 --- /dev/null +++ b/static/css/_variables.scss @@ -0,0 +1,15 @@ +// Colors + +$background: #F4F4F4; +$gray: #E3E3E3; +$lightgray: #ECECEC; +$black: #242424; +$white: #F4F4F4; +$purple: #7765E3; +$red: #E92F2F; + +// Fonts + +$route159: "Route159", serif; +$playfair: "Playfair Display", serif; +$lora: "Lora", serif; diff --git a/static/css/main.css b/static/css/main.css deleted file mode 100644 index 91eb0095..00000000 --- a/static/css/main.css +++ /dev/null @@ -1,994 +0,0 @@ -/* color palette: https://coolors.co/23f0c7-ef767a-7765e3-6457a6-ffe347 */ - -@import url('/static/fonts/Route159/Route159.css'); -@import url('/static/fonts/Lora/Lora.css'); -@import url('/static/fonts/Playfair_Display/PlayfairDisplay.css'); - -/* - * == Global == - */ - - html, body { - margin: 0; - padding: 0; - background: #F4F4F4; - color: #242424; - font-family: "Route159", serif; - } - - a, a:visited { - color: #7765E3; - text-decoration: none; - } - - small { - margin-left: 1em; - color: rgba(36, 36, 36, 0.6); - font-size: 0.75em; - word-wrap: break-word; - word-break: break-all; - } - - .center { - text-align: center; - font-weight: bold; - opacity: 0.6; - padding: 5em; - } - - .spaced { - margin: 4rem 0; - } - - .cards.spaced { - margin: 1rem 0 5rem; - } - - .banner { - background: #DADADA; - padding-top: 2em; - padding-bottom: 1em; - margin: 3em 0px; - } - - .hidden { - display: none; - } - -/* - * == Header == - */ - - header { - background: #ECECEC; - } - header #content { - display: flex; - align-content: center; - justify-content: space-between; - } - - header nav#menu { - position: relative; - display: none; - transform: skewX(-15deg); - left: -1em; - padding: 1em 1em 1em 2em; - background: #7765E3; - align-self: flex-start; - } - header nav#menu a { - transform: skewX(15deg); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 1.4em; - height: 1.4em; - margin: 0; - padding: 0; - color: #ECECEC; - font-size: 1.33em; - } - - header nav { - display: flex; - flex-direction: row; - align-items: center; - } - header nav hr { - height: 100%; - width: 0.2em; - background: #7765E3; - border: none; - transform: skewX(-15deg); - } - header nav a { - display: flex; - align-items: center; - position: relative; - align-self: stretch; - margin: 0; - padding: 0 2em; - font-size: 1em; - } -header nav a.title { - margin: 0; - text-align: center; - padding: 0.5em 1em; - font-size: 1.75em; -} -header nav a.title img { - height: 1.75em; - width: 1.75em; -} -header nav a.title p { - margin: 0; - padding-left: 0.5em; -} - - header nav a i { font-size: 1.2em; } - - /* Only enable label animations on normal screens. */ - @media screen and (min-width: 900px) { - header nav a i { - transition: all 0.2s ease; - margin: 0; - } - - header nav a:hover i { margin-bottom: 0.75em; } - - header nav a .mobile-label { - transition: all 0.2s ease; - display: block; - position: absolute; - left: 50%; - transform: translate(-50%, 0); - opacity: 0; - font-size: 0.9em; - white-space: nowrap; - } - header nav a:hover .mobile-label { - opacity: 1; - transform: translate(-50%, 80%); - } - header nav a img + .mobile-label { display: none; } - } - -/* - * == Main == - */ - - body > main > *, .h-feed > * { - padding: 0 20%; - } - - body > main > .h-entry, .h-feed { - padding: 0; - } - - main h1 { - font-family: "Route159"; - font-size: 2.5em; - font-weight: 300; - } - main h1.article { - max-width: 40rem; - margin: 1em auto 0.5em; - font-family: "Playfair Display", serif; - font-size: 2.5em; - font-weight: normal; - } - - main h2 { - font-family: "Route159"; - font-size: 1.75em; - font-weight: 300; - } - - main h2.article { - max-width: 40rem; - margin: auto; - font-size: 1.25em; - margin-bottom: 0.5em; - } - -/* - * == Article == - */ - - /* Author */ - - main .article-info { - max-width: 40rem; - margin: 0 auto 3em; - font-size: 0.95em; - font-weight: 400; - } - main .article-info .author { font-weight: 600; } - main .article-info .author a { font-weight: 600; } - - /* Cover */ - - main > .cover { - padding: 0px; - margin: 0px; - width: auto; - min-height: 50vh; - background-position: center; - background-size: cover; - overflow: hidden; - } - - /* Article */ - - main article { - max-width: 40rem; - margin: 2.5em auto; - font-family: "Lora", serif; - font-size: 1.2em; - line-height: 1.7em; - } - - main a:hover { - text-decoration: underline; - } - - article img { - display: block; - margin: 3em auto; - max-width: 100%; - } - - article pre { - padding: 1em; - background: #DADADA; - overflow: auto; - border-radius: 5px; - } - - /* Article.Meta */ - - main .article-meta, main .article-meta button { - padding: 0; - font-size: 1.1em; - margin-top: 10%; - } - main .article-meta > * { margin: 0 20%; } - -main .article-meta > p { - margin: 2em 20%; - font-size: 0.9em; -} - -/** Tags **/ - -main .article-meta .tags { - list-style: none; - display: inline-block; - padding: 0px; - margin-bottom: 2em; -} - -main .article-meta .tags li { - display: inline-block; - background: #DADADA; - padding: 0px; - margin-right: 10px; - border-radius: 3px; - transition: all 0.2s ease-in; -} - -main .article-meta .tags li:hover { - background: #BBB; -} - -main .article-meta .tags li a { - display: inline-block; - padding: 10px 20px; - color: #242424; -} - - - /* ~ Likes ~ */ - - main .article-meta .likes p, - main .article-meta .reshares p { display: inline-block; margin: 0; } - - /* Like / Reshare button */ - - main .article-meta .actions { - display: flex; - flex-direction: row; - justify-content: space-around; - } - - main .article-meta .likes, - main .article-meta .reshares { - display: flex; - flex-direction: column; - align-items: center; - padding: 0.5em 0; - } - - main .article-meta .likes > p, - main .article-meta .reshares > p { - font-size: 1.5em; - } - - main .article-meta .likes .action, - main .article-meta .reshares .action { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - margin: 0; - padding: 0; - background: none; - color: #242424; - border: none; - font-size: 1.1em; - } - - main .article-meta .likes > p, - main .article-meta .likes .action:hover { color: #E92F2F; } - main .article-meta .reshares > p, - main .article-meta .reshares .action:hover { color: #7765E3; } - - main .article-meta .likes .action svg.feather, - main .article-meta .reshares .action svg.feather { - transition: background 0.1s ease-in; - display: flex; - align-items: center; - justify-content: center; - - margin: 0.5em 0; - width: 2.5em; - height: 2.5em; - - border-radius: 50%; - } - - main .article-meta .likes .action svg.feather { - padding: 0.7em; - box-sizing: border-box; - color: #E92F2F; - fill: none; - border: solid #E92F2F thin; - } - main .article-meta .likes .action:hover svg.feather { - background: rgba(233, 47, 47, 0.15); - } - - main .article-meta .reshares .action svg.feather { - padding: 0.7em; - box-sizing: border-box; - color: #7765E3; - border: solid #7765E3 thin; - font-weight: 600; - } - main .article-meta .reshares .action:hover svg.feather { - background: rgba(119, 101, 227, 0.15); - } - - main .article-meta .likes .action.liked svg.feather { background: #E92F2F; fill: currentColor; } - main .article-meta .likes .action.liked:hover svg.feather { - background: rgba(233, 47, 47, 0.25); - color: #E92F2F; - } - main .article-meta .reshares .action.reshared svg.feather { background: #7765E3; } - main .article-meta .reshares .action.reshared:hover svg.feather { - background: rgba(119, 101, 227, 0.25); - color: #7765E3; - } - - main .article-meta .likes .action.liked svg.feather, - main .article-meta .reshares .action.reshared svg.feather { - color: #F4F4F4; - font-weight: 900; - } - - /* ~ Comments ~ */ - - main .article-meta .comments { margin: 0; } - main .article-meta .comments > * { margin-left: 20%; margin-right: 20%; } - - .comments h2 { - color: #7765E3; - font-size: 1.5em; - font-weight: 600; - } - -summary { - cursor: pointer; -} - - /* New comment */ - - main .article-meta .comments form input[type="submit"] - { font-size: 1em; } - - /* Comment / Respond button */ - - main .article-meta .comments a.button:before { - color: #7765E3; - padding: 0.5em; - } - main .article-meta .comments a.button { - display: inline-block; - padding: 0; - background: none; - color: #242424; - border: none; - } - main .article-meta .comments a.button:hover { color: #7765E3; } - - /* Comment button only */ - main .article-meta .comments > a.button { margin-bottom: 1em; } - - /* == List == */ - - main .article-meta .comments .list { - display: grid; - margin: 0; - padding: 0 20%; - background: #ECECEC; - } - - /* ~ Comment ~ */ - - .comments .list .comment { - padding: 2em; - font-size: 1em; - } - - .comments .list > .comment { - border: none; - } - - .comments .list .comment .author { - display: flex; - flex-direction: row; - align-items: center; - align-content: center; - } - .comments .list .comment .author * { - transition: all 0.1s ease-in; - } - .comments .list .comment .author .display-name { - color: #242424; - } - .comments .list .comment .author:hover .display-name { color: #7765E3; } - .comments .list .comment .author:hover small { opacity: 1; } - - .comments .list .comment .text { - padding: 1.25em 0; - font-family: "Lora", serif; - font-size: 1.1em; - line-height: 1.4em; - text-align: left; - } - -/* - * == Form == - */ - - label { - display: block; - margin: 2em auto 1em; - font-size: 1.2em; - max-width: 40rem; - } - input, textarea, select { - transition: all 0.1s ease-in; - display: block; - width: 100%; - max-width: 40rem; - margin: auto; - padding: 1em; - box-sizing: border-box; - - background: #F4F4F4; - color: #242424; - border: none; - border: solid #DADADA thin; - border-radius: 0.5em; - - font-size: 1.2em; - font-weight: 400; - } - form input[type="submit"] { margin: 2em auto; } - input:focus, textarea:focus { - background: #FAFAFA; - border-color: #7765E3; - } - - textarea { - resize: vertical; - - font-family: "Lora", serif; - font-size: 1.1em; - line-height: 1.5em; - } - - input[type="checkbox"] { - display: inline; - margin: initial; - min-width: initial; - width: initial; - } - -/** Inline forms (containing only CSRF token and a , for protected links) **/ - -form.inline { - display: inline; - margin: 0px; - padding: 0px; - width: auto; -} - -form.inline input[type="submit"] { - display: inline-block; - color: #7765E3; - cursor: pointer; - font-size: 1em; - width: auto; -} - -form.inline input[type="submit"]:not(.button) { - margin: 0; - padding: 0; - border: none; -} - -form.inline input[type="submit"]:not(.button) { - background: transparent; - color: #7765E3; -} - - /* Button & Submit */ - - .button, input[type="submit"], button { - transition: all 0.1s ease-in; - display: inline-block; - - border-radius: 0.5em; - margin: 0.5em auto; - padding: 0.75em 1em; - - background: transparent; - color: #7765E3; - border: 1px solid #7765E3; - - cursor: pointer; - } - input[type="submit"] { display: block; } - .button:hover, input[type="submit"]:hover { - background: #7765E399; - color: white; - } - -.button.destructive { - color: #ef767a; - border-color: #ef767a; -} - -.button.destructive:hover { - background: #ef767a99; - color: white; -} - - /* Errors */ - - p.error { - color: #ef767a; - font-weight: bold; - max-width: 40rem; - margin: 1em auto; - } - -/* - * == New post == - */ - - form.new-post .title { - margin: 0 auto; - padding: 0.75em 0; - - background: none; - border: none; - - font-family: "Playfair Display", serif; - font-size: 2em; - text-align: left; - } - form.new-post textarea { - min-height: 20em; - overflow-y: hidden; - resize: none; - box-sizing: content-box; - } - form.new-post input[type="submit"] { - background: #ECECEC; - color: #242424; - border: none; - - font-family: "Playfair Display", serif; - font-size: 1.5em; - } - form.new-post input[type="submit"]:hover { background: #DADADA; } - -/* - * == User == - */ - - .user h1 { - display: flex; - flex-direction: row; - align-items: center; - margin: 0px; - } - .badge { - margin-right: 1em; - padding: 0.35em 1em; - - background: #F4F4F4; - color: #7765E3; - border: 1px solid #7765E3; - border-radius: 1em; - - font-size: 1rem; - } - -/* - * == Blog index == - */ - - .cards { - display: flex; - flex-direction: row; - flex-wrap: wrap; - padding: 0 5%; - } - .card { - flex: 1; - display: flex; - flex-direction: column; - - min-width: 17.5em; - min-height: 17.5em; - margin: 1em; - box-sizing: border-box; - - background: #E3E3E3; - - text-overflow: ellipsis; - } - .card > * { - margin: 20px; - } - .list .card { - /* TODO */ - background: 0; - margin: 2em 0; - padding: 0; - min-height: 0; - } - - /* ~ Card content ~ */ - - /* Cover */ - .card .cover { - min-height: 10em; - background-position: center; - background-size: cover; - margin: 0px; - } - - /* Title */ - - .card h3 { - margin: 0.75em 20px; - font-family: "Playfair Display", serif; - font-size: 1.75em; - font-weight: normal; - } - .card h3 a { transition: color 0.1s ease-in; color: #242424; } - .card h3 a:hover { color: #7765E3; } - - /* Content */ - - .card main { - flex: 1; - - font-family: "Lora", serif; - font-size: 1em; - line-height: 1.25em; - text-align: left; - overflow: hidden; - } - - /* Presentation */ - .presentation > h2, .presentation > a { - text-align: center; - } - - .presentation > a { - font-size: 1.2em; - margin: 1em; - } - - /* Stats */ - .stats { - display: flex; - justify-content: space-around; - margin: 2em; - } - - .stats > div { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - } - -.stats p { - text-align: center; -} - - .stats em { - font-weight: bold; - display: block; - margin: 1em 0; - } - - /*== Pagination ==*/ - .pagination { - display: flex; - justify-content: space-evenly; -} - -.pagination > * { - padding: 2em; -} - -/*== Flex boxes ==*/ -.flex { - display: flex; - flex-direction: row; - align-items: center; -} - -.flex .grow { - flex: 1; -} - -.flex.vertical { - flex-direction: column; - justify-content: space-around; - align-items: flex-start; -} - -.flex.vertical small { - margin: initial; -} - -.left-icon { - align-self: center; - padding: 1em; - background: #DADADA; - border-radius: 50px; - margin: 1em; - margin-right: 2em; -} - -/*== Footer ==*/ -body > footer { - display: flex; - align-content: center; - justify-content: space-between; - background: #ECECEC; - padding: 0 20%; - margin-top: 5em; -} - -body > footer * { - margin: 5em 0; -} - -/** Medias **/ - -figure { - text-align: center; - margin: 2em; - max-width: 100%; - width: auto; - height: auto; -} - -figure > * { - max-width: 100%; -} - -figcaption { - padding: 1em; -} - -.preview { - display: block; - max-width: 100px; - max-height: 100px; - width: auto; - height: auto; - margin-right: 20px; -} - -/** Avatars **/ - -.avatar { - background-position: center; - background-size: cover; - border-radius: 100%; -} - -.avatar.small { - width: 50px; - height: 50px; -} - -.avatar.medium { - width: 100px; - height: 100px; - margin: 20px; -} - -.avatar.padded { - margin-right: 2rem; -} - -/** Tabs **/ - -.tabs { - border-bottom: 1px solid #DADADA; - padding: 0px; - margin: auto 20% 2em; - overflow: auto; - display: flex; -} - -.tabs a { - display: inline-block; - color: #242424; - padding: 1em; -} - -.tabs a.selected { - color: #7765E3; - border-bottom: 1px solid #7765E3; -} - -.user-summary { - margin: 2em 0px; -} - -/* ================= * - * Small Screens * - * ================= */ - - @media screen and (max-width: 900px) { - header { - flex-direction: column; - } - - header nav#menu { - display: inline-flex; - } - - header #content { - display: none; - text-align: center; - } - - @keyframes menuOpening { - from { - transform: scaleX(0); - transform-origin: left; - opacity: 0; - } - - to { - transform: scaleX(1); - transform-origin: left; - opacity: 1; - } - } - - header:focus-within #content, #content.show { - position: fixed; - display: flex; - flex-direction: column; - justify-content: flex-start; - - top: 0; - left: 0; - width: 100%; - height: 100%; - box-sizing: border-box; - - animation: 0.2s menuOpening; - } - header:focus-within #content::before, #content.show::before { - content: ""; - position: absolute; - transform: skewX(-10deg); - top: 0; - left: -20%; - width: 100%; - height: 100%; - - z-index: -10; - - background: #7765E3; - } - header:focus-within #content > nav, #content.show > nav { - flex-direction: column; - align-items: flex-start; - } - header:focus-within #content > nav a, #content.show > nav a { - display: flex; - flex-direction: row; - align-items: center; - margin: 0; - padding: 1rem 1.5rem; - color: #F4F4F4; - font-size: 1.4em; - font-weight: 300; - } - header:focus-within #content > nav a > *:first-child, - #content.show > nav a > *:first-child { width: 3rem; } - header:focus-within #content > nav a > img:first-child, - #content.show > nav a > img:first-child { height: 3rem; } - header:focus-within #content > nav a > *:last-child, - #content.show > nav a > *:last-child { margin-left: 1rem; } - header:focus-within #content > nav a.title, #content.show > nav a.title { - font-size: 1.8em; - } - header:focus-within #content > nav hr, #content.show > nav hr { - display: block; - margin: 0; - width: 100%; - border: solid #F4F4F4 0.1rem; - } - header:focus-within #content > nav a .mobile-label, #content.show > nav a .mobile-label { - display: initial; - } - - body > main > * { - padding: 0 5%; - } - main .article-meta > * { margin: 0 5%; } - - main .article-meta > p { - margin: 2em 5%; - font-size: 0.9em; - } - main .article-meta .comments > * { margin-left: 5%; margin-right: 5%; } - - .card { - min-width: 80%; - min-height: 80%; - } - - .tabs { - margin: auto 0px 2em; - } - - .stats { flex-direction: column; } - body > footer { - flex-direction: column; - align-items: center; - } - body > footer * { margin: 1em auto; } - - .flex.wrap { flex-direction: column; } - } diff --git a/static/css/main.scss b/static/css/main.scss new file mode 100644 index 00000000..00ddec72 --- /dev/null +++ b/static/css/main.scss @@ -0,0 +1,134 @@ +/* color palette: https://coolors.co/23f0c7-ef767a-7765e3-6457a6-ffe347 */ + +@import url('/static/fonts/Route159/Route159.css'); +@import url('/static/fonts/Lora/Lora.css'); +@import url('/static/fonts/Playfair_Display/PlayfairDisplay.css'); + +@import 'variables'; +@import 'global'; +@import 'header'; +@import 'article'; +@import 'forms'; + +/// Small screens +@media screen and (max-width: 900px) { + @keyframes menuOpening { + from { + transform: scaleX(0); + transform-origin: left; + opacity: 0; + } + to { + transform: scaleX(1); + transform-origin: left; + opacity: 1; + } + } + + header { + flex-direction: column; + + nav#menu { + display: inline-flex; + } + + #content { + display: none; + text-align: center; + } + } + + header:focus-within #content, #content.show { + position: fixed; + display: flex; + flex-direction: column; + justify-content: flex-start; + + top: 0; + left: 0; + width: 100%; + height: 100%; + box-sizing: border-box; + + animation: 0.2s menuOpening; + + &::before { + content: ""; + position: absolute; + transform: skewX(-10deg); + top: 0; + left: -20%; + width: 100%; + height: 100%; + + z-index: -10; + + background: $purple; + } + + > nav { + flex-direction: column; + align-items: flex-start; + + a { + display: flex; + flex-direction: row; + align-items: center; + margin: 0; + padding: 1rem 1.5rem; + color: $white; + font-size: 1.4em; + font-weight: 300; + + &.title { font-size: 1.8em; } + + > *:first-child { width: 3rem; } + > img:first-child { height: 3rem; } + > *:last-child { margin-left: 1rem; } + > nav hr { + display: block; + margin: 0; + width: 100%; + border: solid $white 0.1rem; + } + .mobile-label { display: initial; } + } + } + } + + body > main > * { + padding: 0 5%; + } + main .article-meta { + > * { + margin: 0 5%; + } + > p { + margin: 2em 5%; + font-size: 0.9em; + } + .comments > * { margin: auto 5%; } + .comments .comment { padding: 2em 0px; } + } + main .article-info, main article, main h1.article, main h2.article { + max-width: 90vw; + } + + .card { + min-width: 80%; + min-height: 80%; + } + + .tabs { + margin: auto 0px 2em; + } + + .stats { flex-direction: column; } + body > footer { + flex-direction: column; + align-items: center; + } + body > footer * { margin: 1em auto; } + + .flex.wrap { flex-direction: column; } +}