big style update

This commit is contained in:
Daniel Ledda
2025-12-20 21:16:00 +01:00
parent 51e44db779
commit 498cb37561
17 changed files with 562 additions and 322 deletions

View File

@@ -17,9 +17,10 @@ const tooltipStyles = css`
opacity: 0;
display: block;
pointer-events: none;
background-color: black;
border: white solid 1px;
color: white;
background-color: var(--dj-bgpalette1);
box-shadow: 0 0 12px 1px rgb(10 12 15 / 70%);
border: var(--dj-palette3) solid 1px;
color: var(--dj-palette3);
padding: 10px;
position: absolute;
z-index: 1;
@@ -119,7 +120,7 @@ export default defineComponent({
return () => <>
<div class="tooltip-container"
{...attrs}
{...attrs}
onMouseenter={(e) => tooltip.show(props.tooltip, e.pageX, e.pageY)}
onMouseleave={() => tooltip.hide()}>
{slots.default?.()}

View File

@@ -1,4 +1,15 @@
export type DjAPIEndpoint = "/rp-articles";
export type DjAPIEndpoint =
| "/rp-articles"
| "/blog-entries"
;
type BlogEntry = {
title: string,
slug: string;
createdAt: string,
updatedAt: string,
tags?: string[],
};
type RPArticle = {
title: string,
@@ -11,6 +22,7 @@ type RPArticle = {
export interface DjAPIResultMap extends Record<DjAPIEndpoint, unknown> {
"/rp-articles": RPArticle[];
"/blog-entries": BlogEntry[];
}
export type DjAPIResult = DjAPIResultMap[DjAPIEndpoint];

98
app/blog/DjBlogEntry.tsx Normal file
View File

@@ -0,0 +1,98 @@
import { computed, createTextVNode, defineComponent, h, type VNode } from "vue";
import useHead from "@/useHead.ts";
import useAsyncState from "@/useAsyncState.ts";
import getDjAPI from "@/api.ts";
import getDomParser from "@/domParse.ts";
import { addCSS, css } from "../util.ts";
const style = css`
.byline {
font-style: italic;
color: gray;
}
h1 {
color: var(--dj-palette1);
}
p {
margin-bottom: 30px;
}
`;
export default defineComponent({
name: "DjBlogEntry",
props: {
slug: {
type: String,
required: true,
},
},
async setup(props) {
addCSS('DjBlogEntry', style);
const parseDom = getDomParser();
const blogpostContent = useAsyncState(
`dj-blog-article-content-${ props.slug }`,
async ({ hostUrl }) => {
const blogpostResponse = await fetch(`${hostUrl}/blog/content/${ props.slug }.html`);
const result = await blogpostResponse.text();
return result;
},
);
const blogpostsMetadata = useAsyncState('article-metadata', ({ hostUrl }) => getDjAPI(hostUrl, '/blog-entries'));
const blogpostMetadata = computed(() => blogpostsMetadata.result.value?.find(_ => _.slug === props.slug));
useHead({
title: () => blogpostMetadata.value?.title ?? '',
metatags: () => blogpostMetadata.value ? [
{ name: 'title', content: blogpostMetadata.value.title },
{ name: 'author', content: 'Daniel Ledda' },
] : [],
});
function transformPostNode(node: Node): VNode | string {
if (node.nodeType === node.ELEMENT_NODE) {
const el = node as Element;
const attrs: Record<string, string> = {};
const children = [...node.childNodes].map((_) => transformPostNode(_));
for (let i = 0; i < el.attributes.length; i++) {
const item = el.attributes.item(i);
if (item) {
attrs[item.name] = item.value;
}
}
return h((node as Element).tagName, attrs, children);
} else {
return createTextVNode(node.textContent ?? "");
}
}
function PostContentTransformed() {
if (blogpostContent.result.value) {
const dom = parseDom(blogpostContent.result.value);
return h("div", {}, [...dom.children].map((_) => transformPostNode(_)));
}
return <div>Blog post loading...</div>;
}
await Promise.allSettled([ blogpostContent.done, blogpostsMetadata.done ]);
return () => <>
{ blogpostMetadata.value
? <>
<h1>{ blogpostMetadata.value.title }</h1>
<div class="byline">by Daniel Ledda, first published { new Date(blogpostMetadata.value.createdAt).toLocaleDateString() }</div>
<PostContentTransformed />
</>
: "Sorry, this blog post doesn't seem to exist."
}
</>;
}
});

42
app/blog/DjBlogMain.tsx Normal file
View File

@@ -0,0 +1,42 @@
import { defineComponent } from "vue";
import useAsyncState from "@/useAsyncState.ts";
import getDjAPI from "@/api.ts";
import { RouterLink } from "vue-router";
import { addCSS, css } from "@/util.ts";
const style = css`
.entry {
display: flex;
flex-direction: row;
gap: 4px;
}
`;
export default defineComponent({
name: "DjBlogMain",
async setup() {
addCSS('DjBlogMain', style);
const blogEntries = useAsyncState('blog-entries-meta', ({ hostUrl }) => getDjAPI(hostUrl, "/blog-entries"));
await blogEntries.done;
return () => <>
<main>
<h2>Entries</h2>
<ul>
{blogEntries.result.value?.map(_ => (
<li key={_.slug}>
<div class="entry">
<RouterLink to={{ name: 'DjBlogEntry', params: { slug: _.slug }}}>{ _.title }</RouterLink>
<span>-</span>
<time datetime={ _.createdAt }>{ new Date(_.createdAt).toLocaleDateString() }</time>
</div>
</li>
)) ?? <li>Blog posts loading...</li>}
</ul>
</main>
</>;
},
});

View File

@@ -1,7 +1,31 @@
import { defineComponent, ref } from "vue";
import useHead from "@/useHead.ts";
import { defineComponent, ref, type VNode, Suspense } from "vue";
import { type RouteRecordRaw, RouterLink, RouterView } from "vue-router";
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
import DjBlogEntry from "@/blog/DjBlogEntry.tsx";
import DjBlogMain from "@/blog/DjBlogMain.tsx";
import DjEmail from "@/DjEmail.tsx";
import { addCSS, css } from "@/util.ts";
import useHead from "@/useHead.ts";
export const routes: RouteRecordRaw[] = [
{
path: "/",
name: "DjBlogMain",
component: DjBlogMain,
},
{
path: "/post/:slug",
name: "DjBlogEntry",
component: DjBlogEntry,
props: ({ params }) => {
if ("slug" in params) {
return { slug: params.slug };
} else {
return false;
}
},
},
];
const styles = css`
.supercontainer {
@@ -9,31 +33,85 @@ const styles = css`
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 100px;
}
.container {
width: 800px;
}
footer {
color: gray;
font-style: italic;
margin-top: 40px;
}
a {
color: var(--dj-palette3);
text-decoration: solid line;
&:visited {
color: var(--dj-visited);
}
}
nav {
font-size: 40px;
margin-bottom: 40px;
text-decoration: none;
text-align: right;
width: 100%;
a, a:visited {
color: var(--dj-palette3);
}
}
`;
export default defineComponent({
name: "app-root",
name: "DjBlogRoot",
setup() {
addCSS('dj-blog-root', styles);
const carrier = ref<HTMLDivElement | null>(null);
setupTooltip({ carrier });
addCSS('dj-blog-root', styles);
useHead({ title: "djblog Home" });
const tooltipCarrier = ref<HTMLDivElement | null>(null);
setupTooltip({ carrier: tooltipCarrier });
return () => <>
<div ref={tooltipCarrier} class="tooltip-carrier" />
<div class="supercontainer">
<div class="container">
<DjTooltip tooltip="come in and find out...">
<h1>dj blog</h1>
</DjTooltip>
return () => (
<>
<div ref={carrier} class="tooltip-carrier" />
<div class="supercontainer">
<div class="container">
<nav>
<DjTooltip tooltip="flog, clog, bog, frog, cog, log, grog, fog, snog...">
<RouterLink to={{ name: 'DjBlogMain' }}>
dj blog
</RouterLink>
</DjTooltip>
</nav>
<RouterView>
{{
default: ({ Component }: { Component: VNode }) => (Component &&
(
<Suspense>
{{
default: () => Component,
fallback: () => <div>Page loading...</div>,
}}
</Suspense>
)),
}}
</RouterView>
<footer>
<div class="bottom">
<div>
<a href="/">djledda.net</a> {new Date().getFullYear()} - <DjEmail>{() => "Contact"}</DjEmail>
</div>
</div>
</footer>
</div>
</div>
</div>
</>;
</>
);
},
});

View File

@@ -1,7 +1,12 @@
import { createSSRApp } from "vue";
import DjBlogRoot from "@/blog//DjBlogRoot.tsx";
import { createRouter, createWebHistory } from "vue-router";
import DjBlogRoot, { routes } from "@/blog//DjBlogRoot.tsx";
import { cssRegistry } from "@/util.ts";
createSSRApp(DjBlogRoot)
.provide(cssRegistry, new Set())
.use(createRouter({
routes,
history: createWebHistory("/blog"),
}))
.mount("#app-root");

View File

@@ -1,7 +1,12 @@
import { createSSRApp } from "vue";
import DjBlogRoot from "@/blog/DjBlogRoot.tsx";
import DjBlogRoot, { routes } from "@/blog/DjBlogRoot.tsx";
import { createMemoryHistory, createRouter } from "vue-router";
export default function createApp() {
const app = createSSRApp(DjBlogRoot);
return { app, router: null };
const router = createRouter({
routes: routes,
history: createMemoryHistory("/blog"),
});
const app = createSSRApp(DjBlogRoot).use(router);
return { app, router };
}

8
app/domParse.ts Normal file
View File

@@ -0,0 +1,8 @@
import { inject } from "vue";
export default function getDomParser() {
return inject(
"dom-parse",
(innerHTML: string) => Object.assign(document.createElement("div"), { innerHTML }),
);
}

View File

@@ -96,7 +96,7 @@ export default defineComponent({
return <div>Artikel lädt...</div>;
}
await Promise.all([ articleContent.done, articlesMetadata.done ]);
await Promise.allSettled([ articleContent.done, articlesMetadata.done ]);
return () => (
<div class="ge-article">

View File

@@ -1,63 +1,88 @@
import { defineComponent, computed, ref, type Ref } from "vue";
import { defineComponent, ref, type Ref } from "vue";
import useHead from "@/useHead.ts";
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
import DjEmail from "@/DjEmail.tsx";
import { addCSS, css } from "@/util.ts";
const styles = css`
:root {
--subject-spacing: 40px;
}
.resource {
margin-bottom: 10px;
}
.title_name {
font-size: 48px;
color: var(--dj-palette3);
text-align: center;
}
.supercontainer {
padding-top: 3em;
margin: auto;
}
.main {
width: 50em;
margin: 20px auto;
text-align: center;
}
@media only screen and (max-width: 1024px) {
.main {
width: 35em;
padding: 20px;
}
:root {
--subject-spacing: 20px;
}
}
@media only screen and (max-width: 768px) {
.title_name {
font-size: 30px;
}
.main {
width: 20em;
padding: 20px;
}
}
a {
color: var(--dj-palette3);
&:visited {
color: var(--dj-visited);
}
}
`;
export default defineComponent({
name: "app-root",
name: "DjHomeRoot",
setup() {
useHead({ title: "DJ Ledda's Homepage" });
addCSS('DjHomeRoot', styles);
useHead({ title: "djledda" });
const tooltipCarrier = ref<HTMLDivElement | null>(null);
setupTooltip({ carrier: tooltipCarrier });
const dude1Spinning = ref(false);
const dude2Spinning = ref(false);
function toggleDude(event: MouseEvent, dudeRef: Ref<boolean>) {
const dude = event.target as HTMLImageElement;
if (dudeRef.value) {
dude.addEventListener("animationiteration", function listener() {
dudeRef.value = false;
dude.removeEventListener("animationiteration", listener as EventListenerOrEventListenerObject);
});
} else {
dudeRef.value = true;
}
}
const shaking = computed(() => dude1Spinning.value || dude2Spinning.value);
return () => <>
<div ref={tooltipCarrier} class="tooltip-carrier" />
<div class="supercontainer">
<div class={{ shakeable: true, shakeMe: shaking.value }}>
<div class="title_name">
<DjTooltip tooltip="I wonder what he's listening to?">
<img src="/home/img/dj.gif" alt="dj legt krasse Mucke auf"
class={{ dude: true, spinMe: dude1Spinning.value }}
onClick={ (e) => toggleDude(e, dude1Spinning)} />
</DjTooltip>
<div>
<div class="dj-title title_name">
<DjTooltip tooltip="Easily the coolest guy out there.">
<span>DJ Ledda</span>
</DjTooltip>
<DjTooltip tooltip="I once heard this guy played at revs.">
<img src="/home/img/dj.gif" alt="dj laying down some sick beats"
class={{ dude: true, spinMe: dude2Spinning.value }}
onClick={ (e) => toggleDude(e, dude2Spinning) } />
<span>dj ledda</span>
</DjTooltip>
</div>
<div class="main">
<div class="subject">
<div class="resourcelist">
<a href="https://drum-slayer.com">
<DjTooltip class="resource" tooltip="Small app for designing multitrack looped rhythms with local save and multiple files. Originally built using just vanilla TypeScript and CSS, now with Vue.">
Drum Slayer
</DjTooltip>
</a>
<a href="/somaesque/index.html">
<DjTooltip class="resource" tooltip="Puzzle solver app for puzzle cubes resembling the original Soma Cube puzzle. Save and edit your own puzzles! Built with Svelte, THREE.js and AssemblyScript.">
Somaesque
<a href="/blog">
<DjTooltip class="resource" tooltip="My musings, my losings, my winnings, my thoughts">
Blog
</DjTooltip>
</a>
<a href="/generative-energy">
@@ -65,6 +90,11 @@ export default defineComponent({
Generative Energy - Ray Peat Resources
</DjTooltip>
</a>
<a href="https://git.djledda.net/Ledda">
<DjTooltip class="resource" tooltip="Check out what I'm coding!">
My git projects
</DjTooltip>
</a>
<a href="/home/muenchen-auf-englisch.html">
<DjTooltip class="resource" tooltip="
Authentic historically accurate translations of all of Munich's S-Bahn and U-Bahn
@@ -74,6 +104,16 @@ export default defineComponent({
M&uuml;nchen auf Englisch - Munich in English
</DjTooltip>
</a>
<a href="https://drum-slayer.com">
<DjTooltip class="resource" tooltip="Small app for designing multitrack looped rhythms with local save and multiple files. Originally built using just vanilla TypeScript and CSS, now with Vue.">
Drum Slayer
</DjTooltip>
</a>
<a href="/somaesque/index.html">
<DjTooltip class="resource" tooltip="Puzzle solver app for puzzle cubes resembling the original Soma Cube puzzle. Save and edit your own puzzles! Built with Svelte, THREE.js and AssemblyScript.">
Somaesque
</DjTooltip>
</a>
<a href="/kadi/">
<DjTooltip class="resource" tooltip="Make an account and start saving paper and tracking your Yatzy stats with your
friends! Make your own rulesets, and more. Built with React, express.js, and
@@ -81,11 +121,6 @@ export default defineComponent({
K A D I: Online Yatzy Scoresheets
</DjTooltip>
</a>
<a href="https://git.djledda.net/Ledda">
<DjTooltip class="resource" tooltip="Check out what I'm coding!">
My git projects
</DjTooltip>
</a>
<DjEmail>
<DjTooltip class="resource" tooltip="You'll see my address when you click here.">
Click here to get in touch
@@ -94,7 +129,6 @@ export default defineComponent({
</div>
</div>
</div>
<div id="tooltipCarrier"></div>
</div>
</div>
</>;

39
main.ts
View File

@@ -100,6 +100,45 @@ async function getAPIResponse(apiReq: Request): Promise<Response> {
}
result.sort((a, b) => a.titleDe.localeCompare(b.titleDe));
jsonResponse = result;
} else if (apiPath === "/blog-entries") {
const paths: string[] = [];
const contentDir = './public/blog/content/';
for await (const dirEnt of Deno.readDir(contentDir)) {
if (dirEnt.isFile && dirEnt.name.endsWith('.html')) {
paths.push(`${contentDir}${dirEnt.name}`);
}
}
const result: DjAPIResultMap['/blog-entries'] = [];
for (const filePath of paths) {
const [ stat, content ] = await Promise.all([Deno.stat(filePath), Deno.readTextFile(filePath)]);
const dom = parser.parseFromString(content, 'text/html');
const metadata = {
slug: '',
tags: [] as string[],
title: '',
createdAt: '',
updatedAt: '',
};
const metaTags = dom.querySelectorAll('meta') as unknown as NodeListOf<HTMLMetaElement>;
for (const metaTag of metaTags) {
const name = metaTag.attributes.getNamedItem('name')?.value ?? '';
const content = metaTag.attributes.getNamedItem('content')?.value ?? '';
if (name === 'title') {
metadata.title = content;
} else if (name === 'tags') {
metadata.tags = content ? content.split(",") : [];
} else if (name === 'slug') {
metadata.slug = content;
} else if (name === 'updatedAt') {
metadata.createdAt = content;
} else if (name === 'createdAt') {
metadata.updatedAt = content;
}
}
result.push(metadata);
}
result.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
jsonResponse = result;
}
if (!jsonResponse) {

View File

@@ -1,51 +0,0 @@
<title>Poof, and it's gone</title>
<article>
<p>
Since reading Ray Peat's work and drastically improving my wellbeing, something that had been declining for years, I've
been thinking more and more often about the phenomenon of learned helpless and its relevance to my life. Sometimes,
looking back to past times is useful to help reorient yourself in the present and aim towards a more desirable future.
Sometimes, a new perspective or experience might instantly obliterate previous behaviour without any sort of concerted
mental or physical grunt to eradicate it.
</p>
<p>
On the flipside, I have sometimes hopelessly tried to forcefully change my behaviour, employing all the en vogue self-help tricks
to form long-term habits, only to practically immediately lose them not long afterwards. These kinds of experiences remind me of those
hypnosis advertisements that claim to have you give up smoking after just a few sessions; sometimes it's even after just one visit. There's no short
supply of stories of miracle cures or sudden, permanent breaks of addiction. Cold-turkey clean cuts that seem to arise with no obvious
effort on the part of the addict, no signs of worn willpower.
</p>
<p>
When I was sixteen I spent six weeks abroad in a small town called Marburg in Hesse, Germany. Those six weeks were spent
living with a new family along with my exchange student, who had lived six weeks with me and my family just prior to my
arrival in Germany. Six weeks of school, new acquaintances, a new language (albeit one I had been "studying" in the
Australian school system) and unfamiliar cultural quirks.
</p>
<p>
It was a barrage of stimulation, I came home every day from school and would collapse, totally exhausted, onto my
exchange student's bed, which was mine for the duration of the stay. It's not like I was actually expected to
<i>learn</i> anything or do any homework whilst I was at school here&mdash;I was basically on holidays and could really
have just treated it as such. Plenty of my own friends who had taken a similar trip certainly did. I'm not manyt of them
learnt or used much German beyond <i>Wo ist McDonalds?</i>. But I had been gradually becoming more fascinated with the
structure of German before arriving. Once there, especially at that age I presume, the Deutsch on the blackboard in
biology class looked more like a sophisticated puzzle game than a complete drag of a memorisation task. Each day was a
new game of deductive guesswork, and better still, I got to play with new ideas about how the language works every day
in the schoolyard with new friends I was making. New ways to describe how things are situated and move in relation to
one another, mysterious new prefixes and other linguistic building blocks, and the insane backwards word order of German
provided unlimited entertainment to see if I was up to the challenge.
</p>
<p>
On top of this, I was in the grade just above mine back home in Australia. Whilst that really shouldn't have made much
difference, the amount of responsibility and independece these kids were allowed to exercise at sixteen or seventeen was
nothing short of amazing to my adolescent self. I had never seen anything like it. Some of my classmates would stand out
the front of school during lunchtime and smoke a couple of cigarettes with their own teachers, something that still to
this day I find kind of insane. It certainly would never have been acceptable back at home. Starting in the senior
school, you were allowed to just leave and go home if you didn't have class on, as long as you were back in time. And we
did. School uniforms simply weren't part of the culture either. For everyone else perhaps stressful and another target
of the cruel status games of teenagerhood, but for me it was like every day was casual dress day back home. To top it
all off, the legal drinking age in Germany is sixteen, at least for wine, beer, and other weaker drinks.
</p>
<p>
These classmates of mine were running their own meetings headed by the <i>Klassensprecher</i>, the class representatives, and they actually seemed cool, like people I would like to hang out and befriend. They were
</article>

View File

@@ -0,0 +1,105 @@
<meta name="title" content="Poof, and it's gone">
<meta name="slug" content="poof-and-its-gone">
<meta name="createdAt" content="2025-12-20T17:54:05.000Z">
<meta name="updatedAt" content="2025-12-20T17:54:05.000Z">
<meta name="tags" content="">
<article>
<p>
Since reading Ray Peat's work and drastically improving my wellbeing&mdash;something that had been declining for years&mdash;I've
been thinking more and more often about the phenomenon of learned helplessness and its relevance in my own life. Sometimes,
looking back to past times can be useful to help reorient yourself in the present. In doing so you're better equipped to
aim towards a more desirable future. Sometimes, a new perspective or experience might instantly obliterate previous
behaviour without any sort of concerted mental or physical grunt to eradicate it.
</p>
<p>
On the flipside, I have sometimes hopelessly tried to forcefully change my behaviour, employing all the en vogue
self-help tricks to form long-term habits, only to lose them just as quickly as they formed in the months that would
follow. These kinds of experiences remind me of those hypnosis advertisements that claim to have you give up smoking
after just a few sessions; sometimes it's even after just one visit. There's no short supply <i>miracle cure</i> stories
or reports of sudden, permanent breaks in addiction. Cold-turkey clean cuts that seem to arise with no obvious effort on
the part of the addict, no signs of worn willpower.
</p>
<p>
When I was sixteen I spent six weeks abroad in a small town called Marburg in Hesse, Germany. Those six weeks were spent
living with a new family along with my exchange student, Arne, who had been staying with my family for the six weeks
prior. Those were six exciting weeks of school, new acquaintances, a new language (albeit one I had been "studying" in
the Australian school system) and unfamiliar cultural quirks.
</p>
<p>
It was a barrage of stimulation, I came home every day from school and would collapse, totally exhausted, onto my
exchange student's bed, which was graciously mine to use for the duration of the stay. It's not like I was actually expected to
<i>learn</i> anything or do any homework whilst I was at school here&mdash;I was basically on holidays and could really
have just treated it as such. Plenty of my own classmates who had been on a very similar trip certainly did. I'm not sure many of them
learnt or used much German beyond <i>"Wo ist McDonalds?"</i> I, on the other hand, thanks to a romantic summer fling,
had been gradually becoming more fascinated with the structure of German before arriving. Once there, especially at that
age I presume, the Deutsch on the blackboard looked more like a sophisticated puzzle game than a
complete drag of a memorisation task. Each day was a new game of deductive guesswork, and better still, I got to play
with new ideas about how the language works every day in the schoolyard with the new friends I was making. New ways to
describe how things are situated in space, adverbs for how they move in relation to one another, mysterious new prefixes and other quaint linguistic
quirks, like the insane backwards word order of German, provided unlimited entertainment to see if I was up to
the challenge. I practically spent all my time in class ogling the immaculate chalk handwriting of the various teachers,
trying to work out what on Earth was going on. For some strange reason, it was a kind of bliss.
</p>
<p>
On top of this, I was in the grade just above mine back home in Australia. Whilst that really shouldn't have made much
difference, the amount of responsibility and independence these kids were allowed to exercise at sixteen or seventeen was
nothing short of amazing to my adolescent self. I had never seen anything like it. Some of my classmates would stand out
the front of school during lunchtime and smoke a couple of cigarettes with their own teachers, something I find kind of insane
still to this day; it certainly would never have been acceptable back at home. Starting in the senior
school, you were allowed to just leave and go home if you didn't have anywhere to be, so long as you were back in time
for class. And we did. School uniforms simply weren't part of the culture either. For everyone else this perhaps just meant stressful decision making,
another way to play the oft cruel status games of teenagerhood, but for me it was like every day was casual dress day back
home. To top it all off, the legal drinking age in Germany is sixteen, at least for wine, beer, and other weaker drinks.
</p>
<p>
These classmates of mine were running their own meetings headed by the <i>Klassensprecher</i>, the class
representatives, and much unlike similar candidates back home, they actually seemed cool, they seemed like people I
might like to hang out with and befriend. Alongside making decision making about general school organisation, they would
organise class bus trips, we saw a local band comprised of kids from the local schools, and for the first time I drank
alcohol with everybody, just hanging out and left to our own devices. It was a sense of freedom and self-responsibility
that wasn't afforded to me by the school system back home. Increasingly Australia, and especially Victoria, from which I
hail, is branded as a "nanny state", and my experiences in Germany reinforce that.
</p>
<p>
I really felt like I was in the midst of some sort of Hollywood production, an atmosphere that didn't quite seem tangible in
Australia. The intersection in the Venn diagram of taking on of responsibility and having free reign was
vanishingly small amongst teenagers. Either you wagged class and/or did drugs, or obediently followed the rules. As the
years went by, the fine line between the two seemed to vanish further and further, at least from where I was standing.
</p>
<p>
Back in Australia, a routine had begun to solidify itself leading up to this trip. It was a routine of coming home,
maybe doing homework, and then browsing Reddit and playing hours of Team Fortress 2. I had racked up an impressive 2000
hours in-game. It seemed fairly inconsequential to me, and my high school friends, unlike primary school, were mostly
fragmented, and so on weeknights I didn't find myself hanging out with many people regularly. I did try to get Team Fortress
working on the old computer my host family had in Germany, just for fun, but to no avail. However, even whilst
attempting to get it set up, something about it began to seem like an entirely futile endeavour.
</p>
<p>
When I arrived back in Australia, it was as if a switch had been flipped. I all but stopped playing Team
Fortress, a regular staple of my free time. Practically overnight it seemed to have turned from being an incredibly
seductive way to pass the time to being a colossal <i>waste</i> of it. I just stopped playing cold turkey, and as far as I could tell, no
effort went in to the dissolution of that habit whatsoever.
</p>
<p>
I'm not exactly sure what facet of my overseas trip pushed me to change my behaviour so effortlessly, but I think it was
the culmination of the incredibly enriched environment. As I have looked back on those times over the past few years, especially since
discovering Ray, I can't help but think that I found myself in a "rat park" experiment during that time. Or I perhaps I was one of the rats
looking on, watching as others were freed from certain death by drowning. My habits in Australia suddenly seemed dull and useless, like I was stuck in
what the Germans call a <i>goldener Käfig</i> or <i>gilded cage</i>; basically trapped in a environment forged by
my own riches and good intentions. Participating in the foreign exchange program widened my horizons. I could see that, indeed, what
I was missing out on <i>was</i> possible, and I had the power to change my lifestyle.
</p>
<p>
It would be nice if I could now say that I've since enjoyed a deeply enriched life and everything has been hunky dory, but alas
I wouldn't be a fan of Ray's if I didn't encounter a struggle or two along the way. But I seems to have profoundly changed the course of my
life for the better. Ever since then, I've found it extremely difficult to waste my days away without having a
sense of direction in my life. Though this has, some times more than others, been a source of anxiety. I certainly don't think I
would have found it so simple to move abroad and continue to learn German whilst living, studying, and working in Munich for
several years like I have been if I had never gone on that trip.
</p>
<p>
So I guess, in that respect, watching your fellow rats have a good time, in real life, might just get you to settle for
no less. One look at those old menial habits and&mdash;<i>poof</i>&mdash;they're gone. And for that I'm grateful.
</p>
</article>

View File

@@ -4,14 +4,8 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/blog/styles.css">
<link
href="https://fonts.googleapis.com/css2?family=Roboto&amp;family=Roboto+Slab:wght@600&amp;display=swap"
rel="stylesheet">
<!-- <link rel="icon" href="/generative-energy/favicon.ico" sizes="any" /> -->
<meta name="description" content="Generative Energy - A page dedicated to Dr. Raymond Peat">
<meta property="og:image" content="icecream.png">
<link rel="stylesheet" href="/theme.css">
<meta name="description" content="dj blog - djledda's blog">
<!-- SSR HEAD OUTLET -->
</head>

View File

@@ -1,185 +0,0 @@
:root {
--subject-spacing: 40px;
}
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #292929;
font-family: "Roboto", serif;
}
.title_name {
font-size: 50px;
color: floralwhite;
font-family: "Roboto Slab", "Times New Roman", Times, serif;
text-align: center;
}
.title_name img {
margin: 20px;
height: 100px;
width: auto;
vertical-align: middle;
}
.spinMe {
animation: spin 1s infinite linear;
}
.shakeMe {
animation: shake 0.2s infinite linear;
}
@keyframes shake {
0% {
transform: scale(1) translate(1px, 1px) rotate(0deg);
}
25% {
transform: scale(0.95) translate(-1px, -2px) rotate(-1deg);
}
50% {
transform: scale(0.9) translate(-3px, 0px) rotate(1deg);
}
75% {
transform: scale(0.95) translate(3px, 2px) rotate(0deg);
}
100% {
transform: scale(1) translate(-1px, 2px) rotate(-1deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg) scale(1);
filter: hue-rotate(0deg) saturate(5);
}
25% {
transform: rotate(90deg) scale(2);
}
50% {
transform: rotate(180deg) scale(1);
}
75% {
transform: rotate(270deg) scale(2);
}
100% {
transform: rotate(360deg) scale(1);
filter: hue-rotate(360deg) saturate(5);
}
}
.supercontainer {
padding-top: 3em;
margin: auto;
}
.main {
width: 50em;
margin: 20px auto;
text-align: center;
}
@media only screen and (max-width: 1024px) {
.main {
width: 35em;
padding: 20px;
}
:root {
--subject-spacing: 20px;
}
}
@media only screen and (max-width: 768px) {
.title_name img {
margin: 10px;
height: 60px;
width: auto;
}
.title_name {
font-size: 30px;
}
.main {
width: 20em;
padding: 20px;
}
}
span.subjecttitle {
height: 100%;
font-family: "Roboto Slab", "Times New Roman", Times, serif;
font-size: 20px;
padding-right: 5px;
}
.subject:first-child {
margin-top: 0;
}
.subject:last-child {
margin-bottom: 0;
}
.subject {
margin-top: var(--subject-spacing);
margin-bottom: var(--subject-spacing);
}
.resourcelist {
margin-top: 2px;
background-color: white;
border-style: solid;
border-color: #292929;
border-width: 1px;
border-radius: 5px;
a:first-of-type {
.resource {
padding: 15px 20px 10px 20px;
border-radius: 5px 5px 0 0;
}
}
a:last-of-type {
.resource {
padding: 10px 20px 15px 20px;
border-radius: 0 0 5px 5px;
}
}
a:only-of-type {
.resource {
border-radius: 5px;
}
}
}
.resource {
position: relative;
background-color: white;
padding: 10px 20px 10px 20px;
display: block;
color: #333333;
text-decorAtion: none;
transition: background-color 200ms;
}
.resource:hover {
background-color: #bde4ff;
}
.resource:active {
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.50) inset;
}
a {
color: #000;
text-decoration: none;
cursor: pointer;
}

View File

@@ -2,13 +2,9 @@
<html>
<head>
<link rel="icon" href="/home/icon.webp" />
<link rel="stylesheet" href="/home/main.css" />
<link rel="stylesheet" href="/theme.css" />
<link rel="icon" href="/home/img/dj.gif" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab:wght@600&display=swap"
rel="stylesheet"
/>
<!-- SSR HEAD OUTLET -->
</head>
<body>

59
public/theme.css Normal file
View File

@@ -0,0 +1,59 @@
@import url('https://fonts.googleapis.com/css2?family=Quattrocento:wght@400;700&family=Vend+Sans:ital,wght@0,300..700;1,300..700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Laila:wght@300;400;500;600;700&family=Quattrocento:wght@400;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Laila:wght@300;400;500;600;700&family=Quattrocento:wght@400;700&family=Roboto+Slab:wght@100..900&display=swap');
:root {
--dj-palette1: #83a6bf;
--dj-palette2: #5e81ac;
--dj-palette3: #8fbcbb;
--dj-visited: #8d8bd5;
--dj-bgpalette1: #2e3440;
}
html, body {
background-color: var(--dj-bgpalette1);
color: var(--dj-palette1);
font-family: "Quattrocento", sans-serif;
font-optical-sizing: auto;
font-weight: 400; /* bold 700 */
font-style: normal;
font-size: 16px;
}
h1, h2, h3, h4, h5, nav, .dj-title, .roboto-slab {
font-family: "Roboto Slab", serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
}
.laila-light {
font-family: "Laila", serif;
font-weight: 300;
font-style: normal;
}
.laila-regular, body {
font-family: "Laila", serif;
font-weight: 400;
font-style: normal;
}
.laila-medium {
font-family: "Laila", serif;
font-weight: 500;
font-style: normal;
}
.laila-semibold {
font-family: "Laila", serif;
font-weight: 600;
font-style: normal;
}
.laila-bold {
font-family: "Laila", serif;
font-weight: 700;
font-style: normal;
}