Composite delete: the page body's compositeSections branch, its CSS, the dead overview hider and showCompositeJump go
No content set compositeSections, so the branch never rendered; the .gamecult-composite-overview hider matched zero children on the built /tour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
340a182e8a
commit
25e280f912
5 changed files with 7 additions and 332 deletions
|
|
@ -2,7 +2,6 @@
|
|||
title: Portfolio Pitch
|
||||
description: "Interactive GameCult portfolio pitch: Personas sell the absurd upside of their favourite projects while Void keeps the receipts in reach."
|
||||
enableToc: false
|
||||
showCompositeJump: false
|
||||
cssclasses:
|
||||
- gamecult-pitch-route
|
||||
sidebarGroups:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
title: GameCult
|
||||
description: "GameCult builds games, creative tools, and AI systems with memory, agency, and someone you can argue with."
|
||||
enableToc: false
|
||||
showCompositeJump: false
|
||||
sidebarGroups:
|
||||
- title: Studio
|
||||
links:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
title: GameCult Tour
|
||||
description: "A full-screen visual novel tour through GameCult's public wiki, project rooms, repo swarm, and serious machinery."
|
||||
enableToc: false
|
||||
showCompositeJump: false
|
||||
sidebarGroups:
|
||||
- title: Studio
|
||||
links:
|
||||
|
|
@ -58,8 +57,6 @@ sidebarGroups:
|
|||
slug: Docs/Site-Architecture
|
||||
- label: Bifrost
|
||||
slug: Docs/Bifrost
|
||||
cssclasses:
|
||||
- gamecult-composite-overview
|
||||
---
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import { ComponentChildren } from "preact"
|
||||
import { Element, ElementContent, Root } from "hast"
|
||||
import { htmlToJsx } from "../util/jsx"
|
||||
import { QuartzPluginData } from "../plugins/vfile"
|
||||
import { clone } from "../util/clone"
|
||||
import {
|
||||
isRelativeURL,
|
||||
normalizeHastElement,
|
||||
resolveRelative,
|
||||
simplifySlug,
|
||||
stripSlashes,
|
||||
|
|
@ -14,7 +12,7 @@ import {
|
|||
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
|
||||
import FolderContent from "./pages/FolderContent"
|
||||
import AutoIndexFolder from "./AutoIndexFolder"
|
||||
import { resolveGameCultReferenceSlug, resolveGameCultSourceFile, stripTopTagline } from "./gamecult"
|
||||
import { resolveGameCultSourceFile, stripTopTagline } from "./gamecult"
|
||||
|
||||
interface Options {
|
||||
fallback: "content" | "folder"
|
||||
|
|
@ -24,14 +22,6 @@ const defaultOptions: Options = {
|
|||
fallback: "content",
|
||||
}
|
||||
|
||||
type CompositeSection = {
|
||||
content: ComponentChildren
|
||||
leadFigure?: ComponentChildren
|
||||
sectionId: string
|
||||
slug: FullSlug
|
||||
title: string
|
||||
}
|
||||
|
||||
function isElement(node: ElementContent): node is Element {
|
||||
return node.type === "element"
|
||||
}
|
||||
|
|
@ -69,104 +59,6 @@ function rebaseSharedSourceElement(
|
|||
return el
|
||||
}
|
||||
|
||||
function buildSectionContent(parentSlug: FullSlug, file: QuartzPluginData): CompositeSection | undefined {
|
||||
if (!file.slug || !file.htmlAst || !file.filePath) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const root = clone(file.htmlAst) as Root
|
||||
const children = [...root.children]
|
||||
|
||||
let firstMeaningfulIndex = -1
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const node = children[i]
|
||||
if (node.type === "text" && node.value.trim().length === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
firstMeaningfulIndex = i
|
||||
break
|
||||
}
|
||||
|
||||
if (firstMeaningfulIndex >= 0) {
|
||||
const node = children[firstMeaningfulIndex]
|
||||
if (isElement(node) && node.tagName === "h1") {
|
||||
children.splice(firstMeaningfulIndex, 1)
|
||||
}
|
||||
}
|
||||
|
||||
let leadFigure: Element | undefined
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const node = children[i]
|
||||
if (node.type === "text" && node.value.trim().length === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (isElement(node) && node.tagName === "figure") {
|
||||
leadFigure = node
|
||||
children.splice(i, 1)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
const normalizedChildren = children.map((child) =>
|
||||
normalizeHastElement(child as Element, parentSlug, file.slug as FullSlug),
|
||||
) as ElementContent[]
|
||||
|
||||
const sectionRoot: Root = {
|
||||
type: "root",
|
||||
children: normalizedChildren,
|
||||
}
|
||||
|
||||
const normalizedFigure = leadFigure
|
||||
? normalizeHastElement(leadFigure, parentSlug, file.slug as FullSlug)
|
||||
: undefined
|
||||
|
||||
const figureRoot: Root | undefined = normalizedFigure
|
||||
? {
|
||||
type: "root",
|
||||
children: [normalizedFigure],
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
content: htmlToJsx(file.filePath, sectionRoot) as ComponentChildren,
|
||||
leadFigure: figureRoot ? (htmlToJsx(file.filePath, figureRoot) as ComponentChildren) : undefined,
|
||||
sectionId: file.slug.split("/").at(-1)?.toLowerCase() ?? "section",
|
||||
slug: file.slug as FullSlug,
|
||||
title: file.frontmatter?.title ?? file.slug.split("/").at(-1) ?? "Section",
|
||||
}
|
||||
}
|
||||
|
||||
function getCompositeSections(
|
||||
renderSlug: FullSlug,
|
||||
sourceFile: QuartzPluginData,
|
||||
allFiles: QuartzPluginData[],
|
||||
): CompositeSection[] {
|
||||
const sourceSlug = sourceFile.slug as FullSlug | undefined
|
||||
const configured = sourceFile.frontmatter?.compositeSections
|
||||
|
||||
if (!renderSlug || !sourceSlug || !Array.isArray(configured) || configured.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const bySlug = new Map(
|
||||
allFiles
|
||||
.filter((file) => typeof file.slug === "string")
|
||||
.map((file) => [file.slug as FullSlug, file]),
|
||||
)
|
||||
|
||||
return configured
|
||||
.map((entry) =>
|
||||
typeof entry === "string" ? resolveGameCultReferenceSlug(sourceSlug, entry) : undefined,
|
||||
)
|
||||
.filter((entry): entry is FullSlug => entry !== undefined)
|
||||
.map((slug) => bySlug.get(slug))
|
||||
.filter((file): file is QuartzPluginData => file !== undefined)
|
||||
.map((file) => buildSectionContent(renderSlug, file))
|
||||
.filter((section): section is CompositeSection => section !== undefined)
|
||||
}
|
||||
|
||||
export default ((opts?: Partial<Options>) => {
|
||||
const options: Options = { ...defaultOptions, ...opts }
|
||||
const DefaultFolderContent = FolderContent()
|
||||
|
|
@ -205,61 +97,20 @@ export default ((opts?: Partial<Options>) => {
|
|||
const classes: string[] =
|
||||
sourceFile.frontmatter?.cssclasses ?? fileData.frontmatter?.cssclasses ?? []
|
||||
const articleClass = ["popover-hint", ...classes].join(" ")
|
||||
const sections = renderSlug ? getCompositeSections(renderSlug, sourceFile, allFiles) : []
|
||||
const showCompositeJump = sourceFile.frontmatter?.showCompositeJump !== false
|
||||
|
||||
if (options.fallback === "folder" && renderSlug === ("Blog/index" as FullSlug)) {
|
||||
return <BlogFolderContent {...props} />
|
||||
}
|
||||
|
||||
if (sections.length === 0) {
|
||||
if (options.fallback === "folder" && sourceFile.frontmatter?.showFolderListing === false) {
|
||||
return <article class={articleClass}>{baseContent}</article>
|
||||
}
|
||||
|
||||
if (options.fallback === "folder") {
|
||||
return <DefaultFolderContent {...props} />
|
||||
}
|
||||
|
||||
if (options.fallback === "folder" && sourceFile.frontmatter?.showFolderListing === false) {
|
||||
return <article class={articleClass}>{baseContent}</article>
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="popover-hint gamecult-composite-page">
|
||||
<article class={articleClass}>{baseContent}</article>
|
||||
{showCompositeJump && (
|
||||
<nav
|
||||
class="gamecult-composite-jump"
|
||||
aria-label={`${fileData.frontmatter?.title ?? "Page"} sections`}
|
||||
>
|
||||
{sections.map((section) => (
|
||||
<a href={`#${section.sectionId}`} class="gamecult-nav-link">
|
||||
{section.title}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
)}
|
||||
<div class="gamecult-composite-sections">
|
||||
{sections.map((section) => (
|
||||
<section id={section.sectionId} class="gamecult-composite-section">
|
||||
<div class="gamecult-composite-divider" aria-hidden="true" />
|
||||
<div
|
||||
class={`gamecult-composite-shell${section.leadFigure ? " has-media" : ""}`}
|
||||
data-section-slug={section.slug}
|
||||
>
|
||||
{section.leadFigure && <div class="gamecult-composite-media">{section.leadFigure}</div>}
|
||||
<article class="gamecult-composite-copy">
|
||||
<header class="gamecult-composite-header">
|
||||
<h2>{section.title}</h2>
|
||||
</header>
|
||||
<div class="gamecult-composite-body">{section.content}</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
if (options.fallback === "folder") {
|
||||
return <DefaultFolderContent {...props} />
|
||||
}
|
||||
|
||||
return <article class={articleClass}>{baseContent}</article>
|
||||
}
|
||||
|
||||
return GameCultCompositeContent
|
||||
|
|
|
|||
|
|
@ -1745,155 +1745,6 @@ body[data-slug="Pitch"] .gamecult-compound-vn .sai-speaker-stage.has-dom-cards {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body[data-slug="tour"] .gamecult-composite-sections {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-overview > h2,
|
||||
.gamecult-composite-overview > ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gamecult-composite-jump {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.65rem;
|
||||
margin: 0;
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-sections {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.45rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-section {
|
||||
position: relative;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gamecult-composite-shell {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 1rem;
|
||||
padding: 1.1rem;
|
||||
border-radius: 24px;
|
||||
border: 1px solid rgba(89, 183, 255, 0.14);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(8, 13, 21, 0.8),
|
||||
rgba(8, 13, 21, 0.72)
|
||||
);
|
||||
overflow: hidden;
|
||||
container-type: inline-size;
|
||||
box-shadow:
|
||||
0 22px 44px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||
backdrop-filter: blur(14px);
|
||||
}
|
||||
|
||||
.gamecult-composite-shell.has-media {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(16rem, 22rem) minmax(0, 1fr);
|
||||
gap: 1.25rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.gamecult-composite-media {
|
||||
min-width: 0;
|
||||
align-self: start;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.gamecult-composite-media > figure {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gamecult-composite-media > figure.gamecult-media-card {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.gamecult-composite-media > figure img {
|
||||
min-height: 280px;
|
||||
}
|
||||
|
||||
.gamecult-composite-copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.9rem;
|
||||
min-width: 0;
|
||||
padding: 0.15rem 0.1rem 0.2rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-header {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0.8rem 0.95rem 0.85rem;
|
||||
border: 1px solid rgba(89, 183, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(10, 16, 24, 0.9),
|
||||
rgba(17, 24, 35, 0.82)
|
||||
);
|
||||
box-shadow:
|
||||
0 14px 28px rgba(0, 0, 0, 0.16),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-header h2 {
|
||||
margin: 0;
|
||||
color: var(--dark);
|
||||
font-family: var(--titleFont);
|
||||
font-size: clamp(1.4rem, 2.1vw, 2rem);
|
||||
font-weight: 200;
|
||||
line-height: 0.92;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.gamecult-composite-header > *,
|
||||
.gamecult-composite-body,
|
||||
.gamecult-composite-copy {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-body > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-body figure {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-body {
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
|
||||
@container (max-width: 58rem) {
|
||||
.gamecult-composite-shell.has-media {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.gamecult-composite-media > figure {
|
||||
max-width: 32rem;
|
||||
}
|
||||
}
|
||||
|
||||
.gamecult-home-hero {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.15fr) minmax(280px, 0.85fr);
|
||||
|
|
@ -2203,28 +2054,6 @@ body[data-slug="tour"] .gamecult-composite-sections {
|
|||
}
|
||||
|
||||
@media all and ($mobile) {
|
||||
.gamecult-composite-header {
|
||||
padding: 0.75rem 0.8rem 0.8rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.gamecult-composite-shell,
|
||||
.gamecult-composite-shell.has-media {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
padding: 0.95rem;
|
||||
}
|
||||
|
||||
.gamecult-composite-divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gamecult-composite-header {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.gamecult-feature-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue