From b3b3f0ce03aca0e53745024c84489be4497cf3ee Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Sun, 14 Jun 2026 15:29:00 +0200 Subject: [PATCH] :goat: --- .vscode/settings.json | 9 ++++++ index.html | 34 +++++++++++----------- style.css | 66 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b082b3f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "cSpell.words": [ + "Centvrion", + "Gade", + "Gitea", + "Nørrebro", + "PCSX" + ] +} \ No newline at end of file diff --git a/index.html b/index.html index 16a7493..716ebc5 100644 --- a/index.html +++ b/index.html @@ -144,21 +144,21 @@

I have significant experience across a range of languages and pick up new ones quickly.

- Python - Bash - C - C# - SQL - Go - Haskell - JavaScript + Python + Bash + C + C# + SQL + Go + Haskell + JavaScript

Environment

-

I've been running Arch Linux (btw) as my daily driver for around five years, so the command line feels like home. I'm comfortable with Docker for containerisation and have a solid grasp of Linux system administration.

+

I've been running Arch Linux (btw) as my daily driver for around five years, so the command line feels like home. I'm comfortable with Docker for containerization and have a solid grasp of Linux system administration.

@@ -199,7 +199,7 @@

The project has grown into something I actively maintain and support, with a small but dedicated community of around 500 players.

- PythonPCSX2 / PINEMIPS assembly + PythonPCSX2 / PINEReverse engineering
@@ -221,7 +221,7 @@

The language includes a tree-walking interpreter and a compiler that targets C. Optional modules extend the standard library with FORS (random numbers), FRACTIO (base-12 fractions for floats), MAGNVM (higher numbers than standard roman numerals), and SVBNVLLA (negative numbers).

- PythonLanguage designCompilerInterpreter + PythonLanguage designCompilerInterpreter
@@ -251,7 +251,7 @@

The frontend is built in Svelte and the backend in Python, deployed with Docker Compose.

- SveltePythonDocker + SveltePythonDockerAPIsFull-stack
@@ -271,7 +271,7 @@

Charizard is turning five this year. In that time I've learned an enormous amount about networking, Linux administration, and the particular satisfaction of fixing something broken at 2 in the morning that nobody asked you to build in the first place.

- UnraidDockerReverse ProxyNetworking + UnraidDockerReverse ProxyNetworkingSelf-hosting
@@ -299,7 +299,7 @@

Copenhagen Capacity · Copenhagen

Working on a Python codebase of web crawlers that scrape job postings from across the web, feeding a database that powers a job portal. The work involves maintaining and extending scraping pipelines, handling the messiness of real-world HTML, and keeping the data clean and consistent.

- PythonWeb scrapingDatabases + PythonWeb scrapingDatabases
@@ -313,9 +313,9 @@

IT Project Manager

360 Law Firm · Copenhagen

-

A broad role spanning data science work, internal tech support, and IT project management. Also served on the firm's AI task force, helping figure out how AI should be used in the organization.

+

Brought in to introduce business intelligence to the firm, where I planned and managed the build of a reporting pipeline that ran from API to finished report. The role broadened from there into wider data science work and internal tech support, and I served on the firm's AI task force, helping figure out how AI should be used in the organization.

- Data scienceProject managementAI + Business intelligenceData scienceProject management
@@ -331,7 +331,7 @@

Valuer.ai · Copenhagen

Database management for a neural network startup, keeping the data infrastructure that fed the core model clean, organised, and running reliably.

- Data scienceDatabasesNeural networks + Data scienceDatabases
diff --git a/style.css b/style.css index 63cfeab..1338f4a 100644 --- a/style.css +++ b/style.css @@ -353,7 +353,7 @@ main { position: relative; z-index: 1; } box-shadow: var(--card-shadow); transition: transform 0.3s var(--ease), box-shadow 0.3s; } -.skill-card:hover { transform: translateY(-5px); box-shadow: var(--glow-orange); } +.skill-card:hover { box-shadow: var(--glow-orange); } .skill-card-icon { width: 42px; height: 42px; border-radius: 10px; background: var(--grad); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 1.05rem; margin-bottom: 0.85rem; } .skill-card h3 { font-size: 1.05rem; font-weight: 800; margin-bottom: 1.25rem; } @@ -368,7 +368,7 @@ main { position: relative; z-index: 1; } transition: transform 0.3s var(--ease), box-shadow 0.3s; will-change: transform; } -.project-card:hover { transform: translateY(-4px); box-shadow: var(--glow-orange); } +.project-card:hover { box-shadow: var(--glow-orange); } .project-header { display: flex; align-items: flex-start; gap: 1rem; @@ -421,6 +421,13 @@ main { position: relative; z-index: 1; } padding: 0.25rem 0.7rem; border-radius: 999px; background: rgba(26,10,0,0.07); color: var(--ink-soft); border: 1px solid rgba(244, 114, 43, 0.18); + transition: all 0.2s var(--ease); +} +.project-tags span:hover, .timeline-tags span:hover { + background: var(--orange); + border-color: var(--orange); + color: #fff; + box-shadow: var(--glow-orange); } /* ── Timeline / Experience ──────────────────────────────────── */ @@ -444,7 +451,7 @@ main { position: relative; z-index: 1; } box-shadow: var(--card-shadow); transition: transform 0.3s var(--ease), box-shadow 0.3s; } -.timeline-card:hover { transform: translateX(5px); box-shadow: var(--glow-orange); } +.timeline-card:hover { box-shadow: var(--glow-orange); } .timeline-meta { display: flex; align-items: center; gap: 0.65rem; margin-bottom: 0.6rem; } .timeline-date { font-family: var(--mono); font-size: 0.75rem; color: var(--orange); } .timeline-tag { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; background: rgba(244,114,43,0.12); color: var(--orange); border-radius: 999px; padding: 0.18rem 0.6rem; } @@ -469,7 +476,7 @@ main { position: relative; z-index: 1; } display: flex; gap: 1.25rem; align-items: flex-start; transition: transform 0.3s var(--ease), box-shadow 0.3s; } -.edu-card:hover { transform: translateY(-4px); box-shadow: var(--glow-orange); } +.edu-card:hover { box-shadow: var(--glow-orange); } .edu-icon { width: 46px; height: 46px; flex-shrink: 0; border-radius: 12px; background: var(--grad); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 1.15rem; } .edu-body h3 { font-size: 1.05rem; font-weight: 800; margin-bottom: 0.25rem; } .edu-school { font-weight: 700; color: var(--orange); font-size: 0.85rem; margin-bottom: 0.2rem; } @@ -561,10 +568,59 @@ footer { background: var(--orange); border-color: var(--orange); color: #fff; - transform: translateY(-2px); box-shadow: var(--glow-orange); } +/* ── Skill pills: shared behavior (no select + tooltip anchor) ─── */ +.lang-tag, .project-tags span, .timeline-tags span { + position: relative; + cursor: default; + user-select: none; + -webkit-user-select: none; +} + +.lang-tag[data-tip]:not([data-tip=""]):hover::after, +.project-tags span[data-tip]:not([data-tip=""]):hover::after, +.timeline-tags span[data-tip]:not([data-tip=""]):hover::after { + content: attr(data-tip); + position: absolute; + bottom: calc(100% + 10px); + left: 50%; + transform: translateX(-50%); + width: max-content; + max-width: 220px; + padding: 0.5rem 0.7rem; + border-radius: 10px; + background: var(--ink); + color: var(--cream); + font-family: var(--font); + font-size: 0.72rem; + font-weight: 500; + line-height: 1.4; + letter-spacing: normal; + text-transform: none; + text-align: center; + white-space: normal; + box-shadow: var(--card-shadow); + z-index: 10; + pointer-events: none; +} + +/* Tooltip arrow */ +.lang-tag[data-tip]:not([data-tip=""]):hover::before, +.project-tags span[data-tip]:not([data-tip=""]):hover::before, +.timeline-tags span[data-tip]:not([data-tip=""]):hover::before { + content: ''; + position: absolute; + bottom: calc(100% - 3px); + left: 50%; + transform: translateX(-50%); + border: 8px solid transparent; + border-top-color: var(--ink); + z-index: 10; + pointer-events: none; +} + .skills-cards { display: grid; grid-template-columns: repeat(2, 1fr);