The page layout is stripped for Game-Design/Concept-Mill the way the GameCult site strips it for Thing: only the Aetheria masthead survives, floating and compact. The selected ship's render fills the viewport, feathered into a dark field; the ship index unfolds from the top left and the technical readout from the bottom right, both collapsible. AetheriaConceptMill embeds the generated manifest and its inline script owns the selection: arrows step ships, up/down or [ ] step render rounds, Escape collapses the panels, M and R toggle them, swipe steps on touch, and the URL hash deep-links #ship/variant. Variants show their hypothesis, the lab's verdict and any operator verdict; the lab's pick is marked LAB PICK. On a phone the panels are bottom sheets over a dock. Motion is event-driven and dissolves only under prefers-reduced-motion. A vote slot stays hidden until votes are configured in ships.yaml. The page note keeps its frontmatter and one paragraph; the card styles it used are removed from custom.scss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
import { PageLayout, SharedLayout } from "./quartz/cfg"
|
|
import * as Component from "./quartz/components"
|
|
import AetheriaAuthorMeta from "./quartz/components/AetheriaAuthorMeta"
|
|
import AetheriaConceptMill, { isConceptMillPage } from "./quartz/components/AetheriaConceptMill"
|
|
import AetheriaEpubReader, { isAetheriaEpubReaderPage } from "./quartz/components/AetheriaEpubReader"
|
|
import AetheriaMasthead from "./quartz/components/AetheriaMasthead"
|
|
import AetheriaOverviewSidebar from "./quartz/components/AetheriaOverviewSidebar"
|
|
import AetheriaThemeLock from "./quartz/components/AetheriaThemeLock"
|
|
|
|
// Pages that take the whole viewport keep only the floating masthead.
|
|
const isFullBleedPage = (slug: string | undefined) => isAetheriaEpubReaderPage(slug) || isConceptMillPage(slug)
|
|
|
|
// components shared across all pages
|
|
export const sharedPageComponents: SharedLayout = {
|
|
head: Component.Head(),
|
|
header: [AetheriaThemeLock(), AetheriaMasthead(), Component.Search()],
|
|
afterBody: [],
|
|
footer: Component.Footer({
|
|
links: {},
|
|
}),
|
|
}
|
|
|
|
// components for pages that display a single page (e.g. a single note)
|
|
export const defaultContentPageLayout: PageLayout = {
|
|
beforeBody: [
|
|
Component.ConditionalRender({
|
|
component: Component.Breadcrumbs({
|
|
rootName: "Aetheria",
|
|
showCurrentPage: false,
|
|
showRoot: false,
|
|
}),
|
|
condition: (page) => page.fileData.slug !== "index" && !isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: Component.ArticleTitle(),
|
|
condition: (page) =>
|
|
!page.fileData.slug?.endsWith("/index") &&
|
|
page.fileData.slug !== "index" &&
|
|
!isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: AetheriaAuthorMeta(),
|
|
condition: (page) =>
|
|
!page.fileData.slug?.endsWith("/index") &&
|
|
page.fileData.slug !== "index" &&
|
|
!isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: Component.ContentMeta(),
|
|
condition: (page) =>
|
|
!page.fileData.slug?.endsWith("/index") &&
|
|
page.fileData.slug !== "index" &&
|
|
!isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: AetheriaConceptMill(),
|
|
condition: (page) => isConceptMillPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: AetheriaEpubReader(),
|
|
condition: (page) => isAetheriaEpubReaderPage(page.fileData.slug),
|
|
}),
|
|
],
|
|
afterBody: [
|
|
Component.ConditionalRender({
|
|
component: Component.AutoIndexFolder({
|
|
rootSlug: "Articles",
|
|
classPrefix: "aetheria-article",
|
|
hideFrontmatterKey: "hideFromArticleIndex",
|
|
defaultAuthor: "Aetheria",
|
|
emptyDescription: "A field note with teeth, filed before it could become polite.",
|
|
sidebarTagline: "Bylined field notes, arguments, and interpretive knives.",
|
|
sidebarSummary: (count) => `${count} Aetheria articles, newest pressure first.`,
|
|
}),
|
|
condition: (page) => page.fileData.slug === "Articles/index",
|
|
}),
|
|
],
|
|
left: [
|
|
Component.ConditionalRender({
|
|
component: AetheriaOverviewSidebar(),
|
|
condition: (page) => !isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
],
|
|
right: [
|
|
Component.ConditionalRender({
|
|
component: Component.DesktopOnly(Component.TableOfContents()),
|
|
condition: (page) => !isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
Component.ConditionalRender({
|
|
component: Component.Backlinks(),
|
|
condition: (page) => !isFullBleedPage(page.fileData.slug),
|
|
}),
|
|
],
|
|
}
|
|
|
|
// components for pages that display lists of pages (e.g. tags or folders)
|
|
export const defaultListPageLayout: PageLayout = {
|
|
beforeBody: [
|
|
Component.Breadcrumbs({
|
|
rootName: "Aetheria",
|
|
showCurrentPage: false,
|
|
showRoot: false,
|
|
}),
|
|
],
|
|
left: [],
|
|
right: [],
|
|
}
|