From fdda688bbe56c2317662b411ff563ba1b00ab72b Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 3 Jan 2026 13:05:03 +0000 Subject: [PATCH 1/6] Switching monitors --- layouts/index.html | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/layouts/index.html b/layouts/index.html index 5ddf19f..109f8ef 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -134,21 +134,6 @@
- -
-
-      ▄▄
- █▄    ██
- ██    ██          ▄▄
- ████▄ ██ ▄███▄ ▄████
- ██ ██ ██ ██ ██ ██ ██
-▄████▀▄██▄▀███▀ ▀████
-                   ██
-██ NEW! ██▶▶▶    ▀▀▀
-
-
-
@@ -230,6 +215,21 @@
+ + +
+
+      ▄▄
+ █▄    ██
+ ██    ██          ▄▄
+ ████▄ ██ ▄███▄ ▄████
+ ██ ██ ██ ██ ██ ██ ██
+▄████▀▄██▄▀███▀ ▀████
+                   ██
+██ NEW! ██▶▶▶    ▀▀▀
+
+
From ac9033c958fdea1c9bc0c63eb2451618b123cede Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 3 Jan 2026 13:10:22 +0000 Subject: [PATCH 2/6] Adding theme colour Removed blank file --- layouts/_default/baseof.html | 3 +-- layouts/partials/terminal.html | 0 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 layouts/partials/terminal.html diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 3a83849..d5fb00f 100755 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -3,8 +3,7 @@ - {{/* NOTE: the Site's title, and if there is a page title, that is set too - */}} + {{ block "title" . }}{{ .Site.Title }} {{ with .Params.Title }} | {{ . }}{{ end }}{{ end }} diff --git a/layouts/partials/terminal.html b/layouts/partials/terminal.html deleted file mode 100644 index e69de29..0000000 From f1460861b982d496a5c2930a51672ba7a3c11e8a Mon Sep 17 00:00:00 2001 From: Dan <dan@unbo.lt> Date: Sun, 4 Jan 2026 07:19:20 +0000 Subject: [PATCH 3/6] Updating weekly post --- assets/sass/style.scss | 145 ------------------ .../blog/2026-01-02-week-2-new-year/index.md | 16 +- lastfm-week.sh | 45 ++++++ 3 files changed, 60 insertions(+), 146 deletions(-) create mode 100755 lastfm-week.sh diff --git a/assets/sass/style.scss b/assets/sass/style.scss index 6cc8b0d..06338fa 100644 --- a/assets/sass/style.scss +++ b/assets/sass/style.scss @@ -801,28 +801,6 @@ body { pointer-events: none; } -/* Cables on desk - now using SVG for curves */ -.desk-cables { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 7; -} - -.cable-svg { - position: absolute; - bottom: 20%; - z-index: 4; - pointer-events: none; -} - -.cable-svg svg { - filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.5)); -} - /* Secondary monitors on desk */ /* Secondary CRT monitors - positioned relative to main monitor */ .secondary-screen { @@ -833,11 +811,6 @@ body { text-decoration: none !important; } -/* Wall-mounted CRT 1 - upper left relative to main */ - -/* Wall-mounted CRT 2 - upper right, larger, closely stacked */ - -/* Wall-mounted CRT 4 - lower left relative to main */ /* Desk-mounted CRT - on desk left side */ .desk-monitor { @@ -896,54 +869,6 @@ body { animation: pulse 2s ease-in-out infinite; } -/* Small equipment on desk */ -.desk-equipment { - position: absolute; - bottom: 10%; - background: linear-gradient(145deg, #4a4a4a 0%, #2a2a2a 100%); - box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.6); - z-index: 8; -} - -.modem { - right: 25%; - width: 35px; - height: 12px; -} - -.modem::after { - content: ""; - position: absolute; - top: 50%; - right: 5px; - transform: translateY(-50%); - width: 2px; - height: 2px; - background: #0f0; - border-radius: 50%; - box-shadow: 0 0 4px #0f0; - animation: pulse 1s ease-in-out infinite; -} - -.power-strip { - left: 35%; - width: 50px; - height: 8px; - background: linear-gradient(145deg, #1a1a1a 0%, #0a0a0a 100%); -} - -.power-strip::before { - content: ""; - position: absolute; - top: 50%; - left: 10px; - transform: translateY(-50%); - width: 3px; - height: 3px; - background: #f00; - border-radius: 50%; - box-shadow: 0 0 4px #f00; -} .monitor-stand-small { position: absolute; bottom: -20px; @@ -1099,53 +1024,6 @@ body { } } -/* Widgets and gadgets */ -.widget { - position: absolute; - bottom: 8%; - border-radius: 2px; - z-index: 6; -} - -.router { - left: 25%; - width: 170px; - height: 50px; - background: linear-gradient(180deg, #2a2a2a 0%, #1a1a1a 100%); - border: 1px solid #333; - box-shadow: - 0 2px 8px rgba(0, 0, 0, 0.5), - inset 0 1px 2px rgba(255, 255, 255, 0.1); -} - -.router::before { - content: ""; - position: absolute; - top: 50%; - left: 10px; - transform: translateY(-50%); - width: 4px; - height: 4px; - background: #0f0; - border-radius: 50%; - box-shadow: 0 0 5px #0f0; - animation: blink-fast 1s infinite; -} - -.router::after { - content: ""; - position: absolute; - top: 50%; - left: 20px; - transform: translateY(-50%); - width: 4px; - height: 4px; - background: #ff0; - border-radius: 50%; - box-shadow: 0 0 5px #ff0; - animation: blink-fast 1.5s infinite; -} - @keyframes blink-fast { 0%, 100% { @@ -1156,30 +1034,7 @@ body { } } -.hard-drive { - left: 30%; - bottom: 20%; - width: 55px; - height: 35px; - background: linear-gradient(180deg, #3a3a3a 0%, #2a2a2a 100%); - border: 1px solid #444; - box-shadow: - 0 2px 8px rgba(0, 0, 0, 0.5), - inset 0 1px 2px rgba(255, 255, 255, 0.1); -} -.hard-drive::before { - content: ""; - position: absolute; - top: 8px; - right: 8px; - width: 3px; - height: 3px; - background: #f00; - border-radius: 50%; - box-shadow: 0 0 5px #f00; - animation: pulse-slow 2s infinite; -} @keyframes pulse-slow { 0%, diff --git a/content/blog/2026-01-02-week-2-new-year/index.md b/content/blog/2026-01-02-week-2-new-year/index.md index ab09fe0..ccbd10d 100644 --- a/content/blog/2026-01-02-week-2-new-year/index.md +++ b/content/blog/2026-01-02-week-2-new-year/index.md @@ -15,7 +15,21 @@ draft: false ## Links I Found Interesting -- [name](https://url) - desc +- [POSSE](https://indieweb.org/POSSE) - I have killed off pretty much all social media, but I might look into posting more on Bluesky or setting up a Mastodon again, and this would be something to keep in mind. + +## Weekly Listening Stats + +**Total Tracks:** 231 + +**Top 5 Artists:** + +- [Lazerhawk](https://www.last.fm/music/Lazerhawk) - 14 plays +- [System of a Down](https://www.last.fm/music/System+of+a+Down) - 14 plays +- [Mystery Skulls](https://www.last.fm/music/Mystery+Skulls) - 8 plays +- [Carpenter Brut](https://www.last.fm/music/Carpenter+Brut) - 7 plays +- [Gunship](https://www.last.fm/music/Gunship) - 7 plays + +_Note: Not all my devices scrobble, so this is just what I have listened to at a computer._ ## Next Week diff --git a/lastfm-week.sh b/lastfm-week.sh new file mode 100755 index 0000000..a4fb1f5 --- /dev/null +++ b/lastfm-week.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Last.fm Weekly Stats Script +# Usage: ./lastfm-weekly.sh + +# Load environment variables from .env file +if [ -f .env ]; then + export $(cat .env | grep -v '^#' | xargs) +else + echo "Error: .env file not found" + exit 1 +fi + +# Check required variables +if [ -z "$LASTFM_API_KEY" ] || [ -z "$LASTFM_USERNAME" ]; then + echo "Error: LASTFM_API_KEY and LASTFM_USERNAME must be set in .env file" + exit 1 +fi + +API_BASE="http://ws.audioscrobbler.com/2.0/" + +# Get current Unix timestamp +NOW=$(date +%s) +# Get timestamp from 7 days ago +WEEK_AGO=$((NOW - 604800)) + +# Fetch top artists for the week +TOP_ARTISTS=$(curl -s "${API_BASE}?method=user.gettopartists&user=${LASTFM_USERNAME}&api_key=${LASTFM_API_KEY}&format=json&period=7day&limit=5") + +# Fetch recent tracks to count this week's scrobbles +RECENT_TRACKS=$(curl -s "${API_BASE}?method=user.getrecenttracks&user=${LASTFM_USERNAME}&api_key=${LASTFM_API_KEY}&format=json&from=${WEEK_AGO}&to=${NOW}&limit=1") + +# Get total track count +TOTAL_TRACKS=$(echo "$RECENT_TRACKS" | jq -r '.recenttracks["@attr"].total') + +# Output in markdown format +echo "## Last.fm Weekly Stats" +echo "" +echo "**Total Tracks:** ${TOTAL_TRACKS}" +echo "" +echo "**Top 5 Artists:**" +echo "" + +# Parse and display top 5 artists as markdown links +echo "$TOP_ARTISTS" | jq -r '.topartists.artist[] | "- [\(.name)](\(.url)) - \(.playcount) plays"' \ No newline at end of file From 1997156c1806fa6fb411ee398d249f2e655b4a9f Mon Sep 17 00:00:00 2001 From: Dan <dan@unbo.lt> Date: Sun, 4 Jan 2026 09:12:10 +0000 Subject: [PATCH 4/6] Finished week 2 post --- content/blog/2026-01-02-week-2-new-year/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/blog/2026-01-02-week-2-new-year/index.md b/content/blog/2026-01-02-week-2-new-year/index.md index ccbd10d..b98d91d 100644 --- a/content/blog/2026-01-02-week-2-new-year/index.md +++ b/content/blog/2026-01-02-week-2-new-year/index.md @@ -10,6 +10,7 @@ draft: false - 🎆 Happy New Year! Last year went by shockingly fast, and the year ahead is looking very exciting too. - 💻 The Thinkpad T480s arrived and has been suitably sticker bombed. I am running Pop!\_OS 24.04 on it and everything so far seems great. - 🌐 I setup a dedicated server for this site and migrated off neocities, I am coming up with a plan on how to make sure updates keep getting posted there but redirect here. +- 📺 There's been a bunch of Taskmaster recently, including Champion of Champions which was good. Traitors is back on so we're up to date on that so far. {{< img src="thinkpad_t480s.jpg" alt="Thinkpad T480s complete with stickerbomb" width="900x" >}} From 0788ab88969f466246eb4de937432ef3b65ec263 Mon Sep 17 00:00:00 2001 From: Dan <dan@unbo.lt> Date: Sun, 4 Jan 2026 10:08:00 +0000 Subject: [PATCH 5/6] Updating blog tags to link everywhere --- assets/sass/pages/blog.scss | 11 ++++++++++- lastfm-week.sh | 2 +- layouts/blog/summary.html | 17 +++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/assets/sass/pages/blog.scss b/assets/sass/pages/blog.scss index 889ff76..249cbe9 100644 --- a/assets/sass/pages/blog.scss +++ b/assets/sass/pages/blog.scss @@ -228,6 +228,13 @@ padding: 15px; } + .blog-tags-filter { + border: 0; + background: transparent; + padding: 0; + margin-bottom: 0px; + } + &:hover { background: rgba(0, 255, 0, 0.1); border-color: rgba(0, 255, 0, 0.6); @@ -264,12 +271,14 @@ } } - .blog-tags .tag { + + .tag-filter-link { background: rgba(255, 153, 0, 0.2); border-color: rgba(255, 153, 0, 0.5); color: #ff9900; text-shadow: 0 0 5px rgba(255, 153, 0, 0.5); } + } // Post title diff --git a/lastfm-week.sh b/lastfm-week.sh index a4fb1f5..c208320 100755 --- a/lastfm-week.sh +++ b/lastfm-week.sh @@ -19,7 +19,7 @@ fi API_BASE="http://ws.audioscrobbler.com/2.0/" -# Get current Unix timestamp +# Get current timestamp NOW=$(date +%s) # Get timestamp from 7 days ago WEEK_AGO=$((NOW - 604800)) diff --git a/layouts/blog/summary.html b/layouts/blog/summary.html index 4bd3a2e..50c1709 100644 --- a/layouts/blog/summary.html +++ b/layouts/blog/summary.html @@ -1,21 +1,22 @@ <div class="blog-post-card{{ if not (in .Params.tags "weeknote") }} non-weekly{{ end }}"> <h1 class="blog-title"> - {{ if in .Params.tags "weeknote" }} + + <a href="{{ .Permalink }}"> {{ .Title }} - {{ else }} - <a href="{{ .Permalink }}"> - {{ .Title }} - </a> - {{ end }} + </a> + {{ if .Date }} <span class="blog-date">{{ .Date.Format "02-01-2006" }}</span> {{ end }} </h1> {{ if .Params.tags }} - <div class="blog-tags"> + <div class="blog-tags-filter"> + <div class="tag-links"> {{ range .Params.tags }} - <span class="tag">{{ . }}</span> + {{ $tagURL := printf "/tags/%s/" (. | urlize) }} + <a href="{{ $tagURL }}" class="tag-filter-link">{{ . }}</a> {{ end }} + </div> </div> {{ end }} {{ if in .Params.tags "weeknote" }} From 8fdc28e7c51796bb93bd6ab7fdca5cb09aeafee8 Mon Sep 17 00:00:00 2001 From: Dan <dan@unbo.lt> Date: Sun, 4 Jan 2026 13:36:59 +0000 Subject: [PATCH 6/6] Start of resources section with placeholders --- archetypes/resources/index.md | 12 + assets/sass/pages/resources.scss | 549 ++++++++++++++++++++++++ assets/sass/style.scss | 1 + config.yml | 4 + content/resources/_index.md | 7 + content/resources/lastfm-stats/index.md | 34 ++ content/resources/lavalamp/index.md | 27 ++ layouts/resources/list.html | 20 + layouts/resources/single.html | 42 ++ layouts/resources/summary.html | 25 ++ 10 files changed, 721 insertions(+) create mode 100644 archetypes/resources/index.md create mode 100644 assets/sass/pages/resources.scss create mode 100644 content/resources/_index.md create mode 100644 content/resources/lastfm-stats/index.md create mode 100644 content/resources/lavalamp/index.md create mode 100644 layouts/resources/list.html create mode 100644 layouts/resources/single.html create mode 100644 layouts/resources/summary.html diff --git a/archetypes/resources/index.md b/archetypes/resources/index.md new file mode 100644 index 0000000..6363485 --- /dev/null +++ b/archetypes/resources/index.md @@ -0,0 +1,12 @@ +--- +title: "{{ replace .File.ContentBaseName "-" " " | title }}" +date: {{ .Date }} +tags: [] +description: "" +icon: "" +demo_url: "" +source_url: "" +draft: false +--- + +Resource description here. diff --git a/assets/sass/pages/resources.scss b/assets/sass/pages/resources.scss new file mode 100644 index 0000000..65c6a81 --- /dev/null +++ b/assets/sass/pages/resources.scss @@ -0,0 +1,549 @@ +// Resources Whiteboard Page +.resources-page { + min-height: 100vh; + padding: 2rem 1rem; + + @include media-up(md) { + padding: 3rem 2rem; + } +} + +.resources-container { + max-width: 1400px; + margin: 0 auto; +} + +.whiteboard { + background: linear-gradient(135deg, #f5f5f0 0%, #e8e8dd 100%); + border-radius: 8px; + padding: 3rem 2rem; + box-shadow: + 0 10px 40px rgba(0, 0, 0, 0.1), + inset 0 0 100px rgba(0, 0, 0, 0.02); + position: relative; + + // Subtle texture overlay + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0, 0, 0, 0.01) 2px, rgba(0, 0, 0, 0.01) 4px), + repeating-linear-gradient(90deg, transparent, transparent 2px, rgba(0, 0, 0, 0.01) 2px, rgba(0, 0, 0, 0.01) 4px); + pointer-events: none; + border-radius: 8px; + } +} + +.whiteboard-header { + text-align: center; + margin-bottom: 4rem; + position: relative; + z-index: 1; + + h1 { + font-size: 3rem; + color: #2c3e50; + margin-bottom: 1rem; + font-weight: 700; + } + + .whiteboard-description { + color: #546e7a; + font-size: 1.1rem; + max-width: 600px; + margin: 0 auto; + } +} + +.whiteboard-pins { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 3rem; + position: relative; + z-index: 1; + + @include media-up(lg) { + grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + } +} + +// Resource Pin (Post-it note style) +.resource-pin { + position: relative; + transform: rotate(0deg); + transition: transform 0.3s ease, box-shadow 0.3s ease; + + // Random slight rotations for pins + &:nth-child(3n+1) { + transform: rotate(-1deg); + } + + &:nth-child(3n+2) { + transform: rotate(1deg); + } + + &:nth-child(3n+3) { + transform: rotate(-0.5deg); + } + + &:hover { + transform: rotate(0deg) translateY(-5px) !important; + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2); + z-index: 10; + + .pin-tack { + transform: translateY(-2px); + } + } +} + +// Pin tack at the top +.pin-tack { + position: absolute; + top: -15px; + left: 50%; + transform: translateX(-50%); + width: 20px; + height: 20px; + background: radial-gradient(circle at 30% 30%, #ff6b6b, #c92a2a); + border-radius: 50%; + box-shadow: + 0 2px 5px rgba(0, 0, 0, 0.3), + inset -2px -2px 4px rgba(0, 0, 0, 0.2); + z-index: 2; + transition: transform 0.3s ease; + + &::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 6px; + height: 6px; + background: #fff; + border-radius: 50%; + opacity: 0.5; + } +} + +// Resource card (the note itself) +.resource-card { + background: linear-gradient(135deg, #fef9c3 0%, #fde68a 100%); + padding: 2rem 1.5rem 1.5rem; + border-radius: 4px; + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.1), + inset 0 -40px 40px -20px rgba(0, 0, 0, 0.05); + min-height: 280px; + display: flex; + flex-direction: column; + gap: 1rem; + + // Vary note colors + .resource-pin:nth-child(4n+1) & { + background: linear-gradient(135deg, #fef9c3 0%, #fde68a 100%); // Yellow + } + + .resource-pin:nth-child(4n+2) & { + background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%); // Blue + } + + .resource-pin:nth-child(4n+3) & { + background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%); // Green + } + + .resource-pin:nth-child(4n+4) & { + background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%); // Pink + } +} + +.resource-icon { + width: 80px; + height: 80px; + margin: 0 auto 1rem; + position: relative; + + // Lavalamp icon + &.lavalamp { + background: linear-gradient(180deg, transparent 0%, transparent 20%, #9333ea 20%, #7c3aed 100%); + border-radius: 10px 10px 40px 40px; + border: 3px solid #6b21a8; + position: relative; + box-shadow: inset 0 0 20px rgba(147, 51, 234, 0.3); + + // Lamp base + &::before { + content: ''; + position: absolute; + bottom: -8px; + left: 50%; + transform: translateX(-50%); + width: 90%; + height: 12px; + background: #1f2937; + border-radius: 4px; + } + + // Lava blobs + &::after { + content: ''; + position: absolute; + top: 30%; + left: 30%; + width: 25px; + height: 30px; + background: radial-gradient(circle, #ec4899 0%, #db2777 100%); + border-radius: 50% 50% 40% 60%; + opacity: 0.9; + animation: float-blob 4s ease-in-out infinite; + } + } + + // Last.fm stats icon + &.lastfm-stats { + background: linear-gradient(135deg, #d32323 0%, #b71c1c 100%); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + overflow: hidden; + + // Equalizer bars + &::before, + &::after { + content: ''; + position: absolute; + bottom: 15px; + width: 8px; + background: #fff; + border-radius: 2px; + } + + &::before { + left: 20px; + height: 35px; + animation: equalizer-1 0.8s ease-in-out infinite; + } + + &::after { + left: 35px; + height: 25px; + animation: equalizer-2 0.8s ease-in-out infinite 0.2s; + } + } +} + +// Additional lava blob for lavalamp +.resource-icon.lavalamp { + & > span { + position: absolute; + top: 50%; + right: 25%; + width: 20px; + height: 25px; + background: radial-gradient(circle, #f97316 0%, #ea580c 100%); + border-radius: 60% 40% 50% 50%; + opacity: 0.85; + animation: float-blob-2 3.5s ease-in-out infinite; + } + + // Create the blob with a pseudo-element instead + &:not(:empty)::before { + // Override for when we add content + animation: float-blob 4s ease-in-out infinite; + } +} + +// Last.fm additional bars +.resource-icon.lastfm-stats { + & > span { + position: absolute; + bottom: 15px; + width: 8px; + background: #fff; + border-radius: 2px; + + &:nth-child(1) { + left: 50px; + height: 30px; + animation: equalizer-3 0.8s ease-in-out infinite 0.4s; + } + } +} + +@keyframes float-blob { + 0%, 100% { + transform: translateY(0) scale(1); + } + 50% { + transform: translateY(-15px) scale(1.1); + } +} + +@keyframes float-blob-2 { + 0%, 100% { + transform: translateY(0) scale(1); + } + 50% { + transform: translateY(-20px) scale(0.9); + } +} + +@keyframes equalizer-1 { + 0%, 100% { + height: 35px; + } + 50% { + height: 20px; + } +} + +@keyframes equalizer-2 { + 0%, 100% { + height: 25px; + } + 50% { + height: 40px; + } +} + +@keyframes equalizer-3 { + 0%, 100% { + height: 30px; + } + 50% { + height: 15px; + } +} + +.resource-info { + flex: 1; + display: flex; + flex-direction: column; + + h2 { + font-size: 1.5rem; + margin: 0 0 0.5rem 0; + color: #1f2937; + font-weight: 600; + + a { + color: inherit; + text-decoration: none; + transition: color 0.2s ease; + + &:hover { + color: #3b82f6; + } + } + } +} + +.resource-description { + color: #4b5563; + font-size: 0.95rem; + line-height: 1.5; + margin: 0 0 1rem 0; + flex: 1; +} + +.resource-tags { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1rem; + + .tag { + background: rgba(0, 0, 0, 0.1); + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-size: 0.8rem; + color: #374151; + text-decoration: none; + transition: background 0.2s ease; + + &:hover { + background: rgba(0, 0, 0, 0.2); + } + } +} + +.resource-links { + display: flex; + gap: 0.75rem; + margin-top: auto; + + .resource-link { + flex: 1; + padding: 0.5rem 1rem; + text-align: center; + text-decoration: none; + border-radius: 4px; + font-weight: 500; + font-size: 0.9rem; + transition: all 0.2s ease; + + &.demo { + background: #3b82f6; + color: #fff; + + &:hover { + background: #2563eb; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(59, 130, 246, 0.4); + } + } + + &.source { + background: #1f2937; + color: #fff; + + &:hover { + background: #111827; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(31, 41, 55, 0.4); + } + } + } +} + +// Single Resource Page +.resource-single { + max-width: 900px; + margin: 0 auto; + padding: 2rem 1rem; + + @include media-up(md) { + padding: 3rem 2rem; + } +} + +.resource-content { + background: #fff; + border-radius: 8px; + padding: 3rem 2rem; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + + @include media-up(md) { + padding: 4rem 3rem; + } +} + +.resource-header { + text-align: center; + margin-bottom: 3rem; + padding-bottom: 2rem; + border-bottom: 2px solid #e5e7eb; + + h1 { + font-size: 2.5rem; + color: #1f2937; + margin: 1rem 0; + + @include media-up(md) { + font-size: 3rem; + } + } + + .lead { + font-size: 1.25rem; + color: #6b7280; + margin: 1rem 0; + } +} + +.resource-icon-large { + width: 120px; + height: 120px; + margin: 0 auto; + + &.lavalamp, + &.lastfm-stats { + // Inherit styles from smaller icons + } +} + +.resource-body { + color: #374151; + line-height: 1.8; + font-size: 1.1rem; + + h2 { + color: #1f2937; + margin-top: 2rem; + margin-bottom: 1rem; + } + + p { + margin-bottom: 1rem; + } + + code { + background: #f3f4f6; + padding: 0.2rem 0.4rem; + border-radius: 4px; + font-size: 0.9em; + } + + pre { + background: #1f2937; + color: #e5e7eb; + padding: 1.5rem; + border-radius: 8px; + overflow-x: auto; + margin: 1.5rem 0; + + code { + background: none; + padding: 0; + color: inherit; + } + } +} + +.resource-navigation { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 3rem; + padding-top: 2rem; + border-top: 2px solid #e5e7eb; + gap: 1rem; + flex-wrap: wrap; + + .nav-link { + padding: 0.75rem 1.5rem; + background: #f3f4f6; + color: #374151; + text-decoration: none; + border-radius: 6px; + font-weight: 500; + transition: all 0.2s ease; + + &:hover { + background: #e5e7eb; + transform: translateY(-2px); + } + + &.back { + background: #3b82f6; + color: #fff; + + &:hover { + background: #2563eb; + } + } + + &.prev, + &.next { + flex: 1; + min-width: 150px; + } + } +} diff --git a/assets/sass/style.scss b/assets/sass/style.scss index 06338fa..31ff094 100644 --- a/assets/sass/style.scss +++ b/assets/sass/style.scss @@ -23,6 +23,7 @@ @import "pages/now"; @import "pages/blog"; @import "pages/media"; +@import "pages/resources"; @import url("https://fonts.bunny.net/css2?family=Caveat:wght@400..700&family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&family=Neonderthaw&display=swap"); diff --git a/config.yml b/config.yml index ddcd53b..f9b9050 100644 --- a/config.yml +++ b/config.yml @@ -52,6 +52,10 @@ menu: name: gear & edc url: /gear/ weight: 10 + - identifier: resources + name: resources + url: /resources/ + weight: 12 - identifier: archives name: archives url: /archives/ diff --git a/content/resources/_index.md b/content/resources/_index.md new file mode 100644 index 0000000..192e39c --- /dev/null +++ b/content/resources/_index.md @@ -0,0 +1,7 @@ +--- +title: "Resources" +description: "A collection of useful tools, scripts, and experiments" +draft: false +--- + +Welcome to my whiteboard of resources. Here you'll find various tools, scripts, and experiments I've built and wanted to share. diff --git a/content/resources/lastfm-stats/index.md b/content/resources/lastfm-stats/index.md new file mode 100644 index 0000000..b33e843 --- /dev/null +++ b/content/resources/lastfm-stats/index.md @@ -0,0 +1,34 @@ +--- +title: "Last.fm Weekly Stats Script" +date: 2026-01-04 +tags: ["javascript", "api", "last.fm"] +description: "Fetch and display your weekly listening stats from Last.fm" +icon: "lastfm-stats" +demo_url: "" +source_url: "" +draft: false +--- + +A handy script for pulling your weekly listening statistics from Last.fm's API. Perfect for tracking your music habits and creating weekly listening reports. + +## Features + +- Fetches weekly top tracks from Last.fm +- Displays track count and listening time +- Formats data in a clean, readable format +- Easy to integrate into blogs or dashboards + +## Setup + +1. Get your Last.fm API key from [Last.fm API](https://www.last.fm/api) +2. Configure your username in the script +3. Run the script to fetch your weekly stats + +## Output + +The script returns your top tracks for the week, including: +- Track name and artist +- Play count +- Listening duration + +Great for weekly blog posts or personal music tracking! diff --git a/content/resources/lavalamp/index.md b/content/resources/lavalamp/index.md new file mode 100644 index 0000000..1660430 --- /dev/null +++ b/content/resources/lavalamp/index.md @@ -0,0 +1,27 @@ +--- +title: "HTML/CSS Lavalamp" +date: 2026-01-04 +tags: ["css", "html", "animation"] +description: "A pure CSS lavalamp animation with floating blobs" +icon: "lavalamp" +demo_url: "" +source_url: "" +draft: false +--- + +A mesmerizing lavalamp effect created entirely with HTML and CSS. Features smooth floating animations and gradient blobs that rise and fall like a classic lava lamp. + +## Features + +- Pure CSS animation (no JavaScript required) +- Customizable colors and blob shapes +- Smooth, organic floating motion +- Responsive design + +## How It Works + +The animation uses CSS keyframes to create the illusion of blobs floating up and down. Multiple blob elements with different animation delays create a realistic lava lamp effect. + +## Usage + +Simply copy the HTML and CSS into your project. You can customize the colors by changing the gradient values and adjust the animation speed by modifying the animation duration. diff --git a/layouts/resources/list.html b/layouts/resources/list.html new file mode 100644 index 0000000..7b25983 --- /dev/null +++ b/layouts/resources/list.html @@ -0,0 +1,20 @@ +{{ define "main" }} +<div class="resources-page"> + <div class="resources-container"> + <div class="whiteboard"> + <div class="whiteboard-header"> + <h1>{{ .Title }}</h1> + <div class="whiteboard-description"> + {{ .Content }} + </div> + </div> + + <div class="whiteboard-pins"> + {{ range .Pages }} + {{ .Render "summary" }} + {{ end }} + </div> + </div> + </div> +</div> +{{ end }} diff --git a/layouts/resources/single.html b/layouts/resources/single.html new file mode 100644 index 0000000..1229678 --- /dev/null +++ b/layouts/resources/single.html @@ -0,0 +1,42 @@ +{{ define "main" }} +<div class="resource-single"> + <article class="resource-content"> + <header class="resource-header"> + <div class="resource-icon-large {{ .Params.icon }}"></div> + <h1>{{ .Title }}</h1> + {{ if .Params.description }} + <p class="lead">{{ .Params.description }}</p> + {{ end }} + {{ if .Params.tags }} + <div class="resource-tags"> + {{ range .Params.tags }} + <a href="{{ printf "/tags/%s/" (. | urlize) }}" class="tag">{{ . }}</a> + {{ end }} + </div> + {{ end }} + <div class="resource-links"> + {{ if .Params.demo_url }} + <a href="{{ .Params.demo_url }}" class="resource-link demo" target="_blank">View Demo</a> + {{ end }} + {{ if .Params.source_url }} + <a href="{{ .Params.source_url }}" class="resource-link source" target="_blank">View Source</a> + {{ end }} + </div> + </header> + + <div class="resource-body"> + {{ .Content }} + </div> + + <nav class="resource-navigation"> + {{ with .PrevInSection }} + <a href="{{ .Permalink }}" class="nav-link prev">← {{ .Title }}</a> + {{ end }} + <a href="/resources/" class="nav-link back">Back to Resources</a> + {{ with .NextInSection }} + <a href="{{ .Permalink }}" class="nav-link next">{{ .Title }} →</a> + {{ end }} + </nav> + </article> +</div> +{{ end }} diff --git a/layouts/resources/summary.html b/layouts/resources/summary.html new file mode 100644 index 0000000..4962fdf --- /dev/null +++ b/layouts/resources/summary.html @@ -0,0 +1,25 @@ +<div class="resource-pin" data-icon="{{ .Params.icon }}"> + <div class="pin-tack"></div> + <div class="resource-card"> + <div class="resource-icon {{ .Params.icon }}"></div> + <div class="resource-info"> + <h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2> + <p class="resource-description">{{ .Params.description }}</p> + {{ if .Params.tags }} + <div class="resource-tags"> + {{ range .Params.tags }} + <span class="tag">{{ . }}</span> + {{ end }} + </div> + {{ end }} + <div class="resource-links"> + {{ if .Params.demo_url }} + <a href="{{ .Params.demo_url }}" class="resource-link demo" target="_blank">Demo</a> + {{ end }} + {{ if .Params.source_url }} + <a href="{{ .Params.source_url }}" class="resource-link source" target="_blank">Source</a> + {{ end }} + </div> + </div> + </div> +</div>