Reimplement base site
64
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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
|
@ -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"
|
||||
}
|
||||
]
|
38
src/lib/components/ArticleHeader.svelte
Normal 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}
|
||||
• Last edited:
|
||||
<DateTime datetime={$page.data.edited} display="dateTime" />
|
||||
{/if}
|
||||
</small>
|
||||
</p>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<style>
|
||||
img.header {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
31
src/lib/components/DateTime.svelte
Normal 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>
|
30
src/lib/components/Footer.svelte
Normal 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>
|
92
src/lib/components/Navbar.svelte
Normal 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
|
@ -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
|
@ -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
|
@ -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 />
|
|
@ -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}
|
||||
• 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>
|
||||
|
|
12
src/routes/[slug]/+page.js
Normal 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");
|
||||
}
|
||||
}
|
17
src/routes/[slug]/+page.svelte
Normal 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
|
@ -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%);
|
||||
}
|
||||
}
|
BIN
static/assets/buttons/css.jpg
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/assets/buttons/emulate.gif
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/assets/buttons/fediverse.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
static/assets/buttons/getfirefox.gif
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/assets/buttons/kattgutte.D3vLs2tl.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
static/assets/buttons/micro.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
static/assets/buttons/pancakes.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
static/assets/buttons/paws.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/assets/buttons/scp.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
static/assets/buttons/team_fortress_get_it.gif
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
static/assets/buttons/ublock.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/assets/buttons/valid-html5.gif
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
static/assets/buttons/wii.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
static/assets/buttons/wontwork.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
static/assets/buttons/xenia.gif
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/assets/fonts/FiraCode-VF/FiraCode-VF.woff
Normal file
BIN
static/assets/fonts/FiraCode-VF/FiraCode-VF.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Bold.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Bold.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-BoldItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-BoldItalic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraBold.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraBold.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraBoldItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraBoldItalic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraLight.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraLight.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraLightItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-ExtraLightItalic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Italic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Italic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Light.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Light.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-LightItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-LightItalic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Medium.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Medium.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-MediumItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-MediumItalic.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Regular.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-Regular.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-SemiBold.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-SemiBold.woff2
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-SemiBoldItalic.woff
Normal file
BIN
static/assets/fonts/FiraGO/FiraGO-SemiBoldItalic.woff2
Normal file
BIN
static/assets/icons/codeberg.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
static/assets/icons/fediverse.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
static/assets/icons/pronouns_cc.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
static/assets/icons/youtube.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
static/assets/neocat_shocked.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
static/assets/project/scp_pages/screenshot.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
static/favicon.png
Normal file → Executable file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 54 KiB |
|
@ -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"] })
|
||||
]
|
||||
};
|
||||
|
|