Add Zyphos Quartz site

This commit is contained in:
Meta Vens 2026-05-18 01:26:44 +01:00
commit caacae52bb
15 changed files with 788 additions and 9 deletions

24
.github/workflows/deploy-quartz.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: Deploy Quartz
on:
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
deploy:
uses: GameCult/GameCult-Quartz/.github/workflows/quartz-pages.yml@main
with:
content-dir: Eusocial Interbeing
overlay-dir: site
output-dir: quartz-site/public

2
.gitignore vendored
View file

@ -22,3 +22,5 @@ state/scratch-compaction-*.md
/.rag/
/.tools/
/.npm-cache/
/.quartz-build/
/quartz-site/

View file

@ -1,24 +1,33 @@
# Eusocial Interbeing
# Zyphos
This setting centers on eusocial inter-species dynamics: civilizations that do not merely live in ecosystems, but negotiate with reproductive sites, memory-bearing forests, immune networks, migratory herds, pollinating castes, fungal archives, and engineered idea-organisms.
*A close-binary living world for the Aquarium demo, with names waiting for Weksa to earn them.*
Zyphos is one member of a tightly bound terrestrial binary. Its slightly smaller twin, [[World/Zyphos Umbros Binary System|Umbros]], hangs in the sky as a fixed planetary presence. The primary star is dim, the habitable zone is close, and the biosphere has learned to treat light as a scarce civic resource rather than wallpaper.
This site collects the setting work behind the Zyphos demo: the physics-constrained world model, the mutable-memory biosphere, the civilizations shaped by ecological contracts, the Aquarium rendering surface, and the future Weksa language work that will name the world from inside its inhabitants' ontologies.
## Core Premise
On one continent, the [[Airawa]] once lived in tight ecological reciprocity with [[Mother Trees]]. Their societies stored communal memory in tree networks that demanded nutrients, ritual labor, and political deference in return. One Airawa tribe created the [[Biological Memetic Engine]] to break that dependency. The tool worked too well. It became the foundation of the [[Airawa Empire]], a eugenics-obsessed biopunk state whose rulers can impose doctrine through the continent's connected living networks.
Zyphos life is founded on [[Ecology/Mutable Memory Endosymbiosis|mutable memory endosymbiosis]]. Every cell carries a memory-bearing symbiont. Sentience is not reserved for human-shaped minds; it gradients through cells, tissues, organisms, colonies, routes, forests, reefs, and landscapes.
On another continent, where Airawa never evolved or migrated, the [[Sa'auei'a]] developed a highly advanced nomadic civilization. They organize in squad-sized family units, keep [[Breeding Grounds]] sacred and communal, and bargain with ecologies that remember generosity.
On one continent, the [[Species/Airawa|Airawa]] once lived in tight ecological reciprocity with [[Species/Mother Trees|Mother Trees]]. Their societies stored communal memory in tree networks that demanded nutrients, ritual labor, and political deference in return. One Airawa tribe created the [[Technologies/Biological Memetic Engine|Biological Memetic Engine]] to break that dependency. The tool worked too well. It became the foundation of the [[Civilizations/Airawa Empire|Airawa Empire]], a eugenics-obsessed biopunk state whose rulers can impose doctrine through the continent's connected living networks.
## Main Paths
On another continent, where Airawa never evolved or migrated, the [[Species/Sa'auei'a|Sa'auei'a]] developed a highly advanced nomadic civilization. They organize in squad-sized family units, keep [[Ecology/Breeding Grounds|Breeding Grounds]] sacred and communal, and bargain with ecologies that remember generosity.
## Project Surfaces
- [[World/Zyphos Simulation Brief]]
- [[World/Zyphos Umbros Binary System]]
- [[Ecology/Mutable Memory Endosymbiosis]]
- [[Ecology/Zyphos Biosphere Examples]]
- [[World/index]]
- [[Ecology/index]]
- [[Species/index]]
- [[Civilizations/index]]
- [[Ecology/index]]
- [[Technologies/index]]
- [[Conflicts/index]]
- [[Themes/index]]
- [[Inspirations/index]]
## Current Design Rule
Every major institution should be legible as an ecological deal, a reproductive pressure, a memory technology, or a path-dependent consequence. If it is just a normal state wearing wet architecture, cut it until the wound has a purpose.
Physics is design authority. If the orbital math or energy budget tightens the image, the world bends. The bruise is usually where the better idea lives.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -5,3 +5,10 @@ An Obsidian vault for an original biopolitical ecology setting: two continents,
The project is loosely inspired by Avatar's underused ecological network premise, Sue Burke's plant-negotiation fiction, and Harry Turtledove's path-dependent technology arguments. It is not an Avatar fan setting. The useful corpse has been composted. We move on.
Start at [[Eusocial Interbeing/index]].
## Site
The Zyphos public site is a GitHub Pages Quartz site using the same deployment
shape as Aetheria. Vault content lives under `Eusocial Interbeing/`; the Quartz
overlay lives under `site/`; the workflow publishes to GitHub Pages for
`zyphos.gamecult.org`.

15
site/README.md Normal file
View file

@ -0,0 +1,15 @@
# Zyphos Quartz Site
Quartz overlay for the future `https://zyphos.gamecult.org` GitHub Pages site.
The content source is the vault directory `Eusocial Interbeing/`; this `site/`
directory only owns presentation, navigation, and static site assets.
The site follows the same deployment pattern as `AetheriaLore`:
- content directory: `Eusocial Interbeing`
- overlay directory: `site`
- output directory: `quartz-site/public`
- GitHub Pages host: `gamecult.github.io`
- custom domain: `zyphos.gamecult.org`
DNS should point `zyphos.gamecult.org` at GitHub Pages, not Yggdrasil.

141
site/quartz.config.ts Normal file
View file

@ -0,0 +1,141 @@
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
import { QuartzEmitterPlugin } from "./quartz/plugins/types"
import { Fragment, h } from "preact"
import { zyphosHeroScript } from "./quartz/components/ZyphosHeroScript"
const ZyphosFavicons: QuartzEmitterPlugin = () => ({
name: "ZyphosFavicons",
async *emit() {},
async *partialEmit() {},
externalResources: () => ({
additionalHead: [
() =>
h(Fragment, {}, [
h("meta", { property: "twitter:domain", content: "zyphos.gamecult.org" }),
h("meta", { property: "og:url", content: "https://zyphos.gamecult.org/" }),
h("meta", { property: "twitter:url", content: "https://zyphos.gamecult.org/" }),
]),
],
}),
})
const ZyphosHeroResources: QuartzEmitterPlugin = () => ({
name: "ZyphosHeroResources",
async *emit() {},
async *partialEmit() {},
externalResources: () => ({
js: [
{
script: zyphosHeroScript,
loadTime: "afterDOMReady",
contentType: "inline",
spaPreserve: true,
},
],
}),
})
const config: QuartzConfig = {
configuration: {
pageTitle: "Zyphos",
pageTitleSuffix: "",
enableSPA: true,
enablePopovers: true,
analytics: null,
locale: "en-GB",
baseUrl: "zyphos.gamecult.org",
ignorePatterns: [
"private",
"templates",
".obsidian",
"Inspirations",
"Inspirations/**",
],
defaultDateType: "modified",
theme: {
fontOrigin: "googleFonts",
cdnCaching: true,
typography: {
header: {
name: "Montserrat",
weights: [100, 200, 300, 400, 600],
},
title: {
name: "Montserrat",
weights: [100, 200, 300],
},
body: {
name: "Ubuntu",
weights: [300, 400, 500, 700],
includeItalic: true,
},
code: "IBM Plex Mono",
},
colors: {
lightMode: {
light: "#07110f",
lightgray: "#16251f",
gray: "#668077",
darkgray: "#bdd4ca",
dark: "#effcf8",
secondary: "#ffae58",
tertiary: "#8edfb0",
highlight: "rgba(142, 223, 176, 0.14)",
textHighlight: "#ffae5855",
},
darkMode: {
light: "#07110f",
lightgray: "#16251f",
gray: "#668077",
darkgray: "#bdd4ca",
dark: "#effcf8",
secondary: "#ffae58",
tertiary: "#8edfb0",
highlight: "rgba(142, 223, 176, 0.14)",
textHighlight: "#ffae5855",
},
},
},
},
plugins: {
transformers: [
Plugin.FrontMatter(),
Plugin.CreatedModifiedDate({
priority: ["frontmatter", "git", "filesystem"],
}),
Plugin.SyntaxHighlighting({
theme: {
light: "github-dark",
dark: "github-dark",
},
keepBackground: false,
}),
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
Plugin.GitHubFlavoredMarkdown(),
Plugin.TableOfContents(),
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
Plugin.Description(),
Plugin.Latex({ renderEngine: "katex" }),
],
filters: [Plugin.RemoveDrafts()],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources(),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.ContentIndex({
enableSiteMap: false,
enableRSS: false,
}),
Plugin.Assets(),
Plugin.Static(),
ZyphosFavicons(),
ZyphosHeroResources(),
Plugin.NotFoundPage(),
Plugin.CustomOgImages(),
],
},
}
export default config

53
site/quartz.layout.ts Normal file
View file

@ -0,0 +1,53 @@
import { PageLayout, SharedLayout } from "./quartz/cfg"
import * as Component from "./quartz/components"
import ZyphosMasthead from "./quartz/components/ZyphosMasthead"
import ZyphosOverviewSidebar from "./quartz/components/ZyphosOverviewSidebar"
import ZyphosThemeLock from "./quartz/components/ZyphosThemeLock"
export const sharedPageComponents: SharedLayout = {
head: Component.Head(),
header: [ZyphosThemeLock(), ZyphosMasthead(), Component.Search()],
afterBody: [],
footer: Component.Footer({
links: {},
}),
}
export const defaultContentPageLayout: PageLayout = {
beforeBody: [
Component.ConditionalRender({
component: Component.Breadcrumbs({
rootName: "Zyphos",
showCurrentPage: false,
showRoot: false,
}),
condition: (page) => page.fileData.slug !== "index",
}),
Component.ConditionalRender({
component: Component.ArticleTitle(),
condition: (page) => !page.fileData.slug?.endsWith("/index") && page.fileData.slug !== "index",
}),
Component.ConditionalRender({
component: Component.ContentMeta(),
condition: (page) => !page.fileData.slug?.endsWith("/index") && page.fileData.slug !== "index",
}),
],
afterBody: [],
left: [ZyphosOverviewSidebar()],
right: [
Component.DesktopOnly(Component.TableOfContents()),
Component.Backlinks(),
],
}
export const defaultListPageLayout: PageLayout = {
beforeBody: [
Component.Breadcrumbs({
rootName: "Zyphos",
showCurrentPage: false,
showRoot: false,
}),
],
left: [],
right: [],
}

View file

@ -0,0 +1,118 @@
import { QuartzComponent, QuartzComponentConstructor } from "./types"
export const zyphosHeroScript = String.raw`
function bootZyphosHero() {
const home = document.querySelector("body[data-slug='index'] article")
if (!home || home.querySelector(".zyphos-hero-canvas")) return
const canvas = document.createElement("canvas")
canvas.className = "zyphos-hero-canvas"
canvas.setAttribute("aria-hidden", "true")
home.prepend(canvas)
const context = canvas.getContext("2d")
function resize() {
const rect = home.getBoundingClientRect()
const ratio = Math.min(window.devicePixelRatio || 1, 2)
canvas.width = Math.max(1, Math.floor(rect.width * ratio))
canvas.height = Math.floor(Math.min(window.innerHeight * 0.72, 620) * ratio)
canvas.style.height = Math.floor(canvas.height / ratio) + "px"
context.setTransform(ratio, 0, 0, ratio, 0, 0)
}
function drawPlanet(x, y, radius, colors, time, shadow) {
const gradient = context.createRadialGradient(x - radius * 0.32, y - radius * 0.35, 0, x, y, radius)
gradient.addColorStop(0, colors[0])
gradient.addColorStop(0.5, colors[1])
gradient.addColorStop(1, colors[2])
context.fillStyle = gradient
context.beginPath()
context.arc(x, y, radius, 0, Math.PI * 2)
context.fill()
const eclipse = context.createRadialGradient(x + Math.cos(time) * radius * 0.3, y, 0, x, y, radius * 1.2)
eclipse.addColorStop(0, shadow)
eclipse.addColorStop(1, "rgba(0, 0, 0, 0)")
context.fillStyle = eclipse
context.beginPath()
context.arc(x, y, radius, 0, Math.PI * 2)
context.fill()
context.strokeStyle = "rgba(142, 223, 176, 0.18)"
for (let i = 0; i < 5; i += 1) {
context.beginPath()
context.ellipse(x, y + Math.sin(i * 1.6) * radius * 0.42, radius * (0.44 + i * 0.05), radius * 0.08, i * 0.28, 0, Math.PI * 2)
context.stroke()
}
}
function frame(now) {
const width = canvas.clientWidth
const height = canvas.clientHeight
const t = now * 0.00025
context.clearRect(0, 0, width, height)
const star = context.createRadialGradient(width * 0.78, height * 0.18, 0, width * 0.78, height * 0.18, width * 0.55)
star.addColorStop(0, "rgba(255, 174, 88, 0.22)")
star.addColorStop(1, "rgba(255, 174, 88, 0)")
context.fillStyle = star
context.fillRect(0, 0, width, height)
context.strokeStyle = "rgba(115, 198, 227, 0.11)"
for (let i = 0; i < 7; i += 1) {
const y = height * (0.2 + i * 0.09) + Math.sin(t * 2 + i) * 6
context.beginPath()
context.moveTo(0, y)
context.bezierCurveTo(width * 0.35, y - 30, width * 0.62, y + 36, width, y - 12)
context.stroke()
}
const zr = Math.min(width, height) * 0.21
const zx = width * 0.68
const zy = height * 0.62
const ur = zr * 0.62
const ux = zx - zr * 1.85
const uy = zy - zr * 0.7
context.strokeStyle = "rgba(239, 252, 248, 0.15)"
context.beginPath()
context.moveTo(ux, uy)
context.lineTo(zx, zy)
context.stroke()
drawPlanet(ux, uy, ur, ["#7d8899", "#2c3a4a", "#070b11"], t + 1.2, "rgba(0, 0, 0, 0.6)")
drawPlanet(zx, zy, zr, ["#c7f7d0", "#28726c", "#06131b"], t, "rgba(0, 0, 0, 0.42)")
context.fillStyle = "rgba(142, 223, 176, 0.62)"
for (let i = 0; i < 56; i += 1) {
const angle = i * 2.399 + t * 0.35
const r = zr * (0.18 + ((i * 37) % 100) / 140)
const x = zx + Math.cos(angle) * r * 0.82
const y = zy + Math.sin(angle) * r * 0.38
const pulse = 1 + Math.sin(now * 0.002 + i) * 0.8
context.beginPath()
context.arc(x, y, Math.max(0.7, pulse), 0, Math.PI * 2)
context.fill()
}
requestAnimationFrame(frame)
}
resize()
window.addEventListener("resize", resize)
requestAnimationFrame(frame)
}
document.addEventListener("nav", bootZyphosHero)
document.addEventListener("DOMContentLoaded", bootZyphosHero)
bootZyphosHero()
`
export default (() => {
const ZyphosHeroScript: QuartzComponent = () => (
<script dangerouslySetInnerHTML={{ __html: zyphosHeroScript }} />
)
return ZyphosHeroScript
}) satisfies QuartzComponentConstructor

View file

@ -0,0 +1,83 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { FullSlug, resolveRelative } from "../util/path"
type Route = {
label: string
slug: FullSlug
matches: string[]
}
const routes: Route[] = [
{
label: "Home",
slug: "index" as FullSlug,
matches: ["index"],
},
{
label: "World",
slug: "World/index" as FullSlug,
matches: ["World"],
},
{
label: "Biosphere",
slug: "Ecology/index" as FullSlug,
matches: ["Ecology", "Species"],
},
{
label: "Civilizations",
slug: "Civilizations/index" as FullSlug,
matches: ["Civilizations", "Technologies", "Conflicts", "Themes"],
},
]
function isMatch(currentSlug: string, prefix: string) {
return currentSlug === prefix || currentSlug.startsWith(`${prefix}/`)
}
function pickActiveRoute(currentSlug: string) {
return routes
.flatMap((route) =>
route.matches
.filter((prefix) => isMatch(currentSlug, prefix))
.map((prefix) => ({
route,
prefixLength: prefix.length,
})),
)
.sort((a, b) => b.prefixLength - a.prefixLength)[0]?.route
}
export default (() => {
const ZyphosMasthead: QuartzComponent = ({ fileData }: QuartzComponentProps) => {
const currentSlug = fileData.slug ?? ("index" as FullSlug)
const activeRoute = pickActiveRoute(currentSlug)
return (
<section class="zyphos-titlebar">
<div class="zyphos-titlebar-copy">
<p class="zyphos-titlebar-title">
<a href={resolveRelative(currentSlug, "index" as FullSlug)}>Zyphos</a>
</p>
<p class="zyphos-titlebar-tagline">
A close-binary living world rendered through Aquarium and named through Weksa.
</p>
</div>
<nav class="zyphos-titlebar-nav" aria-label="Zyphos sections">
{routes.map((route) => {
const active = activeRoute?.slug === route.slug
return (
<a
href={resolveRelative(currentSlug, route.slug)}
class={active ? "zyphos-nav-chip active" : "zyphos-nav-chip"}
>
{route.label}
</a>
)
})}
</nav>
</section>
)
}
return ZyphosMasthead
}) satisfies QuartzComponentConstructor

View file

@ -0,0 +1,37 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { FullSlug, resolveRelative } from "../util/path"
type SidebarLink = {
label: string
slug: FullSlug
}
const links: SidebarLink[] = [
{ label: "Zyphos Simulation Brief", slug: "World/Zyphos-Simulation-Brief" as FullSlug },
{ label: "Zyphos Umbros Binary System", slug: "World/Zyphos-Umbros-Binary-System" as FullSlug },
{ label: "Mutable Memory Endosymbiosis", slug: "Ecology/Mutable-Memory-Endosymbiosis" as FullSlug },
{ label: "Zyphos Biosphere Examples", slug: "Ecology/Zyphos-Biosphere-Examples" as FullSlug },
{ label: "Biological Memetic Engine", slug: "Technologies/Biological-Memetic-Engine" as FullSlug },
]
export default (() => {
const ZyphosOverviewSidebar: QuartzComponent = ({ fileData }: QuartzComponentProps) => {
const currentSlug = fileData.slug ?? ("index" as FullSlug)
return (
<aside class="zyphos-overview" aria-label="Zyphos overview">
<p class="zyphos-overview-title">Project Surface</p>
<p class="zyphos-overview-copy">
Setting canon lives here. Aquarium renders the demo. Weksa will earn the names.
</p>
<nav>
{links.map((link) => (
<a href={resolveRelative(currentSlug, link.slug)}>{link.label}</a>
))}
</nav>
</aside>
)
}
return ZyphosOverviewSidebar
}) satisfies QuartzComponentConstructor

View file

@ -0,0 +1,13 @@
import { QuartzComponent, QuartzComponentConstructor } from "./types"
export default (() => {
const ZyphosThemeLock: QuartzComponent = () => (
<script
dangerouslySetInnerHTML={{
__html: `document.documentElement.setAttribute("saved-theme", "dark")`,
}}
/>
)
return ZyphosThemeLock
}) satisfies QuartzComponentConstructor

View file

@ -0,0 +1,274 @@
@use "./base.scss";
@use "./variables.scss" as *;
:root,
:root[saved-theme="light"],
:root[saved-theme="dark"] {
color-scheme: dark;
}
body {
background:
radial-gradient(circle at 76% 12%, rgba(255, 174, 88, 0.18), transparent 18%),
radial-gradient(circle at 18% 10%, rgba(142, 223, 176, 0.12), transparent 24%),
radial-gradient(circle at 50% 0%, rgba(115, 198, 227, 0.14), transparent 28%),
linear-gradient(180deg, #03070d 0%, #07110f 46%, #091712 100%);
color: var(--darkgray);
}
.page {
position: relative;
max-width: 1680px;
padding: 0 1.2rem 2.5rem;
}
.page::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
background-image:
linear-gradient(rgba(142, 223, 176, 0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(142, 223, 176, 0.035) 1px, transparent 1px);
background-size: 28px 28px;
mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.72), transparent 95%);
opacity: 0.7;
}
.page > #quartz-body .center,
.page > #quartz-body footer {
max-width: none;
}
.page > #quartz-body .left.sidebar {
gap: 0;
padding: 2.4rem 1rem 0 0;
background: transparent;
border: none;
box-shadow: none;
backdrop-filter: none;
}
.page > #quartz-body .center > .page-header {
margin-top: 2.4rem;
}
.page > #quartz-body .center header {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 1rem 1.25rem;
align-items: start;
margin: 0 0 1rem;
padding: 1rem 1.15rem 1.05rem;
border: 1px solid rgba(142, 223, 176, 0.14);
border-radius: 22px;
background:
radial-gradient(circle at 82% 50%, rgba(255, 174, 88, 0.16), transparent 22%),
linear-gradient(135deg, rgba(7, 12, 19, 0.98), rgba(10, 22, 18, 0.95));
box-shadow:
0 20px 44px rgba(0, 0, 0, 0.24),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
overflow: hidden;
}
.page > #quartz-body .center header > .search {
max-width: 9rem;
width: 100%;
justify-self: end;
}
.zyphos-titlebar {
display: flex;
flex-direction: column;
gap: 0.75rem;
min-width: 0;
}
.zyphos-titlebar-copy {
display: flex;
flex-direction: column;
gap: 0.18rem;
}
.zyphos-titlebar-title,
.zyphos-titlebar-title a {
margin: 0;
color: var(--dark);
font-family: var(--titleFont);
font-size: clamp(2.1rem, 4vw, 3.3rem);
font-weight: 200;
line-height: 0.92;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.zyphos-titlebar-tagline {
margin: 0;
color: rgba(189, 212, 202, 0.84);
font-family: var(--titleFont);
font-size: 0.88rem;
font-weight: 200;
letter-spacing: 0.02em;
line-height: 1.4;
max-width: 68ch;
}
.zyphos-titlebar-nav {
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
}
.zyphos-nav-chip {
display: inline-flex;
align-items: center;
min-height: 2.15rem;
padding: 0.3rem 0.8rem;
border-radius: 999px;
border: 1px solid rgba(142, 223, 176, 0.18);
background: rgba(142, 223, 176, 0.07);
color: #e2f6ee;
font-family: var(--titleFont);
font-size: 0.92rem;
font-weight: 300;
letter-spacing: 0.02em;
}
.zyphos-nav-chip:hover,
.zyphos-nav-chip.active {
background: rgba(255, 174, 88, 0.16);
border-color: rgba(255, 174, 88, 0.42);
color: #fff3e8;
}
.article-title,
article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
font-family: var(--titleFont);
letter-spacing: 0.015em;
}
.article-title {
margin: 0;
font-size: clamp(2rem, 3vw, 2.85rem);
font-weight: 200;
line-height: 0.96;
}
.page > #quartz-body .center > article {
position: relative;
background:
linear-gradient(180deg, rgba(10, 18, 16, 0.98), rgba(8, 14, 22, 0.96)),
linear-gradient(180deg, rgba(142, 223, 176, 0.02), rgba(255, 174, 88, 0.02));
border: 1px solid rgba(142, 223, 176, 0.1);
border-radius: 24px;
box-shadow:
0 24px 52px rgba(0, 0, 0, 0.26),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
padding: 1.45rem 1.7rem 1.9rem;
overflow: hidden;
}
body[data-slug="index"] .page > #quartz-body .center > article {
padding-top: 0;
}
.zyphos-hero-canvas {
display: block;
width: calc(100% + 3.4rem);
margin: 0 -1.7rem 1.35rem;
min-height: 360px;
border-bottom: 1px solid rgba(142, 223, 176, 0.12);
background: #03070d;
}
.page > #quartz-body .right.sidebar {
gap: 1rem;
padding: 2.4rem 0 0 1rem;
background: transparent;
border: none;
box-shadow: none;
backdrop-filter: none;
}
.toc,
.backlinks,
.zyphos-overview {
border: 1px solid rgba(142, 223, 176, 0.11);
border-radius: 20px;
background:
linear-gradient(180deg, rgba(10, 18, 16, 0.88), rgba(8, 14, 22, 0.82));
box-shadow:
0 18px 40px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
padding: 1rem;
}
.zyphos-overview-title {
margin: 0 0 0.35rem;
color: var(--secondary);
font-family: var(--titleFont);
font-size: 0.78rem;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.zyphos-overview-copy {
margin: 0 0 0.9rem;
color: rgba(189, 212, 202, 0.78);
font-size: 0.9rem;
line-height: 1.5;
}
.zyphos-overview nav {
display: grid;
gap: 0.45rem;
}
.zyphos-overview a {
display: block;
color: #e5f7ef;
border: 1px solid rgba(142, 223, 176, 0.12);
border-radius: 14px;
padding: 0.55rem 0.65rem;
background: rgba(142, 223, 176, 0.05);
}
.zyphos-overview a:hover {
border-color: rgba(255, 174, 88, 0.36);
background: rgba(255, 174, 88, 0.1);
}
article strong {
color: #f2fff8;
}
article table {
border-color: rgba(142, 223, 176, 0.16);
}
article tr,
article td,
article th {
border-color: rgba(142, 223, 176, 0.12);
}
@media all and not ($desktop) {
.page > #quartz-body .center header {
grid-template-columns: minmax(0, 1fr);
}
.page > #quartz-body .center header > .search {
justify-self: stretch;
max-width: none;
}
.zyphos-hero-canvas {
width: calc(100% + 2rem);
margin-inline: -1rem;
}
}

View file

@ -4,3 +4,4 @@
{"ts":"2026-05-18T00:31:00+01:00","type":"design_doctrine","status":"accepted","note":"Zyphos worldbuilding should bend to physics rather than bending physics for spectacle. Orbital mechanics, energy budget, eclipse geometry, climate, and biosphere constraints are design pressure that should make the setting more specific and grounded."}
{"ts":"2026-05-18T00:46:00+01:00","type":"biosphere_foundation","status":"accepted","note":"Zyphos cells have a mitochondria-like endosymbiont for mutable memory storage and intercellular transmission. Sentience and memory exchange exist in gradients from cells through organisms, colonies, ecosystems, and landscapes; Earth analogue species must be derived from this substrate rather than imported unchanged."}
{"ts":"2026-05-18T01:08:00+01:00","type":"biosphere_examples_and_naming_sync","status":"accepted","note":"First Zyphos biosphere examples should brighten the world through low-energy functional signals: light-return flashes, eclipse guidance, memory-contract routes, and organisms whose beauty is work. Future inhabitant-language names should be coordinated through Weksa from speaker ontology and language-project state, not direct English substitution."}
{"ts":"2026-05-18T01:29:00+01:00","type":"site_surface","status":"accepted","note":"The Zyphos public site belongs inside the Eusocial Interbeing repo rather than a separate repo, because the vault owns the worldbuilding content that will form most of the site. The site should deploy as GitHub Pages Quartz like Aetheria, with DNS pointing zyphos.gamecult.org at gamecult.github.io rather than spending Yggdrasil on static hosting."}

View file

@ -18,6 +18,8 @@ invariants:
- Do not import Avatar, Semiosis, or Turtledove proper nouns into setting canon.
key_files:
entrypoint: Eusocial Interbeing/index.md
zyphos_site_overlay: site/quartz.config.ts
zyphos_site_layout: site/quartz.layout.ts
mutable_memory_endosymbiosis: Eusocial Interbeing/Ecology/Mutable Memory Endosymbiosis.md
zyphos_biosphere_examples: Eusocial Interbeing/Ecology/Zyphos Biosphere Examples.md
zyphos_umbros_binary_system: Eusocial Interbeing/World/Zyphos Umbros Binary System.md