Files
jeanlucmakiola.de/src/pages/index.astro

110 lines
3.7 KiB
Plaintext

---
import BaseLayout from '../layouts/BaseLayout.astro';
import { Icon } from 'astro-icon/components';
import { getCollection } from 'astro:content';
import { SITE, LEGAL } from '../consts';
import { getPublishedPosts } from '../utils/posts';
const posts = (await getPublishedPosts()).slice(0, 4);
const fmt = (d: Date) =>
d.toLocaleDateString(SITE.lang, { year: 'numeric', month: 'short' });
const GITEA = 'https://gitea.jeanlucmakiola.de/makiolaj';
// Selected work — pulled from the projects collection (single source of truth;
// per-app pages live at /work/<slug>). Older experiments live on Gitea.
const projects = (await getCollection('projects')).sort(
(a, b) => a.data.order - b.data.order
);
---
<BaseLayout title={SITE.title}>
<!-- Intro: hero + about side by side on wide screens -->
<section class="intro" aria-label="Intro">
<div class="hero intro__lead">
<span class="hero__eyebrow">Developer &amp; designer</span>
<h1>Jean-Luc Makiola<span class="dot">.</span></h1>
<p class="lead">
I build design-led Android apps with Material 3 Expressive on top of
open, self-hostable standards. This is my corner of the web — projects,
writing, and notes.
</p>
<div class="hero__actions">
<a class="btn btn--filled" href="#work">View work</a>
<a class="text-link" href="/blog">Read the blog <span class="dot">→</span></a>
<a class="text-link" href={`mailto:${LEGAL.email}`}>
<Icon name="mdi:email-outline" /> Get in touch
</a>
</div>
</div>
<div class="about intro__about" id="about">
<p>
I'd rather put a thoughtful interface on top of an open protocol than
reinvent a sync stack. My apps read and write through the platform's own
providers, so your data stays yours — and stays portable.
</p>
<p class="muted">
They form the <strong>Floret</strong> family: small, focused tools that
share one expressive design language. Everything around them — code,
translations, builds — runs on infrastructure I host myself.
</p>
</div>
</section>
<!-- Selected work -->
<section class="section" id="work">
<div class="section-head">
<h2>Selected work</h2>
<a class="btn btn--text" href="/work">All work →</a>
</div>
<ul class="project-grid">
{
projects.map((p) => (
<li>
<a class="project-card" href={`/work/${p.id}/`}>
<span class={`project-card__status${p.data.released ? ' is-released' : ''}`}>
{p.data.status}
</span>
<span class="project-card__title">
{p.data.name}
<span class="arrow" aria-hidden="true">→</span>
</span>
<p>{p.data.summary}</p>
</a>
</li>
))
}
</ul>
<p class="aside">
Plus a trail of smaller experiments and utilities — most unfinished by
design — over on <a href={GITEA} rel="noopener">my Gitea</a>.
</p>
</section>
<!-- Latest writing -->
{
posts.length > 0 && (
<section class="section">
<div class="section-head">
<h2>Latest writing</h2>
<a class="btn btn--text" href="/blog">All posts →</a>
</div>
<ul class="writing-list">
{posts.map((post) => (
<li>
<a class="writing-row" href={`/blog/${post.id}/`}>
<span class="writing-row__title">{post.data.title}</span>
<time datetime={post.data.pubDate.toISOString()}>
{fmt(post.data.pubDate)}
</time>
</a>
</li>
))}
</ul>
</section>
)
}
</BaseLayout>