big style update
This commit is contained in:
@@ -17,9 +17,10 @@ const tooltipStyles = css`
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
display: block;
|
display: block;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background-color: black;
|
background-color: var(--dj-bgpalette1);
|
||||||
border: white solid 1px;
|
box-shadow: 0 0 12px 1px rgb(10 12 15 / 70%);
|
||||||
color: white;
|
border: var(--dj-palette3) solid 1px;
|
||||||
|
color: var(--dj-palette3);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|||||||
14
app/api.ts
14
app/api.ts
@@ -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 = {
|
type RPArticle = {
|
||||||
title: string,
|
title: string,
|
||||||
@@ -11,6 +22,7 @@ type RPArticle = {
|
|||||||
|
|
||||||
export interface DjAPIResultMap extends Record<DjAPIEndpoint, unknown> {
|
export interface DjAPIResultMap extends Record<DjAPIEndpoint, unknown> {
|
||||||
"/rp-articles": RPArticle[];
|
"/rp-articles": RPArticle[];
|
||||||
|
"/blog-entries": BlogEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DjAPIResult = DjAPIResultMap[DjAPIEndpoint];
|
export type DjAPIResult = DjAPIResultMap[DjAPIEndpoint];
|
||||||
|
|||||||
98
app/blog/DjBlogEntry.tsx
Normal file
98
app/blog/DjBlogEntry.tsx
Normal 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
42
app/blog/DjBlogMain.tsx
Normal 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>
|
||||||
|
</>;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
@@ -1,7 +1,31 @@
|
|||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref, type VNode, Suspense } from "vue";
|
||||||
import useHead from "@/useHead.ts";
|
import { type RouteRecordRaw, RouterLink, RouterView } from "vue-router";
|
||||||
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
|
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 { 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`
|
const styles = css`
|
||||||
.supercontainer {
|
.supercontainer {
|
||||||
@@ -9,31 +33,85 @@ const styles = css`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-bottom: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 800px;
|
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({
|
export default defineComponent({
|
||||||
name: "app-root",
|
name: "DjBlogRoot",
|
||||||
setup() {
|
setup() {
|
||||||
addCSS('dj-blog-root', styles);
|
const carrier = ref<HTMLDivElement | null>(null);
|
||||||
|
setupTooltip({ carrier });
|
||||||
|
|
||||||
|
addCSS('dj-blog-root', styles);
|
||||||
useHead({ title: "djblog Home" });
|
useHead({ title: "djblog Home" });
|
||||||
|
|
||||||
const tooltipCarrier = ref<HTMLDivElement | null>(null);
|
return () => (
|
||||||
setupTooltip({ carrier: tooltipCarrier });
|
<>
|
||||||
|
<div ref={carrier} class="tooltip-carrier" />
|
||||||
return () => <>
|
<div class="supercontainer">
|
||||||
<div ref={tooltipCarrier} class="tooltip-carrier" />
|
<div class="container">
|
||||||
<div class="supercontainer">
|
<nav>
|
||||||
<div class="container">
|
<DjTooltip tooltip="flog, clog, bog, frog, cog, log, grog, fog, snog...">
|
||||||
<DjTooltip tooltip="come in and find out...">
|
<RouterLink to={{ name: 'DjBlogMain' }}>
|
||||||
<h1>dj blog</h1>
|
dj blog
|
||||||
</DjTooltip>
|
</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>
|
||||||
</div>
|
</>
|
||||||
</>;
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { createSSRApp } from "vue";
|
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";
|
import { cssRegistry } from "@/util.ts";
|
||||||
|
|
||||||
createSSRApp(DjBlogRoot)
|
createSSRApp(DjBlogRoot)
|
||||||
.provide(cssRegistry, new Set())
|
.provide(cssRegistry, new Set())
|
||||||
|
.use(createRouter({
|
||||||
|
routes,
|
||||||
|
history: createWebHistory("/blog"),
|
||||||
|
}))
|
||||||
.mount("#app-root");
|
.mount("#app-root");
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { createSSRApp } from "vue";
|
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() {
|
export default function createApp() {
|
||||||
const app = createSSRApp(DjBlogRoot);
|
const router = createRouter({
|
||||||
return { app, router: null };
|
routes: routes,
|
||||||
|
history: createMemoryHistory("/blog"),
|
||||||
|
});
|
||||||
|
const app = createSSRApp(DjBlogRoot).use(router);
|
||||||
|
return { app, router };
|
||||||
}
|
}
|
||||||
|
|||||||
8
app/domParse.ts
Normal file
8
app/domParse.ts
Normal 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 }),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@ export default defineComponent({
|
|||||||
return <div>Artikel lädt...</div>;
|
return <div>Artikel lädt...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all([ articleContent.done, articlesMetadata.done ]);
|
await Promise.allSettled([ articleContent.done, articlesMetadata.done ]);
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class="ge-article">
|
<div class="ge-article">
|
||||||
|
|||||||
@@ -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 useHead from "@/useHead.ts";
|
||||||
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
|
import DjTooltip, { setupTooltip } from "@/DjTooltip.tsx";
|
||||||
import DjEmail from "@/DjEmail.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({
|
export default defineComponent({
|
||||||
name: "app-root",
|
name: "DjHomeRoot",
|
||||||
setup() {
|
setup() {
|
||||||
useHead({ title: "DJ Ledda's Homepage" });
|
addCSS('DjHomeRoot', styles);
|
||||||
|
useHead({ title: "djledda" });
|
||||||
|
|
||||||
const tooltipCarrier = ref<HTMLDivElement | null>(null);
|
const tooltipCarrier = ref<HTMLDivElement | null>(null);
|
||||||
setupTooltip({ carrier: tooltipCarrier });
|
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 () => <>
|
return () => <>
|
||||||
<div ref={tooltipCarrier} class="tooltip-carrier" />
|
<div ref={tooltipCarrier} class="tooltip-carrier" />
|
||||||
<div class="supercontainer">
|
<div class="supercontainer">
|
||||||
<div class={{ shakeable: true, shakeMe: shaking.value }}>
|
<div>
|
||||||
<div class="title_name">
|
<div class="dj-title 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>
|
|
||||||
<DjTooltip tooltip="Easily the coolest guy out there.">
|
<DjTooltip tooltip="Easily the coolest guy out there.">
|
||||||
<span>DJ Ledda</span>
|
<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) } />
|
|
||||||
</DjTooltip>
|
</DjTooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="subject">
|
<div class="subject">
|
||||||
<div class="resourcelist">
|
<div class="resourcelist">
|
||||||
<a href="https://drum-slayer.com">
|
<a href="/blog">
|
||||||
<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.">
|
<DjTooltip class="resource" tooltip="My musings, my losings, my winnings, my thoughts">
|
||||||
Drum Slayer
|
Blog
|
||||||
</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>
|
</DjTooltip>
|
||||||
</a>
|
</a>
|
||||||
<a href="/generative-energy">
|
<a href="/generative-energy">
|
||||||
@@ -65,6 +90,11 @@ export default defineComponent({
|
|||||||
Generative Energy - Ray Peat Resources
|
Generative Energy - Ray Peat Resources
|
||||||
</DjTooltip>
|
</DjTooltip>
|
||||||
</a>
|
</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">
|
<a href="/home/muenchen-auf-englisch.html">
|
||||||
<DjTooltip class="resource" tooltip="
|
<DjTooltip class="resource" tooltip="
|
||||||
Authentic historically accurate translations of all of Munich's S-Bahn and U-Bahn
|
Authentic historically accurate translations of all of Munich's S-Bahn and U-Bahn
|
||||||
@@ -74,6 +104,16 @@ export default defineComponent({
|
|||||||
München auf Englisch - Munich in English
|
München auf Englisch - Munich in English
|
||||||
</DjTooltip>
|
</DjTooltip>
|
||||||
</a>
|
</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/">
|
<a href="/kadi/">
|
||||||
<DjTooltip class="resource" tooltip="Make an account and start saving paper and tracking your Yatzy stats with your
|
<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
|
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
|
K A D I: Online Yatzy Scoresheets
|
||||||
</DjTooltip>
|
</DjTooltip>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://git.djledda.net/Ledda">
|
|
||||||
<DjTooltip class="resource" tooltip="Check out what I'm coding!">
|
|
||||||
My git projects
|
|
||||||
</DjTooltip>
|
|
||||||
</a>
|
|
||||||
<DjEmail>
|
<DjEmail>
|
||||||
<DjTooltip class="resource" tooltip="You'll see my address when you click here.">
|
<DjTooltip class="resource" tooltip="You'll see my address when you click here.">
|
||||||
Click here to get in touch
|
Click here to get in touch
|
||||||
@@ -94,7 +129,6 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="tooltipCarrier"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>;
|
||||||
|
|||||||
39
main.ts
39
main.ts
@@ -100,6 +100,45 @@ async function getAPIResponse(apiReq: Request): Promise<Response> {
|
|||||||
}
|
}
|
||||||
result.sort((a, b) => a.titleDe.localeCompare(b.titleDe));
|
result.sort((a, b) => a.titleDe.localeCompare(b.titleDe));
|
||||||
jsonResponse = result;
|
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) {
|
if (!jsonResponse) {
|
||||||
|
|||||||
@@ -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—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>
|
|
||||||
105
public/blog/content/poof-and-its-gone.html
Normal file
105
public/blog/content/poof-and-its-gone.html
Normal 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—something that had been declining for years—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—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—<i>poof</i>—they're gone. And for that I'm grateful.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
@@ -4,14 +4,8 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/blog/styles.css">
|
<link rel="stylesheet" href="/theme.css">
|
||||||
<link
|
<meta name="description" content="dj blog - djledda's blog">
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab:wght@600&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">
|
|
||||||
|
|
||||||
<!-- SSR HEAD OUTLET -->
|
<!-- SSR HEAD OUTLET -->
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -2,13 +2,9 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" href="/home/icon.webp" />
|
<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 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 -->
|
<!-- SSR HEAD OUTLET -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
59
public/theme.css
Normal file
59
public/theme.css
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user