Reimplement base site

This commit is contained in:
pancakes 2024-04-23 22:43:13 +10:00
parent d48ca50d6b
commit 0857f02cfe
67 changed files with 962 additions and 6 deletions

64
package-lock.json generated
View file

@ -15,6 +15,7 @@
"@types/eslint": "^8.56.0",
"eslint": "^8.56.0",
"eslint-plugin-svelte": "^2.35.1",
"mdsvex": "^0.11.0",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"tslib": "^2.4.1",
@ -434,6 +435,12 @@
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
"dev": true
},
"node_modules/@types/unist": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
"integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==",
"dev": true
},
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@ -1555,6 +1562,21 @@
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"dev": true
},
"node_modules/mdsvex": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.0.tgz",
"integrity": "sha512-gJF1s0N2nCmdxcKn8HDn0LKrN8poStqAicp6bBcsKFd/zkUBGLP5e7vnxu+g0pjBbDFOscUyI1mtHz+YK2TCDw==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.3",
"prism-svelte": "^0.4.7",
"prismjs": "^1.17.1",
"vfile-message": "^2.0.4"
},
"peerDependencies": {
"svelte": ">=3 <5"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -1909,6 +1931,21 @@
"node": ">= 0.8.0"
}
},
"node_modules/prism-svelte": {
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
"integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==",
"dev": true
},
"node_modules/prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@ -2434,6 +2471,19 @@
"node": ">=14.17"
}
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.2"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -2449,6 +2499,20 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"node_modules/vfile-message": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-stringify-position": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/vite": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz",

View file

@ -18,6 +18,7 @@
"@types/eslint": "^8.56.0",
"eslint": "^8.56.0",
"eslint-plugin-svelte": "^2.35.1",
"mdsvex": "^0.11.0",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"tslib": "^2.4.1",
@ -25,4 +26,4 @@
"vite": "^5.0.3"
},
"type": "module"
}
}

26
src/data/links.json Normal file
View file

@ -0,0 +1,26 @@
[
{
"href": "https://codeberg.org/pancakes",
"icon": "codeberg.png",
"name": "Codeberg",
"username": "@pancakes"
},
{
"href": "https://cats.city/@pancakes",
"icon": "fediverse.png",
"name": "Fediverse",
"username": "@pancakes@cats.city"
},
{
"href": "https://pronouns.cc/@pancakes",
"icon": "pronouns_cc.png",
"name": "pronouns.cc",
"username": "@pancakes"
},
{
"href": "https://youtube.com/@trypancakes",
"icon": "youtube.png",
"name": "YouTube",
"username": "@trypancakes"
}
]

View file

@ -0,0 +1,38 @@
<script>
import DateTime from "./DateTime.svelte";
import { page } from "$app/stores";
</script>
<svelte:head>
{#if $page.data.header}
<meta property="og:image" content={$page.data.header} />
{/if}
</svelte:head>
<header id="main-content">
{#if $page.data.header}
<img src={$page.data.header} alt="header" class="header" />
{/if}
<h1>{$page.data.title}</h1>
<p>{$page.data.description}</p>
{#if $page.data.published}
<p>
<small>
Published:
<DateTime datetime={$page.data.published} display="date" />
{#if $page.data.edited}
&bull; Last edited:
<DateTime datetime={$page.data.edited} display="dateTime" />
{/if}
</small>
</p>
{/if}
</header>
<style>
img.header {
width: 100%;
}
</style>

View file

@ -0,0 +1,31 @@
<script>
/** @type string | undefined */
export let datetime = undefined;
/** @type "date" | "dateTime" | "time" */
export let display = "date";
/** @type string | undefined */
export let timeZone = undefined;
const date = datetime ? Date.parse(datetime) : Date.now();
/** @type Intl.DateTimeFormatOptions */
let options;
switch (display) {
case "date":
options = { dateStyle: "short", timeZone };
break;
case "dateTime":
options = { dateStyle: "short", timeStyle: "short", timeZone };
break;
case "time":
options = { timeStyle: "short", timeZone };
break;
}
const formattedDate = Intl.DateTimeFormat(
navigator.language,
options,
).format(date);
</script>
<time {datetime}>{formattedDate}</time>

View file

@ -0,0 +1,30 @@
<script>
import { page } from "$app/stores";
</script>
<footer>
{#if $page.data.footer === true}
<p>
The contents of this page are licensed under
<a
href="https://creativecommons.org/licenses/by-sa/4.0/"
target="_blank"
>
CC BY-SA 4.0
</a>
</p>
{:else if $page.data.footer}
<p>{$page.data.footer}</p>
{/if}
<p>🐈‍⬛</p>
</footer>
<style>
footer {
margin-left: auto;
margin-right: auto;
padding: 3rem 1rem;
max-width: 768px;
text-align: center;
}
</style>

View file

@ -0,0 +1,92 @@
<script>
import links from "../../data/links.json";
import { page } from "$app/stores";
</script>
<a href="#main-content" class="skip-to-main">Skip to main content</a>
<nav>
<span class="brand icon-link">
<img src="/favicon.png" alt="a black cat with large eyes" />
<a href="/">pancakes</a>
</span>
{#if $page.url.pathname !== "/"}
<ul>
{#each links as link}
<li>
<div class="icon-link">
<img
src={"/assets/icons/" + link.icon}
alt={link.name}
/>
<a href={link.href} target="_blank">
{link.name}
</a>
</div>
</li>
{/each}
</ul>
{/if}
</nav>
<style>
a.skip-to-main {
position: absolute;
top: -5rem;
left: 1rem;
transition: top 0.5s;
}
a.skip-to-main:focus {
top: 1rem;
}
nav {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
padding: 1rem;
}
nav > ul {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 1rem;
margin: 0;
padding: 0;
list-style: none;
}
a {
color: var(--foreground);
}
a:hover {
background-color: var(--foreground);
color: var(--background);
}
.brand {
font-size: x-large;
}
.brand > img {
border-radius: 20%;
}
.brand > a,
.brand > a:visited {
font-weight: bold;
text-decoration-color: var(--accent);
text-decoration-style: wavy;
}
.brand > a:hover {
background-color: var(--accent);
color: var(--background);
}
</style>

29
src/lib/pages.js Normal file
View file

@ -0,0 +1,29 @@
export function getPages() {
const paths = import.meta.glob("/src/data/pages/*.md", { eager: true });
const pages = [];
for (const path in paths) {
const file = paths[path]
const slug = path.split('/').at(-1)?.replace('.md', '')
if (file && typeof file === 'object' && 'metadata' in file && slug) {
const metadata = file.metadata
// hopefully this will get my attention
if (!metadata.title) throw `${slug} doesn't have a title`;
if (!metadata.description) throw `${slug} doesn't have a description`;
pages.push({ ...metadata, slug });
}
}
const byTitle = pages.filter((page) => !page.published).sort((a, b) => a.title > b.title);
const byDate = pages.filter((page) => page.published).sort((a, b) => {
const aDate = Date.parse(a.published);
const bDate = Date.parse(b.published);
if (aDate == bDate) return a.title > b.title;
aDate < bDate;
});
return byTitle.concat(byDate);
}

14
src/routes/+error.svelte Normal file
View file

@ -0,0 +1,14 @@
<script>
import { page } from "$app/stores";
</script>
<svelte:head>
<title>{$page.status} | pancakes</title>
<meta name="description" content={$page.error.message} />
</svelte:head>
<main>
<h1>{$page.status}</h1>
<p>{$page.error.message}</p>
<img src="/assets/neocat_shocked.png" alt="neocat shocked" />
</main>

28
src/routes/+layout.svelte Normal file
View file

@ -0,0 +1,28 @@
<script>
import "./style.css";
import { page } from "$app/stores";
import Footer from "$lib/components/Footer.svelte";
import Navbar from "$lib/components/Navbar.svelte";
</script>
<svelte:head>
<title>
{$page.data.title ? $page.data.title + " | pancakes" : "pancakes"}
</title>
<meta name="description" content={$page.data.description || "🐈‍⬛"} />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="pancakes" />
<meta
property="og:url"
content={"https://trypancakes.com" + $page.url.pathname}
/>
<meta property="og:title" content={$page.data.title || "pancakes"} />
<meta property="og:image" content="https://trypancakes.com/favicon.png" />
<meta property="og:image:alt" content="a black cat with large eyes" />
</svelte:head>
<Navbar />
<slot />
<Footer />

View file

@ -1,2 +1,210 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script>
import links from "../data/links.json";
import DateTime from "$lib/components/DateTime.svelte";
import { getPages } from "$lib/pages";
const pages = getPages();
</script>
<main id="main-content">
<header>
<h1 id="about-me">About Me</h1>
<p>
I'm a 21 year old from Australia (it's
<DateTime display="time" timeZone="Australia/Brisbane" />). I like
cats, Linux, and programming. I have a vision impairment. Some games
I like are: Minecraft, OneShot, Team Fortress 2, Celeste,
<span class="upper">Death Stranding</span>, and Red Dead Redemption
2.
</p>
</header>
<h2 id="links">Links</h2>
<p>Other profiles and places you can find me on the internet:</p>
{#each links as link}
<div class="icon-link">
<img src={"/assets/icons/" + link.icon} alt={link.name} />
<a href={link.href} target="_blank">
{link.name} ({link.username})
</a>
</div>
{/each}
<h3 id="contact">Contact</h3>
<p>
I would prefer if you contact me on the Fediverse
<a href="https://cats.city/@pancakes" target="_blank">
@pancakes@cats.city
</a>
or Matrix
<a href="https://matrix.to/#/@pancakes:void.rehab" target="_blank">
@pancakes:void.rehab
</a>
but I also have a Discord account @trypancakes.
</p>
<h2 id="pages">Pages</h2>
<div class="notice">
<p>
Content under the pages section uses the
<a
href="https://creativecommons.org/licenses/by-sa/4.0/"
target="_blank"
>
Creative Commons Attribution-ShareAlike 4.0 International (CC
BY-SA 4.0)
</a>
license unless specified in the page footer.
</p>
</div>
<dl>
{#each pages as page}
<h3>
<a href={"/" + page.slug + "/"}>
{page.title}
</a>
</h3>
<p>{page.description}</p>
{#if page.published}
<p>
<small>
Published:
<DateTime datetime={page.published} />
{#if page.edited}
&bull; Last edited:
<DateTime
datetime={page.edited}
display="dateTime"
/>
{/if}
</small>
</p>
{/if}
{/each}
</dl>
<h2 id="projects">Projects</h2>
<h3 id="firefish-edits">Firefish Edits</h3>
<p>
A set of CSS snippets for Firefish and Iceshrimp that make the
experience better for me. This includes things such as indicating when
media doesn't have alt text or that a post is mention-only.
</p>
<p>
<a
href="https://codeberg.org/pancakes/firefish-edits"
target="_blank"
rel="noopener noreferrer"
>
View Project
</a>
</p>
<h3 id="scp-wiki-pages">SCP Wiki Pages</h3>
<p>
A Fediverse bot that posts random articles from the
<a
href="https://scp-wiki.wikidot.com"
target="_blank"
rel="noopener noreferrer"
>
SCP Foundation Wiki
</a>
multiple times per day. The bot posts at
<time datetime="00:00">00:00</time>
<time datetime="06:00">06:00</time>,
<time datetime="12:00">12:00</time>, and
<time datetime="18:00">18:00</time> Sydney time. It displays the title, rating,
author, item number, object class/anomaly classification, tags, and an image
when possible.
</p>
<figure>
<img
src="/assets/project/scp_pages/screenshot.png"
alt="A Mastodon post from @scp_pages@botsin.space. The post content matches the general description noted before."
/>
<figcaption>
Example post:
<a
href="https://botsin.space/@scp_pages/111328337740557018"
target="_blank"
>
View Original
</a>
</figcaption>
</figure>
<p>
<a href="https://botsin.space/@scp_pages" target="_blank">
View Project
</a>
</p>
<section id="buttons">
<a href="/">
<img src="/assets/buttons/pancakes.png" alt="pancakes" />
</a>
<a href="https://blueb.me/" target="_blank">
<img
src="/assets/buttons/kattgutte.D3vLs2tl.png"
alt="blueb's website"
/>
</a>
<a href="https://micro.pages.gay" target="_blank">
<img src="/assets/buttons/micro.png" alt="micro's site" />
</a>
<a href="https://w.on-t.work/" target="_blank">
<img src="/assets/buttons/wontwork.png" alt="Won't Work!" />
</a>
<img src="/assets/buttons/css.jpg" alt="CSS is awesome" />
<img src="/assets/buttons/valid-html5.gif" alt="W3C HTML5 validated" />
<img src="/assets/buttons/emulate.gif" alt="Emulate Now!" />
<a href="https://thefedi.wiki" target="_blank">
<img src="/assets/buttons/fediverse.gif" alt="Join the Fediverse" />
</a>
<a href="https://www.mozilla.org/en-US/firefox/new/" target="_blank"
><img src="/assets/buttons/getfirefox.gif" alt="Get Firefox" /></a
>
<img src="/assets/buttons/xenia.gif" alt="Linux Now" />
<img src="/assets/buttons/paws.png" alt="made with My Own Two Paws" />
<a href="https://scp-wiki.wikidot.com" target="_blank">
<img src="/assets/buttons/scp.png" alt="SCP" />
</a>
<a
href="https://store.steampowered.com/app/440/Team_Fortress_2/"
target="_blank"
>
<img
src="/assets/buttons/team_fortress_get_it.gif"
alt="Team Fortress. Get It!"
/>
</a>
<a href="https://ublockorigin.com/" target="_blank">
<img src="/assets/buttons/ublock.png" alt="uBlock Origin Now!" />
</a>
<img src="/assets/buttons/wii.png" alt="Wii" />
</section>
</main>
<style>
section#buttons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 0.25rem;
justify-content: center;
}
section#buttons img {
image-rendering: pixelated;
width: 88px;
height: 31px;
}
</style>

View file

@ -0,0 +1,12 @@
import { error } from "@sveltejs/kit";
/** @type {import("./$types").PageServerLoad} */
export async function load({ params }) {
try {
const page = await import(`../../data/pages/${params.slug}.md`);
return { ...page.metadata, content: page.default };
} catch (e) {
console.error(e);
error(404, "Not found");
}
}

View file

@ -0,0 +1,17 @@
<script>
import ArticleHeader from "$lib/components/ArticleHeader.svelte";
import { error } from "@sveltejs/kit";
/** @type {import("./$types").PageData} */
export let data;
// hopefully this will get my attention
if (!data.title) error(500, "there is no title dumbass");
if (!data.description) error(500, "there is no description silly");
</script>
<article>
<ArticleHeader />
<svelte:component this={data.content} />
</article>

359
src/routes/style.css Normal file
View file

@ -0,0 +1,359 @@
@font-face {
font-family: "Fira Code VF";
src: url("/assets/fonts/FiraCode-VF/FiraCode-VF.woff2") format("woff2-variations"), url("/assets/fonts/FiraCode-VF/FiraCode-VF.woff") format("woff-variations");
font-weight: 200 700;
font-style: normal;
}
/* This is going to be quite long */
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-ExtraLight.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-ExtraLight.woff") format("woff");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-ExtraLightItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-ExtraLightItalic.woff") format("woff");
font-weight: 200;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-Light.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-Light.woff") format("woff");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-LightItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-LightItalic.woff") format("woff");
font-weight: 300;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-Regular.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-Regular.woff") format("woff");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-Italic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-Italic.woff") format("woff");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-Medium.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-Medium.woff") format("woff");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-MediumItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-MediumItalic.woff") format("woff");
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-SemiBold.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-SemiBold.woff") format("woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-SemiBoldItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-SemiBoldItalic.woff") format("woff");
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-Bold.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-Bold.woff") format("woff");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-BoldItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-BoldItalic.woff") format("woff");
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-ExtraBold.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-ExtraBold.woff") format("woff");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: "FiraGO";
src: url("/assets/fonts/FiraGO/FiraGO-ExtraBoldItalic.woff2") format("woff2"), url("/assets/fonts/FiraGO/FiraGO-ExtraBoldItalic.woff") format("woff");
font-weight: 800;
font-style: italic;
}
:root {
--accent: hsl(287, 50%, 59%);
--accent-2: hsl(287, 50%, 39%);
--background: hsl(302, 69%, 95%);
--background-2: hsl(302, 69%, 90%);
--foreground: hsl(302, 69%, 10%);
--success: hsl(110, 50%, 59%);
--warn: hsl(30, 50%, 59%);
--error: hsl(0, 50%, 59%);
--radius: 12px;
}
body {
/* Display */
margin: 0;
padding: 0;
/* Colors */
background-color: var(--background);
color: var(--foreground);
font-family: "FiraGO", sans-serif;
}
article:first-of-type,
main:first-of-type {
margin-left: auto;
margin-right: auto;
padding: 1rem;
max-width: 768px;
}
h1 {
border-bottom: 2px solid var(--accent-2);
font-size: xx-large;
}
h2 {
border-bottom: 1px solid var(--accent-2);
font-size: x-large;
}
h3 {
font-size: large;
}
h4 {
font-size: medium;
}
h5 {
font-size: small;
}
h6 {
font-size: x-small;
}
a {
padding-left: 0.15em;
padding-right: 0.15em;
color: var(--accent);
text-underline-offset: 0.15rem;
}
a[target="_blank"]:not(:has(>img))::after {
content: "↗";
display: inline-block;
}
a:visited {
color: var(--accent-2);
}
a:not(:has(>img)):hover {
background-color: var(--accent);
color: var(--background);
text-decoration: none;
}
a:not(:has(>img)):visited:hover {
background-color: var(--accent-2);
}
dt::after {
content: ": ";
}
img,
video {
max-width: 100%;
height: auto;
}
blockquote>:not(footer):first-of-type::before {
content: open-quote;
color: var(--accent);
font-weight: 800;
}
blockquote>:not(footer):last-of-type::after {
content: close-quote;
color: var(--accent);
font-weight: 800;
}
blockquote footer::before {
content: "— ";
}
code {
padding-left: 0.15em;
padding-right: 0.15em;
background-color: var(--background-2);
font-family: "Fira Code VF", monospace;
}
pre code {
display: block;
width: 100%;
padding: 0.5rem;
overflow-x: scroll;
border: 1px solid var(--accent);
}
details {
border-left: 2px solid var(--accent-2);
}
details[open] {
padding-bottom: 1px;
}
details+details {
margin-top: 0.5em;
}
details>* {
margin-left: 2em;
}
details>summary {
margin-left: 0;
padding: 0.5em;
width: fit-content;
cursor: pointer;
background-color: var(--accent-2);
color: var(--background);
}
kbd {
padding-left: 0.5em;
padding-right: 0.5em;
background-color: var(--background-2);
border-radius: var(--radius);
}
mark {
padding-left: 0.25em;
padding-right: 0.25em;
background-color: var(--accent);
color: var(--background);
}
td,
th {
padding: 0.25em;
}
table {
display: block;
max-width: 100%;
overflow-x: scroll;
}
table.rows tbody tr {
background-color: var(--background-2);
}
table.rows tbody tr:nth-child(2n) {
background-color: transparent;
}
.table-y {
background-color: var(--success);
color: black;
}
.table-p {
background-color: var(--warn);
color: black;
}
.table-n {
background-color: var(--error);
color: black;
}
.icon-link>a {
line-height: 2em;
}
.icon-link>img {
display: inline-block;
width: 2em;
max-height: 2em;
vertical-align: middle;
}
.notice {
display: block;
padding: 0.5rem;
border: 2px dashed var(--warn);
}
.notice::before {
content: "🛈 Notice";
color: var(--warn);
font-size: larger;
font-weight: bolder;
}
.notice>p:first-child {
margin-top: 0;
}
.notice>p:last-child {
margin-bottom: 0;
}
.upper {
text-transform: uppercase;
}
::selection {
background-color: var(--accent);
color: var(--background);
}
@media (prefers-color-scheme: dark) {
:root {
--accent-2: hsl(287, 50%, 79%);
--background: hsl(302, 69%, 10%);
--background-2: hsl(302, 69%, 5%);
--foreground: hsl(302, 69%, 95%);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
static/assets/neocat_shocked.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
static/favicon.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View file

@ -1,16 +1,23 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { mdsvex } from "mdsvex";
/** @type {import('@sveltejs/kit').Config} */
export default {
kit: {
adapter: adapter({
// default options are shown. On some platforms
// these options are set automatically — see below
pages: 'build',
assets: 'build',
fallback: undefined,
precompress: false,
strict: true
})
}
},
extensions: [".svelte", ".md"],
preprocess: [
vitePreprocess(),
mdsvex({ extensions: [".md"] })
]
};