Compare commits

...

3 Commits

Author SHA1 Message Date
692430f959 Fixes blockquote styling 2026-04-21 15:47:51 -07:00
4a3f6774cc Small cleanups to values 2026-04-21 15:44:40 -07:00
81c912e3ff Adds notes. 2026-04-21 15:39:16 -07:00
15 changed files with 1531 additions and 838 deletions

2153
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,7 @@
"@types/react": "^19.1.7",
"@types/react-dom": "^19.1.6",
"astro": "^5.9.2",
"astro-loader-obsidian": "^0.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"sharp": "^0.34.2"

View File

@@ -18,6 +18,5 @@ const { date } = Astro.props;
<style>
time {
font-family: "Fira Code", monospace;
font-size: var(--font-size-sm);
}
</style>

View File

@@ -33,7 +33,7 @@ import Blazestar from './Blazestar.astro';
</div>
</nav>
<div class="h-card">
<img class="u-photo" src="/public/photos/Bingley Business.jpg" />
<img class="u-photo" src="/photos/Bingley Business.jpg" />
<a class="p-name u-url" href="https://www.blazestar.net">Drew Haven</a>
a.k.a. <span class="p-nickname">Periodic</span>
</div>

View File

@@ -0,0 +1,65 @@
---
import { type Hierarchy } from "../lib/hierarchy.ts";
interface Props {
prefix: string;
hierarchy: Hierarchy;
}
const { prefix, hierarchy } = Astro.props;
const pathname = Astro.url.pathname.replace(import.meta.env.BASE_URL, '/');
---
{
Object.entries(hierarchy).map(([leader, node]) => {
const notePath = `${prefix}/${leader}`;
const isActive = pathname === notePath;
const linkClasses = isActive ? "active" : "";
if (node.children) {
return (
<details open={pathname.startsWith(notePath) && "true"}>
<summary>
{ node.id
? <a href={notePath} class={linkClasses}>{node.title || leader}</a>
: <span class="header-only">{node.title || leader}</span>
}
</summary>
<div class="child-notes">
{ <Astro.self prefix={notePath} hierarchy={node.children} /> }
</div>
</details>
);
}
return (
<div>
<a href={notePath} class={linkClasses}>
{node.title || leader}
</a>
</div>
);
})
}
<style>
.active {
font-weight: bold;
}
.child-notes {
margin-left: 1em;
}
summary {
.header-only {
color: var(--color-gray)
}
&:hover {
color: var(--color-gold);
}
}
</style>

View File

@@ -0,0 +1,29 @@
---
import { makeHierarchy } from '../lib/hierarchy';
import { getCollection } from 'astro:content';
import NotchedBox from './NotchedBox.astro';
import NoteHierarchy from './NoteHierarchy.astro';
const notes = await getCollection('notes');
const hierarchy = makeHierarchy(notes.map(note => [note.id, note.data.title]));
const pathname = Astro.url.pathname.replace(import.meta.env.BASE_URL, '');
const isActive = pathname.startsWith("notes");
---
<NotchedBox fillNotches={isActive ? 'left' : 'none'}>
<div class="notes-header">Notes</div>
<div class="note-links">
<NoteHierarchy prefix="/notes" hierarchy={hierarchy} />
</div>
</NotchedBox>
<style>
.notes-header {
color: var(--color-light-text);
font-size: var(--font-size-lg);
}
.note-links {
margin-left: 8px;
}
</style>

View File

@@ -1,6 +1,7 @@
---
import SidebarLink from './SidebarLink.astro';
import Blazestar from './Blazestar.astro';
import NotesLinks from './NotesLinks.astro';
---
<header>
@@ -10,6 +11,7 @@ import Blazestar from './Blazestar.astro';
<SidebarLink href="/">Home</SidebarLink>
<SidebarLink href="/blog">Blog</SidebarLink>
<SidebarLink href="/about">About</SidebarLink>
<NotesLinks />
</div>
<div class="social-links">
<a href="https://mastodon.social/@periodic" target="_blank" rel="me">
@@ -57,13 +59,12 @@ import Blazestar from './Blazestar.astro';
gap: 16px;
a {
color: var(--color-light-text);
border-bottom: 4px solid transparent;
text-decoration: none;
&:hover {
color: var(--color-accent);
border-bottom: 4px solid transparent;
text-decoration: none;
}
&.active {
text-decoration: none;
}

View File

@@ -1,3 +1,7 @@
import {
ObsidianDocumentSchema,
ObsidianMdLoader,
} from "astro-loader-obsidian";
import { glob } from "astro/loaders";
import { defineCollection, z } from "astro:content";
@@ -26,4 +30,15 @@ const page = defineCollection({
}),
});
export const collections = { blog, page };
const notes = defineCollection({
loader: ObsidianMdLoader({
base: "src/content/notes",
url: "notes",
}),
schema: ({ image }) =>
ObsidianDocumentSchema.extend({
image: image().optional(),
}),
});
export const collections = { blog, page, notes };

View File

@@ -26,8 +26,7 @@ they are living and growing in line with their ideals.
- Take responsibility for your own actions.
- Hold others accountable and responsible for their actions.
- Give honest feedback.
- Take the time to do good work.
- Be proud of your work.
- Take the time to do good work and be proud of it.
- Be your authentic self.
### Sustainability and long-term thinking
@@ -47,8 +46,7 @@ they are living and growing in line with their ideals.
### Self-improvement
- Be curious and motivated to learn and understand.
- Be open to feedback and learning.
- Learn new things.
- Be open to feedback.
- Seek to understand.
- Embrace failure as an opportunity to learn.
- Take the time to review and retrospect.

View File

@@ -62,6 +62,7 @@ const posts = await getPublishedPosts( selectedTag );
}
.date {
color: var(--color-gray);
font-size: var(--font-size-sm);
}
.entry {
padding: 0.5em;

View File

@@ -26,6 +26,10 @@ const { slug, title, description, pubDate, updatedDate, heroImage, tags } = Astr
font-size: 80%;
}
.dt-published {
font-size: var(--font-size-sm);
}
.tags {
display: flex;
flex-direction: row;

37
src/lib/hierarchy.ts Normal file
View File

@@ -0,0 +1,37 @@
export interface HierarchyNode {
id: string | null;
title: string | null;
children: Hierarchy | null;
}
export interface Hierarchy extends Record<string, HierarchyNode> {}
function addToHierarchy(
tree: Hierarchy,
[noteId, title]: [string, string],
): Hierarchy {
const path = noteId.split("/");
if (path.length === 0) {
return tree;
}
if (!tree[path[0]]) {
tree[path[0]] = { id: null, title: null, children: null };
}
let curr = tree[path[0]];
for (const node of path.slice(1)) {
curr.children ||= {};
if (!curr.children[node]) {
curr.children[node] = { id: null, title: null, children: null };
}
curr = curr.children[node];
}
curr.id = noteId;
curr.title = title;
return tree;
}
export function makeHierarchy(notes: Array<[string, string]>): Hierarchy {
return notes.reduce(addToHierarchy, {});
}

View File

@@ -0,0 +1,36 @@
---
import RootLayout from '../../layouts/RootLayout.astro';
import NotchedBox from '../../components/NotchedBox.astro';
import FormattedDate from '../../components/FormattedDate.astro';
import { type CollectionEntry, getCollection } from 'astro:content';
import { render } from 'astro:content';
export async function getStaticPaths() {
const notes = await getCollection('notes');
return notes.map((note) => ({
params: { slug: note.id },
props: note,
}));
}
type Props = CollectionEntry<'notes'>;
const note = Astro.props;
const { Content } = await render(note);
---
<RootLayout>
<NotchedBox fillNotches="left">
<h1>{note.data.title}</h1>
<div class="last-updated">
Last updated <FormattedDate date={note.data.updated} />
</div>
<Content />
</NotchedBox>
</RootLayout>
<style>
.last-updated {
font-size: var(--font-size-sm);
color: var(--color-gray);
}
</style>

View File

@@ -181,10 +181,10 @@ pre > code {
all: unset;
}
blockquote {
border-left: 4px solid var(--accent);
padding: 0 0 0 20px;
margin: 0px;
font-size: 1.333em;
border-left: 4px solid var(--color-gray);
padding: 0 8px 0 16px;
margin: 0;
background-color: var(--color-space-blue-light);
}
hr {
border: none;