Files
personal-website/src/routes/+page.svelte
Stan Runge d0c7b6548b
Some checks failed
Test and deploy staging / staging (push) Has been cancelled
beeeeg update
2026-09-23 04:16:50 +00:00

182 lines
6.0 KiB
Svelte
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts">
import { resolve } from '$app/paths';
import portrait from '$lib/assets/stan.jpg?url';
import ProgressBar from '$lib/components/ProgressBar.svelte';
import type { PageProps } from './$types';
let { data }: PageProps = $props();
const projects = [
{
name: 'vash esports',
subtitle: 'the best way to play osu!',
href: 'https://esports.vash.software',
external: true
},
{
name: 'catchemall',
subtitle: 'catch 1025 pokemon across 53 games',
href: '/projects/catch-em-all',
external: false
},
{
name: 'animaldex',
subtitle: 'add neighborhood pets to the world map 😼',
href: '/projects/animaldex',
external: false
},
{
name: 'osu! map finder',
subtitle: 'find osu! maps for Spotify songs/albums/playlists',
href: '/projects/spotify-beatmap-finder',
external: false
},
{
name: 'derby lens',
subtitle: 'estimate odds for horse betting',
href: '/projects/derby',
external: false
}
] as const;
const experience = [
{ when: '2026–now', role: 'associate software engineer', place: 'Cargill' },
{
when: '2021–2026',
role: 'BSc computer science · software engineering',
place: 'The Hague University of Applied Sciences'
},
{ when: '2026', role: 'software engineering intern', place: '3webapps' },
{ when: '2023', role: 'software engineering intern', place: 'h5mag' },
{ when: '2021–2023', role: 'junior IT specialist', place: 'Finance Plus' }
] as const;
</script>
<svelte:head>
<link rel="preload" as="image" href={portrait} fetchpriority="high" />
</svelte:head>
<div class="mx-auto max-w-6xl px-4 sm:px-6">
<section
class="grid items-center gap-8 pt-7 pb-12 sm:py-20 md:grid-cols-[minmax(0,1fr)_minmax(0,320px)] md:gap-16"
>
<div class="min-w-0 text-center md:text-left">
<h1 class="text-5xl font-semibold tracking-[-0.055em] sm:text-6xl lg:text-7xl">stan runge</h1>
<nav
class="mt-7 grid grid-cols-2 justify-items-center gap-x-4 gap-y-3 text-base text-[var(--site-muted)] sm:flex sm:flex-wrap sm:justify-center sm:gap-x-6 md:justify-start"
aria-label="Find me online"
>
<a
href="https://git.stanrunge.dev/stan"
rel="external"
class="hover:text-[var(--site-text)]">git ↗</a
>
<a href="https://x.com/stanrunge" rel="external" class="hover:text-[var(--site-text)]"
>twitter ↗</a
>
<a href="https://esports.vash.software" rel="external" class="hover:text-[var(--site-text)]"
>vash esports ↗</a
>
<a href="mailto:stan@stanrunge.dev" class="hover:text-[var(--site-text)]">email ↗</a>
</nav>
</div>
<img
src={portrait}
alt="Stan at his desk"
width="760"
height="746"
loading="eager"
decoding="sync"
fetchpriority="high"
class="aspect-square w-full max-w-80 justify-self-center rounded-md bg-[var(--site-surface)] object-cover md:justify-self-end"
/>
</section>
<section aria-labelledby="projects-heading" class="border-t border-[var(--site-border)] pt-8">
<h2 id="projects-heading" class="mb-4 text-2xl font-semibold tracking-tight">
<a href={resolve('/projects')} class="hover:text-[var(--site-muted)]">projects ↗</a>
</h2>
<ul>
{#each projects as project (project.name)}
<li class="border-b border-[var(--site-border)] text-lg">
{#if project.external}
<a
href={project.href}
rel="external"
class="flex items-center justify-between gap-4 py-4 hover:text-[var(--site-muted)]"
>
<span class="min-w-0">
<span class="block">{project.name}</span>
<span class="mt-1 block text-base text-[var(--site-muted)]">{project.subtitle}</span
>
</span><span aria-hidden="true" class="shrink-0 text-[var(--site-muted)]">↗</span>
</a>
{:else}
<a
href={resolve(project.href)}
class="flex items-center justify-between gap-4 py-4 hover:text-[var(--site-muted)]"
>
<span class="min-w-0">
<span class="block">{project.name}</span>
<span class="mt-1 block text-base text-[var(--site-muted)]">{project.subtitle}</span
>
</span><span aria-hidden="true" class="shrink-0 text-[var(--site-muted)]">↗</span>
</a>
{/if}
</li>
{/each}
</ul>
</section>
<section aria-labelledby="lists-heading" class="pt-14 sm:pt-20">
<h2 id="lists-heading" class="mb-4 text-2xl font-semibold tracking-tight">
<a href={resolve('/lists')} class="hover:text-[var(--site-muted)]">lists ↗</a>
</h2>
<ul>
{#each data.lists as list (list.id)}
<li class="border-b border-[var(--site-border)] text-lg">
<a
href={resolve('/lists/[slug]', { slug: list.slug })}
class="block py-4 hover:text-[var(--site-muted)]"
>
<span class="flex flex-wrap items-center justify-between gap-x-6 gap-y-1">
<span>{list.name}</span>
<span class="text-base text-[var(--site-muted)]">
{#if list.isProgress && data.user}
{list.total ? Math.round((list.checked / list.total) * 100) : 0}% · {list.checked}/{list.total}
{:else}
{list.total} {list.total === 1 ? 'item' : 'items'}
{/if} ↗
</span>
</span>
{#if list.isProgress}<span class="mt-3 block"
><ProgressBar
value={list.checked}
max={list.total}
label={`Progress on ${list.name}`}
small
/></span
>{/if}
</a>
</li>
{/each}
</ul>
</section>
<section aria-labelledby="experience-heading" class="pt-14 sm:pt-20">
<h2 id="experience-heading" class="mb-4 text-2xl font-semibold tracking-tight">experience</h2>
<ol>
{#each experience as item (item.when + item.place)}
<li
class="grid gap-1 border-t border-[var(--site-border)] py-4 sm:grid-cols-[minmax(0,1fr)_130px] sm:gap-6"
>
<div class="min-w-0">
<h3 class="font-medium">{item.role}</h3>
<p class="mt-1 text-base text-[var(--site-muted)]">{item.place}</p>
</div>
<span class="text-base text-[var(--site-muted)] sm:text-right">{item.when}</span>
</li>
{/each}
</ol>
</section>
</div>