First Article&Routing
This commit is contained in:
45
src/content/articles/the-crucible/index.mdoc
Normal file
45
src/content/articles/the-crucible/index.mdoc
Normal file
@@ -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
|
||||||
@@ -12,8 +12,8 @@ const articles = defineCollection({
|
|||||||
showInHeader: z.boolean().default(false),
|
showInHeader: z.boolean().default(false),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
publishDate: z.string(),
|
publishDate: z.date(),
|
||||||
updateDate: z.string().optional(),
|
updateDate: z.date().optional(),
|
||||||
status: z.enum(['draft', 'published', 'archived']).default('draft'),
|
status: z.enum(['draft', 'published', 'archived']).default('draft'),
|
||||||
isFeatured: z.boolean().default(false),
|
isFeatured: z.boolean().default(false),
|
||||||
parent: z.string().optional(),
|
parent: z.string().optional(),
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ export const createBaseArticleFields = () => ({
|
|||||||
validation: { isRequired: true },
|
validation: { isRequired: true },
|
||||||
}),
|
}),
|
||||||
cover: createCoverField(),
|
cover: createCoverField(),
|
||||||
publishDate: fields.date({
|
publishDate: fields.datetime({
|
||||||
label: 'Publish Date',
|
label: 'Publish Date',
|
||||||
validation: { isRequired: true },
|
validation: { isRequired: true },
|
||||||
|
defaultValue: { kind: 'now' },
|
||||||
}),
|
}),
|
||||||
updateDate: fields.date({
|
updateDate: fields.datetime({
|
||||||
label: 'Update Date',
|
label: 'Update Date',
|
||||||
}),
|
}),
|
||||||
status: fields.select({
|
status: fields.select({
|
||||||
@@ -32,11 +33,11 @@ export const createBaseArticleFields = () => ({
|
|||||||
}),
|
}),
|
||||||
parent: fields.relationship({
|
parent: fields.relationship({
|
||||||
label: 'Parent',
|
label: 'Parent',
|
||||||
collection: 'Articles',
|
collection: 'articles',
|
||||||
}),
|
}),
|
||||||
tags: fields.array(fields.text({ label: 'Tag' }), {
|
tags: fields.array(fields.text({ label: 'Tag' }), {
|
||||||
label: 'Tags',
|
label: 'Tags',
|
||||||
itemLabel = (props) => props.value,
|
itemLabel: (props) => props.value,
|
||||||
}),
|
}),
|
||||||
relatedArticles: fields.array(
|
relatedArticles: fields.array(
|
||||||
fields.relationship({ label: 'Article', collection: 'articles' }),
|
fields.relationship({ label: 'Article', collection: 'articles' }),
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { fields } from '@keystatic/core';
|
|||||||
export const createCoverField = () =>
|
export const createCoverField = () =>
|
||||||
fields.object(
|
fields.object(
|
||||||
{
|
{
|
||||||
src: fields.object({
|
src: fields.image({
|
||||||
label: 'Cover Image',
|
label: 'Cover Image',
|
||||||
directory: 'src/content/articles',
|
directory: 'src/content/articles',
|
||||||
publicPath: '/content/articles',
|
publicPath: '/content/articles',
|
||||||
}),
|
}),
|
||||||
alt: fields.text({ label: 'Alt Text' }),
|
alt: fields.text({ label: 'Alt Text' }),
|
||||||
caption: fields.text({ label: 'Caption', multline: true }),
|
caption: fields.text({ label: 'Caption', multiline: true }),
|
||||||
showInHeader: fields.checkbox({
|
showInHeader: fields.checkbox({
|
||||||
label: 'Show in header',
|
label: 'Show in header',
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
|
|||||||
28
src/pages/[...path].astro
Normal file
28
src/pages/[...path].astro
Normal file
@@ -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' && (
|
||||||
|
<ArticleLayout entry={props.entry as CollectionEntry<'articles'>} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type === 'page' && (
|
||||||
|
<PageLayout entry={props.entry as CollectionEntry<'pages'>} />
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 var(--spacing-comfortable);
|
padding: 0 var(--spacing-comfortable);
|
||||||
font-size: var(--typo-size-responsive);
|
font-size: var(--typo-size-responsive);
|
||||||
|
font-family: var(--font-body);
|
||||||
/* === Headings === */
|
/* === Headings === */
|
||||||
|
|
||||||
& h1 {
|
& h1 {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
:root {
|
:root {
|
||||||
/* === Heading Colors & Font Sizes === */
|
/* === Heading Colors & Font Sizes === */
|
||||||
/* These remain variables because they reference semantic tokens */
|
|
||||||
|
|
||||||
--el-h1-color: var(--color-text-primary);
|
--el-h1-color: var(--color-text-primary);
|
||||||
--el-h1-font-family: var(--font-display);
|
--el-h1-font-family: var(--font-display);
|
||||||
@@ -28,9 +27,9 @@
|
|||||||
|
|
||||||
/* === Heading Vertical Spacing === */
|
/* === Heading Vertical Spacing === */
|
||||||
--el-h1-vspace-base: calc(1em * 1.125);
|
--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(
|
--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);
|
--el-h2-vspace-base: calc(1em * 1.1765);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
:root {
|
:root {
|
||||||
/* === Font Families === */
|
/* === Font Families === */
|
||||||
--font-header: var(--font-geist-sans);
|
--font-header: 'Geist Variable';
|
||||||
--font-display: var(--font-blaka);
|
--font-display: 'Blaka';
|
||||||
--font-body: var(--font-geist-mono);
|
--font-body: 'Geist Mono Variable';
|
||||||
--font-mono: var(--font-geist-mono);
|
--font-mono: 'Geist Mono Variable';
|
||||||
--font-symbols: var();
|
--font-symbols: 'Unigrim Dee';
|
||||||
|
|
||||||
/* === Type Scale === */
|
/* === Type Scale === */
|
||||||
--typo-size-responsive: clamp(1rem, 2.5vw, 1.25rem);
|
--typo-size-responsive: clamp(1rem, 2.5vw, 1.25rem);
|
||||||
|
|||||||
Reference in New Issue
Block a user