feat: add initial website infrastructure

This commit is contained in:
2026-03-07 20:02:34 +01:00
commit 3e8a34ae35
20 changed files with 8337 additions and 0 deletions

9
.cspell.yaml Normal file
View File

@@ -0,0 +1,9 @@
---
version: "0.2"
import:
- "@cspell/dict-de-de/cspell-ext.json"
language: en,de
words:
- kmoschcau
- markuplint
- moschcau

24
.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# jetbrains setting folder
.idea/

6
.markuplintrc.json Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": ["markuplint:recommended-static-html"],
"parser": {
".astro$": "@markuplint/astro-parser"
}
}

7
.stylelintignore Normal file
View File

@@ -0,0 +1,7 @@
# vim: filetype=gitignore
*.ico
*.json
*.md
*.mjs
*.svg
*.yaml

45
README.md Normal file
View File

@@ -0,0 +1,45 @@
# Astro Starter Kit: Minimal
```sh
pnpm create astro@latest -- --template minimal
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page
is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put
any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm dev` | Starts local dev server at `localhost:4321` |
| `pnpm build` | Build your production site to `./dist/` |
| `pnpm preview` | Preview your build locally, before deploying |
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
| `pnpm astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

10
astro.config.mjs Normal file
View File

@@ -0,0 +1,10 @@
// @ts-check
import { defineConfig } from "astro/config";
import tailwindcss from "@tailwindcss/vite";
// https://astro.build/config
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});

21
eslint.config.mjs Normal file
View File

@@ -0,0 +1,21 @@
import js from "@eslint/js";
import eslintPluginAstro from "eslint-plugin-astro";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
import { defineConfig } from "eslint/config";
import jsxA11y from "eslint-plugin-jsx-a11y";
export default defineConfig([
{
files: ["**/*.{js,mjs}"],
plugins: { js },
extends: ["js/recommended"],
},
{
files: ["**/*.{astro,html}"],
plugins: {
"jsx-a11y": jsxA11y,
},
},
...eslintPluginAstro.configs.recommended,
eslintPluginPrettierRecommended,
]);

45
package.json Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro",
"lint:eslint": "eslint",
"lint:markuplint": "markuplint '**/*.{astro,html}'",
"lint:stylelint": "stylelint ."
},
"dependencies": {
"@tailwindcss/vite": "^4.2.1",
"astro": "^5.17.1",
"tailwindcss": "^4.2.1"
},
"devDependencies": {
"@astrojs/ts-plugin": "^1.10.6",
"@cspell/dict-de-de": "^4.1.2",
"@eslint/js": "^10.0.1",
"@markuplint/astro-parser": "^4.6.23",
"@markuplint/ml-config": "^4.8.15",
"@typescript-eslint/parser": "^8.56.1",
"cspell": "^9.7.0",
"eslint": "^10.0.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-astro": "^1.6.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.5.5",
"markuplint": "^4.14.1",
"postcss-html": "^1.8.1",
"prettier": "^3.8.1",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"sharp": "^0.34.5",
"stylelint": "^17.4.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^18.0.0",
"stylelint-config-standard": "^40.0.0",
"stylelint-config-tailwindcss": "^1.0.1",
"typescript": "^5.9.3"
}
}

7969
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

15
prettier.config.mjs Normal file
View File

@@ -0,0 +1,15 @@
/** @type {import("prettier").Config} */
export default {
plugins: ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
overrides: [
{
files: "*.astro",
options: {
parser: "astro",
},
},
],
astroAllowShorthand: true,
};

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,22 @@
---
import type { HTMLAttributes } from "astro/types";
interface Props extends HTMLAttributes<"a"> {
cssClass: string;
href: string;
title: string;
}
const { cssClass, href, title } = Astro.props;
---
<a
class:list={[
cssClass,
"flex min-w-full items-center justify-center gap-4 rounded px-6 py-2 text-lg sm:px-24",
]}
{href}
{title}
target="_blank"
rel="external me noreferrer"><slot name="logo" /><slot /></a
>

View File

@@ -0,0 +1,22 @@
---
import type { ImageMetadata } from "astro";
import { Image } from "astro:assets";
interface Props {
priority?: boolean;
size?: number;
src: ImageMetadata;
}
const { priority = true, size = 24, src } = Astro.props;
---
<Image
alt=""
height={size}
width={size}
{priority}
{src}
role="presentation"
class="brightness-1000 grayscale"
/>

View File

@@ -0,0 +1,17 @@
---
import type { SvgComponent } from "astro/types";
interface Props {
SvgComponent: SvgComponent;
size?: number;
}
const { size = 24, SvgComponent } = Astro.props;
---
<SvgComponent
height={size}
width={size}
fill="currentColor"
role="presentation"
/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path d="M 30,2.0000001 V 30 h -1 -2 v 2 h 5 V -3.3333334e-8 L 27,0 v 2 z"/>
<path d="M 9.9515939,10.594002 V 12.138 h 0.043994 c 0.3845141,-0.563728 0.8932271,-1.031728 1.4869981,-1.368 0.580003,-0.322998 1.244999,-0.485 1.993002,-0.485 0.72,0 1.376999,0.139993 1.971998,0.42 0.595,0.279004 1.047001,0.771001 1.355002,1.477001 0.338003,-0.500001 0.795999,-0.941 1.376999,-1.323001 0.579999,-0.382998 1.265998,-0.574 2.059998,-0.574 0.602003,0 1.160002,0.074 1.674002,0.220006 0.514,0.148006 0.953998,0.382998 1.321999,0.706998 0.36601,0.322999 0.653001,0.746 0.859,1.268002 0.205001,0.521998 0.307994,1.15 0.307994,1.887001 v 7.632997 h -3.127 v -6.463997 c 0,-0.383002 -0.01512,-0.743002 -0.04399,-1.082003 -0.02079,-0.3072 -0.103219,-0.607113 -0.242003,-0.881998 -0.133153,-0.25081 -0.335962,-0.457777 -0.584001,-0.596002 -0.257008,-0.146003 -0.605998,-0.220006 -1.046997,-0.220006 -0.440002,0 -0.796003,0.085 -1.068,0.253002 -0.272013,0.170003 -0.485001,0.390002 -0.639001,0.662003 -0.159119,0.287282 -0.263585,0.601602 -0.307994,0.926997 -0.05197,0.346923 -0.07801,0.697217 -0.07801,1.048002 v 6.353999 h -3.128005 v -6.398 c 0,-0.338003 -0.0072,-0.673001 -0.02116,-1.004001 -0.01134,-0.313663 -0.07487,-0.623229 -0.187994,-0.915999 -0.107943,-0.276623 -0.300435,-0.512126 -0.550001,-0.673001 -0.25799,-0.168 -0.636,-0.253002 -1.134999,-0.253002 -0.198123,0.0083 -0.394383,0.04195 -0.584002,0.100006 -0.258368,0.07446 -0.498455,0.201827 -0.704999,0.373985 -0.227981,0.183987 -0.421999,0.449 -0.583997,0.794003 -0.161008,0.345978 -0.242003,0.797998 -0.242003,1.356998 v 6.618999 H 6.99942 V 10.590001 Z"/>
<path d="M 2,2.0000001 V 30 h 3 v 2 H 0 V 9.2650922e-8 L 5,0 v 2 z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/images/portrait.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

49
src/pages/index.astro Normal file
View File

@@ -0,0 +1,49 @@
---
import { Image } from "astro:assets";
import ExternalLink from "../components/external-link.astro";
import InlineSvg from "../components/inline-svg.astro";
import MatrixLogo from "../images/matrix-logo.svg";
import portrait from "../images/portrait.jpg";
import "../styles/global.css";
---
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="light dark" />
<meta name="generator" content={Astro.generator} />
<title>kmoschcau.de</title>
</head>
<body
class="flex min-h-screen flex-col justify-center p-6 sm:px-14 md:px-24 lg:px-32"
>
<main>
<article class="flex flex-col items-center gap-10">
<Image
alt="Portrait von Kai Moschcau"
class="rounded-full"
priority
src={portrait}
width={200}
height={200}
/>
<h1>Kai Moschcau</h1>
<ul class="flex flex-col gap-2">
<li>
<ExternalLink
cssClass="link-matrix"
href="https://matrix.to/#/@kmoschcau:matrix.org"
title="Mein Matrix Konto"
>
<InlineSvg SvgComponent={MatrixLogo} slot="logo" />
<span>@kmoschcau:matrix.org</span>
</ExternalLink>
</li>
</ul>
</article>
</main>
</body>
</html>

53
src/styles/global.css Normal file
View File

@@ -0,0 +1,53 @@
@import "tailwindcss";
@theme {
--color-background-dark: oklch(from var(--color-violet-950) 24% 0.08 h);
--link-bg-l: 53.5%;
--hover-darken: 0.05;
--color-fur-affinity: oklch(from #353b45 var(--link-bg-l) c h);
--color-fur-affinity-hover: oklch(
from var(--color-fur-affinity) calc(l - var(--hover-darken)) c h
);
--color-mastodon: oklch(from #6364ff var(--link-bg-l) c h);
--color-mastodon-hover: oklch(
from var(--color-mastodon) calc(l - var(--hover-darken)) c h
);
--color-matrix: oklch(from #0dbd8b var(--link-bg-l) c h);
--color-matrix-hover: oklch(
from var(--color-matrix) calc(l - var(--hover-darken)) c h
);
}
@layer base {
body {
@apply dark:bg-background-dark bg-neutral-50 text-black dark:text-white;
}
h1 {
@apply text-5xl font-bold;
}
}
@layer components {
.link-fur-affinity {
@apply bg-fur-affinity hover:bg-fur-affinity-hover text-white;
}
.link-mastodon {
@apply bg-mastodon hover:bg-mastodon-hover text-white;
}
.link-matrix {
@apply bg-matrix hover:bg-matrix-hover text-white;
}
}
@layer utilities {
.text-soft {
@apply text-zinc-600 dark:text-zinc-400;
}
}

8
stylelint.config.mjs Normal file
View File

@@ -0,0 +1,8 @@
/** @type {import("stylelint").Config} */
export default {
extends: [
"stylelint-config-recommended",
"stylelint-config-tailwindcss",
"stylelint-config-html/astro",
],
};

9
tsconfig.json Normal file
View File

@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"extends": "astro/tsconfigs/strictest",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"],
"compilerOptions": {
"plugins": [{ "name": "@astrojs/ts-plugin" }]
}
}