diff --git a/src/content/articles/the-crucible/index.mdoc b/src/content/articles/the-crucible/index.mdoc new file mode 100644 index 0000000..e6f6f7e --- /dev/null +++ b/src/content/articles/the-crucible/index.mdoc @@ -0,0 +1,45 @@ +--- +title: The Crucible +summary: Generates fantasy settings through seven interconnected alchemical stages. +cover: + showInHeader: false +publishDate: 2026-02-19T14:05:00.000Z +status: published +isFeatured: false +tags: [] +relatedArticles: [] +seo: + description: Short Pitch comes here + noIndex: false +--- +## What this is + +- Generates fantasy settings through seven interconnected alchemical stages +- Start with Geography, end with states locked in political tension +- Not balanced, not optimised – designed to produce contradictions and tension + +## Two Paths + +- **Path I: »I want to generate«** + - Start Building + - Recommended for first-time users +- Path 2: **»I want to understand«** + - Learn the System + - Recommended for designers and theorists + +## The Seven Stages + +1. **Prima Materia. – Land** + - Generate biomes and resources +1. **Calcination – Kin** + - Generates kindred, heritage, and ancestry +1. **Fermentation – Belief** + - Generates religion and belief +1. **Sublimation – Witchcraft** + - Generates magical traditions and crafts +1. **Coagulation – Vessels** + - Generates institutions and factions +1. **Conjunction – Realms** + - Generates states, tribes, and settlements +1. **Dissolution** + - Ways for the state to interact with each over diff --git a/src/content/config.ts b/src/content/config.ts index 8d40143..c4b5008 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -12,8 +12,8 @@ const articles = defineCollection({ showInHeader: z.boolean().default(false), }) .optional(), - publishDate: z.string(), - updateDate: z.string().optional(), + publishDate: z.date(), + updateDate: z.date().optional(), status: z.enum(['draft', 'published', 'archived']).default('draft'), isFeatured: z.boolean().default(false), parent: z.string().optional(), diff --git a/src/keystatic/fields/base-article.ts b/src/keystatic/fields/base-article.ts index f21f666..5c87e95 100644 --- a/src/keystatic/fields/base-article.ts +++ b/src/keystatic/fields/base-article.ts @@ -10,11 +10,12 @@ export const createBaseArticleFields = () => ({ validation: { isRequired: true }, }), cover: createCoverField(), - publishDate: fields.date({ + publishDate: fields.datetime({ label: 'Publish Date', validation: { isRequired: true }, + defaultValue: { kind: 'now' }, }), - updateDate: fields.date({ + updateDate: fields.datetime({ label: 'Update Date', }), status: fields.select({ @@ -32,11 +33,11 @@ export const createBaseArticleFields = () => ({ }), parent: fields.relationship({ label: 'Parent', - collection: 'Articles', + collection: 'articles', }), tags: fields.array(fields.text({ label: 'Tag' }), { label: 'Tags', - itemLabel = (props) => props.value, + itemLabel: (props) => props.value, }), relatedArticles: fields.array( fields.relationship({ label: 'Article', collection: 'articles' }), diff --git a/src/keystatic/fields/cover.ts b/src/keystatic/fields/cover.ts index 2bb72e6..2382ff1 100644 --- a/src/keystatic/fields/cover.ts +++ b/src/keystatic/fields/cover.ts @@ -3,13 +3,13 @@ import { fields } from '@keystatic/core'; export const createCoverField = () => fields.object( { - src: fields.object({ + src: fields.image({ label: 'Cover Image', directory: 'src/content/articles', publicPath: '/content/articles', }), alt: fields.text({ label: 'Alt Text' }), - caption: fields.text({ label: 'Caption', multline: true }), + caption: fields.text({ label: 'Caption', multiline: true }), showInHeader: fields.checkbox({ label: 'Show in header', defaultValue: false, diff --git a/src/pages/[...path].astro b/src/pages/[...path].astro new file mode 100644 index 0000000..51d007a --- /dev/null +++ b/src/pages/[...path].astro @@ -0,0 +1,28 @@ +--- +import { resolveAllPaths, type ResolvedEntry } from '../lib/paths'; +import type { CollectionEntry } from 'astro:content'; +import ArticleLayout from '../layouts/ArticleLayout.astro'; +import PageLayout from '../layouts/PageLayout.astro'; + +export async function getStaticPaths() { + const entries = await resolveAllPaths(); + return entries.map((entry) => ({ + params: { path: entry.path }, + props: entry, + })); +} +const { type, entry } = Astro.props as ResolvedEntry; + +const props = Astro.props as ResolvedEntry; +--- + +{ + type === 'article' && ( + } /> + ) +} +{ + type === 'page' && ( + } /> + ) +} diff --git a/src/styles/content.css b/src/styles/content.css index c5140f3..cf063e7 100644 --- a/src/styles/content.css +++ b/src/styles/content.css @@ -3,7 +3,7 @@ margin: 0 auto; padding: 0 var(--spacing-comfortable); font-size: var(--typo-size-responsive); - + font-family: var(--font-body); /* === Headings === */ & h1 { diff --git a/src/styles/elements.css b/src/styles/elements.css index 474d75e..1906ab6 100644 --- a/src/styles/elements.css +++ b/src/styles/elements.css @@ -1,6 +1,5 @@ :root { /* === Heading Colors & Font Sizes === */ - /* These remain variables because they reference semantic tokens */ --el-h1-color: var(--color-text-primary); --el-h1-font-family: var(--font-display); @@ -28,9 +27,9 @@ /* === Heading Vertical Spacing === */ --el-h1-vspace-base: calc(1em * 1.125); - --el-h1-vspace-top: calc(var(--el-h1-vspace-base) * var(--vspace-spacious)); + --el-h1-vspace-top: calc(var(--el-h1-vspace-base) * var(--vspace-snug)); --el-h1-vspace-bottom: calc( - var(--el-h1-vspace-base) * var(--vspace-comfortable) + var(--el-h1-vspace-base) * var(--vspace-compressed) ); --el-h2-vspace-base: calc(1em * 1.1765); diff --git a/src/styles/typography.css b/src/styles/typography.css index a20f59b..703ecce 100644 --- a/src/styles/typography.css +++ b/src/styles/typography.css @@ -1,10 +1,10 @@ :root { /* === Font Families === */ - --font-header: var(--font-geist-sans); - --font-display: var(--font-blaka); - --font-body: var(--font-geist-mono); - --font-mono: var(--font-geist-mono); - --font-symbols: var(); + --font-header: 'Geist Variable'; + --font-display: 'Blaka'; + --font-body: 'Geist Mono Variable'; + --font-mono: 'Geist Mono Variable'; + --font-symbols: 'Unigrim Dee'; /* === Type Scale === */ --typo-size-responsive: clamp(1rem, 2.5vw, 1.25rem);