Add docker build

This commit is contained in:
myrmidex 2025-08-01 23:48:36 +02:00
parent eff3ae7e57
commit 057e800b1b
10 changed files with 608 additions and 0 deletions

6
.docker/.dockerignore Normal file
View file

@ -0,0 +1,6 @@
public/
.git/
.gitignore
README.md
Dockerfile
.dockerignore

17
.docker/Dockerfile Normal file
View file

@ -0,0 +1,17 @@
# Build stage
FROM alpine:latest as builder
# Install Zola
RUN apk add --no-cache zola
WORKDIR /app
COPY . .
RUN zola build
# Runtime stage
FROM docker.io/library/nginx:alpine
COPY --from=builder /app/public /usr/share/nginx/html
COPY .docker/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

34
.docker/build-docker.sh Executable file
View file

@ -0,0 +1,34 @@
#\!/bin/bash
set -e
# Check if tag is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <tag>"
echo "Example: $0 v0.1.2"
exit 1
fi
# Configuration
REGISTRY="codeberg.org"
NAMESPACE="lvl0"
IMAGE_NAME="website"
TAG="$1"
FULL_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${TAG}"
echo "Building Docker image: ${FULL_IMAGE}"
# Build the image
docker build -f .docker/Dockerfile -t "${FULL_IMAGE}" .
# Also tag as latest
LATEST_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:latest"
docker tag "${FULL_IMAGE}" "${LATEST_IMAGE}"
echo "Image built successfully!"
echo "Tagged as: ${FULL_IMAGE}"
echo "Tagged as: ${LATEST_IMAGE}"
echo ""
echo "To push to registry, run:"
echo "docker login ${REGISTRY}"
echo "docker push ${FULL_IMAGE}"
echo "docker push ${LATEST_IMAGE}"

16
.docker/nginx.conf Normal file
View file

@ -0,0 +1,16 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /404.html;
}
# Cache static assets
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

100
public/404.html Normal file
View file

@ -0,0 +1,100 @@
<!doctype html>
<html class="not-ready lg:text-base overflow-y-scroll scroll-pt-14" lang="en">
<head prefix="og: https://ogp.me/ns#">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="generator" content="Zola" />
<meta name="robots" content="noindex" />
<title>404: Page not found | lvl0</title>
<meta property="og:site_name" content="lvl0" />
<meta property="og:title" content="404: Page not found" />
<meta property="og:type" content="website" />
<!-- Begin Head inject -->
<!-- End Head inject -->
<link rel="stylesheet" href="https://lvl0.xyz/main.min.css?h=fc65ba308cf36d3ba82c" />
<style>
:root{--bg: #f4f4f5; --header: #e4e4e7; color-scheme: light;}
:root.dark{--bg: #18181b; --header: #27272a; color-scheme: dark;}
</style>
<meta name="theme-color" data-light="#e4e4e7" data-dark="#27272a" content="#e4e4e7" />
<link rel="icon" type="image/x-icon" sizes="16x16" href="https://lvl0.xyz/favicon.ico" />
<link rel="apple-touch-icon" type="image/png" href="https://lvl0.xyz/apple-touch-icon.png?h=58bee300054c5308feb3" />
<link rel="icon" type="image/png" href="https://lvl0.xyz/android-icon.png?h=8d80ec95446bd2c36826" />
<script src="https://lvl0.xyz/js/linkita.min.js?h=1dd3ed42fc674277bc34"></script>
<!-- Begin Head End inject -->
<!-- End Head End inject -->
</head>
<body class="text-black duration-100 ease-out bg-[var(--bg)] dark:text-white">
<!-- Header -->
<header class="bg-[var(--header)] fixed top-0 z-40 mx-auto min-h-[3.25rem] w-full header-icons">
<div class="mx-auto w-full max-w-4xl p-2.5 lg:flex lg:justify-between">
<div class="flex justify-between">
<div class="flex items-center min-h-8">
<a title="Go to home page" accesskey="!"
href="https://lvl0.xyz/" class="text-2xl font-semibold">lvl0</a>
<button type="button" title="Switch color scheme" accesskey="$"
onclick="window.linkita.toggleDarkMode();" ondblclick="window.linkita.resetDarkMode();"
class="btn-dark ml-4 h-6 w-6 shrink-0 cursor-pointer text-[0] bg-center bg-no-repeat bg-cover dark:invert [background-image:var(--icon-theme-dark)] dark:[background-image:var(--icon-theme-light)]"
></button>
</div>
<div title="Menu" role="button" accesskey="+" tabindex="0"
class="btn-menu relative z-50 flex h-8 w-8 shrink-0 cursor-pointer flex-col items-center justify-center gap-2.5 lg:hidden"
onclick="window.linkita.toggleHeaderMenu();"
onkeydown="(event.keyCode == 13 || event.keyCode == 32) ? event.preventDefault() || window.linkita.toggleHeaderMenu() : true;"
></div>
</div>
<nav class="flex w-full items-center lg:w-auto">
<menu
class="nav-wrapper flex w-full flex-col py-2 lg:w-auto lg:flex-row lg:self-center lg:py-0">
<li>
<a
class="primary-link block py-2 text-center text-lg font-medium lg:px-3 lg:py-0"
href="/announcements/"
>Announcements</a>
</li>
</menu>
<!-- Begin Header Nav inject -->
<!-- End Header Nav inject -->
</nav>
</div>
</header>
<!-- Begin Body Start inject -->
<!-- End Body Start inject -->
<main class="prose prose-neutral relative mx-auto min-h-[calc(100%-4rem)]
max-w-3xl break-words px-4 pb-12 pt-28 lg:pt-32 dark:prose-invert prose-pre:rounded-lg prose-img:rounded-lg">
<h1 class="absolute inset-x-8 bottom-20 top-0 flex items-center justify-center text-6xl">404: Page not found</h1>
</main>
<!-- Footer -->
<footer class="mx-auto flex lg:mt-5 max-w-3xl flex-wrap items-center px-4 py-3 text-sm opacity-60">
<div class="mr-auto basis-full lg:basis-1/2">
© <time datetime="2025">2025</time>
</div>
<div class="flex basis-full lg:basis-1/2 lg:justify-end">
<span class="mr-6 lg:ml-6">
<a class="link" href="https://www.getzola.org/" target="_blank">Powered by Zola</a>
</span>
<a class="link" href="https://www.getzola.org/themes/linkita/" target="_blank">&#9998; Linkita</a>
</div>
<!-- Begin Footer inject -->
<!-- End Footer inject -->
</footer>
<!-- Begin Body End inject -->
<!-- End Body End inject -->
</body>
</html>

View file

@ -0,0 +1,159 @@
<!doctype html>
<html class="not-ready lg:text-base overflow-y-scroll scroll-pt-14" lang="en">
<head prefix="og: https://ogp.me/ns# article: https://ogp.me/ns/article#">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="generator" content="Zola" />
<title>incr 0.1.2: First Stable Release | lvl0</title>
<meta property="og:site_name" content="lvl0" />
<meta property="og:title" content="incr 0.1.2: First Stable Release" />
<meta property="og:url" content="https://lvl0.xyz/announcements/incr-stable-release/" />
<link rel="canonical" href="https://lvl0.xyz/announcements/incr-stable-release/" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2025-08-01T00:00:00+00:00" />
<!-- Begin Head inject -->
<!-- End Head inject -->
<link rel="stylesheet" href="https://lvl0.xyz/main.min.css?h=fc65ba308cf36d3ba82c" />
<style>
:root{--bg: #f4f4f5; --header: #e4e4e7; color-scheme: light;}
:root.dark{--bg: #18181b; --header: #27272a; color-scheme: dark;}
</style>
<meta name="theme-color" data-light="#e4e4e7" data-dark="#27272a" content="#e4e4e7" />
<link rel="icon" type="image/x-icon" sizes="16x16" href="https://lvl0.xyz/favicon.ico" />
<link rel="apple-touch-icon" type="image/png" href="https://lvl0.xyz/apple-touch-icon.png?h=58bee300054c5308feb3" />
<link rel="icon" type="image/png" href="https://lvl0.xyz/android-icon.png?h=8d80ec95446bd2c36826" />
<script src="https://lvl0.xyz/js/linkita.min.js?h=1dd3ed42fc674277bc34"></script>
<!-- Begin Head End inject -->
<!-- End Head End inject -->
</head>
<body class="text-black duration-100 ease-out bg-[var(--bg)] dark:text-white">
<!-- Header -->
<header class="bg-[var(--header)] fixed top-0 z-40 mx-auto min-h-[3.25rem] w-full header-icons">
<div class="mx-auto w-full max-w-4xl p-2.5 lg:flex lg:justify-between">
<div class="flex justify-between">
<div class="flex items-center min-h-8">
<a title="Go to home page" accesskey="!"
href="https://lvl0.xyz/" class="text-2xl font-semibold">lvl0</a>
<button type="button" title="Switch color scheme" accesskey="$"
onclick="window.linkita.toggleDarkMode();" ondblclick="window.linkita.resetDarkMode();"
class="btn-dark ml-4 h-6 w-6 shrink-0 cursor-pointer text-[0] bg-center bg-no-repeat bg-cover dark:invert [background-image:var(--icon-theme-dark)] dark:[background-image:var(--icon-theme-light)]"
></button>
</div>
<div title="Menu" role="button" accesskey="+" tabindex="0"
class="btn-menu relative z-50 flex h-8 w-8 shrink-0 cursor-pointer flex-col items-center justify-center gap-2.5 lg:hidden"
onclick="window.linkita.toggleHeaderMenu();"
onkeydown="(event.keyCode == 13 || event.keyCode == 32) ? event.preventDefault() || window.linkita.toggleHeaderMenu() : true;"
></div>
</div>
<nav class="flex w-full items-center lg:w-auto">
<menu
class="nav-wrapper flex w-full flex-col py-2 lg:w-auto lg:flex-row lg:self-center lg:py-0">
<li>
<a
class="primary-link block py-2 text-center text-lg font-medium lg:px-3 lg:py-0"
href="/announcements/"
>Announcements</a>
</li>
</menu>
<!-- Begin Header Nav inject -->
<!-- End Header Nav inject -->
</nav>
</div>
</header>
<!-- Begin Body Start inject -->
<!-- End Body Start inject -->
<main class="prose prose-neutral relative mx-auto min-h-[calc(100%-4rem)]
max-w-3xl break-words px-4 pb-12 pt-28 lg:pt-32 dark:prose-invert prose-pre:rounded-lg prose-img:rounded-lg">
<article>
<!-- Begin Page Start inject -->
<!-- End Page Start inject -->
<header class="mb-16">
<h1 class="!my-0 pb-2.5">incr 0.1.2: First Stable Release</h1>
<!-- Page Info -->
<div class="text-sm antialiased opacity-80"><time
datetime="2025-08-01T00:00:00+00:00">2025-08-01</time><span
class="mx-1">&middot;</span><time
datetime="PT0H1M0S">1&nbsp;min</time>
</div>
</header>
<!-- TOC -->
<div class="block-bg mb-12 rounded-lg p-2 text-lg">
<details>
<summary class="select-none py-0.5 lg:py-1 pl-4" accesskey="=">
<span class="cursor-pointer">Table of Contents</span>
</summary>
<div class="px-2">
<ul>
<li>
<a class="no-underline hover:underline" href="https://lvl0.xyz/announcements/incr-stable-release/#what-is-incr">What is incr?</a>
</li>
<li>
<a class="no-underline hover:underline" href="https://lvl0.xyz/announcements/incr-stable-release/#key-features">Key Features</a>
</li>
<li>
<a class="no-underline hover:underline" href="https://lvl0.xyz/announcements/incr-stable-release/#get-started">Get Started</a>
</li>
</ul>
</div>
</details>
</div>
<!-- Content -->
<section><p>We're excited to announce the first stable release of <strong>incr</strong> - our FIRE journey tracking tool that focuses on shares, not slogans.</p>
<h2 id="what-is-incr">What is incr?</h2>
<p>incr is a minimalist tool designed to help you track your Financial Independence, Retire Early (FIRE) journey with precision and clarity. Instead of flashy charts and motivational slogans, incr focuses on what matters: tracking your investment shares and real progress toward financial independence.</p>
<h2 id="key-features">Key Features</h2>
<ul>
<li><strong>Share-based tracking</strong>: Monitor your portfolio in actual shares, not just dollar amounts</li>
<li><strong>Self-hosted</strong>: Keep your financial data private and under your control</li>
<li><strong>Minimalist design</strong>: Clean, distraction-free interface that focuses on your data</li>
<li><strong>Long-term thinking</strong>: Built for the patient investor pursuing financial autonomy</li>
</ul>
<h2 id="get-started">Get Started</h2>
<p>Visit <a href="https://incr.lvl0.xyz">incr.lvl0.xyz</a> to learn more and start tracking your FIRE journey today.</p>
</section>
<hr />
<!-- Post Taxonomies -->
<!-- Begin Page End inject -->
<!-- End Page End inject -->
</article>
</main>
<!-- Footer -->
<footer class="mx-auto flex lg:mt-5 max-w-3xl flex-wrap items-center px-4 py-3 text-sm opacity-60">
<div class="mr-auto basis-full lg:basis-1/2">
© <time datetime="2025">2025</time>
</div>
<div class="flex basis-full lg:basis-1/2 lg:justify-end">
<span class="mr-6 lg:ml-6">
<a class="link" href="https://www.getzola.org/" target="_blank">Powered by Zola</a>
</span>
<a class="link" href="https://www.getzola.org/themes/linkita/" target="_blank">&#9998; Linkita</a>
</div>
<!-- Begin Footer inject -->
<!-- End Footer inject -->
</footer>
<!-- Begin Body End inject -->
<!-- End Body End inject -->
</body>
</html>

View file

@ -0,0 +1,125 @@
<!doctype html>
<html class="not-ready lg:text-base overflow-y-scroll scroll-pt-14" lang="en">
<head prefix="og: https://ogp.me/ns#">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="generator" content="Zola" />
<title>Announcements | lvl0</title>
<meta property="og:site_name" content="lvl0" />
<meta property="og:title" content="Announcements" />
<meta property="og:url" content="https://lvl0.xyz/announcements/" />
<link rel="canonical" href="https://lvl0.xyz/announcements/" />
<meta property="og:type" content="website" />
<!-- Begin Head inject -->
<!-- End Head inject -->
<link rel="stylesheet" href="https://lvl0.xyz/main.min.css?h=fc65ba308cf36d3ba82c" />
<style>
:root{--bg: #f4f4f5; --header: #e4e4e7; color-scheme: light;}
:root.dark{--bg: #18181b; --header: #27272a; color-scheme: dark;}
</style>
<meta name="theme-color" data-light="#e4e4e7" data-dark="#27272a" content="#e4e4e7" />
<link rel="icon" type="image/x-icon" sizes="16x16" href="https://lvl0.xyz/favicon.ico" />
<link rel="apple-touch-icon" type="image/png" href="https://lvl0.xyz/apple-touch-icon.png?h=58bee300054c5308feb3" />
<link rel="icon" type="image/png" href="https://lvl0.xyz/android-icon.png?h=8d80ec95446bd2c36826" />
<script src="https://lvl0.xyz/js/linkita.min.js?h=1dd3ed42fc674277bc34"></script>
<!-- Begin Head End inject -->
<!-- End Head End inject -->
</head>
<body class="text-black duration-100 ease-out bg-[var(--bg)] dark:text-white">
<!-- Header -->
<header class="bg-[var(--header)] fixed top-0 z-40 mx-auto min-h-[3.25rem] w-full header-icons">
<div class="mx-auto w-full max-w-4xl p-2.5 lg:flex lg:justify-between">
<div class="flex justify-between">
<div class="flex items-center min-h-8">
<a title="Go to home page" accesskey="!"
href="https://lvl0.xyz/" class="text-2xl font-semibold">lvl0</a>
<button type="button" title="Switch color scheme" accesskey="$"
onclick="window.linkita.toggleDarkMode();" ondblclick="window.linkita.resetDarkMode();"
class="btn-dark ml-4 h-6 w-6 shrink-0 cursor-pointer text-[0] bg-center bg-no-repeat bg-cover dark:invert [background-image:var(--icon-theme-dark)] dark:[background-image:var(--icon-theme-light)]"
></button>
</div>
<div title="Menu" role="button" accesskey="+" tabindex="0"
class="btn-menu relative z-50 flex h-8 w-8 shrink-0 cursor-pointer flex-col items-center justify-center gap-2.5 lg:hidden"
onclick="window.linkita.toggleHeaderMenu();"
onkeydown="(event.keyCode == 13 || event.keyCode == 32) ? event.preventDefault() || window.linkita.toggleHeaderMenu() : true;"
></div>
</div>
<nav class="flex w-full items-center lg:w-auto">
<menu
class="nav-wrapper flex w-full flex-col py-2 lg:w-auto lg:flex-row lg:self-center lg:py-0">
<li>
<a
class="primary-link block py-2 text-center text-lg font-medium lg:px-3 lg:py-0"
href="/announcements/"
>Announcements</a>
</li>
</menu>
<!-- Begin Header Nav inject -->
<!-- End Header Nav inject -->
</nav>
</div>
</header>
<!-- Begin Body Start inject -->
<!-- End Body Start inject -->
<main class="prose prose-neutral relative mx-auto min-h-[calc(100%-4rem)]
max-w-3xl break-words px-4 pb-12 pt-28 lg:pt-32 dark:prose-invert prose-pre:rounded-lg prose-img:rounded-lg">
<h1 class="mb-8">Announcements</h1>
<section class="mb-12"><p>Stay updated with the latest news and releases from lvl0.</p>
</section>
<div class="not-prose">
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<article class="border border-gray-200 dark:border-gray-700 rounded-lg p-6 hover:shadow-md transition-shadow">
<h2 class="text-xl font-semibold mb-3">
<a href="https://lvl0.xyz/announcements/incr-stable-release/" class="text-blue-600 dark:text-blue-400 hover:underline">
incr 0.1.2: First Stable Release
</a>
</h2>
<time class="text-sm text-gray-500 dark:text-gray-400 mb-4 block">
August 01, 2025
</time>
<div class="text-gray-700 dark:text-gray-300 mb-4">
We&#x27;re excited to announce the first stable release of incr - our FIRE journey tracking tool that focuses on shares, not slogans.
What is incr?
incr is a minimalist tool designed to help you track your…
</div>
<a href="https://lvl0.xyz/announcements/incr-stable-release/" class="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium">
Read more →
</a>
</article>
</div>
</div>
</main>
<!-- Footer -->
<footer class="mx-auto flex lg:mt-5 max-w-3xl flex-wrap items-center px-4 py-3 text-sm opacity-60">
<div class="mr-auto basis-full lg:basis-1/2">
© <time datetime="2025">2025</time>
</div>
<div class="flex basis-full lg:basis-1/2 lg:justify-end">
<span class="mr-6 lg:ml-6">
<a class="link" href="https://www.getzola.org/" target="_blank">Powered by Zola</a>
</span>
<a class="link" href="https://www.getzola.org/themes/linkita/" target="_blank">&#9998; Linkita</a>
</div>
<!-- Begin Footer inject -->
<!-- End Footer inject -->
</footer>
<!-- Begin Body End inject -->
<!-- End Body End inject -->
</body>
</html>

134
public/index.html Normal file
View file

@ -0,0 +1,134 @@
<!doctype html>
<html class="not-ready lg:text-base overflow-y-scroll scroll-pt-14" lang="en">
<head prefix="og: https://ogp.me/ns#">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="generator" content="Zola" />
<title>lvl0</title>
<meta property="og:site_name" content="lvl0" />
<meta property="og:title" content="lvl0" />
<meta property="og:url" content="https://lvl0.xyz/" />
<link rel="canonical" href="https://lvl0.xyz/" />
<meta property="og:type" content="website" />
<!-- Begin Head inject -->
<!-- End Head inject -->
<link rel="stylesheet" href="https://lvl0.xyz/main.min.css?h=fc65ba308cf36d3ba82c" />
<style>
:root{--bg: #f4f4f5; --header: #e4e4e7; color-scheme: light;}
:root.dark{--bg: #18181b; --header: #27272a; color-scheme: dark;}
</style>
<meta name="theme-color" data-light="#e4e4e7" data-dark="#27272a" content="#e4e4e7" />
<link rel="icon" type="image/x-icon" sizes="16x16" href="https://lvl0.xyz/favicon.ico" />
<link rel="apple-touch-icon" type="image/png" href="https://lvl0.xyz/apple-touch-icon.png?h=58bee300054c5308feb3" />
<link rel="icon" type="image/png" href="https://lvl0.xyz/android-icon.png?h=8d80ec95446bd2c36826" />
<script src="https://lvl0.xyz/js/linkita.min.js?h=1dd3ed42fc674277bc34"></script>
<!-- Begin Head End inject -->
<!-- End Head End inject -->
</head>
<body class="text-black duration-100 ease-out bg-[var(--bg)] dark:text-white">
<!-- Header -->
<header class="bg-[var(--header)] fixed top-0 z-40 mx-auto min-h-[3.25rem] w-full header-icons">
<div class="mx-auto w-full max-w-4xl p-2.5 lg:flex lg:justify-between">
<div class="flex justify-between">
<div class="flex items-center min-h-8">
<a title="Go to home page" accesskey="!"
href="https://lvl0.xyz/" class="text-2xl font-semibold">lvl0</a>
<button type="button" title="Switch color scheme" accesskey="$"
onclick="window.linkita.toggleDarkMode();" ondblclick="window.linkita.resetDarkMode();"
class="btn-dark ml-4 h-6 w-6 shrink-0 cursor-pointer text-[0] bg-center bg-no-repeat bg-cover dark:invert [background-image:var(--icon-theme-dark)] dark:[background-image:var(--icon-theme-light)]"
></button>
</div>
<div title="Menu" role="button" accesskey="+" tabindex="0"
class="btn-menu relative z-50 flex h-8 w-8 shrink-0 cursor-pointer flex-col items-center justify-center gap-2.5 lg:hidden"
onclick="window.linkita.toggleHeaderMenu();"
onkeydown="(event.keyCode == 13 || event.keyCode == 32) ? event.preventDefault() || window.linkita.toggleHeaderMenu() : true;"
></div>
</div>
<nav class="flex w-full items-center lg:w-auto">
<menu
class="nav-wrapper flex w-full flex-col py-2 lg:w-auto lg:flex-row lg:self-center lg:py-0">
<li>
<a
class="primary-link block py-2 text-center text-lg font-medium lg:px-3 lg:py-0"
href="/announcements/"
>Announcements</a>
</li>
</menu>
<!-- Begin Header Nav inject -->
<!-- End Header Nav inject -->
</nav>
</div>
</header>
<!-- Begin Body Start inject -->
<!-- End Body Start inject -->
<main class="prose prose-neutral relative mx-auto min-h-[calc(100%-4rem)]
max-w-3xl break-words px-4 pb-12 pt-28 lg:pt-32 dark:prose-invert prose-pre:rounded-lg prose-img:rounded-lg">
<section><p><strong>lvl0 is a starting point.</strong></p>
<p>We build tiny, focused tools that support calm productivity, financial independence, and long-term thinking.</p>
<p>Our projects embrace minimalism, self-hosting, and the pursuit of autonomy — in tech, finance, and life.</p>
<h2 id="current-projects">Current Projects</h2>
<p><strong><a href="https://incr.lvl0.xyz">incr</a></strong> — Track your FIRE journey in shares, not slogans. A minimalist tool for monitoring your path to financial independence with precision and clarity.</p>
</section>
<section class="mt-16 not-prose">
<h2 class="text-2xl font-semibold mb-6 text-black dark:text-white">Recent Announcements</h2>
<div class="grid gap-6 md:grid-cols-1 lg:grid-cols-3">
<article class="border border-gray-200 dark:border-gray-700 rounded-lg p-4 hover:shadow-md transition-shadow">
<h3 class="text-lg font-medium mb-2">
<a href="https://lvl0.xyz/announcements/incr-stable-release/" class="text-blue-600 dark:text-blue-400 hover:underline">
incr 0.1.2: First Stable Release
</a>
</h3>
<time class="text-sm text-gray-500 dark:text-gray-400 mb-3 block">
August 01, 2025
</time>
<div class="text-gray-700 dark:text-gray-300">
We&#x27;re excited to announce the first stable release of incr - our FIRE journey tracking tool that focuses on shares, not slogans.
What is incr?
incr is…
</div>
</article>
</div>
<div class="mt-6 text-center">
<a href="/announcements/" class="text-blue-600 dark:text-blue-400 hover:underline font-medium">
View all announcements →
</a>
</div>
</section>
<!-- Page List -->
</main>
<!-- Footer -->
<footer class="mx-auto flex lg:mt-5 max-w-3xl flex-wrap items-center px-4 py-3 text-sm opacity-60">
<div class="mr-auto basis-full lg:basis-1/2">
© <time datetime="2025">2025</time>
</div>
<div class="flex basis-full lg:basis-1/2 lg:justify-end">
<span class="mr-6 lg:ml-6">
<a class="link" href="https://www.getzola.org/" target="_blank">Powered by Zola</a>
</span>
<a class="link" href="https://www.getzola.org/themes/linkita/" target="_blank">&#9998; Linkita</a>
</div>
<!-- Begin Footer inject -->
<!-- End Footer inject -->
</footer>
<!-- Begin Body End inject -->
<!-- End Body End inject -->
</body>
</html>

4
public/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Disallow:
Allow: /
Sitemap: https://lvl0.xyz/sitemap.xml

13
public/sitemap.xml Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://lvl0.xyz/</loc>
</url>
<url>
<loc>https://lvl0.xyz/announcements/</loc>
</url>
<url>
<loc>https://lvl0.xyz/announcements/incr-stable-release/</loc>
<lastmod>2025-08-01</lastmod>
</url>
</urlset>