migrate site to blatt: content, templates, blog post with old-steam theme

This commit is contained in:
2026-04-15 07:57:30 +02:00
parent c9b15c854b
commit 1f0939e27c
1312 changed files with 18774 additions and 194154 deletions

403
templates/academic.html Normal file
View File

@@ -0,0 +1,403 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Source+Code+Pro:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #d4ccc0; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--paper: #f8f5ef;
--paper-dark: #efe9df;
--text: #1a1714;
--text-light: #5a524a;
--text-lighter: #8a7e75;
--rule: #c8bfb2;
--accent: #2c4a7a;
--link: #1a4a8a;
}
html {
font-size: 17px;
}
body {
background: #d4ccc0;
color: var(--text);
font-family: "EB Garamond", Georgia, "Times New Roman", serif;
line-height: 1.65;
}
.paper {
max-width: 760px;
margin: 40px auto;
background: var(--paper);
padding: 72px 80px;
box-shadow:
0 1px 2px rgba(0,0,0,0.1),
0 4px 16px rgba(0,0,0,0.1),
0 8px 32px rgba(0,0,0,0.08);
min-height: 100vh;
}
/* Document header */
.doc-header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 32px;
border-bottom: 1px solid var(--rule);
}
.journal-name {
font-size: 11px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--text-lighter);
margin-bottom: 32px;
font-family: "EB Garamond", serif;
}
.doc-title {
font-size: 1.9rem;
font-weight: 500;
line-height: 1.2;
color: var(--text);
margin-bottom: 20px;
letter-spacing: -0.01em;
}
.author-line {
font-size: 1.05rem;
color: var(--text-light);
margin-bottom: 6px;
font-style: italic;
}
.author-line a {
color: var(--link);
text-decoration: none;
}
/* Metadata grid */
.meta-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
margin-top: 24px;
border: 1px solid var(--rule);
font-size: 0.82rem;
}
.meta-cell {
padding: 8px 14px;
border-bottom: 1px solid var(--rule);
}
.meta-cell:nth-child(odd) {
border-right: 1px solid var(--rule);
}
.meta-cell:nth-last-child(-n+2) {
border-bottom: none;
}
.meta-label {
font-size: 0.7rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--text-lighter);
margin-bottom: 2px;
}
.meta-value {
color: var(--text);
}
/* Tags / keywords */
.keywords {
margin-top: 20px;
font-size: 0.85rem;
color: var(--text-light);
}
.keywords strong {
color: var(--text);
font-weight: 500;
}
/* Abstract (first paragraph) */
.abstract {
margin: 32px 0 36px;
padding: 20px 24px;
background: var(--paper-dark);
border-left: 3px solid var(--accent);
font-size: 0.95rem;
line-height: 1.7;
color: var(--text-light);
}
.abstract-label {
font-size: 0.72rem;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text-lighter);
margin-bottom: 8px;
font-weight: 500;
}
/* Content — CSS counters for section numbering */
.doc-body {
counter-reset: h2-counter;
font-size: 1rem;
}
.doc-body h1 {
counter-reset: h3-counter;
counter-increment: h2-counter;
font-size: 1.25rem;
font-weight: 500;
margin-top: 40px;
margin-bottom: 14px;
color: var(--text);
padding-top: 8px;
border-top: 1px solid var(--rule);
}
.doc-body h1::before {
content: counter(h2-counter) ". ";
color: var(--text-lighter);
}
.doc-body h2 {
counter-increment: h3-counter;
font-size: 1.1rem;
font-weight: 500;
font-style: italic;
margin-top: 28px;
margin-bottom: 10px;
color: var(--text);
}
.doc-body h2::before {
content: counter(h2-counter) "." counter(h3-counter) " ";
font-style: normal;
color: var(--text-lighter);
}
.doc-body h3 {
font-size: 1rem;
font-weight: 600;
margin-top: 20px;
margin-bottom: 8px;
color: var(--text);
}
.doc-body p {
margin-bottom: 14px;
text-align: justify;
hyphens: auto;
}
.doc-body p + p {
text-indent: 1.5em;
margin-top: -6px;
}
.doc-body h1 + p,
.doc-body h2 + p,
.doc-body h3 + p {
text-indent: 0;
}
.doc-body a {
color: var(--link);
text-decoration: none;
}
.doc-body a:hover {
text-decoration: underline;
}
.doc-body code {
font-family: "Source Code Pro", monospace;
font-size: 0.85em;
background: var(--paper-dark);
padding: 0 4px;
border: 1px solid var(--rule);
}
.doc-body pre {
background: var(--paper-dark);
border: 1px solid var(--rule);
padding: 16px 20px;
margin: 20px 0;
overflow-x: auto;
font-family: "Source Code Pro", monospace;
font-size: 0.83em;
line-height: 1.6;
}
.doc-body pre code {
background: none;
border: none;
padding: 0;
}
.doc-body blockquote {
border-left: 2px solid var(--rule);
padding: 4px 20px;
margin: 18px 0 18px 16px;
color: var(--text-light);
font-style: italic;
}
.doc-body ul,
.doc-body ol {
margin: 12px 0 16px 24px;
}
.doc-body li {
margin-bottom: 4px;
}
.doc-body table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 0.9rem;
}
.doc-body caption {
caption-side: top;
font-size: 0.8rem;
color: var(--text-lighter);
text-align: left;
padding-bottom: 6px;
font-style: italic;
}
.doc-body th {
border-top: 2px solid var(--text);
border-bottom: 1px solid var(--text);
padding: 6px 10px;
text-align: left;
font-weight: 500;
font-size: 0.85rem;
}
.doc-body td {
border-bottom: 1px solid var(--rule);
padding: 6px 10px;
}
.doc-body tr:last-child td {
border-bottom: 1px solid var(--text);
}
.doc-body img {
max-width: 100%;
display: block;
margin: 24px auto;
}
.doc-body hr {
border: none;
border-top: 1px solid var(--rule);
margin: 32px 0;
}
/* Footnote-style footer */
.doc-footer {
margin-top: 48px;
padding-top: 16px;
border-top: 2px solid var(--text);
font-size: 0.8rem;
color: var(--text-lighter);
display: flex;
justify-content: space-between;
}
@media (max-width: 640px) {
.paper {
margin: 0;
padding: 40px 28px;
}
.meta-grid {
grid-template-columns: 1fr;
}
.meta-cell:nth-child(odd) {
border-right: none;
}
.meta-cell:nth-last-child(-n+2) {
border-bottom: 1px solid var(--rule);
}
.meta-cell:last-child {
border-bottom: none;
}
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<article class="paper">
<header class="doc-header">
<div class="journal-name">{{ config.site.name }}</div>
<h1 class="doc-title">{{ title }}</h1>
<div class="author-line">{{ config.site.author }}</div>
<div class="meta-grid">
<div class="meta-cell">
<div class="meta-label">Published</div>
<div class="meta-value">{{ published_date }}</div>
</div>
<div class="meta-cell">
<div class="meta-label">Reading Time</div>
<div class="meta-value">{{ reading_time }}</div>
</div>
{% if updated_date %}
<div class="meta-cell">
<div class="meta-label">Last Revised</div>
<div class="meta-value">{{ updated_date }}</div>
</div>
<div class="meta-cell">
<div class="meta-label">Status</div>
<div class="meta-value">Revised</div>
</div>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="keywords">
<strong>Keywords:</strong>
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}; {% endif %}{% endfor %}
</div>
{% endif %}
</header>
<div class="doc-body">
{{ content | safe }}
</div>
<footer class="doc-footer">
<span>{{ config.site.name }} — {{ config.site.author }}</span>
<span>{{ published_date }}</span>
</footer>
</article>
</body>
</html>

420
templates/apple-hig.html Normal file
View File

@@ -0,0 +1,420 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=SF+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #f2f2f7; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--blue: #007aff;
--blue-light: rgba(0,122,255,0.1);
--bg: #f2f2f7;
--card: #ffffff;
--text: #1c1c1e;
--secondary: #3c3c43;
--tertiary: #8e8e93;
--separator: rgba(60,60,67,0.12);
--radius: 14px;
}
body {
background: var(--bg);
color: var(--text);
font-family: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, sans-serif;
font-size: 15px;
line-height: 1.55;
min-height: 100vh;
}
/* Sidebar + content layout */
.layout {
display: flex;
min-height: 100vh;
}
/* Sidebar */
.sidebar {
width: 260px;
flex-shrink: 0;
background: rgba(255,255,255,0.72);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border-right: 1px solid var(--separator);
padding: 28px 0;
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
}
.sidebar-logo {
padding: 0 20px 20px;
border-bottom: 1px solid var(--separator);
margin-bottom: 12px;
}
.sidebar-logo-name {
font-size: 13px;
font-weight: 600;
color: var(--text);
letter-spacing: -0.01em;
}
.sidebar-logo-sub {
font-size: 11px;
color: var(--tertiary);
margin-top: 2px;
}
.sidebar-section-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--tertiary);
padding: 12px 20px 6px;
}
.sidebar-item {
display: block;
padding: 7px 20px;
font-size: 14px;
font-weight: 400;
color: var(--secondary);
text-decoration: none;
border-radius: 8px;
margin: 0 8px;
}
.sidebar-item.active {
background: var(--blue-light);
color: var(--blue);
font-weight: 500;
}
/* Main */
.main {
flex: 1;
padding: 32px 40px 60px;
max-width: 780px;
}
/* Breadcrumb */
.breadcrumb {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--tertiary);
margin-bottom: 24px;
}
.breadcrumb-sep {
opacity: 0.5;
}
.breadcrumb-current {
color: var(--blue);
font-weight: 500;
}
/* Page header */
.page-header {
margin-bottom: 32px;
}
.page-title {
font-size: 34px;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text);
line-height: 1.15;
margin-bottom: 12px;
}
.page-meta {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.meta-chip {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 12px;
font-weight: 500;
color: var(--blue);
background: var(--blue-light);
padding: 4px 10px;
border-radius: 999px;
}
.meta-plain {
font-size: 12px;
color: var(--tertiary);
}
/* Content card */
.content-card {
background: var(--card);
border-radius: var(--radius);
box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 16px rgba(0,0,0,0.06);
padding: 32px 36px;
margin-bottom: 20px;
}
/* Content styles */
.content-area h1 {
font-size: 26px;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text);
margin-top: 36px;
margin-bottom: 12px;
line-height: 1.2;
}
.content-area h2 {
font-size: 20px;
font-weight: 600;
letter-spacing: -0.01em;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h3 {
font-size: 16px;
font-weight: 600;
color: var(--text);
margin-top: 20px;
margin-bottom: 8px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 14px;
font-weight: 600;
color: var(--secondary);
margin-top: 16px;
margin-bottom: 6px;
}
.content-area p {
margin-bottom: 14px;
color: var(--secondary);
line-height: 1.65;
}
.content-area a {
color: var(--blue);
text-decoration: none;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "SF Mono", "Menlo", "Monaco", monospace;
font-size: 12.5px;
background: var(--bg);
color: #c0392b;
padding: 2px 6px;
border-radius: 5px;
}
.content-area pre {
background: #1c1c1e;
border-radius: 10px;
padding: 18px 20px;
margin: 16px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: #e5e5ea;
padding: 0;
font-size: 13px;
}
.content-area blockquote {
background: var(--blue-light);
border-left: 3px solid var(--blue);
border-radius: 0 10px 10px 0;
padding: 14px 18px;
margin: 16px 0;
}
.content-area blockquote p {
color: var(--blue);
margin: 0;
font-weight: 500;
}
.content-area ul {
margin: 10px 0 16px 20px;
color: var(--secondary);
}
.content-area ol {
margin: 10px 0 16px 24px;
color: var(--secondary);
}
.content-area li {
margin-bottom: 6px;
line-height: 1.55;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
font-size: 14px;
border-radius: 10px;
overflow: hidden;
}
.content-area th {
background: var(--bg);
padding: 10px 14px;
text-align: left;
font-size: 12px;
font-weight: 600;
color: var(--tertiary);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 10px 14px;
border-top: 1px solid var(--separator);
color: var(--secondary);
}
.content-area img {
max-width: 100%;
border-radius: 10px;
margin: 12px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--separator);
margin: 24px 0;
}
/* Tags card */
.tags-card {
background: var(--card);
border-radius: var(--radius);
box-shadow: 0 1px 3px rgba(0,0,0,0.06);
padding: 16px 20px;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.tags-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--tertiary);
}
.tag {
font-size: 12px;
font-weight: 500;
color: var(--blue);
background: var(--blue-light);
padding: 3px 10px;
border-radius: 999px;
}
@media (max-width: 700px) {
.sidebar { display: none; }
.main { padding: 20px 16px 40px; }
.page-title { font-size: 26px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="layout">
<nav class="sidebar">
<div class="sidebar-logo">
<div class="sidebar-logo-name">{{ config.site.name }}</div>
<div class="sidebar-logo-sub">Human Interface Guidelines</div>
</div>
<div class="sidebar-section-label">Topics</div>
<a href="#" class="sidebar-item active">{{ title }}</a>
<div class="sidebar-section-label">Author</div>
<a href="#" class="sidebar-item">{{ config.site.author }}</a>
<div class="sidebar-section-label">Published</div>
<a href="#" class="sidebar-item">{{ published_date }}</a>
{% if taxonomy.tags %}
<div class="sidebar-section-label">Tags</div>
{% for tag in taxonomy.tags %}
<a href="#" class="sidebar-item">{{ tag }}</a>
{% endfor %}
{% endif %}
</nav>
<main class="main">
<div class="breadcrumb">
<span>{{ config.site.name }}</span>
<span class="breadcrumb-sep">/</span>
<span>Posts</span>
<span class="breadcrumb-sep">/</span>
<span class="breadcrumb-current">{{ title }}</span>
</div>
<div class="page-header">
<h1 class="page-title">{{ title }}</h1>
<div class="page-meta">
<span class="meta-chip">{{ config.site.author }}</span>
<span class="meta-plain">{{ published_date }}</span>
<span class="meta-plain">{{ reading_time }}</span>
{% if updated_date %}<span class="meta-plain">Updated {{ updated_date }}</span>{% endif %}
</div>
</div>
<div class="content-card">
<div class="content-area">
{{ content | safe }}
</div>
</div>
{% if taxonomy.tags %}
<div class="tags-card">
<span class="tags-label">Tags</span>
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</main>
</div>
</body>
</html>

500
templates/bootscreen.html Normal file
View File

@@ -0,0 +1,500 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>BIOS — {{ title }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=VT323&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #000000; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: #000000;
color: #aaaaaa;
font-family: "Share Tech Mono", "VT323", "Courier New", monospace;
font-size: 14px;
line-height: 1.45;
min-height: 100vh;
overflow-x: hidden;
}
.screen {
max-width: 800px;
margin: 0 auto;
padding: 16px 20px 60px;
}
/* BIOS header */
.bios-header {
background: #0000aa;
color: #ffffff;
padding: 8px 12px;
margin-bottom: 0;
display: flex;
justify-content: space-between;
}
.bios-header-title {
font-family: "VT323", monospace;
font-size: 18px;
letter-spacing: 0.05em;
}
.bios-header-version {
font-size: 13px;
color: #ffff55;
}
/* Memory test area */
.bios-memory {
background: #000;
color: #aaa;
padding: 8px 12px;
margin-bottom: 8px;
}
.bios-memory-bar {
height: 14px;
background: #0000aa;
margin: 4px 0;
position: relative;
overflow: hidden;
}
.bios-memory-fill {
height: 100%;
background: #aaaaaa;
width: 0%;
animation: memtest 2.5s ease-in-out forwards;
}
@keyframes memtest {
0% { width: 0%; }
100% { width: 100%; }
}
.bios-memory-label {
font-size: 12px;
color: #aaa;
}
.ok {
color: #55ff55;
font-weight: 700;
}
.fail {
color: #ff5555;
}
.warn {
color: #ffff55;
}
/* Boot sequence */
.boot-sequence {
padding: 8px 0;
margin-bottom: 12px;
}
.boot-line {
display: flex;
gap: 8px;
margin-bottom: 2px;
font-size: 13px;
}
.boot-timestamp {
color: #555;
flex-shrink: 0;
width: 60px;
}
.boot-source {
color: #0087ff;
flex-shrink: 0;
width: 120px;
}
.boot-msg {
color: #aaaaaa;
flex: 1;
}
.boot-status-ok { color: #55ff55; }
.boot-status-warn { color: #ffff55; }
/* Separator */
.separator {
color: #333;
font-size: 13px;
margin: 6px 0;
letter-spacing: 0.02em;
}
/* Main content — article is the boot log continuation */
.article-header {
background: #0000aa;
color: #fff;
padding: 6px 12px;
margin: 16px 0 0;
display: flex;
justify-content: space-between;
}
.article-header-title {
font-family: "VT323", monospace;
font-size: 18px;
}
.article-header-meta {
font-size: 12px;
color: #55ffff;
}
.article-meta-line {
background: #000080;
color: #ffff55;
padding: 4px 12px;
font-size: 12px;
display: flex;
gap: 24px;
flex-wrap: wrap;
}
.content-area {
padding: 14px 12px;
border: 1px solid #333;
margin-bottom: 16px;
}
.content-area h1 {
font-family: "VT323", monospace;
font-size: 22px;
color: #ffff55;
margin-top: 20px;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.content-area h1::before {
content: ">> ";
color: #55ff55;
}
.content-area h2 {
font-family: "VT323", monospace;
font-size: 18px;
color: #55ffff;
margin-top: 16px;
margin-bottom: 6px;
text-transform: uppercase;
}
.content-area h2::before {
content: "> ";
color: #555;
}
.content-area h3 {
font-size: 14px;
color: #ff5555;
margin-top: 14px;
margin-bottom: 5px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
color: #aaaaaa;
margin-top: 10px;
margin-bottom: 4px;
}
.content-area p {
color: #cccccc;
margin-bottom: 10px;
line-height: 1.55;
}
.content-area a {
color: #55ffff;
text-decoration: underline;
}
.content-area code {
color: #ffff55;
background: rgba(255,255,0,0.07);
padding: 1px 4px;
border: 1px solid rgba(255,255,0,0.2);
}
.content-area pre {
background: #0a0a0a;
border: 1px solid #333;
padding: 10px 12px;
margin: 10px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: #55ff55;
}
.content-area blockquote {
border-left: 2px solid #0000aa;
padding: 6px 12px;
margin: 10px 0;
background: rgba(0,0,170,0.1);
color: #55ffff;
}
.content-area blockquote p {
color: #55ffff;
}
.content-area ul {
margin: 6px 0 10px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 20px;
margin-bottom: 3px;
color: #cccccc;
position: relative;
}
.content-area ul li::before {
content: "*";
position: absolute;
left: 6px;
color: #55ff55;
}
.content-area ol {
margin: 6px 0 10px 0;
list-style: none;
padding: 0;
counter-reset: bios-list;
}
.content-area ol li {
counter-increment: bios-list;
padding-left: 28px;
margin-bottom: 3px;
color: #cccccc;
position: relative;
}
.content-area ol li::before {
content: "[" counter(bios-list) "]";
position: absolute;
left: 0;
color: #ffff55;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 10px 0;
font-size: 12px;
}
.content-area th {
background: #0000aa;
color: #fff;
padding: 5px 10px;
text-align: left;
font-size: 11px;
text-transform: uppercase;
}
.content-area td {
padding: 5px 10px;
border: 1px solid #333;
color: #aaaaaa;
}
.content-area img {
max-width: 100%;
filter: grayscale(100%) contrast(1.2);
border: 1px solid #555;
margin: 8px 0;
}
.content-area hr {
border: none;
border-top: 1px solid #333;
margin: 14px 0;
}
/* Tags */
.bios-tags {
background: #001100;
border: 1px solid #333;
padding: 6px 12px;
font-size: 12px;
color: #55ff55;
margin-bottom: 8px;
}
/* Footer bar */
.bios-footer {
background: #0000aa;
color: #fff;
padding: 5px 12px;
display: flex;
justify-content: space-between;
font-size: 12px;
flex-wrap: wrap;
gap: 8px;
}
.bios-key {
background: #aaa;
color: #000;
padding: 1px 5px;
font-size: 11px;
margin-right: 4px;
}
/* Blinking cursor */
.cursor {
display: inline-block;
width: 8px;
height: 14px;
background: #aaaaaa;
vertical-align: middle;
animation: blink 1s step-end infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="screen">
<div class="bios-header">
<div class="bios-header-title">Felix's Blatt Server v2026.04 — BIOS Setup</div>
<div class="bios-header-version">Build {{ published_date | replace("-", "") }}</div>
</div>
<div class="bios-memory">
<div class="bios-memory-label">Memory Test:</div>
<div class="bios-memory-bar"><div class="bios-memory-fill"></div></div>
<div>640 KB Base Memory <span class="ok">OK</span></div>
<div>65536 KB Extended Memory <span class="ok">OK</span></div>
</div>
<div class="separator">────────────────────────────────────────────────────────────────────────────────</div>
<div class="boot-sequence">
<div class="boot-line">
<span class="boot-timestamp">[0.000000]</span>
<span class="boot-source">KERNEL:</span>
<span class="boot-msg">Initializing Blatt content server</span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.001234]</span>
<span class="boot-source">MARKDOWN:</span>
<span class="boot-msg">Parser loaded, CommonMark extensions enabled <span class="boot-status-ok">[OK]</span></span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.002841]</span>
<span class="boot-source">KATEX:</span>
<span class="boot-msg">Math renderer initialized <span class="boot-status-ok">[OK]</span></span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.004100]</span>
<span class="boot-source">TEMPLATE:</span>
<span class="boot-msg">Loading bootscreen.html <span class="boot-status-ok">[OK]</span></span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.005500]</span>
<span class="boot-source">NUNJUCKS:</span>
<span class="boot-msg">Template engine ready <span class="boot-status-ok">[OK]</span></span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.007200]</span>
<span class="boot-source">CONTENT:</span>
<span class="boot-msg">Loading post: {{ title }}</span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.008100]</span>
<span class="boot-source">META:</span>
<span class="boot-msg">author={{ config.site.author }} date={{ published_date }} read={{ reading_time }}</span>
</div>
{% if taxonomy.tags %}
<div class="boot-line">
<span class="boot-timestamp">[0.008500]</span>
<span class="boot-source">TAGS:</span>
<span class="boot-msg">{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}</span>
</div>
{% endif %}
<div class="boot-line">
<span class="boot-timestamp">[0.009800]</span>
<span class="boot-source">RENDER:</span>
<span class="boot-msg">Content rendered to HTML <span class="boot-status-ok">[OK]</span></span>
</div>
<div class="boot-line">
<span class="boot-timestamp">[0.010200]</span>
<span class="boot-source">SYSTEM:</span>
<span class="boot-msg">Boot complete. Serving content.</span>
</div>
</div>
<div class="separator">────────────────────────────────────────────────────────────────────────────────</div>
<div class="article-header">
<div class="article-header-title">{{ title }}</div>
<div class="article-header-meta">{{ published_date }}</div>
</div>
<div class="article-meta-line">
<span>AUTHOR: {{ config.site.author }}</span>
<span>DATE: {{ published_date }}</span>
<span>READ: {{ reading_time }}</span>
{% if updated_date %}<span>UPDATED: {{ updated_date }}</span>{% endif %}
</div>
{% if taxonomy.tags %}
<div class="bios-tags">
TAGS: {% for tag in taxonomy.tags %}[{{ tag }}]{% if not loop.last %} {% endif %}{% endfor %}
</div>
{% endif %}
<div class="content-area">
{{ content | safe }}
<div style="margin-top: 16px; color: #555;">
<span class="cursor"></span>
</div>
</div>
<div class="bios-footer">
<span><span class="bios-key">F1</span> Help <span class="bios-key">F5</span> Defaults <span class="bios-key">F10</span> Save</span>
<span>{{ config.site.name }} · {{ config.site.author }}</span>
<span>Press <span class="bios-key">F12</span> for boot menu</span>
</div>
</div>
</body>
</html>

408
templates/cafe-menu.html Normal file
View File

@@ -0,0 +1,408 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;600;700&family=Shadows+Into+Light&family=Special+Elite&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #3d2a14; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--cream: #f5edd8;
--parchment: #efe4c8;
--parchment-dark: #e0d0a8;
--brown-dark: #3d2010;
--brown: #6b3a1f;
--brown-mid: #8b5e3c;
--brown-light: #c49a6c;
--brown-faint: rgba(107,58,31,0.12);
--ink: #2a1508;
}
body {
background: #3d2a14;
background-image:
radial-gradient(ellipse at 30% 20%, rgba(100,60,20,0.4) 0%, transparent 60%),
radial-gradient(ellipse at 70% 80%, rgba(60,30,10,0.5) 0%, transparent 60%);
color: var(--ink);
font-family: "Caveat", cursive;
font-size: 18px;
line-height: 1.65;
min-height: 100vh;
padding: 32px 16px 48px;
}
.menu-card {
max-width: 760px;
margin: 0 auto;
background: var(--cream);
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 28px,
rgba(107,58,31,0.04) 28px,
rgba(107,58,31,0.04) 29px
);
padding: 0;
position: relative;
}
/* Ornamental outer border */
.menu-border {
border: 3px solid var(--brown);
padding: 8px;
}
.menu-inner-border {
border: 1px solid var(--brown-light);
padding: 32px 40px 40px;
}
/* Corner ornaments using CSS */
.corner-ornament {
position: absolute;
width: 40px;
height: 40px;
font-size: 28px;
color: var(--brown-light);
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.corner-ornament.tl { top: 4px; left: 4px; }
.corner-ornament.tr { top: 4px; right: 4px; }
.corner-ornament.bl { bottom: 4px; left: 4px; }
.corner-ornament.br { bottom: 4px; right: 4px; }
/* Masthead */
.menu-header {
text-align: center;
margin-bottom: 24px;
padding-bottom: 20px;
}
.cafe-name {
font-family: "Shadows Into Light", cursive;
font-size: clamp(26px, 5vw, 52px);
color: var(--brown-dark);
line-height: 1.1;
letter-spacing: 0.04em;
margin-bottom: 6px;
}
.cafe-subtitle {
font-size: 15px;
color: var(--brown-mid);
letter-spacing: 0.12em;
font-family: "Special Elite", cursive;
}
.ornamental-divider {
text-align: center;
font-size: 20px;
color: var(--brown-light);
margin: 16px 0;
letter-spacing: 0.2em;
}
.ornamental-divider-sm {
text-align: center;
font-size: 16px;
color: var(--brown-light);
margin: 12px 0;
letter-spacing: 0.15em;
}
/* Title section */
.item-title-section {
text-align: center;
margin-bottom: 20px;
padding: 16px 0;
background: var(--parchment);
border-top: 1px solid var(--brown-light);
border-bottom: 1px solid var(--brown-light);
position: relative;
}
.item-title-section::before,
.item-title-section::after {
content: "~";
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 24px;
color: var(--brown-light);
}
.item-title-section::before { left: 20px; }
.item-title-section::after { right: 20px; }
.item-title {
font-family: "Shadows Into Light", cursive;
font-size: clamp(22px, 4vw, 40px);
color: var(--brown-dark);
line-height: 1.2;
letter-spacing: 0.02em;
}
/* Meta row */
.meta-row {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 16px 32px;
font-size: 15px;
color: var(--brown-mid);
padding: 10px 0 16px;
font-family: "Special Elite", cursive;
}
.meta-row .bean {
color: var(--brown-light);
}
/* Tags */
.tag-row {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
margin-bottom: 20px;
}
.tag {
font-size: 14px;
color: var(--brown);
padding: 2px 12px;
border: 1px solid var(--brown-light);
border-radius: 2px;
font-family: "Special Elite", cursive;
background: var(--parchment);
}
/* Content */
.content-area {
margin-top: 8px;
}
.content-area h1 {
font-family: "Shadows Into Light", cursive;
font-size: 32px;
color: var(--brown-dark);
margin-top: 32px;
margin-bottom: 12px;
text-align: center;
border-bottom: 1px dashed var(--brown-light);
padding-bottom: 8px;
}
.content-area h2 {
font-size: 26px;
color: var(--brown);
margin-top: 28px;
margin-bottom: 10px;
text-align: center;
}
.content-area h3 {
font-size: 22px;
color: var(--brown-mid);
margin-top: 20px;
margin-bottom: 8px;
}
.content-area p {
margin-bottom: 14px;
color: var(--brown-dark);
}
.content-area a {
color: var(--brown);
text-decoration: underline;
text-decoration-style: dotted;
}
.content-area code {
font-family: "Special Elite", cursive;
font-size: 16px;
background: var(--parchment);
padding: 0 5px;
border: 1px dashed var(--brown-light);
color: var(--brown);
}
.content-area pre {
background: var(--parchment-dark);
border: 1px solid var(--brown-light);
border-left: 3px solid var(--brown);
padding: 16px 18px;
margin: 16px 0;
overflow-x: auto;
font-family: "Special Elite", cursive;
font-size: 14px;
line-height: 1.7;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: var(--brown-dark);
}
.content-area blockquote {
border-top: 1px dashed var(--brown-light);
border-bottom: 1px dashed var(--brown-light);
padding: 12px 8px;
margin: 18px 0;
text-align: center;
font-size: 20px;
font-style: italic;
color: var(--brown-mid);
}
.content-area ul {
margin: 12px 0 16px 0;
list-style: none;
padding: 0;
}
.content-area ul li::before {
content: "(o) ";
color: var(--brown-light);
}
.content-area ol {
margin: 12px 0 16px 20px;
}
.content-area ol li::marker {
color: var(--brown-mid);
}
.content-area li {
margin-bottom: 6px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
}
.content-area th {
border-bottom: 2px solid var(--brown);
padding: 7px 10px;
text-align: left;
color: var(--brown-dark);
font-size: 16px;
}
.content-area td {
border-bottom: 1px dashed var(--brown-light);
padding: 7px 10px;
}
.content-area img {
max-width: 100%;
display: block;
margin: 16px auto;
border: 2px solid var(--brown-light);
}
.content-area hr {
border: none;
text-align: center;
margin: 24px 0;
color: var(--brown-light);
font-size: 20px;
letter-spacing: 0.3em;
}
.content-area hr::after {
content: "* * *";
}
/* Footer */
.menu-footer {
margin-top: 32px;
padding-top: 16px;
border-top: 1px solid var(--brown-light);
text-align: center;
font-family: "Special Elite", cursive;
font-size: 13px;
color: var(--brown-mid);
letter-spacing: 0.08em;
line-height: 2;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="menu-card">
<div class="corner-ornament tl">*</div>
<div class="corner-ornament tr">*</div>
<div class="corner-ornament bl">*</div>
<div class="corner-ornament br">*</div>
<div class="menu-border">
<div class="menu-inner-border">
<header class="menu-header">
<div class="cafe-name">{{ config.site.name }}</div>
<div class="cafe-subtitle">Est. by {{ config.site.author }}</div>
<div class="ornamental-divider">~ * ~</div>
</header>
<div class="item-title-section">
<h1 class="item-title">{{ title }}</h1>
</div>
<div class="meta-row">
<span>{{ published_date }}</span>
<span class="bean">*</span>
<span>{{ reading_time }}</span>
{% if updated_date %}
<span class="bean">*</span>
<span>Updated {{ updated_date }}</span>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="tag-row">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
<div class="ornamental-divider-sm">- - - - - -</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="ornamental-divider">~ * ~</div>
<footer class="menu-footer">
<div>{{ config.site.name }}</div>
<div>{{ config.site.author }} | {{ published_date }}</div>
</footer>
</div>
</div>
</div>
</body>
</html>

389
templates/chalkboard.html Normal file
View File

@@ -0,0 +1,389 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;600;700&family=Caveat+Brush&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #243d24; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--board: #2d4a2d;
--board-dark: #243d24;
--chalk-white: #f0ede8;
--chalk-dim: rgba(240,237,232,0.6);
--chalk-faint: rgba(240,237,232,0.3);
--chalk-yellow: #f5e642;
--chalk-blue: #7ec8e3;
--chalk-pink: #f5a0b0;
--chalk-orange: #f5b042;
--eraser: rgba(240,237,232,0.04);
}
body {
background: var(--board-dark);
color: var(--chalk-white);
font-family: "Caveat", cursive;
font-size: 20px;
line-height: 1.7;
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
/* SVG noise texture overlay for chalk dust */
body::before {
content: "";
position: fixed;
inset: 0;
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 0;
opacity: 0.6;
}
/* Chalkboard rail at bottom */
body::after {
content: "";
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 32px;
background: linear-gradient(to bottom, #3d2a1a, #2a1c0e);
border-top: 4px solid #5a3d28;
z-index: 100;
}
/* Fake eraser smudges */
.eraser-marks {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
overflow: hidden;
}
.eraser-mark {
position: absolute;
border-radius: 50%;
background: var(--eraser);
filter: blur(20px);
}
.board {
position: relative;
z-index: 2;
max-width: 920px;
margin: 0 auto;
padding: 40px 48px 80px;
}
/* Board edge lines */
.board-frame {
border: 2px solid rgba(240,237,232,0.12);
padding: 32px 40px 48px;
position: relative;
}
.board-frame::before,
.board-frame::after {
content: "";
position: absolute;
background: rgba(240,237,232,0.08);
}
.board-frame::before {
top: 6px;
left: 6px;
right: 6px;
bottom: 6px;
border: 1px solid rgba(240,237,232,0.07);
}
/* Header / lecture heading */
.lecture-header {
text-align: center;
margin-bottom: 32px;
padding-bottom: 24px;
border-bottom: 2px solid var(--chalk-dim);
position: relative;
}
.lecture-header::after {
content: "";
position: absolute;
bottom: -6px;
left: 10%;
right: 10%;
border-bottom: 1px solid var(--chalk-faint);
}
.course-label {
font-size: 15px;
color: var(--chalk-dim);
letter-spacing: 0.15em;
text-transform: uppercase;
margin-bottom: 8px;
}
.lecture-title {
font-family: "Caveat Brush", cursive;
font-size: clamp(28px, 5vw, 52px);
color: var(--chalk-white);
text-shadow:
1px 1px 0 rgba(255,255,255,0.1),
0 0 20px rgba(240,237,232,0.15),
2px 2px 4px rgba(0,0,0,0.4);
line-height: 1.1;
letter-spacing: 0.01em;
}
.lecture-meta {
display: flex;
justify-content: center;
gap: 32px;
margin-top: 16px;
font-size: 16px;
color: var(--chalk-dim);
}
.lecture-meta .chalk-yellow { color: var(--chalk-yellow); }
/* Chalk line divider */
.chalk-divider {
text-align: center;
margin: 28px 0;
height: 2px;
background: linear-gradient(
to right,
transparent 0%,
var(--chalk-dim) 15%,
var(--chalk-white) 40%,
var(--chalk-white) 60%,
var(--chalk-dim) 85%,
transparent 100%
);
position: relative;
}
/* Content */
.content-area {
margin-top: 32px;
}
.content-area h1 {
font-family: "Caveat Brush", cursive;
font-size: 36px;
color: var(--chalk-yellow);
text-shadow: 0 0 12px rgba(245,230,66,0.3), 1px 1px 2px rgba(0,0,0,0.5);
margin-top: 40px;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid rgba(245,230,66,0.3);
letter-spacing: 0.01em;
}
.content-area h2 {
font-size: 28px;
color: var(--chalk-blue);
text-shadow: 0 0 10px rgba(126,200,227,0.3), 1px 1px 2px rgba(0,0,0,0.5);
margin-top: 32px;
margin-bottom: 12px;
}
.content-area h3 {
font-size: 24px;
color: var(--chalk-pink);
text-shadow: 0 0 8px rgba(245,160,176,0.3);
margin-top: 24px;
margin-bottom: 10px;
}
.content-area p {
margin-bottom: 18px;
text-shadow: 0 0 1px rgba(240,237,232,0.3), 1px 1px 1px rgba(0,0,0,0.3);
}
.content-area a {
color: var(--chalk-blue);
text-decoration: underline;
text-decoration-style: dotted;
text-shadow: 0 0 6px rgba(126,200,227,0.3);
}
.content-area code {
font-family: "Courier New", monospace;
font-size: 16px;
color: var(--chalk-orange);
background: rgba(245,176,66,0.08);
padding: 1px 6px;
border: 1px solid rgba(245,176,66,0.2);
border-radius: 2px;
}
.content-area pre {
background: rgba(0,0,0,0.25);
border: 1px solid var(--chalk-faint);
border-left: 3px solid var(--chalk-orange);
padding: 20px 22px;
margin: 20px 0;
overflow-x: auto;
font-family: "Courier New", monospace;
font-size: 15px;
line-height: 1.7;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: var(--chalk-white);
}
.content-area blockquote {
border-left: 3px solid var(--chalk-yellow);
padding: 12px 20px;
margin: 20px 0;
background: rgba(245,230,66,0.04);
font-style: italic;
color: var(--chalk-yellow);
text-shadow: 0 0 8px rgba(245,230,66,0.2);
}
.content-area ul,
.content-area ol {
margin: 14px 0 18px 8px;
list-style: none;
padding: 0;
}
.content-area ul li::before {
content: "- ";
color: var(--chalk-dim);
}
.content-area ol {
counter-reset: chalkitem;
}
.content-area ol li {
counter-increment: chalkitem;
}
.content-area ol li::before {
content: counter(chalkitem) ". ";
color: var(--chalk-yellow);
}
.content-area li {
margin-bottom: 6px;
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.content-area th {
border-bottom: 2px solid var(--chalk-dim);
padding: 8px 12px;
text-align: left;
color: var(--chalk-yellow);
font-size: 18px;
}
.content-area td {
border-bottom: 1px solid var(--chalk-faint);
padding: 8px 12px;
}
.content-area img {
max-width: 100%;
border: 1px solid var(--chalk-faint);
display: block;
margin: 24px auto;
}
.content-area hr {
border: none;
margin: 28px 0;
height: 1px;
background: linear-gradient(to right, transparent, var(--chalk-faint), transparent);
}
/* KaTeX math — make it readable on dark board */
.content-area .katex {
color: var(--chalk-white);
font-size: 1.1em;
}
.content-area .katex-display {
padding: 16px 0;
color: var(--chalk-yellow);
}
.footer-chalk {
margin-top: 48px;
padding-top: 20px;
border-top: 1px solid var(--chalk-faint);
display: flex;
justify-content: space-between;
font-size: 16px;
color: var(--chalk-dim);
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="eraser-marks">
<div class="eraser-mark" style="width:300px;height:200px;top:15%;left:5%;"></div>
<div class="eraser-mark" style="width:200px;height:150px;top:60%;right:8%;"></div>
<div class="eraser-mark" style="width:250px;height:180px;top:80%;left:30%;"></div>
<div class="eraser-mark" style="width:180px;height:100px;top:35%;right:20%;"></div>
</div>
<div class="board">
<div class="board-frame">
<header class="lecture-header">
<div class="course-label">{{ config.site.name }} — {{ config.site.author }}</div>
<div class="lecture-title">{{ title }}</div>
<div class="lecture-meta">
<span>{{ published_date }}</span>
<span class="chalk-yellow">{{ reading_time }}</span>
{% if taxonomy.tags %}
<span>
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}
</span>
{% endif %}
</div>
</header>
<div class="chalk-divider"></div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="footer-chalk">
<span>{{ config.site.name }}</span>
<span>{{ published_date }}</span>
</div>
</div>
</div>
</body>
</html>

312
templates/collection.html Normal file
View File

@@ -0,0 +1,312 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }}</title>
{{ meta_tags | safe }}
<link rel="preload" href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-300-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-500-normal.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Iosevka';
font-style: normal;
font-weight: 300;
font-display: block;
src: url(https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-300-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Iosevka';
font-style: normal;
font-weight: 400;
font-display: block;
src: url(https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-400-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Iosevka';
font-style: normal;
font-weight: 500;
font-display: block;
src: url(https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-500-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Iosevka';
font-style: normal;
font-weight: 600;
font-display: block;
src: url(https://cdn.jsdelivr.net/npm/@fontsource/iosevka@latest/files/iosevka-latin-600-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
</style>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
background: #060d1a;
}
body {
font-family: 'Iosevka', monospace;
color: #f0ece4;
min-height: 100vh;
overflow-x: hidden;
padding-top: env(safe-area-inset-top);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
#vanta-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.page-content {
position: relative;
z-index: 1;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.hero {
padding: calc(6rem + env(safe-area-inset-top, 0px)) 2rem 3rem;
text-align: center;
}
.hero h1 {
font-family: 'Iosevka', monospace;
font-size: clamp(2.5rem, 7vw, 4.5rem);
font-weight: 300;
letter-spacing: -0.02em;
line-height: 1.1;
color: #ffffff;
text-shadow: 0 2px 40px rgba(0, 0, 0, 0.3);
}
{% if description %}
.hero p {
font-size: 1.1rem;
color: rgba(240, 236, 228, 0.7);
margin-top: 1rem;
font-weight: 300;
letter-spacing: 0.02em;
}
{% endif %}
{% if draft_banner %}
.draft-notice {
display: inline-block;
background: rgba(245, 158, 11, 0.2);
border: 1px solid rgba(245, 158, 11, 0.4);
color: #fbbf24;
padding: 0.3em 0.8em;
border-radius: 4px;
font-size: 0.8rem;
margin-top: 1rem;
backdrop-filter: blur(8px);
}
{% endif %}
.posts-container {
flex: 1;
max-width: 680px;
width: 100%;
margin: 0 auto;
padding: 0 1.5rem 4rem;
}
.post-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 1px;
}
.post-item {
display: block;
text-decoration: none;
color: inherit;
padding: 1.25rem 1.5rem;
background: rgba(0, 0, 0, 0.25);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 8px;
margin-bottom: 0.5rem;
transition: background 0.25s ease, transform 0.2s ease, border-color 0.25s ease;
}
.post-item:hover {
background: rgba(0, 0, 0, 0.4);
transform: translateY(-1px);
border-color: rgba(255, 255, 255, 0.12);
}
.post-header {
display: flex;
align-items: baseline;
gap: 0.75rem;
flex-wrap: wrap;
}
.post-title {
font-family: 'Iosevka', monospace;
font-size: 1.2rem;
font-weight: 500;
color: #ffffff;
line-height: 1.3;
}
.draft-tag {
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #fbbf24;
background: rgba(245, 158, 11, 0.15);
border: 1px solid rgba(245, 158, 11, 0.3);
padding: 0.15em 0.5em;
border-radius: 3px;
font-family: 'Iosevka', monospace;
font-weight: 500;
}
.post-date {
font-size: 0.8rem;
color: rgba(240, 236, 228, 0.4);
margin-top: 0.3rem;
font-weight: 300;
font-variant-numeric: tabular-nums;
}
.post-description {
font-size: 0.9rem;
color: rgba(240, 236, 228, 0.6);
margin-top: 0.4rem;
line-height: 1.5;
font-weight: 300;
}
.empty-state {
text-align: center;
padding: 3rem;
color: rgba(240, 236, 228, 0.4);
font-style: italic;
}
.site-footer {
position: relative;
z-index: 1;
text-align: center;
padding: 2rem 2rem calc(2rem + env(safe-area-inset-bottom, 0px));
font-size: 0.75rem;
color: rgba(240, 236, 228, 0.25);
}
.site-footer a {
color: rgba(240, 236, 228, 0.35);
text-decoration: none;
}
{% if content %}
.page-body {
max-width: 680px;
width: 100%;
margin: 0 auto 2rem;
padding: 0 1.5rem;
color: rgba(240, 236, 228, 0.7);
line-height: 1.7;
}
.page-body a { color: #93c5fd; }
{% endif %}
@media (max-width: 600px) {
.hero { padding: calc(3rem + env(safe-area-inset-top, 0px)) 1.5rem 2rem; }
.posts-container { padding-left: calc(1rem + env(safe-area-inset-left, 0px)); padding-right: calc(1rem + env(safe-area-inset-right, 0px)); }
.post-item { padding: 1rem 1.25rem; }
.post-title { font-size: 1.05rem; }
}
</style>
</head>
<body>
<div id="vanta-bg"></div>
<div class="page-content">
<header class="hero">
<h1>{{ title }}</h1>
{% if description %}
<p>{{ description }}</p>
{% endif %}
{% if draft_banner %}
<div class="draft-notice">Draft — not published</div>
{% endif %}
</header>
{% if content %}
<div class="page-body">
{{ content | safe }}
</div>
{% endif %}
<div class="posts-container">
<ul class="post-list">
{% for p in pages %}
<li>
<a href="{{ p.slug }}{{ preview_query }}" class="post-item">
<div class="post-header">
<span class="post-title">{{ p.title }}</span>
{% if p.draft %}
<span class="draft-tag">draft</span>
{% endif %}
</div>
{% if p.published_date %}
<div class="post-date">
<time datetime="{{ p.published_date }}">{{ p.published_date }}</time>
</div>
{% endif %}
{% if p.description %}
<p class="post-description">{{ p.description }}</p>
{% endif %}
</a>
</li>
{% else %}
<li class="empty-state">No pages found.</li>
{% endfor %}
</ul>
</div>
<footer class="site-footer">
Powered by <a href="https://github.com/felixfoertsch/blatt">Blatt</a>
</footer>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.waves.min.js"></script>
<script>
VANTA.WAVES({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.0,
minWidth: 200.0,
scale: 1.0,
scaleMobile: 1.0,
color: 0x0a1628,
shininess: 35.0,
waveHeight: 20.0,
waveSpeed: 0.7,
zoom: 0.85
});
</script>
</body>
</html>

View File

@@ -0,0 +1,486 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,300;0,400;0,500;0,700;1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #f9f9fb; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #f9f9fb;
--surface: #ffffff;
--text: #111118;
--muted: #555560;
--dim: #9898a8;
--border: #e4e4ec;
}
body {
background: var(--bg);
color: var(--text);
font-family: "DM Sans", system-ui, sans-serif;
font-size: 14px;
line-height: 1.5;
min-height: 100vh;
}
/* Top bar */
.topbar {
border-bottom: 1px solid var(--border);
background: var(--surface);
padding: 0 32px;
height: 52px;
display: flex;
align-items: center;
justify-content: space-between;
}
.topbar-left {
display: flex;
align-items: center;
gap: 20px;
}
.topbar-brand {
font-weight: 700;
font-size: 15px;
color: var(--text);
letter-spacing: -0.02em;
}
.topbar-nav {
display: flex;
gap: 2px;
}
.topbar-nav-item {
font-size: 13px;
font-weight: 500;
color: var(--dim);
padding: 4px 10px;
border-radius: 6px;
}
.topbar-nav-item.active {
background: #f0f0f8;
color: var(--text);
}
.topbar-right {
font-size: 12px;
color: var(--dim);
}
/* Color strip */
.color-strip {
display: flex;
height: 80px;
}
.color-strip-swatch {
flex: 1;
position: relative;
cursor: default;
transition: flex 0.2s ease;
}
.color-strip-swatch:hover {
flex: 2;
}
.color-strip-hex {
position: absolute;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
font-family: "DM Mono", monospace;
font-size: 9px;
font-weight: 500;
background: rgba(0,0,0,0.4);
color: #fff;
padding: 2px 6px;
border-radius: 3px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.15s;
}
.color-strip-swatch:hover .color-strip-hex {
opacity: 1;
}
/* Page */
.page {
max-width: 960px;
margin: 0 auto;
padding: 32px 32px 64px;
}
/* Page header */
.page-header {
margin-bottom: 32px;
}
.page-title {
font-size: 28px;
font-weight: 700;
letter-spacing: -0.03em;
color: var(--text);
margin-bottom: 10px;
}
.page-meta {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.meta-badge {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 12px;
font-weight: 500;
color: var(--muted);
background: var(--border);
padding: 3px 10px;
border-radius: 6px;
}
.meta-dot {
width: 8px;
height: 8px;
border-radius: 2px;
}
/* Swatch cards grid */
.swatch-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 12px;
margin-bottom: 32px;
}
.swatch-card {
border-radius: 12px;
overflow: hidden;
background: var(--surface);
border: 1px solid var(--border);
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.swatch-color {
height: 72px;
}
.swatch-info {
padding: 8px 10px;
}
.swatch-name {
font-size: 11px;
font-weight: 600;
color: var(--text);
margin-bottom: 2px;
}
.swatch-hex {
font-family: "DM Mono", monospace;
font-size: 10px;
color: var(--dim);
}
/* Content */
.content-section-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--dim);
border-bottom: 1px solid var(--border);
padding-bottom: 8px;
margin-bottom: 20px;
}
.content-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 28px 32px;
margin-bottom: 16px;
}
.content-area h1 {
font-size: 22px;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h2 {
font-size: 17px;
font-weight: 700;
color: var(--text);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h3 {
font-size: 14px;
font-weight: 700;
color: var(--text);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
font-weight: 600;
color: var(--muted);
margin-top: 14px;
margin-bottom: 4px;
}
.content-area p {
font-size: 14px;
color: var(--muted);
margin-bottom: 12px;
line-height: 1.65;
}
.content-area a {
color: #5b4fcf;
text-decoration: none;
font-weight: 500;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "DM Mono", monospace;
font-size: 12px;
background: #f3f3f8;
color: #5b4fcf;
padding: 2px 6px;
border-radius: 5px;
}
.content-area pre {
background: #18181f;
border-radius: 10px;
padding: 16px 18px;
margin: 14px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: #e0e0f0;
padding: 0;
font-size: 13px;
}
.content-area blockquote {
border-left: 3px solid #5b4fcf;
background: rgba(91,79,207,0.04);
border-radius: 0 8px 8px 0;
padding: 12px 16px;
margin: 14px 0;
}
.content-area blockquote p {
color: #5b4fcf;
font-weight: 500;
margin: 0;
}
.content-area ul {
margin: 8px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 16px;
margin-bottom: 5px;
color: var(--muted);
position: relative;
}
.content-area ul li::before {
content: "";
position: absolute;
left: 3px;
top: 7px;
width: 6px;
height: 6px;
border-radius: 2px;
background: #5b4fcf;
}
.content-area ol {
margin: 8px 0 14px 22px;
color: var(--muted);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 13px;
border-radius: 8px;
overflow: hidden;
}
.content-area th {
background: #f3f3f8;
padding: 9px 13px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--dim);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 9px 13px;
border-top: 1px solid var(--border);
color: var(--muted);
}
.content-area img {
max-width: 100%;
border-radius: 8px;
margin: 10px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 20px 0;
}
/* Tags */
.tags-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 20px;
}
.tag {
font-size: 11px;
font-weight: 600;
color: #5b4fcf;
background: rgba(91,79,207,0.08);
padding: 3px 10px;
border-radius: 6px;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="topbar">
<div class="topbar-left">
<div class="topbar-brand">{{ config.site.name }}</div>
<nav class="topbar-nav">
<div class="topbar-nav-item">Palettes</div>
<div class="topbar-nav-item active">Articles</div>
<div class="topbar-nav-item">Swatches</div>
</nav>
</div>
<div class="topbar-right">{{ published_date }} · {{ reading_time }}</div>
</div>
<!-- Decorative color strip -->
<div class="color-strip">
<div class="color-strip-swatch" style="background:#ef4444"><span class="color-strip-hex">#ef4444</span></div>
<div class="color-strip-swatch" style="background:#f97316"><span class="color-strip-hex">#f97316</span></div>
<div class="color-strip-swatch" style="background:#eab308"><span class="color-strip-hex">#eab308</span></div>
<div class="color-strip-swatch" style="background:#84cc16"><span class="color-strip-hex">#84cc16</span></div>
<div class="color-strip-swatch" style="background:#22c55e"><span class="color-strip-hex">#22c55e</span></div>
<div class="color-strip-swatch" style="background:#14b8a6"><span class="color-strip-hex">#14b8a6</span></div>
<div class="color-strip-swatch" style="background:#3b82f6"><span class="color-strip-hex">#3b82f6</span></div>
<div class="color-strip-swatch" style="background:#6366f1"><span class="color-strip-hex">#6366f1</span></div>
<div class="color-strip-swatch" style="background:#a855f7"><span class="color-strip-hex">#a855f7</span></div>
<div class="color-strip-swatch" style="background:#ec4899"><span class="color-strip-hex">#ec4899</span></div>
</div>
<div class="page">
<div class="page-header">
<h1 class="page-title">{{ title }}</h1>
<div class="page-meta">
<div class="meta-badge">
<div class="meta-dot" style="background: #5b4fcf;"></div>
{{ config.site.author }}
</div>
<div class="meta-badge">
<div class="meta-dot" style="background: #22c55e;"></div>
{{ published_date }}
</div>
<div class="meta-badge">
<div class="meta-dot" style="background: #f97316;"></div>
{{ reading_time }}
</div>
{% if updated_date %}
<div class="meta-badge">
<div class="meta-dot" style="background: #14b8a6;"></div>
Updated {{ updated_date }}
</div>
{% endif %}
</div>
</div>
<!-- Decorative swatch grid -->
<div class="swatch-grid">
<div class="swatch-card"><div class="swatch-color" style="background:#ef4444"></div><div class="swatch-info"><div class="swatch-name">Red 500</div><div class="swatch-hex">#ef4444</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#f97316"></div><div class="swatch-info"><div class="swatch-name">Orange 500</div><div class="swatch-hex">#f97316</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#eab308"></div><div class="swatch-info"><div class="swatch-name">Yellow 500</div><div class="swatch-hex">#eab308</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#22c55e"></div><div class="swatch-info"><div class="swatch-name">Green 500</div><div class="swatch-hex">#22c55e</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#3b82f6"></div><div class="swatch-info"><div class="swatch-name">Blue 500</div><div class="swatch-hex">#3b82f6</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#a855f7"></div><div class="swatch-info"><div class="swatch-name">Purple 500</div><div class="swatch-hex">#a855f7</div></div></div>
<div class="swatch-card"><div class="swatch-color" style="background:#ec4899"></div><div class="swatch-info"><div class="swatch-name">Pink 500</div><div class="swatch-hex">#ec4899</div></div></div>
</div>
<div class="content-section-label">Content</div>
<div class="content-card">
<div class="content-area">
{{ content | safe }}
</div>
{% if taxonomy.tags %}
<div class="tags-row">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
</div>
</body>
</html>

465
templates/conspiracy.html Normal file
View File

@@ -0,0 +1,465 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>!!! {{ title }} !!! — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Creepster&family=Fredoka+One&family=Abril+Fatface&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #000000; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: #000000;
color: #00ff00;
font-family: "Comic Sans MS", "Chalkboard SE", "Fredoka One", cursive;
font-size: 15px;
line-height: 1.6;
min-height: 100vh;
overflow-x: hidden;
}
/* Star field */
body::before {
content: "";
position: fixed;
inset: 0;
background:
radial-gradient(1px 1px at 10% 15%, #fff 100%, transparent),
radial-gradient(1px 1px at 25% 40%, #fff 100%, transparent),
radial-gradient(1px 1px at 40% 5%, #fff 100%, transparent),
radial-gradient(1px 1px at 55% 60%, #fff 100%, transparent),
radial-gradient(1px 1px at 70% 20%, #fff 100%, transparent),
radial-gradient(1px 1px at 85% 70%, #fff 100%, transparent),
radial-gradient(1px 1px at 15% 80%, #fff 100%, transparent),
radial-gradient(1px 1px at 30% 90%, #fff 100%, transparent),
radial-gradient(1px 1px at 60% 35%, #fff 100%, transparent),
radial-gradient(1px 1px at 78% 45%, #fff 100%, transparent),
radial-gradient(1px 1px at 92% 10%, #fff 100%, transparent),
radial-gradient(1px 1px at 5% 50%, #fff 100%, transparent),
radial-gradient(1px 1px at 45% 75%, #fff 100%, transparent),
radial-gradient(1px 1px at 65% 85%, #fff 100%, transparent),
radial-gradient(2px 2px at 20% 30%, #ffff00 100%, transparent),
radial-gradient(2px 2px at 50% 50%, #ffff00 100%, transparent),
radial-gradient(2px 2px at 80% 80%, #ffff00 100%, transparent);
pointer-events: none;
z-index: 0;
}
.page {
position: relative;
z-index: 1;
max-width: 820px;
margin: 0 auto;
padding: 20px 16px 60px;
}
/* Under construction banner */
.construction-banner {
background: #ffff00;
color: #000;
font-family: "Comic Sans MS", cursive;
font-weight: 700;
font-size: 14px;
text-align: center;
padding: 8px;
letter-spacing: 0.2em;
text-transform: uppercase;
margin-bottom: 16px;
animation: flash 0.8s step-end infinite;
border: 3px dashed #ff0000;
}
@keyframes flash {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
/* Scrolling marquee-style ticker */
.ticker-wrap {
overflow: hidden;
background: #000080;
border: 2px solid #00ffff;
padding: 6px 0;
margin-bottom: 16px;
}
.ticker-text {
display: inline-block;
white-space: nowrap;
color: #ffff00;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.05em;
animation: scroll-left 20s linear infinite;
}
@keyframes scroll-left {
from { transform: translateX(100vw); }
to { transform: translateX(-100%); }
}
/* Header */
.site-header {
text-align: center;
margin-bottom: 20px;
padding: 12px;
border: 3px double #ff00ff;
}
.site-title {
font-family: "Creepster", "Abril Fatface", cursive;
font-size: 42px;
color: #ff00ff;
text-shadow:
0 0 10px #ff00ff,
0 0 20px #ff00ff,
2px 2px 0 #000;
line-height: 1.1;
animation: glow-pink 2s ease-in-out infinite alternate;
}
@keyframes glow-pink {
from { text-shadow: 0 0 10px #ff00ff, 0 0 20px #ff00ff; }
to { text-shadow: 0 0 20px #ff00ff, 0 0 40px #ff00ff, 0 0 60px #ff00ff; }
}
.site-subtitle {
color: #00ffff;
font-size: 13px;
margin-top: 8px;
letter-spacing: 0.1em;
animation: glow-cyan 1.5s ease-in-out infinite alternate;
}
@keyframes glow-cyan {
from { color: #00ffff; }
to { color: #ff0000; }
}
/* Post meta */
.post-meta {
text-align: center;
margin-bottom: 16px;
padding: 10px;
border: 2px solid #ffff00;
background: rgba(0,0,80,0.5);
}
.post-meta-title {
font-family: "Creepster", cursive;
font-size: 28px;
color: #ffff00;
text-shadow: 0 0 8px #ffff00;
line-height: 1.2;
margin-bottom: 8px;
animation: glow-yellow 1.8s ease-in-out infinite alternate;
}
@keyframes glow-yellow {
from { text-shadow: 0 0 8px #ffff00; }
to { text-shadow: 0 0 20px #ffff00, 0 0 30px #ffff00; }
}
.post-meta-info {
color: #ff9900;
font-size: 13px;
letter-spacing: 0.06em;
}
/* Rainbow colors cycle through content elements */
.content-area h1 {
font-family: "Creepster", cursive;
font-size: 26px;
text-align: center;
text-transform: uppercase;
color: #ff0000;
text-shadow: 0 0 8px #ff0000;
margin: 24px 0 12px;
animation: rainbow 3s linear infinite;
}
@keyframes rainbow {
0% { color: #ff0000; text-shadow: 0 0 8px #ff0000; }
16% { color: #ff9900; text-shadow: 0 0 8px #ff9900; }
33% { color: #ffff00; text-shadow: 0 0 8px #ffff00; }
50% { color: #00ff00; text-shadow: 0 0 8px #00ff00; }
66% { color: #00ffff; text-shadow: 0 0 8px #00ffff; }
83% { color: #ff00ff; text-shadow: 0 0 8px #ff00ff; }
100% { color: #ff0000; text-shadow: 0 0 8px #ff0000; }
}
.content-area h2 {
font-family: "Creepster", cursive;
font-size: 22px;
color: #00ffff;
text-shadow: 0 0 6px #00ffff;
margin: 20px 0 10px;
text-transform: uppercase;
}
.content-area h3 {
font-size: 16px;
color: #ff9900;
text-shadow: 0 0 4px #ff9900;
margin: 16px 0 8px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 14px;
color: #ff00ff;
margin: 12px 0 6px;
}
.content-area p {
color: #00ff00;
margin-bottom: 14px;
text-shadow: 0 0 2px rgba(0,255,0,0.3);
}
.content-area a {
color: #ff0000;
text-decoration: underline;
font-weight: 700;
animation: link-blink 1.2s step-end infinite;
}
@keyframes link-blink {
0%, 100% { color: #ff0000; }
50% { color: #ffff00; }
}
.content-area code {
background: #000080;
color: #ffff00;
padding: 1px 5px;
font-family: "Courier New", monospace;
border: 1px solid #00ff00;
font-size: 13px;
}
.content-area pre {
background: #001a00;
border: 2px solid #00ff00;
padding: 14px;
overflow-x: auto;
margin: 14px 0;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: #00ff00;
}
.content-area blockquote {
border: 2px dashed #ff00ff;
background: rgba(255,0,255,0.05);
padding: 12px 16px;
margin: 14px 0;
color: #ff00ff;
text-shadow: 0 0 4px #ff00ff;
font-style: italic;
}
.content-area ul {
margin: 10px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
color: #ffff00;
padding-left: 22px;
margin-bottom: 5px;
position: relative;
}
.content-area ul li::before {
content: ">>>";
position: absolute;
left: 0;
color: #ff0000;
font-weight: 700;
font-size: 10px;
top: 2px;
}
.content-area ol {
margin: 10px 0 14px 0;
list-style: none;
padding: 0;
counter-reset: cons-list;
}
.content-area ol li {
counter-increment: cons-list;
padding-left: 28px;
margin-bottom: 5px;
color: #ff9900;
position: relative;
}
.content-area ol li::before {
content: "[" counter(cons-list) "]";
position: absolute;
left: 0;
color: #ff0000;
font-weight: 700;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 13px;
}
.content-area th {
background: #800000;
color: #ffff00;
padding: 7px 10px;
border: 1px solid #ff0000;
text-align: left;
text-transform: uppercase;
font-size: 11px;
}
.content-area td {
padding: 7px 10px;
border: 1px solid #004400;
color: #00ff00;
}
.content-area img {
max-width: 100%;
border: 3px solid #ff00ff;
filter: contrast(110%) saturate(130%);
margin: 8px 0;
}
.content-area hr {
border: none;
height: 2px;
background: repeating-linear-gradient(90deg, #ff0000, #ffff00, #00ff00, #00ffff, #ff00ff, #ff0000);
margin: 20px 0;
}
/* Visitor counter style */
.visitor-counter {
text-align: center;
margin: 16px 0;
padding: 8px;
border: 2px solid #ffff00;
background: rgba(0,0,80,0.4);
}
.visitor-label {
font-size: 11px;
color: #ffff00;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.visitor-number {
font-family: "Courier New", monospace;
font-size: 28px;
color: #ff0000;
font-weight: 700;
text-shadow: 0 0 10px #ff0000;
letter-spacing: 0.15em;
}
/* Tags */
.tags-area {
text-align: center;
margin: 16px 0;
}
.tag {
display: inline-block;
background: #800080;
color: #ffff00;
border: 1px solid #ff00ff;
padding: 3px 10px;
font-size: 11px;
margin: 3px;
text-transform: uppercase;
letter-spacing: 0.1em;
}
/* Footer */
.page-footer {
text-align: center;
margin-top: 32px;
padding-top: 16px;
border-top: 2px dashed #00ff00;
font-size: 11px;
color: #00ff00;
letter-spacing: 0.08em;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="page">
<div class="construction-banner">
!!! UNDER CONSTRUCTION !!! TRUTH WILL NOT BE SILENCED !!! UNDER CONSTRUCTION !!!
</div>
<div class="ticker-wrap">
<span class="ticker-text">
*** THEY DON'T WANT YOU TO READ THIS *** WAKE UP *** THE TRUTH IS HERE *** SHARE WITH EVERYONE *** THEY ARE WATCHING *** DO YOUR OWN RESEARCH *** QUESTION EVERYTHING *** WELCOME TO {{ config.site.name }} ***
</span>
</div>
<div class="site-header">
<div class="site-title">{{ config.site.name }}</div>
<div class="site-subtitle">
>>> The Truth They Don't Want You To Know <<<
</div>
</div>
<div class="visitor-counter">
<div class="visitor-label">Visitors Since 1997</div>
<div class="visitor-number">0069420</div>
</div>
<div class="post-meta">
<div class="post-meta-title">{{ title }}</div>
<div class="post-meta-info">
Posted by: {{ config.site.author }} | Date: {{ published_date }} | Read time: {{ reading_time }}
{% if updated_date %} | Last Updated: {{ updated_date }}{% endif %}
</div>
{% if taxonomy.tags %}
<div class="tags-area">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="page-footer">
&copy; {{ config.site.name }} — {{ config.site.author }} — {{ published_date }}<br>
BEST VIEWED IN NETSCAPE NAVIGATOR 4.0 AT 800x600
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,531 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #000000; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--cyber-green: #00ff88;
--cyber-magenta: #ff00ff;
--cyber-blue: #00ffff;
--bg: #000000;
--bg-panel: #040a04;
--dim-green: #00882e;
--dim-magenta: #880088;
}
body {
background: var(--bg);
color: var(--cyber-green);
font-family: "Share Tech Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.7;
min-height: 100vh;
overflow-x: hidden;
position: relative;
}
/* Matrix rain canvas */
#matrix-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.07;
pointer-events: none;
z-index: 0;
}
/* Geometric corner ornaments */
.corner {
position: fixed;
width: 80px;
height: 80px;
opacity: 0.4;
z-index: 1;
pointer-events: none;
}
.corner.tl {
top: 16px;
left: 16px;
border-top: 1px solid var(--cyber-green);
border-left: 1px solid var(--cyber-green);
}
.corner.tr {
top: 16px;
right: 16px;
border-top: 1px solid var(--cyber-magenta);
border-right: 1px solid var(--cyber-magenta);
}
.corner.bl {
bottom: 16px;
left: 16px;
border-bottom: 1px solid var(--cyber-green);
border-left: 1px solid var(--cyber-green);
}
.corner.br {
bottom: 16px;
right: 16px;
border-bottom: 1px solid var(--cyber-magenta);
border-right: 1px solid var(--cyber-magenta);
}
.corner-dot {
position: absolute;
width: 4px;
height: 4px;
background: var(--cyber-green);
box-shadow: 0 0 6px var(--cyber-green);
}
.corner.tl .corner-dot { top: -2px; left: -2px; }
.corner.tr .corner-dot { top: -2px; right: -2px; background: var(--cyber-magenta); box-shadow: 0 0 6px var(--cyber-magenta); }
.corner.bl .corner-dot { bottom: -2px; left: -2px; }
.corner.br .corner-dot { bottom: -2px; right: -2px; background: var(--cyber-magenta); box-shadow: 0 0 6px var(--cyber-magenta); }
/* Main layout */
.container {
position: relative;
z-index: 2;
max-width: 860px;
margin: 0 auto;
padding: 60px 32px;
}
/* Header scan line animation */
.scan-header {
position: relative;
overflow: hidden;
padding: 24px 0;
margin-bottom: 8px;
border-bottom: 1px solid var(--dim-green);
}
.scan-header::after {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 1px;
background: linear-gradient(to right, transparent, var(--cyber-green), transparent);
animation: scan 4s linear infinite;
}
@keyframes scan {
0% { left: -100%; }
100% { left: 200%; }
}
.site-label {
font-size: 11px;
letter-spacing: 0.3em;
color: var(--dim-green);
text-transform: uppercase;
margin-bottom: 8px;
}
.site-label span {
color: var(--cyber-magenta);
text-shadow: 0 0 8px var(--cyber-magenta);
}
/* Glitch title */
.glitch-title {
position: relative;
font-family: "Orbitron", sans-serif;
font-size: clamp(24px, 4vw, 44px);
font-weight: 900;
color: var(--cyber-green);
text-shadow:
0 0 10px var(--cyber-green),
0 0 30px rgba(0,255,136,0.4);
line-height: 1.1;
letter-spacing: 0.02em;
margin-bottom: 4px;
}
.glitch-title::before,
.glitch-title::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.glitch-title::before {
color: var(--cyber-magenta);
text-shadow: 0 0 8px var(--cyber-magenta);
animation: glitch-before 3.5s infinite;
clip-path: polygon(0 0, 100% 0, 100% 35%, 0 35%);
opacity: 0;
}
.glitch-title::after {
color: var(--cyber-blue);
text-shadow: 0 0 8px var(--cyber-blue);
animation: glitch-after 3.5s infinite;
clip-path: polygon(0 65%, 100% 65%, 100% 100%, 0 100%);
opacity: 0;
}
@keyframes glitch-before {
0%, 88%, 100% { opacity: 0; transform: none; }
90% { opacity: 1; transform: translate(-3px, 0); }
92% { opacity: 1; transform: translate(3px, 0); }
94% { opacity: 0; }
}
@keyframes glitch-after {
0%, 88%, 100% { opacity: 0; transform: none; }
91% { opacity: 1; transform: translate(3px, 0); }
93% { opacity: 1; transform: translate(-3px, 0); }
95% { opacity: 0; }
}
.meta-row {
display: flex;
flex-wrap: wrap;
gap: 24px;
padding: 12px 0;
border-bottom: 1px solid rgba(0,255,136,0.15);
margin-bottom: 32px;
font-size: 12px;
color: var(--dim-green);
}
.meta-row .meta-item {
display: flex;
align-items: center;
gap: 6px;
}
.meta-row .meta-key {
color: var(--cyber-magenta);
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
}
.meta-row .meta-val {
color: var(--cyber-green);
}
.tag-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 40px;
}
.tag {
font-size: 11px;
padding: 2px 10px;
border: 1px solid var(--dim-green);
color: var(--cyber-green);
letter-spacing: 0.1em;
position: relative;
overflow: hidden;
}
.tag:nth-child(even) {
border-color: var(--dim-magenta);
color: var(--cyber-magenta);
}
.tag::before {
content: "#";
margin-right: 2px;
color: var(--dim-green);
}
.tag:nth-child(even)::before {
color: var(--dim-magenta);
}
/* Content styles */
.post-content {
color: rgba(0,255,136,0.85);
}
.post-content h1 {
font-family: "Orbitron", sans-serif;
font-size: 22px;
font-weight: 700;
color: var(--cyber-magenta);
text-shadow: 0 0 10px var(--cyber-magenta);
margin-top: 40px;
margin-bottom: 16px;
letter-spacing: 0.05em;
padding-bottom: 8px;
border-bottom: 1px solid var(--dim-magenta);
}
.post-content h2 {
font-family: "Orbitron", sans-serif;
font-size: 17px;
font-weight: 700;
color: var(--cyber-blue);
text-shadow: 0 0 8px var(--cyber-blue);
margin-top: 32px;
margin-bottom: 12px;
letter-spacing: 0.05em;
}
.post-content h3 {
font-size: 15px;
color: var(--cyber-green);
text-shadow: 0 0 6px var(--cyber-green);
margin-top: 24px;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.post-content p {
margin-bottom: 18px;
}
.post-content a {
color: var(--cyber-blue);
text-decoration: none;
text-shadow: 0 0 6px var(--cyber-blue);
border-bottom: 1px solid rgba(0,255,255,0.3);
}
.post-content a:hover {
color: var(--cyber-magenta);
text-shadow: 0 0 8px var(--cyber-magenta);
border-bottom-color: var(--cyber-magenta);
}
.post-content code {
font-family: "Share Tech Mono", monospace;
font-size: 13px;
color: var(--cyber-blue);
background: rgba(0,255,255,0.06);
border: 1px solid rgba(0,255,255,0.2);
padding: 1px 6px;
}
.post-content pre {
background: var(--bg-panel);
border: 1px solid var(--dim-green);
border-left: 2px solid var(--cyber-green);
padding: 18px 20px;
margin: 20px 0;
overflow-x: auto;
position: relative;
}
.post-content pre::before {
content: "//decrypt";
position: absolute;
top: 6px;
right: 10px;
font-size: 10px;
color: var(--dim-green);
letter-spacing: 0.1em;
}
.post-content pre code {
background: none;
border: none;
padding: 0;
color: var(--cyber-green);
text-shadow: 0 0 3px rgba(0,255,136,0.4);
}
.post-content blockquote {
border-left: 2px solid var(--cyber-magenta);
padding: 12px 18px;
margin: 20px 0;
background: rgba(255,0,255,0.04);
color: var(--cyber-magenta);
font-style: italic;
}
.post-content ul,
.post-content ol {
margin: 14px 0 18px 20px;
}
.post-content li {
margin-bottom: 6px;
}
.post-content ul li::marker {
color: var(--cyber-magenta);
}
.post-content ol li::marker {
color: var(--cyber-blue);
}
.post-content table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 13px;
}
.post-content th {
border: 1px solid var(--dim-green);
background: rgba(0,255,136,0.06);
padding: 8px 12px;
color: var(--cyber-green);
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.1em;
}
.post-content td {
border: 1px solid rgba(0,255,136,0.15);
padding: 8px 12px;
}
.post-content tr:hover td {
background: rgba(0,255,136,0.04);
}
.post-content hr {
border: none;
border-top: 1px solid var(--dim-green);
margin: 28px 0;
}
.post-content img {
max-width: 100%;
border: 1px solid var(--dim-green);
filter: hue-rotate(120deg) saturate(0.7) brightness(0.9);
}
.footer-bar {
margin-top: 60px;
padding-top: 16px;
border-top: 1px solid var(--dim-green);
display: flex;
justify-content: space-between;
font-size: 11px;
color: var(--dim-green);
letter-spacing: 0.1em;
}
.footer-bar span {
color: var(--cyber-magenta);
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<canvas id="matrix-canvas"></canvas>
<div class="corner tl"><div class="corner-dot"></div></div>
<div class="corner tr"><div class="corner-dot"></div></div>
<div class="corner bl"><div class="corner-dot"></div></div>
<div class="corner br"><div class="corner-dot"></div></div>
<div class="container">
<div class="scan-header">
<div class="site-label">
{{ config.site.name }} / <span>{{ config.site.author }}</span> / encrypted
</div>
<h1 class="glitch-title" data-text="{{ title }}">{{ title }}</h1>
</div>
<div class="meta-row">
<div class="meta-item">
<span class="meta-key">date</span>
<span class="meta-val">{{ published_date }}</span>
</div>
<div class="meta-item">
<span class="meta-key">read</span>
<span class="meta-val">{{ reading_time }}</span>
</div>
<div class="meta-item">
<span class="meta-key">author</span>
<span class="meta-val">{{ config.site.author }}</span>
</div>
{% if updated_date %}
<div class="meta-item">
<span class="meta-key">updated</span>
<span class="meta-val">{{ updated_date }}</span>
</div>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="tag-row">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
<div class="post-content">
{{ content | safe }}
</div>
<div class="footer-bar">
<span>{{ config.site.name }}</span>
<span>{{ published_date }}</span>
</div>
</div>
<script>
(function() {
const canvas = document.getElementById('matrix-canvas');
const ctx = canvas.getContext('2d');
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*()アイウエオカキクケコサシスセソタチツテト';
const fontSize = 13;
let columns, drops;
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
columns = Math.floor(canvas.width / fontSize);
drops = new Array(columns).fill(1);
}
function draw() {
ctx.fillStyle = 'rgba(0,0,0,0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#00ff88';
ctx.font = fontSize + 'px monospace';
for (let i = 0; i < drops.length; i++) {
const ch = chars[Math.floor(Math.random() * chars.length)];
ctx.fillText(ch, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
resize();
window.addEventListener('resize', resize);
setInterval(draw, 55);
})();
</script>
</body>
</html>

430
templates/dracula.html Normal file
View File

@@ -0,0 +1,430 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #21222c; }
:root {
--bg: #282a36;
--bg-lighter: #343746;
--bg-darker: #21222c;
--selection: #44475a;
--comment: #6272a4;
--fg: #f8f8f2;
--cyan: #8be9fd;
--green: #50fa7b;
--orange: #ffb86c;
--pink: #ff79c6;
--purple: #bd93f9;
--red: #ff5555;
--yellow: #f1fa8c;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-darker);
color: var(--fg);
font-family: "Inter", system-ui, sans-serif;
font-size: 16px;
line-height: 1.7;
min-height: 100vh;
}
.layout {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
header {
grid-area: header;
background: var(--bg);
border-bottom: 1px solid var(--selection);
padding: 0 32px;
display: flex;
align-items: center;
justify-content: space-between;
height: 56px;
}
.site-name {
font-family: "Fira Code", monospace;
font-size: 13px;
color: var(--purple);
letter-spacing: 0.05em;
}
.site-name span {
color: var(--comment);
}
.header-meta {
display: flex;
align-items: center;
gap: 20px;
font-size: 13px;
color: var(--comment);
font-family: "Fira Code", monospace;
}
.header-meta .reading-time {
color: var(--cyan);
}
.header-meta .date {
color: var(--green);
}
.sidebar {
grid-area: sidebar;
background: var(--bg);
border-right: 1px solid var(--selection);
padding: 24px 0;
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
}
.sidebar-section {
padding: 0 20px;
margin-bottom: 28px;
}
.sidebar-label {
font-family: "Fira Code", monospace;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.15em;
color: var(--comment);
margin-bottom: 12px;
}
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.tag {
font-family: "Fira Code", monospace;
font-size: 11px;
padding: 2px 10px;
border-radius: 999px;
letter-spacing: 0.02em;
}
.tag:nth-child(6n+1) { background: rgba(189,147,249,0.2); color: var(--purple); border: 1px solid rgba(189,147,249,0.4); }
.tag:nth-child(6n+2) { background: rgba(255,121,198,0.2); color: var(--pink); border: 1px solid rgba(255,121,198,0.4); }
.tag:nth-child(6n+3) { background: rgba(139,233,253,0.2); color: var(--cyan); border: 1px solid rgba(139,233,253,0.4); }
.tag:nth-child(6n+4) { background: rgba(80,250,123,0.2); color: var(--green); border: 1px solid rgba(80,250,123,0.4); }
.tag:nth-child(6n+5) { background: rgba(255,184,108,0.2); color: var(--orange); border: 1px solid rgba(255,184,108,0.4); }
.tag:nth-child(6n+6) { background: rgba(255,85,85,0.2); color: var(--red); border: 1px solid rgba(255,85,85,0.4); }
.sidebar-info {
font-family: "Fira Code", monospace;
font-size: 12px;
color: var(--fg);
line-height: 1.9;
}
.sidebar-info .key {
color: var(--purple);
}
.sidebar-info .val {
color: var(--green);
}
.sidebar-info .colon {
color: var(--pink);
}
.sidebar-divider {
height: 1px;
background: var(--selection);
margin: 0 20px 28px;
}
main {
grid-area: main;
padding: 48px 64px;
max-width: 860px;
}
.post-title {
font-size: 36px;
font-weight: 600;
color: var(--fg);
line-height: 1.2;
margin-bottom: 8px;
letter-spacing: -0.02em;
}
.title-accent {
display: block;
width: 48px;
height: 3px;
background: linear-gradient(to right, var(--purple), var(--pink));
margin-top: 16px;
margin-bottom: 40px;
border-radius: 2px;
}
.post-content h1 {
font-size: 28px;
font-weight: 600;
color: var(--purple);
margin-top: 40px;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid var(--selection);
}
.post-content h2 {
font-size: 22px;
font-weight: 600;
color: var(--pink);
margin-top: 36px;
margin-bottom: 14px;
}
.post-content h3 {
font-size: 18px;
font-weight: 500;
color: var(--cyan);
margin-top: 28px;
margin-bottom: 10px;
}
.post-content h4 {
font-size: 16px;
font-weight: 500;
color: var(--orange);
margin-top: 20px;
margin-bottom: 8px;
}
.post-content p {
margin-bottom: 20px;
color: var(--fg);
}
.post-content a {
color: var(--cyan);
text-decoration: none;
border-bottom: 1px solid rgba(139,233,253,0.4);
transition: border-color 0.2s;
}
.post-content a:hover {
border-color: var(--cyan);
}
.post-content code {
font-family: "Fira Code", monospace;
font-size: 14px;
background: var(--bg);
color: var(--green);
padding: 1px 6px;
border-radius: 4px;
border: 1px solid var(--selection);
}
.post-content pre {
background: var(--bg);
border: 1px solid var(--selection);
border-left: 3px solid var(--purple);
border-radius: 6px;
padding: 20px 24px;
margin: 24px 0;
overflow-x: auto;
}
.post-content pre code {
background: none;
border: none;
padding: 0;
color: var(--fg);
font-size: 14px;
}
.post-content blockquote {
border-left: 3px solid var(--yellow);
background: rgba(241,250,140,0.05);
padding: 16px 20px;
margin: 24px 0;
border-radius: 0 6px 6px 0;
color: var(--yellow);
font-style: italic;
}
.post-content ul,
.post-content ol {
margin: 16px 0 20px 24px;
}
.post-content li {
margin-bottom: 6px;
}
.post-content ul li::marker {
color: var(--purple);
}
.post-content ol li::marker {
color: var(--cyan);
font-family: "Fira Code", monospace;
}
.post-content table {
width: 100%;
border-collapse: collapse;
margin: 24px 0;
font-size: 14px;
}
.post-content th {
background: var(--selection);
color: var(--purple);
padding: 10px 14px;
text-align: left;
font-family: "Fira Code", monospace;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.post-content td {
border-bottom: 1px solid var(--selection);
padding: 10px 14px;
}
.post-content tr:hover td {
background: rgba(68,71,90,0.4);
}
.post-content img {
max-width: 100%;
border-radius: 6px;
border: 1px solid var(--selection);
}
.post-content hr {
border: none;
border-top: 1px solid var(--selection);
margin: 32px 0;
}
footer {
grid-area: footer;
background: var(--bg);
border-top: 1px solid var(--selection);
padding: 16px 32px;
display: flex;
align-items: center;
justify-content: space-between;
font-family: "Fira Code", monospace;
font-size: 12px;
color: var(--comment);
}
footer span {
color: var(--pink);
}
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
.sidebar {
position: static;
height: auto;
border-right: none;
border-top: 1px solid var(--selection);
}
main {
padding: 32px 24px;
}
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="layout">
<header>
<div class="site-name">
<span>// </span>{{ config.site.name }}
</div>
<div class="header-meta">
<span class="date">{{ published_date }}</span>
<span class="reading-time">{{ reading_time }}</span>
</div>
</header>
<aside class="sidebar">
<div class="sidebar-section">
<div class="sidebar-label">// file info</div>
<div class="sidebar-info">
<div><span class="key">author</span><span class="colon">:</span> <span class="val">"{{ config.site.author }}"</span></div>
<div><span class="key">date</span><span class="colon">:</span> <span class="val">{{ published_date }}</span></div>
<div><span class="key">read</span><span class="colon">:</span> <span class="val">"{{ reading_time }}"</span></div>
{% if updated_date %}
<div><span class="key">updated</span><span class="colon">:</span> <span class="val">{{ updated_date }}</span></div>
{% endif %}
</div>
</div>
{% if taxonomy.tags %}
<div class="sidebar-divider"></div>
<div class="sidebar-section">
<div class="sidebar-label">// tags</div>
<div class="tag-list">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
</div>
{% endif %}
</aside>
<main>
<h1 class="post-title">{{ title }}</h1>
<span class="title-accent"></span>
<div class="post-content">
{{ content | safe }}
</div>
</main>
<footer>
<span>{{ config.site.name }}</span>
<span>by <span>{{ config.site.author }}</span></span>
</footer>
</div>
</body>
</html>

494
templates/envelope.html Normal file
View File

@@ -0,0 +1,494 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,700;1,400;1,500&family=Special+Elite&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #7a6a50; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--envelope: #f0ebe0;
--paper: #faf8f3;
--ink: #2a1f0e;
--ink-dim: #6b5a3e;
--red: #c0392b;
--blue-stamp: #1a3a6e;
--border: #c8b99a;
}
body {
background: #7a6a50;
min-height: 100vh;
padding: 40px 16px 60px;
font-family: "EB Garamond", "Georgia", serif;
color: var(--ink);
}
/* Envelope container */
.envelope {
max-width: 760px;
margin: 0 auto;
background: var(--envelope);
position: relative;
box-shadow: 0 4px 16px rgba(0,0,0,0.3), 0 12px 48px rgba(0,0,0,0.25);
}
/* Airmail border top */
.airmail-border-top {
height: 14px;
background: repeating-linear-gradient(
90deg,
var(--red) 0px,
var(--red) 14px,
#fff 14px,
#fff 28px,
#1a3a6e 28px,
#1a3a6e 42px,
#fff 42px,
#fff 56px
);
}
/* Envelope V-flap (CSS triangle at bottom) */
.envelope-inner {
position: relative;
padding: 28px 36px 0;
}
/* Postmark circle over title area */
.postmark {
position: absolute;
top: 28px;
left: 50%;
transform: translateX(-50%);
width: 110px;
height: 110px;
border: 2px solid var(--ink-dim);
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0.35;
pointer-events: none;
z-index: 10;
}
.postmark-top {
font-family: "Special Elite", monospace;
font-size: 9px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink);
}
.postmark-date {
font-size: 14px;
font-weight: 700;
color: var(--ink);
line-height: 1.2;
text-align: center;
font-family: "Special Elite", monospace;
}
.postmark-bottom {
font-family: "Special Elite", monospace;
font-size: 8px;
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--ink);
}
/* Stamp */
.stamp-area {
position: absolute;
top: 28px;
right: 36px;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.stamp {
width: 64px;
height: 80px;
background: var(--blue-stamp);
border: 3px solid #eee;
outline: 2px dashed rgba(255,255,255,0.4);
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
/* Perforations */
.stamp::before {
content: "";
position: absolute;
inset: -5px;
border: 5px dashed #fff;
}
.stamp-flag {
font-size: 24px;
color: #fff;
line-height: 1;
margin-bottom: 3px;
}
.stamp-value {
font-family: "Special Elite", monospace;
font-size: 10px;
color: rgba(255,255,255,0.9);
letter-spacing: 0.08em;
}
.stamp-name {
font-size: 8px;
font-family: "Special Elite", monospace;
text-align: center;
color: rgba(255,255,255,0.7);
letter-spacing: 0.06em;
text-transform: uppercase;
}
/* Address block */
.address-area {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
padding: 20px 0 24px;
border-bottom: 1px dashed var(--border);
margin-bottom: 28px;
}
.address-block {
font-size: 14px;
color: var(--ink-dim);
line-height: 1.8;
}
.address-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.14em;
color: var(--ink-dim);
margin-bottom: 4px;
}
.address-name {
font-size: 16px;
font-weight: 700;
color: var(--ink);
margin-bottom: 2px;
}
/* Letter / paper section */
.letter {
background: var(--paper);
margin: 0 -36px;
padding: 40px 52px 52px;
border-top: 1px solid var(--border);
box-shadow: inset 0 4px 12px rgba(0,0,0,0.05);
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 27px,
rgba(0,0,0,0.04) 27px,
rgba(0,0,0,0.04) 28px
);
}
.letter-date {
text-align: right;
font-size: 14px;
font-style: italic;
color: var(--ink-dim);
margin-bottom: 20px;
}
.letter-salutation {
font-size: 17px;
color: var(--ink);
margin-bottom: 16px;
}
.letter-title {
font-size: 26px;
font-weight: 700;
color: var(--ink);
line-height: 1.2;
margin-bottom: 24px;
font-style: italic;
}
/* Content styles */
.content-area h1 {
font-size: 22px;
font-weight: 700;
font-style: italic;
color: var(--ink);
margin-top: 32px;
margin-bottom: 10px;
}
.content-area h2 {
font-size: 18px;
font-weight: 700;
color: var(--ink);
margin-top: 24px;
margin-bottom: 8px;
text-decoration: underline;
text-underline-offset: 3px;
}
.content-area h3 {
font-size: 16px;
font-weight: 700;
color: var(--ink-dim);
margin-top: 20px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 15px;
font-weight: 700;
color: var(--ink-dim);
margin-top: 16px;
margin-bottom: 5px;
}
.content-area p {
font-size: 17px;
margin-bottom: 16px;
color: var(--ink);
text-align: justify;
hyphens: auto;
line-height: 1.7;
}
.content-area a {
color: var(--blue-stamp);
text-decoration: underline;
}
.content-area code {
font-family: "Special Elite", monospace;
font-size: 14px;
background: rgba(0,0,0,0.05);
padding: 1px 4px;
}
.content-area pre {
background: rgba(0,0,0,0.04);
border-left: 3px solid var(--border);
padding: 12px 16px;
margin: 14px 0;
overflow-x: auto;
font-size: 14px;
}
.content-area pre code {
background: none;
padding: 0;
}
.content-area blockquote {
border-left: 3px solid var(--ink-dim);
padding: 8px 18px;
margin: 14px 0;
font-style: italic;
color: var(--ink-dim);
}
.content-area ul {
margin: 10px 0 16px 24px;
color: var(--ink);
}
.content-area ol {
margin: 10px 0 16px 28px;
color: var(--ink);
}
.content-area li {
margin-bottom: 6px;
font-size: 16px;
line-height: 1.6;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 15px;
}
.content-area th {
border-bottom: 2px solid var(--ink);
padding: 7px 12px;
font-weight: 700;
text-align: left;
}
.content-area td {
border-bottom: 1px solid var(--border);
padding: 7px 12px;
}
.content-area img {
max-width: 100%;
margin: 12px 0;
}
.content-area hr {
border: none;
text-align: center;
margin: 24px 0;
color: var(--ink-dim);
font-size: 20px;
letter-spacing: 0.4em;
}
.content-area hr::before {
content: "* * *";
}
/* Sign-off */
.letter-signoff {
margin-top: 36px;
padding-top: 8px;
}
.signoff-farewell {
font-size: 17px;
color: var(--ink);
margin-bottom: 24px;
font-style: italic;
}
.signoff-signature {
font-size: 22px;
color: var(--ink);
font-style: italic;
}
.signoff-site {
font-size: 13px;
color: var(--ink-dim);
margin-top: 4px;
}
/* Tags at bottom */
.letter-tags {
margin-top: 20px;
padding-top: 16px;
border-top: 1px dashed var(--border);
font-size: 12px;
color: var(--ink-dim);
}
/* Airmail border bottom */
.airmail-border-bottom {
height: 14px;
background: repeating-linear-gradient(
90deg,
#1a3a6e 0px,
#1a3a6e 14px,
#fff 14px,
#fff 28px,
var(--red) 28px,
var(--red) 42px,
#fff 42px,
#fff 56px
);
}
@media (max-width: 600px) {
.envelope-inner { padding: 20px 20px 0; }
.letter { margin: 0 -20px; padding: 28px 24px 36px; }
.address-area { grid-template-columns: 1fr; }
.stamp-area { right: 20px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="envelope">
<div class="airmail-border-top"></div>
<div class="envelope-inner">
<div class="postmark">
<div class="postmark-top">{{ config.site.name }}</div>
<div class="postmark-date">{{ published_date | replace("-", "\A") }}</div>
<div class="postmark-bottom">Germany</div>
</div>
<div class="stamp-area">
<div class="stamp">
<div class="stamp-flag">DE</div>
<div class="stamp-value">€0.85</div>
<div class="stamp-name">Brief</div>
</div>
</div>
<div class="address-area">
<div class="address-block">
<div class="address-label">From</div>
<div class="address-name">{{ config.site.author }}</div>
<div>{{ config.site.name }}</div>
<div>{{ published_date }}</div>
</div>
<div class="address-block">
<div class="address-label">To</div>
<div class="address-name">Dear Reader</div>
<div>Wherever You Are</div>
<div>World</div>
</div>
</div>
<div class="letter">
<div class="letter-date">{{ published_date }}</div>
<div class="letter-salutation">Dear Reader,</div>
<div class="letter-title">Re: {{ title }}</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="letter-signoff">
<div class="signoff-farewell">With warm regards,</div>
<div class="signoff-signature">{{ config.site.author }}</div>
<div class="signoff-site">{{ config.site.name }}</div>
</div>
{% if taxonomy.tags %}
<div class="letter-tags">
P.S. Tags: {% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %} · {{ reading_time }}
</div>
{% endif %}
</div>
</div>
<div class="airmail-border-bottom"></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,668 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;1,400&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #191b22; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #191b22;
--column: #16181f;
--card: #1f2130;
--card-hover: #242638;
--purple: #6364ff;
--purple-light: #858afa;
--blue-accent: #2b90d9;
--text: #ffffff;
--text-secondary: #c3c8e0;
--text-muted: #9099c1;
--border: #313549;
--boost: #79bd9a;
--fav: #ca8f04;
--reply: #9099c1;
}
body {
background: var(--bg);
color: var(--text);
font-family: "Roboto", system-ui, sans-serif;
font-size: 14px;
line-height: 1.45;
min-height: 100vh;
}
/* Mastodon layout */
.app {
display: flex;
min-height: 100vh;
}
/* Left navigation */
.nav-sidebar {
width: 240px;
flex-shrink: 0;
background: var(--column);
border-right: 1px solid var(--border);
padding: 16px 8px;
display: flex;
flex-direction: column;
gap: 4px;
}
.nav-logo {
padding: 8px 12px 16px;
margin-bottom: 4px;
}
.nav-logo-icon {
font-size: 28px;
color: var(--purple);
line-height: 1;
margin-bottom: 2px;
}
.nav-logo-name {
font-size: 15px;
font-weight: 700;
color: var(--text);
}
.nav-logo-handle {
font-size: 12px;
color: var(--text-muted);
}
.nav-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border-radius: 8px;
font-size: 15px;
font-weight: 500;
color: var(--text-secondary);
cursor: default;
}
.nav-item.active {
color: var(--text);
}
.nav-item-icon {
font-size: 20px;
width: 24px;
text-align: center;
flex-shrink: 0;
}
.nav-compose {
margin-top: 16px;
background: var(--purple);
color: #fff;
font-weight: 700;
border-radius: 999px;
text-align: center;
padding: 12px;
font-size: 14px;
}
/* Main content column */
.main-column {
flex: 1;
max-width: 600px;
border-right: 1px solid var(--border);
}
/* Column header */
.column-header {
background: rgba(31,33,48,0.9);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
padding: 14px 16px;
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
gap: 12px;
}
.column-header-back {
font-size: 18px;
color: var(--text-secondary);
}
.column-header-title {
font-size: 16px;
font-weight: 700;
color: var(--text);
}
/* Status card */
.status {
background: var(--card);
border-bottom: 1px solid var(--border);
padding: 16px;
}
.status-pinned {
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.status-header {
display: flex;
gap: 12px;
margin-bottom: 10px;
}
.avatar {
width: 46px;
height: 46px;
border-radius: 8px;
background: linear-gradient(135deg, var(--purple) 0%, #9b59b6 100%);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: 700;
color: #fff;
}
.avatar-sm {
width: 24px;
height: 24px;
border-radius: 4px;
background: linear-gradient(135deg, var(--purple) 0%, #9b59b6 100%);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 700;
color: #fff;
}
.status-meta {
flex: 1;
min-width: 0;
}
.status-name-row {
display: flex;
align-items: baseline;
gap: 6px;
flex-wrap: wrap;
}
.status-name {
font-size: 15px;
font-weight: 700;
color: var(--text);
}
.status-handle {
font-size: 13px;
color: var(--text-muted);
}
.status-dot {
color: var(--text-muted);
font-size: 12px;
}
.status-time {
font-size: 13px;
color: var(--text-muted);
}
/* Toot title as a subtitle */
.toot-subject {
font-size: 13px;
font-weight: 500;
color: var(--text-secondary);
background: rgba(99,100,255,0.1);
border-left: 3px solid var(--purple);
padding: 8px 12px;
margin-bottom: 10px;
border-radius: 0 6px 6px 0;
}
/* Content */
.status-body {
color: var(--text-secondary);
font-size: 15px;
line-height: 1.5;
margin-bottom: 12px;
}
.content-area h1 {
font-size: 18px;
font-weight: 700;
color: var(--text);
margin: 16px 0 8px;
}
.content-area h2 {
font-size: 15px;
font-weight: 700;
color: var(--text);
margin: 14px 0 6px;
}
.content-area h3 {
font-size: 14px;
font-weight: 700;
color: var(--text-secondary);
margin: 12px 0 5px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
margin: 10px 0 4px;
}
.content-area p {
font-size: 15px;
margin-bottom: 10px;
color: var(--text-secondary);
line-height: 1.55;
}
.content-area a {
color: var(--blue-accent);
text-decoration: none;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "Roboto Mono", monospace;
font-size: 13px;
background: rgba(255,255,255,0.08);
color: #e6e6ff;
padding: 2px 6px;
border-radius: 4px;
}
.content-area pre {
background: #111218;
border: 1px solid var(--border);
border-radius: 8px;
padding: 14px 16px;
margin: 12px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: #d4d8f0;
padding: 0;
font-size: 13px;
}
.content-area blockquote {
border-left: 3px solid var(--border);
padding: 8px 14px;
margin: 10px 0;
color: var(--text-muted);
font-style: italic;
}
.content-area blockquote p {
margin: 0;
color: var(--text-muted);
}
.content-area ul {
margin: 8px 0 12px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 16px;
margin-bottom: 4px;
color: var(--text-secondary);
position: relative;
}
.content-area ul li::before {
content: "·";
position: absolute;
left: 4px;
color: var(--purple-light);
font-weight: 700;
}
.content-area ol {
margin: 8px 0 12px 20px;
color: var(--text-secondary);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 12px 0;
font-size: 13px;
}
.content-area th {
background: rgba(255,255,255,0.05);
padding: 7px 12px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--text-muted);
border-bottom: 1px solid var(--border);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 7px 12px;
border-bottom: 1px solid var(--border);
color: var(--text-secondary);
}
.content-area img {
max-width: 100%;
border-radius: 8px;
border: 1px solid var(--border);
margin: 8px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 16px 0;
}
/* Hashtags */
.status-hashtags {
margin-bottom: 12px;
}
.hashtag {
color: var(--blue-accent);
font-size: 15px;
font-weight: 500;
}
/* Status timestamp detail */
.status-timestamp {
font-size: 13px;
color: var(--text-muted);
margin-bottom: 12px;
padding-bottom: 12px;
border-bottom: 1px solid var(--border);
}
/* Action bar */
.status-actions {
display: flex;
gap: 0;
justify-content: space-between;
padding: 4px 0;
}
.action-btn {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 500;
color: var(--text-muted);
padding: 6px 12px;
border-radius: 6px;
cursor: default;
}
.action-btn-icon {
font-size: 16px;
}
.action-btn.boost { color: var(--boost); }
.action-btn.fav { color: var(--fav); }
/* Boost count strip */
.engagement-strip {
padding: 10px 0 8px;
border-bottom: 1px solid var(--border);
border-top: 1px solid var(--border);
margin-bottom: 12px;
display: flex;
gap: 20px;
}
.engagement-item {
font-size: 14px;
color: var(--text-secondary);
}
.engagement-count {
font-weight: 700;
color: var(--text);
}
/* Right sidebar */
.right-sidebar {
width: 300px;
flex-shrink: 0;
padding: 20px 12px;
display: flex;
flex-direction: column;
gap: 16px;
}
.sidebar-card {
background: var(--card);
border-radius: 12px;
border: 1px solid var(--border);
overflow: hidden;
}
.sidebar-card-header {
font-size: 13px;
font-weight: 700;
color: var(--text);
padding: 14px 16px 10px;
border-bottom: 1px solid var(--border);
}
.sidebar-card-item {
padding: 10px 16px;
display: flex;
align-items: center;
gap: 10px;
border-bottom: 1px solid var(--border);
}
.sidebar-card-item:last-child { border-bottom: none; }
.sidebar-item-text {
font-size: 13px;
color: var(--text-secondary);
}
.sidebar-item-label {
font-size: 11px;
color: var(--text-muted);
}
@media (max-width: 900px) {
.nav-sidebar { display: none; }
.right-sidebar { display: none; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="app">
<nav class="nav-sidebar">
<div class="nav-logo">
<div class="nav-logo-icon">M</div>
<div class="nav-logo-name">{{ config.site.author | truncate(18) }}</div>
<div class="nav-logo-handle">@felix@{{ config.site.name }}</div>
</div>
<div class="nav-item">
<span class="nav-item-icon">&#9679;</span>
<span>Home</span>
</div>
<div class="nav-item active">
<span class="nav-item-icon">&#9675;</span>
<span>Notifications</span>
</div>
<div class="nav-item">
<span class="nav-item-icon">&#8981;</span>
<span>Explore</span>
</div>
<div class="nav-item">
<span class="nav-item-icon">&#9872;</span>
<span>Local</span>
</div>
<div class="nav-item">
<span class="nav-item-icon">&#9673;</span>
<span>Federated</span>
</div>
<div class="nav-item">
<span class="nav-item-icon">&#9737;</span>
<span>Profile</span>
</div>
<div class="nav-compose">Compose</div>
</nav>
<main class="main-column">
<div class="column-header">
<div class="column-header-back">&larr;</div>
<div class="column-header-title">Post</div>
</div>
<div class="status">
<div class="status-header">
<div class="avatar">{{ config.site.author | first }}</div>
<div class="status-meta">
<div class="status-name-row">
<span class="status-name">{{ config.site.author }}</span>
<span class="status-handle">@felix@{{ config.site.name }}</span>
</div>
<div class="status-time">{{ published_date }}</div>
</div>
</div>
<div class="toot-subject">{{ title }}</div>
<div class="status-body">
<div class="content-area">
{{ content | safe }}
</div>
</div>
{% if taxonomy.tags %}
<div class="status-hashtags">
{% for tag in taxonomy.tags %}
<span class="hashtag">#{{ tag | replace(" ", "") }}</span>{% if not loop.last %} {% endif %}
{% endfor %}
</div>
{% endif %}
<div class="status-timestamp">
{{ published_date }} · {{ reading_time }}{% if updated_date %} · Updated {{ updated_date }}{% endif %} · via {{ config.site.name }}
</div>
<div class="engagement-strip">
<div class="engagement-item"><span class="engagement-count">0</span> Reposts</div>
<div class="engagement-item"><span class="engagement-count">0</span> Quotes</div>
<div class="engagement-item"><span class="engagement-count">0</span> Favourites</div>
</div>
<div class="status-actions">
<div class="action-btn">
<span class="action-btn-icon">&#9652;</span>
<span>Reply</span>
</div>
<div class="action-btn boost">
<span class="action-btn-icon">&#8635;</span>
<span>Boost</span>
</div>
<div class="action-btn fav">
<span class="action-btn-icon">&#9733;</span>
<span>Favourite</span>
</div>
<div class="action-btn">
<span class="action-btn-icon">&#8943;</span>
</div>
</div>
</div>
</main>
<aside class="right-sidebar">
<div class="sidebar-card">
<div class="sidebar-card-header">About {{ config.site.author }}</div>
<div class="sidebar-card-item">
<div class="avatar-sm">{{ config.site.author | first }}</div>
<div>
<div class="sidebar-item-text">{{ config.site.author }}</div>
<div class="sidebar-item-label">{{ config.site.name }}</div>
</div>
</div>
<div class="sidebar-card-item">
<div>
<div class="sidebar-item-text">{{ published_date }}</div>
<div class="sidebar-item-label">Published</div>
</div>
</div>
<div class="sidebar-card-item">
<div>
<div class="sidebar-item-text">{{ reading_time }}</div>
<div class="sidebar-item-label">Reading time</div>
</div>
</div>
</div>
{% if taxonomy.tags %}
<div class="sidebar-card">
<div class="sidebar-card-header">Hashtags</div>
{% for tag in taxonomy.tags %}
<div class="sidebar-card-item">
<div class="sidebar-item-text" style="color: var(--blue-accent);">#{{ tag | replace(" ", "") }}</div>
</div>
{% endfor %}
</div>
{% endif %}
</aside>
</div>
</body>
</html>

View File

@@ -0,0 +1,496 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;0,900;1,400;1,700&family=EB+Garamond:ital,wght@0,400;0,500;1,400;1,500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #1a2f1a; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--cover: #1a2f1a; /* Forest green */
--gold: #c9a84c;
--gold-light: #e8c97a;
--gold-dim: #8a6e30;
--paper: #faf6ed;
--paper-dark: #f0e8d5;
--ink: #1c1208;
--ink-dim: #4a3c20;
--ink-light: #8a7050;
--spine: #142614;
}
body {
background: var(--cover);
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 3px,
rgba(0,0,0,0.03) 3px,
rgba(0,0,0,0.03) 4px
),
repeating-linear-gradient(
90deg,
transparent,
transparent 3px,
rgba(0,0,0,0.03) 3px,
rgba(0,0,0,0.03) 4px
);
color: var(--ink);
font-family: "EB Garamond", "Georgia", serif;
font-size: 17px;
line-height: 1.7;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 40px 0;
}
/* Open book container */
.book {
display: flex;
max-width: 1100px;
width: 100%;
box-shadow: 0 20px 80px rgba(0,0,0,0.6), 0 4px 16px rgba(0,0,0,0.4);
}
/* Spine */
.spine {
width: 32px;
flex-shrink: 0;
background: var(--spine);
background-image: linear-gradient(90deg,
rgba(0,0,0,0.4) 0%,
rgba(255,255,255,0.06) 30%,
rgba(0,0,0,0.3) 100%
);
display: flex;
align-items: center;
justify-content: center;
}
.spine-text {
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
font-family: "Playfair Display", serif;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--gold-dim);
}
/* Left page — decorative cover flap */
.cover-flap {
width: 200px;
flex-shrink: 0;
background: var(--cover);
background-image:
linear-gradient(90deg,
rgba(0,0,0,0.2) 0%,
transparent 40%
);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
border-right: 1px solid rgba(201,168,76,0.15);
}
.flap-ornament {
width: 80px;
height: 80px;
border: 2px solid var(--gold-dim);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
position: relative;
}
.flap-ornament::before {
content: "";
position: absolute;
inset: 6px;
border: 1px solid var(--gold-dim);
border-radius: 50%;
}
.flap-ornament-inner {
font-family: "Playfair Display", serif;
font-size: 28px;
font-weight: 700;
color: var(--gold-dim);
}
.flap-site {
font-family: "Playfair Display", serif;
font-size: 12px;
font-weight: 400;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--gold-dim);
text-align: center;
line-height: 1.6;
}
.flap-divider {
width: 40px;
height: 1px;
background: var(--gold-dim);
margin: 16px auto;
}
.flap-year {
font-family: "EB Garamond", serif;
font-size: 13px;
color: var(--gold-dim);
font-style: italic;
}
/* Right — the actual page */
.page {
flex: 1;
background: var(--paper);
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 26px,
rgba(0,0,0,0.03) 26px,
rgba(0,0,0,0.03) 27px
);
padding: 56px 64px 80px 56px;
position: relative;
min-height: 100vh;
}
/* Left red margin line */
.page::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 44px;
width: 1px;
background: rgba(150,40,40,0.15);
}
/* Page top ornament */
.page-ornament-top {
text-align: center;
color: var(--gold);
font-size: 20px;
letter-spacing: 0.3em;
margin-bottom: 32px;
}
/* Chapter heading */
.chapter-label {
text-align: center;
font-family: "Playfair Display", serif;
font-size: 11px;
font-weight: 400;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--ink-light);
margin-bottom: 8px;
}
.chapter-title {
font-family: "Playfair Display", serif;
font-size: 32px;
font-weight: 700;
color: var(--ink);
text-align: center;
line-height: 1.2;
margin-bottom: 8px;
}
.chapter-subtitle {
text-align: center;
font-style: italic;
font-size: 16px;
color: var(--ink-dim);
margin-bottom: 16px;
}
/* Drop cap ornament divider */
.ornament-divider {
text-align: center;
color: var(--gold);
font-size: 16px;
letter-spacing: 0.4em;
margin: 20px 0 28px;
}
/* Meta */
.page-meta {
font-size: 13px;
color: var(--ink-light);
text-align: center;
font-style: italic;
margin-bottom: 32px;
padding-bottom: 20px;
border-bottom: 1px solid rgba(201,168,76,0.3);
}
/* Tags */
.tags-line {
text-align: center;
font-size: 12px;
color: var(--ink-light);
margin-top: -10px;
margin-bottom: 32px;
letter-spacing: 0.06em;
}
/* Content */
.content-area {
/* Drop cap on first paragraph */
}
.content-area > p:first-of-type::first-letter {
font-family: "Playfair Display", serif;
font-size: 4.5em;
font-weight: 700;
float: left;
line-height: 0.75;
padding-right: 8px;
padding-top: 6px;
color: var(--ink);
}
.content-area h1 {
font-family: "Playfair Display", serif;
font-size: 24px;
font-weight: 700;
color: var(--ink);
margin-top: 40px;
margin-bottom: 12px;
text-align: center;
letter-spacing: 0.02em;
}
.content-area h2 {
font-family: "Playfair Display", serif;
font-size: 19px;
font-weight: 700;
font-style: italic;
color: var(--ink-dim);
margin-top: 32px;
margin-bottom: 10px;
}
.content-area h3 {
font-size: 16px;
font-weight: 600;
color: var(--ink-dim);
margin-top: 24px;
margin-bottom: 8px;
font-style: italic;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 15px;
font-weight: 600;
color: var(--ink-light);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area p {
font-size: 17px;
margin-bottom: 14px;
color: var(--ink);
text-align: justify;
hyphens: auto;
line-height: 1.75;
}
.content-area a {
color: var(--ink-dim);
text-decoration: underline;
text-underline-offset: 2px;
}
.content-area code {
font-family: "Courier New", monospace;
font-size: 14px;
background: var(--paper-dark);
color: var(--ink-dim);
padding: 1px 4px;
border-radius: 2px;
}
.content-area pre {
background: var(--paper-dark);
border-left: 3px solid var(--gold-dim);
padding: 14px 18px;
margin: 16px 0;
overflow-x: auto;
font-size: 14px;
}
.content-area pre code {
background: none;
padding: 0;
}
.content-area blockquote {
padding: 12px 24px;
margin: 20px 0;
font-style: italic;
font-size: 18px;
color: var(--ink-dim);
border-left: 3px solid var(--gold-dim);
}
.content-area ul {
margin: 10px 0 16px 28px;
color: var(--ink);
}
.content-area ol {
margin: 10px 0 16px 32px;
color: var(--ink);
}
.content-area li {
margin-bottom: 6px;
font-size: 17px;
line-height: 1.6;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px auto;
font-size: 15px;
}
.content-area th {
border-bottom: 2px solid var(--ink-dim);
padding: 8px 12px;
font-weight: 700;
text-align: left;
font-family: "Playfair Display", serif;
font-size: 14px;
}
.content-area td {
padding: 8px 12px;
border-bottom: 1px solid rgba(138,112,80,0.2);
}
.content-area img {
max-width: 100%;
display: block;
margin: 16px auto;
}
.content-area hr {
border: none;
text-align: center;
margin: 28px 0;
font-size: 18px;
color: var(--gold-dim);
letter-spacing: 0.4em;
}
.content-area hr::before {
content: "* * *";
}
/* Page numbers */
.page-footer {
margin-top: 40px;
padding-top: 12px;
border-top: 1px solid rgba(201,168,76,0.25);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: var(--ink-light);
font-style: italic;
}
.page-number {
font-family: "EB Garamond", serif;
font-size: 14px;
}
@media (max-width: 800px) {
.cover-flap { display: none; }
.page { padding: 36px 24px 48px; }
.page::before { left: 20px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="book">
<div class="spine">
<div class="spine-text">{{ config.site.name }}</div>
</div>
<div class="cover-flap">
<div class="flap-ornament">
<div class="flap-ornament-inner">FF</div>
</div>
<div class="flap-divider"></div>
<div class="flap-site">{{ config.site.name }}</div>
<div class="flap-divider"></div>
<div class="flap-year">{{ published_date | truncate(4, true, "") }}</div>
</div>
<div class="page">
<div class="page-ornament-top">&#10048; &#10048; &#10048;</div>
<div class="chapter-label">{{ config.site.author }}</div>
<h1 class="chapter-title">{{ title }}</h1>
<div class="ornament-divider">&#8727; &#8727; &#8727;</div>
<div class="page-meta">
{{ published_date }}{% if updated_date %} — Überarbeitet {{ updated_date }}{% endif %} · {{ reading_time }}
</div>
{% if taxonomy.tags %}
<div class="tags-line">
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %} · {% endif %}{% endfor %}
</div>
{% endif %}
<div class="content-area">
{{ content | safe }}
</div>
<div class="page-footer">
<span>{{ config.site.name }}</span>
<span class="page-number">1</span>
<span>{{ config.site.author }}</span>
</div>
</div>
</div>
</body>
</html>

431
templates/invoice.html Normal file
View File

@@ -0,0 +1,431 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>Rechnung — {{ title }} — {{ config.site.name }}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #f0f0f0; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #f0f0f0;
--paper: #ffffff;
--text: #1a1a1a;
--muted: #555555;
--light: #888888;
--border: #cccccc;
--border-dark: #999999;
--accent: #1a1a1a;
}
body {
background: var(--bg);
color: var(--text);
font-family: Arial, Helvetica, "Neue Haas Grotesk", sans-serif;
font-size: 12px;
line-height: 1.4;
min-height: 100vh;
padding: 32px 16px 48px;
}
.page {
background: var(--paper);
max-width: 794px; /* A4 width at 96dpi */
margin: 0 auto;
padding: 60px 64px 80px;
box-shadow: 0 2px 16px rgba(0,0,0,0.12);
}
/* Header */
.invoice-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 48px;
padding-bottom: 28px;
border-bottom: 2px solid var(--accent);
}
.sender-block {
flex: 1;
}
.sender-name {
font-size: 18px;
font-weight: 700;
color: var(--text);
letter-spacing: -0.01em;
margin-bottom: 4px;
}
.sender-details {
font-size: 11px;
color: var(--muted);
line-height: 1.6;
}
.rechnung-block {
text-align: right;
}
.rechnung-title {
font-size: 36px;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text);
text-transform: uppercase;
line-height: 1;
margin-bottom: 8px;
}
.invoice-number {
font-size: 11px;
color: var(--muted);
margin-bottom: 2px;
}
.invoice-date {
font-size: 11px;
color: var(--muted);
}
/* Recipient block */
.recipient-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 32px;
margin-bottom: 40px;
}
.field-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.field-label {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--light);
border-bottom: 1px solid var(--border);
padding-bottom: 4px;
margin-bottom: 4px;
}
.field-value {
font-size: 12px;
color: var(--text);
line-height: 1.6;
}
/* Content title */
.content-subject {
background: #f7f7f7;
border-left: 4px solid var(--accent);
padding: 12px 16px;
margin-bottom: 28px;
}
.content-subject-label {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--light);
margin-bottom: 4px;
}
.content-subject-value {
font-size: 15px;
font-weight: 700;
color: var(--text);
}
/* Main content area */
.content-section-label {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--light);
border-bottom: 1px solid var(--border);
padding-bottom: 4px;
margin-bottom: 16px;
}
.content-area {
margin-bottom: 32px;
}
.content-area h1 {
font-size: 16px;
font-weight: 700;
color: var(--text);
margin-top: 24px;
margin-bottom: 8px;
}
.content-area h2 {
font-size: 14px;
font-weight: 700;
color: var(--text);
margin-top: 20px;
margin-bottom: 6px;
}
.content-area h3 {
font-size: 12px;
font-weight: 700;
color: var(--muted);
margin-top: 16px;
margin-bottom: 4px;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 12px;
font-weight: 700;
color: var(--muted);
margin-top: 12px;
margin-bottom: 4px;
}
.content-area p {
font-size: 12px;
margin-bottom: 10px;
color: var(--muted);
line-height: 1.55;
}
.content-area a {
color: var(--text);
text-decoration: underline;
}
.content-area code {
font-family: "Courier New", monospace;
font-size: 11px;
background: #f4f4f4;
border: 1px solid var(--border);
padding: 1px 4px;
}
.content-area pre {
background: #f4f4f4;
border: 1px solid var(--border);
padding: 12px 14px;
overflow-x: auto;
margin: 10px 0;
font-size: 11px;
}
.content-area pre code {
border: none;
padding: 0;
background: none;
}
.content-area blockquote {
border-left: 3px solid var(--border-dark);
padding: 8px 14px;
margin: 10px 0;
color: var(--muted);
font-style: italic;
}
.content-area ul {
margin: 8px 0 12px 20px;
}
.content-area ol {
margin: 8px 0 12px 24px;
}
.content-area li {
margin-bottom: 4px;
color: var(--muted);
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 12px 0;
font-size: 11px;
}
.content-area th {
background: #f0f0f0;
padding: 7px 10px;
text-align: left;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
border: 1px solid var(--border);
}
.content-area td {
padding: 7px 10px;
border: 1px solid var(--border);
color: var(--muted);
}
.content-area img {
max-width: 100%;
margin: 8px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 16px 0;
}
/* Summary / tags row */
.summary-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
padding: 12px 0;
border-top: 1px solid var(--border);
border-bottom: 2px solid var(--accent);
margin-bottom: 40px;
}
.summary-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.summary-tag {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
border: 1px solid var(--border);
padding: 2px 7px;
}
.summary-reading {
font-size: 11px;
color: var(--light);
}
/* Footer */
.invoice-footer {
border-top: 1px solid var(--border);
padding-top: 20px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
font-size: 10px;
color: var(--light);
}
.footer-block-label {
font-size: 8px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--border-dark);
margin-bottom: 3px;
}
.footer-block-value {
line-height: 1.6;
}
@media (max-width: 600px) {
.page { padding: 32px 20px 48px; }
.invoice-header { flex-direction: column; gap: 20px; }
.rechnung-block { text-align: left; }
.recipient-section { grid-template-columns: 1fr; }
.invoice-footer { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="page">
<div class="invoice-header">
<div class="sender-block">
<div class="sender-name">{{ config.site.author }}</div>
<div class="sender-details">
{{ config.site.name }}<br>
Erstellt am {{ published_date }}
{% if updated_date %}<br>Aktualisiert {{ updated_date }}{% endif %}
</div>
</div>
<div class="rechnung-block">
<div class="rechnung-title">RECHNUNG</div>
<div class="invoice-number">Nr. {{ published_date | replace("-", "") }}</div>
<div class="invoice-date">Datum: {{ published_date }}</div>
</div>
</div>
<div class="recipient-section">
<div>
<div class="field-label">Empfänger</div>
<div class="field-value">Leser/in<br>{{ config.site.name }}</div>
</div>
<div>
<div class="field-label">Lesezeit</div>
<div class="field-value">{{ reading_time }}</div>
</div>
</div>
<div class="content-subject">
<div class="content-subject-label">Betreff</div>
<div class="content-subject-value">{{ title }}</div>
</div>
<div class="content-section-label">Inhalt</div>
<div class="content-area">
{{ content | safe }}
</div>
{% if taxonomy.tags %}
<div class="summary-row">
<div class="summary-tags">
{% for tag in taxonomy.tags %}
<span class="summary-tag">{{ tag }}</span>
{% endfor %}
</div>
<div class="summary-reading">{{ reading_time }}</div>
</div>
{% endif %}
<div class="invoice-footer">
<div>
<div class="footer-block-label">Autor</div>
<div class="footer-block-value">{{ config.site.author }}</div>
</div>
<div>
<div class="footer-block-label">Website</div>
<div class="footer-block-value">{{ config.site.name }}</div>
</div>
<div>
<div class="footer-block-label">Datum</div>
<div class="footer-block-value">{{ published_date }}</div>
</div>
</div>
</div>
</body>
</html>

440
templates/ipad-ui.html Normal file
View File

@@ -0,0 +1,440 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #e5e5ea; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #e5e5ea;
--card: rgba(255,255,255,0.88);
--blue: #007aff;
--text: #1c1c1e;
--secondary: #3c3c43;
--tertiary: #8e8e93;
--border: rgba(60,60,67,0.1);
}
body {
background: var(--bg);
background-image:
radial-gradient(at 20% 20%, rgba(0,122,255,0.08) 0%, transparent 50%),
radial-gradient(at 80% 80%, rgba(52,199,89,0.06) 0%, transparent 50%);
color: var(--text);
font-family: "Nunito", -apple-system, "SF Pro Rounded", system-ui, sans-serif;
font-size: 16px;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Status bar */
.status-bar {
height: 20px;
background: transparent;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 24px;
font-size: 11px;
font-weight: 600;
color: var(--secondary);
}
/* Navigation bar */
.nav-bar {
background: rgba(255,255,255,0.72);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border-bottom: 1px solid var(--border);
padding: 12px 28px;
display: flex;
justify-content: space-between;
align-items: center;
}
.nav-back {
font-size: 15px;
font-weight: 600;
color: var(--blue);
display: flex;
align-items: center;
gap: 4px;
}
.nav-back::before {
content: "<";
font-weight: 300;
}
.nav-title {
font-size: 16px;
font-weight: 700;
color: var(--text);
}
.nav-right {
font-size: 14px;
font-weight: 600;
color: var(--blue);
}
/* Page */
.page {
flex: 1;
padding: 24px 24px 48px;
display: flex;
flex-direction: column;
align-items: center;
}
/* Main card */
.main-card {
background: var(--card);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border-radius: 24px;
box-shadow:
0 2px 8px rgba(0,0,0,0.08),
0 12px 40px rgba(0,0,0,0.1);
width: 100%;
max-width: 740px;
overflow: hidden;
}
/* Card header */
.card-header {
padding: 28px 32px 0;
border-bottom: 1px solid var(--border);
padding-bottom: 24px;
}
.reading-label {
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--blue);
margin-bottom: 10px;
}
.card-title {
font-size: 28px;
font-weight: 800;
letter-spacing: -0.02em;
color: var(--text);
line-height: 1.2;
margin-bottom: 14px;
}
.card-meta {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.meta-author-chip {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--blue);
color: #fff;
font-size: 12px;
font-weight: 700;
padding: 4px 10px 4px 6px;
border-radius: 999px;
}
.meta-author-avatar {
width: 18px;
height: 18px;
border-radius: 50%;
background: rgba(255,255,255,0.3);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 800;
}
.meta-pill {
font-size: 12px;
font-weight: 600;
color: var(--tertiary);
background: rgba(142,142,147,0.12);
padding: 4px 10px;
border-radius: 999px;
}
/* Tags in header */
.card-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin-top: 12px;
}
.tag {
font-size: 11px;
font-weight: 700;
color: var(--blue);
background: rgba(0,122,255,0.1);
padding: 3px 10px;
border-radius: 999px;
}
/* Card body */
.card-body {
padding: 28px 32px 36px;
}
/* Content */
.content-area h1 {
font-size: 24px;
font-weight: 800;
letter-spacing: -0.02em;
color: var(--text);
margin-top: 32px;
margin-bottom: 12px;
}
.content-area h2 {
font-size: 20px;
font-weight: 700;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h3 {
font-size: 17px;
font-weight: 700;
color: var(--text);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 15px;
font-weight: 700;
color: var(--secondary);
margin-top: 16px;
margin-bottom: 6px;
}
.content-area p {
margin-bottom: 14px;
color: var(--secondary);
font-size: 16px;
line-height: 1.7;
font-weight: 400;
}
.content-area a {
color: var(--blue);
text-decoration: none;
font-weight: 600;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "SF Mono", "Menlo", monospace;
font-size: 13px;
background: rgba(142,142,147,0.14);
color: #c0392b;
padding: 2px 6px;
border-radius: 6px;
}
.content-area pre {
background: #1c1c1e;
border-radius: 16px;
padding: 20px 22px;
margin: 16px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: #e5e5ea;
padding: 0;
font-size: 13px;
}
.content-area blockquote {
background: rgba(0,122,255,0.06);
border-left: 4px solid var(--blue);
border-radius: 0 12px 12px 0;
padding: 14px 18px;
margin: 16px 0;
}
.content-area blockquote p {
color: var(--blue);
font-weight: 600;
margin: 0;
}
.content-area ul {
margin: 10px 0 16px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 20px;
margin-bottom: 6px;
color: var(--secondary);
position: relative;
}
.content-area ul li::before {
content: "";
position: absolute;
left: 4px;
top: 9px;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--blue);
}
.content-area ol {
margin: 10px 0 16px 22px;
color: var(--secondary);
}
.content-area li {
margin-bottom: 6px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
border-radius: 12px;
overflow: hidden;
font-size: 14px;
}
.content-area th {
background: rgba(142,142,147,0.12);
padding: 10px 14px;
text-align: left;
font-size: 12px;
font-weight: 700;
color: var(--tertiary);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 10px 14px;
border-top: 1px solid var(--border);
color: var(--secondary);
}
.content-area img {
max-width: 100%;
border-radius: 12px;
margin: 12px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 24px 0;
}
/* Bottom home indicator */
.home-indicator {
display: flex;
justify-content: center;
padding: 16px 0 8px;
}
.home-bar {
width: 134px;
height: 5px;
background: rgba(60,60,67,0.3);
border-radius: 3px;
}
@media (max-width: 600px) {
.card-header,
.card-body {
padding-left: 20px;
padding-right: 20px;
}
.card-title { font-size: 22px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="status-bar">
{{ published_date }} · {{ reading_time }}
</div>
<nav class="nav-bar">
<div class="nav-back">{{ config.site.name }}</div>
<div class="nav-title">Reader</div>
<div class="nav-right">Done</div>
</nav>
<div class="page">
<div class="main-card">
<div class="card-header">
<div class="reading-label">Article</div>
<h1 class="card-title">{{ title }}</h1>
<div class="card-meta">
<div class="meta-author-chip">
<span class="meta-author-avatar">F</span>
<span>{{ config.site.author }}</span>
</div>
<span class="meta-pill">{{ published_date }}</span>
<span class="meta-pill">{{ reading_time }}</span>
{% if updated_date %}<span class="meta-pill">Updated {{ updated_date }}</span>{% endif %}
</div>
{% if taxonomy.tags %}
<div class="card-tags">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
<div class="card-body">
<div class="content-area">
{{ content | safe }}
</div>
</div>
</div>
</div>
<div class="home-indicator">
<div class="home-bar"></div>
</div>
</body>
</html>

363
templates/math-theorem.html Normal file
View File

@@ -0,0 +1,363 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Libre+Caslon+Text:ital,wght@0,400;0,700;1,400&family=Libre+Caslon+Display&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #dcdccc; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--paper: #fffff8;
--text: #111111;
--muted: #444444;
--dim: #777777;
--border: #cccccc;
--accent: #00369a;
--block-bg: #f8f8f4;
}
body {
background: #dcdccc;
color: var(--text);
font-family: "Libre Caslon Text", "Computer Modern", "Latin Modern Math", "Times New Roman", serif;
font-size: 16px;
line-height: 1.65;
min-height: 100vh;
padding: 40px 16px;
}
/* Main paper */
.paper {
background: var(--paper);
max-width: 700px;
margin: 0 auto;
padding: 72px 80px 80px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1), 0 8px 32px rgba(0,0,0,0.15);
}
/* Title block */
.paper-title {
text-align: center;
margin-bottom: 48px;
padding-bottom: 32px;
border-bottom: 1px solid var(--border);
}
.paper-maintitle {
font-family: "Libre Caslon Display", "Libre Caslon Text", serif;
font-size: 26px;
font-weight: 400;
color: var(--text);
line-height: 1.25;
margin-bottom: 20px;
}
.paper-author {
font-size: 14px;
color: var(--muted);
margin-bottom: 6px;
}
.paper-date {
font-size: 13px;
color: var(--dim);
font-style: italic;
}
/* Abstract */
.abstract {
margin: 0 32px 40px;
padding: 0 0 32px;
border-bottom: 1px solid var(--border);
}
.abstract-label {
font-weight: 700;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.08em;
text-align: center;
margin-bottom: 10px;
color: var(--text);
}
.abstract-text {
font-size: 14px;
font-style: italic;
color: var(--muted);
text-align: justify;
hyphens: auto;
}
/* Section headings */
.content-area {
counter-reset: section theorem definition lemma;
}
.content-area h1 {
font-size: 18px;
font-weight: 700;
color: var(--text);
margin-top: 40px;
margin-bottom: 14px;
counter-increment: section;
}
.content-area h1::before {
content: counter(section) ". ";
color: var(--muted);
}
.content-area h2 {
font-size: 16px;
font-weight: 700;
font-style: italic;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h3 {
font-size: 15px;
font-weight: 700;
color: var(--muted);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 14px;
font-weight: 700;
color: var(--dim);
margin-top: 16px;
margin-bottom: 6px;
}
.content-area p {
margin-bottom: 14px;
text-align: justify;
hyphens: auto;
color: var(--text);
}
.content-area a {
color: var(--accent);
text-decoration: none;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "Courier New", monospace;
font-size: 14px;
color: #444;
background: #f0f0e8;
padding: 1px 4px;
border-radius: 2px;
}
.content-area pre {
background: var(--block-bg);
border: 1px solid var(--border);
padding: 14px 18px;
margin: 16px 0;
overflow-x: auto;
font-size: 13px;
}
.content-area pre code {
background: none;
padding: 0;
}
/* Theorem-style blockquotes */
.content-area blockquote {
background: var(--block-bg);
border-left: 4px solid var(--accent);
padding: 16px 20px;
margin: 20px 0;
font-style: italic;
counter-increment: theorem;
}
.content-area blockquote::before {
display: block;
content: "Theorem " counter(theorem) ".";
font-style: normal;
font-weight: 700;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--accent);
margin-bottom: 8px;
}
.content-area blockquote p {
margin: 0;
text-align: left;
}
.content-area ul {
margin: 10px 0 16px 28px;
color: var(--text);
}
.content-area ol {
margin: 10px 0 16px 28px;
color: var(--text);
}
.content-area li {
margin-bottom: 5px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px auto;
font-size: 14px;
}
.content-area th {
font-weight: 700;
padding: 8px 14px;
border-bottom: 2px solid var(--text);
text-align: center;
font-size: 13px;
}
.content-area td {
padding: 7px 14px;
border-bottom: 1px solid var(--border);
text-align: center;
}
.content-area img {
max-width: 100%;
display: block;
margin: 16px auto;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 28px 0;
}
/* Proof block — indented */
.proof-block {
margin: 16px 0;
padding-left: 20px;
border-left: 2px solid var(--border);
}
.proof-label {
font-style: italic;
font-size: 14px;
color: var(--muted);
margin-bottom: 6px;
}
.qed {
display: block;
text-align: right;
font-size: 18px;
color: var(--text);
margin-top: 8px;
}
/* Keywords / tags */
.keywords {
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid var(--border);
font-size: 13px;
color: var(--muted);
}
.keywords-label {
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 12px;
margin-bottom: 6px;
color: var(--text);
}
/* Footer */
.paper-footer {
margin-top: 40px;
padding-top: 16px;
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--dim);
text-align: center;
font-style: italic;
}
@media (max-width: 700px) {
.paper { padding: 40px 24px 48px; }
.abstract { margin: 0 0 32px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="paper">
<div class="paper-title">
<h1 class="paper-maintitle" style="counter-increment: none;">{{ title }}</h1>
<div class="paper-author">{{ config.site.author }}</div>
<div class="paper-date">{{ published_date }}{% if updated_date %} (revised {{ updated_date }}){% endif %} · {{ reading_time }}</div>
{% if taxonomy.tags %}
<div class="paper-date" style="margin-top: 6px;">
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}
</div>
{% endif %}
</div>
<div class="abstract">
<div class="abstract-label">Abstract</div>
<div class="abstract-text">
This paper presents the contents of "{{ title }}" by {{ config.site.author }}, submitted {{ published_date }}. The following sections develop the main arguments and supporting material in a systematic manner.
</div>
</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="proof-block">
<div class="proof-label">Proof.</div>
<p style="font-size: 14px; color: var(--muted);">The assertions above follow directly from the preceding definitions and observations. The reader may verify each claim by inspection.</p>
<span class="qed">&#9632;</span>
</div>
{% if taxonomy.tags %}
<div class="keywords">
<div class="keywords-label">Keywords</div>
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}.
</div>
{% endif %}
<div class="paper-footer">
{{ config.site.name }} · {{ config.site.author }} · {{ published_date }}
</div>
</div>
</body>
</html>

327
templates/meditation.html Normal file
View File

@@ -0,0 +1,327 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #faf7f2; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--cream: #faf7f2;
--warm-white: #f5f0e8;
--text: #2c2825;
--text-light: #7a6e65;
--text-lighter: #b0a499;
--accent: #8b7355;
--circle: #c4b89a;
}
html {
font-size: 18px;
}
body {
background: var(--cream);
color: var(--text);
font-family: "Cormorant Garamond", Georgia, serif;
font-weight: 400;
line-height: 1.85;
min-height: 100vh;
}
.page {
max-width: 580px;
margin: 0 auto;
padding: 80px 32px 120px;
}
/* Circle motif */
.circle-motif {
display: flex;
justify-content: center;
margin-bottom: 64px;
}
.circle {
width: 48px;
height: 48px;
border-radius: 50%;
border: 1px solid var(--circle);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.circle::before {
content: "";
width: 36px;
height: 36px;
border-radius: 50%;
border: 1px solid var(--circle);
opacity: 0.6;
}
/* Title area */
.post-header {
text-align: center;
margin-bottom: 64px;
}
.post-title {
font-size: 2.2rem;
font-weight: 300;
letter-spacing: 0.02em;
line-height: 1.25;
color: var(--text);
margin-bottom: 0;
}
/* Content */
.post-content {
font-size: 1.05rem;
line-height: 1.9;
}
.post-content h1 {
font-size: 1.7rem;
font-weight: 400;
letter-spacing: 0.01em;
margin-top: 64px;
margin-bottom: 24px;
color: var(--text);
text-align: center;
}
.post-content h2 {
font-size: 1.35rem;
font-weight: 400;
font-style: italic;
margin-top: 52px;
margin-bottom: 20px;
color: var(--accent);
text-align: center;
}
.post-content h3 {
font-size: 1.1rem;
font-weight: 500;
margin-top: 40px;
margin-bottom: 16px;
color: var(--text);
letter-spacing: 0.05em;
text-transform: uppercase;
font-size: 0.85rem;
}
.post-content p {
margin-bottom: 28px;
}
.post-content p:first-child::first-letter {
font-size: 3.5rem;
font-weight: 300;
line-height: 0.8;
float: left;
margin-right: 6px;
margin-top: 6px;
color: var(--accent);
}
.post-content a {
color: var(--accent);
text-decoration: none;
border-bottom: 1px solid var(--circle);
}
.post-content a:hover {
border-bottom-color: var(--accent);
}
.post-content em {
font-style: italic;
}
.post-content strong {
font-weight: 600;
color: var(--text);
}
.post-content code {
font-family: "Courier New", monospace;
font-size: 0.85em;
background: var(--warm-white);
padding: 1px 6px;
border-radius: 2px;
color: var(--accent);
}
.post-content pre {
background: var(--warm-white);
padding: 24px 28px;
margin: 32px 0;
overflow-x: auto;
font-family: "Courier New", monospace;
font-size: 0.82em;
line-height: 1.7;
border-left: 2px solid var(--circle);
}
.post-content pre code {
background: none;
padding: 0;
color: var(--text);
}
.post-content blockquote {
text-align: center;
padding: 32px 0;
margin: 40px 0;
border-top: 1px solid var(--circle);
border-bottom: 1px solid var(--circle);
font-size: 1.2rem;
font-style: italic;
color: var(--text-light);
font-weight: 300;
}
.post-content ul,
.post-content ol {
margin: 20px 0 28px 0;
padding-left: 0;
list-style: none;
}
.post-content ul li {
padding-left: 20px;
position: relative;
margin-bottom: 10px;
}
.post-content ul li::before {
content: "·";
position: absolute;
left: 6px;
color: var(--circle);
font-size: 1.2em;
}
.post-content ol {
counter-reset: item;
}
.post-content ol li {
counter-increment: item;
padding-left: 28px;
position: relative;
margin-bottom: 10px;
}
.post-content ol li::before {
content: counter(item) ".";
position: absolute;
left: 0;
color: var(--text-light);
font-variant-numeric: oldstyle-nums;
}
.post-content table {
width: 100%;
border-collapse: collapse;
margin: 32px 0;
font-size: 0.95rem;
}
.post-content th {
border-bottom: 1px solid var(--circle);
padding: 8px 12px;
text-align: left;
font-weight: 500;
letter-spacing: 0.05em;
color: var(--text-light);
font-size: 0.8rem;
text-transform: uppercase;
}
.post-content td {
border-bottom: 1px solid var(--warm-white);
padding: 10px 12px;
}
.post-content img {
max-width: 100%;
display: block;
margin: 40px auto;
}
.post-content hr {
border: none;
text-align: center;
margin: 48px 0;
color: var(--text-lighter);
font-size: 1.2rem;
letter-spacing: 0.5em;
}
.post-content hr::after {
content: "· · ·";
}
/* Footer */
.post-footer {
margin-top: 80px;
padding-top: 32px;
border-top: 1px solid var(--warm-white);
text-align: center;
font-size: 0.8rem;
color: var(--text-lighter);
letter-spacing: 0.08em;
line-height: 2;
}
.post-footer .site-name {
color: var(--text-light);
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="page">
<div class="circle-motif">
<div class="circle"></div>
</div>
<header class="post-header">
<h1 class="post-title">{{ title }}</h1>
</header>
<main class="post-content">
{{ content | safe }}
</main>
<footer class="post-footer">
<div class="site-name">{{ config.site.name }}</div>
<div>{{ config.site.author }}</div>
<div>{{ published_date }}{% if updated_date %} · revised {{ updated_date }}{% endif %}</div>
<div>{{ reading_time }}</div>
{% if taxonomy.tags %}
<div>
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %} · {% endif %}{% endfor %}
</div>
{% endif %}
</footer>
</div>
</body>
</html>

395
templates/newspaper.html Normal file
View File

@@ -0,0 +1,395 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=UnifrakturMaguntia&family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=Old+Standard+TT:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #8a7a60; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--newsprint: #f4ecd8;
--newsprint-dark: #e8dcc5;
--ink: #1a1410;
--ink-light: #4a3f30;
--ink-lighter: #7a6a55;
--rule-color: #2a1e10;
}
body {
background: #8a7a60;
color: var(--ink);
font-family: "Old Standard TT", Georgia, serif;
font-size: 15px;
line-height: 1.6;
}
.broadsheet {
max-width: 960px;
margin: 24px auto;
background: var(--newsprint);
padding: 0;
box-shadow: 4px 4px 20px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,0,0,0.1);
}
/* Masthead */
.masthead {
padding: 20px 32px 0;
text-align: center;
border-bottom: 4px double var(--rule-color);
}
.masthead-top {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
color: var(--ink-lighter);
padding-bottom: 8px;
border-bottom: 1px solid var(--rule-color);
margin-bottom: 12px;
font-style: italic;
}
.masthead-name {
font-family: "UnifrakturMaguntia", cursive;
font-size: clamp(36px, 6vw, 72px);
color: var(--ink);
line-height: 1;
letter-spacing: 0.01em;
margin-bottom: 8px;
}
.masthead-tagline {
font-size: 11px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-lighter);
font-style: italic;
margin-bottom: 12px;
}
/* Horizontal rules */
.rule-thick {
border: none;
border-top: 3px solid var(--rule-color);
margin: 0;
}
.rule-thin {
border: none;
border-top: 1px solid var(--rule-color);
margin: 4px 0;
}
.rule-double {
border: none;
border-top: 3px double var(--rule-color);
margin: 4px 0;
}
/* Headline section */
.headline-section {
padding: 24px 32px 0;
}
.kicker {
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-lighter);
margin-bottom: 8px;
font-style: italic;
}
.main-headline {
font-family: "Playfair Display", Georgia, serif;
font-size: clamp(26px, 4.5vw, 52px);
font-weight: 900;
line-height: 1.1;
color: var(--ink);
margin-bottom: 12px;
letter-spacing: -0.01em;
}
.deck {
font-family: "Playfair Display", Georgia, serif;
font-size: 17px;
font-style: italic;
color: var(--ink-light);
line-height: 1.4;
margin-bottom: 16px;
}
.byline-bar {
display: flex;
align-items: center;
gap: 20px;
padding: 8px 0;
border-top: 1px solid var(--rule-color);
border-bottom: 1px solid var(--rule-color);
margin-bottom: 20px;
font-size: 11px;
color: var(--ink-lighter);
letter-spacing: 0.05em;
text-transform: uppercase;
}
.byline-bar strong {
color: var(--ink);
font-weight: 700;
}
/* Main content columns */
.content-columns {
padding: 0 32px 32px;
}
.columns-body {
columns: 2;
column-gap: 32px;
column-rule: 1px solid var(--rule-color);
font-size: 14px;
line-height: 1.65;
text-align: justify;
hyphens: auto;
}
/* Drop cap on first paragraph */
.columns-body p:first-child::first-letter {
font-family: "Playfair Display", Georgia, serif;
font-size: 5rem;
font-weight: 900;
line-height: 0.8;
float: left;
margin-right: 6px;
margin-top: 4px;
color: var(--ink);
}
.columns-body h1 {
column-span: all;
font-family: "Playfair Display", serif;
font-size: 22px;
font-weight: 700;
margin-top: 24px;
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 2px solid var(--rule-color);
text-align: left;
}
.columns-body h2 {
font-family: "Playfair Display", serif;
font-size: 17px;
font-weight: 700;
font-style: italic;
margin-top: 20px;
margin-bottom: 8px;
color: var(--ink);
}
.columns-body h3 {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
margin-top: 16px;
margin-bottom: 6px;
color: var(--ink-light);
}
.columns-body p {
margin-bottom: 10px;
}
.columns-body a {
color: var(--ink);
text-decoration: underline;
}
.columns-body code {
font-family: "Courier New", monospace;
font-size: 12px;
background: var(--newsprint-dark);
padding: 0 3px;
border: 1px solid rgba(0,0,0,0.1);
}
.columns-body pre {
background: var(--newsprint-dark);
border: 1px solid var(--rule-color);
padding: 12px 14px;
margin: 12px 0;
overflow-x: auto;
font-family: "Courier New", monospace;
font-size: 11px;
line-height: 1.5;
column-span: all;
}
.columns-body pre code {
background: none;
border: none;
padding: 0;
}
.columns-body blockquote {
border-top: 2px solid var(--rule-color);
border-bottom: 2px solid var(--rule-color);
padding: 12px 0;
margin: 16px 0;
font-family: "Playfair Display", serif;
font-size: 15px;
font-style: italic;
color: var(--ink-light);
text-align: center;
column-span: all;
}
.columns-body ul,
.columns-body ol {
margin: 8px 0 12px 16px;
}
.columns-body li {
margin-bottom: 4px;
}
.columns-body table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 12px;
column-span: all;
}
.columns-body th {
border-top: 2px solid var(--ink);
border-bottom: 1px solid var(--ink);
padding: 5px 8px;
text-align: left;
font-weight: 700;
font-size: 11px;
letter-spacing: 0.05em;
}
.columns-body td {
border-bottom: 1px solid var(--newsprint-dark);
padding: 5px 8px;
}
.columns-body img {
max-width: 100%;
display: block;
margin: 12px auto;
border: 1px solid var(--ink-lighter);
filter: sepia(20%) contrast(1.05);
}
.columns-body hr {
border: none;
border-top: 1px solid var(--rule-color);
margin: 16px 0;
column-span: all;
}
/* Page footer */
.page-footer {
border-top: 4px double var(--rule-color);
padding: 10px 32px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
color: var(--ink-lighter);
background: var(--newsprint-dark);
}
.page-footer .folio {
font-family: "Playfair Display", serif;
font-style: italic;
}
.tags-footer {
font-size: 11px;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media (max-width: 640px) {
.columns-body {
columns: 1;
}
.broadsheet {
margin: 0;
}
.headline-section,
.content-columns {
padding-left: 20px;
padding-right: 20px;
}
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="broadsheet">
<header class="masthead">
<div class="masthead-top">
<span>Vol. 1, No. 1</span>
<span>Established {{ published_date }}</span>
<span>{{ reading_time }}</span>
</div>
<div class="masthead-name">{{ config.site.name }}</div>
<div class="masthead-tagline">Independent publishing — {{ config.site.author }}</div>
</header>
<div class="headline-section">
<hr class="rule-thick">
<hr class="rule-thin">
<div class="kicker">Featured</div>
<h1 class="main-headline">{{ title }}</h1>
<p class="deck">An exploration of ideas by {{ config.site.author }}, published on {{ published_date }}.</p>
<div class="byline-bar">
<span>By <strong>{{ config.site.author }}</strong></span>
<span>{{ published_date }}</span>
<span>{{ reading_time }}</span>
{% if updated_date %}<span>Updated {{ updated_date }}</span>{% endif %}
{% if taxonomy.tags %}
<span class="tags-footer">
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %} · {% endif %}{% endfor %}
</span>
{% endif %}
</div>
</div>
<div class="content-columns">
<div class="columns-body">
{{ content | safe }}
</div>
</div>
<footer class="page-footer">
<span class="folio">{{ config.site.name }}</span>
<span>{{ published_date }}</span>
<span class="folio">{{ config.site.author }}</span>
</footer>
</div>
</body>
</html>

446
templates/old-steam.html Normal file
View File

@@ -0,0 +1,446 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
background: #3d3d3d;
font-family: "Verdana", "Tahoma", Arial, sans-serif;
font-size: 12px;
color: #dadada;
min-height: 100vh;
}
body {
background:
radial-gradient(ellipse at top, #5d5d5d 0%, #2b2b2b 70%),
#2b2b2b;
padding: 24px;
min-height: 100vh;
}
.steam-window {
max-width: 960px;
margin: 0 auto;
background: #4a4a4a;
border: 1px solid #111;
box-shadow:
0 0 0 1px #6a6a6a inset,
0 8px 32px rgba(0,0,0,0.6);
}
.titlebar {
background: linear-gradient(to bottom, #5d7a9a 0%, #3f5a78 50%, #2e4560 100%);
color: #ffffff;
padding: 4px 8px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #1e2e40;
text-shadow: 0 -1px 0 rgba(0,0,0,0.5);
font-size: 11px;
font-weight: bold;
}
.titlebar-left {
display: flex;
align-items: center;
gap: 6px;
}
.steam-mark {
display: inline-block;
width: 14px;
height: 14px;
background: #000;
border: 1px solid #6d8ab0;
color: #a7c6e8;
font-family: "Times New Roman", serif;
font-style: italic;
font-weight: bold;
text-align: center;
line-height: 12px;
font-size: 10px;
}
.titlebar-btns { display: flex; gap: 2px; }
.tb-b {
width: 16px; height: 14px;
background: linear-gradient(to bottom, #6d7d90, #394756);
border: 1px solid #1e2e40;
color: #fff;
font-size: 9px;
display: flex; align-items: center; justify-content: center;
}
.mainnav {
background: linear-gradient(to bottom, #3f4b5a 0%, #242c36 100%);
border-bottom: 1px solid #000;
padding: 0;
display: flex;
gap: 0;
}
.mainnav-tab {
padding: 8px 18px;
color: #c0c8d2;
font-weight: bold;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.06em;
border-right: 1px solid #111;
cursor: default;
user-select: none;
}
.mainnav-tab.active {
background: linear-gradient(to bottom, #556b85 0%, #33455c 100%);
color: #ffcc66;
box-shadow: inset 0 -2px 0 #ffa200;
}
.mainnav-tab:not(.active):hover {
color: #fff;
}
.subbar {
background: #1e1e1e;
border-bottom: 1px solid #000;
padding: 4px 12px;
font-size: 10px;
color: #8a9ab0;
display: flex;
justify-content: space-between;
align-items: center;
}
.subbar .crumbs { font-family: "Courier New", monospace; }
.subbar .who { color: #99c266; font-weight: bold; }
.body-grid {
display: grid;
grid-template-columns: 200px 1fr;
min-height: 520px;
background: #2b2b2b;
}
.side {
background: linear-gradient(to right, #2a3240 0%, #1c2230 100%);
border-right: 1px solid #000;
padding: 10px 0;
color: #c0c8d2;
}
.side-section-title {
padding: 4px 14px;
font-size: 10px;
font-weight: bold;
text-transform: uppercase;
color: #ffcc66;
letter-spacing: 0.08em;
border-bottom: 1px solid #000;
background: rgba(0,0,0,0.25);
margin-bottom: 6px;
}
.side-item {
padding: 4px 14px 4px 26px;
font-size: 11px;
position: relative;
}
.side-item::before {
content: "▸";
color: #6da3d5;
position: absolute;
left: 12px;
}
.side-item.alert::before {
content: "●";
color: #6fc54c;
}
.side-item b { color: #fff; }
.side-meta {
margin-top: 14px;
padding: 10px 14px;
font-size: 10px;
color: #8a9ab0;
border-top: 1px solid rgba(0,0,0,0.4);
}
.side-meta .k { color: #c0c8d2; display: block; font-weight: bold; margin-top: 6px; }
.side-meta .v { color: #99c266; }
.main {
padding: 0;
background: #2b2b2b;
}
.hero {
background:
linear-gradient(to bottom, rgba(30,40,58,0.92) 0%, rgba(20,26,38,0.98) 100%),
repeating-linear-gradient(90deg, rgba(255,255,255,0.02) 0 2px, transparent 2px 4px);
padding: 24px 28px 20px;
border-bottom: 2px solid #000;
box-shadow: 0 -1px 0 rgba(255,255,255,0.04) inset;
}
.hero h1 {
font-family: "Verdana", "Tahoma", sans-serif;
font-size: 22px;
color: #ffcc66;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(0,0,0,0.6);
margin: 0 0 10px 0;
padding: 0;
border: none;
}
.hero .byline {
color: #99c266;
font-size: 11px;
font-weight: bold;
}
.hero .byline .date { color: #8a9ab0; font-weight: normal; margin-left: 8px; }
.article {
padding: 24px 28px;
color: #dadada;
font-size: 12px;
line-height: 1.7;
}
.article h2 {
font-family: "Verdana", sans-serif;
font-size: 14px;
color: #ffcc66;
text-transform: uppercase;
letter-spacing: 0.06em;
margin: 24px 0 8px;
padding-bottom: 4px;
border-bottom: 1px solid #1e2e40;
}
.article h3 {
font-size: 12px;
color: #a7c6e8;
font-weight: bold;
margin: 18px 0 6px;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.article p { margin-bottom: 12px; }
.article strong { color: #fff; }
.article em { color: #a7c6e8; font-style: normal; }
.article a {
color: #ffcc66;
text-decoration: none;
border-bottom: 1px dotted #ffcc66;
}
.article a:hover {
color: #fff;
border-bottom-color: #fff;
}
.article ul, .article ol {
margin: 10px 0 14px 20px;
}
.article li { margin-bottom: 4px; }
.article li::marker { color: #6da3d5; }
.article code {
font-family: "Consolas", "Courier New", monospace;
background: #1b1b1b;
color: #ffcc66;
border: 1px solid #000;
padding: 0 4px;
font-size: 11px;
}
.article pre {
background: #151515;
border: 1px solid #000;
box-shadow: inset 0 0 0 1px #333;
padding: 12px;
margin: 14px 0;
overflow-x: auto;
font-family: "Consolas", "Courier New", monospace;
font-size: 11px;
color: #c0c8d2;
line-height: 1.5;
}
.article pre code {
background: none;
border: none;
padding: 0;
color: inherit;
}
.article blockquote {
border-left: 3px solid #ffa200;
background: rgba(255,162,0,0.04);
padding: 10px 14px;
margin: 14px 0;
color: #c0c8d2;
font-style: italic;
}
.article table {
border-collapse: collapse;
width: 100%;
margin: 14px 0;
font-size: 11px;
}
.article th {
background: #1e2e40;
color: #ffcc66;
padding: 6px 10px;
text-align: left;
text-transform: uppercase;
font-size: 10px;
letter-spacing: 0.05em;
border-bottom: 1px solid #000;
}
.article td {
padding: 5px 10px;
border-bottom: 1px solid #1e1e1e;
color: #c0c8d2;
}
.article tr:nth-child(even) td { background: rgba(255,255,255,0.02); }
.article hr {
border: none;
height: 1px;
background: linear-gradient(to right, transparent, #4c6b22, transparent);
margin: 24px 0;
}
.status {
background: linear-gradient(to bottom, #3f4b5a 0%, #242c36 100%);
border-top: 1px solid #000;
padding: 4px 10px;
display: flex;
justify-content: space-between;
font-size: 10px;
color: #8a9ab0;
}
.status .online { color: #6fc54c; }
.status .online::before { content: "● "; }
.back-pill {
position: fixed;
top: calc(1rem + env(safe-area-inset-top, 0px));
left: calc(1rem + env(safe-area-inset-left, 0px));
z-index: 9999;
font-family: "Verdana", sans-serif;
font-size: 11px;
padding: 5px 11px;
background: linear-gradient(to bottom, #5d7a9a, #2e4560);
color: #fff;
text-decoration: none;
border: 1px solid #000;
box-shadow: 0 1px 0 rgba(255,255,255,0.15) inset, 0 2px 6px rgba(0,0,0,0.5);
font-weight: bold;
text-shadow: 0 -1px 0 rgba(0,0,0,0.5);
}
.back-pill:hover { color: #ffcc66; }
@media (max-width: 720px) {
.body-grid { grid-template-columns: 1fr; }
.side { border-right: none; border-bottom: 1px solid #000; }
.article { padding: 20px 18px; }
}
</style>
</head>
<body>
<a class="back-pill" href="/{{ preview_query }}">&larr; back</a>
<div class="steam-window">
<div class="titlebar">
<div class="titlebar-left">
<span class="steam-mark">S</span>
<span>Steam — {{ title }}</span>
</div>
<div class="titlebar-btns">
<div class="tb-b">_</div>
<div class="tb-b"></div>
<div class="tb-b">×</div>
</div>
</div>
<div class="mainnav">
<div class="mainnav-tab">Store</div>
<div class="mainnav-tab">News</div>
<div class="mainnav-tab active">My Games</div>
<div class="mainnav-tab">Community</div>
<div class="mainnav-tab">Friends</div>
</div>
<div class="subbar">
<span class="crumbs">My Games &nbsp;&nbsp; Workshop &nbsp;&nbsp; {{ title }}</span>
<span class="who">{{ config.site.author }} <small style="color:#8a9ab0;font-weight:normal;">(Online)</small></span>
</div>
<div class="body-grid">
<aside class="side">
<div class="side-section-title">Library</div>
<div class="side-item alert"><b>{{ title }}</b></div>
<div class="side-item">Blog</div>
<div class="side-item">Projects</div>
<div class="side-item">About</div>
<div class="side-meta">
<span class="k">Installed:</span>
<span class="v">{{ published_date }}</span>
<span class="k">Play time:</span>
<span class="v">{{ reading_time }}</span>
{% if taxonomy.tags %}
<span class="k">Tags:</span>
{% for tag in taxonomy.tags %}
<span class="v" style="display:inline-block;margin-right:6px;">#{{ tag }}</span>
{% endfor %}
{% endif %}
</div>
</aside>
<main class="main">
<div class="hero">
<h1>{{ title }}</h1>
<div class="byline">
{{ config.site.author }}
<span class="date">· {{ published_date }} · {{ reading_time }}</span>
</div>
</div>
<article class="article">
{{ content | safe }}
</article>
</main>
</div>
<div class="status">
<span class="online">{{ config.site.author }} is online</span>
<span>{{ published_date }}</span>
</div>
</div>
</body>
</html>

514
templates/passport.html Normal file
View File

@@ -0,0 +1,514 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400&family=Libre+Caslon+Text:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #1a1a2e; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--navy: #0a1628;
--navy-mid: #122244;
--gold: #c9a84c;
--gold-light: #e8c97a;
--paper: #f5f0e5;
--paper-dark: #e8e0cc;
--ink: #1a1410;
--ink-dim: #3d3020;
--ink-light: #7a6a50;
}
body {
background: #1a1a2e;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 40px 16px 60px;
font-family: "Libre Caslon Text", "Georgia", serif;
}
.document {
width: 100%;
max-width: 720px;
}
/* Passport cover */
.passport-cover {
background: var(--navy);
background-image:
repeating-linear-gradient(45deg,
rgba(201,168,76,0.03) 0px,
rgba(201,168,76,0.03) 1px,
transparent 1px,
transparent 12px
);
padding: 32px 40px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
border-bottom: 3px solid var(--gold);
}
.cover-emblem {
width: 80px;
height: 80px;
border: 2px solid var(--gold);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
position: relative;
}
.cover-emblem::before {
content: "";
position: absolute;
inset: 6px;
border: 1px solid rgba(201,168,76,0.4);
border-radius: 50%;
}
.cover-emblem-inner {
font-size: 28px;
color: var(--gold);
font-weight: 700;
letter-spacing: -0.02em;
}
.cover-country {
font-family: "Courier Prime", monospace;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--gold-light);
margin-bottom: 8px;
}
.cover-type {
font-size: 24px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 4px;
}
.cover-type-de {
font-size: 14px;
letter-spacing: 0.08em;
color: rgba(201,168,76,0.6);
}
/* Security watermark pattern */
.cover-watermark {
margin-top: 20px;
font-size: 9px;
font-family: "Courier Prime", monospace;
color: rgba(201,168,76,0.2);
letter-spacing: 0.3em;
text-transform: uppercase;
}
/* Photo + biodata page */
.biodata-page {
background: var(--paper);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Ccircle cx='50' cy='50' r='30' fill='none' stroke='%23c9a84c' stroke-width='0.3' stroke-opacity='0.15'/%3E%3C/svg%3E");
background-size: 60px 60px;
padding: 28px 32px;
border-bottom: 2px solid var(--gold);
}
.biodata-top {
display: grid;
grid-template-columns: 100px 1fr;
gap: 20px;
margin-bottom: 20px;
}
.photo-box {
width: 100px;
height: 120px;
border: 1px solid var(--gold);
background: var(--paper-dark);
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.photo-placeholder {
font-size: 40px;
color: var(--ink-light);
line-height: 1;
}
.photo-box-label {
position: absolute;
bottom: 4px;
left: 0;
right: 0;
text-align: center;
font-family: "Courier Prime", monospace;
font-size: 8px;
letter-spacing: 0.12em;
color: var(--ink-light);
text-transform: uppercase;
}
.biodata-fields {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
align-content: start;
}
.field {
display: flex;
flex-direction: column;
gap: 1px;
}
.field-label {
font-family: "Courier Prime", monospace;
font-size: 8px;
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-light);
}
.field-value {
font-size: 14px;
color: var(--ink);
font-weight: 700;
border-bottom: 1px solid var(--ink-light);
padding-bottom: 2px;
}
.field-value-sm {
font-size: 12px;
font-weight: 400;
}
/* Document number banner */
.doc-number-strip {
background: var(--navy-mid);
color: var(--gold);
font-family: "Courier Prime", monospace;
font-size: 11px;
letter-spacing: 0.3em;
padding: 6px 32px;
display: flex;
justify-content: space-between;
}
/* Tags as stamps */
.stamps-section {
background: var(--paper);
padding: 20px 32px;
border-bottom: 1px solid var(--paper-dark);
}
.stamps-label {
font-family: "Courier Prime", monospace;
font-size: 9px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-light);
margin-bottom: 12px;
}
.stamps-grid {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.stamp-item {
border: 2px solid var(--ink-light);
padding: 6px 12px;
transform: rotate(-2deg);
font-family: "Courier Prime", monospace;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--ink-dim);
}
.stamp-item:nth-child(2n) { transform: rotate(1.5deg); }
.stamp-item:nth-child(3n) { transform: rotate(-1deg); border-color: var(--navy-mid); color: var(--navy-mid); }
.stamp-item:nth-child(4n) { transform: rotate(2.5deg); }
/* Content / observations pages */
.content-pages {
background: var(--paper);
padding: 28px 36px 48px;
}
.observations-header {
font-family: "Courier Prime", monospace;
font-size: 9px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-light);
border-bottom: 1px solid var(--paper-dark);
padding-bottom: 6px;
margin-bottom: 20px;
}
.content-area h1 {
font-family: "Libre Caslon Text", serif;
font-size: 22px;
font-weight: 700;
color: var(--ink);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h2 {
font-size: 18px;
font-weight: 700;
color: var(--ink-dim);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h3 {
font-size: 15px;
font-weight: 700;
color: var(--ink-dim);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
font-weight: 700;
color: var(--ink-light);
margin-top: 14px;
margin-bottom: 5px;
}
.content-area p {
font-size: 15px;
margin-bottom: 12px;
color: var(--ink);
line-height: 1.7;
text-align: justify;
hyphens: auto;
}
.content-area a {
color: var(--navy-mid);
text-decoration: underline;
}
.content-area code {
font-family: "Courier Prime", monospace;
font-size: 13px;
background: var(--paper-dark);
color: var(--ink-dim);
padding: 1px 5px;
}
.content-area pre {
background: var(--paper-dark);
border-left: 3px solid var(--navy-mid);
padding: 12px 16px;
margin: 12px 0;
overflow-x: auto;
font-size: 13px;
font-family: "Courier Prime", monospace;
}
.content-area pre code {
background: none;
padding: 0;
}
.content-area blockquote {
border-left: 3px solid var(--gold);
padding: 10px 16px;
margin: 12px 0;
background: rgba(201,168,76,0.06);
font-style: italic;
color: var(--ink-dim);
}
.content-area ul {
margin: 8px 0 14px 22px;
color: var(--ink);
}
.content-area ol {
margin: 8px 0 14px 26px;
color: var(--ink);
}
.content-area li {
margin-bottom: 5px;
font-size: 15px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 12px 0;
font-size: 14px;
}
.content-area th {
background: var(--navy-mid);
color: var(--gold-light);
padding: 7px 12px;
text-align: left;
font-family: "Courier Prime", monospace;
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.content-area td {
padding: 7px 12px;
border-bottom: 1px solid var(--paper-dark);
}
.content-area img {
max-width: 100%;
border: 1px solid var(--paper-dark);
margin: 10px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--paper-dark);
margin: 20px 0;
}
/* MRZ (Machine Readable Zone) */
.mrz {
background: var(--navy);
padding: 12px 20px;
font-family: "Courier Prime", monospace;
font-size: 12px;
color: var(--gold-light);
letter-spacing: 0.15em;
overflow-x: auto;
}
.mrz-line {
white-space: nowrap;
margin-bottom: 2px;
opacity: 0.7;
}
@media (max-width: 600px) {
.biodata-top { grid-template-columns: 1fr; }
.biodata-fields { grid-template-columns: 1fr; }
.content-pages { padding: 20px 20px 40px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="document">
<div class="passport-cover">
<div class="cover-emblem">
<div class="cover-emblem-inner">{{ config.site.author | first }}</div>
</div>
<div class="cover-country">{{ config.site.name }}</div>
<div class="cover-type">REISEPASS</div>
<div class="cover-type-de">PASSPORT / PASSEPORT</div>
<div class="cover-watermark">
DOCUMENT FOR READING ONLY · DOKUMENT NUR ZUM LESEN · DOCUMENT POUR LECTURE UNIQUEMENT
</div>
</div>
<div class="doc-number-strip">
<span>P&lt;DEU</span>
<span>{{ published_date | replace("-", "") }}</span>
<span>{{ config.site.name | upper | truncate(12, true, "") | replace(" ", "") }}</span>
</div>
<div class="biodata-page">
<div class="biodata-top">
<div class="photo-box">
<div class="photo-placeholder">&#9786;</div>
<div class="photo-box-label">Photo</div>
</div>
<div class="biodata-fields">
<div class="field">
<div class="field-label">Surname / Nom</div>
<div class="field-value">{{ config.site.author | upper }}</div>
</div>
<div class="field">
<div class="field-label">Type / Type</div>
<div class="field-value field-value-sm">ARTICLE</div>
</div>
<div class="field">
<div class="field-label">Date of Publication</div>
<div class="field-value field-value-sm">{{ published_date }}</div>
</div>
<div class="field">
<div class="field-label">Reading Time</div>
<div class="field-value field-value-sm">{{ reading_time }}</div>
</div>
{% if updated_date %}
<div class="field">
<div class="field-label">Revised / Überarbeitet</div>
<div class="field-value field-value-sm">{{ updated_date }}</div>
</div>
{% endif %}
<div class="field">
<div class="field-label">Issuing Authority</div>
<div class="field-value field-value-sm">{{ config.site.name }}</div>
</div>
</div>
</div>
</div>
{% if taxonomy.tags %}
<div class="stamps-section">
<div class="stamps-label">Entry Stamps / Einreisestempel</div>
<div class="stamps-grid">
{% for tag in taxonomy.tags %}
<div class="stamp-item">{{ tag }}</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="content-pages">
<div class="observations-header">Observations / Bemerkungen — {{ title }}</div>
<div class="content-area">
{{ content | safe }}
</div>
</div>
<div class="mrz">
<div class="mrz-line">P&lt;DEU{{ config.site.author | upper | replace(" ", "&lt;") }}&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;</div>
<div class="mrz-line">{{ published_date | replace("-", "") }}0DEU9991231M{{ updated_date | default("0000000") | replace("-", "") }}&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;{{ reading_time | replace(" min read", "") | replace(" ", "") }}</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,606 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #1a0a38; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--purple-dark: #4b2d8f;
--purple-mid: #6441a5;
--purple-light: #9b59b6;
--purple-pale: #c39bd3;
--bg-gradient-start: #2c1654;
--bg-gradient-end: #1a0a38;
--card: #ffffff;
--text: #1a1a2e;
--muted: #4a4a6a;
--dim: #8e8ea8;
--border: #e8e4f0;
}
body {
background: linear-gradient(160deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
min-height: 100vh;
font-family: "Inter", -apple-system, system-ui, sans-serif;
font-size: 15px;
line-height: 1.55;
padding: 24px 16px 60px;
}
/* App chrome */
.app {
max-width: 680px;
margin: 0 auto;
}
/* Top navigation */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 4px 20px;
}
.nav-back {
font-size: 14px;
font-weight: 600;
color: rgba(255,255,255,0.7);
}
.nav-title {
font-size: 14px;
font-weight: 600;
color: rgba(255,255,255,0.9);
}
.nav-action {
font-size: 14px;
font-weight: 600;
color: #c39bd3;
}
/* Podcast artwork + info */
.episode-hero {
display: flex;
align-items: flex-start;
gap: 16px;
margin-bottom: 20px;
padding: 20px;
background: rgba(255,255,255,0.07);
border-radius: 20px;
backdrop-filter: blur(12px);
}
.artwork {
width: 88px;
height: 88px;
border-radius: 14px;
background: linear-gradient(135deg, var(--purple-mid), #e91e8c);
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 20px rgba(0,0,0,0.4);
overflow: hidden;
}
.artwork-letter {
font-size: 36px;
font-weight: 800;
color: rgba(255,255,255,0.9);
letter-spacing: -0.03em;
}
.episode-info {
flex: 1;
min-width: 0;
}
.episode-show {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--purple-pale);
margin-bottom: 4px;
}
.episode-title {
font-size: 17px;
font-weight: 700;
color: #fff;
line-height: 1.25;
margin-bottom: 8px;
}
.episode-meta {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.episode-meta-item {
font-size: 12px;
font-weight: 500;
color: rgba(255,255,255,0.5);
}
.episode-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--purple-pale);
background: rgba(155,89,182,0.2);
padding: 2px 8px;
border-radius: 999px;
}
/* Waveform */
.waveform {
margin-bottom: 20px;
padding: 16px 20px;
background: rgba(255,255,255,0.07);
border-radius: 16px;
}
.waveform-bars {
display: flex;
gap: 2px;
align-items: center;
height: 40px;
}
.waveform-bar {
flex: 1;
background: rgba(195,155,211,0.4);
border-radius: 2px;
min-height: 4px;
}
/* Generate waveform via nth-child heights */
.waveform-bar:nth-child(1) { height: 20%; }
.waveform-bar:nth-child(2) { height: 60%; }
.waveform-bar:nth-child(3) { height: 40%; }
.waveform-bar:nth-child(4) { height: 85%; }
.waveform-bar:nth-child(5) { height: 55%; }
.waveform-bar:nth-child(6) { height: 100%; background: #c39bd3; }
.waveform-bar:nth-child(7) { height: 70%; background: #c39bd3; }
.waveform-bar:nth-child(8) { height: 45%; }
.waveform-bar:nth-child(9) { height: 30%; }
.waveform-bar:nth-child(10) { height: 65%; }
.waveform-bar:nth-child(11) { height: 50%; }
.waveform-bar:nth-child(12) { height: 80%; }
.waveform-bar:nth-child(13) { height: 35%; }
.waveform-bar:nth-child(14) { height: 60%; }
.waveform-bar:nth-child(15) { height: 90%; }
.waveform-bar:nth-child(16) { height: 45%; }
.waveform-bar:nth-child(17) { height: 25%; }
.waveform-bar:nth-child(18) { height: 70%; }
.waveform-bar:nth-child(19) { height: 55%; }
.waveform-bar:nth-child(20) { height: 40%; }
.waveform-bar:nth-child(21) { height: 75%; }
.waveform-bar:nth-child(22) { height: 35%; }
.waveform-bar:nth-child(23) { height: 60%; }
.waveform-bar:nth-child(24) { height: 45%; }
.waveform-bar:nth-child(25) { height: 85%; }
.waveform-bar:nth-child(26) { height: 30%; }
.waveform-bar:nth-child(27) { height: 65%; }
.waveform-bar:nth-child(28) { height: 50%; }
.waveform-bar:nth-child(29) { height: 40%; }
.waveform-bar:nth-child(30) { height: 70%; }
.waveform-timeline {
display: flex;
justify-content: space-between;
margin-top: 6px;
font-size: 10px;
font-weight: 500;
color: rgba(255,255,255,0.35);
}
/* Playback controls */
.controls {
display: flex;
align-items: center;
justify-content: center;
gap: 28px;
margin-bottom: 20px;
}
.ctrl-btn {
font-size: 20px;
color: rgba(255,255,255,0.6);
}
.ctrl-play {
width: 52px;
height: 52px;
background: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: var(--purple-dark);
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
}
/* Content card */
.notes-card {
background: var(--card);
border-radius: 20px;
overflow: hidden;
}
.notes-header {
padding: 20px 24px 16px;
border-bottom: 1px solid var(--border);
}
.notes-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--purple-mid);
margin-bottom: 4px;
}
.notes-title {
font-size: 20px;
font-weight: 700;
color: var(--text);
line-height: 1.3;
}
.notes-meta {
display: flex;
gap: 12px;
margin-top: 8px;
flex-wrap: wrap;
}
.notes-meta-chip {
font-size: 11px;
font-weight: 600;
color: var(--purple-mid);
background: rgba(100,65,165,0.08);
padding: 3px 9px;
border-radius: 999px;
}
/* Tags */
.notes-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
padding: 12px 24px;
border-bottom: 1px solid var(--border);
}
.tag {
font-size: 11px;
font-weight: 600;
color: var(--purple-mid);
background: rgba(100,65,165,0.08);
padding: 3px 10px;
border-radius: 999px;
}
.notes-body {
padding: 20px 24px 28px;
}
/* Content */
.content-area h1 {
font-size: 20px;
font-weight: 700;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h2 {
font-size: 16px;
font-weight: 700;
color: var(--purple-mid);
margin-top: 22px;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.06em;
font-size: 12px;
}
.content-area h3 {
font-size: 15px;
font-weight: 600;
color: var(--text);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 14px;
font-weight: 600;
color: var(--muted);
margin-top: 14px;
margin-bottom: 4px;
}
.content-area p {
font-size: 15px;
margin-bottom: 12px;
color: var(--muted);
line-height: 1.65;
}
.content-area a {
color: var(--purple-mid);
text-decoration: none;
font-weight: 500;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "SF Mono", "Menlo", monospace;
font-size: 12.5px;
background: rgba(100,65,165,0.08);
color: var(--purple-dark);
padding: 2px 6px;
border-radius: 5px;
}
.content-area pre {
background: var(--text);
border-radius: 12px;
padding: 16px 18px;
margin: 14px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: #e8e4f0;
padding: 0;
font-size: 13px;
}
.content-area blockquote {
border-left: 3px solid var(--purple-mid);
background: rgba(100,65,165,0.05);
border-radius: 0 10px 10px 0;
padding: 12px 16px;
margin: 14px 0;
}
.content-area blockquote p {
color: var(--purple-dark);
font-weight: 500;
margin: 0;
}
.content-area ul {
margin: 8px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 18px;
margin-bottom: 5px;
color: var(--muted);
position: relative;
}
.content-area ul li::before {
content: "";
position: absolute;
left: 4px;
top: 8px;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--purple-pale);
}
.content-area ol {
margin: 8px 0 14px 22px;
color: var(--muted);
}
.content-area li {
margin-bottom: 5px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 14px;
border-radius: 10px;
overflow: hidden;
}
.content-area th {
background: rgba(100,65,165,0.08);
padding: 9px 13px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--purple-mid);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 9px 13px;
border-top: 1px solid var(--border);
color: var(--muted);
}
.content-area img {
max-width: 100%;
border-radius: 10px;
margin: 10px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 20px 0;
}
/* Subscribe section */
.subscribe-bar {
margin-top: 20px;
padding: 16px 20px;
background: rgba(255,255,255,0.07);
border-radius: 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.subscribe-text {
font-size: 13px;
font-weight: 600;
color: rgba(255,255,255,0.8);
}
.subscribe-btn {
font-size: 12px;
font-weight: 700;
color: var(--purple-dark);
background: #fff;
padding: 7px 16px;
border-radius: 999px;
text-transform: uppercase;
letter-spacing: 0.08em;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="app">
<nav class="nav">
<div class="nav-back">Library</div>
<div class="nav-title">{{ config.site.name }}</div>
<div class="nav-action">Share</div>
</nav>
<div class="episode-hero">
<div class="artwork">
<div class="artwork-letter">{{ config.site.author | first }}</div>
</div>
<div class="episode-info">
<div class="episode-show">{{ config.site.name }}</div>
<div class="episode-title">{{ title }}</div>
<div class="episode-meta">
<span class="episode-label">EPISODE</span>
<span class="episode-meta-item">{{ published_date }}</span>
<span class="episode-meta-item">{{ reading_time }}</span>
</div>
</div>
</div>
<div class="waveform">
<div class="waveform-bars">
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
<div class="waveform-bar"></div>
</div>
<div class="waveform-timeline">
<span>0:00</span>
<span>{{ reading_time }}</span>
</div>
</div>
<div class="controls">
<div class="ctrl-btn">&#8634;</div>
<div class="ctrl-btn">&#9664;&#9664;</div>
<div class="ctrl-play">&#9654;</div>
<div class="ctrl-btn">&#9654;&#9654;</div>
<div class="ctrl-btn">&#9654;&#9654;&#9654;</div>
</div>
<div class="notes-card">
<div class="notes-header">
<div class="notes-label">Show Notes</div>
<div class="notes-title">{{ title }}</div>
<div class="notes-meta">
<span class="notes-meta-chip">{{ config.site.author }}</span>
<span class="notes-meta-chip">{{ published_date }}</span>
{% if updated_date %}<span class="notes-meta-chip">Updated {{ updated_date }}</span>{% endif %}
</div>
</div>
{% if taxonomy.tags %}
<div class="notes-tags">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
<div class="notes-body">
<div class="content-area">
{{ content | safe }}
</div>
</div>
</div>
<div class="subscribe-bar">
<div class="subscribe-text">{{ config.site.name }}</div>
<div class="subscribe-btn">Subscribe</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,307 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }}(1) — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #0a0a0a; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--green: #33ff33;
--green-dim: #22bb22;
--bg: #0a0a0a;
}
body {
background: var(--bg);
color: var(--green);
font-family: "IBM Plex Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.5;
min-height: 100vh;
}
/* CRT phosphor glow */
body::before {
content: "";
position: fixed;
inset: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0,0,0,0.15) 2px,
rgba(0,0,0,0.15) 4px
);
pointer-events: none;
z-index: 999;
}
.page {
max-width: 900px;
margin: 0 auto;
padding: 20px 24px 60px;
}
/* Man page header and footer */
.man-header,
.man-footer {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 700;
font-size: 14px;
color: var(--green);
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 4px 0;
border-bottom: 1px solid var(--green-dim);
margin-bottom: 24px;
}
.man-footer {
border-bottom: none;
border-top: 1px solid var(--green-dim);
margin-top: 32px;
margin-bottom: 0;
padding-top: 8px;
}
.man-header-center,
.man-footer-center {
text-align: center;
}
/* Section headings */
.man-section {
font-weight: 700;
text-transform: uppercase;
color: var(--green);
margin-top: 24px;
margin-bottom: 8px;
font-size: 14px;
letter-spacing: 0.08em;
}
.man-section-body {
padding-left: 7ch;
}
/* NAME section */
.man-name-line {
padding-left: 7ch;
margin-bottom: 8px;
}
/* SYNOPSIS */
.man-synopsis {
padding-left: 7ch;
font-weight: 700;
margin-bottom: 8px;
}
/* Content area */
.content-area {
padding-left: 7ch;
}
.content-area h1 {
font-weight: 700;
text-transform: uppercase;
font-size: 14px;
letter-spacing: 0.08em;
color: var(--green);
padding-left: -7ch;
margin-left: -7ch;
margin-top: 24px;
margin-bottom: 8px;
}
.content-area h2 {
font-weight: 700;
font-size: 14px;
color: var(--green);
margin-top: 20px;
margin-bottom: 6px;
text-transform: uppercase;
}
.content-area h3 {
font-weight: 700;
font-size: 14px;
color: var(--green-dim);
margin-top: 16px;
margin-bottom: 4px;
}
.content-area p {
margin-bottom: 12px;
text-shadow: 0 0 2px rgba(51,255,51,0.3);
}
.content-area a {
color: var(--green);
text-decoration: underline;
}
.content-area code {
font-family: "IBM Plex Mono", monospace;
font-weight: 700;
}
.content-area pre {
background: #000;
border-left: 2px solid var(--green-dim);
padding: 12px 16px;
margin: 12px 0;
overflow-x: auto;
}
.content-area pre code {
font-weight: 400;
}
.content-area blockquote {
border-left: 2px solid var(--green-dim);
padding-left: 16px;
margin: 12px 0;
color: var(--green-dim);
font-style: italic;
}
.content-area ul {
margin: 8px 0 12px 0;
list-style: none;
padding: 0;
}
.content-area ul li::before {
content: "o ";
color: var(--green-dim);
}
.content-area ol {
margin: 8px 0 12px 0;
list-style: none;
padding: 0;
counter-reset: man-list;
}
.content-area ol li {
counter-increment: man-list;
}
.content-area ol li::before {
content: counter(man-list) ". ";
color: var(--green-dim);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 12px 0;
font-size: 13px;
}
.content-area th {
font-weight: 700;
text-transform: uppercase;
padding: 4px 12px 4px 0;
text-align: left;
border-bottom: 1px solid var(--green-dim);
}
.content-area td {
padding: 4px 12px 4px 0;
border-bottom: 1px solid rgba(34,187,34,0.2);
}
.content-area img {
max-width: 100%;
filter: grayscale(100%) sepia(50%) hue-rotate(80deg) brightness(0.8);
border: 1px solid var(--green-dim);
margin: 8px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--green-dim);
margin: 20px 0;
}
.meta-section {
font-size: 13px;
color: var(--green-dim);
padding-left: 7ch;
margin-bottom: 16px;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="page">
<div class="man-header">
<span>POST(1)</span>
<span class="man-header-center">General Commands Manual</span>
<span>POST(1)</span>
</div>
<div class="man-section">NAME</div>
<div class="man-name-line">
{{ title | lower | replace(" ", "_") }} — {{ title }}
</div>
<div class="man-section">SYNOPSIS</div>
<div class="man-synopsis">
<strong>read</strong> [<em>-v</em>] [<em>-author {{ config.site.author }}</em>] <em>{{ title | lower | replace(" ", "_") }}</em>
</div>
<div class="man-section">DESCRIPTION</div>
<div class="meta-section">
<div>AUTHOR {{ config.site.author }}</div>
<div>DATE {{ published_date }}</div>
<div>READING {{ reading_time }}</div>
{% if updated_date %}<div>UPDATED {{ updated_date }}</div>{% endif %}
{% if taxonomy.tags %}<div>TAGS {% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}</div>{% endif %}
</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="man-section" style="margin-top: 32px;">SEE ALSO</div>
<div class="meta-section">
{{ config.site.name }}(1), blog(7)
</div>
<div class="man-section">AUTHOR</div>
<div class="meta-section">
Written by {{ config.site.author }}.
</div>
<div class="man-footer">
<span>{{ config.site.name }}</span>
<span class="man-footer-center">{{ published_date }}</span>
<span>POST(1)</span>
</div>
</div>
</body>
</html>

423
templates/stage-play.html Normal file
View File

@@ -0,0 +1,423 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #d0c8b8; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--paper: #fffff8;
--ink: #111111;
--ink-dim: #444444;
--ink-light: #777777;
--border: #cccccc;
}
body {
background: #d0c8b8;
min-height: 100vh;
padding: 40px 16px 80px;
font-family: "Courier Prime", "Courier New", monospace;
font-size: 14px;
line-height: 1.6;
color: var(--ink);
}
/* Script page */
.script {
background: var(--paper);
max-width: 760px;
margin: 0 auto;
padding: 60px 80px 80px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15), 0 8px 40px rgba(0,0,0,0.15);
}
/* Title page block */
.title-block {
text-align: center;
margin-bottom: 60px;
padding-bottom: 40px;
border-bottom: 1px solid var(--border);
}
.title-label {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--ink-light);
margin-bottom: 20px;
}
.title-main {
font-size: 28px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink);
line-height: 1.2;
margin-bottom: 12px;
}
.title-subtitle {
font-size: 14px;
font-style: italic;
color: var(--ink-dim);
margin-bottom: 40px;
}
.title-byline {
font-size: 14px;
color: var(--ink-dim);
line-height: 2;
}
/* ACT heading */
.act-heading {
text-align: center;
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--ink);
margin: 40px 0 24px;
}
/* Scene heading */
.scene-heading {
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink);
margin: 32px 0 16px;
}
/* Stage direction */
.stage-direction {
font-style: italic;
color: var(--ink-dim);
margin: 12px 64px;
font-size: 13px;
line-height: 1.55;
}
/* Character name */
.character {
text-align: center;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
margin-top: 20px;
margin-bottom: 4px;
font-size: 14px;
}
/* Dialogue */
.dialogue {
margin: 0 80px 16px;
font-size: 14px;
line-height: 1.65;
}
/* Parenthetical */
.paren {
text-align: center;
font-style: italic;
color: var(--ink-dim);
margin-bottom: 4px;
font-size: 13px;
}
/* Content area — rendered markdown */
.content-area {
margin-top: 24px;
}
.content-area h1 {
text-align: center;
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--ink);
margin-top: 40px;
margin-bottom: 20px;
}
.content-area h2 {
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ink);
margin-top: 28px;
margin-bottom: 12px;
}
.content-area h3 {
text-align: center;
font-weight: 700;
text-transform: uppercase;
font-size: 13px;
color: var(--ink-dim);
margin-top: 24px;
margin-bottom: 4px;
}
.content-area h4 {
font-style: italic;
font-size: 13px;
color: var(--ink-dim);
margin: 8px 64px;
}
.content-area h5, .content-area h6 {
font-size: 13px;
color: var(--ink-light);
margin: 8px 0;
}
.content-area p {
margin: 0 80px 16px;
font-size: 14px;
line-height: 1.65;
}
.content-area a {
color: var(--ink);
text-decoration: underline;
}
.content-area code {
font-family: "Courier Prime", monospace;
font-size: 13px;
background: rgba(0,0,0,0.06);
padding: 1px 4px;
}
.content-area pre {
background: rgba(0,0,0,0.04);
border-left: 3px solid var(--border);
padding: 12px 16px;
margin: 14px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
padding: 0;
}
/* Blockquote = stage direction */
.content-area blockquote {
font-style: italic;
color: var(--ink-dim);
margin: 12px 64px;
font-size: 13px;
}
.content-area blockquote::before {
content: "[";
}
.content-area blockquote::after {
content: "]";
}
.content-area blockquote p {
margin: 0;
display: inline;
}
.content-area ul {
margin: 10px 80px 16px;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 16px;
margin-bottom: 4px;
position: relative;
}
.content-area ul li::before {
content: "—";
position: absolute;
left: 0;
}
.content-area ol {
margin: 10px 80px 16px;
color: var(--ink);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 13px;
}
.content-area th {
font-weight: 700;
padding: 6px 12px;
border-bottom: 2px solid var(--ink);
text-align: left;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 6px 12px;
border-bottom: 1px solid var(--border);
}
.content-area img {
max-width: 100%;
margin: 12px 0;
}
.content-area hr {
border: none;
margin: 28px 0;
text-align: center;
font-size: 12px;
color: var(--ink-light);
letter-spacing: 0.4em;
}
.content-area hr::before {
content: "* * * * *";
}
/* Page number footer */
.script-footer {
margin-top: 48px;
padding-top: 12px;
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
font-size: 12px;
color: var(--ink-light);
}
/* Tags as cast list */
.cast-list {
margin: 20px 0;
padding: 16px 0;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.cast-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--ink-light);
margin-bottom: 8px;
text-align: center;
}
.cast-items {
display: flex;
gap: 12px;
justify-content: center;
flex-wrap: wrap;
}
.cast-item {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--ink-dim);
font-weight: 700;
}
@media (max-width: 600px) {
.script { padding: 32px 20px 48px; }
.content-area p,
.content-area ul,
.content-area ol { margin-left: 16px; margin-right: 16px; }
.dialogue { margin-left: 16px; margin-right: 16px; }
.stage-direction { margin-left: 16px; margin-right: 16px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="script">
<div class="title-block">
<div class="title-label">A Post by</div>
<div class="title-main">{{ title }}</div>
<div class="title-subtitle">A reading in one act</div>
<div class="title-byline">
Written by {{ config.site.author }}<br>
{{ config.site.name }}<br>
{{ published_date }}
</div>
</div>
{% if taxonomy.tags %}
<div class="cast-list">
<div class="cast-label">Dramatis Personae</div>
<div class="cast-items">
{% for tag in taxonomy.tags %}
<span class="cast-item">{{ tag }}</span>
{% endfor %}
</div>
</div>
{% endif %}
<div class="act-heading">ACT I</div>
<div class="scene-heading">Scene 1. {{ config.site.name }}, the present day.</div>
<div class="stage-direction">
The stage is bare. A single light falls on a reading stand. The author steps forward. Reading time: {{ reading_time }}.
</div>
<div class="character">{{ config.site.author | upper }}</div>
<div class="paren">(addressing the audience)</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="stage-direction">
The author steps back. Lights fade.
{% if updated_date %}This work was last revised on {{ updated_date }}.{% endif %}
</div>
<div class="act-heading">— CURTAIN —</div>
<div class="script-footer">
<span>{{ config.site.name }}</span>
<span>{{ published_date }}</span>
<span>1.</span>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,450 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Space+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #ffffff; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--blue: #0ea5e9;
--purple: #8b5cf6;
--bg: #ffffff;
--text: #0f172a;
--muted: #64748b;
--border: #e2e8f0;
}
body {
background: var(--bg);
color: var(--text);
font-family: "Space Grotesk", system-ui, sans-serif;
font-size: 16px;
line-height: 1.6;
min-height: 100vh;
}
/* Top nav bar */
.topbar {
position: sticky;
top: 0;
z-index: 100;
background: rgba(255,255,255,0.9);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
padding: 0 32px;
height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
}
.topbar-logo {
font-weight: 700;
font-size: 14px;
background: linear-gradient(90deg, var(--blue), var(--purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: -0.02em;
}
.topbar-meta {
font-size: 12px;
color: var(--muted);
font-weight: 500;
}
/* Hero */
.hero {
padding: 80px 32px 64px;
max-width: 960px;
margin: 0 auto;
}
.hero-badge {
display: inline-block;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--blue);
background: rgba(14,165,233,0.08);
border: 1px solid rgba(14,165,233,0.2);
padding: 4px 12px;
border-radius: 999px;
margin-bottom: 24px;
}
.hero-title {
font-size: clamp(36px, 6vw, 64px);
font-weight: 700;
letter-spacing: -0.04em;
line-height: 1.05;
margin-bottom: 24px;
background: linear-gradient(135deg, var(--text) 0%, #334155 60%, var(--purple) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-meta {
display: flex;
gap: 24px;
align-items: center;
flex-wrap: wrap;
}
.hero-meta-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--muted);
font-weight: 500;
}
.hero-meta-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: linear-gradient(135deg, var(--blue), var(--purple));
}
/* Gradient divider */
.gradient-bar {
height: 3px;
background: linear-gradient(90deg, var(--blue), var(--purple));
max-width: 960px;
margin: 0 auto 0;
}
/* Metrics strip */
.metrics-strip {
background: #f8fafc;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
padding: 24px 32px;
}
.metrics-inner {
max-width: 960px;
margin: 0 auto;
display: flex;
gap: 48px;
flex-wrap: wrap;
}
.metric {
display: flex;
flex-direction: column;
gap: 2px;
}
.metric-value {
font-size: 28px;
font-weight: 700;
letter-spacing: -0.03em;
background: linear-gradient(90deg, var(--blue), var(--purple));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.metric-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--muted);
}
/* Main content */
.main {
max-width: 960px;
margin: 0 auto;
padding: 48px 32px 80px;
}
/* Section dividers */
.content-area h2 {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.14em;
color: var(--blue);
border-top: 1px solid var(--border);
padding-top: 32px;
margin-top: 48px;
margin-bottom: 16px;
}
.content-area h3 {
font-size: 22px;
font-weight: 700;
letter-spacing: -0.03em;
color: var(--text);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 15px;
font-weight: 600;
color: var(--text);
margin-top: 20px;
margin-bottom: 8px;
}
.content-area h1 {
font-size: 32px;
font-weight: 700;
letter-spacing: -0.03em;
margin-top: 40px;
margin-bottom: 16px;
}
.content-area p {
font-size: 16px;
color: #334155;
margin-bottom: 16px;
line-height: 1.7;
}
.content-area a {
color: var(--blue);
text-decoration: none;
font-weight: 500;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "Space Mono", monospace;
font-size: 13px;
background: #f1f5f9;
color: var(--purple);
padding: 2px 6px;
border-radius: 4px;
}
.content-area pre {
background: #0f172a;
color: #e2e8f0;
padding: 20px 24px;
border-radius: 12px;
margin: 20px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: inherit;
padding: 0;
font-size: 14px;
}
.content-area blockquote {
border-left: 3px solid;
border-image: linear-gradient(180deg, var(--blue), var(--purple)) 1;
padding: 16px 20px;
margin: 20px 0;
background: linear-gradient(90deg, rgba(14,165,233,0.04), transparent);
border-radius: 0 8px 8px 0;
}
.content-area blockquote p {
font-size: 18px;
font-weight: 500;
color: var(--text);
font-style: italic;
margin: 0;
}
.content-area ul {
margin: 12px 0 20px 0;
padding: 0;
list-style: none;
}
.content-area ul li {
padding-left: 20px;
margin-bottom: 8px;
position: relative;
color: #334155;
}
.content-area ul li::before {
content: "";
position: absolute;
left: 0;
top: 10px;
width: 8px;
height: 2px;
background: linear-gradient(90deg, var(--blue), var(--purple));
}
.content-area ol {
margin: 12px 0 20px 0;
padding-left: 24px;
color: #334155;
}
.content-area li {
margin-bottom: 6px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 14px;
}
.content-area th {
background: #f8fafc;
padding: 10px 16px;
text-align: left;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--muted);
border-bottom: 2px solid var(--border);
}
.content-area td {
padding: 10px 16px;
border-bottom: 1px solid var(--border);
}
.content-area img {
max-width: 100%;
border-radius: 12px;
margin: 16px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 32px 0;
}
/* Tags */
.tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 8px;
}
.tag {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--purple);
background: rgba(139,92,246,0.08);
border: 1px solid rgba(139,92,246,0.2);
padding: 3px 10px;
border-radius: 999px;
}
/* Footer */
.footer {
border-top: 1px solid var(--border);
padding: 24px 32px;
max-width: 960px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: var(--muted);
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<nav class="topbar">
<div class="topbar-logo">{{ config.site.name }}</div>
<div class="topbar-meta">{{ published_date }} · {{ reading_time }}</div>
</nav>
<div class="hero">
<div class="hero-badge">New Post</div>
<h1 class="hero-title">{{ title }}</h1>
<div class="hero-meta">
<div class="hero-meta-item">
<div class="hero-meta-dot"></div>
<span>{{ config.site.author }}</span>
</div>
<div class="hero-meta-item">
<div class="hero-meta-dot"></div>
<span>{{ published_date }}</span>
</div>
<div class="hero-meta-item">
<div class="hero-meta-dot"></div>
<span>{{ reading_time }}</span>
</div>
{% if updated_date %}
<div class="hero-meta-item">
<div class="hero-meta-dot"></div>
<span>Updated {{ updated_date }}</span>
</div>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="tags" style="margin-top: 20px;">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
<div class="gradient-bar"></div>
<div class="metrics-strip">
<div class="metrics-inner">
<div class="metric">
<div class="metric-value">{{ reading_time | replace(" min read", "") | replace(" min", "") }}m</div>
<div class="metric-label">Read Time</div>
</div>
<div class="metric">
<div class="metric-value">100%</div>
<div class="metric-label">Signal / Noise</div>
</div>
<div class="metric">
<div class="metric-value">{{ published_date | replace("-", ".") }}</div>
<div class="metric-label">Published</div>
</div>
</div>
</div>
<div class="main">
<div class="content-area">
{{ content | safe }}
</div>
</div>
<div class="footer">
<span>&copy; {{ config.site.author }} — {{ config.site.name }}</span>
<span>{{ published_date }}</span>
</div>
</body>
</html>

361
templates/sticky-notes.html Normal file
View File

@@ -0,0 +1,361 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;600;700&family=Kalam:wght@300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #f1ece3; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--yellow: #fef08a;
--yellow-dark: #f59e0b;
--pink: #fda4af;
--pink-dark: #e11d48;
--blue: #bfdbfe;
--blue-dark: #2563eb;
--green: #bbf7d0;
--green-dark: #16a34a;
--orange: #fed7aa;
--orange-dark: #ea580c;
--bg: #f1ece3;
}
body {
background: var(--bg);
background-image:
linear-gradient(rgba(0,0,0,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.04) 1px, transparent 1px);
background-size: 32px 32px;
color: #1a1a1a;
font-family: "Kalam", "Caveat", cursive;
font-size: 16px;
line-height: 1.5;
min-height: 100vh;
padding: 40px 16px 80px;
}
.board {
max-width: 900px;
margin: 0 auto;
position: relative;
}
/* Pin at top of title note */
.note::before {
content: "";
position: absolute;
top: -8px;
left: 50%;
transform: translateX(-50%);
width: 12px;
height: 12px;
background: radial-gradient(circle at 40% 35%, #888, #222);
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.4);
z-index: 10;
}
/* Base note style */
.note {
position: relative;
padding: 24px 20px 20px;
box-shadow:
2px 2px 8px rgba(0,0,0,0.12),
4px 6px 20px rgba(0,0,0,0.1);
}
/* Title note — big yellow, centered */
.note-title {
background: var(--yellow);
max-width: 480px;
margin: 0 auto 40px;
transform: rotate(-0.8deg);
}
.note-title .note-heading {
font-family: "Caveat", cursive;
font-size: 32px;
font-weight: 700;
color: #78350f;
text-align: center;
line-height: 1.2;
margin-bottom: 12px;
}
.note-title .note-meta {
font-size: 15px;
color: #92400e;
text-align: center;
}
/* Meta strip */
.meta-strip {
display: flex;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 48px;
}
.meta-note {
background: var(--blue);
padding: 10px 18px;
transform: rotate(1.2deg);
font-size: 14px;
font-weight: 600;
color: #1e40af;
box-shadow: 2px 2px 6px rgba(0,0,0,0.1);
}
.meta-note:nth-child(2) {
background: var(--green);
color: #14532d;
transform: rotate(-0.8deg);
}
.meta-note:nth-child(3) {
background: var(--orange);
color: #7c2d12;
transform: rotate(1.5deg);
}
/* Tags as small sticky notes */
.tags-area {
display: flex;
gap: 12px;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 48px;
}
.tag-note {
background: var(--pink);
padding: 7px 14px;
font-size: 13px;
font-weight: 600;
color: var(--pink-dark);
box-shadow: 1px 2px 6px rgba(0,0,0,0.1);
position: relative;
}
.tag-note:nth-child(2n) { transform: rotate(-1.2deg); background: var(--yellow); color: var(--yellow-dark); }
.tag-note:nth-child(3n) { transform: rotate(0.8deg); background: var(--blue); color: var(--blue-dark); }
.tag-note:nth-child(4n) { transform: rotate(-1.8deg); background: var(--green); color: var(--green-dark); }
.tag-note::before { display: none; }
/* Content grid */
.content-grid {
columns: 2;
column-gap: 24px;
}
@media (max-width: 600px) {
.content-grid { columns: 1; }
}
/* Content area — each block gets a note style */
.content-area {
break-inside: avoid;
margin-bottom: 24px;
}
.content-area > * {
break-inside: avoid;
}
/* Individual content-element wrappers */
.sticky-block {
break-inside: avoid;
margin-bottom: 24px;
position: relative;
padding: 20px 18px 18px;
box-shadow: 2px 2px 8px rgba(0,0,0,0.12), 4px 6px 20px rgba(0,0,0,0.08);
}
.sticky-block::before {
content: "";
position: absolute;
top: -6px;
left: 50%;
transform: translateX(-50%);
width: 10px;
height: 10px;
background: radial-gradient(circle at 40% 35%, #888, #333);
border-radius: 50%;
box-shadow: 0 2px 3px rgba(0,0,0,0.3);
}
/* Rotate and color cycling */
.sticky-block:nth-child(1) { background: var(--yellow); transform: rotate(-0.5deg); }
.sticky-block:nth-child(2) { background: var(--pink); transform: rotate(1.2deg); }
.sticky-block:nth-child(3) { background: var(--blue); transform: rotate(-0.8deg); }
.sticky-block:nth-child(4) { background: var(--green); transform: rotate(0.6deg); }
.sticky-block:nth-child(5) { background: var(--orange); transform: rotate(-1.1deg); }
.sticky-block:nth-child(6) { background: var(--yellow); transform: rotate(0.9deg); }
.sticky-block:nth-child(7) { background: var(--pink); transform: rotate(-0.4deg); }
.sticky-block:nth-child(8) { background: var(--blue); transform: rotate(1.3deg); }
.sticky-block:nth-child(9) { background: var(--green); transform: rotate(-0.7deg); }
.sticky-block:nth-child(10) { background: var(--orange); transform: rotate(0.5deg); }
.sticky-block:nth-child(11) { background: var(--yellow); transform: rotate(-1.2deg); }
.sticky-block:nth-child(12) { background: var(--pink); transform: rotate(0.8deg); }
/* Typography inside notes */
.sticky-block h1, .sticky-block h2, .sticky-block h3,
.sticky-block h4, .sticky-block h5, .sticky-block h6 {
font-family: "Caveat", cursive;
font-weight: 700;
margin-bottom: 8px;
line-height: 1.2;
}
.sticky-block h1 { font-size: 24px; }
.sticky-block h2 { font-size: 20px; }
.sticky-block h3 { font-size: 18px; }
.sticky-block h4, .sticky-block h5, .sticky-block h6 { font-size: 16px; }
.sticky-block p {
font-size: 15px;
margin-bottom: 8px;
line-height: 1.55;
}
.sticky-block a {
color: #1e40af;
text-decoration: underline;
}
.sticky-block code {
font-family: "Courier New", monospace;
font-size: 13px;
background: rgba(0,0,0,0.08);
padding: 1px 4px;
border-radius: 3px;
}
.sticky-block pre {
background: rgba(0,0,0,0.08);
padding: 10px 12px;
margin: 8px 0;
overflow-x: auto;
border-radius: 4px;
font-size: 12px;
}
.sticky-block pre code {
background: none;
padding: 0;
}
.sticky-block blockquote {
border-left: 3px solid rgba(0,0,0,0.2);
padding: 6px 12px;
margin: 8px 0;
font-style: italic;
opacity: 0.8;
}
.sticky-block ul {
margin: 6px 0 8px 18px;
}
.sticky-block ol {
margin: 6px 0 8px 22px;
}
.sticky-block li {
margin-bottom: 4px;
font-size: 15px;
}
.sticky-block table {
width: 100%;
border-collapse: collapse;
margin: 8px 0;
font-size: 13px;
}
.sticky-block th {
font-weight: 700;
padding: 5px 8px;
border-bottom: 2px solid rgba(0,0,0,0.15);
text-align: left;
}
.sticky-block td {
padding: 5px 8px;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.sticky-block img {
max-width: 100%;
border-radius: 4px;
margin: 6px 0;
}
.sticky-block hr {
border: none;
border-top: 1px dashed rgba(0,0,0,0.2);
margin: 12px 0;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="board">
<div class="note note-title">
<div class="note-heading">{{ title }}</div>
<div class="note-meta">{{ config.site.author }} · {{ published_date }}</div>
</div>
<div class="meta-strip">
<div class="meta-note">{{ config.site.author }}</div>
<div class="meta-note">{{ published_date }}</div>
<div class="meta-note">{{ reading_time }}</div>
{% if updated_date %}<div class="meta-note" style="background: var(--orange); color: #7c2d12; transform: rotate(-1deg);">Updated {{ updated_date }}</div>{% endif %}
</div>
{% if taxonomy.tags %}
<div class="tags-area">
{% for tag in taxonomy.tags %}
<div class="tag-note"># {{ tag }}</div>
{% endfor %}
</div>
{% endif %}
<div class="content-grid">
<div class="content-area">
{{ content | safe }}
</div>
</div>
</div>
<script>
// Wrap each direct child of content-area in a sticky-block div
document.addEventListener("DOMContentLoaded", function() {
const area = document.querySelector(".content-area");
if (!area) return;
const children = Array.from(area.children);
children.forEach(function(el) {
const wrapper = document.createElement("div");
wrapper.className = "sticky-block";
el.parentNode.insertBefore(wrapper, el);
wrapper.appendChild(el);
});
});
</script>
</body>
</html>

516
templates/tech-catalog.html Normal file
View File

@@ -0,0 +1,516 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }} Catalog</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,300;0,400;0,500;0,700;0,900;1,400&family=Courier+Prime&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #f0ebe1; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #f0ebe1;
--paper: #f7f3ea;
--red: #c0272d;
--black: #1a1210;
--dark-gray: #2d2926;
--mid-gray: #6b6560;
--light-gray: #b0a89a;
--cream: #e8e0d0;
}
body {
background: var(--bg);
color: var(--black);
font-family: "Jost", "Futura", "Century Gothic", "Gill Sans", sans-serif;
font-size: 13px;
line-height: 1.45;
min-height: 100vh;
}
/* Top catalog header strip */
.catalog-header {
background: var(--black);
color: #fff;
padding: 0;
display: flex;
flex-direction: column;
}
.catalog-header-top {
background: var(--red);
padding: 6px 28px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.catalog-header-main {
padding: 16px 28px 20px;
display: flex;
align-items: baseline;
gap: 16px;
}
.catalog-brand {
font-size: 36px;
font-weight: 900;
letter-spacing: -0.02em;
text-transform: uppercase;
line-height: 1;
}
.catalog-brand-sub {
font-size: 11px;
font-weight: 500;
letter-spacing: 0.2em;
text-transform: uppercase;
color: rgba(255,255,255,0.5);
}
.catalog-num {
margin-left: auto;
text-align: right;
}
.catalog-num-value {
font-family: "Courier Prime", monospace;
font-size: 24px;
color: var(--red);
line-height: 1;
}
.catalog-num-label {
font-size: 9px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: rgba(255,255,255,0.4);
}
/* Category tabs */
.category-tabs {
background: var(--dark-gray);
display: flex;
padding: 0 28px;
overflow-x: auto;
}
.cat-tab {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: rgba(255,255,255,0.5);
padding: 10px 16px;
border-bottom: 3px solid transparent;
white-space: nowrap;
}
.cat-tab.active {
color: #fff;
border-bottom-color: var(--red);
}
/* Page layout */
.page {
max-width: 960px;
margin: 0 auto;
padding: 28px 28px 64px;
}
/* Product hero */
.product-hero {
background: var(--paper);
border: 1px solid var(--cream);
margin-bottom: 24px;
display: grid;
grid-template-columns: auto 1fr;
gap: 0;
}
.product-hero-num {
background: var(--red);
color: #fff;
font-size: 56px;
font-weight: 900;
letter-spacing: -0.04em;
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
padding: 20px 12px;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.product-hero-content {
padding: 24px 28px;
}
.product-label {
font-size: 9px;
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--red);
margin-bottom: 6px;
}
.product-name {
font-size: 28px;
font-weight: 900;
letter-spacing: -0.02em;
text-transform: uppercase;
line-height: 1.1;
margin-bottom: 12px;
color: var(--black);
}
.product-specs {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 12px;
}
.spec-item {
display: flex;
flex-direction: column;
gap: 1px;
}
.spec-label {
font-size: 8px;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--light-gray);
}
.spec-value {
font-size: 13px;
font-weight: 700;
color: var(--dark-gray);
}
.product-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.tag {
font-size: 9px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--mid-gray);
border: 1px solid var(--light-gray);
padding: 2px 8px;
}
/* Divider */
.section-divider {
display: grid;
grid-template-columns: auto 1fr;
gap: 12px;
align-items: center;
margin: 28px 0 16px;
}
.section-divider-label {
font-size: 9px;
font-weight: 900;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--black);
background: var(--black);
color: #fff;
padding: 5px 12px;
}
.section-divider-line {
height: 1px;
background: var(--black);
}
/* Content area */
.content-area h1 {
font-size: 22px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: -0.01em;
color: var(--black);
margin-top: 28px;
margin-bottom: 10px;
border-bottom: 3px solid var(--red);
padding-bottom: 6px;
}
.content-area h2 {
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--black);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h3 {
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--red);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 12px;
font-weight: 700;
color: var(--mid-gray);
margin-top: 14px;
margin-bottom: 4px;
}
.content-area p {
font-size: 13px;
margin-bottom: 12px;
color: var(--dark-gray);
line-height: 1.6;
}
.content-area a {
color: var(--red);
text-decoration: none;
font-weight: 700;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "Courier Prime", monospace;
font-size: 12px;
background: var(--cream);
color: var(--dark-gray);
padding: 1px 5px;
border: 1px solid var(--light-gray);
}
.content-area pre {
background: var(--dark-gray);
color: #e0d8c8;
padding: 14px 16px;
margin: 12px 0;
overflow-x: auto;
font-family: "Courier Prime", monospace;
font-size: 12px;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: inherit;
}
.content-area blockquote {
border-left: 4px solid var(--red);
background: var(--paper);
border-top: 1px solid var(--cream);
border-bottom: 1px solid var(--cream);
padding: 12px 16px;
margin: 14px 0;
color: var(--mid-gray);
font-style: italic;
}
.content-area ul {
margin: 8px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 18px;
margin-bottom: 5px;
color: var(--dark-gray);
position: relative;
font-size: 13px;
}
.content-area ul li::before {
content: "—";
position: absolute;
left: 0;
color: var(--red);
font-weight: 700;
}
.content-area ol {
margin: 8px 0 14px 22px;
color: var(--dark-gray);
font-size: 13px;
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 12px;
}
.content-area th {
background: var(--dark-gray);
color: #fff;
padding: 8px 12px;
text-align: left;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
}
.content-area tr:nth-child(even) td {
background: var(--cream);
}
.content-area td {
padding: 8px 12px;
border-bottom: 1px solid var(--cream);
}
.content-area img {
max-width: 100%;
margin: 10px 0;
}
.content-area hr {
border: none;
border-top: 2px solid var(--black);
margin: 20px 0;
}
/* Footer */
.catalog-footer {
background: var(--black);
color: rgba(255,255,255,0.5);
padding: 16px 28px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
letter-spacing: 0.12em;
text-transform: uppercase;
}
@media (max-width: 600px) {
.product-hero { grid-template-columns: 1fr; }
.product-hero-num { writing-mode: horizontal-tb; transform: none; padding: 12px 20px; font-size: 36px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="catalog-header">
<div class="catalog-header-top">
<span>{{ config.site.name }} — Publications Division</span>
<span>Vol. {{ published_date | replace("-", ".") }}</span>
</div>
<div class="catalog-header-main">
<div>
<div class="catalog-brand">{{ config.site.name }}</div>
<div class="catalog-brand-sub">Technical Publications</div>
</div>
<div class="catalog-num">
<div class="catalog-num-value">No. {{ published_date | replace("-", "") }}</div>
<div class="catalog-num-label">Catalog Number</div>
</div>
</div>
<div class="category-tabs">
<div class="cat-tab">All Products</div>
<div class="cat-tab active">Articles</div>
<div class="cat-tab">Technical</div>
<div class="cat-tab">Guides</div>
<div class="cat-tab">Reviews</div>
</div>
</div>
<div class="page">
<div class="product-hero">
<div class="product-hero-num">01</div>
<div class="product-hero-content">
<div class="product-label">Featured Article</div>
<div class="product-name">{{ title }}</div>
<div class="product-specs">
<div class="spec-item">
<div class="spec-label">Author</div>
<div class="spec-value">{{ config.site.author }}</div>
</div>
<div class="spec-item">
<div class="spec-label">Published</div>
<div class="spec-value">{{ published_date }}</div>
</div>
<div class="spec-item">
<div class="spec-label">Read Time</div>
<div class="spec-value">{{ reading_time }}</div>
</div>
{% if updated_date %}
<div class="spec-item">
<div class="spec-label">Revised</div>
<div class="spec-value">{{ updated_date }}</div>
</div>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="product-tags">
{% for tag in taxonomy.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="section-divider">
<div class="section-divider-label">Content</div>
<div class="section-divider-line"></div>
</div>
<div class="content-area">
{{ content | safe }}
</div>
</div>
<div class="catalog-footer">
<span>{{ config.site.name }}</span>
<span>{{ config.site.author }}</span>
<span>{{ published_date }}</span>
</div>
</body>
</html>

429
templates/terminal.html Normal file
View File

@@ -0,0 +1,429 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=VT323&family=IBM+Plex+Mono:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #000000; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--green: #00ff41;
--green-dim: #00b32d;
--green-dark: #004a14;
--bg: #000000;
--amber: #ffb000;
}
body {
background: var(--bg);
color: var(--green);
font-family: "IBM Plex Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.6;
min-height: 100vh;
overflow-x: hidden;
position: relative;
}
/* CRT scanline overlay */
body::before {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.18) 2px,
rgba(0, 0, 0, 0.18) 4px
);
pointer-events: none;
z-index: 999;
}
/* CRT vignette */
body::after {
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.7) 100%);
pointer-events: none;
z-index: 998;
}
.terminal {
max-width: 900px;
margin: 0 auto;
padding: 24px 20px 60px;
}
/* Window chrome */
.window-bar {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 14px;
background: #111111;
border: 1px solid var(--green-dim);
border-bottom: none;
margin-bottom: 0;
}
.wdot {
width: 12px;
height: 12px;
border-radius: 50%;
border: 1px solid var(--green-dim);
}
.wdot.red { background: #ff5f57; border-color: #e0443e; }
.wdot.yellow { background: #febc2e; border-color: #d4a017; }
.wdot.green { background: #28c840; border-color: #1aab29; }
.window-title {
flex: 1;
text-align: center;
font-size: 12px;
color: var(--green-dim);
letter-spacing: 0.1em;
}
.screen {
background: #020f02;
border: 1px solid var(--green-dim);
padding: 20px 24px 32px;
min-height: 80vh;
}
.prompt-line {
display: flex;
align-items: center;
gap: 0;
margin-bottom: 4px;
font-family: "VT323", monospace;
font-size: 20px;
text-shadow: 0 0 8px var(--green);
}
.prompt-user { color: var(--green); }
.prompt-at { color: var(--green-dim); }
.prompt-host { color: #00cc33; }
.prompt-colon { color: var(--green-dim); }
.prompt-path { color: #00aaff; text-shadow: 0 0 8px #00aaff; }
.prompt-dollar { color: var(--green); margin: 0 8px; }
.prompt-cmd { color: #ffffff; text-shadow: 0 0 6px #ffffff; }
.ascii-divider {
font-family: "VT323", monospace;
font-size: 16px;
color: var(--green-dim);
margin: 16px 0;
letter-spacing: 0.05em;
text-shadow: 0 0 4px var(--green-dim);
white-space: pre;
}
.output-meta {
font-size: 12px;
color: var(--green-dim);
margin-bottom: 20px;
padding-left: 2px;
}
.output-meta span {
margin-right: 20px;
}
.blink {
display: inline-block;
width: 8px;
height: 14px;
background: var(--green);
vertical-align: middle;
animation: blink 1.1s step-end infinite;
box-shadow: 0 0 6px var(--green);
margin-left: 2px;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.post-title-line {
font-family: "VT323", monospace;
font-size: 36px;
color: var(--green);
text-shadow: 0 0 12px var(--green), 0 0 24px rgba(0,255,65,0.4);
line-height: 1.1;
margin-bottom: 4px;
letter-spacing: 0.02em;
}
.content-area {
margin-top: 20px;
}
.content-area h1 {
font-family: "VT323", monospace;
font-size: 30px;
color: var(--green);
text-shadow: 0 0 8px var(--green);
margin-top: 28px;
margin-bottom: 12px;
}
.content-area h1::before {
content: "## ";
color: var(--green-dim);
}
.content-area h2 {
font-size: 16px;
color: #00dd44;
text-shadow: 0 0 6px #00dd44;
margin-top: 24px;
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.content-area h2::before {
content: "### ";
color: var(--green-dim);
}
.content-area h3 {
font-size: 14px;
color: var(--green);
margin-top: 20px;
margin-bottom: 8px;
}
.content-area h3::before {
content: "> ";
color: var(--green-dim);
}
.content-area p {
margin-bottom: 14px;
text-shadow: 0 0 3px rgba(0,255,65,0.3);
}
.content-area a {
color: #00aaff;
text-decoration: none;
text-shadow: 0 0 6px #00aaff;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "IBM Plex Mono", monospace;
font-size: 13px;
color: #ffff00;
text-shadow: 0 0 4px #ffff00;
background: rgba(255,255,0,0.07);
padding: 1px 5px;
border: 1px solid rgba(255,255,0,0.3);
}
.content-area pre {
background: #000a00;
border: 1px solid var(--green-dim);
padding: 16px 18px;
margin: 16px 0;
overflow-x: auto;
}
.content-area pre::before {
content: "$ ";
color: var(--green-dim);
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: var(--green);
text-shadow: 0 0 3px rgba(0,255,65,0.4);
}
.content-area blockquote {
border-left: 3px solid var(--green-dim);
padding-left: 16px;
margin: 16px 0;
color: var(--green-dim);
font-style: normal;
}
.content-area blockquote::before {
display: block;
content: "/* OUTPUT:";
color: var(--green-dim);
font-size: 12px;
margin-bottom: 4px;
}
.content-area blockquote::after {
display: block;
content: "*/";
color: var(--green-dim);
font-size: 12px;
margin-top: 4px;
}
.content-area ul,
.content-area ol {
margin: 12px 0 16px 0;
list-style: none;
padding: 0;
}
.content-area ul li::before {
content: " -> ";
color: var(--green-dim);
}
.content-area ol {
counter-reset: list;
}
.content-area ol li {
counter-increment: list;
}
.content-area ol li::before {
content: " [" counter(list) "] ";
color: var(--green-dim);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
font-size: 13px;
}
.content-area th {
border: 1px solid var(--green-dim);
padding: 6px 12px;
color: var(--green);
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.1em;
background: rgba(0,255,65,0.05);
}
.content-area td {
border: 1px solid rgba(0,255,65,0.2);
padding: 6px 12px;
}
.content-area img {
max-width: 100%;
filter: grayscale(100%) sepia(50%) hue-rotate(80deg);
border: 1px solid var(--green-dim);
}
.content-area hr {
border: none;
border-top: 1px dashed var(--green-dim);
margin: 24px 0;
}
.bottom-prompt {
margin-top: 32px;
display: flex;
align-items: center;
font-family: "VT323", monospace;
font-size: 20px;
color: var(--green-dim);
text-shadow: 0 0 4px var(--green-dim);
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="terminal">
<div class="window-bar">
<div class="wdot red"></div>
<div class="wdot yellow"></div>
<div class="wdot green"></div>
<div class="window-title">bash -- 80x24</div>
</div>
<div class="screen">
<div class="prompt-line">
<span class="prompt-user">felix</span>
<span class="prompt-at">@</span>
<span class="prompt-host">server</span>
<span class="prompt-colon">:</span>
<span class="prompt-path">~/posts</span>
<span class="prompt-dollar">$</span>
<span class="prompt-cmd">cat "{{ title }}.md"</span>
</div>
<div class="ascii-divider">================================================================================</div>
<div class="post-title-line">{{ title }}</div>
<div class="output-meta">
<span>author: {{ config.site.author }}</span>
<span>date: {{ published_date }}</span>
<span>{{ reading_time }}</span>
{% if updated_date %}<span>updated: {{ updated_date }}</span>{% endif %}
</div>
{% if taxonomy.tags %}
<div class="output-meta">
<span>tags:
{% for tag in taxonomy.tags %}[{{ tag }}] {% endfor %}
</span>
</div>
{% endif %}
<div class="ascii-divider">--------------------------------------------------------------------------------</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="ascii-divider">================================================================================</div>
<div class="bottom-prompt">
<span class="prompt-user">felix</span>
<span class="prompt-at">@</span>
<span class="prompt-host">server</span>
<span class="prompt-colon">:</span>
<span class="prompt-path">~/posts</span>
<span class="prompt-dollar">$</span>
<span class="blink"></span>
</div>
</div>
</div>
</body>
</html>

404
templates/typewriter.html Normal file
View File

@@ -0,0 +1,404 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Special+Elite&family=Courier+Prime:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #c8b99a; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--paper: #f5f0e8;
--paper-dark: #ede5d0;
--ink: #1a1209;
--ink-faint: #3d2e0f;
--ink-dim: #7a6545;
--red-stamp: #8b1a1a;
}
body {
background: #c8b99a;
color: var(--ink);
font-family: "Courier Prime", "Courier New", monospace;
font-size: 15px;
line-height: 1.7;
min-height: 100vh;
padding: 40px 20px;
}
.page-wrapper {
max-width: 720px;
margin: 0 auto;
position: relative;
}
/* Paper texture */
.paper {
background: var(--paper);
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 27px,
rgba(100,80,40,0.08) 27px,
rgba(100,80,40,0.08) 28px
);
padding: 60px 72px 80px;
position: relative;
box-shadow:
0 2px 4px rgba(0,0,0,0.15),
0 8px 32px rgba(0,0,0,0.2),
inset 0 0 60px rgba(100,80,40,0.05);
}
/* Paper edge curl */
.paper::after {
content: "";
position: absolute;
bottom: 0;
right: 0;
width: 40px;
height: 40px;
background: linear-gradient(135deg, var(--paper) 50%, #a89070 50%);
box-shadow: -2px -2px 4px rgba(0,0,0,0.15);
}
/* Left red margin line */
.paper::before {
content: "";
position: absolute;
top: 0;
left: 60px;
bottom: 0;
width: 1px;
background: rgba(180,40,40,0.25);
}
/* Memo header */
.memo-header {
font-family: "Special Elite", monospace;
margin-bottom: 40px;
padding-bottom: 20px;
border-bottom: 2px solid var(--ink);
}
.memo-top-line {
font-size: 22px;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.18em;
text-align: center;
color: var(--ink);
margin-bottom: 20px;
/* Slight type misalignment */
transform: rotate(-0.3deg);
text-shadow: 1px 1px 0 rgba(0,0,0,0.15);
}
.memo-fields {
display: grid;
grid-template-columns: max-content 1fr;
gap: 6px 12px;
font-size: 14px;
}
.memo-field-label {
font-weight: 700;
text-transform: uppercase;
color: var(--ink-faint);
}
.memo-field-value {
border-bottom: 1px solid var(--ink-dim);
padding-bottom: 1px;
/* Simulate typewritten uneven characters */
letter-spacing: 0.02em;
}
/* Title typed on a line */
.memo-title {
font-family: "Special Elite", monospace;
font-size: 28px;
text-align: center;
color: var(--ink);
margin: 32px 0 8px;
transform: rotate(-0.2deg);
letter-spacing: 0.04em;
line-height: 1.2;
/* ink smudge */
text-shadow:
0.5px 0.5px 1px rgba(0,0,0,0.3),
-0.3px 0 0 rgba(0,0,0,0.1);
}
/* Red CONFIDENTIAL stamp (for fun) */
.stamp {
position: absolute;
top: 52px;
right: 64px;
border: 3px solid var(--red-stamp);
color: var(--red-stamp);
font-family: "Special Elite", monospace;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.14em;
padding: 4px 8px;
transform: rotate(12deg);
opacity: 0.55;
}
/* Content */
.content-area {
margin-top: 24px;
}
.content-area h1 {
font-family: "Special Elite", monospace;
font-size: 20px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--ink);
margin-top: 32px;
margin-bottom: 10px;
text-align: center;
transform: rotate(-0.15deg);
}
.content-area h2 {
font-family: "Special Elite", monospace;
font-size: 16px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink);
margin-top: 28px;
margin-bottom: 8px;
text-decoration: underline;
}
.content-area h3 {
font-size: 15px;
font-weight: 700;
color: var(--ink-faint);
margin-top: 20px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 14px;
font-weight: 700;
color: var(--ink-dim);
margin-top: 16px;
margin-bottom: 4px;
}
.content-area p {
margin-bottom: 16px;
text-align: justify;
hyphens: auto;
/* Subtle uneven ink */
text-shadow: 0.3px 0.3px 0 rgba(0,0,0,0.12);
}
/* Alternating slight rotation on paragraphs */
.content-area p:nth-child(odd) {
transform: rotate(0.05deg);
}
.content-area p:nth-child(even) {
transform: rotate(-0.05deg);
}
.content-area a {
color: var(--ink);
text-decoration: underline;
}
.content-area code {
font-family: "Courier Prime", monospace;
font-size: 13px;
background: rgba(0,0,0,0.06);
padding: 1px 4px;
border-bottom: 1px solid var(--ink-dim);
}
.content-area pre {
background: rgba(0,0,0,0.04);
border-left: 3px solid var(--ink-dim);
padding: 12px 16px;
margin: 16px 0;
overflow-x: auto;
font-size: 13px;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
}
.content-area blockquote {
border-left: 3px solid var(--ink-dim);
padding: 8px 16px;
margin: 16px 0;
font-style: italic;
color: var(--ink-faint);
transform: rotate(-0.1deg);
}
.content-area ul {
margin: 10px 0 16px 24px;
list-style: none;
padding: 0;
}
.content-area ul li {
margin-bottom: 6px;
padding-left: 20px;
position: relative;
}
.content-area ul li::before {
content: "x";
position: absolute;
left: 0;
color: var(--ink-dim);
font-weight: 700;
}
.content-area ol {
margin: 10px 0 16px 0;
list-style: none;
padding: 0;
counter-reset: typed-list;
}
.content-area ol li {
counter-increment: typed-list;
padding-left: 28px;
margin-bottom: 6px;
position: relative;
}
.content-area ol li::before {
content: counter(typed-list) ".";
position: absolute;
left: 0;
color: var(--ink-dim);
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
font-size: 13px;
}
.content-area th {
font-weight: 700;
text-transform: uppercase;
padding: 6px 12px;
border: 1px solid var(--ink);
text-align: left;
font-size: 12px;
letter-spacing: 0.06em;
}
.content-area td {
padding: 6px 12px;
border: 1px solid var(--ink-dim);
}
.content-area img {
max-width: 100%;
filter: sepia(30%) contrast(90%);
margin: 12px 0;
}
.content-area hr {
border: none;
text-align: center;
color: var(--ink-dim);
margin: 24px 0;
font-size: 18px;
letter-spacing: 0.5em;
}
.content-area hr::before {
content: "- - - - - - -";
}
.footer {
margin-top: 40px;
padding-top: 16px;
border-top: 1px solid var(--ink-dim);
font-size: 12px;
color: var(--ink-dim);
display: flex;
justify-content: space-between;
}
@media (max-width: 600px) {
.paper {
padding: 40px 28px 60px;
}
.paper::before {
left: 20px;
}
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="page-wrapper">
<div class="paper">
<div class="stamp">DRAFT</div>
<div class="memo-header">
<div class="memo-top-line">MEMORANDUM</div>
<div class="memo-fields">
<span class="memo-field-label">TO:</span>
<span class="memo-field-value">Reader</span>
<span class="memo-field-label">FROM:</span>
<span class="memo-field-value">{{ config.site.author }}</span>
<span class="memo-field-label">DATE:</span>
<span class="memo-field-value">{{ published_date }}</span>
<span class="memo-field-label">RE:</span>
<span class="memo-field-value">{{ title }}</span>
<span class="memo-field-label">READ:</span>
<span class="memo-field-value">{{ reading_time }}</span>
</div>
</div>
{% if taxonomy.tags %}
<div style="font-size: 12px; color: var(--ink-dim); margin-bottom: 8px; text-align: center; letter-spacing: 0.08em; text-transform: uppercase;">
[ {% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %} / {% endif %}{% endfor %} ]
</div>
{% endif %}
<div class="content-area">
{{ content | safe }}
</div>
<div class="footer">
<span>{{ config.site.name }}</span>
{% if updated_date %}<span>Updated: {{ updated_date }}</span>{% endif %}
<span>- 1 -</span>
</div>
</div>
</div>
</body>
</html>

609
templates/vinyl-record.html Normal file
View File

@@ -0,0 +1,609 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Helvetica+Neue:wght@300;400;700&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #3d2b1f; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--wood: #3d2b1f;
--wood-light: #5a3d2a;
--vinyl: #1a1a1a;
--vinyl-groove: #0d0d0d;
--label-bg: #f5c842;
--label-text: #1a1208;
--cream: #faf3e0;
--amber: #d4891a;
--text-dark: #1c1208;
--text-mid: #5a4020;
--text-dim: #9a7850;
--border: #e0d4b8;
}
body {
background: var(--wood);
background-image:
repeating-linear-gradient(
90deg,
rgba(0,0,0,0.08) 0px,
rgba(0,0,0,0.08) 1px,
transparent 1px,
transparent 12px
),
repeating-linear-gradient(
0deg,
rgba(0,0,0,0.03) 0px,
rgba(0,0,0,0.03) 1px,
transparent 1px,
transparent 24px
),
radial-gradient(ellipse at 20% 50%, rgba(90,61,42,0.6) 0%, transparent 60%),
radial-gradient(ellipse at 80% 50%, rgba(90,61,42,0.5) 0%, transparent 60%);
color: var(--text-dark);
font-family: "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 15px;
line-height: 1.55;
min-height: 100vh;
}
.player-layout {
display: flex;
min-height: 100vh;
flex-direction: column;
}
/* Player top section */
.player-top {
display: flex;
align-items: flex-start;
gap: 0;
padding: 40px 40px 32px;
}
/* Turntable platter */
.turntable-section {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding-right: 40px;
}
.platter {
width: 280px;
height: 280px;
border-radius: 50%;
background: radial-gradient(circle,
rgba(80,60,40,0.3) 0%,
rgba(60,40,20,0.5) 60%,
rgba(30,20,10,0.7) 100%
);
border: 4px solid rgba(255,255,255,0.05);
box-shadow:
0 0 0 8px rgba(0,0,0,0.3),
0 8px 40px rgba(0,0,0,0.5),
inset 0 0 40px rgba(0,0,0,0.4);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
/* Vinyl record */
.vinyl {
width: 240px;
height: 240px;
border-radius: 50%;
background:
radial-gradient(circle at center, transparent 14%, rgba(255,255,255,0.02) 14.5%, transparent 15%),
radial-gradient(circle at center, transparent 18%, rgba(255,255,255,0.02) 18.5%, transparent 19%),
radial-gradient(circle at center, transparent 22%, rgba(255,255,255,0.02) 22.5%, transparent 23%),
radial-gradient(circle at center, transparent 26%, rgba(255,255,255,0.02) 26.5%, transparent 27%),
radial-gradient(circle at center, transparent 30%, rgba(255,255,255,0.02) 30.5%, transparent 31%),
radial-gradient(circle at center, transparent 34%, rgba(255,255,255,0.02) 34.5%, transparent 35%),
radial-gradient(circle at center, transparent 38%, rgba(255,255,255,0.02) 38.5%, transparent 39%),
radial-gradient(circle at center, transparent 42%, rgba(255,255,255,0.02) 42.5%, transparent 43%),
radial-gradient(circle at center, transparent 46%, rgba(255,255,255,0.02) 46.5%, transparent 47%),
conic-gradient(
from 0deg,
#111 0deg, #1a1a1a 2deg, #0d0d0d 4deg, #1a1a1a 6deg,
#111 8deg, #1a1a1a 10deg, #0d0d0d 12deg, #1a1a1a 14deg,
#111 16deg, #1a1a1a 18deg, #0d0d0d 20deg, #1a1a1a 22deg,
#111 24deg, #1a1a1a 26deg, #0d0d0d 28deg, #1a1a1a 30deg,
#111 360deg
);
animation: spin 3.5s linear infinite;
position: relative;
box-shadow: 0 4px 20px rgba(0,0,0,0.6), inset 0 0 8px rgba(0,0,0,0.4);
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Record label in center */
.record-label {
position: absolute;
width: 90px;
height: 90px;
border-radius: 50%;
background: var(--label-bg);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* Counter-rotate so label stays readable while record spins */
animation: counter-spin 3.5s linear infinite;
box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
@keyframes counter-spin {
from { transform: rotate(0deg); }
to { transform: rotate(-360deg); }
}
.label-title {
font-size: 8px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--label-text);
text-align: center;
padding: 0 6px;
line-height: 1.2;
}
.label-side {
font-size: 16px;
font-weight: 700;
color: var(--label-text);
line-height: 1;
}
.label-site {
font-size: 6px;
color: rgba(26,18,8,0.6);
text-transform: uppercase;
letter-spacing: 0.1em;
text-align: center;
padding: 0 6px;
}
/* Center spindle hole */
.spindle {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: #333;
border: 2px solid #555;
z-index: 10;
}
/* Tonearm */
.tonearm {
position: absolute;
right: -28px;
top: 20px;
width: 120px;
height: 4px;
background: linear-gradient(90deg, rgba(200,180,140,0.8), rgba(160,140,100,0.6));
border-radius: 2px;
transform-origin: left center;
transform: rotate(25deg);
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.tonearm::after {
content: "";
position: absolute;
right: 0;
top: -3px;
width: 10px;
height: 10px;
background: rgba(140,120,80,0.8);
border-radius: 2px;
transform: rotate(-10deg);
}
/* Controls strip */
.controls-strip {
background: rgba(0,0,0,0.3);
border-radius: 8px;
padding: 10px 16px;
display: flex;
gap: 16px;
align-items: center;
}
.ctrl {
font-size: 18px;
color: rgba(200,180,140,0.7);
cursor: default;
}
.ctrl-play {
width: 36px;
height: 36px;
background: var(--amber);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
/* Track info */
.track-info {
flex: 1;
padding-left: 8px;
}
.track-side-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--amber);
margin-bottom: 8px;
}
.track-title {
font-size: 28px;
font-weight: 700;
color: var(--cream);
letter-spacing: -0.02em;
line-height: 1.15;
margin-bottom: 12px;
}
.track-meta {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.track-meta-item {
display: flex;
flex-direction: column;
gap: 2px;
}
.track-meta-label {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.14em;
color: rgba(200,180,140,0.5);
}
.track-meta-value {
font-size: 14px;
font-weight: 500;
color: var(--cream);
}
.track-tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 14px;
}
.track-tag {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--amber);
border: 1px solid rgba(212,137,26,0.4);
padding: 3px 9px;
border-radius: 3px;
}
/* Liner notes */
.liner-notes {
background: var(--cream);
flex: 1;
padding: 40px 48px 64px;
}
.liner-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32px;
padding-bottom: 16px;
border-bottom: 2px solid var(--border);
}
.liner-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--text-dim);
}
.liner-catalog {
font-size: 11px;
color: var(--text-dim);
font-family: "Courier New", monospace;
}
.content-area h1 {
font-size: 22px;
font-weight: 700;
color: var(--text-dark);
margin-top: 32px;
margin-bottom: 10px;
letter-spacing: -0.01em;
}
.content-area h2 {
font-size: 16px;
font-weight: 700;
color: var(--amber);
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 11px;
margin-top: 28px;
margin-bottom: 8px;
}
.content-area h3 {
font-size: 15px;
font-weight: 700;
color: var(--text-dark);
margin-top: 22px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
font-weight: 600;
color: var(--text-mid);
margin-top: 16px;
margin-bottom: 5px;
}
.content-area p {
font-size: 15px;
margin-bottom: 14px;
color: var(--text-mid);
line-height: 1.7;
}
.content-area a {
color: var(--amber);
text-decoration: none;
font-weight: 500;
}
.content-area a:hover {
text-decoration: underline;
}
.content-area code {
font-family: "Courier New", monospace;
font-size: 13px;
background: rgba(0,0,0,0.06);
color: var(--text-dark);
padding: 2px 6px;
border-radius: 3px;
}
.content-area pre {
background: var(--wood);
color: var(--cream);
border-radius: 8px;
padding: 16px 18px;
margin: 14px 0;
overflow-x: auto;
font-size: 13px;
}
.content-area pre code {
background: none;
color: inherit;
padding: 0;
}
.content-area blockquote {
border-left: 3px solid var(--amber);
background: rgba(212,137,26,0.06);
border-radius: 0 8px 8px 0;
padding: 12px 18px;
margin: 14px 0;
}
.content-area blockquote p {
color: var(--amber);
font-weight: 500;
margin: 0;
font-style: italic;
}
.content-area ul {
margin: 8px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 18px;
margin-bottom: 5px;
color: var(--text-mid);
position: relative;
}
.content-area ul li::before {
content: "";
position: absolute;
left: 4px;
top: 9px;
width: 6px;
height: 2px;
background: var(--amber);
}
.content-area ol {
margin: 8px 0 14px 22px;
color: var(--text-mid);
}
.content-area li {
margin-bottom: 5px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 14px;
}
.content-area th {
background: rgba(0,0,0,0.06);
padding: 8px 12px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--text-dim);
text-transform: uppercase;
letter-spacing: 0.06em;
border-bottom: 2px solid var(--border);
}
.content-area td {
padding: 8px 12px;
border-bottom: 1px solid var(--border);
color: var(--text-mid);
}
.content-area img {
max-width: 100%;
border-radius: 6px;
margin: 12px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 24px 0;
}
.liner-footer {
margin-top: 40px;
padding-top: 16px;
border-top: 1px solid var(--border);
display: flex;
justify-content: space-between;
font-size: 11px;
color: var(--text-dim);
}
@media (max-width: 800px) {
.player-top { flex-direction: column; padding: 24px 20px 20px; }
.turntable-section { padding-right: 0; padding-bottom: 24px; border-right: none; border-bottom: 1px solid rgba(255,255,255,0.1); width: 100%; }
.track-info { padding-left: 0; }
.liner-notes { padding: 28px 20px 48px; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="player-layout">
<div class="player-top">
<div class="turntable-section">
<div class="platter">
<div class="vinyl">
<div class="record-label">
<div class="label-side">A</div>
<div class="label-title">{{ title | truncate(20) }}</div>
<div class="label-site">{{ config.site.name }}</div>
</div>
<div class="spindle"></div>
</div>
<div class="tonearm"></div>
</div>
<div class="controls-strip">
<div class="ctrl">&#9664;&#9664;</div>
<div class="ctrl-play">&#9654;</div>
<div class="ctrl">&#9654;&#9654;</div>
</div>
</div>
<div class="track-info">
<div class="track-side-label">Side A — {{ config.site.name }}</div>
<div class="track-title">{{ title }}</div>
<div class="track-meta">
<div class="track-meta-item">
<div class="track-meta-label">Artist</div>
<div class="track-meta-value">{{ config.site.author }}</div>
</div>
<div class="track-meta-item">
<div class="track-meta-label">Released</div>
<div class="track-meta-value">{{ published_date }}</div>
</div>
<div class="track-meta-item">
<div class="track-meta-label">Duration</div>
<div class="track-meta-value">{{ reading_time }}</div>
</div>
{% if updated_date %}
<div class="track-meta-item">
<div class="track-meta-label">Reissued</div>
<div class="track-meta-value">{{ updated_date }}</div>
</div>
{% endif %}
</div>
{% if taxonomy.tags %}
<div class="track-tags">
{% for tag in taxonomy.tags %}
<span class="track-tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="liner-notes">
<div class="liner-header">
<div class="liner-label">Liner Notes</div>
<div class="liner-catalog">CAT-{{ published_date | replace("-", "") }}</div>
</div>
<div class="content-area">
{{ content | safe }}
</div>
<div class="liner-footer">
<span>&copy; {{ config.site.author }} · {{ config.site.name }}</span>
<span>{{ published_date }}</span>
</div>
</div>
</div>
</body>
</html>

306
templates/void.html Normal file
View File

@@ -0,0 +1,306 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #000000; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--void: #000000;
--white: #ffffff;
--dim: rgba(255,255,255,0.35);
--faint: rgba(255,255,255,0.12);
}
html, body {
height: 100%;
}
body {
background: var(--void);
color: var(--white);
font-family: "Space Mono", "Courier New", monospace;
font-size: 14px;
line-height: 1.75;
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
/* Single vertical line */
.vertical-line {
position: fixed;
top: 0;
bottom: 0;
left: 60px;
width: 1px;
background: var(--faint);
z-index: 0;
}
.page {
position: relative;
z-index: 1;
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}
/* Oppressive title block */
.title-block {
padding: 80px 80px 0 100px;
max-width: 100vw;
overflow: hidden;
}
.site-whisper {
font-size: 11px;
color: var(--dim);
letter-spacing: 0.3em;
text-transform: uppercase;
margin-bottom: 40px;
padding-left: 2px;
}
.main-title {
font-size: clamp(48px, 8vw, 120px);
font-weight: 700;
line-height: 0.9;
color: var(--white);
letter-spacing: -0.03em;
word-break: break-word;
margin-left: -4px;
}
/* The title pushes right and nearly off the edge */
.main-title-inner {
display: block;
}
.title-meta {
margin-top: 48px;
padding-bottom: 40px;
display: flex;
flex-direction: column;
gap: 4px;
}
.title-meta span {
font-size: 11px;
color: var(--dim);
letter-spacing: 0.15em;
text-transform: uppercase;
}
/* Content area — pushed right, away from the line */
.content-wrapper {
padding: 60px 80px 0 100px;
max-width: 720px;
}
.content-area {
font-size: 14px;
line-height: 1.8;
}
.content-area h1 {
font-size: 22px;
font-weight: 700;
margin-top: 64px;
margin-bottom: 20px;
letter-spacing: -0.02em;
}
.content-area h2 {
font-size: 16px;
font-weight: 700;
margin-top: 48px;
margin-bottom: 16px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--dim);
}
.content-area h3 {
font-size: 14px;
font-weight: 700;
margin-top: 36px;
margin-bottom: 12px;
color: var(--dim);
}
.content-area p {
margin-bottom: 22px;
color: rgba(255,255,255,0.88);
}
.content-area a {
color: var(--white);
text-decoration: none;
border-bottom: 1px solid var(--dim);
}
.content-area a:hover {
border-bottom-color: var(--white);
}
.content-area code {
font-family: "Space Mono", monospace;
font-size: 12px;
background: rgba(255,255,255,0.06);
padding: 1px 6px;
border: 1px solid var(--faint);
}
.content-area pre {
background: rgba(255,255,255,0.03);
border: 1px solid var(--faint);
padding: 20px 22px;
margin: 24px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
border: none;
padding: 0;
color: rgba(255,255,255,0.75);
}
.content-area blockquote {
border-left: 1px solid var(--dim);
padding-left: 20px;
margin: 24px 0;
color: var(--dim);
}
.content-area ul,
.content-area ol {
margin: 14px 0 20px 20px;
}
.content-area li {
margin-bottom: 6px;
color: rgba(255,255,255,0.88);
}
.content-area ul li::marker {
color: var(--dim);
}
.content-area ol li::marker {
color: var(--dim);
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 24px 0;
font-size: 13px;
}
.content-area th {
border-bottom: 1px solid var(--white);
padding: 8px 12px;
text-align: left;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--dim);
}
.content-area td {
border-bottom: 1px solid var(--faint);
padding: 8px 12px;
}
.content-area img {
max-width: 100%;
display: block;
filter: grayscale(100%) contrast(1.1);
margin: 28px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--faint);
margin: 36px 0;
}
/* Footer — sparse */
.page-footer {
padding: 80px 80px 48px 100px;
display: flex;
flex-direction: column;
gap: 4px;
}
.page-footer span {
font-size: 11px;
color: var(--faint);
letter-spacing: 0.15em;
text-transform: uppercase;
}
@media (max-width: 600px) {
.title-block,
.content-wrapper,
.page-footer {
padding-left: 28px;
padding-right: 28px;
}
.vertical-line {
left: 14px;
}
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="vertical-line"></div>
<div class="page">
<div class="title-block">
<div class="site-whisper">{{ config.site.name }}</div>
<h1 class="main-title">
<span class="main-title-inner">{{ title }}</span>
</h1>
<div class="title-meta">
<span>{{ config.site.author }}</span>
<span>{{ published_date }}</span>
<span>{{ reading_time }}</span>
{% if taxonomy.tags %}
<span>
{% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %} / {% endif %}{% endfor %}
</span>
{% endif %}
</div>
</div>
<div class="content-wrapper">
<div class="content-area">
{{ content | safe }}
</div>
</div>
<footer class="page-footer">
<span>{{ config.site.name }}</span>
<span>{{ published_date }}</span>
</footer>
</div>
</body>
</html>

565
templates/win98.html Normal file
View File

@@ -0,0 +1,565 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — {{ config.site.name }}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #008080; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: #008080;
background-image: repeating-linear-gradient(
45deg,
transparent,
transparent 2px,
rgba(0,0,0,0.03) 2px,
rgba(0,0,0,0.03) 4px
);
font-family: "Tahoma", "MS Sans Serif", Arial, sans-serif;
font-size: 11px;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.desktop-icon-row {
width: 100%;
max-width: 900px;
display: flex;
gap: 24px;
margin-bottom: 16px;
padding: 4px;
}
.window {
width: 100%;
max-width: 900px;
background: #c0c0c0;
border-top: 2px solid #ffffff;
border-left: 2px solid #ffffff;
border-right: 2px solid #808080;
border-bottom: 2px solid #808080;
box-shadow: 2px 2px 0 #000000;
}
.title-bar {
background: linear-gradient(to right, #000080, #1084d0);
color: #ffffff;
padding: 3px 5px;
display: flex;
align-items: center;
justify-content: space-between;
user-select: none;
}
.title-bar-left {
display: flex;
align-items: center;
gap: 6px;
font-weight: bold;
font-size: 11px;
}
.title-bar-icon {
width: 16px;
height: 16px;
background: #ffffff;
border: 1px solid #808080;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 9px;
color: #000080;
font-weight: bold;
flex-shrink: 0;
}
.title-bar-buttons {
display: flex;
gap: 2px;
}
.tb-btn {
width: 16px;
height: 14px;
background: #c0c0c0;
border-top: 1px solid #ffffff;
border-left: 1px solid #ffffff;
border-right: 1px solid #808080;
border-bottom: 1px solid #808080;
display: flex;
align-items: center;
justify-content: center;
font-size: 9px;
color: #000000;
cursor: pointer;
font-family: "Marlett", "Webdings", sans-serif;
}
.menu-bar {
background: #c0c0c0;
border-bottom: 1px solid #808080;
padding: 2px 4px;
display: flex;
gap: 2px;
}
.menu-item {
padding: 2px 8px;
font-size: 11px;
cursor: pointer;
}
.menu-item:hover {
background: #000080;
color: #ffffff;
}
.toolbar {
background: #c0c0c0;
border-bottom: 1px solid #808080;
padding: 3px 4px;
display: flex;
gap: 4px;
align-items: center;
}
.tool-btn {
width: 24px;
height: 22px;
background: #c0c0c0;
border-top: 1px solid #ffffff;
border-left: 1px solid #ffffff;
border-right: 1px solid #808080;
border-bottom: 1px solid #808080;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
cursor: pointer;
}
.toolbar-sep {
width: 1px;
height: 20px;
background: #808080;
border-right: 1px solid #ffffff;
margin: 0 2px;
}
.address-bar {
background: #c0c0c0;
border-bottom: 1px solid #808080;
padding: 3px 6px;
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
}
.address-label {
font-size: 11px;
color: #000000;
}
.address-input {
flex: 1;
background: #ffffff;
border-top: 1px solid #808080;
border-left: 1px solid #808080;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
padding: 1px 4px;
font-size: 11px;
font-family: "Tahoma", Arial, sans-serif;
}
.window-body {
display: flex;
min-height: 500px;
}
.sidebar {
width: 160px;
background: #c0c0c0;
border-right: 2px solid #808080;
padding: 8px 4px;
flex-shrink: 0;
}
.sidebar-section {
margin-bottom: 12px;
}
.sidebar-header {
background: #000080;
color: #ffffff;
padding: 2px 6px;
font-size: 10px;
font-weight: bold;
margin-bottom: 4px;
}
.sidebar-item {
padding: 2px 6px;
font-size: 11px;
cursor: pointer;
display: flex;
align-items: center;
gap: 4px;
}
.sidebar-item:hover {
background: #000080;
color: #ffffff;
}
.sidebar-icon {
width: 16px;
height: 16px;
background: #ffff00;
border: 1px solid #808080;
display: inline-block;
font-size: 8px;
text-align: center;
line-height: 16px;
}
.content-area {
flex: 1;
background: #ffffff;
border-top: 2px inset #808080;
border-left: 2px inset #808080;
overflow: auto;
}
.content-header {
background: #c0c0c0;
border-bottom: 1px solid #808080;
padding: 6px 12px;
display: flex;
gap: 20px;
font-size: 10px;
color: #444444;
}
.content-scroll {
padding: 16px 20px;
font-size: 12px;
line-height: 1.6;
color: #000000;
}
.content-scroll h1 {
font-size: 18px;
font-weight: bold;
margin-bottom: 16px;
padding-bottom: 6px;
border-bottom: 2px solid #000080;
color: #000080;
}
.content-scroll h2 {
font-size: 15px;
font-weight: bold;
margin-top: 20px;
margin-bottom: 8px;
color: #000080;
}
.content-scroll h3 {
font-size: 13px;
font-weight: bold;
margin-top: 16px;
margin-bottom: 6px;
}
.content-scroll p {
margin-bottom: 10px;
}
.content-scroll ul,
.content-scroll ol {
margin: 8px 0 10px 20px;
}
.content-scroll li {
margin-bottom: 4px;
}
.content-scroll code {
font-family: "Courier New", monospace;
font-size: 11px;
background: #f0f0f0;
border: 1px solid #c0c0c0;
padding: 0 3px;
}
.content-scroll pre {
background: #f0f0f0;
border-top: 1px solid #808080;
border-left: 1px solid #808080;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
padding: 8px;
margin: 10px 0;
overflow-x: auto;
font-family: "Courier New", monospace;
font-size: 11px;
}
.content-scroll pre code {
background: none;
border: none;
padding: 0;
}
.content-scroll blockquote {
border-left: 3px solid #000080;
padding-left: 12px;
margin: 10px 0;
color: #444444;
font-style: italic;
}
.content-scroll table {
border-collapse: collapse;
width: 100%;
margin: 10px 0;
}
.content-scroll th {
background: #000080;
color: #ffffff;
padding: 4px 8px;
text-align: left;
font-size: 11px;
}
.content-scroll td {
border: 1px solid #c0c0c0;
padding: 4px 8px;
font-size: 11px;
}
.content-scroll tr:nth-child(even) td {
background: #f0f0f0;
}
.content-scroll a {
color: #0000ff;
text-decoration: underline;
}
.content-scroll img {
max-width: 100%;
border: 2px inset #808080;
}
.status-bar {
background: #c0c0c0;
border-top: 2px solid #808080;
padding: 2px 6px;
display: flex;
gap: 1px;
font-size: 10px;
}
.status-pane {
flex: 1;
border-top: 1px solid #808080;
border-left: 1px solid #808080;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
padding: 1px 6px;
}
.taskbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 32px;
background: #c0c0c0;
border-top: 2px solid #ffffff;
display: flex;
align-items: center;
padding: 0 4px;
gap: 4px;
z-index: 1000;
}
.start-btn {
display: flex;
align-items: center;
gap: 4px;
background: #c0c0c0;
border-top: 2px solid #ffffff;
border-left: 2px solid #ffffff;
border-right: 2px solid #808080;
border-bottom: 2px solid #808080;
padding: 2px 8px;
font-weight: bold;
font-size: 11px;
cursor: pointer;
height: 24px;
}
.start-logo {
width: 16px;
height: 16px;
background: linear-gradient(135deg, #ff0000 25%, #00ff00 25%, #00ff00 50%, #0000ff 50%, #0000ff 75%, #ffff00 75%);
border: 1px solid #000000;
flex-shrink: 0;
}
.taskbar-sep {
width: 2px;
height: 22px;
border-left: 1px solid #808080;
border-right: 1px solid #ffffff;
margin: 0 2px;
}
.taskbar-window {
height: 24px;
background: #c0c0c0;
border-top: 2px solid #808080;
border-left: 2px solid #808080;
border-right: 2px solid #ffffff;
border-bottom: 2px solid #ffffff;
padding: 0 8px;
font-size: 11px;
display: flex;
align-items: center;
gap: 4px;
cursor: pointer;
}
.taskbar-clock {
margin-left: auto;
border-top: 1px solid #808080;
border-left: 1px solid #808080;
border-right: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
padding: 2px 6px;
font-size: 11px;
}
body {
padding-bottom: 48px;
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="window">
<div class="title-bar">
<div class="title-bar-left">
<div class="title-bar-icon">N</div>
{{ title }} — {{ config.site.name }}
</div>
<div class="title-bar-buttons">
<div class="tb-btn">_</div>
<div class="tb-btn">&#9633;</div>
<div class="tb-btn">x</div>
</div>
</div>
<div class="menu-bar">
<span class="menu-item">File</span>
<span class="menu-item">Edit</span>
<span class="menu-item">View</span>
<span class="menu-item">Go</span>
<span class="menu-item">Favorites</span>
<span class="menu-item">Help</span>
</div>
<div class="toolbar">
<div class="tool-btn">&#9664;</div>
<div class="tool-btn">&#9654;</div>
<div class="tool-btn">&#8593;</div>
<div class="toolbar-sep"></div>
<div class="tool-btn">&#9003;</div>
<div class="tool-btn">&#9998;</div>
<div class="toolbar-sep"></div>
<div class="tool-btn">&#9733;</div>
<div class="tool-btn">&#9776;</div>
<div class="tool-btn">&#128247;</div>
</div>
<div class="address-bar">
<span class="address-label">Address</span>
<div class="address-input">C:\Documents\{{ config.site.name }}\posts\{{ title }}</div>
</div>
<div class="window-body">
<div class="sidebar">
<div class="sidebar-section">
<div class="sidebar-header">Site</div>
<div class="sidebar-item">
<span class="sidebar-icon">H</span> Home
</div>
<div class="sidebar-item">
<span class="sidebar-icon">P</span> Posts
</div>
<div class="sidebar-item">
<span class="sidebar-icon">A</span> About
</div>
</div>
<div class="sidebar-section">
<div class="sidebar-header">File Info</div>
<div class="sidebar-item">Date: {{ published_date }}</div>
<div class="sidebar-item">Read: {{ reading_time }}</div>
{% if taxonomy.tags %}
<div class="sidebar-item">Tags:</div>
{% for tag in taxonomy.tags %}
<div class="sidebar-item" style="padding-left:16px;">> {{ tag }}</div>
{% endfor %}
{% endif %}
</div>
<div class="sidebar-section">
<div class="sidebar-header">Author</div>
<div class="sidebar-item">{{ config.site.author }}</div>
</div>
</div>
<div class="content-area">
<div class="content-scroll">
{{ content | safe }}
</div>
</div>
</div>
<div class="status-bar">
<div class="status-pane">{{ reading_time }}</div>
<div class="status-pane">{{ published_date }}</div>
<div class="status-pane">{{ config.site.name }}</div>
</div>
</div>
<div class="taskbar">
<div class="start-btn">
<div class="start-logo"></div>
Start
</div>
<div class="taskbar-sep"></div>
<div class="taskbar-window">
<div class="title-bar-icon">N</div>
{{ title }}
</div>
<div class="taskbar-clock">{{ published_date }}</div>
</div>
</body>
</html>

565
templates/xcode.html Normal file
View File

@@ -0,0 +1,565 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>{{ title }} — Xcode</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<style>
html { background: #1e1e1e; }
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #1e1e1e;
--sidebar-bg: #252526;
--toolbar-bg: #3c3c3c;
--tab-bg: #2d2d2d;
--tab-active: #1e1e1e;
--text: #d4d4d4;
--muted: #808080;
--border: #3e3e42;
--purple: #c586c0;
--blue: #569cd6;
--cyan: #4ec9b0;
--green: #6a9955;
--red: #f44747;
--orange: #ce9178;
--yellow: #dcdcaa;
--pink: #c586c0;
}
body {
background: var(--bg);
color: var(--text);
font-family: "JetBrains Mono", "SF Mono", "Menlo", "Monaco", monospace;
font-size: 13px;
line-height: 1.5;
min-height: 100vh;
overflow-x: hidden;
}
/* App chrome */
.xcode-app {
display: flex;
flex-direction: column;
min-height: 100vh;
}
/* Title bar */
.titlebar {
height: 38px;
background: var(--toolbar-bg);
border-bottom: 1px solid #1a1a1a;
display: flex;
align-items: center;
gap: 12px;
padding: 0 12px;
flex-shrink: 0;
}
.traffic-lights {
display: flex;
gap: 7px;
flex-shrink: 0;
}
.tl {
width: 12px;
height: 12px;
border-radius: 50%;
}
.tl-red { background: #ff5f57; }
.tl-yellow { background: #febc2e; }
.tl-green { background: #28c840; }
.titlebar-title {
flex: 1;
text-align: center;
font-size: 12px;
color: var(--muted);
}
.titlebar-run {
display: flex;
gap: 8px;
align-items: center;
}
.run-btn {
width: 26px;
height: 18px;
background: rgba(255,255,255,0.08);
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: var(--muted);
border: 1px solid rgba(255,255,255,0.08);
}
/* Main layout */
.layout {
flex: 1;
display: flex;
overflow: hidden;
}
/* Sidebar */
.sidebar {
width: 220px;
background: var(--sidebar-bg);
border-right: 1px solid var(--border);
flex-shrink: 0;
overflow-y: auto;
padding: 8px 0;
}
.sidebar-section {
padding: 6px 0;
}
.sidebar-section-header {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--muted);
padding: 4px 12px 4px;
}
.sidebar-item {
display: flex;
align-items: center;
gap: 6px;
padding: 3px 12px;
font-size: 12px;
color: var(--text);
cursor: default;
}
.sidebar-item.active {
background: #094771;
color: #fff;
}
.sidebar-item-icon {
font-size: 10px;
width: 14px;
text-align: center;
color: var(--blue);
flex-shrink: 0;
}
.sidebar-item-icon.swift { color: var(--orange); }
.sidebar-item-icon.md { color: var(--cyan); }
.sidebar-item-icon.folder { color: var(--yellow); }
/* Editor area */
.editor-area {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* Tab bar */
.tab-bar {
height: 34px;
background: var(--tab-bg);
border-bottom: 1px solid var(--border);
display: flex;
align-items: stretch;
overflow-x: auto;
flex-shrink: 0;
}
.tab {
display: flex;
align-items: center;
gap: 7px;
padding: 0 14px;
font-size: 12px;
color: var(--muted);
border-right: 1px solid var(--border);
white-space: nowrap;
flex-shrink: 0;
}
.tab.active {
background: var(--tab-active);
color: var(--text);
position: relative;
}
.tab.active::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: var(--blue);
}
.tab-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: #febc2e;
flex-shrink: 0;
}
/* Gutter + content */
.editor-body {
flex: 1;
display: flex;
overflow-y: auto;
overflow-x: hidden;
}
/* Line numbers */
.line-gutter {
background: var(--sidebar-bg);
border-right: 1px solid var(--border);
padding: 16px 12px 16px 8px;
text-align: right;
color: #4a4a4a;
font-size: 11px;
line-height: 1.8;
user-select: none;
flex-shrink: 0;
min-width: 44px;
}
/* Actual content */
.editor-content {
flex: 1;
padding: 16px 28px 60px 20px;
overflow-x: auto;
}
/* Post meta as a comment block */
.meta-comment {
margin-bottom: 24px;
}
.comment-line {
color: var(--green);
line-height: 1.8;
}
/* Post title as a string literal */
.code-title {
margin-bottom: 20px;
}
.keyword { color: var(--purple); }
.type { color: var(--cyan); }
.string { color: var(--orange); }
.number { color: #b5cea8; }
.func { color: var(--yellow); }
/* Content area — rendered markdown as if it's code documentation */
.content-area {
margin-top: 24px;
}
.content-area h1 {
font-size: 16px;
font-weight: 700;
color: var(--blue);
margin-top: 28px;
margin-bottom: 10px;
}
.content-area h1::before {
content: "// MARK: - ";
color: var(--green);
font-weight: 400;
}
.content-area h2 {
font-size: 14px;
font-weight: 700;
color: var(--cyan);
margin-top: 22px;
margin-bottom: 8px;
}
.content-area h2::before {
content: "/// ";
color: var(--green);
font-weight: 400;
}
.content-area h3 {
font-size: 13px;
color: var(--yellow);
margin-top: 18px;
margin-bottom: 6px;
}
.content-area h4, .content-area h5, .content-area h6 {
font-size: 13px;
color: var(--muted);
margin-top: 14px;
margin-bottom: 4px;
}
.content-area p {
color: var(--text);
margin-bottom: 12px;
line-height: 1.7;
}
.content-area a {
color: var(--blue);
text-decoration: underline;
}
.content-area code {
font-family: "JetBrains Mono", monospace;
font-size: 12px;
background: rgba(255,255,255,0.06);
color: var(--orange);
padding: 1px 5px;
border-radius: 3px;
}
.content-area pre {
background: #141414;
border: 1px solid var(--border);
border-radius: 6px;
padding: 14px 16px;
margin: 14px 0;
overflow-x: auto;
}
.content-area pre code {
background: none;
color: var(--text);
padding: 0;
}
.content-area blockquote {
border-left: 3px solid var(--purple);
padding: 10px 16px;
margin: 14px 0;
background: rgba(197,134,192,0.06);
}
.content-area blockquote p {
color: var(--purple);
}
.content-area ul {
margin: 8px 0 14px 0;
list-style: none;
padding: 0;
}
.content-area ul li {
padding-left: 18px;
margin-bottom: 4px;
color: var(--text);
position: relative;
}
.content-area ul li::before {
content: "-";
position: absolute;
left: 4px;
color: var(--muted);
}
.content-area ol {
margin: 8px 0 14px 22px;
color: var(--text);
}
.content-area li {
margin-bottom: 4px;
}
.content-area table {
width: 100%;
border-collapse: collapse;
margin: 14px 0;
font-size: 12px;
}
.content-area th {
background: rgba(255,255,255,0.05);
padding: 7px 12px;
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--cyan);
border-bottom: 1px solid var(--border);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.content-area td {
padding: 7px 12px;
border-bottom: 1px solid rgba(62,62,66,0.5);
}
.content-area img {
max-width: 100%;
border: 1px solid var(--border);
border-radius: 4px;
margin: 10px 0;
}
.content-area hr {
border: none;
border-top: 1px solid var(--border);
margin: 20px 0;
}
/* Status bar */
.status-bar {
height: 22px;
background: #007acc;
display: flex;
align-items: center;
padding: 0 12px;
gap: 16px;
font-size: 11px;
color: rgba(255,255,255,0.9);
flex-shrink: 0;
}
@media (max-width: 700px) {
.sidebar { display: none; }
.line-gutter { display: none; }
}
</style>
</head>
<body>
<a href="/{{ preview_query }}" style="position:fixed;top:calc(1rem + env(safe-area-inset-top, 0px));left:calc(1rem + env(safe-area-inset-left, 0px));z-index:9999;font-family:system-ui,-apple-system,sans-serif;font-size:0.8rem;padding:0.5rem 0.9rem;background:rgba(255,255,255,0.95);color:#000;text-decoration:none;border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,0.15);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(0,0,0,0.1);transition:transform 0.2s">&larr; back</a>
<div class="xcode-app">
<div class="titlebar">
<div class="traffic-lights">
<div class="tl tl-red"></div>
<div class="tl tl-yellow"></div>
<div class="tl tl-green"></div>
</div>
<div class="titlebar-title">{{ config.site.name }} — {{ title }}</div>
<div class="titlebar-run">
<div class="run-btn"></div>
<div class="run-btn"></div>
</div>
</div>
<div class="layout">
<nav class="sidebar">
<div class="sidebar-section">
<div class="sidebar-section-header">Project</div>
<div class="sidebar-item">
<span class="sidebar-item-icon folder"></span>
<span>{{ config.site.name }}</span>
</div>
<div class="sidebar-item" style="padding-left: 28px;">
<span class="sidebar-item-icon folder"></span>
<span>Posts</span>
</div>
<div class="sidebar-item active" style="padding-left: 44px;">
<span class="sidebar-item-icon md">M</span>
<span>{{ title | truncate(18) }}</span>
</div>
</div>
<div class="sidebar-section">
<div class="sidebar-section-header">Meta</div>
<div class="sidebar-item">
<span class="sidebar-item-icon">A</span>
<span>{{ config.site.author }}</span>
</div>
<div class="sidebar-item">
<span class="sidebar-item-icon">D</span>
<span>{{ published_date }}</span>
</div>
<div class="sidebar-item">
<span class="sidebar-item-icon">T</span>
<span>{{ reading_time }}</span>
</div>
{% if taxonomy.tags %}
{% for tag in taxonomy.tags %}
<div class="sidebar-item" style="padding-left: 24px;">
<span class="sidebar-item-icon" style="color: var(--pink);">#</span>
<span>{{ tag }}</span>
</div>
{% endfor %}
{% endif %}
</div>
</nav>
<div class="editor-area">
<div class="tab-bar">
<div class="tab active">
<div class="tab-dot"></div>
<span>{{ title | truncate(24) }}.md</span>
</div>
<div class="tab">README.md</div>
<div class="tab">Package.swift</div>
</div>
<div class="editor-body">
<div class="line-gutter">
{% for i in range(1, 80) %}{{ i }}<br>{% endfor %}
</div>
<div class="editor-content">
<div class="meta-comment">
<div class="comment-line">// ============================================================</div>
<div class="comment-line">// {{ title }}</div>
<div class="comment-line">// Author: {{ config.site.author }}</div>
<div class="comment-line">// Date: {{ published_date }}</div>
{% if updated_date %}<div class="comment-line">// Updated: {{ updated_date }}</div>{% endif %}
<div class="comment-line">// Read: {{ reading_time }}</div>
{% if taxonomy.tags %}<div class="comment-line">// Tags: {% for tag in taxonomy.tags %}{{ tag }}{% if not loop.last %}, {% endif %}{% endfor %}</div>{% endif %}
<div class="comment-line">// ============================================================</div>
</div>
<div class="code-title">
<span class="keyword">let</span> title: <span class="type">String</span> = <span class="string">"{{ title }}"</span>
</div>
<div class="content-area">
{{ content | safe }}
</div>
</div>
</div>
</div>
</div>
<div class="status-bar">
<span>{{ config.site.name }}</span>
<span>Ln 1, Col 1</span>
<span>UTF-8</span>
<span>Markdown</span>
<span>{{ published_date }}</span>
</div>
</div>
</body>
</html>