aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2026-01-14 06:34:44 +0100
committerLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2026-01-14 06:34:44 +0100
commitc446fe9590b0a4c5d1442651453b28685ad93239 (patch)
treec4f44fc3c246e4e5c990967e1bce7e3d369822c4 /src
parent69db9b45dd8704102c612863c8ff73ee4bcdbf72 (diff)
downloadmem-estrogen-zone-c446fe9590b0a4c5d1442651453b28685ad93239.tar.gz
mem-estrogen-zone-c446fe9590b0a4c5d1442651453b28685ad93239.tar.bz2
mem-estrogen-zone-c446fe9590b0a4c5d1442651453b28685ad93239.tar.lz
mem-estrogen-zone-c446fe9590b0a4c5d1442651453b28685ad93239.zip

feat: a lot of shit

Diffstat (limited to 'src')
-rw-r--r--src/app.css95
-rw-r--r--src/app.html1
-rw-r--r--src/lib/blog/TableWrapper.svelte15
-rw-r--r--src/routes/blog/+page.svelte25
-rw-r--r--src/routes/blog/[id=int]/+page.svelte25
-rw-r--r--src/routes/blog/posts/test-post.svx105
6 files changed, 246 insertions, 20 deletions
diff --git a/src/app.css b/src/app.css
index ae807c9..7dcddd4 100644
--- a/src/app.css
+++ b/src/app.css
@@ -13,7 +13,8 @@
--font-sans:
InterVariable, Inter, "Noto Sans",
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
- "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", sans-serif;
+ --font-space-grotesk: "Space Grotesk", var(--font-sans), sans-serif;
--font-bios:
'Ac437 IBM EGA 8x14', 'Hack', 'Courier New', 'Courier', 'monospace';
--font-grub:
@@ -23,6 +24,43 @@
'PxPlus IBM EGA 8x14', 'Hack', 'Courier New', 'Courier', 'monospace';
--font-genericmono:
'JetBrainsMono NF', 'Jetbrains Mono', 'JetBrains Mono', monospace;
+ --color-formatted-table-border: var(--color-neutral-900);
+ --color-formatted-table-background: var(--color-neutral-950);
+ --color-codeblock-border: var(--color-neutral-900);
+ --color-codeblock-background: var(--color-neutral-950);
+}
+
+@utility afterunderline-* {
+ @apply relative;
+ &::before {
+ content: '';
+ background: --value(--color-*);
+ @apply absolute top-full left-0 -mt-0.5 h-[0.2rem] w-full transition-all -z-10;
+ }
+}
+@utility afterunderline-hoverstate {
+ &::before {
+ @apply top-0 left-0 mt-0 h-full w-full;
+ }
+}
+
+@utility formatted-table {
+ @apply relative overflow-x-auto shadow-xs rounded-xl border bg-formatted-table-background border-formatted-table-border;
+ table {
+ @apply w-full text-sm text-left rtl:text-right bg-formatted-table-background;
+ thead {
+ @apply text-sm border-b rounded-xl border-formatted-table-border;
+ }
+ tbody tr {
+ @apply not-last:border-b border-formatted-table-border;
+ }
+ th,td {
+ @apply px-6 py-3;
+ }
+ td > b:first-child:last-child {
+ @apply px-6 py-4 font-medium whitespace-nowrap;
+ }
+ }
}
@utility internal-header-active {
@@ -35,8 +73,11 @@
}
#postmd {
@apply font-sans;
+ a {
+ @apply text-red-400 transition-all afterunderline-red-400 hover:afterunderline-hoverstate hover:text-white;
+ }
h1 {
- @apply first:font-bios first:text-5xl text-4xl mb-1.5 mt-2;
+ @apply text-4xl mb-1.5 mt-2;
}
h2 {
@apply my-1.5 text-2xl;
@@ -62,6 +103,9 @@
&:hover::after {
@apply -ml-3 bg-gray-200/75;
}
+ &:hover ~ p:is(p)::after {
+ @apply bg-gray-200/4;
+ }
}
h1 {
&:not(:hover):has(~*:hover):not(:has(~h1~*:hover)) {
@@ -94,6 +138,53 @@
p {
@apply my-1;
}
+ code {
+ @apply font-genericmono;
+ }
+ p code {
+ @apply bg-codeblock-background -my-1 p-1 rounded-lg;
+ }
+ pre {
+ @apply p-3 -mx-2 overflow-scroll bg-codeblock-background border border-codeblock-border rounded-lg transition-colors max-h-[min(75vh,38rem)];
+ code {
+ .token {
+ @apply text-red-500;
+ }
+ &,
+ .token.builtin,
+ .token.interpolation {
+ @apply text-[#9CDCFE] selection:bg-[#9CDCFE] selection:text-black;
+ }
+ .token.operator {
+ @apply text-[#d4d4d4] selection:bg-[#d4d4d4] selection:text-black;
+ }
+ .token.class-name {
+ @apply text-[#4ec9b0] selection:bg-[#4ec9b0] selection:text-black;
+ }
+ .token.number {
+ @apply text-[#b5cea8] selection:bg-[#b5cea8] selection:text-black;
+ }
+ .token.comment {
+ @apply text-[#6a9955] selection:bg-[#6a9955] selection:text-black;
+ }
+ .token.keyword {
+ @apply text-[#c586c0] selection:bg-[#c586c0] selection:text-black;
+ }
+ .token.punctuation {
+ @apply text-[white] selection:bg-[white] selection:text-black;
+ }
+ .token.function {
+ @apply text-[#dcdcaa] selection:bg-[#dcdcaa] selection:text-black;
+ }
+ .token.string {
+ @apply text-[#ce9178] selection:bg-[#ce9178] selection:text-black;
+ }
+ .token.boolean,
+ .token.interpolation-punctuation {
+ @apply text-[#5293c9] selection:bg-[#5293c9] selection:text-black;
+ }
+ }
+ }
}
/*
diff --git a/src/app.html b/src/app.html
index 2d05f4f..aaf7ac2 100644
--- a/src/app.html
+++ b/src/app.html
@@ -21,6 +21,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.webp" />
<link rel="stylesheet" href="%sveltekit.assets%/inter/inter.css" />
+ <link rel="stylesheet" href="%sveltekit.assets%/spacegrotesk/spacegrotesk.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
diff --git a/src/lib/blog/TableWrapper.svelte b/src/lib/blog/TableWrapper.svelte
new file mode 100644
index 0000000..ddf3d73
--- /dev/null
+++ b/src/lib/blog/TableWrapper.svelte
@@ -0,0 +1,15 @@
+<script lang="ts">
+ import type { Snippet } from 'svelte';
+
+ const {
+ children,
+ maxwidth = false,
+ }: {
+ children: Snippet;
+ maxwidth?: boolean;
+ } = $props();
+</script>
+
+<div class={{ 'formatted-table my-1': true, 'w-max': !maxwidth }}>
+ {@render children()}
+</div>
diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte
index a817d44..89a3b3a 100644
--- a/src/routes/blog/+page.svelte
+++ b/src/routes/blog/+page.svelte
@@ -1,13 +1,26 @@
<script lang="ts">
+ import { resolve } from '$app/paths';
import type { PageProps } from './$types';
let { data }: PageProps = $props();
</script>
-<div class="font-mono">
- {#each Object.entries(data.posts) as [_filename, post]}
- {JSON.stringify(post.metadata, (k, v) =>
- v instanceof Date ? v.toISOString() : v,
- )}
- {/each}
+<div class="flex justify-center">
+ <div class="max-w-2xl">
+ <div class="font-genericmono">
+ {#each Object.entries(data.posts) as [_filename, post]}
+ <a
+ href={resolve('/blog/[id=int]-[slug]', {
+ id: post.metadata.id.toString(),
+ slug: post.metadata.slug,
+ })}
+ class="text-red-400 transition-all afterunderline-red-400 hover:afterunderline-hoverstate hover:text-white"
+ >link</a
+ >
+ {JSON.stringify(post.metadata, (k, v) =>
+ v instanceof Date ? v.toISOString() : v,
+ )}
+ {/each}
+ </div>
+ </div>
</div>
diff --git a/src/routes/blog/[id=int]/+page.svelte b/src/routes/blog/[id=int]/+page.svelte
index 16fc586..b2f6807 100644
--- a/src/routes/blog/[id=int]/+page.svelte
+++ b/src/routes/blog/[id=int]/+page.svelte
@@ -10,19 +10,22 @@
let { data }: PageProps = $props();
+ let route = $derived(
+ forceTrailingSlash(
+ resolve('/blog/[id=int]-[slug]', {
+ id: data.post.metadata.id.toString(),
+ slug: data.post.metadata.slug,
+ }),
+ ),
+ );
+
onMount(() => {
- tick().then(() =>
- replaceState(
- forceTrailingSlash(
- resolve('/blog/[id=int]-[slug]', {
- id: data.post.metadata.id.toString(),
- slug: data.post.metadata.slug,
- }),
- ),
- page.state,
- ),
- );
+ tick().then(() => replaceState(route, page.state));
});
</script>
+<svelte:head>
+ <link rel="canonical" href={new URL(route, page.url).href} />
+</svelte:head>
+
<Post post={data.post} />
diff --git a/src/routes/blog/posts/test-post.svx b/src/routes/blog/posts/test-post.svx
index a3f8248..71d8c21 100644
--- a/src/routes/blog/posts/test-post.svx
+++ b/src/routes/blog/posts/test-post.svx
@@ -10,9 +10,45 @@ created: "2026-01-14T01:25:14Z"
updated: "2026-01-14T01:25:14Z"
---
+<script lang="ts">
+ import TableWrapper from '$/lib/blog/TableWrapper.svelte';
+</script>
+
# Test Post
-this is a test blog post
+this is a test blog post.
+
+## markdown
+
+[this is a link](https://en.wikipedia.org/wiki/Catgirl).
+
+*this is italic*, and _this is too_. __this is underscore bolded__, and **this is asterisk bolded**.
+
+`this is single backticked`.
+
+```js
+console.log('and this is a codeblock');
+```
+
+### unwrapped table
+
+| | awawa | test |
+|-------|-------|-------|
+| **a** | b | k |
+| **z** | c | |
+| **f** | d | f |
+
+### wrapped table
+
+<TableWrapper>
+
+| | awawa | test |
+|-------|-------|-------|
+| **a** | b | k |
+| **z** | c | |
+| **f** | d | f |
+
+</TableWrapper>
# section testing
@@ -79,3 +115,70 @@ Eaque cum dolores ut enim voluptatibus id velit velit. Iure eveniet alias dolori
Autem ut nam sapiente et a magni. Qui maiores in qui earum. Veniam veniam omnis id architecto. Et optio et et molestias.
Eaque cum dolores ut enim voluptatibus id velit velit. Iure eveniet alias doloribus. Ratione in in est aspernatur.
+
+## some code
+
+```ts
+/*
+ Copyright (C) 2024-2026 memdmp
+
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by Affero, Inc., at version 1.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Affero General Public License for more details.
+
+ You should have received a copy of the Affero General Public License along with this program. If not, see <https://spdx.org/licenses/AGPL-1.0-only>.
+*/
+import { Animation, MultiObjectKeyframe } from '@memdmp/keyframegen';
+import {
+ biosStepInterval,
+ biosSteps,
+ getDelay,
+ login,
+ ttyLines,
+} from './shared.ts';
+import fs from 'node:fs';
+import esbuild from 'esbuild';
+console.log('hi');
+const anim = new Animation();
+let ttyCtr = 0;
+const stages = [
+ anim.selector('.anmroot #bios'),
+ anim.selector('.anmroot #grub'),
+ anim.selector('.anmroot #grub-term'),
+ anim.selector('.anmroot #openrc'),
+ ...ttyLines.flatMap((v) =>
+ v.kind === 'clear' ? [anim.selector('.anmroot #tty-' + ttyCtr++)] : [],
+ ),
+];
+const handleSteps: Step[] = [
+ // (n) => {
+ // toStage(0);
+ // anim.in(500, n);
+ // },
+ ...biosStepHandlers,
+ ...grubStepHandlers,
+ ...openrcStepHandlers(1),
+ ...ttyStepHandlers,
+ (n) => {
+ const s = anim.selector('.anmroot #app .hidden-after-anim');
+ s.style(visibleStyles);
+ anim._internal_timeline.now += 1;
+ s.style(hiddenStyles);
+ anim.in(1000, n);
+ },
+];
+fs.writeFileSync(
+ 'src/routes/anim.css',
+ `${comment}
+${esbuild.buildSync({
+ stdin: {
+ contents: `${exported}
+${tail}`,
+ loader: 'css',
+ },
+ write: false,
+ minify: false,
+ }).outputFiles![0].text
+ }`,
+);
+```