Merge ; commit '99b0aed4701ba39dccda43751482fd08f6353010'
This commit is contained in:
commit
febb7c310c
28 changed files with 246 additions and 179 deletions
_redirectspackage-lock.jsonpackage.json
src
|
@ -40,6 +40,8 @@
|
|||
/posts/2024/link-blogging-using-readwise/ /posts/2024/link-blogging-using-readwise-reader/ 301
|
||||
/2022/12/automating-email-cleanup-in-gmail /posts/2022/automating-email-cleanup-in-gmail/ 301
|
||||
/posts/2023/automate-syndicate-content-mastodon-eleventy/ /posts/2023/automate-and-syndicate-content-from-eleventy-to-mastodon/ 301
|
||||
/posts/2023/road-to-madness-apple-music-charts/ /posts/2023/road-to-madness-charting-apple-music-listening-data/ 301
|
||||
/posts/2023/semi-automated-hashtags-syndicated-posts/ /posts/2023/semi-automated-hashtags-for-syndicated-posts/ 301
|
||||
|
||||
# music
|
||||
/music/artists/hyperdontia-denmark-turkiye /music/artists/hyperdontia-denmark-tuerkiye 301
|
||||
|
@ -47,6 +49,7 @@
|
|||
# 404s
|
||||
/robot.txt /robots.txt 301
|
||||
robotx.txt /robots.txt 301
|
||||
/sitemap /sitemap.xml 301
|
||||
/sitemap.txt /sitemap.xml 301
|
||||
/blog / 301
|
||||
/posts/2024 / 301
|
||||
|
|
78
package-lock.json
generated
78
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "coryd.dev",
|
||||
"version": "19.5.19",
|
||||
"version": "19.6.13",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "coryd.dev",
|
||||
"version": "19.5.19",
|
||||
"version": "19.6.13",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cdransf/api-text": "^1.4.0",
|
||||
|
@ -16,12 +16,12 @@
|
|||
"youtube-video-element": "^1.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0-alpha.13",
|
||||
"@11ty/eleventy": "3.0.0-alpha.14",
|
||||
"@11ty/eleventy-fetch": "^4.0.1",
|
||||
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
|
||||
"@11tyrocks/eleventy-plugin-lightningcss": "^1.4.0",
|
||||
"@cdransf/eleventy-plugin-tabler-icons": "^1.6.1",
|
||||
"@supabase/supabase-js": "^2.43.5",
|
||||
"@cdransf/eleventy-plugin-tabler-icons": "^1.7.0",
|
||||
"@supabase/supabase-js": "^2.44.1",
|
||||
"dotenv-flow": "^4.1.0",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"liquidjs": "^10.14.0",
|
||||
|
@ -68,9 +68,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@11ty/eleventy": {
|
||||
"version": "3.0.0-alpha.13",
|
||||
"resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.0.0-alpha.13.tgz",
|
||||
"integrity": "sha512-LZ1mI2JoB/vu6eIzeh9Eim0istAmKiJ0C5LEYG8HigvGgVsADd7OGHpOeOpDgKjotPSO+DTVh48gQj/cW2mRNw==",
|
||||
"version": "3.0.0-alpha.14",
|
||||
"resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.0.0-alpha.14.tgz",
|
||||
"integrity": "sha512-SQGvi/0cSrgyjhTocO8nGpivQbZBXnFlVLp1M3H8xcdvpXYgCVHiEYvrY79TnDd9Nxvj5QtsQuCiselJb3X16g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -83,6 +83,7 @@
|
|||
"@11ty/posthtml-urls": "^1.0.0",
|
||||
"@sindresorhus/slugify": "^2.2.1",
|
||||
"bcp-47-normalize": "^2.3.0",
|
||||
"chardet": "^2.0.0",
|
||||
"chokidar": "^3.6.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"debug": "^4.3.5",
|
||||
|
@ -93,7 +94,7 @@
|
|||
"is-glob": "^4.0.3",
|
||||
"iso-639-1": "^3.1.2",
|
||||
"kleur": "^4.1.5",
|
||||
"liquidjs": "^10.13.1",
|
||||
"liquidjs": "^10.14.0",
|
||||
"luxon": "^3.4.4",
|
||||
"markdown-it": "^14.1.0",
|
||||
"micromatch": "^4.0.7",
|
||||
|
@ -269,9 +270,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@cdransf/eleventy-plugin-tabler-icons": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@cdransf/eleventy-plugin-tabler-icons/-/eleventy-plugin-tabler-icons-1.6.1.tgz",
|
||||
"integrity": "sha512-ZWR9W1yShXcKQD8/eai27ooPVYhAjnqtrKfkyXEMyiITE7tAQ0PU/V9tarn6X6o1UO4R5MMMJs2e/f9AeaF8lQ==",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@cdransf/eleventy-plugin-tabler-icons/-/eleventy-plugin-tabler-icons-1.7.0.tgz",
|
||||
"integrity": "sha512-rC0exJmeoiM6C27i7/zIC7A76tUPPeZqOcGe4/Pf/rbywdKQL7eeHMQjkC5I+y5Bn94JJ04PDc4BaHcNfZlpMA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
@ -456,9 +457,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@supabase/postgrest-js": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.5.tgz",
|
||||
"integrity": "sha512-YR4TiitTE2hizT7mB99Cl3V9i00RAY5sUxS2/NuWWzkreM7OeYlP2OqnqVwwb4z6ILn+j8x9e/igJDepFhjswQ==",
|
||||
"version": "1.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.7.tgz",
|
||||
"integrity": "sha512-TJztay5lcnnKuXjIO/X/aaajOsP8qNeW0k3MqIFoOtRolj5MEAIy8rixNakRk3o23eVCdsuP3iMLYPvOOruH6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -466,9 +467,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@supabase/realtime-js": {
|
||||
"version": "2.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz",
|
||||
"integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.10.1.tgz",
|
||||
"integrity": "sha512-SrrXxE8xgwWvjREQMkC9LIHIoCQde+OqkFPKP2s/O0ROjhmJ/iXeLvoWhAzXh9gwire4oaK14/ncL/iRiaVWQw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -489,17 +490,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@supabase/supabase-js": {
|
||||
"version": "2.43.5",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.5.tgz",
|
||||
"integrity": "sha512-Y4GukjZWW6ouohMaPlYz8tSz9ykf9jY7w9/RhqKuScmla3Xiklce8eLr8TYAtA+oQYCWxo3RgS3B6O4rd/72FA==",
|
||||
"version": "2.44.1",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.44.1.tgz",
|
||||
"integrity": "sha512-4vCOkefRoeacmMELIWlYPwsfd9y/stH4fCZ4GZZjiOCHeViIrZ8artdj61MwkjQKFuF1uZ87gCKjtMDKLJsDlA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@supabase/auth-js": "2.64.2",
|
||||
"@supabase/functions-js": "2.4.1",
|
||||
"@supabase/node-fetch": "2.6.15",
|
||||
"@supabase/postgrest-js": "1.15.5",
|
||||
"@supabase/realtime-js": "2.9.5",
|
||||
"@supabase/postgrest-js": "1.15.7",
|
||||
"@supabase/realtime-js": "2.10.1",
|
||||
"@supabase/storage-js": "2.6.0"
|
||||
}
|
||||
},
|
||||
|
@ -532,9 +533,9 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz",
|
||||
"integrity": "sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==",
|
||||
"version": "20.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
|
||||
"integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -825,9 +826,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001636",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz",
|
||||
"integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==",
|
||||
"version": "1.0.30001638",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
|
||||
"integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -845,6 +846,13 @@
|
|||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/chardet": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.0.0.tgz",
|
||||
"integrity": "sha512-xVgPpulCooDjY6zH4m9YW3jbkaBe3FKIAvF5sj5t7aBNsVl2ljIE+xwJ4iNgiDZHFQvNIpjdKdVOQvvk5ZfxbQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
|
@ -1149,9 +1157,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.807",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.807.tgz",
|
||||
"integrity": "sha512-kSmJl2ZwhNf/bcIuCH/imtNOKlpkLDn2jqT5FJ+/0CXjhnFaOa9cOe9gHKKy71eM49izwuQjZhKk+lWQ1JxB7A==",
|
||||
"version": "1.4.812",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
|
||||
"integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
|
@ -2343,9 +2351,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "coryd.dev",
|
||||
"version": "19.5.19",
|
||||
"version": "19.6.13",
|
||||
"description": "The source for my personal site. Built using 11ty.",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
@ -26,12 +26,12 @@
|
|||
"youtube-video-element": "^1.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0-alpha.13",
|
||||
"@11ty/eleventy": "3.0.0-alpha.14",
|
||||
"@11ty/eleventy-fetch": "^4.0.1",
|
||||
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
|
||||
"@11tyrocks/eleventy-plugin-lightningcss": "^1.4.0",
|
||||
"@cdransf/eleventy-plugin-tabler-icons": "^1.6.1",
|
||||
"@supabase/supabase-js": "^2.43.5",
|
||||
"@cdransf/eleventy-plugin-tabler-icons": "^1.7.0",
|
||||
"@supabase/supabase-js": "^2.44.1",
|
||||
"dotenv-flow": "^4.1.0",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"liquidjs": "^10.14.0",
|
||||
|
|
|
@ -6,14 +6,14 @@ export default async function () {
|
|||
{ name: 'Watching', url: '/watching', icon: 'device-tv' },
|
||||
{ name: 'Books', url: '/books', icon: 'books' },
|
||||
{ name: 'Links', icon: 'link' },
|
||||
{ name: 'About', url: '/about', icon: 'info-square' },
|
||||
{ name: 'About', url: '/about', icon: 'info-circle' },
|
||||
{ name: 'Search', icon: 'search' },
|
||||
{ name: 'Feeds', icon: 'rss' },
|
||||
{ name: 'Mastodon', icon: 'brand-mastodon' },
|
||||
],
|
||||
footer: [
|
||||
{ name: 'Now' },
|
||||
{ name: 'Uses' },
|
||||
{ name: 'Colophon' },
|
||||
{ name: 'Blogroll' },
|
||||
{ name: 'Save' },
|
||||
],
|
||||
|
@ -23,8 +23,8 @@ export default async function () {
|
|||
{ name: 'npm', url: 'https://www.npmjs.com/~cdransf', icon: 'brand-npm'},
|
||||
{ name: 'Mastodon', url: 'https://social.lol/@cory', icon: 'brand-mastodon' },
|
||||
{ name: 'ListenBrainz', url: 'https://listenbrainz.org/user/cdransf/', icon: 'brain' },
|
||||
{ name: 'Instapaper', url: 'https://www.instapaper.com/p/coryd', icon: 'news' },
|
||||
{ name: 'Coffee', url: 'https://buymeacoffee.com/cory', icon: 'coffee' },
|
||||
{ name: 'Now', url: '/now', icon: 'clock-hour-3' },
|
||||
{ name: 'Webrings', url: '/webrings', icon: 'heart-handshake' },
|
||||
],
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{{ pageTitle }}</title>
|
||||
<link rel="preload" href="/assets/fonts/MonoLisa.min.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/assets/fonts/MonoLisa.min.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="/assets/styles/index.css?v={% appVersion %}" type="text/css" />
|
||||
<link rel="canonical" href="{{ fullUrl }}" />
|
||||
<meta property="og:title" content="{{ pageTitle }}" />
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
<div class="music-chart">
|
||||
{% assign items = data.items | default: data %}
|
||||
{% for item in items limit: count | default: items.size %}
|
||||
{%- assign playTotal = playTotal | default: mostPlayed -%}
|
||||
{%- assign percentage = item.plays | calculatePlayPercentage: playTotal -%}
|
||||
<div class="item">
|
||||
<div class="presentation">
|
||||
<div class="count">{{ item.rank | formatNumber }}.</div>
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||
<ol type="1">
|
||||
{% for item in items limit: count | default: items.size %}
|
||||
{%- assign playTotal = playTotal | default: mostPlayed -%}
|
||||
{%- assign percentage = item.plays | calculatePlayPercentage: playTotal -%}
|
||||
<li value="{{ item.rank }}">
|
||||
<div class="item">
|
||||
<div class="presentation">
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
<a href="{{ item.url }}">{{ item.title }}</a>
|
||||
</div>
|
||||
{% capture playsLabel %}
|
||||
{% if item.plays > 1 %}
|
||||
plays
|
||||
{% else %}
|
||||
play
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
<div class="subtext">{{ item.artist }}</div>
|
||||
<div class="subtext">{{ item.plays }} {{ playsLabel }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% capture playsLabel %}
|
||||
{% if item.plays > 1 %}
|
||||
plays
|
||||
{% else %}
|
||||
play
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
<div class="subtext">{{ item.artist }}</div>
|
||||
<div class="subtext">{{ item.plays }} {{ playsLabel }}</div>
|
||||
{% render "partials/media/progress-bar.liquid", percentage:percentage %}
|
||||
</div>
|
||||
</div>
|
||||
{% render "partials/media/progress-bar.liquid", percentage:percentage %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
{% unless count %}
|
||||
{% render "partials/widgets/paginator.liquid", pagination:data %}
|
||||
|
|
|
@ -5,15 +5,11 @@
|
|||
<div class="meta">
|
||||
<img
|
||||
srcset="
|
||||
https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=64 256w 64w,
|
||||
https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=64 64w,
|
||||
https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=128 128w,
|
||||
https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=256 256w,
|
||||
https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=512 512w
|
||||
"
|
||||
sizes="(max-width: 450px) 64px,
|
||||
(max-width: 850px) 128px,
|
||||
(max-width: 1000px) 256px,
|
||||
512px"
|
||||
sizes="(max-width: 1000px) 64px,
|
||||
128px"
|
||||
src="https://cdn.coryd.dev{{ item.image }}?aspect_ratio=1:1&width=512"
|
||||
alt="{{ alt }}"
|
||||
loading="lazy"
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
<script>{{ js }}</script>
|
||||
<div class="flex-centered">
|
||||
<input id="menu-toggle" type="checkbox" aria-hidden="true" />
|
||||
<label class="menu-button-container" for="menu-toggle" aria-expanded="false" tabindex="0">
|
||||
<span id="menu-label-text" class="screen-readers-only">Toggle mobile menu</span>
|
||||
<label class="menu-button-container" for="menu-toggle" tabindex="0">
|
||||
<div class="menu-closed" aria-hidden="true">{% tablericon "menu" "Menu closed" %}</div>
|
||||
<div class="menu-open" aria-hidden="true">{% tablericon "x" "Menu open" %}</div>
|
||||
</label>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script type="module" src="/assets/scripts/components/theme-toggle.js"></script>
|
||||
<script type="module" src="/assets/scripts/components/theme-toggle.js" crossorigin="anonymous"></script>
|
||||
<span class="client-side">
|
||||
<theme-toggle>
|
||||
<button class="theme-toggle" aria-label="Toggle site theme" tabindex="0">
|
||||
<button class="theme-toggle" tabindex="0">
|
||||
<span class="light">
|
||||
{% tablericon "sun" "Toggle light theme" %}
|
||||
</span>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script type="module" src="/assets/scripts/components/api-text.js"></script>
|
||||
<script type="module" src="/assets/scripts/components/api-text.js" crossorigin="anonymous"></script>
|
||||
<api-text class="client-side" api-url="/api/now-playing">
|
||||
<p class="loading">🎧 Loading...</p>
|
||||
<p class="content"></p>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% if popularPosts.size > 0 %}
|
||||
<h3 class="link-list-header flex-centered">
|
||||
<h3 class="flex-centered">
|
||||
{% tablericon "flame" "Popular" %}
|
||||
Popular posts
|
||||
</h3>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% if links.size > 0 %}
|
||||
<h3 id="links" class="link-list-header flex-centered">
|
||||
<h3 id="links" class="flex-centered">
|
||||
{% tablericon "link" "Links" %}
|
||||
Recent links
|
||||
</h3>
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
window.addEventListener('load', () => {
|
||||
const menuInput = document.getElementById('menu-toggle')
|
||||
const menuLabelText = document.getElementById('menu-label-text')
|
||||
const menuButtonContainer = document.querySelector('.menu-button-container')
|
||||
const menuItems = document.querySelectorAll('.menu-primary li')
|
||||
const isMobile = () => window.innerWidth <= 768
|
||||
|
||||
const udpateMenuState = () => {
|
||||
const isExpanded = menuInput.checked
|
||||
menuButtonContainer.setAttribute('aria-expanded', isExpanded)
|
||||
|
||||
if(isExpanded) menuLabelText.textContent = 'Close mobile menu'
|
||||
if (!isExpanded) menuLabelText.textContent = 'Open mobile menu'
|
||||
}
|
||||
|
||||
udpateMenuState()
|
||||
|
||||
menuInput.addEventListener('change', udpateMenuState)
|
||||
|
||||
menuButtonContainer.addEventListener('keydown', e => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault()
|
||||
menuInput.checked = !menuInput.checked
|
||||
udpateMenuState()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -35,9 +20,6 @@ window.addEventListener('load', () => {
|
|||
})
|
||||
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape' && isMobile() && menuInput.checked) {
|
||||
menuInput.checked = false
|
||||
udpateMenuState()
|
||||
}
|
||||
if (e.key === 'Escape' && menuInput.checked) menuInput.checked = false
|
||||
})
|
||||
})
|
|
@ -138,6 +138,11 @@ a {
|
|||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
& + .page-header,
|
||||
& + .music-chart {
|
||||
margin-top: var(--sizing-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,9 +184,12 @@ h5 { font-size: var(--font-size-md) }
|
|||
h6 { font-size: var(--font-size-sm) }
|
||||
|
||||
.section-header-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin: var(--sizing-xl) 0 var(--sizing-lg);
|
||||
|
||||
& .section-header {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.section-header {
|
||||
|
@ -197,10 +205,12 @@ h6 { font-size: var(--font-size-sm) }
|
|||
}
|
||||
|
||||
.section-header-buttons {
|
||||
margin: 0 0 var(--sizing-lg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sizing-sm);
|
||||
|
||||
& > button {
|
||||
margin-bottom: var(--sizing-sm) !important;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0 !important;
|
||||
|
@ -338,23 +348,23 @@ nav .active svg {
|
|||
}
|
||||
|
||||
/* social icons */
|
||||
.at svg { stroke: var(--brand-fastmail) !important; }
|
||||
.at svg { stroke: var(--brand-proton) !important; }
|
||||
.brand-github svg { stroke: var(--brand-github) !important; }
|
||||
.brand-npm svg { stroke: var(--brand-npm) !important; }
|
||||
.brand-mastodon svg { stroke: var(--brand-mastodon) !important; }
|
||||
.brain svg { stroke: var(--brand-listenbrainz) !important; }
|
||||
.article svg { stroke: var(--posts) !important }
|
||||
.headphones svg { stroke: var(--music) !important; }
|
||||
.device-tv svg { stroke: var(--tv) !important; }
|
||||
.books svg { stroke: var(--books) !important; }
|
||||
.link svg { stroke: var(--links) !important; }
|
||||
.info-square svg { stroke: var(--about) !important }
|
||||
.search svg { stroke: var(--search) !important }
|
||||
.news svg { stroke: var(--brand-instapaper) !important; }
|
||||
.brain svg { stroke: var(--brand-listenbrainz) !important; }
|
||||
.clock-hour-3 svg { stroke: var(--now) !important; }
|
||||
.coffee svg { stroke: var(--brand-buy-me-a-coffee) !important; }
|
||||
.heart-handshake svg { stroke: var(--webrings) !important; }
|
||||
.rss svg { stroke: var(--brand-rss) !important; }
|
||||
.device-tv svg { stroke: var(--tv) !important; }
|
||||
.favorite svg { stroke: var(--favorite) !important }
|
||||
.headphones svg { stroke: var(--music) !important; }
|
||||
.heart-handshake svg { stroke: var(--webrings) !important; }
|
||||
.info-circle svg { stroke: var(--about) !important }
|
||||
.link svg { stroke: var(--links) !important; }
|
||||
.rss svg { stroke: var(--brand-rss) !important; }
|
||||
.search svg { stroke: var(--search) !important }
|
||||
|
||||
/* layout */
|
||||
.default-wrapper {
|
||||
|
@ -418,8 +428,7 @@ footer {
|
|||
}
|
||||
|
||||
& a {
|
||||
width: var(--sizing-xl);
|
||||
height: var(--sizing-xl);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,10 +537,6 @@ li {
|
|||
}
|
||||
}
|
||||
|
||||
.link-list-header {
|
||||
margin: var(--sizing-3xl) 0 var(--sizing-lg);
|
||||
}
|
||||
|
||||
/* images */
|
||||
.image-banner {
|
||||
border: 1px solid var(--accent-color);
|
||||
|
@ -617,14 +622,6 @@ li {
|
|||
max-width: 768px;
|
||||
}
|
||||
|
||||
.section-header-wrapper {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.section-header-buttons {
|
||||
margin: var(--sizing-md) 0 var(--sizing-lg);
|
||||
}
|
||||
|
||||
footer nav.social {
|
||||
gap: var(--sizing-md);
|
||||
}
|
||||
|
|
|
@ -10,28 +10,46 @@ button {
|
|||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-bold);
|
||||
line-height: var(--line-height-base);
|
||||
white-space: nowrap;
|
||||
color: var(--color-lightest);
|
||||
background-color: var(--accent-color);
|
||||
appearance: none;
|
||||
border: 2px solid var(--accent-color);
|
||||
transition-property: all;
|
||||
transition-property: border;
|
||||
}
|
||||
|
||||
&:not(.theme-toggle, .active):hover,
|
||||
&:not(.theme-toggle, .active):active,
|
||||
&:not(.theme-toggle, .active):focus,
|
||||
&:not(.theme-toggle, .active):focus-within {
|
||||
outline: 2px dashed var(--accent-color);
|
||||
background-color: var(--accent-color-hover);
|
||||
border-color: var(--accent-color-hover);
|
||||
transition-timing-function: var(--transition-ease-in-out);
|
||||
transition-duration: var(--transition-duration-default);
|
||||
}
|
||||
|
||||
&:not(.theme-toggle, .active):focus,
|
||||
&:not(.theme-toggle, .active):focus-within {
|
||||
transition-property: none;
|
||||
outline: 2px dashed var(--accent-color);
|
||||
padding: calc(var(--sizing-sm) + 2px) calc(var(--sizing-lg) + 2px);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&.theme-toggle:focus,
|
||||
&.theme-toggle:focus-within {
|
||||
outline: 2px dashed var(--accent-color);
|
||||
}
|
||||
|
||||
&.small {
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-sm);
|
||||
padding: var(--sizing-xs) var(--sizing-sm);
|
||||
|
||||
&:not(.active):focus,
|
||||
&:not(.active):focus-within {
|
||||
padding: var(--sizing-xs) calc(var(--sizing-sm) + 2px);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
|
|
|
@ -31,10 +31,14 @@ textarea:focus-within {
|
|||
|
||||
.search__form {
|
||||
margin-top: 0;
|
||||
|
||||
& .search__form--input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search__results {
|
||||
margin-top: 0;
|
||||
margin: var(--sizing-base) 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
:root {
|
||||
--grid-square: repeat(2,minmax(0,1fr));
|
||||
--grid-vertical: repeat(3,minmax(0,1fr));
|
||||
--aspect-ratio-square: 1/1;
|
||||
--aspect-ratio-vertical: 2/3;
|
||||
}
|
||||
|
||||
.media-grid {
|
||||
|
@ -15,6 +17,10 @@
|
|||
&.square {
|
||||
grid-template-columns: var(--grid-square);
|
||||
|
||||
& a {
|
||||
aspect-ratio: var(--aspect-ratio-square);
|
||||
}
|
||||
|
||||
& img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -24,6 +30,10 @@
|
|||
&.vertical {
|
||||
grid-template-columns: var(--grid-vertical);
|
||||
|
||||
& a {
|
||||
aspect-ratio: var(--aspect-ratio-vertical);
|
||||
}
|
||||
|
||||
& img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
@ -50,11 +60,15 @@
|
|||
}
|
||||
|
||||
& a:hover img,
|
||||
& a:focus img,
|
||||
& a:active img {
|
||||
border-color: var(--accent-color-hover)
|
||||
}
|
||||
|
||||
& a:focus img,
|
||||
& a:focus-within img {
|
||||
border: 0
|
||||
}
|
||||
|
||||
& .meta-text {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.menu-primary {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
list-style-type: none;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
gap: var(--sizing-md);
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
.music-chart {
|
||||
margin-bottom: var(--sizing-base);
|
||||
|
||||
& ol {
|
||||
padding-left: 0;
|
||||
margin-top: 0;
|
||||
|
||||
& li:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& .item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -76,10 +85,6 @@
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
& .count {
|
||||
margin-right: var(--sizing-sm);
|
||||
}
|
||||
|
||||
& .info {
|
||||
max-width: calc(75% - var(--sizing-lg));
|
||||
}
|
||||
|
@ -110,6 +115,10 @@
|
|||
|
||||
@media screen and (min-width: 768px) {
|
||||
.music-chart {
|
||||
& ol {
|
||||
list-style-position: outside;
|
||||
}
|
||||
|
||||
& .meta,
|
||||
& .presentation {
|
||||
width: calc(80% - var(--sizing-lg));
|
||||
|
|
|
@ -42,27 +42,28 @@
|
|||
--accent-color: var(--blue-600);
|
||||
--accent-color-hover: var(--blue-800);
|
||||
|
||||
--brand-fastmail: #0067b9;
|
||||
--brand-proton: #6d4aff;
|
||||
--brand-github: #333;
|
||||
--brand-npm: #cc3534;
|
||||
--brand-mastodon: #6364ff;
|
||||
--brand-listenbrainz: #e97941;
|
||||
--brand-instapaper: var(--text-color);
|
||||
--brand-buy-me-a-coffee: #40dca5;
|
||||
--brand-rss: #f26522;
|
||||
--posts: #008080;
|
||||
--music: #1e90ff;
|
||||
--tv: #ff4500;
|
||||
--books: #32cd32;
|
||||
--links: #9370db;
|
||||
|
||||
--about: #ff6347;
|
||||
--search: #4682b4;
|
||||
--webrings: #da70d6;
|
||||
--moon: #6a5acd;
|
||||
--sun: #ffa500;
|
||||
--favorite: #ff69b4;
|
||||
--warning: #ff8c00;
|
||||
--books: #32cd32;
|
||||
--error: #d92525;
|
||||
--favorite: #ff69b4;
|
||||
--links: #9370db;
|
||||
--moon: #6a5acd;
|
||||
--music: #1e90ff;
|
||||
--now: #ff1493;
|
||||
--posts: #008080;
|
||||
--search: #4682b4;
|
||||
--sun: #ffa500;
|
||||
--tv: #ff4500;
|
||||
--warning: #ff8c00;
|
||||
--webrings: #da70d6;
|
||||
|
||||
/* fonts */
|
||||
--font-mono: MonoLisa, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, ui-monospace, monospace;
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
transition-duration: 300ms;
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
& a:hover img,
|
||||
& a:focus img,
|
||||
& a:active img {
|
||||
|
@ -65,7 +69,7 @@
|
|||
& p {
|
||||
&.title {
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: 1;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
&.sub-meta {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
:root {
|
||||
--aspect-ratio-banner: 1 / 0.5625;
|
||||
}
|
||||
|
||||
.watching {
|
||||
& img {
|
||||
border: 1px solid var(--accent-color);
|
||||
|
@ -12,12 +16,17 @@
|
|||
&.hero {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
|
||||
div.meta-text {
|
||||
& img {
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
}
|
||||
|
||||
& div.meta-text {
|
||||
color: white;
|
||||
position: absolute;
|
||||
left: var(--sizing-sm);
|
||||
bottom: var(--sizing-lg);
|
||||
bottom: var(--sizing-sm);
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -43,11 +52,11 @@
|
|||
position: absolute;
|
||||
z-index: 1;
|
||||
content: '';
|
||||
bottom: 11px;
|
||||
bottom: 1px;
|
||||
left: 1px;
|
||||
box-shadow: inset 0 -70px 75px -40px #000;
|
||||
width: calc(100% - 2px);
|
||||
height: calc(100% - 11px);
|
||||
height: calc(100% - 1px);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,9 +66,9 @@
|
|||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
margin-bottom: var(--sizing-base);
|
||||
|
||||
& a,
|
||||
& div {
|
||||
& a {
|
||||
display: flex;
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
}
|
||||
|
||||
& div {
|
||||
|
@ -103,6 +112,7 @@
|
|||
position: relative;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
|
||||
&.shadow::after {
|
||||
position: absolute;
|
||||
|
@ -121,6 +131,10 @@
|
|||
margin-top: var(--sizing-base);
|
||||
border-bottom: 0;
|
||||
|
||||
& img {
|
||||
aspect-ratio: var(--aspect-ratio-banner);
|
||||
}
|
||||
|
||||
& .watching-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: var(--blue-100);
|
||||
color: #b0cfff;
|
||||
background: none;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: var(--font-mono);
|
||||
|
@ -14,31 +14,29 @@ pre[class*="language-"] {
|
|||
hyphens: none;
|
||||
}
|
||||
|
||||
/* code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: var(--sizing-lg);
|
||||
margin: var(--sizing-xl) 0;
|
||||
overflow: auto;
|
||||
background: var(--gray-darkest);
|
||||
border: 1px solid var(--gray-light);
|
||||
background: #1a1d22;
|
||||
border: 1px solid #dfe3e8;
|
||||
}
|
||||
|
||||
/* inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: var(--sizing-xs);
|
||||
white-space: normal;
|
||||
background: var(--gray-darkest);
|
||||
background: #1a1d22;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: var(--gray-600);
|
||||
color: #7f899b;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: var(--gray-200);
|
||||
color: #dfe3e8;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
|
@ -50,12 +48,12 @@ pre[class*="language-"] {
|
|||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: var(--blue-500);
|
||||
color: #4b88ff;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: var(--blue-700);
|
||||
color: #2458d4;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
|
@ -64,7 +62,7 @@ pre[class*="language-"] {
|
|||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: var(--green-500);
|
||||
color: #2ecc71;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
|
@ -73,23 +71,23 @@ pre[class*="language-"] {
|
|||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: var(--blue-100);
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: var(--orange-600);
|
||||
color: #e67e22;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: var(--teal-500);
|
||||
color: #1abc9c;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: var(--orange-500);
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
|
|
|
@ -19,6 +19,7 @@ image: https://cdn.coryd.dev/assets/404.jpg
|
|||
src="https://cdn.coryd.dev/assets/404.jpg?aspect_ratio=1:.5625&width=2048"
|
||||
alt="{{ alt }}"
|
||||
class="image-banner"
|
||||
style="aspect-ratio:1/0.5625"
|
||||
loading="eager"
|
||||
decoding="async"
|
||||
width="768"
|
||||
|
|
|
@ -29,7 +29,7 @@ schema: music-index
|
|||
</a>
|
||||
</h3>
|
||||
{% render "partials/media/grid.liquid", data:music.week.albums, shape: "square", count: 8 %}
|
||||
<div class="section-header-wrapper">
|
||||
<div class="section-header-wrapper flex-centered">
|
||||
<h3 id="tracks" class="section-header">
|
||||
<a class="link-icon" href="/music/tracks/this-week">
|
||||
{% tablericon "playlist" "Tracks" %}
|
||||
|
|
19
src/pages/secondary/colophon.md
Normal file
19
src/pages/secondary/colophon.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
title: Colophon
|
||||
layout: page
|
||||
permalink: /colophon.html
|
||||
description: The tools I use to build and maintain this site.
|
||||
---
|
||||
<h2 class="page-header">{{ title }}</h2>
|
||||
|
||||
This site is built and maintained using a number of tools.
|
||||
|
||||
- The frontend of the site is built using [11ty](https://www.11ty.dev) and the source for that is openly available on [GitHub](https://github.com/cdransf/coryd.dev).
|
||||
- The frontend is hosted on [Cloudflare Pages](https://pages.cloudflare.com) and rebuilds hourly.
|
||||
- Posts, links and media data (music, watching and books) are stored various tables at [Supabase](https://supabase.com) and managed via a [Directus](https://directus.io) instance hosted at <a class="plausible-event-name=DigitalOcean+referral" href="https://m.do.co/c/3635bf99aee2">DigitalOcean</a>.
|
||||
- My contact form is submitted to [Supabase](https://supabase.com) using a Cloudflare worker and entries are available to read in [Directus](https://directus.io).
|
||||
- Posts are composed in [Obsidian](https://obsidian.md) before being saved in [Directus](https://directus.io).
|
||||
- Images are hosted on <a class="plausible-event-name=bunny.net+referral" href="https://bunny.net?ref=revw3mehej">bunny.net</a>.
|
||||
- I use <a class="plausible-event-name=DNSimple+referral" href="https://dnsimple.com/r/3a7cbb9e15df8f">DNSimple</a> to register my domains and [DNSControl](https://dnscontrol.org) to configure and manage records.
|
||||
- I use [Plausible](https://plausible.io) for analytics.
|
||||
- <a class="plausible-event-name=Feedpress+referral" href="https://feedpress.com/?affid=34370">Feedpress</a> helps normalize my feeds and provides lightweight feed insights.
|
|
@ -9,12 +9,12 @@ description: Save a little bit on services that I also use.
|
|||
Referral links for services I use. I save some money, and you do as well if you choose to use them.
|
||||
|
||||
<ul class="link-list">
|
||||
<li><a class="plausible-event-name=Fastmail+referral" href="https://join.fastmail.com/5363c193">Fastmail</a></li>
|
||||
<li><a class="plausible-event-name=Proton+referral" href="https://pr.tn/ref/X775YX40Z50G">Proton</a></li>
|
||||
<li><a class="plausible-event-name=NextDNS+referral" href="https://nextdns.io/?from=m56mt3z6">NextDNS</a></li>
|
||||
<li><a class="plausible-event-name=DNSimple+referral" href="https://dnsimple.com/r/3a7cbb9e15df8f">DNSimple</a></li>
|
||||
<li><a class="plausible-event-name=bunny.net+referral" href="https://bunny.net?ref=revw3mehej">bunny.net</a></li>
|
||||
<li><a class="plausible-event-name=Feedpress+referral" href="https://feedpress.com/?affid=34370">Feedpress</a></li>
|
||||
<li><a class="plausible-event-name=Proton+referral" href="https://pr.tn/ref/X775YX40Z50G">Proton</a></li>
|
||||
<li><a class="plausible-event-name=Matter+referral" href="https://web.getmatter.com/referral/ss6td795">Matter</a></li>
|
||||
<li><a class="plausible-event-name=DigitalOcean+referral" href="https://m.do.co/c/3635bf99aee2">DigitalOcean</a></li>
|
||||
<li><a class="plausible-event-name=Garbage+Day+referral" href="https://www.garbageday.email/subscribe?ref=4JeD4bFKQE">Garbage Day newsletter</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -28,7 +28,7 @@ Software and services that I use for work and my own enjoyment.
|
|||
- [Obsidian](https://obsidian.md): fast, flexible and configurable (or minimal) as you'd like.
|
||||
- [Plexamp](https://www.plex.tv/plexamp/): Plex's flexible and delightful music player.
|
||||
- [Ivory](https://tapbots.com/ivory/): the best, most polished Mastodon client for macOS and iOS.
|
||||
- [ReadKit](https://readkit.app): super flexible and universal — it makes it easy to triage my feeds and save things over to Instapaper.
|
||||
- [Reeder](https://reeder.app): flexible and universal — it makes it easy to triage my feeds and save things over to Instapaper.
|
||||
- [Parcel](https://parcelapp.net): the most flexible and reliable package tracker for Apple's ecosystem.
|
||||
- [Flighty](https://flightyapp.com): I don't travel a ton but Flighty makes doing so a fair bit less stressful.
|
||||
|
||||
|
@ -42,9 +42,7 @@ Software and services that I use for work and my own enjoyment.
|
|||
|
||||
<h3>macOS</h3>
|
||||
|
||||
- [FMail2](https://fmail-app.fr): a lightweight wrapper around the Fastmail web app.
|
||||
- [Rectangle](https://rectangleapp.com): to quickly move around/organize/snap application windows. Using a Mac without it now feels like it's broken.
|
||||
- [Dato](https://sindresorhus.com/dato): an option-rich calendar utility that lives in your menubar.
|
||||
- [AirBuddy](https://v2.airbuddy.app): finer-grained control over AirPods and other wireless devices.
|
||||
- [Meta](https://www.nightbirdsevolve.com/meta): the _best_ utility for tagging and organizing music files on macOS.
|
||||
- [Permute](https://software.charliemonroe.net/permute): a useful utility for quickly converting files to different formats.
|
||||
|
@ -58,7 +56,7 @@ Software and services that I use for work and my own enjoyment.
|
|||
|
||||
<h3>Services</h3>
|
||||
|
||||
- <a class="plausible-event-name=Fastmail+referral" href="https://join.fastmail.com/5363c193">Fastmail</a>: the best, most reliable email, calendar and contacts provider around.
|
||||
- <a class="plausible-event-name=Proton+referral" href="https://pr.tn/ref/X775YX40Z50G">Proton</a>: the premier encrypted mail service with a number of other features like calendars and a reliable VPN.
|
||||
- <a class="plausible-event-name=NextDNS+referral" href="https://nextdns.io/?from=m56mt3z6">NextDNS</a>: a privacy-focused, set it and forget it DNS service. I use their security features on my home network and a profile with strict ad-blocking rules on all of my devices.
|
||||
- <a class="plausible-event-name=DNSimple+referral" href="https://dnsimple.com/r/3a7cbb9e15df8f">DNSimple</a>: a robust, user-friendly DNS provider and registrar. I moved my domains here after my old provider was acquired.
|
||||
- [Cloudflare](https://cloudfllare.com): I use their pages hosting, workers and myriad other features.
|
||||
|
@ -66,10 +64,9 @@ Software and services that I use for work and my own enjoyment.
|
|||
- [Plausible](https://plausible.io): lightweight, privacy-friendly analytics.
|
||||
- <a class="plausible-event-name=Feedpress+referral" href="https://feedpress.com/?affid=34370">Feedpress</a>: they've been around for a while now and don't change much (nor do they need to), but look no further for reliable, helpful feed analytics.
|
||||
- [Feedbin](https://feedbin.com): performant, open and super reliable RSS.
|
||||
- [Instapaper](https://instapaper.com): slow to change and often better for it — a reliable and steady read it later service.
|
||||
- <a class="plausible-event-name=Matter+referral" href="https://web.getmatter.com/referral/ss6td795">Matter</a>: a newer read it later service, but a rapidly developed and extremely powerful one. It's text to speech features are _excellent_.
|
||||
- [forwardemail.net](https://forwardemail.net): a simple and reliable service for forwarding and routing emails from a few of the domains I own.
|
||||
- [Backblaze](https://backblaze.com): It backs up my MacBook Air and attached storage drive and I don't have to think about it.
|
||||
- <a class="plausible-event-name=Proton+referral" href="https://pr.tn/ref/X775YX40Z50G">Proton</a>: a reliable, trustworthy VPN with all of the features you'd expect from such a service.
|
||||
|
||||
<hr />
|
||||
|
||||
|
|
Reference in a new issue