Adding start of the /now page

This commit is contained in:
Dan 2025-12-29 18:33:30 +00:00
parent b4d33e213d
commit 65b5ec1978
28 changed files with 2413 additions and 36 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 KiB

View file

@ -0,0 +1,6 @@
<svg width="150" height="250" xmlns="http://www.w3.org/2000/svg">
<rect width="150" height="250" fill="#2f4f4f"/>
<text x="75" y="125" font-family="Arial, sans-serif" font-size="14" fill="white" text-anchor="middle" writing-mode="tb" transform="rotate(180 75 125)">
Designing Data-Intensive Apps
</text>
</svg>

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1,6 @@
<svg width="150" height="250" xmlns="http://www.w3.org/2000/svg">
<rect width="150" height="250" fill="#1a472a"/>
<text x="75" y="125" font-family="Arial, sans-serif" font-size="16" fill="white" text-anchor="middle" writing-mode="tb" transform="rotate(180 75 125)">
The Phoenix Project
</text>
</svg>

After

Width:  |  Height:  |  Size: 311 B

View file

@ -0,0 +1,6 @@
<svg width="150" height="250" xmlns="http://www.w3.org/2000/svg">
<rect width="150" height="250" fill="#8b4513"/>
<text x="75" y="125" font-family="Arial, sans-serif" font-size="16" fill="white" text-anchor="middle" writing-mode="tb" transform="rotate(180 75 125)">
The Rust Programming Language
</text>
</svg>

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1,12 @@
<svg width="120" height="180" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="akira-grad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#8b0000;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2d0000;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="120" height="180" fill="url(#akira-grad)"/>
<text x="60" y="100" font-family="Arial, sans-serif" font-size="28" font-weight="bold" fill="#fff" text-anchor="middle">
AKIRA
</text>
</svg>

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,15 @@
<svg width="120" height="180" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="br-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1a1a2e;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0f0f1e;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="120" height="180" fill="url(#br-grad)"/>
<text x="60" y="90" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#00ff9f" text-anchor="middle">
BLADE
</text>
<text x="60" y="110" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#00ff9f" text-anchor="middle">
RUNNER
</text>
</svg>

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -0,0 +1,15 @@
<svg width="120" height="180" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gits-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4a148c;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1a0a3c;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="120" height="180" fill="url(#gits-grad)"/>
<text x="60" y="80" font-family="Arial, sans-serif" font-size="14" fill="#00ffff" text-anchor="middle">
GHOST IN
</text>
<text x="60" y="100" font-family="Arial, sans-serif" font-size="14" fill="#00ffff" text-anchor="middle">
THE SHELL
</text>
</svg>

After

Width:  |  Height:  |  Size: 644 B

View file

@ -0,0 +1,9 @@
<svg width="120" height="180" xmlns="http://www.w3.org/2000/svg">
<rect width="120" height="180" fill="#000"/>
<text x="60" y="90" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#0f0" text-anchor="middle">
THE
</text>
<text x="60" y="110" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#0f0" text-anchor="middle">
MATRIX
</text>
</svg>

After

Width:  |  Height:  |  Size: 404 B

1748
assets/sass/pages/now.scss Normal file

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
@import "pages/about";
@import "pages/audio";
@import "pages/now";
@import url("https://fonts.googleapis.com/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");

View file

@ -4,6 +4,9 @@ date: 2025-01-12
tags: ["album"]
description: ""
cover: "cover.jpg"
render: never
build:
render: never
---
Neon Odin's _Allfather_ feels like mythology filtered through analog circuits and a CRT glow (much like myself). The album merges darksynth with handcrafted Nordic folk instruments - talharpa and nyckelharpa built by the artist himself - creating something that shouldn't work but absolutely does.

View file

@ -4,13 +4,15 @@ date: 2025-12-12
tags: ["album"]
description: ""
cover: "cover.jpg"
build:
render: never
---
Ninajirachi's _I Love My Computer_ captures something truthful about growing up shaped by screens and bandwidth. The album explores that strange intimacy we developed with our machines - the late nights, the secret discoveries, the way technology became less of a tool and more of a companion.
Tracks like "Fuck My Computer" and "iPod Touch" aren't just bangers; they're confessions about a relationship that transcends generations. Whether you learned HTML on Geocities or taught yourself production in GarageBand, there's recognition here.
The production has a restless energy, shifting between euphoric and introspective, mirroring how the internet itself feelschaotic, isolating, and strangely beautiful all at once. It's a debut album that understands what it meant to have your world widened by a glowing rectangle - and I relate deeply to its content despite being at least one generation older than Ninajirachi.
The production has a restless energy, shifting between euphoric and introspective, mirroring how the internet itself feels - chaotic, isolating, and strangely beautiful all at once. It's a debut album that understands what it meant to have your world widened by a glowing rectangle - and I relate deeply to its content despite being at least one generation older than Ninajirachi.
Not my usual genre of listen, but it has been a regular spin since it came into my world.

15
content/now/currently.md Normal file
View file

@ -0,0 +1,15 @@
---
title: Currently
width: 500px
height: 550px
sticky_notes:
- text: "Remember to update blog!"
color: "yellow"
- text: "New feature idea: dark mode toggle"
color: "pink"
---
**Tinkering with:**
- ritual.sh - This website! I've been exploring the indieweb movement and working on this site to carve out my own little digital garden to tend. I'm having a lot of fun making art using pure CSS.
- After years of using Linux exclusively for servers, Microsoft's relentless [enshittification](https://en.wikipedia.org/wiki/Enshittification) of Windows finally pushed me to migrate my actual workstations. Now running Linux on most machines (currently experimenting with Bazzite) and MacOS on the rest. Desktop customisation is as enjoyable as it was back in the day - maybe more so.

View file

@ -0,0 +1,23 @@
---
title: Daily Drivers
width: 450px
height: 550px
order: 3
---
**Desktop:**
- OS: Bazzite Linux
- DE: KDE Plasma
- Terminal: kitty
- Editor: VSCode / Neovim
- Browser: Firefox
- Shell: Zsh + Oh My Zsh
**Hardware:**
- CPU: Ryzen 7 9800X3D
- GPU: Radeon RX 7900 XTX
- RAM: 64GB DDR5
- Camera: Fuji X-T5
- Audio: Hiby R4 EVA, Fiio FT-1

28
content/now/homelab.md Normal file
View file

@ -0,0 +1,28 @@
---
title: Homelab Architecture
width: 550px
height: 600px
order: 4
---
**Network Topology:**
```
Internet
|
+-- Firewall
|
+-- Core Switch
|
+-- PROD Servers
+-- DEV Environment
+-- Storage/NAS
+-- Services
```
**Self-Hosted Services:**
- Git server, CI/CD
- Media server
- Home automation
- Monitoring stack

View file

@ -0,0 +1,21 @@
---
title: Learning Queue
width: 400px
height: 500px
order: 2
---
**2025 Goals:**
- Master Rust programming
- Build a complete homelab
- Contribute to FOSS projects
- Advanced photography
- Music production basics
- Kubernetes certification
**Books in Progress:**
- The Rust Programming Language
- Designing Data-Intensive Applications
- The Phoenix Project

View file

@ -3,6 +3,8 @@ title: "2025 12 08 Homepage"
date: 2025-12-08T14:02:19Z
tags: []
description: ""
build:
render: never
---
First version of the homepage created with the interactive terminal.

View file

@ -3,6 +3,8 @@ title: "2025 12 09 About"
date: 2025-12-09T14:07:59Z
tags: []
description: ""
build:
render: never
---
Added initial version of the about page with some approximation of a manifesto.

View file

@ -3,6 +3,8 @@ title: "2025 12 13 Album Reviews"
date: 2025-12-13T15:16:18Z
tags: []
description: ""
build:
render: never
---
Added some of my thoughts about Allfather by Neon Odin and I Love My Computer by Ninajirachi

View file

@ -3,6 +3,8 @@ title: "2025 12 13 Music"
date: 2025-12-13T14:09:08Z
tags: []
description: ""
build:
render: never
---
Created the music and audio gear section!

View file

@ -1,37 +1,176 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Basement Window</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
{{ define "main" }}
<div class="server-room">
<!-- Page title sign -->
<div class="server-room-sign">
<div class="sign-frame">
<div class="sign-content">
<div class="sign-title">/NOW</div>
<div class="sign-subtitle">Updated {{ now.Format "02/01/2006" }}</div>
</div>
</div>
</div>
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%);
font-family: "Courier New", monospace;
overflow: hidden;
}
<div class="server-room-container">
<!-- Server Rack 1: Production Infrastructure -->
<!-- prettier-ignore -->
{{ partial "elements/server-rack.html"
(dict "height" "650px" "title" "PROD-RACK-01"
"units" (slice
(dict "type" "switch" "label" "Core-SW-01" "ports" 24)
(dict "type" "spacer")
(dict "type" "server" "label" "WEB-01" "led1" "green" "led2" "green" "drives" 1)
(dict "type" "server" "label" "WEB-02" "led1" "green" "led2" "amber" "drives" 1)
(dict "type" "server" "label" "DB-01" "led1" "green" "led2" "green" "drives" 2)
(dict "type" "spacer")
(dict "type" "patch-panel" "ports" 24)
(dict "type" "blank")
(dict "type" "server" "label" "API-01" "led1" "green" "led2" "blue" "drives" 1)
(dict "type" "server" "label" "Cache-01" "led1" "green" "led2" "green" "drives" 1)
) ) }}
.basement-wall {
width: 100%;
max-width: 800px;
padding: 20px;
position: relative;
color: #fff;
text-align: center;
<!-- Whiteboard: Currently -->
{{ partial "elements/whiteboard.html" (dict "file" "currently.md" "context" .) }}
<!-- Server Rack 2: Storage & Backup -->
<!-- prettier-ignore -->
{{ partial "elements/server-rack.html"
(dict "height" "650px" "title" "STORAGE-01"
"units" (slice
(dict "type" "server" "label" "NAS-01" "led1" "green" "led2" "green" "drives" 1 "size" 1)
(dict "type" "spacer")
(dict "type" "storage" "label" "SAN-Primary" "drives" 12 "size" 3)
(dict "type" "spacer")
(dict "type" "server" "label" "Backup-01" "led1" "blue" "led2" "amber" "drives" 2)
(dict "type" "blank")
) ) }}
<!-- Terminal Desk -->
<div class="terminal-desk">
<div class="terminal-monitor">
<div class="terminal-screen">
<div style="color: #0f0; text-shadow: 0 0 5px #0f0">
<p>$ whoami</p>
<p>dan@ritual.sh</p>
<br />
<p>$ cat current_stack.txt</p>
<p>Languages: JavaScript, TypeScript, Python, Rust (learning)</p>
<p>Frontend: React, Vue, Hugo</p>
<p>Backend: Node.js, FastAPI</p>
<p>DevOps: Docker, Linux, Git</p>
<p>Interests: Homelab, Self-hosting, Open Source</p>
<br />
<p>$ uptime</p>
<p>
{{ now.Format "15:04:05" }} up 42 days, load average: 0.15, 0.23,
0.18
</p>
<br />
<p><span class="cursor-blink">_</span></p>
</div>
</div>
</div>
<div class="desk-surface"></div>
<div
class="ambient-light green"
style="bottom: 200px; left: 50%; width: 200px; height: 200px"
></div>
</div>
<!-- Bookshelf: Currently Reading -->
<!-- prettier-ignore -->
{{ partial "elements/bookshelf.html" (dict
"width" "350px"
"height" "600px"
"title" "Currently Reading"
"type" "books"
"shelves" 1
"items" (slice
(dict "image" "images/books/alchemised.png" "title" "Alchemised" "current" true)
)
) }}
<!-- Whiteboard: Daily Drivers -->
{{ partial "elements/whiteboard.html" (dict "file" "daily-drivers.md" "context" .) }}
<!-- Server Rack 3: Dev & Testing -->
<!-- prettier-ignore -->
{{ partial "elements/server-rack.html"
(dict "height" "700px" "title" "DEV-RACK-01"
"units" (slice
(dict "type" "switch" "label" "Dev-SW-01" "ports" 24)
(dict "type" "patch-panel" "label" "Patch-Dev" "ports" 24)
(dict "type" "spacer")
(dict "type" "server" "label" "Dev-01" "led1" "green" "led2" "amber" "drives" 2)
(dict "type" "server" "label" "Dev-02" "led1" "blue" "led2" "green" "drives" 2)
(dict "type" "server" "label" "Test-01" "led1" "green" "led2" "red" "drives" 1)
(dict "type" "spacer")
(dict "type" "server" "label" "CI/CD" "led1" "green" "led2" "green" "drives" 2)
(dict "type" "blank")
(dict "type" "server" "label" "Monitoring" "led1" "blue" "led2" "amber" "drives" 1)
)) }}
<!-- Whiteboard: Learning Queue -->
{{ partial "elements/whiteboard.html" (dict "file" "learning-queue.md" "context" .) }}
<!-- Server Rack 4: Power & Network -->
<!-- prettier-ignore -->
{{ partial "elements/server-rack.html" (dict "height" "550px" "title"
"INFRA-01" "units" (slice (dict "type" "ups" "label" "UPS-Primary"
"capacity" "98" "size" 2) (dict "type" "spacer") (dict "type" "switch"
"label" "Edge-SW-01" "ports" 24) (dict "type" "server" "label" "Firewall"
"led1" "green" "led2" "green" "drives" 1) (dict "type" "server" "label"
"DNS/DHCP" "led1" "green" "led2" "blue" "drives" 1) (dict "type" "blank")
(dict "type" "blank") ) ) }}
<!-- DVD Collection -->
<!-- prettier-ignore -->
{{ partial "elements/bookshelf.html" (dict "width" "400px" "height" "550px"
"title" "DVD Collection" "type" "dvds" "shelves" 2 "items" (slice (dict
"image" "images/dvds/dandadan.png" "title" "DAN DA DAN" "current" true)
(dict "image" "images/dvds/assassination_classroom.jpg" "title"
"Assassination Classroom") ) ) }}
<!-- Whiteboard: Homelab Architecture -->
{{ partial "elements/whiteboard.html" (dict "file" "homelab.md" "context" .) }}
<!-- Monitor: System Metrics -->
{{ partial "elements/monitor-screen.html" (dict "width" "400px" "height"
"350px" "type" "metrics" "title" "WEB-01 - METRICS" "color" "green" ) }}
<!-- Monitor: Live Graph -->
{{ partial "elements/monitor-screen.html" (dict "width" "450px" "height"
"380px" "type" "graph" "title" "NETWORK TRAFFIC" "color" "blue" ) }}
<!-- Monitor: System Logs -->
{{ partial "elements/monitor-screen.html" (dict "width" "420px" "height"
"400px" "type" "logs" "title" "SYSTEM LOGS" "color" "green" ) }}
<!-- Monitor: Network Stats -->
{{ partial "elements/monitor-screen.html" (dict "width" "380px" "height"
"380px" "type" "network" "title" "BANDWIDTH MONITOR" "color" "amber" ) }}
<!-- Monitor: Terminal -->
{{ partial "elements/monitor-screen.html" (dict "width" "400px" "height"
"320px" "type" "terminal" "title" "db-primary.local" "color" "green" ) }}
</div>
</div>
<script>
// Enable horizontal scrolling with mouse wheel
const serverRoom = document.querySelector(".server-room");
if (serverRoom) {
serverRoom.addEventListener(
"wheel",
(e) => {
// Check if there's horizontal scrollable content
if (serverRoom.scrollWidth > serverRoom.clientWidth) {
e.preventDefault();
serverRoom.scrollLeft += e.deltaY;
}
</style>
</head>
<body>
<div class="basement-wall">Coming soon...</div>
</body>
</html>
},
{ passive: false },
);
}
</script>
{{ end }}

View file

@ -0,0 +1,39 @@
{{ $items := .items | default (slice) }} {{ $shelves := .shelves | default 4 }}
{{ $width := .width | default "300px" }} {{ $height := .height | default "400px"
}} {{ $type := .type | default "books" }} {{ $title := .title | default "" }}
<div class="bookshelf">
{{ if $title }}
<div class="bookshelf-title">{{ $title }}</div>
{{ end }} {{ range seq $shelves }}
<div class="shelf">
<div class="shelf-board"></div>
<div class="shelf-items">
{{ if $items }} {{ range $items }}
<div class="shelf-item item {{ if .current }}current{{ end }}">
{{ if .image }} {{ $img := resources.Get .image }} {{ if $img }} {{
$resized := $img.Resize "100x120" }}
<img
src="{{ $resized.RelPermalink }}"
alt="{{ .title }}"
class="dvd-cover"
/>
{{ end }} {{ end }} {{ if .current }}
<div class="current-indicator">
<div class="current-glow"></div>
<div class="current-label">
{{ if eq $type "dvds" }}WATCHING{{ else }}READING{{ end }}
</div>
</div>
{{ end }}
</div>
{{ end }} {{ end }}
</div>
</div>
{{ end }}
<div class="bookshelf-frame"></div>
<div class="bookshelf-legs">
<div class="bookshelf-leg leg-left"></div>
<div class="bookshelf-leg leg-right"></div>
</div>
</div>

View file

@ -0,0 +1,142 @@
{{ $width := .width | default "400px" }}
{{ $height := .height | default "350px" }}
{{ $type := .type | default "metrics" }}
{{ $title := .title | default "System Monitor" }}
{{ $color := .color | default "green" }}
<div class="monitor-screen" style="width: {{ $width }}; height: {{ $height }};">
<div class="monitor-bezel monitor-bezel-{{ $color }}">
<div class="monitor-display monitor-display-{{ $color }} crt">
<div class="monitor-content screen-display">
{{ if eq $type "metrics" }}
<!-- System Metrics Display -->
<div class="metrics-header">{{ $title }}</div>
<div class="metrics-grid">
<div class="metric-item">
<div class="metric-label">CPU</div>
<div class="metric-bar">
<div class="metric-fill metric-fill-animated" style="width: 67%; animation-delay: 0s;"></div>
</div>
<div class="metric-value">67%</div>
</div>
<div class="metric-item">
<div class="metric-label">RAM</div>
<div class="metric-bar">
<div class="metric-fill metric-fill-animated" style="width: 82%; animation-delay: 0.2s;"></div>
</div>
<div class="metric-value">82%</div>
</div>
<div class="metric-item">
<div class="metric-label">DISK</div>
<div class="metric-bar">
<div class="metric-fill metric-fill-animated" style="width: 45%; animation-delay: 0.4s;"></div>
</div>
<div class="metric-value">45%</div>
</div>
<div class="metric-item">
<div class="metric-label">NET</div>
<div class="metric-bar">
<div class="metric-fill metric-fill-animated" style="width: 34%; animation-delay: 0.6s;"></div>
</div>
<div class="metric-value">34%</div>
</div>
</div>
{{ else if eq $type "graph" }}
<!-- Live Graph Display -->
<div class="metrics-header">{{ $title }}</div>
<div class="graph-container">
<div class="graph-wrapper">
<!-- First instance of the graph -->
<svg class="graph-svg graph-instance" viewBox="0 0 300 150" preserveAspectRatio="none">
<polyline class="graph-line graph-line-{{ $color }}"
points="0,80 10,75 20,85 30,78 40,65 50,70 60,60 70,55 80,65 90,58 100,45 110,50 120,40 130,35 140,45 150,38 160,25 170,30 180,20 190,15 200,25 210,18 220,12 230,20 240,15 250,25 260,22 270,28 280,25 290,35 300,80"
fill="none" />
<polyline class="graph-fill graph-fill-{{ $color }}"
points="0,80 10,75 20,85 30,78 40,65 50,70 60,60 70,55 80,65 90,58 100,45 110,50 120,40 130,35 140,45 150,38 160,25 170,30 180,20 190,15 200,25 210,18 220,12 230,20 240,15 250,25 260,22 270,28 280,25 290,35 300,80 300,150 0,150"
/>
</svg>
<!-- Second instance (duplicate for seamless loop) -->
<svg class="graph-svg graph-instance" viewBox="0 0 300 150" preserveAspectRatio="none">
<polyline class="graph-line graph-line-{{ $color }}"
points="0,80 10,75 20,85 30,78 40,65 50,70 60,60 70,55 80,65 90,58 100,45 110,50 120,40 130,35 140,45 150,38 160,25 170,30 180,20 190,15 200,25 210,18 220,12 230,20 240,15 250,25 260,22 270,28 280,25 290,35 300,80"
fill="none" />
<polyline class="graph-fill graph-fill-{{ $color }}"
points="0,80 10,75 20,85 30,78 40,65 50,70 60,60 70,55 80,65 90,58 100,45 110,50 120,40 130,35 140,45 150,38 160,25 170,30 180,20 190,15 200,25 210,18 220,12 230,20 240,15 250,25 260,22 270,28 280,25 290,35 300,80 300,150 0,150"
/>
</svg>
</div>
<div class="graph-grid"></div>
</div>
<div class="graph-legend">
<span class="graph-legend-item">▲ Throughput: 2.4 GB/s</span>
</div>
{{ else if eq $type "terminal" }}
<!-- Terminal Output -->
<div class="terminal-output">
<div class="terminal-line">$ systemctl status</div>
<div class="terminal-line">● {{ $title }}</div>
<div class="terminal-line"> Loaded: loaded (/etc/systemd/system/)</div>
<div class="terminal-line"> Active: <span class="status-active">active (running)</span></div>
<div class="terminal-line"> Memory: 2.4G</div>
<div class="terminal-line"> CPU: 12.5%</div>
<div class="terminal-line terminal-cursor">$<span class="cursor-blink">_</span></div>
</div>
{{ else if eq $type "logs" }}
<!-- Scrolling Logs -->
<div class="metrics-header">{{ $title }}</div>
<div class="log-container">
<div class="log-line">[OK] Started Network Manager</div>
<div class="log-line">[OK] Started User Login Management</div>
<div class="log-line log-warning">[WARN] High memory usage detected</div>
<div class="log-line">[INFO] Service nginx.service reloaded</div>
<div class="log-line">[OK] Mounted /mnt/storage</div>
<div class="log-line log-success">[OK] System backup completed</div>
<div class="log-line">[INFO] Connection established</div>
<div class="log-line">[OK] Started Docker Engine</div>
<div class="log-line log-error">[ERR] Failed to resolve hostname</div>
<div class="log-line">[INFO] Firewall rules updated</div>
</div>
{{ else if eq $type "network" }}
<!-- Network Traffic -->
<div class="metrics-header">{{ $title }}</div>
<div class="network-stats">
<div class="network-row">
<div class="network-label">↓ RX</div>
<div class="network-graph">
{{ range seq 20 }}
<div class="network-bar network-bar-rx"></div>
{{ end }}
</div>
<div class="network-value">24.3 MB/s</div>
</div>
<div class="network-row">
<div class="network-label">↑ TX</div>
<div class="network-graph">
{{ range seq 20 }}
<div class="network-bar network-bar-tx"></div>
{{ end }}
</div>
<div class="network-value">12.8 MB/s</div>
</div>
</div>
{{ end }}
</div>
<!-- Screen scanlines effect -->
<div class="monitor-scanlines"></div>
</div>
<!-- Monitor power LED -->
<div class="monitor-power-led monitor-led-{{ $color }}"></div>
</div>
<!-- Monitor stand -->
<div class="monitor-stand"></div>
</div>

View file

@ -0,0 +1,116 @@
{{ $height := .height | default "600px" }}
{{ $title := .title | default "" }}
{{ $units := .units | default (slice) }}
<div class="server-rack" style="height: {{ $height }};">
<div class="rack-frame">
{{ if $title }}
<div class="rack-label">{{ $title }}</div>
{{ end }}
{{ if $units }}
{{ range $units }}
{{ if eq .type "server" }}
<div class="server-unit {{ if .size }}server-{{ .size }}u{{ end }}">
<div class="server-front-panel">
<div class="server-led led-{{ .led1 | default "green" }}"></div>
<div class="server-led led-{{ .led2 | default "amber" }}"></div>
{{ if .label }}
<div class="server-label">{{ .label }}</div>
{{ end }}
<div class="server-drive-bays">
{{ range seq (.drives | default 2) }}
<div class="drive-bay"></div>
{{ end }}
</div>
<div class="server-vents"></div>
</div>
</div>
{{ else if eq .type "switch" }}
<div class="network-switch {{ if .size }}server-{{ .size }}u{{ end }}">
<div class="switch-front-panel">
{{ if .label }}
<div class="switch-label">{{ .label }}</div>
{{ end }}
<div class="switch-ports">
{{ range seq (.ports | default 24) }}
<div class="switch-port {{ if mod . 2 }}active{{ end }}"></div>
{{ end }}
</div>
<div class="switch-leds">
<div class="switch-status-led led-green"></div>
<div class="switch-status-led led-green"></div>
<div class="switch-status-led led-amber"></div>
</div>
</div>
</div>
{{ else if eq .type "patch-panel" }}
<div class="patch-panel {{ if .size }}server-{{ .size }}u{{ end }}">
<div class="patch-front">
{{ if .label }}
<div class="patch-label">{{ .label }}</div>
{{ end }}
<div class="patch-ports">
{{ range seq (.ports | default 24) }}
<div class="patch-port"></div>
{{ end }}
</div>
</div>
</div>
{{ else if eq .type "ups" }}
<div class="ups-unit {{ if .size }}server-{{ .size }}u{{ end }}">
<div class="ups-front-panel">
{{ if .label }}
<div class="ups-label">{{ .label }}</div>
{{ end }}
<div class="ups-display">
<div class="ups-lcd">
<span style="font-size: 10px;">{{ .capacity | default "100" }}%</span>
</div>
</div>
<div class="ups-indicators">
<div class="ups-led led-green"></div>
<div class="ups-led led-green"></div>
</div>
</div>
</div>
{{ else if eq .type "storage" }}
<div class="storage-unit {{ if .size }}server-{{ .size }}u{{ end }}">
<div class="storage-front-panel">
{{ if .label }}
<div class="storage-label">{{ .label }}</div>
{{ end }}
<div class="storage-drive-grid">
{{ range seq (.drives | default 12) }}
<div class="storage-drive">
<div class="storage-drive-led led-{{ if mod . 3 }}green{{ else }}amber{{ end }}"></div>
</div>
{{ end }}
</div>
</div>
</div>
{{ else if eq .type "blank" }}
<div class="blank-panel {{ if .size }}server-{{ .size }}u{{ end }}"></div>
{{ else if eq .type "spacer" }}
<div class="rack-spacer {{ if .size }}server-{{ .size }}u{{ end }}"></div>
{{ end }}
{{ end }}
{{ else }}
<!-- Default configuration if no units specified -->
{{ range seq 8 }}
<div class="server-unit">
<div class="server-front-panel">
<div class="server-led led-green"></div>
<div class="server-led led-amber"></div>
<div class="server-drive-bays">
<div class="drive-bay"></div>
<div class="drive-bay"></div>
</div>
<div class="server-vents"></div>
</div>
</div>
{{ end }}
{{ end }}
</div>
<div class="rack-legs"></div>
</div>

View file

@ -0,0 +1,23 @@
{{ $file := .file }}
{{ $context := .context }}
{{ with $context.Resources.GetMatch $file }}
<div class="whiteboard" style="width: {{ .Params.width }}; height: {{ .Params.height }}">
<div class="whiteboard-surface">
<div class="whiteboard-title">{{ .Title }}</div>
<div class="whiteboard-content">
{{ .Content }}
</div>
{{ if .Params.sticky_notes }}
<div class="wb-notes">
{{ range $index, $note := .Params.sticky_notes }}
{{ if lt $index 3 }}
<div class="wb-note wb-note-{{ $note.color | default "yellow" }}">
<div class="wb-note-content">{{ $note.text }}</div>
</div>
{{ end }}
{{ end }}
</div>
{{ end }}
</div>
</div>
{{ end }}