Initial portfolio site: Astro + Tailwind MVP

Outcome-led hero, about, grouped skills, experience summary, featured
projects + /projects index, static contact, SEO/OG, dark/light theme.
Dockerfile + nginx config + build script for homelab deploy.
This commit is contained in:
2026-06-17 16:22:53 +10:00
commit 2d4b6ea097
38 changed files with 8232 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
---
import type { Project } from "../data/projects";
interface Props {
project: Project;
}
const { project } = Astro.props;
const href = project.hasCaseStudy ? `/projects/${project.slug}` : undefined;
const Tag = href ? "a" : "article";
---
<Tag class="project card" href={href} data-reveal>
<div class="project__top">
<h3 class="project__title">{project.title}</h3>
{href && <span class="project__arrow" aria-hidden="true">→</span>}
</div>
<p class="project__outcome">{project.outcome}</p>
<p class="project__summary">{project.summary}</p>
<ul class="project__stack">
{project.stack.map((s) => <li class="tag">{s}</li>)}
</ul>
<p class="project__meta mono">
<span>{project.role}</span><span class="project__sep">·</span><span>{project.period}</span>
</p>
</Tag>
<style>
.project {
padding: var(--space-5);
display: flex;
flex-direction: column;
gap: var(--space-3);
color: inherit;
height: 100%;
}
a.project:hover {
text-decoration: none;
transform: translateY(-3px);
}
.project__top {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-3);
}
.project__title {
font-size: var(--step-1);
}
.project__arrow {
color: var(--accent);
transition: transform 0.2s var(--ease);
}
a.project:hover .project__arrow {
transform: translateX(4px);
}
.project__outcome {
color: var(--text);
font-weight: 500;
border-left: 2px solid var(--accent);
padding-left: var(--space-3);
}
.project__summary {
color: var(--text-dim);
font-size: var(--step--1);
line-height: 1.6;
}
.project__stack {
list-style: none;
padding: 0;
margin: var(--space-2) 0 0;
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.project__meta {
margin-top: auto;
padding-top: var(--space-3);
font-size: 0.72rem;
color: var(--text-faint);
display: flex;
gap: 0.5rem;
}
.project__sep {
opacity: 0.6;
}
</style>