aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_config.yml2
-rw-r--r--_data/.gitignore1
-rw-r--r--_data/authors.yml15
-rw-r--r--_includes/head.html3
-rw-r--r--_includes/icon/home-round.svg1
-rw-r--r--_includes/icon/search-round.svg1
-rw-r--r--_includes/navbar.html14
-rw-r--r--_includes/opengraph.html4
-rw-r--r--_includes/tags.html6
-rw-r--r--_includes/title.html5
-rw-r--r--_layouts/default.html76
-rw-r--r--_plugins/authors.rb38
-rw-r--r--_plugins/tag-color.rb13
-rw-r--r--_plugins/toc.rb6
-rw-r--r--_sass/button.css22
-rw-r--r--_sass/card.css22
-rw-r--r--_sass/code.scss51
-rw-r--r--_sass/globals.css63
-rw-r--r--_sass/image.css16
-rw-r--r--_sass/layout.css144
-rw-r--r--_sass/layout.scss118
-rw-r--r--_sass/media.scss42
-rw-r--r--_sass/navbar.css196
-rw-r--r--_sass/print.css19
-rw-r--r--_sass/search.css65
-rw-r--r--_sass/separator.css8
-rw-r--r--_sass/tags.css45
-rw-r--r--_sass/theme.css110
-rw-r--r--_sass/theme.scss60
-rw-r--r--_sass/typography.scss9
-rwxr-xr-x_scripts/postinfo2
-rwxr-xr-x_scripts/repoinfo8
-rw-r--r--index.md39
-rw-r--r--makefile9
-rw-r--r--search.html30
-rw-r--r--style.scss13
36 files changed, 375 insertions, 901 deletions
diff --git a/_config.yml b/_config.yml
index 1c542f1..e805b30 100644
--- a/_config.yml
+++ b/_config.yml
@@ -16,11 +16,11 @@ defaults:
lang: en
toc: true
output: true
+ footer: true
markdown: kramdown
sass:
style: compressed
sourcemap: development
gems:
- jekyll-liquify
-nojs-search: https://google.com/search
diff --git a/_data/.gitignore b/_data/.gitignore
index 8b1e502..ef668c9 100644
--- a/_data/.gitignore
+++ b/_data/.gitignore
@@ -1 +1,2 @@
post
+meta.yml
diff --git a/_data/authors.yml b/_data/authors.yml
index 62cc535..286b392 100644
--- a/_data/authors.yml
+++ b/_data/authors.yml
@@ -1,8 +1,7 @@
-authors:
- - name: Loek
- git:
- - Loek Le Blansch
- - lonkaars
- - name: Willem
- git:
- - Willem Paternotte
+- name: Loek
+ git:
+ - Loek Le Blansch
+ - lonkaars
+- name: Willem
+ git:
+ - Willem Paternotte
diff --git a/_includes/head.html b/_includes/head.html
deleted file mode 100644
index ff907a0..0000000
--- a/_includes/head.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<meta charset="UTF-8">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="/style.css">
diff --git a/_includes/icon/home-round.svg b/_includes/icon/home-round.svg
deleted file mode 100644
index 57039b4..0000000
--- a/_includes/icon/home-round.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z"></path></svg>
diff --git a/_includes/icon/search-round.svg b/_includes/icon/search-round.svg
deleted file mode 100644
index e79a75c..0000000
--- a/_includes/icon/search-round.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15.5 14h-.79l-.28-.27c1.2-1.4 1.82-3.31 1.48-5.34-.47-2.78-2.79-5-5.59-5.34-4.23-.52-7.79 3.04-7.27 7.27.34 2.8 2.56 5.12 5.34 5.59 2.03.34 3.94-.28 5.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg>
diff --git a/_includes/navbar.html b/_includes/navbar.html
deleted file mode 100644
index 88092e7..0000000
--- a/_includes/navbar.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<div class="globalLinks">
- <a href="/" class="indentLevel0 link navbarItem {% if include.page == "index" %}active{% endif %}">
- <div class="inner">
- <div class="icon">{% include icon/home-round.svg %}</div>
- <span class="title">Home</span>
- </div>
- </a>
- <a href="/search" class="indentLevel0 link navbarItem {% if include.page == "search" %}active{% endif %}">
- <div class="inner">
- <div class="icon">{% include icon/search-round.svg %}</div>
- <span class="title">Search for posts</span>
- </div>
- </a>
-</div>
diff --git a/_includes/opengraph.html b/_includes/opengraph.html
deleted file mode 100644
index 7cb9517..0000000
--- a/_includes/opengraph.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<meta property='og:site_name' content='{{ page.date }}' />
-<meta property='og:title' content='{{ page.title }}' />
-<meta property='og:description' content='{{ page.subtitle }}' />
-<meta property="og:image" content='{{ page.cover }}' />
diff --git a/_includes/tags.html b/_includes/tags.html
deleted file mode 100644
index 8fc9383..0000000
--- a/_includes/tags.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<div class="tags">
- <span>Tags:</span>
- {%- for tag in include.tags -%}
- <a class="tag" href="/search?q={{ tag }}" style="--tag-hue: {{ tag | to_tag_color }};">{{ tag }}</a>
- {%- endfor -%}
-</div>
diff --git a/_includes/title.html b/_includes/title.html
deleted file mode 100644
index 08643ad..0000000
--- a/_includes/title.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% if page.id == "index" %}
-<title>{{ site.title }}</title>
-{% else %}
-<title>{{ page.title }} - {{ site.title }}</title>
-{% endif %}
diff --git a/_layouts/default.html b/_layouts/default.html
index a923692..46cf1e9 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,27 +1,65 @@
<!DOCTYPE html>
-<html lang='{{ page.lang }}'>
+<html lang="{{ page.lang }}">
<head>
- {% include head.html %}
- {% include title.html %}
- {% include opengraph.html %}
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="/style.css">
+ <meta property='og:site_name' content='{{ page.date }}' />
+ <meta property='og:title' content='{{ page.title }}' />
+ <meta property='og:description' content='{{ page.subtitle }}' />
+ {% if page.id == "index" %}
+ <title>{{ site.title }}</title>
+ {% else %}
+ <title>{{ page.title }} - {{ site.title }}</title>
+ {% endif %}
</head>
<body>
- <div class='centeredPage'>
- <div class='titleWrapper'>
- <h1>{{ page.title }}</h1>
- {% if page.subtitle %}<p class='subtile'>{{ page.subtitle }}</p>{% endif %}
- {% if page.tags %}{% include tags.html tags=page.tags %}{% endif %}
+ <header class="invert plainlink">
+ <div class="limitwidth">
+ <span class="title">{{ page.title | smartify }}</span>
</div>
- <div class='navAreaWrapper'>
- <div class='sticky'>
- {% include navbar.html page=page.id %}
- {% if page.toc %}{% toc %}{% endif %}
- </div>
- </div>
- <!-- <MobileNavbar /> -->
- <div class='contentWrapper'>
- {{ content }}
+ </header>
+ <nav class="invert plainlink">
+ <div class="limitwidth">
+ <a href="/" class="item {% if page.id == "index" %}active{% endif %}">home</a>
+ <a href="/posts" class="item {% if page.id == "posts" %}active{% endif %}">posts</a>
+ <span class="right">
+ {% if page.toc %}<a href="#" class="item">top</a>{% endif %}
+ {% if page.footer %}<a href="#footer" class="item">bottom</a>{% endif %}
+ </span>
</div>
- </div>
+ </nav>
+ <article class="limitwidth content">
+ {% if page.toc %}{% toc %}{% endif %}
+ {{ content }}
+ </article>
+ {% if page.footer %}
+ {% assign post_meta = site.data.post[page.slug] %}
+ {% assign site_meta = site.data.meta %}
+ <footer id="footer" class="invert plainlink">
+ <div class="limitwidth">
+ <div class="autocolumn">
+ <div class="column">
+ <span class="title">about this post</span>
+ <ul>
+ <li>written by {% fmt_authors site.data.authors post_meta.authors %}</li>
+ <li>published on {{ post_meta.date }}</li>
+ </ul>
+ <ul>
+ <li>edited {{ post_meta.edits }} times</li>
+ <li>first published on {{ post_meta.date_initial }}</li>
+ </ul>
+ </div>
+ <div class="column">
+ <a href="/" class="title">{{ site.domain }}</a>
+ <ul>
+ <li>version <code>{{ site_meta.slug }}</code> (<a href="https://git.pipeframe.xyz/lonkaars/blog">git</a>)</li>
+ <li>built {{ site_meta.build_date }}</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </footer>
+ {% endif %}
</body>
</html>
diff --git a/_plugins/authors.rb b/_plugins/authors.rb
new file mode 100644
index 0000000..a2e0a53
--- /dev/null
+++ b/_plugins/authors.rb
@@ -0,0 +1,38 @@
+require 'set'
+
+module Jekyll
+ class FormatAuthors < Liquid::Tag
+ def initialize(tag_name, input, tokens)
+ super
+ @args = input.split(" ").map { |arg| arg.strip() }
+ end
+
+ def transform_authors(author_meta, git_authors)
+ authors = Set[]
+ for substitute in author_meta do
+ for name in substitute['git'] do
+ if git_authors.include?(name)
+ authors.add(substitute['name'])
+ end
+ end
+ end
+ return authors.to_a()
+ end
+
+ def join_names(authors)
+ return "nobody?" if authors.length == 0
+ return "#{authors[0]}" if authors.length == 1
+ return "#{authors[0..-2].join(", ")} and #{authors[-1]}"
+ end
+
+ def render(context)
+ author_meta = context[@args[0]]
+ git_authors = context[@args[1]]
+ authors = transform_authors(author_meta, git_authors)
+ return join_names(authors)
+ end
+ end
+end
+
+Liquid::Template.register_tag('fmt_authors', Jekyll::FormatAuthors)
+
diff --git a/_plugins/tag-color.rb b/_plugins/tag-color.rb
deleted file mode 100644
index 9f119fb..0000000
--- a/_plugins/tag-color.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module TagColor
- def to_tag_color(str)
- sum = 0
- str.chars.each do |i|
- sum += ?i.ord
- sum %= 360
- end
- sum
- end
-end
-
-Liquid::Template.register_filter(TagColor)
-
diff --git a/_plugins/toc.rb b/_plugins/toc.rb
index 3c4f836..80acc82 100644
--- a/_plugins/toc.rb
+++ b/_plugins/toc.rb
@@ -9,7 +9,9 @@ module Jekyll
# enumerate over all h1-4 headings
@els = doc.css("h1, h2, h3, h4")
- return '<div class="chapterChildren">%s</div>' % [ output_toc ]
+ toc = output_toc()
+ return '' if toc.empty?
+ return '<aside id="toc" class="plainlink">%s</aside>' % [ toc ]
end
def output_toc
@@ -29,7 +31,7 @@ module Jekyll
if level >= level_next
output += '<li>'
else
- output += '<li class="stub"><details open>'
+ output += '<li class="stub"><details>'
output += '<summary>'
end
diff --git a/_sass/button.css b/_sass/button.css
deleted file mode 100644
index 9efe41f..0000000
--- a/_sass/button.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.button {
- padding: 12px;
- min-width: 200px;
- text-align: center;
- width: min-content;
-
- display: block !important;
- margin: 0 auto var(--page-margins) auto;
-
- font-size: 1rem;
- font-family: "Inter", sans-serif;
- font-weight: 600;
-
- border-radius: 8px;
- border: 0;
-
- cursor: pointer;
-}
-
-a.button { min-width: calc(200px - 2 * 12px); }
-a.button::after { display: none; }
-
diff --git a/_sass/card.css b/_sass/card.css
deleted file mode 100644
index 58037b5..0000000
--- a/_sass/card.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.postCard {
- background-color: var(--bg-alt);
- padding: 12px;
- border-radius: 8px;
-
- overflow-x: hidden;
-}
-
-.postCard a { color: var(--fg) !important; }
-.postCard a::after { display: none; }
-
-.postCard .cover {
- width: 100%;
- border-radius: 6px;
- max-height: 220px;
- object-fit: cover;
- margin-bottom: 6px;
-}
-
-.postCard .title { font-size: 24px; }
-.postCard .subtitle { font-weight: 500; }
-
diff --git a/_sass/code.scss b/_sass/code.scss
index 331b5bd..abec864 100644
--- a/_sass/code.scss
+++ b/_sass/code.scss
@@ -1,11 +1,5 @@
-pre {
- background-color: var(--bg-alt);
- border-radius: 6px;
- padding: 6px;
-}
-
pre.highlight {
- code { color: var(--magnolia); }
+ code { color: var(--code); }
// https://github.com/rouge-ruby/rouge/wiki/List-of-tokens
@each $c in c,cm,cp,c1,cs { .#{$c} { @extend %token_comment } }
@each $c in k,kc,kd,kn,kp,kr,kt { .#{$c} { @extend %token_keyword } }
@@ -14,39 +8,14 @@ pre.highlight {
@each $c in o,ow { .#{$c} { @extend %token_operator } }
}
-%token_comment
-{ font-style: italic; }
-
-%token_keyword
-{ font-weight: 700; }
-
-%token_string,
-%token_number
-{ color: var(--fg); }
-
-%token_comment {
- color: var(--heliotrope-gray);
- opacity: .7;
-}
-
-%token_keyword
-{ color: var(--fire-opal); }
-
-%token_operator
-{ opacity: .8; }
-
-@media (prefers-color-scheme: light) {
- pre { background-color: var(--heliotrope-gray); }
+%token_comment { font-style: italic; }
+%token_keyword { font-weight: 700; }
+%token_comment { opacity: .7; }
+%token_operator { opacity: .8; }
- pre.highlight code { color: var(--fg); }
-
- %token_string,
- %token_number
- { opacity: .8; }
-
- %token_comment {
- color: var(--oxford-blue);
- opacity: .5;
- }
-}
+%token_comment { color: var(--code-comment); }
+%token_keyword { color: var(--code-keyword); }
+%token_string { color: var(--code-string); }
+%token_number { color: var(--code-number); }
+%token_operator { color: var(--code-operator); }
diff --git a/_sass/globals.css b/_sass/globals.css
deleted file mode 100644
index 769153e..0000000
--- a/_sass/globals.css
+++ /dev/null
@@ -1,63 +0,0 @@
-html, body {
- padding: 0;
- margin: 0;
-
- background-color: var(--bg);
- color: var(--fg);
-
- hyphens: auto;
-}
-
-.block { display: block; }
-
-.contentWrapper a.nolink {
- color: unset;
-}
-
-.contentWrapper a:not(.nolink) {
- color: var(--links);
- position: relative;
- display: inline-block;
-}
-
-.contentWrapper a {
- text-decoration: none;
-}
-
-.contentWrapper a:not(.nolink)::after {
- content: '';
- position: absolute;
- left: 0;
- bottom: 0;
- height: 1px;
- width: 0%;
- transition: width;
- transition-duration: 150ms;
- background-color: var(--links);
-}
-
-.contentWrapper a:hover::after {
- width: 100%;
-}
-
-::-webkit-scrollbar {
- width: 12px;
- height: 12px;
-}
-
-::-webkit-scrollbar-thumb {
- border-radius: 6px;
- border: 4px solid var(--bg);
-}
-
-:focus { outline: none; }
-
-li {
- margin-bottom: 6px;
-}
-
-.icon svg {
- width: 24px;
- height: 24px;
- fill: currentColor;
-}
diff --git a/_sass/image.css b/_sass/image.css
deleted file mode 100644
index f1d48bb..0000000
--- a/_sass/image.css
+++ /dev/null
@@ -1,16 +0,0 @@
-img, figure {
- display: block;
- margin: 0 auto var(--page-margins) auto;
- max-width: 500px;
-}
-
-img {
- position: relative;
- overflow: visible;
-}
-
-figure {
- opacity: .8;
- font-style: italic;
-}
-
diff --git a/_sass/layout.css b/_sass/layout.css
deleted file mode 100644
index c459e8e..0000000
--- a/_sass/layout.css
+++ /dev/null
@@ -1,144 +0,0 @@
-:root {
- --collapse-horizontal-gap: 0;
- --nav-width: calc(200px * (1 - var(--collapse-horizontal-gap))) !important;
- --page-width: 700px;
- --page-margins: 24px;
-}
-
-.centeredPage {
- transition-property: gap, max-width;
- transition-duration: 500ms;
-
- max-width: calc(var(--nav-width) + var(--page-width) + var(--page-margins));
- margin: 0 auto;
- margin-top: 96px;
- padding: 0 var(--page-margins);
-
- display: grid;
- grid-auto-rows: auto;
- grid-auto-columns: auto 1fr;
-
- gap: var(--page-margins) calc((1 - var(--collapse-horizontal-gap)) * var(--page-margins));
-}
-
-.titleWrapper {
- grid-column: 2;
- grid-row: 1;
-}
-.titleWrapper > * {
- margin: 0;
- word-break: break-word;
-}
-
-.navAreaWrapper {
- grid-column: 1;
- grid-row: 2;
-
- transition-property: width;
- transition-duration: 500ms;
- width: var(--nav-width);
-}
-.navAreaWrapper > .sticky {
- position: sticky;
- top: var(--page-margins);
- bottom: var(--page-margins);
- max-height: calc(100vh - 2 * var(--page-margins));
-
- overflow-y: scroll;
- overflow-x: hidden;
-
- border-radius: 8px;
-}
-
-.contentWrapper {
- grid-column: 2;
- grid-row: 2;
-
- overflow-x: hidden;
-}
-
-.contentWrapper :first-child {
- margin-top: 0;
-}
-
-.contentWrapper p {
- text-align: justify;
-}
-
-.contentWrapper table,
-.contentWrapper code,
-.contentWrapper pre {
- overflow-x: scroll;
-}
-
-.recentPosts {
- display: grid;
- grid-gap: 12px;
- grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );
-}
-
-.mobileNav {
- display: none;
-}
-
-@media screen and (max-device-width: 550px) {
- .centeredPage {
- grid-template-columns: 0 1fr;
- gap: var(--page-margins) 0;
- padding: 0 12px;
- }
-
- .navAreaWrapper {
- grid-column: none;
- grid-row: none;
-
- width: 100vw;
-
- position: fixed;
- inset: 0px 0px 0px 0px;
-
- z-index: 2;
-
- transition-property: opacity;
- transition-duration: .1s;
-
- opacity: 0;
- pointer-events: none;
- backdrop-filter: blur(50px);
- }
-
- .navAreaWrapper:before {
- content: '';
- position: absolute;
- inset: 0px 0px 0px 0px;
-
- background-color: var(--bg-alt);
- opacity: .7;
- }
-
- .navAreaWrapper.navVisible {
- pointer-events: initial;
- opacity: 1;
- }
-
- .navAreaWrapper .globalLinks {
- display: none;
- }
-
- .navAreaWrapper > .sticky {
- position: absolute;
- inset: 0px 0px 0px 0px;
-
- padding: 24px;
- overflow-y: scroll;
- }
-
- .mobileNav {
- display: inline-block;
- position: fixed;
- bottom: 24px;
- right: 24px;
- z-index: 5;
- }
-}
-
diff --git a/_sass/layout.scss b/_sass/layout.scss
new file mode 100644
index 0000000..d699ee1
--- /dev/null
+++ b/_sass/layout.scss
@@ -0,0 +1,118 @@
+html, body {
+ padding: 0;
+ margin: 0;
+}
+
+.limitwidth {
+ max-width: 650px;
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 12px;
+ padding-right: 12px;
+}
+
+nav {
+ position: sticky;
+ z-index: 2; // above toc
+
+ top: 0;
+ left: 0;
+ right: 0;
+
+ line-height: 20px;
+}
+
+article {
+ margin-top: 24px;
+ margin-bottom: 24px;
+}
+
+nav a {
+ display: inline-block;
+ padding: 2px 8px;
+}
+
+nav .right { float: right; }
+
+header, footer { padding: 8px 0px; }
+
+img, figcaption {
+ display: block;
+ max-width: 80%;
+ margin: 0 auto;
+}
+
+// table of contents
+aside {
+ // make sure mouse events work on toc even if content is behind toc
+ position: relative;
+ z-index: 1;
+
+ float: right;
+ width: 40%;
+
+ margin-left: 12px;
+ margin-bottom: 6px;
+ padding: 6px 0px;
+}
+
+aside ul {
+ padding-left: 16px;
+ margin: 0;
+ // list-style-position: inside;
+ list-style-type: square;
+}
+
+// indent first level
+aside > ul { margin-left: 12px; }
+
+// align description arrow with list bullet inside toc
+aside summary { list-style-position: outside; }
+
+// hide bullets for list items that can be expanded
+li.stub::marker { content: ""; }
+
+// give collapsable element arrow "clickable" cursor
+summary::marker { cursor: pointer; }
+
+blockquote {
+ position: relative;
+ padding-left: 12px;
+}
+
+blockquote, figure {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+pre {
+ overflow-x: auto;
+ border-radius: 6px;
+ padding: 6px 8px;
+}
+
+figure figcaption {
+ margin-top: 6px;
+}
+
+// fix anchor scroll offset
+h1, h2, h3, h4, h5, h6 { scroll-margin-top: 40px; }
+
+footer ul {
+ list-style: none;
+ padding: 0;
+}
+
+.autocolumn {
+ display: flex;
+ gap: 24px;
+ justify-content: flex-start;
+ flex-direction: row;
+ flex-wrap: wrap;
+}
+.autocolumn .column {
+ min-width: 250px;
+ flex-grow: 1;
+}
+
+
diff --git a/_sass/media.scss b/_sass/media.scss
new file mode 100644
index 0000000..2b4fc8b
--- /dev/null
+++ b/_sass/media.scss
@@ -0,0 +1,42 @@
+// no floating toc when screen too narrow
+@media only screen and (max-width: 450px) {
+ aside {
+ float: none;
+ width: unset;
+
+ border-left: none;
+ border-bottom: 1px dashed;
+ margin-left: 0px;
+ }
+}
+
+@media only screen and (prefers-color-scheme: dark) {
+ :root, html {
+ background-color: black;
+ color: white;
+ }
+ .invert {
+ background-color: #222;
+ color: inherit;
+ }
+ nav .item.active {
+ color: inherit;
+ background-color: black;
+ text-decoration: underline;
+ font-weight: bold;
+ }
+ a { color: #9aa9f9; }
+ a:visited { color: #bb87f2; }
+}
+
+@media print {
+ nav { display: none; }
+
+ .invert {
+ background-color: unset;
+ color: unset;
+ }
+
+ .limitwidth { max-width: 35em; }
+}
+
diff --git a/_sass/navbar.css b/_sass/navbar.css
deleted file mode 100644
index 10933a0..0000000
--- a/_sass/navbar.css
+++ /dev/null
@@ -1,196 +0,0 @@
-.navbarItem .inner {
- background-color: var(--bg-alt);
- color: var(--fg);
-
- padding: 8px;
- border-radius: 8px;
-
- transition-property: background-color, color;
- transition-duration: .15s;
-
- position: relative;
-
- display: flex;
- gap: 8px;
- align-items: center;
-}
-
-.navbarItem {
- text-decoration: none;
- display: block;
-}
-
-.navbarItem .icon { display: inline-block; }
-
-.navbarItem.indentLevel0 { margin-bottom: 12px; }
-
-.navbarItem.active .inner,
-.navbarItem.link:hover .inner {
- background-color: var(--fg-alt);
- color: var(--bg-alt);
-}
-
-.navbarItem.chapter .inner,
-.navbarItem.pinned .inner {
- background-color: transparent;
- color: var(--fg);
-
- padding: 4px 0;
- overflow: visible;
-}
-
-.navbarItem.pinned .inner .title {
- margin: 0;
- font-style: italic;
- opacity: .8;
- color: var(--fg-alt)
-}
-.navbarItem.pinned * { cursor: default !important; }
-
-.navbarItem .title {
- display: inline-block;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
-}
-.navbarItem.chapter .title { margin-top: 1px; }
-
-.navbarItem.chapter .chapterChildren {
- transition-property: height;
- transition-duration: .3s;
-
- overflow: hidden;
-}
-
-.navbarItem.chapter.childrenCollapsed > .chapterChildren { height: 0; }
-.navbarItem.chapter > .chapterChildren { height: var(--children-height); }
-
-.navbarItem .inner,
-.navbarItem .icon,
-.navbarItem .icon .collapseIcon {
- height: 24px;
-}
-
-.navbarItem > div > svg { vertical-align: super; }
-
-@media (prefers-color-scheme: light) {
- .navbarItem.active .inner,
- .navbarItem.link:hover .inner {
- background-color: var(--fg);
- }
-
- .navbarItem.pinned .inner .title {
- opacity: .6;
- color: var(--fg-alt);
- }
-}
-
-.mobileNav {
- width: 48px;
- text-align: center;
- line-height: 0;
-}
-
-.mobileNav .button:last-child {
- margin-bottom: 0;
-}
-
-.mobileNav .button {
- padding: 12px;
- display: inline-block !important;
- min-width: 0;
- border-radius: 24px;
- margin: 0;
- box-shadow: 0 4px 10px -2px rgba(0, 0, 0, 25%);
-
- width: 24px;
- height: 24px;
- position: relative;
-}
-
-.mobileNav .button > svg {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- fill: currentColor !important;
-}
-
-.mobileNav .button.small {
- padding: 6px;
- margin-bottom: 12px;
-
- opacity: 0;
- transition: opacity .3s;
-}
-
-.mobileNav.open .button.small {
- opacity: 1;
-}
-
-.chapterChildren > ul { padding-left: 0 !important; }
-.chapterChildren ul { padding-left: 12px; }
-
-.chapterChildren li,
-.chapterChildren summary {
- margin: 4px 0;
-}
-
-.chapterChildren ul,
-.chapterChildren summary {
- list-style: none;
-}
-
-.chapterChildren li,
-.chapterChildren summary {
- min-height: 24px;
- padding-left: 32px;
- position: relative;
- display: flex;
- align-items: center;
-}
-
-.chapterChildren li.stub {
- padding-left: 0;
- margin: 0;
-}
-.chapterChildren li.stub::before {
- display: none;
-}
-
-.chapterChildren summary {
- cursor: pointer;
-}
-
-.chapterChildren li::before,
-.chapterChildren summary::before {
- content: "";
- position: absolute;
- width: 24px;
- height: 24px;
- left: 0;
- top: 0;
- background-color: var(--fg);
-}
-
-.chapterChildren details > summary::before {
- transform: rotate(-90deg);
- transition-property: transform;
- transition-duration: .3s;
-}
-.chapterChildren details[open] > summary::before {
- transform: rotate(0deg);
-}
-
-.chapterChildren details summary::before {
- clip-path: path('M8.12 9.29L12 13.17l3.88-3.88c.39-.39 1.02-.39 1.41 0 .39.39.39 1.02 0 1.41l-4.59 4.59c-.39.39-1.02.39-1.41 0L6.7 10.7a.9959.9959 0 010-1.41c.39-.38 1.03-.39 1.42 0z');
-}
-.chapterChildren li::before {
- clip-path: path('M18 13H6c-.55 0-1-.45-1-1s.45-1 1-1h12c.55 0 1 .45 1 1s-.45 1-1 1z');
-}
-
-.chapterChildren a {
- color: var(--fg);
- text-decoration: none;
- user-select: none;
-}
diff --git a/_sass/print.css b/_sass/print.css
deleted file mode 100644
index 4867c83..0000000
--- a/_sass/print.css
+++ /dev/null
@@ -1,19 +0,0 @@
-@media print {
- :root {
- --nav-width: 0px;
-
- --bg: #ffffff;
- --fg: #000000;
-
- --heliotrope-gray: var(--bg);
- --purple-navy: #989abb;
-
- --fire-opal: #ba3321;
- --cyan-process: #397889;
- --forest-green-crayola: #376848;
-
- }
-
- .centeredPage { grid-gap: var(--page-margins) 0; }
- pre { border: solid 2px var(--fg); }
-}
diff --git a/_sass/search.css b/_sass/search.css
deleted file mode 100644
index d46c80f..0000000
--- a/_sass/search.css
+++ /dev/null
@@ -1,65 +0,0 @@
-.searchBar {
- background-color: var(--fg-alt);
- border-radius: 8px;
- padding: 12px;
- margin-bottom: 24px;
-
- display: flex;
-}
-
-.searchBar .input {
- background-color: transparent;
- border: 0;
-
- color: var(--bg);
-
- margin-left: 12px;
- flex-grow: 1;
-}
-
-.searchBar .input::placeholder {
- font-style: italic;
- opacity: .75;
-
- color: var(--bg);
-}
-
-.searchBar .button {
- margin: 0;
- line-height: 0;
- min-width: unset;
- background-color: var(--bg);
- color: var(--fg-alt) !important;
-}
-
-.searchResults .post::after {
- display: none;
-}
-
-.searchResults .post {
- display: block;
- border-radius: 8px;
-
- padding: 12px;
- margin-bottom: 12px;
- background-color: var(--bg-alt);
-
- color: var(--fg);
-}
-
-.searchResults .post .title,
-.searchResults .post .subtitle,
-.searchResults .post .authordate {
- margin: 4px 0;
-}
-
-.searchResults .post .authordate {
- font-style: italic;
- opacity: .75;
-}
-
-@media (prefers-color-scheme: light) {
- .searchBar { background-color: var(--fg); }
- .searchBar .button { color: var(--fg) !important; }
-}
-
diff --git a/_sass/separator.css b/_sass/separator.css
deleted file mode 100644
index 24ee769..0000000
--- a/_sass/separator.css
+++ /dev/null
@@ -1,8 +0,0 @@
-hr {
- display: block;
- height: 12px;
- margin-bottom: var(--page-margins);
- background-color: var(--fire-opal);
- border: none;
- clip-path: path('M8.04282 8.19986C6.51226 9.73171 4.24587 12 0 12V6C1.68094 6 2.4102 5.34716 3.87868 3.87868C3.90463 3.85273 3.9308 3.82654 3.95718 3.80014C5.48774 2.26829 7.75413 0 12 0C16.2459 0 18.5123 2.26829 20.0428 3.80014C20.0692 3.82654 20.0954 3.85273 20.1213 3.87868C21.5898 5.34716 22.3191 6 24 6C25.6809 6 26.4102 5.34716 27.8787 3.87868C27.9046 3.85273 27.9308 3.82654 27.9572 3.80014C29.4877 2.26829 31.7541 0 36 0C40.2459 0 42.5123 2.26829 44.0428 3.80014C44.0692 3.82654 44.0954 3.85273 44.1213 3.87868C45.5898 5.34716 46.3191 6 48 6C49.6809 6 50.4102 5.34716 51.8787 3.87868C51.9046 3.85273 51.9308 3.82654 51.9572 3.80014C53.4877 2.26829 55.7541 0 60 0C64.2459 0 66.5123 2.26829 68.0428 3.80014C68.0692 3.82654 68.0954 3.85273 68.1213 3.87868C69.5898 5.34716 70.3191 6 72 6C73.6809 6 74.4102 5.34716 75.8787 3.87868L75.9572 3.80014C77.4877 2.26829 79.7541 0 84 0C88.2459 0 90.5123 2.26829 92.0428 3.80014L92.1213 3.87868C93.5898 5.34716 94.3191 6 96 6V12C91.7541 12 89.4877 9.73171 87.9572 8.19986L87.8787 8.12132C86.4102 6.65284 85.6809 6 84 6C82.3191 6 81.5898 6.65284 80.1213 8.12132L80.0428 8.19986C78.5123 9.73171 76.2459 12 72 12C67.7541 12 65.4877 9.73171 63.9572 8.19986C63.9308 8.17346 63.9046 8.14727 63.8787 8.12132C62.4102 6.65284 61.6809 6 60 6C58.3191 6 57.5898 6.65284 56.1213 8.12132C56.0954 8.14727 56.0692 8.17346 56.0428 8.19986C54.5123 9.73171 52.2459 12 48 12C43.7541 12 41.4877 9.73171 39.9572 8.19986C39.9308 8.17346 39.9046 8.14727 39.8787 8.12132C38.4102 6.65284 37.6809 6 36 6C34.3191 6 33.5898 6.65284 32.1213 8.12132C32.0954 8.14727 32.0692 8.17346 32.0428 8.19986C30.5123 9.73171 28.2459 12 24 12C19.7541 12 17.4877 9.73171 15.9572 8.19986C15.9308 8.17346 15.9046 8.14727 15.8787 8.12132C14.4102 6.65284 13.6809 6 12 6C10.3191 6 9.5898 6.65284 8.12132 8.12132C8.09537 8.14727 8.0692 8.17346 8.04282 8.19986Z');
-}
diff --git a/_sass/tags.css b/_sass/tags.css
deleted file mode 100644
index 8e8e242..0000000
--- a/_sass/tags.css
+++ /dev/null
@@ -1,45 +0,0 @@
-.tags {
- margin-top: 12px;
-}
-
-.tags .tag {
- --tag-color: hsl(var(--tag-hue), 75%, 70%);
-
- padding: 4px 12px;
- border-radius: 999px;
-
- text-decoration: none;
- color: var(--fg) !important;
-
- box-shadow: inset 0 0 0 2px var(--tag-color);
-
- position: relative;
- z-index: 1;
-
- margin-top: 6px;
- display: inline-block;
-}
-
-@media (prefers-color-scheme: light) {
- .tags .tag {
- --tag-color: hsl(var(--tag-hue), 50%, 40%);
- }
-}
-
-.tags .tag::after { display: none; }
-
-.tags .tag::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: -1;
-
- border-radius: 999px;
- background-color: var(--tag-color);
- opacity: .25;
-}
-
-.tags > * { margin-right: 6px; }
diff --git a/_sass/theme.css b/_sass/theme.css
deleted file mode 100644
index c3a8dee..0000000
--- a/_sass/theme.css
+++ /dev/null
@@ -1,110 +0,0 @@
-:root {
- --almond: #F4DEC9;
- --heliotrope-gray: #A69CAC;
- --purple-navy: #474973;
- --oxford-blue: #161B33;
- --xiketic: #0D0C1A;
- --magnolia: #EFE9F4;
-
- --fire-opal: #EE6352;
- --cyan-process: #08B2E3;
- --forest-green-crayola: #57A773;
-
- --bg: var(--xiketic);
- --fg: var(--almond);
-
- --bg-alt: var(--oxford-blue);
- --fg-alt: var(--heliotrope-gray);
- --links: var(--fire-opal);
-}
-
-html,
-.searchBar .input {
- font-family: "Inter", sans-serif;
- font-size: 16px;
-}
-
-code, pre {
- font-family: "JetBrainsMono", monospace;
- font-size: 12px;
-}
-
-.subtile {
- font-style: italic;
- opacity: .75;
- color: var(--heliotrope-gray);
-}
-
-h1, h2, h3 {
- font-weight: 700;
- margin: 0;
-}
-
-h1 { font-size: 64px; }
-h2 { font-size: 48px; }
-h3 { font-size: 32px; }
-
-::-webkit-scrollbar-track { background-color: var(--bg); }
-::-webkit-scrollbar-thumb { background-color: var(--purple-navy); }
-::-webkit-scrollbar-thumb:hover { background-color: var(--fg); }
-
-.button {
- background-color: var(--fire-opal);
- color: var(--fg) !important;
-}
-
-::selection {
- background-color: var(--fire-opal);
-}
-
-blockquote {
- position: relative;
- padding-left: 12px;
- font-style: italic;
- color: var(--fg-alt);
-}
-
-blockquote:before {
- position: absolute;
- content: '';
- top: 0;
- bottom: 0;
- left: 0;
- width: 3px;
- background-color: var(--cyan-process);
-}
-
-.mobileNav .button {
- background-color: var(--fire-opal);
- color: var(--fg);
-}
-
-.mobileNav .button.small {
- background-color: var(--fg-alt);
- color: var(--bg) !important;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- --heliotrope-gray: #dbdbe6;
- --purple-navy: #989abb;
-
- --fire-opal: #ba3321;
- --cyan-process: #397889;
- --forest-green-crayola: #376848;
-
- --bg: var(--magnolia);
- --fg: var(--xiketic);
- --bg-alt: var(--heliotrope-gray);
- --fg-alt: var(--oxford-blue);
- }
-
- .subtile {
- opacity: .6;
- color: var(--fg);
- }
-
- blockquote { opacity: .8; }
- .button { color: var(--bg) !important; }
-}
-
diff --git a/_sass/theme.scss b/_sass/theme.scss
new file mode 100644
index 0000000..f3fd683
--- /dev/null
+++ b/_sass/theme.scss
@@ -0,0 +1,60 @@
+html {
+ font-family: "Inter", sans-serif;
+ font-size: 10pt;
+ font-feature-settings: "ss07", "ss08";
+}
+
+code {
+ font-family: "JetBrainsMono", monospace;
+ font-size: 9pt;
+}
+
+blockquote {
+ font-style: italic;
+ opacity: .8;
+}
+blockquote::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ width: 2px;
+ background-color: currentcolor;
+}
+
+// navbar colors
+.invert {
+ background-color: black;
+ color: white;
+}
+nav a.active {
+ color: canvastext;
+ background-color: canvas;
+}
+
+// only show underline when hovering link
+a { text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+// separator style
+hr {
+ display: block;
+ border: none;
+ border-top: 1px dashed;
+}
+
+aside { border-left: 1px dashed; }
+
+pre { border: 1px solid; }
+
+.title { font-size: 150%; }
+
+.plainlink a,
+.plainlink a:visited { color: inherit; }
+
+nav .right a {
+ opacity: .75;
+ font-style: italic;
+}
+
diff --git a/_sass/typography.scss b/_sass/typography.scss
new file mode 100644
index 0000000..836c9da
--- /dev/null
+++ b/_sass/typography.scss
@@ -0,0 +1,9 @@
+html {
+ hyphens: auto;
+ tab-size: 2;
+}
+
+h1, h2, h3, h4, h5, h6,
+aside,
+header { text-wrap: balance; }
+
diff --git a/_scripts/postinfo b/_scripts/postinfo
index 95fe872..f31b145 100755
--- a/_scripts/postinfo
+++ b/_scripts/postinfo
@@ -1,4 +1,6 @@
#!/bin/sh
+export LANG=C
+
file="$1"
tab="$(printf '\t')"
diff --git a/_scripts/repoinfo b/_scripts/repoinfo
new file mode 100755
index 0000000..b413e6e
--- /dev/null
+++ b/_scripts/repoinfo
@@ -0,0 +1,8 @@
+#!/bin/sh
+export LANG=C
+cat << EOF
+commit: $(git rev-parse HEAD)
+slug: $(git describe --always --dirty='*' --abbrev)
+build_date: $(date -Idate)
+EOF
+
diff --git a/index.md b/index.md
index e1758b9..aa7f218 100644
--- a/index.md
+++ b/index.md
@@ -1,43 +1,18 @@
---
-title: Loek's excruciatingly interesting blog
+title: blog.pipeframe.xyz
layout: default
id: index
toc: false
+footer: false
---
-Welcome to my blog page! This is where I post updates on things that I do such
-as:
+Welcome to my blog! If I ever feel like writing something there's a good chance
+it'll be posted here. As common with programmers, I have a serious
+[bikeshedding](https://en.wiktionary.org/wiki/bikeshedding) problem, so beware
+of any outdated posts or references to unfinished projects.
-- Cool open source software that I think you should use
-- How to set up self-hosted applications
-- Rants about Microsoft Windows
-- Maybe some recipes I dunno
-
-The page you're looking at right now is also open-source! The code for this
-page can be found on [GitHub](https://github.com/lonkaars/blog), and should
-also be available on [my private git server](https://git.pipeframe.xyz).
-
-An rss/atom feed of this blog is also available:
+RSS/atom:
```
https://{{ site.domain }}/atom.xml
```
----
-
-## Recent posts
-
-<div class="recentPosts">
- {% for post in site.items limit:4 %}
- <div class="postCard">
- <a href="{{ post.url }}" class="nolink block">
- <img src="{{ post.cover }}" alt="post cover" class="cover">
- <h2 class="title">{{ post.title }}</h2>
- <strong class="subtitle">{{ post.subtitle }}</strong>
- </a>
- {% include tags.html tags=post.tags %}
- </div>
- {% endfor %}
-</div>
-
-[Go to all posts](/search){:.button}
-
diff --git a/makefile b/makefile
index 95b7666..77c6e51 100644
--- a/makefile
+++ b/makefile
@@ -14,8 +14,11 @@ GEMS = Gemfile.lock
POSTS := $(wildcard _items/*)
POST_META := $(patsubst _items/%.md,_data/post/%.yml,$(POSTS))
+REPO_META := _data/meta.yml
-build: $(GEMS) $(POST_META) FORCE
+META := $(POST_META) $(REPO_META)
+
+build: $(GEMS) $(META) FORCE
bundle exec jekyll build $(JEKYLL_BUILD_ARGS)
$(GEMS): Gemfile
@@ -25,6 +28,10 @@ _data/post/%.yml: _items/%.md
@mkdir -p _data/post
_scripts/postinfo $< > $@
+$(REPO_META):
+ @mkdir -p _data/post
+ _scripts/repoinfo > $@
+
clean: FORCE
$(RM) -r $(WEBROOT)
diff --git a/search.html b/search.html
deleted file mode 100644
index 026a20c..0000000
--- a/search.html
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: Search for posts
-layout: default
-id: search
-toc: false
----
-
-<form class="searchBar" method="get" action="{{ site.nojs-search }}">
- <input type="text" class="input" id="searchInput" name="q" placeholder="Search for posts..." spellcheck="false" autocomplete="off">
- <input type="hidden" name="q" value="site:{{ site.domain }}">
- <button class="button">
- <div class="icon">{% include icon/search-round.svg %}</div>
- </button>
-</form>
-
-<div class="searchResults">
- {% for post in site.items %}
- <div class="post">
- <a href="{{ post.url }}" class="nolink block">
- <b class="title">{{ post.title }}</b>
- <p class="subtitle">{{ post.subtitle }}</p>
- <p class="authordate">???</p>
- <input class="keywords" type="hidden" value=""/>
- </a>
- {% include tags.html tags=post.tags %}
- </div>
- {% endfor %}
-</div>
-
-
diff --git a/style.scss b/style.scss
index ce9d442..56b6c17 100644
--- a/style.scss
+++ b/style.scss
@@ -2,15 +2,8 @@
---
@import "theme";
-@import "globals";
@import "layout";
-
-@import "button";
-@import "card";
+@import "typography";
@import "code";
-@import "image";
-@import "navbar";
-@import "print";
-@import "search";
-@import "tags";
-@import "separator";
+@import "media";
+