Compare commits

..

17 Commits

Author SHA1 Message Date
4f6e53aa14 feat: Implement rio's new rio.json
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-03 17:01:24 +01:00
b6dea7dc55 Revert "test: Add self-hosted Plausible"
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This reverts commit e06e562568.
2024-02-02 20:26:07 +01:00
e06e562568 test: Add self-hosted Plausible
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-02 19:37:11 +01:00
614793eab2 feat: Add WKD policy
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-14 22:00:48 +01:00
ee72e087a6 fix: Add missing CNAME file
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-14 18:17:34 +01:00
942f3ab64e feat: Switch to an SSH deployment method
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-11 13:20:21 +01:00
e72314fb05 fix: Ignore tailwindcss' output
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-10 23:23:37 +01:00
f98a5218ac feat: Add CI 2024-01-10 23:22:18 +01:00
8d7621ab4c feat: Migrate to zola 2024-01-10 23:20:56 +01:00
b8a4c87abc feat: Change flake to zola 2024-01-10 22:38:53 +01:00
0e1ed09bee feat: Bump Nix package's version 2023-07-22 21:09:45 +02:00
1dd95f2418 feat: Adjust to blog rework 2023-07-22 21:09:19 +02:00
2a06d6666e fix: Update AniTrack's screenshot 2023-07-17 17:04:06 +02:00
2d0c954a82 feat: Make prettier 2023-07-17 17:01:11 +02:00
eac0b06afc feat: Change Mastodon to my own server 2023-05-13 12:06:19 +02:00
99aa4c47d4 Fix a typo again 2023-02-06 21:33:14 +01:00
c85dd65ae7 Fix typo 2023-02-06 21:32:04 +01:00
36 changed files with 305 additions and 280 deletions

7
.gitignore vendored
View File

@@ -2,3 +2,10 @@ _site
result
.direnv
.envrc
public/
# Generated using tailwindcss
static/css/index.css
# Zola build output
public/

16
.woodpecker.yml Normal file
View File

@@ -0,0 +1,16 @@
steps:
build:
image: alpine:3.19
commands:
- apk add --no-cache zola npm
- npm install -D tailwindcss @tailwindcss/typography
- npx tailwindcss -i input.css -o static/css/index.css --minify
- zola build
deploy:
image: git.polynom.me/papatutuwawa/woodpecker-ssg-deploy@sha256:9cfec13eb8ab1b8920c2f1f00f0258a7bfd159fe4e14e0985328086392c0da34
secrets: [ ssh_key ]
settings:
email: "ci@polynom.me"
name: "polynom.me CI system"
token_env: "SSH_KEY"
output: "public"

View File

@@ -1,27 +0,0 @@
BUILD_DATE := $(shell date '+%H:%M %d.%m.%Y')
serve:
python ../shared-assets/makesite.py \
-p params.json \
-v page_assets=/assets \
-v build_time="${BUILD_DATE}" \
--assets ../shared-assets/assets \
--assets ./assets \
--copy-assets \
--ignore ../shared-assets/assets/img \
--include robots.txt
# A workaround to making the fonts load without the CDN
mv _site/assets/fonts _site/fonts
cp -r well-known _site/.well-known
cd _site/ && python -m http.server 8080
build:
python ../shared-assets/makesite.py \
-p params.json \
-v page_assets=https://cdn.polynom.me \
-v build_time="${BUILD_DATE}" \
--assets ./assets \
--copy-assets \
--include robots.txt
cp -r well-known _site/.well-known
tar -czf blog.tar.gz _site

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

46
config.toml Normal file
View File

@@ -0,0 +1,46 @@
base_url = "https://polynom.me"
title = "PapaTutuWawa's Website"
description = "The personal website of Alexander 'PapaTutuWawa'."
[extra]
# Code information
gitea_url = "git.polynom.me"
gitea_username = "PapaTutuWawa"
github_username = "PapaTutuWawa"
codeberg_username = "PapaTutuWawa"
# Contact information
email_user = "papatutuwawa"
email_domain = "polynom.me"
gpg_key_url = "pki.polynom.me/pubkeys/papatutuwawa.pub"
fediverse_instance = "social.polynom.me"
fediverse_username = "papatutuwawa"
[[extra.projects]]
title = "Moxxy"
description = "A modern XMPP client written in Flutter. Licensed under GPLv3."
screenshot = "img/moxxy.jpg"
source_url = "codeberg.org/moxxy/moxxyv2"
website = "moxxy.org"
[[extra.projects]]
title = "AniTrack"
description = "A simple Anime and Manga tracker written in Flutter. Licensed under MIT."
screenshot = "img/anitrack.jpg"
source_url = "codeberg.org/PapaTutuWawa/anitrack"
website = "codeberg.org/PapaTutuWawa/anitrack"
[[extra.projects]]
title = "xmpp-discord-bridge"
description = "An XMPP to Discord bridge that attempts to feel as native as possible on each chat platform, written in Python. Licensed under GPLv3."
screenshot = ""
source_url = "codeberg.org/PapaTutuWawa/xmpp-discord-bridge.git"
website = "codeberg.org/PapaTutuWawa/xmpp-discord-bridge.git"
[[extra.projects]]
title = "mira"
description = "An XMPP bot framework for persistent subscription services, written in Python. Licensed under GPLv3."
screenshot = ""
source_url = "git.polynom.me/PapaTutuWawa/mira"
website = "git.polynom.me/PapaTutuWawa/mira"

4
content/_index.md Normal file
View File

@@ -0,0 +1,4 @@
+++
title = "PapaTutuWawa's Website"
template = "index.html"
+++

View File

@@ -1,25 +0,0 @@
<!-- title: Code | polynom.me -->
<!-- description: Alexander 'PapaTutuWawa' 's code repositories. -->
<!-- render: yes -->
<div class="project-row" />
<p>
I keep my code mostly on my private Gitea instance <a href="https://{{ gitea_url }}/{{ gitea_username }}">here</a>. For purposes of allowing other people to also contribute
I try to mirror my code on GitHub and codeberg.
</p>
<table id="social-links">
<tr>
<td>GitHub</td>
<td><a href="https://github.com/{{ github_username }}">{{ github_username }}</a></td>
</tr>
<tr>
<td>Codeberg</td>
<td><a href="https://codeberg.org/{{ codeberg_username }}">{{ codeberg_username }}</a></td>
</tr>
<tr>
<td>Gitea</td>
<td><a href="https://{{ gitea_url }}/{{ gitea_username }}">{{ gitea_username }}</a></td>
</tr>
</table>

5
content/code.md Normal file
View File

@@ -0,0 +1,5 @@
+++
title = "Code | polynom.me"
description = "Alexander 'PapaTutuWawa' 's code repositories."
template = "code.html"
+++

View File

@@ -1,38 +0,0 @@
<!-- title: Contact | polynom.me -->
<!-- description: Contact details for getting in touch with Alexander 'PapaTutuWawa'. -->
<!-- render: yes -->
<div class="project-row"></div>
<p>
If you have any questions about my projects or just want to talk, feel
free to reach out to me.
</p>
<table id="social-links">
<tr>
<td>Mastodon (<a href="https://{{ mastodon_instance_url }}">{{ mastodon_instance_name }}</a>)</td>
<td><a href="https://{{ mastodon_instance_url}}/{{ mastodon_handle }}">{{ mastodon_handle }}</a></td>
</tr>
<tr>
<td class="table-no-padding-bottom">E-Mail</td>
<td class="table-no-padding-bottom">{{ email_user }} [a with a circle] {{ email_domain }}</td>
</tr>
<tr>
<td class="table-no-padding-top" />
<td class="table-no-padding-top">
Please use my <a href="https://{{ gpg_key_url }}">GPG public key</a>
</td>
</tr>
<tr>
<td>GitHub</td>
<td><a href="https://github.com/{{ github_username }}">{{ github_username }}</a></td>
</tr>
<tr>
<td>Codeberg</td>
<td><a href="https://codeberg.org/{{ codeberg_username }}">{{ codeberg_username }}</a></td>
</tr>
<tr>
<td>Gitea</td>
<td><a href="https://{{ gitea_url }}/{{ gitea_username }}">{{ gitea_username }}</a></td>
</tr>
</table>

5
content/contact.md Normal file
View File

@@ -0,0 +1,5 @@
+++
title = "Contact | polynom.me"
description = "Contact details for getting in touch with Alexander 'PapaTutuWawa'."
template = "contact.html"
+++

View File

@@ -1,16 +0,0 @@
<!-- title: Home | polynom.me -->
<!-- description: The personal website of Alexander 'PapaTutuWawa'. -->
<!-- render: yes -->
<div class="project-row"></div>
<p class="quote">
Hello! My online pseudonym is <i>PapaTutuWawa</i> and I am
just some random person on the Internet who is passionate about
topics like XMPP, federated Internet services and privacy. Linux system
administration, Linux tinkering and programming are my favourite things to do.
</p>
<div class="project-row"></div>
<h1>Projects</h1>
<p>This is a small selection of my projects. More are available <a href="code.html">here.</a></p>
{{ for_each projects layout/templates/project.html }}

8
flake.lock generated
View File

@@ -36,16 +36,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1638239011,
"narHash": "sha256-AjhmbT4UBlJWqxY0ea8a6GU2C2HdKUREkG43oRr3TZg=",
"lastModified": 1689449371,
"narHash": "sha256-sK3Oi8uEFrFPL83wKPV6w0+96NrmwqIpw9YFffMifVg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a7ecde854aee5c4c7cd6177f54a99d2c1ff28a31",
"rev": "29bcead8405cfe4c00085843eb372cc43837bb9d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "21.11",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}

View File

@@ -2,7 +2,7 @@
description = "The website hosted at https://polynom.me";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/21.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
assets.url = "git+https://git.polynom.me/polynom.me/shared-assets.git";
};
@@ -14,20 +14,17 @@
supportedSystems = [ "x86_64-linux" ];
forAllSystems = nixpkgs.lib.attrsets.genAttrs supportedSystems;
in {
packages = forAllSystems (system: let
pkgs = import nixpkgs { inherit system; };
in {
default = pkgs.callPackage ./pkgs/website.nix {
shared-assets = assets.packages.${system}.default;
};
});
devShell = forAllSystems (system: let
pkgs = import nixpkgs { inherit system; };
pythonEnv = pkgs.python3.withPackages (ps: with ps; [ markdown ]);
tailwindWithTypography = pkgs.nodePackages.tailwindcss.overrideAttrs (old: {
plugins = [
pkgs.nodePackages."@tailwindcss/typography"
];
});
in pkgs.mkShell {
buildInputs = with pkgs; [
pythonEnv
tailwindWithTypography zola
];
});
};

17
input.css Normal file
View File

@@ -0,0 +1,17 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
background-color: #212121;
}
html {
@apply text-white;
}
a {
@apply text-indigo-400 !important;
}
}

View File

@@ -1,53 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ title }}</title>
<meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ description }}" />
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<link rel="stylesheet" href="assets/css/index.css" />
<link rel="stylesheet" href="{{ page_assets }}/css/main.css" />
<!-- Mastodon -->
<link rel="me" href="https://{{ mastodon_instance_url }}/{{ mastodon_handle }}" />
</head>
<body>
<div class="horizontal-center">
<div class="vertical header">
<div id="header" class="horizontal">
<img class="avatar" src="{{ page_assets }}/img/avatar.jpg" alt="" />
<div class="vertical-center">
<span class="name-title">Alexander "PapaTutuWawa"</span>
<div id="header-links">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="https://{{ blog_url }}">Blog</a></li>
<li><a href="code.html">Code</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</div>
</div>
</div>
{{ content }}
<br />
<div class="horizontal-center footer">
<span>
Created by <i>PapaTutuWawa</i> with &lt;3 using
<a href="https://github.com/google/roboto">Roboto</a>,
<a href="https://github.com/RedHatOfficial/Overpass">Overpass</a> and
<a href="https://github.com/sunainapai/makesite">makesite</a>
</span>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,9 +0,0 @@
<div class="no-screenshot clickable">
<a href="https://{{ item.source_url }}">
<div class="vertical-center">
<div class="horizontal-center">
<span class="no-screenshot-pound">#</span>
</div>
</div>
</a>
</div>

View File

@@ -1,12 +0,0 @@
<div class="horizontal project-row">
{{ template_if_empty item.screenshot layout/templates/no_screenshot.html layout/templates/screenshot.html }}
<div class="vertical">
<h2>{{ item.title }}</h2>
<p>{{ item.description }}</p>
<ul>
{{ template_if_empty item.website layout/templates/empty.html layout/templates/project_website.html }}
<li><a href="https://{{ item.source_url }}">Code</a></li>
</ul>
</div>
</div>

View File

@@ -1 +0,0 @@
<li><a href="https://{{ item.website }}">Website</a></li>

View File

@@ -1,5 +0,0 @@
<div>
<a href="https://{{ item.source_url }}" target="_blank">
<img class="screenshot clickable" src="{{ item.screenshot }}" alt="Screenshot of {{ item.title }}" />
</a>
</div>

View File

@@ -1,41 +0,0 @@
{
"author_name": "Alexander \"PapaTutuWawa\"",
"blog_url": "blog.polynom.me",
"mastodon_instance_name": "Fosstodon",
"mastodon_instance_url": "fosstodon.org",
"mastodon_handle": "@polynomdivision",
"email_domain": "polynom.me",
"email_user": "papatutuwawa",
"gpg_key_url": "pki.polynom.me/pubkeys/papatutuwawa.pub",
"github_username": "PapaTutuWawa",
"codeberg_username": "PapaTutuWawa",
"gitea_username": "PapaTutuWawa",
"gitea_url": "git.polynom.me",
"projects": [{
"title": "Moxxy",
"description": "A modern XMPP client written in Flutter. Licensed under GPLv3.",
"screenshot": "assets/img/moxxy.jpg",
"source_url": "codeberg.org/moxxy/moxxyv2",
"website": "codeberg.org/moxxy/moxxyv2"
}, {
"title": "AniTrack",
"description": "A simple Anime and Manga tracker writtein in Flutter. Licensed under MIT.",
"screenshot": "assets/img/anitrack.jpg",
"source_url": "codeberg.org/PapaTutuWawa/anitrack",
"website": "codeberg.org/PapaTutuWawa/anitrack"
}, {
"title": "xmpp-discord-bridge",
"description": "An XMPP to Discord bridge that attempts to feel as native as possible on each chat platform, written in Python. Licensed under GPLv3.",
"screenshot": "",
"source_url": "codeberg.org/PapaTutuWawa/xmpp-discord-bridge.git",
"website": "codeberg.org/PapaTutuWawa/xmpp-discord-bridge.git"
}, {
"title": "mira",
"description": "An XMPP bot framework for persistent subscription services, written in Python. Licensed under GPLv3.",
"screenshot": "",
"source_url": "git.polynom.me/PapaTutuWawa/mira",
"website": "git.polynom.me/PapaTutuWawa/mira"
}]
}

View File

@@ -1,38 +0,0 @@
{
lib, stdenv
, python3
, shared-assets
}:
stdenv.mkDerivation {
pname = "website";
version = "202205120-01";
src = ../.;
buildInputs = [ shared-assets python3 ];
buildPhase = ''
${python3}/bin/python ${shared-assets}/bin/makesite.py \
-v page_assets=https://cdn.polynom.me \
--assets ./assets \
--copy-assets \
--include robots.txt \
-p params.json
'';
installPhase = ''
mkdir -p $out/srv/www/website
cp -vr _site/* $out/srv/www/website
cp -vr well-known $out/srv/www/website/.well-known
'';
doCheck = false;
meta = with lib; {
description = "The website hosted at https://polynom.me";
homepage = "https://git.polynom.me/polynom.me/website";
maintainers = [];
license = licenses.gpl3;
};
}

1
static/CNAME Normal file
View File

@@ -0,0 +1 @@
polynom.me

BIN
static/img/anitrack.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

BIN
static/img/avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

View File

Before

Width:  |  Height:  |  Size: 565 KiB

After

Width:  |  Height:  |  Size: 565 KiB

8
static/rio.json Normal file
View File

@@ -0,0 +1,8 @@
{
"CNAME": "polynom.me",
"headers": {
"Content-Security-Policy": "default-src 'self'; script-src 'self'; script-src-elem 'self'; script-src-attr 'none'; style-src * 'self'; img-src 'self' data:; font-src 'self'; connect-src 'none'; media-src 'self'; object-src 'none'; prefetch-src 'none'; child-src 'none'; frame-src 'none'; worker-src 'none'; frame-ancestors 'none'; form-action 'none'; upgrade-insecure-requests; block-all-mixed-content; disown-opener; sandbox; base-uri https://polynom.me; manifest-src 'none'",
"X-Frame-Options": "DENY",
"Referrer-Policy": "no-referrer, strict-origin-when-cross-origin"
}
}

10
tailwind.config.js Normal file
View File

@@ -0,0 +1,10 @@
module.exports = {
content: [
"./templates/*.html",
],
theme: {
},
plugins: [
require('@tailwindcss/typography'),
],
}

42
templates/base.html Normal file
View File

@@ -0,0 +1,42 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="{{ get_url(path="css/index.css") }}" rel="stylesheet" />
<link href="{{ get_url(path="css/extra.css") }}" rel="stylesheet" />
{% if page %}
<meta property="og:title" content="{{ page.title }}" />
<meta property="og:description" content="{{ page.description }}" />
<title>{{ page.title }}</title>
{% else %}
<meta property="og:title" content="{{ config.title }}" />
<meta property="og:description" content="{{ config.description }}" />
<title>{{ config.title }}</title>
{% endif %}
</head>
<body>
<div class="flex flex-col p-2 md:p-8 items-start md:w-4/5 mx-auto">
<!-- Header -->
<div class="flex flex-row self-center">
<img
class="w-12 h-12 md:w-24 md:h-24 rounded-lg"
src="/img/avatar.jpg"
alt="Profile picture"
integrity="sha386-{{ get_hash(path="img/avatar.jpg", sha_type=384, base64=true) | safe }}" />
<div class="ml-4 self-center">
<a class="self-center text-2xl font-bold" href="/">PapaTutuWawa's Website</a>
<ul class="list-none">
<li class="inline mr-8"><a href="https://blog.polynom.me">Blog</a></li>
<li class="inline mr-8"><a href="{{ get_url(path="@/code.md" ) }}">Code</a></li>
<li class="inline mr-8"><a href="{{ get_url(path="@/contact.md" ) }}">Contact</a></li>
</ul>
</div>
</div>
{% block content %}{% endblock %}
</div>
</body>
</html>

30
templates/code.html Normal file
View File

@@ -0,0 +1,30 @@
{% extends "base.html" %}
{% block content %}
<div class="flex flex-col pt-8 mx-auto">
<p class="prose text-white">
I keep my code mostly on my private Gitea instance <a class="text-indigo-400"
href="https://{{ config.extra.gitea_url }}/{{ config.extra.gitea_username }}">here</a>.
For purposes of allowing other people to also contribute
I try to mirror my code on GitHub and codeberg.
</p>
<div class="pt-8 w-full">
<table class="text-white pt-8 w-full">
<tr>
<td>GitHub</td>
<td><a class="text-indigo-400" href="https://github.com/{{ config.extra.github_username }}">{{ config.extra.github_username }}</a></td>
</tr>
<tr>
<td>Codeberg</td>
<td><a class="text-indigo-400" href="https://codeberg.org/{{ config.extra.codeberg_username }}">{{ config.extra.codeberg_username }}</a>
</td>
</tr>
<tr>
<td>Gitea</td>
<td><a class="text-indigo-400" href="https://{{ config.extra.gitea_url }}/{{ config.extra.gitea_username }}">{{ config.extra.gitea_username }}</a></td>
</tr>
</table>
</div>
</div>
{% endblock %}

45
templates/contact.html Normal file
View File

@@ -0,0 +1,45 @@
{% extends "base.html" %}
{% block content %}
<div class="flex flex-col pt-8 mx-auto">
<p class="prose text-white">
If you have any questions about my projects or just want to talk, feel
free to reach out to me.
</p>
<div class="w-full pt-8">
<table class="text-white w-full">
<tr>
<td>Fediverse</td>
<td>
<a class="text-indigo-400" href="https://{{ config.extra.fediverse_instance}}/{{ config.extra.fediverse_username }}">@{{ config.extra.fediverse_username }}@{{ config.extra.fediverse_instance }}</a>
</td>
</tr>
<tr>
<td>E-Mail</td>
<td>{{ config.extra.email_user }} [a with a circle] {{ config.extra.email_domain }}</td>
</tr>
<tr>
<td />
<td>
Please use my <a class="text-indigo-400" href="https://{{ config.extra.gpg_key_url }}">GPG public key</a>
</td>
</tr>
<tr>
<td>GitHub</td>
<td><a class="text-indigo-400" href="https://github.com/{{ config.extra.github_username }}">{{ config.extra.github_username }}</a></td>
</tr>
<tr>
<td>Codeberg</td>
<td><a class="text-indigo-400" href="https://codeberg.org/{{ config.extra.codeberg_username }}">{{ config.extra.codeberg_username }}</a>
</td>
</tr>
<tr>
<td>Gitea</td>
<td><a class="text-indigo-400" href="https://{{ config.extra.gitea_url }}/{{ config.extra.gitea_username }}">{{ config.extra.gitea_username }}</a></td>
</tr>
</table>
</div>
</div>
{% endblock %}

57
templates/index.html Normal file
View File

@@ -0,0 +1,57 @@
{% extends "base.html" %}
{% block content %}
<div class="flex flex-col mx-auto">
<p class="text-white prose py-8 self-center">
Hello! My online pseudonym is <i>PapaTutuWawa</i> and I am
just some random person on the Internet who is passionate about
topics like XMPP, federated Internet services and privacy. Linux system
administration, Linux tinkering and programming are my favourite things to do.
</p>
<h1 class="prose text-2xl text-indigo-400 self-start">Projects</h1>
<p class="prose text-white text-left self-start">This is a small selection of my projects. More are available <a
class="text-indigo-400" href="code.html">here.</a></p>
{% for project in config.extra.projects %}
<div class="flex flex-row self-start pt-8">
{% if project.screenshot != "" %}
<div>
<a href="https://{{ project.website }}" target="_blank">
<img
class="w-24 md:w-48 max-w-none rounded-lg clickable"
src="{{ project.screenshot }}"
alt="Screenshot of {{ project.title }}"
integrity="sha386-{{ get_hash(path=project.screenshot, sha_type=384, base64=true) | safe }}" />
</a>
</div>
{% else %}
<div class="flex justify-center md:w-48 md:h-48 w-24 h-24 rounded-lg clickable bg-indigo-950">
<a class="prose text-white text-5xl" href="https://{{ project.website }}">
<div class="md:w-48 md:h-48 w-24 h-24 flex flex-col justify-center">
<span class="text-center">#</span>
</div>
</a>
</div>
{% endif %}
<div class="flex flex-col pl-8">
<h2 class="prose text-indigo-400 text-2xl">{{ project.title }}</h2>
<p class="prose text-white text-justify">{{ project.description }}</p>
<div class="pt-4">
<ul>
{% if project.website != "" %}
<li>
<a class="text-indigo-400" href="https://{{ project.website }}">Website</a>
</li>
{% endif %}
<li><a class="prose text-indigo-400" href="https://{{ project.source_url }}">Code</a></li>
</ul>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}