diff --git a/app/components/boot-sequence.tsx b/app/components/boot-sequence.tsx index 00019b2..1508d58 100644 --- a/app/components/boot-sequence.tsx +++ b/app/components/boot-sequence.tsx @@ -25,7 +25,7 @@ const BOOT_LINES = [ const GREETING_LINES = [ 'Welcome back, root.', - "Hi, I'm Pietro — systems engineer, developer, homelabber.", + "Hi, I'm Pietro, systems engineer, developer, homelabber.", ] const DURIN_ART = ` ______________ _ _,-----------._ ___ @@ -139,10 +139,10 @@ const EGG_ART: Record, string> = { } const EGG_CAPTIONS: Record, string> = { - moria: 'the doors of durin, lord of moria — speak, friend, and enter', - balrog: 'a demon of the ancient world — YOU SHALL NOT PASS', - iddqd: 'IDDQD — GOD MODE ON — degreelessness achieved', - idkfa: 'IDKFA — armed to the teeth — all keys, all ammo', + moria: 'the doors of durin, lord of moria: speak, friend, and enter', + balrog: 'a demon of the ancient world: YOU SHALL NOT PASS', + iddqd: 'IDDQD - GOD MODE ON - degreelessness achieved', + idkfa: 'IDKFA - armed to the teeth - all keys, all ammo', } const EGG_DURATION = 4200 @@ -333,7 +333,7 @@ export default function BootSequence({ onComplete, onReboot }: { onComplete: () disabled={eggBusy} /> -
type start to enter — speak, friend, and enter…
+
type start to enter, speak, friend, and enter…
) : (
diff --git a/app/globals.css b/app/globals.css index 182da3d..f1e8b5e 100644 --- a/app/globals.css +++ b/app/globals.css @@ -3,6 +3,7 @@ @tailwind utilities; *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} +a:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--navy2);outline-offset:2px} :root{ --stone:#F7F6F1; --stone2:#FFFFFF; @@ -409,9 +410,10 @@ nav.nav-open .nav-burger span:nth-child(3){transform:translateY(-5.5px) rotate(- .econ-tags{margin-top:22px} .langs{display:grid;grid-template-columns:repeat(5,1fr);border-top:1px solid var(--navy);margin-top:28px} -.langc{padding:16px 26px;border-bottom:1px solid var(--line)} -.langc:first-child{padding-left:0} -.langc:not(:last-child){border-right:1px solid var(--line)} +.langc{padding:16px 26px;border-bottom:1px solid var(--line);border-right:1px solid var(--line)} +.langc:nth-child(5n+1){padding-left:0} +.langc:nth-child(5n){border-right:none} +.langs .langc:last-child{border-right:none;border-bottom:none} .lang-n{font-size:13px;font-weight:600;color:var(--navy);margin-bottom:3px;font-family:var(--f-head)} .lang-l{font-size:10px;color:var(--mid);text-transform:uppercase;letter-spacing:.05em;font-family:var(--f-mono)} @@ -582,6 +584,9 @@ footer a:hover{color:var(--navy2)} .cert-row{grid-template-columns:36px 1fr} .cert-status{display:none} .langs{grid-template-columns:repeat(3,1fr)} + .langc:nth-child(5n+1){padding-left:26px} + .langc:nth-child(5n){border-right:1px solid var(--line)} + .langc:nth-child(3n+1){padding-left:0} .langc:nth-child(3n){border-right:none} } @media(max-width:700px){ @@ -590,6 +595,8 @@ footer a:hover{color:var(--navy2)} .sec-body,.about-split,.contact{padding:40px var(--pad)} .contact-body{padding:40px 24px} .langs{grid-template-columns:repeat(2,1fr)} + .langc:nth-child(3n+1){padding-left:26px} .langc:nth-child(3n){border-right:1px solid var(--line)} + .langc:nth-child(2n+1){padding-left:0} .langc:nth-child(2n){border-right:none} } diff --git a/app/not-found.tsx b/app/not-found.tsx new file mode 100644 index 0000000..3a6815c --- /dev/null +++ b/app/not-found.tsx @@ -0,0 +1,12 @@ +export default function NotFound() { + return ( +
+
404
+
Page not
found.
+

The page you’re looking for doesn’t exist or has moved.

+
+ Back to home +
+
+ ) +} diff --git a/app/page.tsx b/app/page.tsx index 97e72c9..c5248b9 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -177,8 +177,8 @@ export default function Home() {
- ▪Applied — used in production or a shipped project - ▫Exposure — coursework or limited use + ▪Applied: used in production or a shipped project + ▫Exposure: coursework or limited use
@@ -278,20 +278,20 @@ export default function Home() {

Homelab Infrastructure

- Started with a single Proxmox node — my first real server, and the one that taught me virtualisation and LXC. + Started with a single Proxmox node: my first real server, and the one that taught me virtualisation and LXC. When file storage and parity-protected array management outgrew that setup, I built Nargothrond: a dedicated UNRAID box, named after the hidden fortress from The Silmarillion. Every service containerised, every entry-point proxied, every failure logged.

-
—
Hardware
+
-
Hardware
- + - + @@ -299,7 +299,7 @@ export default function Home() {
ComponentUNRAID Server (Nargothrond)Proxmox Node
CPUIntel Core Ultra 5 225Intel Core i7-8700
MotherboardASUS Prime Z890M-Plus—
MotherboardASUS Prime Z890M-Plus-
RAM48GB DDR5 5600MHz32GB DDR4
CaseJonsbo N6—
CaseJonsbo N6-
Storage14TB + 2×12TB parity array + 2TB NVMe cache + 1TB NVMe bootSSD (OS) + SATA pool
Network10GbE (Realtek RTL8127) + 1Gbps LAN · VLANs1Gbps LAN · VLANs
OSUNRAID 7.3.1Proxmox VE 8
-
—
Services & Stack
+
-
Services & Stack
01
@@ -353,7 +353,7 @@ export default function Home() {
07
Network Segmentation
-
Six Docker networks isolate containers by sensitivity — bridge, tunnel, explo_default, a dedicated pangolin network for the security-critical core, macvlan for AdGuard, and a Tailscale overlay for Jellyfin/Immich remote access.
+
Six Docker networks isolate containers by sensitivity: bridge, tunnel, explo_default, a dedicated pangolin network for the security-critical core, macvlan for AdGuard, and a Tailscale overlay for Jellyfin/Immich remote access.
Docker networkingTailscaleVLANsZero-trust
@@ -364,7 +364,7 @@ export default function Home() {
All services reachable remotely through a combination of Tailscale mesh VPN (for trusted devices) and Cloudflare Tunnels (for public-facing services). No port-forwarding. Pangolin’s Newt agent tunnels external traffic into the private LAN.
-
—
Traffic Flow
+
-
Traffic Flow
@@ -468,7 +468,7 @@ export default function Home() {
Spun up on demand, not left running
-
A Satisfactory game server, FileFlows for media re-encoding, and an sftp-server for bulk transfers stay fully configured but stopped until a specific project or game night needs them — keeping idle power draw down.
+
A Satisfactory game server, FileFlows for media re-encoding, and an sftp-server for bulk transfers stay fully configured but stopped until a specific project or game night needs them, keeping idle power draw down.
@@ -748,7 +748,7 @@ export default function Home() {
-
—
Education
+
-
Education
-
—
Languages
+
-
Languages
Italian
Native · C2
English
Fluent · C2