Implement repository-driven theme rendering

This commit is contained in:
root
2026-07-23 17:49:10 -07:00
parent 68d76a59df
commit 884d182c86
32 changed files with 3040 additions and 1417 deletions
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Labyricorn mark">
<path fill="#c5a059" d="M8 8h12v36h36v12H8z"/>
<path fill="#f5f0e7" d="M28 8h28v12H40v16H28z"/>
</svg>

After

Width:  |  Height:  |  Size: 204 B

@@ -0,0 +1 @@
document.documentElement.dataset.themeReady = "true";
@@ -0,0 +1,33 @@
:root{color-scheme:dark;--bg:#090909;--panel:#121212;--ink:#f4f0e8;--muted:#a7a29a;--gold:#c5a059;--line:#292722;font-family:Georgia,"Times New Roman",serif}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);line-height:1.65}
a{color:var(--gold);text-underline-offset:.2em}
img{max-width:100%}
.site-header,.site-footer,main{width:min(1180px,calc(100% - 2rem));margin:auto}
.site-header{min-height:76px;display:flex;align-items:center;justify-content:space-between;gap:2rem;border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:.7rem;color:var(--ink);text-decoration:none;font-weight:700}
nav{display:flex;gap:1.15rem;flex-wrap:wrap;font:600 .72rem/1.3 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.08em}
main{padding:5rem 0 7rem}
.hero{max-width:850px;padding:3rem 0 5rem}
.hero h1,.section-heading h1,.project-body>h1,.not-found h1{font-size:clamp(2.8rem,7vw,6.8rem);line-height:.95;letter-spacing:-.045em;margin:.2em 0}
.hero p:not(.eyebrow),.lede{font-size:1.3rem;color:var(--muted);max-width:62ch}
.eyebrow{font:700 .7rem/1.2 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.16em;color:var(--gold)}
.feed{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.feed>h2,.feed>p{grid-column:1/-1;background:var(--bg);margin:0;padding:1.5rem}
.feed article{background:var(--panel);padding:2rem;min-height:180px}
.section-heading{margin-bottom:3rem}
.project-grid,.content-grid{display:grid;grid-template-columns:minmax(220px,300px) minmax(0,1fr);gap:clamp(2rem,7vw,7rem);align-items:start}
.project-meta,.content-grid>aside{position:sticky;top:1rem;border-top:2px solid var(--gold);padding-top:1rem}
dt{font:700 .65rem/1.2 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.1em;color:var(--muted)}
dd{margin:0 0 1rem;overflow-wrap:anywhere}
.project-body{max-width:760px}
.project-body h2,.prose h2{margin-top:2.5em;border-bottom:1px solid var(--line);padding-bottom:.35em}
.tags{display:flex;gap:.5rem;list-style:none;padding:0;flex-wrap:wrap}
.tags li{border:1px solid var(--line);padding:.2rem .55rem;font:600 .72rem/1.5 ui-monospace,monospace}
pre{overflow:auto;padding:1rem;background:#050505;border:1px solid var(--line)}
code{font-family:ui-monospace,monospace;font-size:.9em}
blockquote{margin-left:0;border-left:3px solid var(--gold);padding-left:1rem;color:var(--muted)}
.site-footer{display:flex;justify-content:space-between;gap:1rem;border-top:1px solid var(--line);padding:2rem 0;color:var(--muted);font-size:.8rem}
.not-found{max-width:720px}
.standalone-demo{max-width:780px}
@media(max-width:720px){.site-header{align-items:flex-start;flex-direction:column;padding:1rem 0}nav{gap:.75rem}main{padding-top:3rem}.feed,.project-grid,.content-grid{grid-template-columns:1fr}.project-meta,.content-grid>aside{position:static}.site-footer{flex-direction:column}pre{max-width:calc(100vw - 2rem)}}
@@ -0,0 +1,6 @@
<section class="not-found">
<p class="eyebrow">404</p>
<h1>That route is not in this release.</h1>
<p>The immutable artifact has no matching output.</p>
<p><a href="/">Return home</a></p>
</section>
@@ -0,0 +1,9 @@
<article class="content-grid">
<aside><h2>Contents</h2><ol>{% for heading in item.tableOfContents %}<li><a href="#{{ heading.id | escape }}">{{ heading.text | escape }}</a></li>{% endfor %}</ol></aside>
<div>
<p class="eyebrow">{{ item.artifactType | escape }}</p>
<h1>{{ item.title | escape }}</h1>
<p class="lede">{{ item.summary | escape }}</p>
<div class="prose">{{ item.content | safe_content }}</div>
</div>
</article>
@@ -0,0 +1,28 @@
<article class="project-grid">
<aside class="project-meta">
<p class="eyebrow">Project</p>
<dl>
<dt>Version</dt><dd>{{ project.version | escape }}</dd>
<dt>License</dt><dd>{{ project.license | escape }}</dd>
<dt>Source commit</dt><dd><code>{{ project.sourceSnapshot.commit | escape }}</code></dd>
<dt>Updated</dt><dd>{{ project.sourceSnapshot.committedAt | escape }}</dd>
</dl>
<h2>Stack</h2>
<ul>{% for item in project.stack %}<li>{{ item | escape }}</li>{% endfor %}</ul>
</aside>
<div class="project-body">
<h1>{{ project.title | escape }}</h1>
<p class="lede">{{ project.summary | escape }}</p>
<p><a href="{{ project.homepage | escape }}">Open the standalone demo</a></p>
<h2 id="provenance">Pinned provenance</h2>
<p>The project and its publication were read from <code>{{ project.sourceSnapshot.repository | escape }}</code> at one exact commit.</p>
<h2 id="tags">Tags</h2>
<ul class="tags">{% for tag in project.tags %}<li>{{ tag | escape }}</li>{% endfor %}</ul>
<h2 id="devlogs">Devlogs</h2>
{% if project.relatedContent.devlogs.size == 0 %}<p>No matching devlogs in this snapshot.</p>{% endif %}
{% for item in project.relatedContent.devlogs %}<article><h3><a href="{{ item.route | escape }}">{{ item.title | escape }}</a></h3></article>{% endfor %}
<h2 id="articles">Related articles</h2>
{% if project.relatedContent.articles.size == 0 %}<p>No matching articles in this snapshot.</p>{% endif %}
{% for item in project.relatedContent.articles %}<article><h3><a href="{{ item.route | escape }}">{{ item.title | escape }}</a></h3></article>{% endfor %}
</div>
</article>
@@ -0,0 +1,12 @@
<section class="hero">
<p class="eyebrow">Engineering · Architecture · Operations</p>
<h1>{{ site.title | escape }}</h1>
<p>Repository-owned presentation rendered from an exact Git commit.</p>
</section>
<section class="feed" aria-labelledby="latest">
<h2 id="latest">Latest publications</h2>
{% if content.size == 0 %}<p>No published content in this snapshot.</p>{% endif %}
{% for item in content %}
<article><p class="eyebrow">{{ item.artifactType | escape }}</p><h3><a href="{{ item.route | escape }}">{{ item.title | escape }}</a></h3><p>{{ item.summary | escape }}</p></article>
{% endfor %}
</section>
@@ -0,0 +1,24 @@
<!doctype html>
<html lang="{{ site.language | escape }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="labyricorn-theme/v1">
<title>{{ page.title | escape }} · {{ site.title | escape }}</title>
{% for stylesheet in theme.stylesheets %}<link rel="stylesheet" href="{{ stylesheet | escape }}">
{% endfor %}{% for script in theme.scripts %}<script src="{{ script | escape }}" defer></script>
{% endfor %}</head>
<body>
<header class="site-header">
<a class="brand" href="/"><img src="/assets/images/logo.svg" width="32" height="32" alt=""><span>{{ site.title | escape }}</span></a>
<nav aria-label="Primary">
{% for entry in navigation %}<a href="{{ entry.route | escape }}">{{ entry.label | escape }}</a>{% endfor %}
</nav>
</header>
<main>{{ page.body | safe_page_body }}</main>
<footer class="site-footer">
<span>Built from immutable Git snapshots.</span>
<code>{{ build.id | escape }}</code>
</footer>
</body>
</html>
@@ -0,0 +1,10 @@
<header class="section-heading">
<p class="eyebrow">Section</p>
<h1>{{ section.label | escape }}</h1>
</header>
<section class="feed">
{% if content.size == 0 %}<p>No published items in this snapshot.</p>{% endif %}
{% for item in content %}
<article><h2><a href="{{ item.route | escape }}">{{ item.title | escape }}</a></h2><p>{{ item.summary | escape }}</p></article>
{% endfor %}
</section>
+29
View File
@@ -0,0 +1,29 @@
protocol: labyricorn-theme/v1
id: labyricorn-editorial
version: 2.0.0
engine: liquid
templates:
layout: templates/layout.liquid
home: templates/home.liquid
notFound: templates/404.liquid
sections:
articles: templates/sections/listing.liquid
projects: templates/sections/listing.liquid
documentation: templates/sections/listing.liquid
community: templates/sections/listing.liquid
downloads: templates/sections/listing.liquid
content:
project: templates/content/project.liquid
article: templates/content/article.liquid
assets:
styles:
- assets/styles/theme.css
scripts:
- assets/scripts/theme.js
files:
- assets/images/logo.svg
fonts: []
security:
allowScripts: true
allowExternalAssets: false
allowedExternalOrigins: []
@@ -0,0 +1,17 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Website Engine Demo</title>
<link rel="stylesheet" href="/assets/styles/theme.css">
</head>
<body>
<main class="standalone-demo">
<p class="eyebrow">Published file</p>
<h1>Repository bytes, published unchanged</h1>
<p>This page is declared by <code>projects.yml</code> and copied from the pinned source commit.</p>
<p><a href="/project/website-engine-control-plane/">Return to the project</a></p>
</main>
</body>
</html>
+10
View File
@@ -9,23 +9,33 @@ navigation:
route: "/articles/"
iconName: "FileText"
contentModel: "article"
presentation:
sectionTemplate: "articles"
- id: "projects"
label: "Projects"
route: "/projects/"
iconName: "LayoutTemplate"
contentModel: "project"
presentation:
sectionTemplate: "projects"
- id: "documentation"
label: "Documentation"
route: "/docs/"
iconName: "FolderOpen"
contentModel: "documentation"
presentation:
sectionTemplate: "documentation"
- id: "community"
label: "Community"
route: "/community/"
iconName: "MessageSquare"
contentModel: "discussion"
presentation:
sectionTemplate: "community"
- id: "downloads"
label: "Downloads"
route: "/downloads/"
iconName: "Download"
contentModel: "release"
presentation:
sectionTemplate: "downloads"
+26
View File
@@ -0,0 +1,26 @@
projects:
- id: website-engine-control-plane
source: site-definition
route: /project/website-engine-control-plane/
title: Website Engine Control Plane
summary: A deterministic Git-native static site control plane.
version: 2.0.0
license: MIT
homepage: /project/website-engine-control-plane/demo.html
tags: [static-site, git, liquid]
stack: [TypeScript, React, LiquidJS, Git]
presentation:
detailTemplate: project
relationships:
devlogs:
contentModel: devlog
matchField: metadata.projectId
required: false
articles:
contentModel: article
matchField: metadata.projectId
required: false
publishedFiles:
- source: packages/site-definition/demo-project/demo.html
route: /project/website-engine-control-plane/demo.html
mediaType: text/html
+3 -1
View File
@@ -4,9 +4,11 @@ site:
title: "Labyricorn Engineering & Architecture"
baseUrl: "https://labyricorn.com"
language: "en-US"
navigationFile: "navigation.yml"
projectsFile: "projects.yml"
theme:
source: "site-definition"
path: "/.theme"
path: ".theme"
markdown:
dialect: "labyricorn-commonmark-v1"
rawHtmlPolicy: "disabled"