From 99985430c28e9fa4e6e2377181f539eec6727be7 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Tue, 3 Feb 2026 05:19:12 -0800 Subject: [PATCH] Inline icons from Font Awesome --- public/about.md | 8 ++-- public/css/style.css | 34 ++++++++++++----- .../Posts/Templates/PostTemplate.swift | 2 +- .../Projects/Templates/ProjectTemplate.swift | 2 +- .../Projects/Templates/ProjectsTemplate.swift | 2 +- .../samhuri.net/Site/Templates/Icons.swift | 38 +++++++++++++++++++ .../Site/Templates/PageTemplate.swift | 2 +- .../Site/Templates/SiteTemplate.swift | 31 +++++++++++---- .../Sources/samhuri.net/samhuri.net.swift | 2 +- 9 files changed, 93 insertions(+), 28 deletions(-) create mode 100644 samhuri.net/Sources/samhuri.net/Site/Templates/Icons.swift diff --git a/public/about.md b/public/about.md index 20495d9..9ae5a17 100644 --- a/public/about.md +++ b/public/about.md @@ -61,13 +61,11 @@ Have a look at my [work history](/cv). ## So meta -This site is lovingly hand-crafted, tag by tag, and pixel by pixel. It adheres to and embraces modern web standards. It is authored in [Markdown][], HTML, CSS, and JavaScript, and then it's all compiled with [some custom code][samhuri.net] before [Apache][] serves it up. The header and body font, [Museo Sans][], is provided by [TypeKit][]. +This site is lovingly hand-crafted, tag by tag, and pixel by pixel. It adheres to and embraces modern web standards. It is authored in [Markdown][], HTML, CSS, and JavaScript, and then it's all compiled with [some custom code][samhuri.net] before [Caddy][] serves it up. -Oh, and a shout out to [Font Awesome][fa] for being awesome. +Oh, and a shout out to [Font Awesome][fa] for being awesome. [Markdown]: http://daringfireball.net/projects/markdown/ [samhuri.net]: https://github.com/samsonjs/samhuri.net -[Apache]: http://apache.org -[Museo Sans]: http://www.exljbris.com/museosans.html -[TypeKit]: https://typekit.com/fonts +[Caddy]: https://caddyserver.com [fa]: http://fontawesome.io diff --git a/public/css/style.css b/public/css/style.css index 613e7a0..d08c332 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -103,8 +103,8 @@ img { body { background-color: #f7f7f7; color: #222; - font-family: "museo-sans", "Helvetica Neue", "Verdana", "Roboto", sans-serif; - font-display: swap; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, + sans-serif; padding-bottom: env(safe-area-inset-bottom); } @@ -156,8 +156,8 @@ header.primary h4 { margin: 0; padding: 0; word-wrap: break-word; - font-family: "museo-sans", "Helvetica Neue", "Verdana", "Roboto", sans-serif; - font-display: swap; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, + sans-serif; font-weight: normal; } @@ -229,20 +229,29 @@ header.primary nav ul li:last-child { padding-right: 0; } -header.primary nav ul li i.fa { - font-size: 1.4rem; - padding: 0.2rem; +.icon { + display: inline-block; + width: 1em; + height: 1em; + fill: currentColor; + vertical-align: -0.125em; } -header.primary nav ul li.rss i.fa-rss { +header.primary nav ul li .icon { + width: 1.6rem; + height: 1.6rem; + padding: 0.15rem; +} + +header.primary nav ul li.rss .icon { color: #e66b19; } -header.primary nav ul li.mastodon i.fa-mastodon { +header.primary nav ul li.mastodon .icon { color: #5e4fe5; } -header.primary nav ul li.github i.fa-github { +header.primary nav ul li.github .icon { color: #4183c4; } @@ -440,6 +449,11 @@ p.fin { margin: 1rem 0; } +p.fin .icon { + width: 1.4rem; + height: 1.4rem; +} + blockquote { margin-left: 6%; font-family: "Helvetica Neue", "Verdana", "Roboto", sans-serif; diff --git a/samhuri.net/Sources/samhuri.net/Posts/Templates/PostTemplate.swift b/samhuri.net/Sources/samhuri.net/Posts/Templates/PostTemplate.swift index cac06fe..973fa43 100644 --- a/samhuri.net/Sources/samhuri.net/Posts/Templates/PostTemplate.swift +++ b/samhuri.net/Sources/samhuri.net/Posts/Templates/PostTemplate.swift @@ -20,7 +20,7 @@ extension Node where Context == HTML.BodyContext { .raw(post.body) ), .div(.class("row clearfix"), - .p(.class("fin"), .i(.class("fa fa-code"))) + .p(.class("fin"), Icons.code()) ) ]) } diff --git a/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectTemplate.swift b/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectTemplate.swift index b487cf0..5fad87d 100644 --- a/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectTemplate.swift +++ b/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectTemplate.swift @@ -40,7 +40,7 @@ extension Node where Context == HTML.BodyContext { ), .div(.class("row clearfix"), - .p(.class("fin"), .i(.class("fa fa-code"))) + .p(.class("fin"), Icons.code()) ), .group(context.scripts.map { url in diff --git a/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectsTemplate.swift b/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectsTemplate.swift index 0c50152..97ebde1 100644 --- a/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectsTemplate.swift +++ b/samhuri.net/Sources/samhuri.net/Projects/Templates/ProjectsTemplate.swift @@ -23,7 +23,7 @@ extension Node where Context == HTML.BodyContext { ), .div(.class("row clearfix"), - .p(.class("fin"), .i(.class("fa fa-code"))) + .p(.class("fin"), Icons.code()) ) ]) } diff --git a/samhuri.net/Sources/samhuri.net/Site/Templates/Icons.swift b/samhuri.net/Sources/samhuri.net/Site/Templates/Icons.swift new file mode 100644 index 0000000..a00e4b5 --- /dev/null +++ b/samhuri.net/Sources/samhuri.net/Site/Templates/Icons.swift @@ -0,0 +1,38 @@ +// +// Icons.swift +// samhuri.net +// +// Created by Sami Samhuri on 2026-02-03. +// + +import Foundation +import Plot + +enum Icons { + static func mastodon() -> Node { + .raw(svg(className: "icon icon-mastodon", viewBox: "0 0 448 512", path: IconPath.mastodon)) + } + + static func github() -> Node { + .raw(svg(className: "icon icon-github", viewBox: "0 0 496 512", path: IconPath.github)) + } + + static func rss() -> Node { + .raw(svg(className: "icon icon-rss", viewBox: "0 0 448 512", path: IconPath.rss)) + } + + static func code() -> Node { + .raw(svg(className: "icon icon-code", viewBox: "0 0 640 512", path: IconPath.code)) + } + + private static func svg(className: String, viewBox: String, path: String) -> String { + "" + } +} + +private enum IconPath { + static let mastodon = "M433 268.89c0 0 0.799805 -71.6992 -9 -121.5c-6.23047 -31.5996 -55.1104 -66.1992 -111.23 -72.8994c-20.0996 -2.40039 -93.1191 -14.2002 -178.75 6.7002c0 -0.116211 -0.00390625 -0.119141 -0.00390625 -0.235352c0 -4.63281 0.307617 -9.19434 0.904297 -13.665 c6.62988 -49.5996 49.2197 -52.5996 89.6299 -54c40.8105 -1.2998 77.1201 10.0996 77.1201 10.0996l1.7002 -36.8994s-28.5098 -15.2998 -79.3203 -18.1006c-28.0098 -1.59961 -62.8193 0.700195 -103.33 11.4004c-112.229 29.7002 -105.63 173.4 -105.63 289.1 c0 97.2002 63.7197 125.7 63.7197 125.7c61.9209 28.4004 227.96 28.7002 290.48 0c0 0 63.71 -28.5 63.71 -125.7zM357.88 143.69c0 122 5.29004 147.71 -18.4199 175.01c-25.71 28.7002 -79.7197 31 -103.83 -6.10059l-11.5996 -19.5l-11.6006 19.5 c-24.0098 36.9004 -77.9297 35 -103.83 6.10059c-23.6094 -27.1006 -18.4092 -52.9004 -18.4092 -175h46.7295v114.2c0 49.6992 64 51.5996 64 -6.90039v-62.5098h46.3301v62.5c0 58.5 64 56.5996 64 6.89941v-114.199h46.6299z" + static let github = "M165.9 50.5996c0 -2 -2.30078 -3.59961 -5.2002 -3.59961c-3.2998 -0.299805 -5.60059 1.2998 -5.60059 3.59961c0 2 2.30078 3.60059 5.2002 3.60059c3 0.299805 5.60059 -1.2998 5.60059 -3.60059zM134.8 55.0996c0.700195 2 3.60059 3 6.2002 2.30078 c3 -0.900391 4.90039 -3.2002 4.2998 -5.2002c-0.599609 -2 -3.59961 -3 -6.2002 -2c-3 0.599609 -5 2.89941 -4.2998 4.89941zM179 56.7998c2.90039 0.299805 5.59961 -1 5.90039 -2.89941c0.299805 -2 -1.7002 -3.90039 -4.60059 -4.60059 c-3 -0.700195 -5.59961 0.600586 -5.89941 2.60059c-0.300781 2.2998 1.69922 4.19922 4.59961 4.89941zM244.8 440c138.7 0 251.2 -105.3 251.2 -244c0 -110.9 -67.7998 -205.8 -167.8 -239c-12.7002 -2.2998 -17.2998 5.59961 -17.2998 12.0996 c0 8.2002 0.299805 49.9004 0.299805 83.6006c0 23.5 -7.7998 38.5 -17 46.3994c55.8994 6.30078 114.8 14 114.8 110.5c0 27.4004 -9.7998 41.2002 -25.7998 58.9004c2.59961 6.5 11.0996 33.2002 -2.60059 67.9004c-20.8994 6.59961 -69 -27 -69 -27 c-20 5.59961 -41.5 8.5 -62.7998 8.5s-42.7998 -2.90039 -62.7998 -8.5c0 0 -48.0996 33.5 -69 27c-13.7002 -34.6006 -5.2002 -61.4004 -2.59961 -67.9004c-16 -17.5996 -23.6006 -31.4004 -23.6006 -58.9004c0 -96.1992 56.4004 -104.3 112.3 -110.5 c-7.19922 -6.59961 -13.6992 -17.6992 -16 -33.6992c-14.2998 -6.60059 -51 -17.7002 -72.8994 20.8994c-13.7002 23.7998 -38.6006 25.7998 -38.6006 25.7998c-24.5 0.300781 -1.59961 -15.3994 -1.59961 -15.3994c16.4004 -7.5 27.7998 -36.6006 27.7998 -36.6006 c14.7002 -44.7998 84.7002 -29.7998 84.7002 -29.7998c0 -21 0.299805 -55.2002 0.299805 -61.3994c0 -6.5 -4.5 -14.4004 -17.2998 -12.1006c-99.7002 33.4004 -169.5 128.3 -169.5 239.2c0 138.7 106.1 244 244.8 244zM97.2002 95.0996 c1.2998 1.30078 3.59961 0.600586 5.2002 -1c1.69922 -1.89941 2 -4.19922 0.699219 -5.19922c-1.2998 -1.30078 -3.59961 -0.600586 -5.19922 1c-1.7002 1.89941 -2 4.19922 -0.700195 5.19922zM86.4004 103.2c0.699219 1 2.2998 1.2998 4.2998 0.700195 c2 -1 3 -2.60059 2.2998 -3.90039c-0.700195 -1.40039 -2.7002 -1.7002 -4.2998 -0.700195c-2 1 -3 2.60059 -2.2998 3.90039zM118.8 67.5996c1.2998 1.60059 4.2998 1.30078 6.5 -1c2 -1.89941 2.60059 -4.89941 1.2998 -6.19922 c-1.2998 -1.60059 -4.19922 -1.30078 -6.5 1c-2.2998 1.89941 -2.89941 4.89941 -1.2998 6.19922zM107.4 82.2998c1.59961 1.2998 4.19922 0.299805 5.59961 -2c1.59961 -2.2998 1.59961 -4.89941 0 -6.2002c-1.2998 -1 -4 0 -5.59961 2.30078 c-1.60059 2.2998 -1.60059 4.89941 0 5.89941z" + static let rss = "M128.081 32.041c0 -35.3691 -28.6719 -64.041 -64.041 -64.041s-64.04 28.6719 -64.04 64.041s28.6719 64.041 64.041 64.041s64.04 -28.6729 64.04 -64.041zM303.741 -15.209c0.494141 -9.13477 -6.84668 -16.791 -15.9951 -16.79h-48.0693 c-8.41406 0 -15.4707 6.49023 -16.0176 14.8867c-7.29883 112.07 -96.9404 201.488 -208.772 208.772c-8.39648 0.545898 -14.8867 7.60254 -14.8867 16.0176v48.0693c0 9.14746 7.65625 16.4883 16.791 15.9941c154.765 -8.36328 278.596 -132.351 286.95 -286.95z M447.99 -15.4971c0.324219 -9.03027 -6.97168 -16.5029 -16.0049 -16.5039h-48.0684c-8.62598 0 -15.6455 6.83496 -15.999 15.4531c-7.83789 191.148 -161.286 344.626 -352.465 352.465c-8.61816 0.354492 -15.4531 7.37402 -15.4531 15.999v48.0684 c0 9.03418 7.47266 16.3301 16.5029 16.0059c234.962 -8.43555 423.093 -197.667 431.487 -431.487z" + static let code = "M278.9 -63.5l-61 17.7002c-6.40039 1.7998 -10 8.5 -8.2002 14.8994l136.5 470.2c1.7998 6.40039 8.5 10 14.8994 8.2002l61 -17.7002c6.40039 -1.7998 10 -8.5 8.2002 -14.8994l-136.5 -470.2c-1.89941 -6.40039 -8.5 -10.1006 -14.8994 -8.2002zM164.9 48.7002 c-4.5 -4.90039 -12.1006 -5.10059 -17 -0.5l-144.101 135.1c-5.09961 4.7002 -5.09961 12.7998 0 17.5l144.101 135c4.89941 4.60059 12.5 4.2998 17 -0.5l43.5 -46.3994c4.69922 -4.90039 4.2998 -12.7002 -0.800781 -17.2002l-90.5996 -79.7002l90.5996 -79.7002 c5.10059 -4.5 5.40039 -12.2998 0.800781 -17.2002zM492.1 48.0996c-4.89941 -4.5 -12.5 -4.2998 -17 0.600586l-43.5 46.3994c-4.69922 4.90039 -4.2998 12.7002 0.800781 17.2002l90.5996 79.7002l-90.5996 79.7998c-5.10059 4.5 -5.40039 12.2998 -0.800781 17.2002 l43.5 46.4004c4.60059 4.7998 12.2002 5 17 0.5l144.101 -135.2c5.09961 -4.7002 5.09961 -12.7998 0 -17.5z" +} diff --git a/samhuri.net/Sources/samhuri.net/Site/Templates/PageTemplate.swift b/samhuri.net/Sources/samhuri.net/Site/Templates/PageTemplate.swift index f62a86a..7d63664 100644 --- a/samhuri.net/Sources/samhuri.net/Site/Templates/PageTemplate.swift +++ b/samhuri.net/Sources/samhuri.net/Site/Templates/PageTemplate.swift @@ -16,7 +16,7 @@ extension Node where Context == HTML.BodyContext { .raw(bodyHTML) ), .div(.class("row clearfix"), - .p(.class("fin"), .i(.class("fa fa-code"))) + .p(.class("fin"), Icons.code()) ) ]) } diff --git a/samhuri.net/Sources/samhuri.net/Site/Templates/SiteTemplate.swift b/samhuri.net/Sources/samhuri.net/Site/Templates/SiteTemplate.swift index feea3da..915b7f3 100644 --- a/samhuri.net/Sources/samhuri.net/Site/Templates/SiteTemplate.swift +++ b/samhuri.net/Sources/samhuri.net/Site/Templates/SiteTemplate.swift @@ -42,8 +42,6 @@ enum Template { .meta(.name("msapplication-config"), .content(context.imageURL("browserconfig.xml").absoluteString)), .meta(.name("theme-color"), .content("#121212")), // matches header .meta(.name("viewport"), .content("width=device-width, initial-scale=1.0, viewport-fit=cover")), - .link(.rel(.dnsPrefetch), .href("https://use.typekit.net")), - .link(.rel(.dnsPrefetch), .href("https://netdna.bootstrapcdn.com")), .link(.rel(.dnsPrefetch), .href("https://gist.github.com")), .group(context.styles.map { url in .link(.rel(.stylesheet), .type("text/css"), .href(url)) @@ -62,9 +60,28 @@ enum Template { ), .nav(.class("remote"), .ul( - .li(.class("mastodon"), .a(.attribute(named: "rel", value: "me"), .href("https://techhub.social/@sjs"), .i(.class("fab fa-mastodon")))), - .li(.class("github"), .a(.href("https://github.com/samsonjs"), .i(.class("fab fa-github")))), - .li(.class("rss"), .a(.href(context.url(for: "feed.xml")), .i(.class("fa fa-rss")))) + .li(.class("mastodon"), + .a( + .attribute(named: "rel", value: "me"), + .attribute(named: "aria-label", value: "Mastodon"), + .href("https://techhub.social/@sjs"), + Icons.mastodon() + ) + ), + .li(.class("github"), + .a( + .attribute(named: "aria-label", value: "GitHub"), + .href("https://github.com/samsonjs"), + Icons.github() + ) + ), + .li(.class("rss"), + .a( + .attribute(named: "aria-label", value: "RSS"), + .href(context.url(for: "feed.xml")), + Icons.rss() + ) + ) ) ), .nav(.class("local"), @@ -86,9 +103,7 @@ enum Template { .group(context.scripts.map { script in .script(.attribute(named: "defer"), .src(script)) - }), - .script(.src("https://use.typekit.net/tcm1whv.js"), .attribute(named: "crossorigin", value: "anonymous")), - .script("try{Typekit.load({ async: true });}catch(e){}") + }) ) ) } diff --git a/samhuri.net/Sources/samhuri.net/samhuri.net.swift b/samhuri.net/Sources/samhuri.net/samhuri.net.swift index 180b915..5965ccf 100644 --- a/samhuri.net/Sources/samhuri.net/samhuri.net.swift +++ b/samhuri.net/Sources/samhuri.net/samhuri.net.swift @@ -56,7 +56,7 @@ public extension samhuri { email: "sami@samhuri.net", url: siteURLOverride ?? URL(string: "https://samhuri.net")! ) - .styles("normalize.css", "style.css", "fontawesome.min.css", "brands.min.css", "solid.min.css") + .styles("normalize.css", "style.css") .renderMarkdown(pageRenderer: renderer) .plugin(projectsPlugin) .plugin(postsPlugin)