Inline icons from Font Awesome

This commit is contained in:
Sami Samhuri 2026-02-03 05:19:12 -08:00
parent 5c646d8d50
commit 99985430c2
No known key found for this signature in database
9 changed files with 93 additions and 28 deletions

View file

@ -61,13 +61,11 @@ Have a look at my [work history](/cv).
## So meta ## 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. <i class="fa fa-thumbs-up" style="color: #ccc"></i> Oh, and a shout out to [Font Awesome][fa] for being awesome. <svg class="icon icon-thumbs-up" viewBox="0 0 512 512" aria-hidden="true" focusable="false" style="color: #ccc"><path transform="translate(0,448) scale(1,-1)" d="M104 224c13.2549 0 24 -10.7451 24 -24v-240c0 -13.2549 -10.7451 -24 -24 -24h-80c-13.2549 0 -24 10.7451 -24 24v240c0 13.2549 10.7451 24 24 24h80zM64 -24c13.2549 0 24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24zM384 366.548 c0 -42.416 -25.9697 -66.208 -33.2773 -94.5479h101.724c33.3965 0 59.3965 -27.7461 59.5527 -58.0977c0.0839844 -17.9385 -7.5459 -37.249 -19.4395 -49.1973l-0.109375 -0.110352c9.83594 -23.3369 8.23633 -56.0371 -9.30859 -79.4688 c8.68164 -25.8945 -0.0683594 -57.7041 -16.3818 -74.7568c4.29785 -17.5977 2.24414 -32.5752 -6.14746 -44.6318c-20.4102 -29.3242 -70.9961 -29.7373 -113.773 -29.7373l-2.84473 0.000976562c-48.2871 0.0166016 -87.8057 17.5977 -119.561 31.7246 c-15.957 7.09961 -36.8203 15.8877 -52.6504 16.1787c-6.54004 0.120117 -11.7832 5.45703 -11.7832 11.998v213.77c0 3.2002 1.28223 6.27148 3.55762 8.52148c39.6143 39.1436 56.6484 80.5869 89.1172 113.11c14.8037 14.832 20.1885 37.2363 25.3936 58.9023 c4.44629 18.501 13.749 57.7939 33.9316 57.7939c24 0 72 -8 72 -81.4521z"/></svg>
[Markdown]: http://daringfireball.net/projects/markdown/ [Markdown]: http://daringfireball.net/projects/markdown/
[samhuri.net]: https://github.com/samsonjs/samhuri.net [samhuri.net]: https://github.com/samsonjs/samhuri.net
[Apache]: http://apache.org [Caddy]: https://caddyserver.com
[Museo Sans]: http://www.exljbris.com/museosans.html
[TypeKit]: https://typekit.com/fonts
[fa]: http://fontawesome.io [fa]: http://fontawesome.io

View file

@ -103,8 +103,8 @@ img {
body { body {
background-color: #f7f7f7; background-color: #f7f7f7;
color: #222; color: #222;
font-family: "museo-sans", "Helvetica Neue", "Verdana", "Roboto", sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial,
font-display: swap; sans-serif;
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
} }
@ -156,8 +156,8 @@ header.primary h4 {
margin: 0; margin: 0;
padding: 0; padding: 0;
word-wrap: break-word; word-wrap: break-word;
font-family: "museo-sans", "Helvetica Neue", "Verdana", "Roboto", sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial,
font-display: swap; sans-serif;
font-weight: normal; font-weight: normal;
} }
@ -229,20 +229,29 @@ header.primary nav ul li:last-child {
padding-right: 0; padding-right: 0;
} }
header.primary nav ul li i.fa { .icon {
font-size: 1.4rem; display: inline-block;
padding: 0.2rem; 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; color: #e66b19;
} }
header.primary nav ul li.mastodon i.fa-mastodon { header.primary nav ul li.mastodon .icon {
color: #5e4fe5; color: #5e4fe5;
} }
header.primary nav ul li.github i.fa-github { header.primary nav ul li.github .icon {
color: #4183c4; color: #4183c4;
} }
@ -440,6 +449,11 @@ p.fin {
margin: 1rem 0; margin: 1rem 0;
} }
p.fin .icon {
width: 1.4rem;
height: 1.4rem;
}
blockquote { blockquote {
margin-left: 6%; margin-left: 6%;
font-family: "Helvetica Neue", "Verdana", "Roboto", sans-serif; font-family: "Helvetica Neue", "Verdana", "Roboto", sans-serif;

View file

@ -20,7 +20,7 @@ extension Node where Context == HTML.BodyContext {
.raw(post.body) .raw(post.body)
), ),
.div(.class("row clearfix"), .div(.class("row clearfix"),
.p(.class("fin"), .i(.class("fa fa-code"))) .p(.class("fin"), Icons.code())
) )
]) ])
} }

View file

@ -40,7 +40,7 @@ extension Node where Context == HTML.BodyContext {
), ),
.div(.class("row clearfix"), .div(.class("row clearfix"),
.p(.class("fin"), .i(.class("fa fa-code"))) .p(.class("fin"), Icons.code())
), ),
.group(context.scripts.map { url in .group(context.scripts.map { url in

View file

@ -23,7 +23,7 @@ extension Node where Context == HTML.BodyContext {
), ),
.div(.class("row clearfix"), .div(.class("row clearfix"),
.p(.class("fin"), .i(.class("fa fa-code"))) .p(.class("fin"), Icons.code())
) )
]) ])
} }

View file

@ -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<Context>() -> Node<Context> {
.raw(svg(className: "icon icon-mastodon", viewBox: "0 0 448 512", path: IconPath.mastodon))
}
static func github<Context>() -> Node<Context> {
.raw(svg(className: "icon icon-github", viewBox: "0 0 496 512", path: IconPath.github))
}
static func rss<Context>() -> Node<Context> {
.raw(svg(className: "icon icon-rss", viewBox: "0 0 448 512", path: IconPath.rss))
}
static func code<Context>() -> Node<Context> {
.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 {
"<svg class=\"\(className)\" viewBox=\"\(viewBox)\" aria-hidden=\"true\" focusable=\"false\"><path transform=\"translate(0,448) scale(1,-1)\" d=\"\(path)\"/></svg>"
}
}
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"
}

View file

@ -16,7 +16,7 @@ extension Node where Context == HTML.BodyContext {
.raw(bodyHTML) .raw(bodyHTML)
), ),
.div(.class("row clearfix"), .div(.class("row clearfix"),
.p(.class("fin"), .i(.class("fa fa-code"))) .p(.class("fin"), Icons.code())
) )
]) ])
} }

View file

@ -42,8 +42,6 @@ enum Template {
.meta(.name("msapplication-config"), .content(context.imageURL("browserconfig.xml").absoluteString)), .meta(.name("msapplication-config"), .content(context.imageURL("browserconfig.xml").absoluteString)),
.meta(.name("theme-color"), .content("#121212")), // matches header .meta(.name("theme-color"), .content("#121212")), // matches header
.meta(.name("viewport"), .content("width=device-width, initial-scale=1.0, viewport-fit=cover")), .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")), .link(.rel(.dnsPrefetch), .href("https://gist.github.com")),
.group(context.styles.map { url in .group(context.styles.map { url in
.link(.rel(.stylesheet), .type("text/css"), .href(url)) .link(.rel(.stylesheet), .type("text/css"), .href(url))
@ -62,9 +60,28 @@ enum Template {
), ),
.nav(.class("remote"), .nav(.class("remote"),
.ul( .ul(
.li(.class("mastodon"), .a(.attribute(named: "rel", value: "me"), .href("https://techhub.social/@sjs"), .i(.class("fab fa-mastodon")))), .li(.class("mastodon"),
.li(.class("github"), .a(.href("https://github.com/samsonjs"), .i(.class("fab fa-github")))), .a(
.li(.class("rss"), .a(.href(context.url(for: "feed.xml")), .i(.class("fa fa-rss")))) .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"), .nav(.class("local"),
@ -86,9 +103,7 @@ enum Template {
.group(context.scripts.map { script in .group(context.scripts.map { script in
.script(.attribute(named: "defer"), .src(script)) .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){}")
) )
) )
} }

View file

@ -56,7 +56,7 @@ public extension samhuri {
email: "sami@samhuri.net", email: "sami@samhuri.net",
url: siteURLOverride ?? URL(string: "https://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) .renderMarkdown(pageRenderer: renderer)
.plugin(projectsPlugin) .plugin(projectsPlugin)
.plugin(postsPlugin) .plugin(postsPlugin)