diff options
author | Miguel Ángel Moreno <mail@migalmoreno.com> | 2023-05-27 19:05:15 +0200 |
---|---|---|
committer | Miguel Ángel Moreno <mail@migalmoreno.com> | 2023-05-27 19:05:15 +0200 |
commit | e7fa3750b3b94230ba072c2f98d1a1926d78011c (patch) | |
tree | 71c5d37a06a255d1cc5d81cf3a1507b907bb2c19 | |
parent | 275500466e1514f4ffcaf877ab9ed94251911b49 (diff) |
feat: Switch to BEM naming
-rw-r--r-- | assets/css/main.css | 266 | ||||
-rw-r--r-- | assets/js/main.js | 12 | ||||
-rw-r--r-- | haunt.scm | 252 |
3 files changed, 284 insertions, 246 deletions
diff --git a/assets/css/main.css b/assets/css/main.css index 60cf133..ba92f7d 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -55,33 +55,47 @@ a { text-decoration: none; } -main { +.main { flex: auto; padding: 20px; position: relative; } -main a, footer a { +.main__title { + padding: 10px 0; +} + +.main a { color: var(--accent); } -main dl, main ul { +code { + background: var(--secondary); + color: var(--accent); + border-radius: 5px; + padding: 2px 4px; +} + +.list { list-style: none; padding: 10px 0; } -main dl div { +.descriptions__wrapper { padding: 4px 0; } -main dl div dt { +.descriptions__title { + font-style: italic; + font-weight: bold; white-space: nowrap; } -main dl div dd { +.descriptions__text { padding-left: 30px; } -main dl.bulleted dt::before, main ul.bulleted li::before { + +.list-item--type-bulleted::before { content: "\2022"; font-size: 20px; padding: 10px 10px 0 0; @@ -90,15 +104,15 @@ main dl.bulleted dt::before, main ul.bulleted li::before { color: var(--accent); } -main dl a, main ul a { - font-weight: bold; +.post__subtitle { + font-style: italic; } .post-container { padding: 20px 0; } -header { +.navbar { height: 120px; box-sizing: border-box; width: 100%; @@ -109,7 +123,7 @@ header { align-items: center; } -header > div { +.navbar__images { padding: 20px; display: flex; flex-wrap: wrap; @@ -117,14 +131,17 @@ header > div { align-items: center; } -#logo a { +.navbar__logo { white-space: nowrap; + font-weight: 600; +} + +.navbar__link { text-decoration: none; color: var(--on-bg); - font-weight: 600; } -nav { +.navbar__nav { display: flex; justify-content: flex-end; align-items: center; @@ -135,7 +152,7 @@ nav { z-index: 999; } -nav ul { +.navbar__menu { height: inherit; width: 100%; display: flex; @@ -144,11 +161,11 @@ nav ul { justify-content: center; } -nav li { +.menu-item { padding: 20px; } -nav a { +.menu-item__link { text-decoration: none; font-weight: 500; color: var(--on-bg-dim); @@ -156,23 +173,23 @@ nav a { padding: 5px 0; } -nav a.current, nav a.current:hover { +.menu-item__link:hover { color: var(--on-bg); - border-color: var(--accent); + border-color: var(--on-bg); } -nav a:hover { +.menu-item__link--selected, .menu-item__link--selected:hover { color: var(--on-bg); - border-color: var(--on-bg); + border-color: var(--accent); } -.hamburger { +.navbar__menu-icon { cursor: pointer; float: right; display: none; } -.hamburger-icon { +.menu-icon { height: 2px; width: 24px; display: block; @@ -180,7 +197,7 @@ nav a:hover { background: var(--on-bg); } -.hamburger-icon::before, .hamburger-icon::after { +.menu-icon::before, .menu-icon::after { background: var(--on-bg); content: ""; display: block; @@ -190,37 +207,37 @@ nav a:hover { width: 100%; } -.hamburger-icon::before { +.menu-icon::before { top: 5px; } -.hamburger-icon::after { +.menu-icon::after { top: -5px; } -.mobile-menu { +.navbar__mobile-menu { display: none; } -.mobile-menu:checked ~ nav { +.navbar__mobile-menu:checked ~ .navbar__nav { max-height: calc(100vh - 80px); } -.mobile-menu:checked ~ div .hamburger .hamburger-icon { +.navbar__mobile-menu:checked ~ .navbar__images .menu-icon { background: transparent; } -.mobile-menu:checked ~ div .hamburger .hamburger-icon::before { +.navbar__mobile-menu:checked ~ .navbar__images .menu-icon::before { transform: rotate(-45deg); top: 0; } -.mobile-menu:checked ~ div .hamburger .hamburger-icon::after { +.navbar__mobile-menu:checked ~ .navbar__images .menu-icon::after { transform: rotate(45deg); top: 0; } -body > .container { +.body-container { min-height: calc(100vh - 120px); height: auto; max-height: auto; @@ -230,7 +247,7 @@ body > .container { align-items: center; } -footer { +.footer { display: flex; flex-direction: column; justify-content: center; @@ -240,52 +257,26 @@ footer { box-sizing: border-box; } -footer .container { +.footer__wrapper { width: 100%; padding: 10px 0; } -footer .container i { +.footer__icon { padding: 0 10px; font-size: 1.2rem; } -#source { - padding: 0 5px; -} - -#source a { - color: var(--on-bg); +.footer__link { + color: var(--accent); font-weight: 600; } -.title { +.hero__title, .portfolio__title, .blog__title { padding: 10px 0px; } -.text-bold { - font-weight: bold; -} - -.text-italic { - font-style: italic; -} - -.text-faint { - color: var(--on-bg-dim); -} - -i { - padding-right: 10px; -} - -main p code { - background: var(--secondary); - color: var(--accent); - border-radius: 5px; -} - -pre { +.codeblock { background: var(--bg-dim); padding: 15px; margin: 10px 0; @@ -297,13 +288,29 @@ pre { overflow-x: scroll; } -.metadata { +.codeblock__code { + background: inherit; + color: var(--on-bg); + border-radius: none; +} + +.project__subtitle { + color: var(--on-bg-dim); + font-style: italic; +} + +.project__icon { + padding-right: 10px; +} + +.project__metadata { padding: 10px 0; display: flex; flex-wrap: wrap; + align-items: center; } -.metadata span { +.project__metadata-items { text-align: center; white-space: nowrap; padding: 2px 20px 2px 0; @@ -330,12 +337,12 @@ pre { color: #999; } -figure{ - margin: 30px 10px; +.post__image { border-radius: 5px; } -figure img { +figure { + margin: 30px 10px; border-radius: 5px; } @@ -346,7 +353,7 @@ figcaption { color: var(--on-bg-dim); } -button.back { +.button--type-bare { background: none; border: none; font-family: "Helvetica Neue", Helvetica, sans-serif; @@ -355,11 +362,15 @@ button.back { color: var(--on-bg-dim); } -button.back a { +.button--type-bare .button__label { color: var(--on-bg-dim); } -#portfolio { +.button__icon { + padding-right: 10px; +} + +.portfolio { padding: 20px 0; display: flex; align-items: center; @@ -367,7 +378,7 @@ button.back a { flex-wrap: wrap; } -.project { +.project-item { border: 1px solid var(--on-secondary); display: block; background: var(--secondary); @@ -383,30 +394,26 @@ button.back a { margin: 15px; } -.project h1 { +.project-item__title { font-weight: bold; font-size: 1.3rem; } -.project:hover h1 { +.project-item:hover .project-item__title { text-decoration: underline; } -.project h4 { - font-weight: normal; - font-size: 1rem; -} - -.project p { +.project-item__synopsis { color: var(--on-bg); font-size: 1rem; } .tags { display: flex; + padding: 10px 0; } -.tags li { +.tag { list-style: none; background: var(--secondary); border-radius: 12px; @@ -419,17 +426,38 @@ button.back a { white-space: nowrap; } -.blog.preview { +.blog--type-preview { padding: 40px 0 20px 0; } -.blog h2 { +.blog__title { display: flex; justify-content: space-between; align-items: center; } -.post { +.blog__wrapper { + padding: 10px 0; +} + +.button--type-border { + text-decoration: none; + background: var(--secondary); + font-family: "Helvetica Neue"; + font-size: 1rem; + font-weight: bold; + padding: 10px 15px; + border: 1px solid transparent; + border-radius: 5px; + color: var(--on-bg); +} + +.button--type-border:hover { + border: 1px solid var(--border); + cursor: pointer; +} + +.post-item { display: flex; justify-content: space-between; align-items: center; @@ -441,46 +469,30 @@ button.back a { text-decoration: none; } -.post:last-of-type { +.post-item:last-of-type { border-bottom: none; } -.post:hover { +.post-item:hover { text-decoration: none; } -.post:hover .title { +.post-item:hover .post-item__title { text-decoration: underline; } -.blog button { - text-decoration: none; - background: var(--secondary); - font-family: "Helvetica Neue"; - font-size: 1rem; - font-weight: bold; - padding: 10px 15px; - border: 1px solid transparent; - border-radius: 5px; +.post-item__title { color: var(--on-bg); + padding: 10px 0; } -.blog button:hover { - border: 1px solid var(--border); - cursor: pointer; -} - -.blog button a:hover { - text-decoration: none; -} - -.date { +.post-item__date { color: var(--accent); font-family: monospace; font-size: 1rem; } -#not-found { +.not-found { height: 100%; position: absolute; display: flex; @@ -515,42 +527,42 @@ button.back a { margin: 0; } - body > .container { + .body-container { min-height: calc(100vh - 80px); } - header { + .navbar { height: 80px; - } - - main, header { margin: 0; min-width: 100%; max-width: 100%; } - main { + .main { padding-top: 0; + margin: 0; + min-width: 100%; + max-width: 100%; } - header > div { + .navbar__images { width: 100%; } - .hamburger { + .navbar__menu-icon { display: block; } - .project { + .project-item { min-width: 250px; max-width: 250px; } - .tags li { + .tag { font-size: 0.6rem; } - nav { + .navbar__nav { max-height: 0; height: 100%; width: 100%; @@ -558,33 +570,33 @@ button.back a { top: 80px; } - nav ul { + .nav__menu { flex-direction: column; } - nav ul li { + .menu-item { font-size: 18px; } - button.back { + .button--type-bare { font-size: 15px; } - .post { + .post-item { font-size: 1rem; } - .date { + .post-item__date { font-size: .9rem; } } @media screen and (max-width: 468px) { - .date { + .post-item__date { display: none; } - .project { + .project-item { min-width: 100%; max-width: 100%; } diff --git a/assets/js/main.js b/assets/js/main.js index b350b2f..d4c8af3 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,19 +1,17 @@ function setCopyrightYear() { - document.querySelector("#year").innerHTML = new Date().getFullYear() + document.querySelector(".footer__year").innerHTML = new Date().getFullYear() } function highlightCurrentRoute() { const rx = /\/+$/ - for (let el of document.querySelectorAll("nav ul a")) { + for (let el of document.querySelectorAll(".menu-item__link")) { if (el.href.replace(rx, "") === window.location.href.replace(rx, "")) { - el.classList.add("current") + el.classList.add("menu-item__link--selected") } } } -function init() { +(function init() { setCopyrightYear() highlightCurrentRoute() -} - -init() +})() @@ -28,7 +28,9 @@ ('c lex-c) (_ #f)))) (if lexer - `(pre (code ,(highlights->sxml (highlight lexer code)))) + `(pre (@ (class "codeblock")) + (code (@ (class "codeblock__code")) + ,(highlights->sxml (highlight lexer code)))) code))) (define (static-page title filename body) @@ -37,8 +39,11 @@ (with-layout %blog-theme site title body) sxml->html))) -(define* (anchor label url #:key external?) +(define* (anchor label url #:key external? class) `(a (@ (href ,url) + ,@(if class + `((class ,class)) + '()) ,@(if external? '((rel noopener) (target _blank)) @@ -68,12 +73,11 @@ #:description `((p "Tubo is an alternative web frontend to some of the most popular streaming sites, including:") - (ul (@ (class "bulleted")) - (li "YouTube") - (li "SoundCloud") - (li "media.ccc.de") - (li "PeerTube") - (li "Bandcamp")) + (ul (@ (class "list")) + ,@(map (lambda (i) + `(li (@ (class "list-item--type-bulleted")) ,i)) + (list "YouTube" "SoundCloud" "media.ccc.de" "PeerTube" + "Bandcamp"))) (p "It acts like a privacy-friendly proxy that compiles all the content from the above sites and presents it to you in a distraction-free interface. It gathers the necessary data via " @@ -90,7 +94,8 @@ downloads, offline mode, and more.") (figure (img (@ (src "https://files.mianmoreno.com/tubo_channel.jpg") (style "width:100%") - (alt "Tubo channel page screenshot"))) + (alt "Tubo channel page screenshot") + (class "post__image"))) (figcaption "Channel page view")))) (project #:name "nx-router" @@ -138,7 +143,8 @@ depending on the time of the day.") (video (@ (src "https://files.mianmoreno.com/nx_tailor.mp4") (style "width:100%") (autoplay "true") - (controls "true"))) + (controls "true") + (class "post__image"))) (figcaption "Changing the theme via the prompt buffer")))) (project #:name "fdroid.el" @@ -203,12 +209,13 @@ describe my personal projects and contributions."))))) ;; (define (post-entries site posts) - `(ul + `(ul (@ (class "blog__wrapper")) ,@(map (lambda (post) - `(a (@ (class "post") + `(a (@ (class "post-item") (href ,(post-uri site post))) - (span (@ (class title)) ,(post-ref post 'title)) - (span (@ (class "date")) ,(date->string* (post-date post))))) + (span (@ (class "post-item__title")) ,(post-ref post 'title)) + (span (@ (class "post-item__date")) + ,(date->string* (post-date post))))) posts))) (define* (stylesheet name #:key local?) @@ -222,48 +229,54 @@ describe my personal projects and contributions."))))) (src ,(string-append "/assets/js/" name ".js"))))) (define navbar - `(header - (input (@ (class "mobile-menu") (type "checkbox") (id "mobile-menu"))) - (div - (div (@ (id "logo")) ,(anchor %fullname "/")) - (label (@ (class "hamburger") (for "mobile-menu")) - (span (@ (class "hamburger-icon"))))) - (nav - (ul - ,@(map (lambda (a) - `(li ,(anchor (car a) (cdr a)))) - '(("Home" . "/") - ("Projects" . "/projects") - ("Blog" . "/posts") - ("Contact" . "/contact.html"))))))) + `(header (@ (class "navbar")) + (input (@ (class "navbar__mobile-menu") + (type "checkbox") (id "mobile-menu"))) + (div (@ (class "navbar__images")) + (div (@ (class "navbar__logo")) + ,(anchor %fullname "/" #:class "navbar__link")) + (label (@ (class "navbar__menu-icon") (for "mobile-menu")) + (span (@ (class "menu-icon"))))) + (nav (@ (class "navbar__nav")) + (ul (@ (class "navbar__menu")) + ,@(map (lambda (a) + `(li (@ (class "menu-item")) + ,(anchor (car a) (cdr a) + #:class "menu-item__link"))) + '(("Home" . "/") + ("Projects" . "/projects") + ("Blog" . "/posts") + ("Contact" . "/contact.html"))))))) (define footer - `(footer - (div (@ (class "container")) - ,(anchor '(i (@ (class "fa-solid fa-envelope"))) - (string-append "mailto:" %email) - #:external? #t) - ,(anchor '(i (@ (class "fa-brands fa-linkedin"))) - "https://linkedin.com/in/mianmoreno" - #:external? #t) - ,(anchor '(i (@ (class "fa-brands fa-git-alt"))) - (string-append "https://git." %domain) - #:external? #t) - ,(anchor '(i (@ (class "fa-regular fa-circle"))) - "https://sr.ht/~mmoreno" - #:external? #t) - ,(anchor '(i (@ (class "fa-brands fa-github"))) - "https://github.com/mianmoreno" - #:external? #t) - ,(anchor '(i (@ (class "fa-brands fa-gitlab"))) - "https://gitlab.com/mianmoreno" - #:external? #t)) - (div (@ (class "container")) + `(footer (@ (class "footer")) + (div (@ (class "footer__wrapper")) + ,@(map (lambda (item) + (anchor `(i (@ (class + ,(string-append (cdr item) + " footer__icon")))) + (car item) + #:external? #t + #:class "footer__link")) + (list + (cons (format #f "https://git.~a/blog" %domain) + "fa-solid fa-code") + (cons (string-append "mailto:" %email) + "fa-solid fa-envelope") + (cons "https://linkedin.com/in/mianmoreno" + "fa-brands fa-linkedin") + (cons (string-append "https://git." %domain) + "fa-brands fa-git-alt") + (cons "https://sr.ht/~mmoreno" + "fa-regular fa-circle") + (cons "https://github.com/mianmoreno" + "fa-brands fa-github") + (cons "https://gitlab.com/mianmoreno" + "fa-brands fa-gitlab")))) + (div (@ (class "footer__wrapper")) "© " - (span (@ (id "year"))) - ,(format #f " ~a —" %fullname) - (span (@ (id "source")) - ,(anchor "Source" (format #f "https://git.~a/blog" %domain)))))) + (span (@ (class "footer__year"))) + ,(format #f " ~a" %fullname)))) (define (base-layout site title body) `((doctype "html") @@ -277,8 +290,8 @@ describe my personal projects and contributions."))))) ,(stylesheet "https://use.fontawesome.com/releases/v6.3.0/css/all.css")) (body ,navbar - (div (@ (class "container")) - (main ,body) + (div (@ (class "body-container")) + (main (@ (class "main")) ,body) ,footer) ,(script "main"))))) @@ -288,55 +301,66 @@ describe my personal projects and contributions."))))) ;; (define (post-template post) - `((button (@ (class "back")) - (i (@ (class "fa-solid fa-caret-left"))) - (a (@ (href "/posts")) "Back to posts")) - (h1 (@ (class "title")) ,(post-ref post 'title)) - (span (@ (class "text-italic")) " on " ,(date->string* (post-date post))) - (ul (@ (class "tags")) - ,@(map (lambda (tag) - `(li (a (@ (href ,(string-append "/feeds/tags/" tag ".xml"))) - ,tag))) - (assq-ref (post-metadata post) 'tags))) + `((div (@ (class "post__metadata")) + (button (@ (class "button button--type-bare")) + (i (@ (class "fa-solid fa-caret-left button__icon"))) + (a (@ (href "/posts") (class "button__label")) "Back to posts")) + (h1 (@ (class "main__title")) ,(post-ref post 'title)) + (span (@ (class "post__subtitle")) " on " + ,(date->string* (post-date post))) + (ul (@ (class "tags")) + ,@(map (lambda (tag) + `(li (@ (class "tag")) + (a (@ (href + ,(string-append "/feeds/tags/" tag ".xml"))) + ,tag))) + (assq-ref (post-metadata post) 'tags)))) (div (@ (class "post-container")) ,(post-sxml post)))) (define (project-template project) - `((button (@ (class "back")) - (i (@ (class "fa-solid fa-caret-left"))) - (a (@ (href "/projects")) "Back to projects")) - (h1 ,(project-name project)) - (h4 (@ (class "text-italic text-faint")) ,(project-synopsis project)) - (div (@ (class "metadata")) - (span (i (@ (class "fa-brands fa-git-alt"))) - ,(anchor (project-link project) - (string-append (project-link project) "/about") - #:external? #t)) - (span (i (@ (class "fa-solid fa-file-lines"))) - ,(project-license project))) - (ul (@ (class "tags")) - ,@(map (lambda (tag) - `(li ,tag)) (project-tags project))) - ,@(project-description project))) + `((div (@ (class "project")) + (button (@ (class "button--type-bare")) + (i (@ (class "fa-solid fa-caret-left button__icon"))) + (a (@ (href "/projects") (class "button__label")) + "Back to projects")) + (h1 ,(project-name project)) + (h4 (@ (class "project__subtitle")) ,(project-synopsis project)) + (div (@ (class "project__metadata")) + (span (@ (class "project__metadata-items")) + (i (@ (class "fa-brands fa-git-alt project__icon"))) + ,(anchor (project-link project) + (string-append (project-link project) "/about") + #:external? #t)) + (span (@ (classs "project__metadata-items")) + (i (@ (class "fa-solid fa-file-lines project__icon"))) + ,(project-license project))) + (ul (@ (class "tags")) + ,@(map (lambda (tag) + `(li (@ (class "tag")) ,tag)) (project-tags project))) + ,@(project-description project)))) (define (blog-template site title posts prefix) `((div (@ (class "blog")) - (h1 (@ (class "title")) ,title) + (h1 (@ (class "main__title")) ,title) ,(post-entries site (posts/reverse-chronological posts))))) (define (portfolio-template site title projects prefix) (define (project-uri project) (string-append (or prefix "") "/" (project-name project) ".html")) - `((h1 (@ (class "title")) ,title) - (div (@ (id "portfolio")) + `((h1 (@ (class "portfolio__title")) ,title) + (div (@ (class "portfolio")) ,@(map (lambda (project) `(a (@ (href ,(project-uri project)) - (class "project")) - (h1 ,(project-name project)) + (class "project-item")) + (h1 (@ (class "project-item__title")) + ,(project-name project)) (ul (@ (class "tags")) ,@(map (lambda (tag) - `(li ,tag)) (project-tags project))) - (p ,(project-synopsis project)))) + `(li (@ (class "tag")) ,tag)) + (project-tags project))) + (p (@ (class "project-item__synopsis")) + ,(project-synopsis project)))) projects)))) (define %blog-collections @@ -369,21 +393,23 @@ describe my personal projects and contributions."))))) "index.html" (with-layout %blog-theme site "Home" - `((div (@ (id "about")) - (h1 (@ (class "title")) "Hi, I'm Miguel Ángel!") + `((div (@ (class "hero")) + (h1 (@ (class "hero__title")) "Hi, I'm Miguel Ángel!") (p "I'm a software engineer based in Barcelona and a recent Computer Science graduate from the University of Kent.") (p "My interests currently revolve around these topics:") - (ul (@ (class "bulleted")) - (li "Functional programming") - (li "LISP") - (li "Web development") - (li "Operating systems") - (li "Introspectable and extensible tooling") - (li "Digital privacy") - (li "Free and open source software"))) - (div (@ (class "blog preview")) - (h2 "Latest Posts" ,(anchor '(button "See all") "/posts")) + (ul (@ (class "list")) + ,@(map (lambda (i) + `(li (@ (class "list-item--type-bulleted")) ,i)) + (list "Functional programming" "LISP" "Web development" + "Operating systems" + "Introspectable and extensible tooling" + "Digital privacy" + "Free and open source software")))) + (div (@ (class "blog blog--type-preview")) + (h2 (@ (class "blog__title")) "Latest Posts" + ,(anchor '(button (@ (class "button button--type-border")) + "See all") "/posts")) ,(post-entries site posts)))) sxml->html)))) @@ -391,24 +417,26 @@ Computer Science graduate from the University of Kent.") (static-page "Contact" "/contact.html" - `((h1 (@ (class "title")) "Contact me") - (dl - (div - (dt (@ (class "text-bold text-italic")) "Email") - (dd (code "me") " at " (code "$DOMAIN"))) - (div - (dt (@ (class "text-bold text-italic")) "PGP") - (dd ,(anchor "4956 DAC8 B077 15EA 9F14 E13A EF1F 69BF 5F23 F458" + `((h1 (@ (class "main__title")) "Contact me") + (dl (@ (class "list")) + (div (@ (class "descriptions__wrapper")) + (dt (@ (class "descriptions__title")) "Email") + (dd (@ (class "descriptions__text")) + (code "me") " at " (code "$DOMAIN"))) + (div (@ (class "descriptions__wrapper")) + (dt (@ (class "descriptions__title")) "PGP") + (dd (@ (class "descriptions__text")) + ,(anchor "4956 DAC8 B077 15EA 9F14 E13A EF1F 69BF 5F23 F458" "assets/pubkey.asc"))) - (div - (dt (@ (class "text-bold text-italic")) "Matrix") - (dd (code "@sloan:conses.eu"))))))) + (div (@ (class "descriptions__wrapper")) + (dt (@ (class "descriptions__title")) "Matrix") + (dd (@ (class "descriptions__text")) (code "@sloan:conses.eu"))))))) (define not-found-page (static-page "404 Not found" "/404.html" - `((div (@ (id "not-found")) + `((div (@ (class "not-found")) (h1 "404") (h1 "Not Found"))))) |