Commit 19d07f88 authored by santiago duque's avatar santiago duque

prallax now working, also with image and text as 2 blocks

parent 349f1f15
# resident-kirby — Claude instructions
## Project structure
- **Edit source files only:** `src/` (SCSS, JS) and `www/site/` (PHP templates, snippets, blueprints)
- **Never read or edit:** `www/kirby/` — Kirby CMS core, treat as a black box
- **Never manually edit:** `www/assets/` — CodeKit compiles `src/` into here automatically
## Tooling
- CodeKit 3 watches `src/css/``www/assets/css/` and `src/js/``www/assets/js/`
- After editing a `src/` file, CodeKit recompiles; no need to touch the output files
...@@ -17,6 +17,51 @@ ...@@ -17,6 +17,51 @@
"oAP" : "\/.gitignore", "oAP" : "\/.gitignore",
"oF" : 0 "oF" : 0
}, },
"\/CLAUDE.md" : {
"cB" : 0,
"cS" : 0,
"eF" : 1,
"eL" : 1,
"ema" : 1,
"eSQ" : 1,
"ft" : 4096,
"hM" : 0,
"oA" : 0,
"oAP" : "\/CLAUDE.html",
"oF" : 0,
"oFM" : 0,
"oS" : 0,
"pHT" : 0,
"pME" : 1,
"rFN" : 0,
"uCM" : 0
},
"\/src\/css\/_mixins.scss" : {
"aP" : 1,
"bl" : 0,
"co" : 0,
"ec" : 1,
"ft" : 4,
"ma" : 1,
"oA" : 1,
"oAP" : "\/www\/assets\/css\/_mixins.css",
"oF" : 0,
"oS" : 3,
"pg" : 0
},
"\/src\/css\/_vars.scss" : {
"aP" : 1,
"bl" : 0,
"co" : 0,
"ec" : 1,
"ft" : 4,
"ma" : 1,
"oA" : 1,
"oAP" : "\/www\/assets\/css\/_vars.css",
"oF" : 0,
"oS" : 3,
"pg" : 0
},
"\/src\/css\/shared.scss" : { "\/src\/css\/shared.scss" : {
"aP" : 1, "aP" : 1,
"bl" : 0, "bl" : 0,
......
// Sass breakpoints + shared patterns
$bp-laptop: 1100px;
$bp-tablet: 900px;
$bp-mobile: 600px;
@mixin bp($max) {
@media (max-width: $max) {
@content;
}
}
// Monospaced label — font-family, size, tracking, uppercase
@mixin mono-label($size: 11px, $tracking: 0.25em) {
font-family: var(--font-mono);
font-size: $size;
letter-spacing: $tracking;
text-transform: uppercase;
}
// Display type — font-family, size, italic, weight
@mixin display-italic($size, $weight: 400) {
font-family: var(--font-display);
font-size: $size;
font-style: italic;
font-weight: $weight;
}
// Design tokens — The Friedrichshof Account
:root {
--bg: #0a0707;
--bg-2: #120c0c;
--paper: #e8e2d6;
--ink: #d8d2c4;
--ink-dim: #8a847a;
--ink-faint: #4a4540;
--accent: #b91c1c;
--accent-bright: #ef2b2b;
--accent-deep: #5a0e0e;
--rule: #1f1616;
--vignette: rgba(0, 0, 0, 0.85);
--section-margin-bottom: 80px;
--font-display: "Cormorant Garamond", "EB Garamond", Georgia, serif;
--font-body: "EB Garamond", Georgia, "Times New Roman", serif;
--font-mono: "JetBrains Mono", ui-monospace, "Courier New", monospace;
--font-sans: "Inter Tight", system-ui, sans-serif;
}
:root[data-mode="dim"] {
--bg: #1a1414;
--bg-2: #221919;
--ink: #e8e2d6;
--ink-dim: #a8a298;
--ink-faint: #5a5550;
--rule: #2f2222;
--vignette: rgba(0, 0, 0, 0.55);
}
/* =================================================================== /* ===================================================================
Shared styles — atmospheric horror scrollytelling Shared styles — atmospheric horror scrollytelling
=================================================================== */ =================================================================== */
@use 'vars';
@use 'mixins' as m;
:root { // ===== Reset =====
--bg: #0a0707;
--bg-2: #120c0c;
--paper: #e8e2d6;
--ink: #d8d2c4;
--ink-dim: #8a847a;
--ink-faint: #4a4540;
--accent: #b91c1c;
--accent-bright: #ef2b2b;
--accent-deep: #5a0e0e;
--rule: #1f1616;
--vignette: rgba(0,0,0,0.85);
--font-display: "Cormorant Garamond", "EB Garamond", Georgia, serif;
--font-body: "EB Garamond", Georgia, "Times New Roman", serif;
--font-mono: "JetBrains Mono", ui-monospace, "Courier New", monospace;
--font-sans: "Inter Tight", system-ui, sans-serif;
}
:root[data-mode="dim"] {
--bg: #1a1414;
--bg-2: #221919;
--ink: #e8e2d6;
--ink-dim: #a8a298;
--ink-faint: #5a5550;
--rule: #2f2222;
--vignette: rgba(0,0,0,0.55);
}
* { box-sizing: border-box; margin: 0; padding: 0; } * { box-sizing: border-box; margin: 0; padding: 0; }
html, body { html, body {
...@@ -49,7 +23,7 @@ body { ...@@ -49,7 +23,7 @@ body {
position: relative; position: relative;
} }
/* Paper grain */ // ===== Atmospheric overlays =====
.grain { .grain {
position: fixed; position: fixed;
inset: 0; inset: 0;
...@@ -60,7 +34,6 @@ body { ...@@ -60,7 +34,6 @@ body {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"); background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
} }
/* Slow vignette pulse */
.vignette { .vignette {
position: fixed; position: fixed;
inset: 0; inset: 0;
...@@ -69,20 +42,21 @@ body { ...@@ -69,20 +42,21 @@ body {
background: radial-gradient(ellipse at center, transparent 40%, var(--vignette) 100%); background: radial-gradient(ellipse at center, transparent 40%, var(--vignette) 100%);
animation: vignette-pulse 9s ease-in-out infinite; animation: vignette-pulse 9s ease-in-out infinite;
} }
@keyframes vignette-pulse { @keyframes vignette-pulse {
0%, 100% { opacity: 0.85; } 0%, 100% { opacity: 0.85; }
50% { opacity: 1; } 50% { opacity: 1; }
} }
/* Ambient flicker */
.flicker { .flicker {
position: fixed; position: fixed;
inset: 0; inset: 0;
pointer-events: none; pointer-events: none;
z-index: 8000; z-index: 8000;
background: rgba(255,240,230,0.02); background: rgba(255, 240, 230, 0.02);
animation: flicker 7s steps(2, end) infinite; animation: flicker 7s steps(2, end) infinite;
} }
@keyframes flicker { @keyframes flicker {
0%, 92%, 100% { opacity: 0; } 0%, 92%, 100% { opacity: 0; }
93% { opacity: 1; } 93% { opacity: 1; }
...@@ -91,11 +65,15 @@ body { ...@@ -91,11 +65,15 @@ body {
96% { opacity: 0; } 96% { opacity: 0; }
} }
[data-effects="off"] .grain, [data-effects="off"] {
[data-effects="off"] .vignette, .grain, .vignette, .flicker { display: none; }
[data-effects="off"] .flicker { display: none; } .reveal { opacity: 1; transform: none; }
.glitch {
&::before, &::after { display: none; }
}
}
/* ===== Top bar ===== */ // ===== Top bar =====
.topbar { .topbar {
position: fixed; position: fixed;
top: 0; left: 0; right: 0; top: 0; left: 0; right: 0;
...@@ -105,8 +83,9 @@ body { ...@@ -105,8 +83,9 @@ body {
justify-content: space-between; justify-content: space-between;
padding: 28px 40px; padding: 28px 40px;
pointer-events: none; pointer-events: none;
> * { pointer-events: auto; }
} }
.topbar > * { pointer-events: auto; }
.wordmark { .wordmark {
font-family: var(--font-display); font-family: var(--font-display);
...@@ -119,15 +98,18 @@ body { ...@@ -119,15 +98,18 @@ body {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
}
.wordmark::before { &::before {
content: ""; content: "";
width: 8px; height: 8px; width: 8px;
background: var(--accent); height: 8px;
border-radius: 50%; background: var(--accent);
box-shadow: 0 0 12px var(--accent); border-radius: 50%;
box-shadow: 0 0 12px var(--accent);
}
} }
// ===== Menu button =====
.menu-btn { .menu-btn {
background: transparent; background: transparent;
border: none; border: none;
...@@ -137,29 +119,30 @@ body { ...@@ -137,29 +119,30 @@ body {
flex-direction: column; flex-direction: column;
gap: 6px; gap: 6px;
padding: 10px; padding: 10px;
font-family: var(--font-mono); @include m.mono-label(11px, 0.2em);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
align-items: flex-end; align-items: flex-end;
&:hover { color: var(--accent-bright); }
&-lines {
display: flex;
flex-direction: column;
gap: 4px;
align-items: flex-end;
span {
display: block;
height: 1px;
background: currentColor;
&:nth-child(1) { width: 28px; }
&:nth-child(2) { width: 20px; }
&:nth-child(3) { width: 28px; }
}
}
} }
.menu-btn:hover { color: var(--accent-bright); }
.menu-btn-lines {
display: flex;
flex-direction: column;
gap: 4px;
align-items: flex-end;
}
.menu-btn-lines span {
display: block;
height: 1px;
background: currentColor;
}
.menu-btn-lines span:nth-child(1) { width: 28px; }
.menu-btn-lines span:nth-child(2) { width: 20px; }
.menu-btn-lines span:nth-child(3) { width: 28px; }
/* ===== Main menu overlay ===== */ // ===== Menu overlay =====
.menu-overlay { .menu-overlay {
position: fixed; position: fixed;
inset: 0; inset: 0;
...@@ -168,31 +151,42 @@ body { ...@@ -168,31 +151,42 @@ body {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
transition: opacity 0.5s ease; transition: opacity 0.5s ease;
&.open { opacity: 1; pointer-events: auto; }
&::before {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
opacity: 0.15;
mix-blend-mode: overlay;
pointer-events: none;
}
} }
.menu-overlay.open { opacity: 1; pointer-events: auto; }
.menu-overlay::before {
content: "";
position: absolute; inset: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
opacity: 0.15; mix-blend-mode: overlay; pointer-events: none;
}
.menu-close { .menu-close {
position: absolute; top: 28px; right: 40px; position: absolute;
background: transparent; border: none; color: var(--ink); top: 28px;
font-family: var(--font-mono); font-size: 11px; right: 40px;
letter-spacing: 0.2em; text-transform: uppercase; background: transparent;
cursor: pointer; padding: 10px; z-index: 10; border: none;
color: var(--ink);
@include m.mono-label(11px, 0.2em);
cursor: pointer;
padding: 10px;
z-index: 10;
&:hover { color: var(--accent-bright); }
} }
.menu-close:hover { color: var(--accent-bright); }
.menu-inner { .menu-inner {
position: absolute; inset: 0; position: absolute;
inset: 0;
display: grid; display: grid;
grid-template-columns: 1fr 360px; grid-template-columns: 1fr 360px;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
grid-template-areas: grid-template-areas: "head head" "list side";
"head head"
"list side";
padding: 90px 64px 48px; padding: 90px 64px 48px;
gap: 0 64px; gap: 0 64px;
max-height: 100vh; max-height: 100vh;
...@@ -208,6 +202,7 @@ body { ...@@ -208,6 +202,7 @@ body {
border-bottom: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
flex-wrap: wrap; flex-wrap: wrap;
} }
.menu-filter { .menu-filter {
flex: 1; flex: 1;
min-width: 220px; min-width: 220px;
...@@ -220,19 +215,31 @@ body { ...@@ -220,19 +215,31 @@ body {
letter-spacing: 0.1em; letter-spacing: 0.1em;
outline: none; outline: none;
transition: border-color 0.2s; transition: border-color 0.2s;
&:focus { border-color: var(--accent); }
&::placeholder {
color: var(--ink-faint);
text-transform: uppercase;
letter-spacing: 0.15em;
font-size: 11px;
}
} }
.menu-filter:focus { border-color: var(--accent); }
.menu-filter::placeholder { color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.15em; font-size: 11px; }
.menu-section-label { .menu-section-label {
font-family: var(--font-mono); font-size: 11px; @include m.mono-label(11px, 0.25em);
letter-spacing: 0.25em; text-transform: uppercase;
color: var(--accent); color: var(--accent);
display: flex; align-items: center; gap: 12px; display: flex;
align-items: center;
gap: 12px;
white-space: nowrap; white-space: nowrap;
}
.menu-section-label::after { &::after {
content: ""; width: 80px; height: 1px; background: var(--accent-deep); content: "";
width: 80px;
height: 1px;
background: var(--accent-deep);
}
} }
.menu-list { .menu-list {
...@@ -241,33 +248,43 @@ body { ...@@ -241,33 +248,43 @@ body {
padding-right: 24px; padding-right: 24px;
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: var(--accent-deep) transparent; scrollbar-color: var(--accent-deep) transparent;
}
.menu-list::-webkit-scrollbar { width: 6px; }
.menu-list::-webkit-scrollbar-thumb { background: var(--accent-deep); }
.menu-list::-webkit-scrollbar-track { background: transparent; }
.menu-part { margin-bottom: 40px; } &::-webkit-scrollbar { width: 6px; }
.menu-part-head { &::-webkit-scrollbar-thumb { background: var(--accent-deep); }
position: sticky; &::-webkit-scrollbar-track { background: transparent; }
top: 0;
background: linear-gradient(to bottom, var(--bg) 70%, transparent); &.is-empty {
padding: 8px 0 14px; .menu-empty { display: block; }
display: flex; .menu-part { display: none; }
align-items: baseline; }
gap: 16px;
border-bottom: 1px solid var(--rule);
margin-bottom: 8px;
z-index: 2;
}
.menu-part-label {
font-family: var(--font-mono); font-size: 10px;
letter-spacing: 0.3em; text-transform: uppercase;
color: var(--accent);
} }
.menu-part-sub {
font-family: var(--font-display); font-style: italic; .menu-part {
font-size: 18px; color: var(--ink-dim); margin-bottom: 40px;
letter-spacing: 0;
&-head {
position: sticky;
top: 0;
background: linear-gradient(to bottom, var(--bg) 70%, transparent);
padding: 8px 0 14px;
display: flex;
align-items: baseline;
gap: 16px;
border-bottom: 1px solid var(--rule);
margin-bottom: 8px;
z-index: 2;
}
&-label {
@include m.mono-label(10px, 0.3em);
color: var(--accent);
}
&-sub {
@include m.display-italic(18px);
color: var(--ink-dim);
letter-spacing: 0;
}
} }
.menu-chapters { .menu-chapters {
...@@ -275,71 +292,82 @@ body { ...@@ -275,71 +292,82 @@ body {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 0 32px; gap: 0 32px;
}
.menu-chapters li {
border-bottom: 1px solid var(--rule);
transition: opacity 0.2s;
}
.menu-chapters li.hidden { display: none; }
.menu-chapters a {
display: grid;
grid-template-columns: 36px 1fr;
gap: 20px;
align-items: baseline;
padding: 14px 0 14px 14px;
text-decoration: none;
color: var(--ink);
font-family: var(--font-display);
font-size: 22px;
font-weight: 400;
font-style: italic;
transition: color 0.25s, padding 0.25s, background 0.25s;
position: relative;
text-wrap: balance;
}
.menu-chapters a:hover {
color: var(--accent-bright);
padding-left: 22px;
background: rgba(185, 28, 28, 0.04);
}
.menu-chapters a::before {
content: "";
position: absolute;
left: 0; top: 0; bottom: 0;
width: 0;
background: var(--accent);
transition: width 0.25s;
}
.menu-chapters a:hover::before { width: 2px; }
.menu-chapters .num {
font-family: var(--font-mono);
font-style: normal;
font-size: 11px;
letter-spacing: 0.2em;
color: var(--ink-faint);
align-self: center;
}
.menu-chapters .title { line-height: 1.2; }
.menu-chapters .current a { color: var(--accent-bright); } li {
.menu-chapters .current .num { color: var(--accent-bright); } border-bottom: 1px solid var(--rule);
.menu-chapters .current a::before { transition: opacity 0.2s;
width: 2px;
background: var(--accent-bright); &.hidden { display: none; }
}
.menu-chapters .current::after { &.current {
content: "READING"; position: relative;
position: absolute;
right: 0; top: 50%; a { color: var(--accent-bright); }
transform: translateY(-50%); .num { color: var(--accent-bright); }
font-family: var(--font-mono); a::before {
font-size: 9px; width: 2px;
letter-spacing: 0.25em; background: var(--accent-bright);
color: var(--accent); }
padding: 4px 8px;
border: 1px solid var(--accent-deep); &::after {
content: "READING";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
@include m.mono-label(9px, 0.25em);
color: var(--accent);
padding: 4px 8px;
border: 1px solid var(--accent-deep);
}
}
}
a {
display: grid;
grid-template-columns: 36px 1fr;
gap: 20px;
align-items: baseline;
padding: 14px 0 14px 14px;
text-decoration: none;
color: var(--ink);
@include m.display-italic(22px);
font-weight: 400;
transition: color 0.25s, padding 0.25s, background 0.25s;
position: relative;
text-wrap: balance;
&:hover {
color: var(--accent-bright);
padding-left: 22px;
background: rgba(185, 28, 28, 0.04);
&::before { width: 2px; }
}
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0;
background: var(--accent);
transition: width 0.25s;
}
}
.num {
font-family: var(--font-mono);
font-style: normal;
font-size: 11px;
letter-spacing: 0.2em;
color: var(--ink-faint);
align-self: center;
}
.title { line-height: 1.2; }
} }
.menu-chapters .current { position: relative; }
.menu-side { .menu-side {
grid-area: side; grid-area: side;
...@@ -350,55 +378,53 @@ body { ...@@ -350,55 +378,53 @@ body {
flex-direction: column; flex-direction: column;
gap: 24px; gap: 24px;
} }
.menu-about { .menu-about {
font-family: var(--font-display); @include m.display-italic(19px);
font-size: 19px;
font-style: italic;
color: var(--ink-dim); color: var(--ink-dim);
line-height: 1.5; line-height: 1.5;
} }
.menu-progress { .menu-progress {
margin-top: auto; margin-top: auto;
padding-top: 24px; padding-top: 24px;
border-top: 1px solid var(--rule); border-top: 1px solid var(--rule);
&-bar {
height: 2px;
background: var(--rule);
margin-bottom: 12px;
position: relative;
span {
position: absolute;
left: 0;
top: 0;
bottom: 0;
background: var(--accent);
box-shadow: 0 0 8px var(--accent);
}
}
&-meta {
display: flex;
justify-content: space-between;
@include m.mono-label(10px, 0.25em);
color: var(--ink-dim);
.accent { color: var(--accent-bright); }
}
} }
.menu-progress-bar {
height: 2px;
background: var(--rule);
margin-bottom: 12px;
position: relative;
}
.menu-progress-bar span {
position: absolute;
left: 0; top: 0; bottom: 0;
background: var(--accent);
box-shadow: 0 0 8px var(--accent);
}
.menu-progress-meta {
display: flex;
justify-content: space-between;
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-dim);
}
.menu-progress-meta .accent { color: var(--accent-bright); }
.menu-empty { .menu-empty {
padding: 24px; padding: 24px;
font-family: var(--font-mono); @include m.mono-label(11px, 0.2em);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
text-align: center; text-align: center;
display: none; display: none;
} }
.menu-list.is-empty .menu-empty { display: block; }
.menu-list.is-empty .menu-part { display: none; }
/* ===== Chapter pagination footer ===== */ // ===== Chapter footer =====
.chapter-footer { .chapter-footer {
position: relative; position: relative;
padding: 120px 40px 80px; padding: 120px 40px 80px;
...@@ -407,19 +433,21 @@ body { ...@@ -407,19 +433,21 @@ body {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 40px; gap: 40px;
background: var(--bg); background: var(--bg);
&::before {
content: "";
position: absolute;
top: -1px;
left: 50%;
transform: translateX(-50%);
width: 12px;
height: 12px;
background: var(--accent);
border-radius: 50%;
box-shadow: 0 0 0 4px var(--bg), 0 0 20px var(--accent);
}
} }
.chapter-footer::before {
content: "";
position: absolute;
top: -1px;
left: 50%;
transform: translateX(-50%);
width: 12px;
height: 12px;
background: var(--accent);
border-radius: 50%;
box-shadow: 0 0 0 4px var(--bg), 0 0 20px var(--accent);
}
.nav-card { .nav-card {
text-decoration: none; text-decoration: none;
color: var(--ink); color: var(--ink);
...@@ -430,59 +458,64 @@ body { ...@@ -430,59 +458,64 @@ body {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
min-height: 180px; min-height: 180px;
&:hover {
border-color: var(--accent);
background: rgba(185, 28, 28, 0.05);
.arrow { color: var(--accent-bright); }
}
&.disabled {
opacity: 0.3;
pointer-events: none;
}
&.prev {
.arrow { left: 28px; }
&:hover .arrow { transform: translateX(-6px); }
}
&.next {
text-align: right;
.arrow { right: 28px; }
&:hover .arrow { transform: translateX(6px); }
}
.label, .num-big, .title { display: block; }
.label {
@include m.mono-label(11px, 0.25em);
color: var(--ink-faint);
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 10px;
}
.num-big {
font-family: var(--font-display);
font-size: 14px;
letter-spacing: 0.2em;
color: var(--accent);
margin-bottom: 8px;
}
.title {
@include m.display-italic(28px);
line-height: 1.2;
}
.arrow {
position: absolute;
bottom: 24px;
@include m.mono-label(11px, 0.2em);
color: var(--ink-faint);
transition: color 0.3s, transform 0.3s;
}
} }
.nav-card:hover {
border-color: var(--accent);
background: rgba(185, 28, 28, 0.05);
}
.nav-card.disabled {
opacity: 0.3;
pointer-events: none;
}
.nav-card .label, .nav-card .num-big, .nav-card .title { display: block; }
.nav-card .label {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-faint);
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 10px;
}
.nav-card.next { text-align: right; }
.nav-card .num-big {
font-family: var(--font-display);
font-size: 14px;
letter-spacing: 0.2em;
color: var(--accent);
margin-bottom: 8px;
}
.nav-card .title {
font-family: var(--font-display);
font-size: 28px;
font-style: italic;
font-weight: 400;
line-height: 1.2;
}
.nav-card .arrow {
position: absolute;
bottom: 24px;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-faint);
transition: color 0.3s, transform 0.3s;
}
.nav-card.prev .arrow { left: 28px; }
.nav-card.next .arrow { right: 28px; }
.nav-card:hover .arrow { color: var(--accent-bright); }
.nav-card.prev:hover .arrow { transform: translateX(-6px); }
.nav-card.next:hover .arrow { transform: translateX(6px); }
/* ===== Brush dividers ===== */ // ===== Brush dividers =====
.brush-divider { .brush-divider {
width: 100%; width: 100%;
height: 24px; height: 24px;
...@@ -490,61 +523,62 @@ body { ...@@ -490,61 +523,62 @@ body {
opacity: 0.7; opacity: 0.7;
} }
/* ===== Reveal-on-scroll ===== */ // ===== Reveal on scroll =====
.reveal { .reveal {
opacity: 0; opacity: 0;
transform: translateY(30px); transform: translateY(30px);
transition: opacity 1.2s ease, transform 1.2s ease; transition: opacity 1.2s ease, transform 1.2s ease;
}
.reveal.in { &.in {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
} }
[data-effects="off"] .reveal {
opacity: 1;
transform: none;
} }
/* ===== Glitch / chromatic aberration ===== */ // ===== Glitch / chromatic aberration =====
.glitch { .glitch {
position: relative; position: relative;
display: inline-block; display: inline-block;
color: var(--ink); color: var(--ink);
&::before,
&::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
pointer-events: none;
opacity: 0.7;
}
&::before {
color: var(--accent-bright);
transform: translate(-1.5px, 0);
mix-blend-mode: screen;
animation: glitch-shift 4s infinite steps(2, end);
}
&::after {
color: #1ea7c4;
transform: translate(1.5px, 0);
mix-blend-mode: screen;
animation: glitch-shift 4.3s infinite steps(2, end) reverse;
}
} }
.glitch::before,
.glitch::after {
content: attr(data-text);
position: absolute;
top: 0; left: 0;
width: 100%;
pointer-events: none;
opacity: 0.7;
}
.glitch::before {
color: var(--accent-bright);
transform: translate(-1.5px, 0);
mix-blend-mode: screen;
animation: glitch-shift 4s infinite steps(2, end);
}
.glitch::after {
color: #1ea7c4;
transform: translate(1.5px, 0);
mix-blend-mode: screen;
animation: glitch-shift 4.3s infinite steps(2, end) reverse;
}
@keyframes glitch-shift { @keyframes glitch-shift {
0%, 88%, 100% { transform: translate(0, 0); opacity: 0; } 0%, 88%, 100% { transform: translate(0, 0); opacity: 0; }
90% { transform: translate(-2px, 0.5px); opacity: 0.8; } 90% { transform: translate(-2px, 0.5px); opacity: 0.8; }
92% { transform: translate(2px, -0.5px); opacity: 0.6; } 92% { transform: translate(2px, -0.5px); opacity: 0.6; }
94% { transform: translate(-1px, 0); opacity: 0.4; } 94% { transform: translate(-1px, 0); opacity: 0.4; }
} }
[data-effects="off"] .glitch::before,
[data-effects="off"] .glitch::after { display: none; }
/* ===== Scroll progress bar ===== */ // ===== Scroll progress bar =====
.progress { .progress {
position: fixed; position: fixed;
top: 0; left: 0; top: 0;
left: 0;
height: 2px; height: 2px;
background: var(--accent); background: var(--accent);
z-index: 200; z-index: 200;
...@@ -553,8 +587,8 @@ body { ...@@ -553,8 +587,8 @@ body {
box-shadow: 0 0 8px var(--accent); box-shadow: 0 0 8px var(--accent);
} }
/* ===== Utility ===== */ // ===== Utility =====
.mono { font-family: var(--font-mono); letter-spacing: 0.15em; text-transform: uppercase; font-size: 11px; } .mono { @include m.mono-label(11px, 0.15em); }
.dim { color: var(--ink-dim); } .dim { color: var(--ink-dim); }
.faint { color: var(--ink-faint); } .faint { color: var(--ink-faint); }
...@@ -563,8 +597,8 @@ body { ...@@ -563,8 +597,8 @@ body {
color: var(--paper); color: var(--paper);
} }
/* ===== Responsive menu ===== */ // ===== Responsive =====
@media (max-width: 1100px) { @include m.bp(m.$bp-laptop) {
.menu-inner { .menu-inner {
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto; grid-template-rows: auto 1fr auto;
...@@ -572,7 +606,9 @@ body { ...@@ -572,7 +606,9 @@ body {
padding: 80px 32px 24px; padding: 80px 32px 24px;
gap: 16px; gap: 16px;
} }
.menu-list { min-height: 50vh; padding-right: 8px; } .menu-list { min-height: 50vh; padding-right: 8px; }
.menu-side { .menu-side {
border-left: none; border-left: none;
border-top: 1px solid var(--rule); border-top: 1px solid var(--rule);
...@@ -583,9 +619,12 @@ body { ...@@ -583,9 +619,12 @@ body {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
.menu-section-label { display: none; }
} }
.menu-side .menu-section-label { display: none; }
.menu-about { display: none; } .menu-about { display: none; }
.menu-progress { .menu-progress {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
...@@ -593,13 +632,19 @@ body { ...@@ -593,13 +632,19 @@ body {
flex: 1; flex: 1;
min-width: 200px; min-width: 200px;
} }
.menu-chapters { grid-template-columns: 1fr; } .menu-chapters { grid-template-columns: 1fr; }
} }
@media (max-width: 600px) {
@include m.bp(m.$bp-mobile) {
.menu-close { top: 18px; right: 20px; } .menu-close { top: 18px; right: 20px; }
.menu-inner { padding: 70px 20px 24px; } .menu-inner { padding: 70px 20px 24px; }
.menu-list { min-height: 55vh; } .menu-list { min-height: 55vh; }
.menu-chapters a { font-size: 19px; padding: 12px 0 12px 10px; }
.menu-chapters .current::after { display: none; } .menu-chapters {
a { font-size: 19px; padding: 12px 0 12px 10px; }
.current::after { display: none; }
}
.menu-head { gap: 16px; } .menu-head { gap: 16px; }
} }
/* =================================================================== /* ===================================================================
Chapter page — scrollytelling layout Chapter page — scrollytelling layout
=================================================================== */ =================================================================== */
@use '../mixins' as m;
.chapter-page { .chapter-page { position: relative; }
position: relative;
}
/* ===== Hero / chapter opener ===== */ // ===== Hero / chapter opener =====
.chapter-hero { .chapter-hero {
height: 100vh; height: 100vh;
min-height: 700px; min-height: 700px;
...@@ -15,33 +14,34 @@ ...@@ -15,33 +14,34 @@
justify-content: center; justify-content: center;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
}
.chapter-hero-bg { &-bg {
position: absolute; position: absolute;
inset: -10%; inset: -10%;
background: background:
radial-gradient(ellipse at 30% 40%, rgba(90, 14, 14, 0.6) 0%, transparent 50%), radial-gradient(ellipse at 30% 40%, rgba(90, 14, 14, 0.6) 0%, transparent 50%),
radial-gradient(ellipse at 70% 60%, rgba(20, 8, 8, 0.8) 0%, transparent 60%), var(--bg); radial-gradient(ellipse at 70% 60%, rgba(20, 8, 8, 0.8) 0%, transparent 60%), var(--bg);
will-change: transform; will-change: transform;
} }
.chapter-hero-grain { &-grain {
position: absolute; position: absolute;
inset: 0; inset: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.02' numOctaves='3' seed='3'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"); background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.02' numOctaves='3' seed='3'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
opacity: 0.4; opacity: 0.4;
mix-blend-mode: multiply; mix-blend-mode: multiply;
} }
.chapter-hero-content { &-content {
position: relative; position: relative;
z-index: 2; z-index: 2;
text-align: center; text-align: center;
max-width: 800px; max-width: 800px;
padding: 0 40px; padding: 0 40px;
}
} }
// ===== Chapter numeral =====
.chapter-numeral-frame { .chapter-numeral-frame {
position: relative; position: relative;
width: 280px; width: 280px;
...@@ -50,14 +50,16 @@ ...@@ -50,14 +50,16 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
svg.ring {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
animation: slow-rotate 120s linear infinite;
}
} }
.chapter-numeral-frame svg.ring {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
animation: slow-rotate 120s linear infinite;
}
.chapter-numeral { .chapter-numeral {
font-family: var(--font-display); font-family: var(--font-display);
font-size: 180px; font-size: 180px;
...@@ -72,46 +74,38 @@ ...@@ -72,46 +74,38 @@
} }
@keyframes slow-rotate { @keyframes slow-rotate {
to { to { transform: rotate(360deg); }
transform: rotate(360deg);
}
} }
.chapter-kicker { .chapter-kicker {
font-family: var(--font-mono); @include m.mono-label(12px, 0.4em);
font-size: 12px;
letter-spacing: 0.4em;
text-transform: uppercase;
color: var(--ink-dim); color: var(--ink-dim);
margin-bottom: 16px; margin-bottom: 16px;
}
.chapter-kicker .accent { .accent { color: var(--accent); }
color: var(--accent);
} }
.chapter-title { .chapter-title {
font-family: var(--font-display); @include m.display-italic(clamp(48px, 7vw, 96px));
font-size: clamp(48px, 7vw, 96px);
font-weight: 400; font-weight: 400;
font-style: italic;
line-height: 1.05; line-height: 1.05;
letter-spacing: -0.02em; letter-spacing: -0.02em;
color: var(--paper); color: var(--paper);
margin-bottom: 32px; margin-bottom: 32px;
.typed-cursor {
display: inline-block;
width: 0.5ch;
background: var(--accent);
animation: blink 0.8s steps(2, end) infinite;
margin-left: 4px;
height: 0.9em;
vertical-align: -0.1em;
}
} }
.chapter-title .typed-cursor {
display: inline-block;
width: 0.5ch;
background: var(--accent);
animation: blink 0.8s steps(2, end) infinite;
margin-left: 4px;
height: 0.9em;
vertical-align: -0.1em;
}
@keyframes blink { @keyframes blink {
50% { 50% { opacity: 0; }
opacity: 0;
}
} }
.chapter-meta { .chapter-meta {
...@@ -119,14 +113,10 @@ ...@@ -119,14 +113,10 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 24px; gap: 24px;
font-family: var(--font-mono); @include m.mono-label(11px, 0.25em);
font-size: 11px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
}
.chapter-meta .dot { .dot { color: var(--accent); }
color: var(--accent);
} }
.scroll-cue { .scroll-cue {
...@@ -134,36 +124,28 @@ ...@@ -134,36 +124,28 @@
bottom: 40px; bottom: 40px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
font-family: var(--font-mono); @include m.mono-label(10px, 0.3em);
font-size: 10px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
animation: bob 2.5s ease-in-out infinite; animation: bob 2.5s ease-in-out infinite;
&::after {
content: "";
width: 1px;
height: 32px;
background: linear-gradient(to bottom, var(--accent), transparent);
}
} }
.scroll-cue::after {
content: "";
width: 1px;
height: 32px;
background: linear-gradient(to bottom, var(--accent), transparent);
}
@keyframes bob { @keyframes bob {
0%, 0%, 100% { transform: translate(-50%, 0); opacity: 0.6; }
100% { 50% { transform: translate(-50%, 6px); opacity: 1; }
transform: translate(-50%, 0);
opacity: 0.6;
}
50% {
transform: translate(-50%, 6px);
opacity: 1;
}
} }
/* ===== Prose body ===== */ // ===== Prose body =====
.chapter-body { .chapter-body {
margin: 0 auto; margin: 0 auto;
position: relative; position: relative;
...@@ -172,132 +154,182 @@ ...@@ -172,132 +154,182 @@
margin: 0 auto; margin: 0 auto;
padding: 0 40px; padding: 0 40px;
max-width: 680px; max-width: 680px;
&:first-of-type {
padding-top: 120px;
}
&:last-of-type {
padding-top: 60px;
}
} }
}
.chapter-body p { p {
font-family: var(--font-body); font-family: var(--font-body);
font-size: 21px; font-size: 21px;
line-height: 1.75; line-height: 1.75;
color: var(--ink); color: var(--ink);
margin-bottom: 1.6em; margin-bottom: 1.6em;
text-wrap: pretty; text-wrap: pretty;
} position: relative;
}
.prose.capitalise p:first-of-type::first-letter { .pull {
font-family: var(--font-display); @include m.display-italic(38px);
font-size: 5.5em; font-weight: 400;
font-style: italic; line-height: 1.25;
font-weight: 400; color: var(--paper);
float: left; margin: 80px -40px;
line-height: 0.85; padding: 0 40px;
margin: 0.05em 0.12em 0 -0.05em; position: relative;
color: var(--accent); text-wrap: balance;
}
.chapter-body .pull { &::before {
font-family: var(--font-display); content: "";
font-size: 38px; position: absolute;
font-style: italic; left: 0;
font-weight: 400; top: 0;
line-height: 1.25; bottom: 0;
color: var(--paper); width: 2px;
margin: 80px -40px; background: var(--accent);
padding: 0 40px; }
position: relative; }
text-wrap: balance;
}
.chapter-body .pull::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 2px;
background: var(--accent);
}
.chapter-body .key-line, .key-line,
.chapter-body em { em {
//font-family: var(--font-display); //font-family: var(--font-display);
font-style: italic; font-style: italic;
color: var(--accent-bright); color: var(--accent-bright);
}
} }
/* ===== Pinned full-bleed section ===== */ .prose.capitalise {
.pinned-section { padding-top: 120px;
height: 250vh;
position: relative; p:first-of-type::first-letter {
} @include m.display-italic(5.5em);
.pinned-stage { font-weight: 400;
position: sticky; float: left;
top: 0; line-height: 0.85;
height: 100vh; margin: 0.05em 0.12em 0 -0.05em;
display: flex; color: var(--accent);
align-items: center; }
justify-content: center;
overflow: hidden;
background: var(--bg-2);
}
.pinned-bg {
position: absolute;
inset: -15% 0;
background-size: cover;
background-position: center;
opacity: 0.5;
filter: contrast(1.2) brightness(0.5);
}
.pinned-bg.t1 {
background:
radial-gradient(circle at 20% 80%, rgba(185, 28, 28, 0.3), transparent 40%),
radial-gradient(circle at 80% 20%, rgba(40, 12, 12, 0.8), transparent 50%),
linear-gradient(180deg, #0a0707 0%, #1a0a0a 50%, #0a0707 100%);
}
.pinned-overlay {
position: absolute;
inset: 0;
background-image: repeating-linear-gradient(
90deg,
transparent 0,
transparent 80px,
rgba(232, 226, 214, 0.02) 80px,
rgba(232, 226, 214, 0.02) 81px
);
} }
// ===== Pinned text — full-bleed sticky stage with centred heading/body =====
.pinned-text { .pinned-text {
position: relative; &-section {
z-index: 2; height: 250vh;
max-width: 800px; position: relative;
padding: 0 40px; margin: var(--section-margin-bottom) 0;
text-align: center; }
}
.pinned-text h2 { &-stage {
font-family: var(--font-display); position: sticky;
font-size: clamp(40px, 6vw, 72px); top: 0;
font-style: italic; height: 100vh;
font-weight: 400; display: flex;
line-height: 1.1; align-items: center;
color: var(--paper); justify-content: center;
margin-bottom: 32px; overflow: hidden;
text-wrap: balance; background: var(--bg-2);
}
&-bg {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
opacity: 0.5;
filter: contrast(1.2) brightness(0.5);
&.t1 {
background:
radial-gradient(circle at 20% 80%, rgba(185, 28, 28, 0.3), transparent 40%),
radial-gradient(circle at 80% 20%, rgba(40, 12, 12, 0.8), transparent 50%),
linear-gradient(180deg, #0a0707 0%, #1a0a0a 50%, #0a0707 100%);
}
}
&-overlay {
position: absolute;
inset: 0;
background-image: repeating-linear-gradient(
90deg,
transparent 0,
transparent 80px,
rgba(232, 226, 214, 0.02) 80px,
rgba(232, 226, 214, 0.02) 81px
);
}
&-copy {
position: relative;
z-index: 2;
max-width: 800px;
padding: 0 40px;
text-align: center;
h2 {
@include m.display-italic(clamp(40px, 6vw, 72px));
font-weight: 400;
line-height: 1.1;
color: var(--paper);
margin-bottom: 32px;
text-wrap: balance;
}
p {
@include m.display-italic(22px);
color: var(--ink-dim);
max-width: 520px;
margin: 0 auto;
line-height: 1.5;
}
}
} }
.pinned-text p {
font-family: var(--font-display); // ===== Pinned image — image sticks, text scrolls over it =====
font-size: 22px; .pinned-image {
font-style: italic; &-section {
color: var(--ink-dim); position: relative;
max-width: 520px; clip-path: inset(0);
margin: 0 auto; margin: var(--section-margin-bottom) 0;
line-height: 1.5; }
&-stage {
position: sticky;
top: 0;
height: 100vh;
overflow: hidden;
margin-bottom: -100vh;
}
&-bg {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
filter: brightness(0.5);
}
&-overlay {
position: absolute;
inset: 0;
background: linear-gradient(to bottom, transparent 30%, rgba(10, 7, 7, 0.85) 100%);
}
&-content {
position: relative;
z-index: 1;
padding: 50vh 40px 50vh;
max-width: 680px;
margin: 0 auto;
p {
font-family: var(--font-body);
font-size: 21px;
line-height: 1.75;
color: var(--ink);
margin-bottom: 1.6em;
text-wrap: pretty;
}
}
} }
/* ===== Section label ===== */ // ===== Section label =====
.section-label { .section-label {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -305,78 +337,76 @@ ...@@ -305,78 +337,76 @@
max-width: 680px; max-width: 680px;
margin: 0 auto 40px; margin: 0 auto 40px;
padding: 0 40px; padding: 0 40px;
font-family: var(--font-mono); @include m.mono-label(11px, 0.3em);
font-size: 11px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--accent); color: var(--accent);
}
.section-label::before { &::before {
content: ""; content: "";
width: 24px; width: 24px;
height: 1px; height: 1px;
background: var(--accent); background: var(--accent);
}
} }
/* ===== Image slot (abstract texture placeholder) ===== */ // ===== Image slot (abstract texture placeholder) =====
.texture-slot { .texture-slot {
width: 100%; width: 100%;
height: 60vh; height: 60vh;
margin: 80px 0; margin: var(--section-margin-bottom) 0;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
}
.texture-slot.t-rust { &.t-rust {
background: background:
radial-gradient(ellipse at 30% 50%, rgba(120, 30, 20, 0.4), transparent 60%), radial-gradient(ellipse at 30% 50%, rgba(120, 30, 20, 0.4), transparent 60%),
radial-gradient(ellipse at 70% 30%, rgba(40, 10, 10, 0.6), transparent 50%), radial-gradient(ellipse at 70% 30%, rgba(40, 10, 10, 0.6), transparent 50%),
linear-gradient(135deg, #1a0a0a, #0a0707); linear-gradient(135deg, #1a0a0a, #0a0707);
} }
.texture-slot.t-concrete {
background: &.t-concrete {
radial-gradient(circle at 20% 80%, rgba(60, 40, 35, 0.3), transparent 50%), background:
radial-gradient(circle at 80% 20%, rgba(20, 14, 14, 0.8), transparent 60%), #0d0908; radial-gradient(circle at 20% 80%, rgba(60, 40, 35, 0.3), transparent 50%),
} radial-gradient(circle at 80% 20%, rgba(20, 14, 14, 0.8), transparent 60%), #0d0908;
.texture-slot::after { }
content: "";
position: absolute; &::after {
inset: 0; content: "";
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.015' numOctaves='4'/><feColorMatrix values='0 0 0 0 0.3 0 0 0 0 0.1 0 0 0 0 0.05 0 0 0 0.7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>"); position: absolute;
mix-blend-mode: multiply; inset: 0;
opacity: 0.6; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.015' numOctaves='4'/><feColorMatrix values='0 0 0 0 0.3 0 0 0 0 0.1 0 0 0 0 0.05 0 0 0 0.7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
} mix-blend-mode: multiply;
.texture-slot .texture-caption { opacity: 0.6;
position: absolute; }
bottom: 20px;
left: 24px; .texture-caption {
font-family: var(--font-mono); position: absolute;
font-size: 10px; bottom: 20px;
letter-spacing: 0.25em; left: 24px;
text-transform: uppercase; @include m.mono-label(10px, 0.25em);
color: var(--ink-dim); color: var(--ink-dim);
z-index: 2; z-index: 2;
}
} }
/* ===== Marginalia / note ===== */ // ===== Marginalia / note =====
.note { .note {
margin: 60px auto; margin: 60px auto;
padding: 32px 40px; padding: 32px 40px;
border-left: 2px solid var(--accent-deep); border-left: 2px solid var(--accent-deep);
background: rgba(185, 28, 28, 0.04); background: rgba(185, 28, 28, 0.04);
}
.note, &, p {
.note p { font-family: var(--font-mono);
font-family: var(--font-mono); font-size: 13px;
font-size: 13px; line-height: 1.7;
line-height: 1.7; color: var(--ink-dim);
color: var(--ink-dim); letter-spacing: 0.02em;
letter-spacing: 0.02em; }
}
.note .note-label { .note-label {
display: block; display: block;
font-size: 10px; @include m.mono-label(10px, 0.3em);
letter-spacing: 0.3em; color: var(--accent);
text-transform: uppercase; margin-bottom: 12px;
color: var(--accent); }
margin-bottom: 12px;
} }
/* ===== Cover-specific ===== */ /* ===================================================================
Home / cover page
=================================================================== */
@use '../mixins' as m;
// ===== Cover hero =====
.cover-hero { .cover-hero {
min-height: 100vh; min-height: 100vh;
position: relative; position: relative;
...@@ -6,6 +11,7 @@ ...@@ -6,6 +11,7 @@
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
} }
.cover-bg { .cover-bg {
position: absolute; position: absolute;
inset: 0; inset: 0;
...@@ -14,24 +20,25 @@ ...@@ -14,24 +20,25 @@
radial-gradient(ellipse at 80% 70%, rgba(120, 20, 20, 0.25) 0%, transparent 50%), radial-gradient(ellipse at 80% 70%, rgba(120, 20, 20, 0.25) 0%, transparent 50%),
radial-gradient(ellipse at 50% 100%, rgba(20, 8, 8, 1) 0%, transparent 60%), radial-gradient(ellipse at 50% 100%, rgba(20, 8, 8, 1) 0%, transparent 60%),
var(--bg); var(--bg);
}
.cover-bg::after {
content: "";
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='600'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='8'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
mix-blend-mode: multiply;
opacity: 0.5;
}
.cover-bg .brush { &::after {
position: absolute; content: "";
left: -5%; position: absolute;
right: -5%; inset: 0;
top: 56%; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='600'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='8'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
height: 220px; mix-blend-mode: multiply;
pointer-events: none; opacity: 0.5;
opacity: 0.55; }
.brush {
position: absolute;
left: -5%;
right: -5%;
top: 56%;
height: 220px;
pointer-events: none;
opacity: 0.55;
}
} }
.cover-content { .cover-content {
...@@ -42,27 +49,28 @@ ...@@ -42,27 +49,28 @@
grid-template-rows: 1fr auto; grid-template-rows: 1fr auto;
padding: 140px 80px 60px; padding: 140px 80px 60px;
} }
.cover-titleblock { .cover-titleblock {
align-self: center; align-self: center;
max-width: 1100px; max-width: 1100px;
} }
.cover-eyebrow { .cover-eyebrow {
font-family: var(--font-mono); @include m.mono-label(12px, 0.4em);
font-size: 12px;
letter-spacing: 0.4em;
text-transform: uppercase;
color: var(--accent); color: var(--accent);
margin-bottom: 40px; margin-bottom: 40px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16px; gap: 16px;
&::before {
content: "";
width: 32px;
height: 1px;
background: var(--accent);
}
} }
.cover-eyebrow::before {
content: "";
width: 32px;
height: 1px;
background: var(--accent);
}
.cover-title { .cover-title {
font-family: var(--font-display); font-family: var(--font-display);
font-size: clamp(72px, 11vw, 168px); font-size: clamp(72px, 11vw, 168px);
...@@ -72,33 +80,32 @@ ...@@ -72,33 +80,32 @@
color: var(--paper); color: var(--paper);
margin-bottom: 32px; margin-bottom: 32px;
text-wrap: balance; text-wrap: balance;
em {
font-style: italic;
font-weight: 400;
color: var(--accent-bright);
display: block;
}
} }
.cover-title em {
font-style: italic;
font-weight: 400;
color: var(--accent-bright);
display: block;
}
.cover-tagline { .cover-tagline {
font-family: var(--font-display); @include m.display-italic(clamp(20px, 2vw, 26px));
font-size: clamp(20px, 2vw, 26px);
font-style: italic;
color: var(--ink-dim); color: var(--ink-dim);
max-width: 540px; max-width: 540px;
line-height: 1.4; line-height: 1.4;
margin-bottom: 48px; margin-bottom: 48px;
} }
.cover-meta { .cover-meta {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 32px; gap: 32px;
font-family: var(--font-mono); @include m.mono-label(11px, 0.25em);
font-size: 11px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-dim); color: var(--ink-dim);
.pip { color: var(--accent); }
} }
.cover-meta .pip { color: var(--accent); }
.cover-bottom { .cover-bottom {
align-self: end; align-self: end;
...@@ -109,60 +116,56 @@ ...@@ -109,60 +116,56 @@
padding-top: 60px; padding-top: 60px;
border-top: 1px solid var(--rule); border-top: 1px solid var(--rule);
} }
.cover-cta { .cover-cta {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 16px; gap: 16px;
font-family: var(--font-mono); @include m.mono-label(12px, 0.3em);
font-size: 12px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(--paper); color: var(--paper);
text-decoration: none; text-decoration: none;
padding: 18px 28px; padding: 18px 28px;
border: 1px solid var(--accent); border: 1px solid var(--accent);
background: rgba(185, 28, 28, 0.08); background: rgba(185, 28, 28, 0.08);
transition: background 0.3s, border-color 0.3s, transform 0.3s; transition: background 0.3s, border-color 0.3s, transform 0.3s;
&:hover {
background: rgba(185, 28, 28, 0.2);
border-color: var(--accent-bright);
transform: translateX(4px);
}
.arr { color: var(--accent); }
} }
.cover-cta:hover {
background: rgba(185, 28, 28, 0.2);
border-color: var(--accent-bright);
transform: translateX(4px);
}
.cover-cta .arr { color: var(--accent); }
.cover-warning { .cover-warning {
font-family: var(--font-mono); @include m.mono-label(10px, 0.25em);
font-size: 10px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
line-height: 1.8; line-height: 1.8;
max-width: 280px; max-width: 280px;
text-align: right; text-align: right;
}
.cover-warning .label { .label {
color: var(--accent); color: var(--accent);
display: block; display: block;
margin-bottom: 6px; margin-bottom: 6px;
}
} }
.cover-stamp { .cover-stamp {
font-family: var(--font-mono); @include m.mono-label(10px, 0.25em);
font-size: 10px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
line-height: 1.8; line-height: 1.8;
} }
/* ===== Chapter index ===== */ // ===== Chapter index =====
.index-section { .index-section {
position: relative; position: relative;
padding: 160px 80px 120px; padding: 160px 80px 120px;
background: var(--bg-2); background: var(--bg-2);
border-top: 1px solid var(--rule); border-top: 1px solid var(--rule);
} }
.index-header { .index-header {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
...@@ -171,87 +174,90 @@ ...@@ -171,87 +174,90 @@
max-width: 1400px; max-width: 1400px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
}
.index-header h2 { h2 {
font-family: var(--font-display); font-family: var(--font-display);
font-size: clamp(56px, 7vw, 96px); font-size: clamp(56px, 7vw, 96px);
font-style: italic; font-style: italic;
font-weight: 300; font-weight: 300;
line-height: 1; line-height: 1;
color: var(--paper); color: var(--paper);
letter-spacing: -0.02em; letter-spacing: -0.02em;
} }
.index-header .text {
font-family: var(--font-display); .text {
font-size: 22px; @include m.display-italic(22px);
font-style: italic; color: var(--ink-dim);
color: var(--ink-dim); line-height: 1.5;
line-height: 1.5; max-width: 36ch;
max-width: 36ch; align-self: end;
align-self: end; }
} }
.index-list { .index-list {
max-width: 1400px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
list-style: none; list-style: none;
li {
border-top: 1px solid var(--rule);
&:last-child { border-bottom: 1px solid var(--rule); }
}
a {
display: grid;
grid-template-columns: 100px 1fr 200px 80px;
align-items: center;
gap: 40px;
padding: 36px 24px;
text-decoration: none;
color: var(--ink);
transition: padding 0.4s, background 0.4s;
position: relative;
&:hover {
background: rgba(185, 28, 28, 0.06);
padding-left: 48px;
&::before { width: 3px; }
.index-title { color: var(--accent-bright); }
.index-arrow { color: var(--accent-bright); transform: translateX(8px); }
}
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0;
background: var(--accent);
transition: width 0.4s;
}
}
} }
.index-list li {
border-top: 1px solid var(--rule);
}
.index-list li:last-child {
border-bottom: 1px solid var(--rule);
}
.index-list a {
display: grid;
grid-template-columns: 100px 1fr 200px 80px;
align-items: center;
gap: 40px;
padding: 36px 24px;
text-decoration: none;
color: var(--ink);
transition: padding 0.4s, background 0.4s;
position: relative;
}
.index-list a:hover {
background: rgba(185, 28, 28, 0.06);
padding-left: 48px;
}
.index-list a::before {
content: "";
position: absolute;
left: 0; top: 0; bottom: 0;
width: 0;
background: var(--accent);
transition: width 0.4s;
}
.index-list a:hover::before {
width: 3px;
}
.index-num { .index-num {
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 14px; font-size: 14px;
letter-spacing: 0.2em; letter-spacing: 0.2em;
color: var(--accent); color: var(--accent);
} }
.index-title { .index-title {
font-family: var(--font-display); @include m.display-italic(clamp(28px, 3vw, 42px));
font-size: clamp(28px, 3vw, 42px);
font-style: italic;
font-weight: 400; font-weight: 400;
line-height: 1.1; line-height: 1.1;
color: var(--paper); color: var(--paper);
} }
.index-list a:hover .index-title {
color: var(--accent-bright);
}
.index-meta { .index-meta {
font-family: var(--font-mono); @include m.mono-label(11px, 0.2em);
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
} }
.index-arrow { .index-arrow {
text-align: right; text-align: right;
font-family: var(--font-mono); font-family: var(--font-mono);
...@@ -260,12 +266,8 @@ ...@@ -260,12 +266,8 @@
color: var(--ink-faint); color: var(--ink-faint);
transition: color 0.3s, transform 0.3s; transition: color 0.3s, transform 0.3s;
} }
.index-list a:hover .index-arrow {
color: var(--accent-bright);
transform: translateX(8px);
}
/* ===== Footer ===== */ // ===== Footer =====
.cover-footer { .cover-footer {
padding: 80px 80px 60px; padding: 80px 80px 60px;
border-top: 1px solid var(--rule); border-top: 1px solid var(--rule);
...@@ -273,45 +275,48 @@ ...@@ -273,45 +275,48 @@
grid-template-columns: 1fr auto 1fr; grid-template-columns: 1fr auto 1fr;
gap: 40px; gap: 40px;
align-items: center; align-items: center;
font-family: var(--font-mono); @include m.mono-label(10px, 0.25em);
font-size: 10px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--ink-faint); color: var(--ink-faint);
.center { color: var(--accent); text-align: center; }
.right { text-align: right; }
} }
.cover-footer .center {
color: var(--accent);
text-align: center;
}
.cover-footer .right { text-align: right; }
/* Floating numerals in cover bg */ // Floating numerals in cover bg
.cover-numerals { .cover-numerals {
position: absolute; position: absolute;
inset: 0; inset: 0;
pointer-events: none; pointer-events: none;
z-index: 1; z-index: 1;
overflow: hidden; overflow: hidden;
span {
position: absolute;
font-family: var(--font-display);
font-style: italic;
font-weight: 300;
color: rgba(185, 28, 28, 0.05);
user-select: none;
&:nth-child(1) { font-size: 320px; top: 8%; left: -40px; }
&:nth-child(2) { font-size: 200px; top: 60%; right: 6%; color: rgba(232, 226, 214, 0.025); }
}
} }
.cover-numerals span {
position: absolute;
font-family: var(--font-display);
font-style: italic;
font-weight: 300;
color: rgba(185, 28, 28, 0.05);
user-select: none;
}
.cover-numerals span:nth-child(1) { font-size: 320px; top: 8%; left: -40px; }
.cover-numerals span:nth-child(2) { font-size: 200px; top: 60%; right: 6%; color: rgba(232, 226, 214, 0.025); }
@media (max-width: 900px) { // ===== Responsive =====
@include m.bp(m.$bp-tablet) {
.cover-content { padding: 120px 32px 40px; } .cover-content { padding: 120px 32px 40px; }
.cover-bottom { grid-template-columns: 1fr; gap: 32px; } .cover-bottom { grid-template-columns: 1fr; gap: 32px; }
.cover-warning, .cover-footer .right { text-align: left; } .cover-warning { text-align: left; }
.index-section { padding: 100px 32px; } .index-section { padding: 100px 32px; }
.index-list a { grid-template-columns: 60px 1fr 60px; gap: 20px; } .index-list a { grid-template-columns: 60px 1fr 60px; gap: 20px; }
.index-meta { display: none; } .index-meta { display: none; }
.index-header { grid-template-columns: 1fr; gap: 24px; margin-bottom: 60px; } .index-header { grid-template-columns: 1fr; gap: 24px; margin-bottom: 60px; }
.cover-footer { grid-template-columns: 1fr; }
.cover-footer .center, .cover-footer .right { text-align: left; } .cover-footer {
grid-template-columns: 1fr;
.center, .right { text-align: left; }
}
} }
...@@ -36,22 +36,16 @@ ...@@ -36,22 +36,16 @@
const onScroll = () => { const onScroll = () => {
bgs.forEach(bg => { bgs.forEach(bg => {
const speed = parseFloat(bg.dataset.parallax) || 0.4; const speed = parseFloat(bg.dataset.parallax) || 0.4;
const section = bg.closest('.pinned-section'); const section = bg.closest('.pinned-text-section');
if (section) { if (section) {
// Inside sticky container: getBoundingClientRect on the bg itself is always
// ~0 because the sticky parent pins it. Track the outer section's scroll
// progress instead. The bg has inset:-15% 0 so it extends beyond the stage;
// overflow:hidden clips the edges, giving the image room to travel.
const r = section.getBoundingClientRect(); const r = section.getBoundingClientRect();
const scrollable = section.offsetHeight - window.innerHeight; const scrollable = section.offsetHeight - window.innerHeight;
if (scrollable <= 0) return; if (scrollable <= 0) return;
const progress = Math.max(0, Math.min(1, -r.top / scrollable)); const progress = Math.max(0, Math.min(1, -r.top / scrollable));
const shift = (progress - 0.5) * speed * 400; bg.style.backgroundPosition = `center ${(progress * 100).toFixed(2)}%`;
bg.style.transform = `translate3d(0, ${shift}px, 0)`;
} else { } else {
const r = bg.getBoundingClientRect(); const r = bg.getBoundingClientRect();
const offset = -r.top * speed; bg.style.transform = `translate3d(0, ${-r.top * speed}px, 0)`;
bg.style.transform = `translate3d(0, ${offset}px, 0)`;
} }
}); });
}; };
...@@ -130,27 +124,6 @@ ...@@ -130,27 +124,6 @@
}); });
} }
// ----- Tweaks integration -----
function initTweaksListener() {
window.addEventListener('message', (e) => {
const d = e.data;
if (!d || typeof d !== 'object') return;
if (d.type === '__re_tweaks_apply') applyTweaks(d.tweaks);
});
try {
const saved = localStorage.getItem('re_tweaks');
if (saved) applyTweaks(JSON.parse(saved));
} catch(e) {}
}
function applyTweaks(t) {
if (!t) return;
const root = document.documentElement;
if (t.grain != null) root.style.setProperty('--grain-opacity', t.grain);
if (t.effects != null) root.dataset.effects = t.effects ? 'on' : 'off';
if (t.mode) root.dataset.mode = t.mode;
}
// ----- Init ----- // ----- Init -----
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
bindReveals(); bindReveals();
...@@ -159,6 +132,5 @@ ...@@ -159,6 +132,5 @@
initTypewriter(); initTypewriter();
initMenu(); initMenu();
initMenuFilter(); initMenuFilter();
initTweaksListener();
}); });
})(); })();
:root{--bg: #0a0707;--bg-2: #120c0c;--paper: #e8e2d6;--ink: #d8d2c4;--ink-dim: #8a847a;--ink-faint: #4a4540;--accent: #b91c1c;--accent-bright: #ef2b2b;--accent-deep: #5a0e0e;--rule: #1f1616;--vignette: rgba(0,0,0,0.85);--font-display: "Cormorant Garamond", "EB Garamond", Georgia, serif;--font-body: "EB Garamond", Georgia, "Times New Roman", serif;--font-mono: "JetBrains Mono", ui-monospace, "Courier New", monospace;--font-sans: "Inter Tight", system-ui, sans-serif}:root[data-mode=dim]{--bg: #1a1414;--bg-2: #221919;--ink: #e8e2d6;--ink-dim: #a8a298;--ink-faint: #5a5550;--rule: #2f2222;--vignette: rgba(0,0,0,0.55)}*{box-sizing:border-box;margin:0;padding:0}html,body{background:var(--bg);color:var(--ink);font-family:var(--font-body);font-size:19px;line-height:1.7;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:clip}body{min-height:100vh;position:relative}.grain{position:fixed;inset:0;pointer-events:none;z-index:9000;opacity:var(--grain-opacity, 0.18);mix-blend-mode:overlay;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>")}.vignette{position:fixed;inset:0;pointer-events:none;z-index:8500;background:radial-gradient(ellipse at center, transparent 40%, var(--vignette) 100%);animation:vignette-pulse 9s ease-in-out infinite}@keyframes vignette-pulse{0%,100%{opacity:.85}50%{opacity:1}}.flicker{position:fixed;inset:0;pointer-events:none;z-index:8000;background:rgba(255,240,230,.02);animation:flicker 7s steps(2, end) infinite}@keyframes flicker{0%,92%,100%{opacity:0}93%{opacity:1}94%{opacity:.2}95%{opacity:.9}96%{opacity:0}}[data-effects=off] .grain,[data-effects=off] .vignette,[data-effects=off] .flicker{display:none}.topbar{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;align-items:center;justify-content:space-between;padding:28px 40px;pointer-events:none}.topbar>*{pointer-events:auto}.wordmark{font-family:var(--font-display);font-weight:500;font-size:17px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink);text-decoration:none;display:flex;align-items:center;gap:12px}.wordmark::before{content:"";width:8px;height:8px;background:var(--accent);border-radius:50%;box-shadow:0 0 12px var(--accent)}.menu-btn{background:rgba(0,0,0,0);border:none;color:var(--ink);cursor:pointer;display:flex;flex-direction:column;gap:6px;padding:10px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;align-items:flex-end}.menu-btn:hover{color:var(--accent-bright)}.menu-btn-lines{display:flex;flex-direction:column;gap:4px;align-items:flex-end}.menu-btn-lines span{display:block;height:1px;background:currentColor}.menu-btn-lines span:nth-child(1){width:28px}.menu-btn-lines span:nth-child(2){width:20px}.menu-btn-lines span:nth-child(3){width:28px}.menu-overlay{position:fixed;inset:0;background:var(--bg);z-index:1500;opacity:0;pointer-events:none;transition:opacity .5s ease}.menu-overlay.open{opacity:1;pointer-events:auto}.menu-overlay::before{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");opacity:.15;mix-blend-mode:overlay;pointer-events:none}.menu-close{position:absolute;top:28px;right:40px;background:rgba(0,0,0,0);border:none;color:var(--ink);font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;cursor:pointer;padding:10px;z-index:10}.menu-close:hover{color:var(--accent-bright)}.menu-inner{position:absolute;inset:0;display:grid;grid-template-columns:1fr 360px;grid-template-rows:auto 1fr;grid-template-areas:"head head" "list side";padding:90px 64px 48px;gap:0 64px;max-height:100vh}.menu-head{grid-area:head;display:flex;align-items:center;gap:32px;padding-bottom:24px;margin-bottom:24px;border-bottom:1px solid var(--rule);flex-wrap:wrap}.menu-filter{flex:1;min-width:220px;background:rgba(0,0,0,0);border:1px solid var(--rule);color:var(--ink);padding:12px 16px;font-family:var(--font-mono);font-size:12px;letter-spacing:.1em;outline:none;transition:border-color .2s}.menu-filter:focus{border-color:var(--accent)}.menu-filter::-moz-placeholder{color:var(--ink-faint);text-transform:uppercase;letter-spacing:.15em;font-size:11px}.menu-filter::placeholder{color:var(--ink-faint);text-transform:uppercase;letter-spacing:.15em;font-size:11px}.menu-section-label{font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--accent);display:flex;align-items:center;gap:12px;white-space:nowrap}.menu-section-label::after{content:"";width:80px;height:1px;background:var(--accent-deep)}.menu-list{grid-area:list;overflow-y:auto;padding-right:24px;scrollbar-width:thin;scrollbar-color:var(--accent-deep) rgba(0,0,0,0)}.menu-list::-webkit-scrollbar{width:6px}.menu-list::-webkit-scrollbar-thumb{background:var(--accent-deep)}.menu-list::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.menu-part{margin-bottom:40px}.menu-part-head{position:-webkit-sticky;position:sticky;top:0;background:linear-gradient(to bottom, var(--bg) 70%, transparent);padding:8px 0 14px;display:flex;align-items:baseline;gap:16px;border-bottom:1px solid var(--rule);margin-bottom:8px;z-index:2}.menu-part-label{font-family:var(--font-mono);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent)}.menu-part-sub{font-family:var(--font-display);font-style:italic;font-size:18px;color:var(--ink-dim);letter-spacing:0}.menu-chapters{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:0 32px}.menu-chapters li{border-bottom:1px solid var(--rule);transition:opacity .2s}.menu-chapters li.hidden{display:none}.menu-chapters a{display:grid;grid-template-columns:36px 1fr;gap:20px;align-items:baseline;padding:14px 0 14px 14px;text-decoration:none;color:var(--ink);font-family:var(--font-display);font-size:22px;font-weight:400;font-style:italic;transition:color .25s,padding .25s,background .25s;position:relative;text-wrap:balance}.menu-chapters a:hover{color:var(--accent-bright);padding-left:22px;background:rgba(185,28,28,.04)}.menu-chapters a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:0;background:var(--accent);transition:width .25s}.menu-chapters a:hover::before{width:2px}.menu-chapters .num{font-family:var(--font-mono);font-style:normal;font-size:11px;letter-spacing:.2em;color:var(--ink-faint);align-self:center}.menu-chapters .title{line-height:1.2}.menu-chapters .current a{color:var(--accent-bright)}.menu-chapters .current .num{color:var(--accent-bright)}.menu-chapters .current a::before{width:2px;background:var(--accent-bright)}.menu-chapters .current::after{content:"READING";position:absolute;right:0;top:50%;transform:translateY(-50%);font-family:var(--font-mono);font-size:9px;letter-spacing:.25em;color:var(--accent);padding:4px 8px;border:1px solid var(--accent-deep)}.menu-chapters .current{position:relative}.menu-side{grid-area:side;align-self:stretch;border-left:1px solid var(--rule);padding-left:40px;display:flex;flex-direction:column;gap:24px}.menu-about{font-family:var(--font-display);font-size:19px;font-style:italic;color:var(--ink-dim);line-height:1.5}.menu-progress{margin-top:auto;padding-top:24px;border-top:1px solid var(--rule)}.menu-progress-bar{height:2px;background:var(--rule);margin-bottom:12px;position:relative}.menu-progress-bar span{position:absolute;left:0;top:0;bottom:0;background:var(--accent);box-shadow:0 0 8px var(--accent)}.menu-progress-meta{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim)}.menu-progress-meta .accent{color:var(--accent-bright)}.menu-empty{padding:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);text-align:center;display:none}.menu-list.is-empty .menu-empty{display:block}.menu-list.is-empty .menu-part{display:none}.chapter-footer{position:relative;padding:120px 40px 80px;border-top:1px solid var(--rule);display:grid;grid-template-columns:1fr 1fr;gap:40px;background:var(--bg)}.chapter-footer::before{content:"";position:absolute;top:-1px;left:50%;transform:translateX(-50%);width:12px;height:12px;background:var(--accent);border-radius:50%;box-shadow:0 0 0 4px var(--bg),0 0 20px var(--accent)}.nav-card{text-decoration:none;color:var(--ink);display:block;padding:28px;border:1px solid var(--rule);transition:border-color .3s,background .3s,transform .4s;position:relative;overflow:hidden;min-height:180px}.nav-card:hover{border-color:var(--accent);background:rgba(185,28,28,.05)}.nav-card.disabled{opacity:.3;pointer-events:none}.nav-card .label,.nav-card .num-big,.nav-card .title{display:block}.nav-card .label{font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:16px;display:flex;align-items:center;gap:10px}.nav-card.next{text-align:right}.nav-card .num-big{font-family:var(--font-display);font-size:14px;letter-spacing:.2em;color:var(--accent);margin-bottom:8px}.nav-card .title{font-family:var(--font-display);font-size:28px;font-style:italic;font-weight:400;line-height:1.2}.nav-card .arrow{position:absolute;bottom:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);transition:color .3s,transform .3s}.nav-card.prev .arrow{left:28px}.nav-card.next .arrow{right:28px}.nav-card:hover .arrow{color:var(--accent-bright)}.nav-card.prev:hover .arrow{transform:translateX(-6px)}.nav-card.next:hover .arrow{transform:translateX(6px)}.brush-divider{width:100%;height:24px;margin:80px 0;opacity:.7}.reveal{opacity:0;transform:translateY(30px);transition:opacity 1.2s ease,transform 1.2s ease}.reveal.in{opacity:1;transform:translateY(0)}[data-effects=off] .reveal{opacity:1;transform:none}.glitch{position:relative;display:inline-block;color:var(--ink)}.glitch::before,.glitch::after{content:attr(data-text);position:absolute;top:0;left:0;width:100%;pointer-events:none;opacity:.7}.glitch::before{color:var(--accent-bright);transform:translate(-1.5px, 0);mix-blend-mode:screen;animation:glitch-shift 4s infinite steps(2, end)}.glitch::after{color:#1ea7c4;transform:translate(1.5px, 0);mix-blend-mode:screen;animation:glitch-shift 4.3s infinite steps(2, end) reverse}@keyframes glitch-shift{0%,88%,100%{transform:translate(0, 0);opacity:0}90%{transform:translate(-2px, 0.5px);opacity:.8}92%{transform:translate(2px, -0.5px);opacity:.6}94%{transform:translate(-1px, 0);opacity:.4}}[data-effects=off] .glitch::before,[data-effects=off] .glitch::after{display:none}.progress{position:fixed;top:0;left:0;height:2px;background:var(--accent);z-index:200;width:0%;transition:width .1s linear;box-shadow:0 0 8px var(--accent)}.mono{font-family:var(--font-mono);letter-spacing:.15em;text-transform:uppercase;font-size:11px}.dim{color:var(--ink-dim)}.faint{color:var(--ink-faint)}::-moz-selection{background:var(--accent);color:var(--paper)}::selection{background:var(--accent);color:var(--paper)}@media(max-width: 1100px){.menu-inner{grid-template-columns:1fr;grid-template-rows:auto 1fr auto;grid-template-areas:"head" "list" "side";padding:80px 32px 24px;gap:16px}.menu-list{min-height:50vh;padding-right:8px}.menu-side{border-left:none;border-top:1px solid var(--rule);padding-left:0;padding-top:16px;gap:12px;flex-direction:row;align-items:center;justify-content:space-between;flex-wrap:wrap}.menu-side .menu-section-label{display:none}.menu-about{display:none}.menu-progress{margin-top:0;padding-top:0;border-top:none;flex:1;min-width:200px}.menu-chapters{grid-template-columns:1fr}}@media(max-width: 600px){.menu-close{top:18px;right:20px}.menu-inner{padding:70px 20px 24px}.menu-list{min-height:55vh}.menu-chapters a{font-size:19px;padding:12px 0 12px 10px}.menu-chapters .current::after{display:none}.menu-head{gap:16px}} :root{--bg: #0a0707;--bg-2: #120c0c;--paper: #e8e2d6;--ink: #d8d2c4;--ink-dim: #8a847a;--ink-faint: #4a4540;--accent: #b91c1c;--accent-bright: #ef2b2b;--accent-deep: #5a0e0e;--rule: #1f1616;--vignette: rgba(0, 0, 0, 0.85);--section-margin-bottom: 80px;--font-display: "Cormorant Garamond", "EB Garamond", Georgia, serif;--font-body: "EB Garamond", Georgia, "Times New Roman", serif;--font-mono: "JetBrains Mono", ui-monospace, "Courier New", monospace;--font-sans: "Inter Tight", system-ui, sans-serif}:root[data-mode=dim]{--bg: #1a1414;--bg-2: #221919;--ink: #e8e2d6;--ink-dim: #a8a298;--ink-faint: #5a5550;--rule: #2f2222;--vignette: rgba(0, 0, 0, 0.55)}*{box-sizing:border-box;margin:0;padding:0}html,body{background:var(--bg);color:var(--ink);font-family:var(--font-body);font-size:19px;line-height:1.7;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:clip}body{min-height:100vh;position:relative}.grain{position:fixed;inset:0;pointer-events:none;z-index:9000;opacity:var(--grain-opacity, 0.18);mix-blend-mode:overlay;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>")}.vignette{position:fixed;inset:0;pointer-events:none;z-index:8500;background:radial-gradient(ellipse at center, transparent 40%, var(--vignette) 100%);animation:vignette-pulse 9s ease-in-out infinite}@keyframes vignette-pulse{0%,100%{opacity:.85}50%{opacity:1}}.flicker{position:fixed;inset:0;pointer-events:none;z-index:8000;background:rgba(255,240,230,.02);animation:flicker 7s steps(2, end) infinite}@keyframes flicker{0%,92%,100%{opacity:0}93%{opacity:1}94%{opacity:.2}95%{opacity:.9}96%{opacity:0}}[data-effects=off] .grain,[data-effects=off] .vignette,[data-effects=off] .flicker{display:none}[data-effects=off] .reveal{opacity:1;transform:none}[data-effects=off] .glitch::before,[data-effects=off] .glitch::after{display:none}.topbar{position:fixed;top:0;left:0;right:0;z-index:100;display:flex;align-items:center;justify-content:space-between;padding:28px 40px;pointer-events:none}.topbar>*{pointer-events:auto}.wordmark{font-family:var(--font-display);font-weight:500;font-size:17px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink);text-decoration:none;display:flex;align-items:center;gap:12px}.wordmark::before{content:"";width:8px;height:8px;background:var(--accent);border-radius:50%;box-shadow:0 0 12px var(--accent)}.menu-btn{background:rgba(0,0,0,0);border:none;color:var(--ink);cursor:pointer;display:flex;flex-direction:column;gap:6px;padding:10px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;align-items:flex-end}.menu-btn:hover{color:var(--accent-bright)}.menu-btn-lines{display:flex;flex-direction:column;gap:4px;align-items:flex-end}.menu-btn-lines span{display:block;height:1px;background:currentColor}.menu-btn-lines span:nth-child(1){width:28px}.menu-btn-lines span:nth-child(2){width:20px}.menu-btn-lines span:nth-child(3){width:28px}.menu-overlay{position:fixed;inset:0;background:var(--bg);z-index:1500;opacity:0;pointer-events:none;transition:opacity .5s ease}.menu-overlay.open{opacity:1;pointer-events:auto}.menu-overlay::before{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");opacity:.15;mix-blend-mode:overlay;pointer-events:none}.menu-close{position:absolute;top:28px;right:40px;background:rgba(0,0,0,0);border:none;color:var(--ink);font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;cursor:pointer;padding:10px;z-index:10}.menu-close:hover{color:var(--accent-bright)}.menu-inner{position:absolute;inset:0;display:grid;grid-template-columns:1fr 360px;grid-template-rows:auto 1fr;grid-template-areas:"head head" "list side";padding:90px 64px 48px;gap:0 64px;max-height:100vh}.menu-head{grid-area:head;display:flex;align-items:center;gap:32px;padding-bottom:24px;margin-bottom:24px;border-bottom:1px solid var(--rule);flex-wrap:wrap}.menu-filter{flex:1;min-width:220px;background:rgba(0,0,0,0);border:1px solid var(--rule);color:var(--ink);padding:12px 16px;font-family:var(--font-mono);font-size:12px;letter-spacing:.1em;outline:none;transition:border-color .2s}.menu-filter:focus{border-color:var(--accent)}.menu-filter::-moz-placeholder{color:var(--ink-faint);text-transform:uppercase;letter-spacing:.15em;font-size:11px}.menu-filter::placeholder{color:var(--ink-faint);text-transform:uppercase;letter-spacing:.15em;font-size:11px}.menu-section-label{font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--accent);display:flex;align-items:center;gap:12px;white-space:nowrap}.menu-section-label::after{content:"";width:80px;height:1px;background:var(--accent-deep)}.menu-list{grid-area:list;overflow-y:auto;padding-right:24px;scrollbar-width:thin;scrollbar-color:var(--accent-deep) rgba(0,0,0,0)}.menu-list::-webkit-scrollbar{width:6px}.menu-list::-webkit-scrollbar-thumb{background:var(--accent-deep)}.menu-list::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.menu-list.is-empty .menu-empty{display:block}.menu-list.is-empty .menu-part{display:none}.menu-part{margin-bottom:40px}.menu-part-head{position:-webkit-sticky;position:sticky;top:0;background:linear-gradient(to bottom, var(--bg) 70%, transparent);padding:8px 0 14px;display:flex;align-items:baseline;gap:16px;border-bottom:1px solid var(--rule);margin-bottom:8px;z-index:2}.menu-part-label{font-family:var(--font-mono);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent)}.menu-part-sub{font-family:var(--font-display);font-size:18px;font-style:italic;font-weight:400;color:var(--ink-dim);letter-spacing:0}.menu-chapters{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:0 32px}.menu-chapters li{border-bottom:1px solid var(--rule);transition:opacity .2s}.menu-chapters li.hidden{display:none}.menu-chapters li.current{position:relative}.menu-chapters li.current a{color:var(--accent-bright)}.menu-chapters li.current .num{color:var(--accent-bright)}.menu-chapters li.current a::before{width:2px;background:var(--accent-bright)}.menu-chapters li.current::after{content:"READING";position:absolute;right:0;top:50%;transform:translateY(-50%);font-family:var(--font-mono);font-size:9px;letter-spacing:.25em;text-transform:uppercase;color:var(--accent);padding:4px 8px;border:1px solid var(--accent-deep)}.menu-chapters a{display:grid;grid-template-columns:36px 1fr;gap:20px;align-items:baseline;padding:14px 0 14px 14px;text-decoration:none;color:var(--ink);font-family:var(--font-display);font-size:22px;font-style:italic;font-weight:400;font-weight:400;transition:color .25s,padding .25s,background .25s;position:relative;text-wrap:balance}.menu-chapters a:hover{color:var(--accent-bright);padding-left:22px;background:rgba(185,28,28,.04)}.menu-chapters a:hover::before{width:2px}.menu-chapters a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:0;background:var(--accent);transition:width .25s}.menu-chapters .num{font-family:var(--font-mono);font-style:normal;font-size:11px;letter-spacing:.2em;color:var(--ink-faint);align-self:center}.menu-chapters .title{line-height:1.2}.menu-side{grid-area:side;align-self:stretch;border-left:1px solid var(--rule);padding-left:40px;display:flex;flex-direction:column;gap:24px}.menu-about{font-family:var(--font-display);font-size:19px;font-style:italic;font-weight:400;color:var(--ink-dim);line-height:1.5}.menu-progress{margin-top:auto;padding-top:24px;border-top:1px solid var(--rule)}.menu-progress-bar{height:2px;background:var(--rule);margin-bottom:12px;position:relative}.menu-progress-bar span{position:absolute;left:0;top:0;bottom:0;background:var(--accent);box-shadow:0 0 8px var(--accent)}.menu-progress-meta{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim)}.menu-progress-meta .accent{color:var(--accent-bright)}.menu-empty{padding:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);text-align:center;display:none}.chapter-footer{position:relative;padding:120px 40px 80px;border-top:1px solid var(--rule);display:grid;grid-template-columns:1fr 1fr;gap:40px;background:var(--bg)}.chapter-footer::before{content:"";position:absolute;top:-1px;left:50%;transform:translateX(-50%);width:12px;height:12px;background:var(--accent);border-radius:50%;box-shadow:0 0 0 4px var(--bg),0 0 20px var(--accent)}.nav-card{text-decoration:none;color:var(--ink);display:block;padding:28px;border:1px solid var(--rule);transition:border-color .3s,background .3s,transform .4s;position:relative;overflow:hidden;min-height:180px}.nav-card:hover{border-color:var(--accent);background:rgba(185,28,28,.05)}.nav-card:hover .arrow{color:var(--accent-bright)}.nav-card.disabled{opacity:.3;pointer-events:none}.nav-card.prev .arrow{left:28px}.nav-card.prev:hover .arrow{transform:translateX(-6px)}.nav-card.next{text-align:right}.nav-card.next .arrow{right:28px}.nav-card.next:hover .arrow{transform:translateX(6px)}.nav-card .label,.nav-card .num-big,.nav-card .title{display:block}.nav-card .label{font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:16px;display:flex;align-items:center;gap:10px}.nav-card .num-big{font-family:var(--font-display);font-size:14px;letter-spacing:.2em;color:var(--accent);margin-bottom:8px}.nav-card .title{font-family:var(--font-display);font-size:28px;font-style:italic;font-weight:400;line-height:1.2}.nav-card .arrow{position:absolute;bottom:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint);transition:color .3s,transform .3s}.brush-divider{width:100%;height:24px;margin:80px 0;opacity:.7}.reveal{opacity:0;transform:translateY(30px);transition:opacity 1.2s ease,transform 1.2s ease}.reveal.in{opacity:1;transform:translateY(0)}.glitch{position:relative;display:inline-block;color:var(--ink)}.glitch::before,.glitch::after{content:attr(data-text);position:absolute;top:0;left:0;width:100%;pointer-events:none;opacity:.7}.glitch::before{color:var(--accent-bright);transform:translate(-1.5px, 0);mix-blend-mode:screen;animation:glitch-shift 4s infinite steps(2, end)}.glitch::after{color:#1ea7c4;transform:translate(1.5px, 0);mix-blend-mode:screen;animation:glitch-shift 4.3s infinite steps(2, end) reverse}@keyframes glitch-shift{0%,88%,100%{transform:translate(0, 0);opacity:0}90%{transform:translate(-2px, 0.5px);opacity:.8}92%{transform:translate(2px, -0.5px);opacity:.6}94%{transform:translate(-1px, 0);opacity:.4}}.progress{position:fixed;top:0;left:0;height:2px;background:var(--accent);z-index:200;width:0%;transition:width .1s linear;box-shadow:0 0 8px var(--accent)}.mono{font-family:var(--font-mono);font-size:11px;letter-spacing:.15em;text-transform:uppercase}.dim{color:var(--ink-dim)}.faint{color:var(--ink-faint)}::-moz-selection{background:var(--accent);color:var(--paper)}::selection{background:var(--accent);color:var(--paper)}@media(max-width: 1100px){.menu-inner{grid-template-columns:1fr;grid-template-rows:auto 1fr auto;grid-template-areas:"head" "list" "side";padding:80px 32px 24px;gap:16px}.menu-list{min-height:50vh;padding-right:8px}.menu-side{border-left:none;border-top:1px solid var(--rule);padding-left:0;padding-top:16px;gap:12px;flex-direction:row;align-items:center;justify-content:space-between;flex-wrap:wrap}.menu-side .menu-section-label{display:none}.menu-about{display:none}.menu-progress{margin-top:0;padding-top:0;border-top:none;flex:1;min-width:200px}.menu-chapters{grid-template-columns:1fr}}@media(max-width: 600px){.menu-close{top:18px;right:20px}.menu-inner{padding:70px 20px 24px}.menu-list{min-height:55vh}.menu-chapters a{font-size:19px;padding:12px 0 12px 10px}.menu-chapters .current::after{display:none}.menu-head{gap:16px}}
/*# sourceMappingURL=shared.css.map */ /*# sourceMappingURL=shared.css.map */
\ No newline at end of file
{"version":3,"sources":["../../../src/css/shared.scss"],"names":[],"mappings":"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","file":"shared.css"} {"version":3,"sources":["../../../src/css/_vars.scss","../../../src/css/shared.scss","../../../src/css/_mixins.scss"],"names":[],"mappings":"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","file":"shared.css"}
\ No newline at end of file \ No newline at end of file
.chapter-page{position:relative}.chapter-hero{height:100vh;min-height:700px;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden}.chapter-hero-bg{position:absolute;inset:-10%;background:radial-gradient(ellipse at 30% 40%, rgba(90, 14, 14, 0.6) 0%, transparent 50%),radial-gradient(ellipse at 70% 60%, rgba(20, 8, 8, 0.8) 0%, transparent 60%),var(--bg);will-change:transform}.chapter-hero-grain{position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.02' numOctaves='3' seed='3'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");opacity:.4;mix-blend-mode:multiply}.chapter-hero-content{position:relative;z-index:2;text-align:center;max-width:800px;padding:0 40px}.chapter-numeral-frame{position:relative;width:280px;height:280px;margin:0 auto 48px;display:flex;align-items:center;justify-content:center}.chapter-numeral-frame svg.ring{position:absolute;inset:0;width:100%;height:100%;animation:slow-rotate 120s linear infinite}.chapter-numeral{font-family:var(--font-display);font-size:180px;font-weight:300;font-style:italic;color:var(--accent);line-height:1;letter-spacing:-0.02em;text-shadow:0 0 40px rgba(185,28,28,.4);position:relative;z-index:2}@keyframes slow-rotate{to{transform:rotate(360deg)}}.chapter-kicker{font-family:var(--font-mono);font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--ink-dim);margin-bottom:16px}.chapter-kicker .accent{color:var(--accent)}.chapter-title{font-family:var(--font-display);font-size:clamp(48px,7vw,96px);font-weight:400;font-style:italic;line-height:1.05;letter-spacing:-0.02em;color:var(--paper);margin-bottom:32px}.chapter-title .typed-cursor{display:inline-block;width:.5ch;background:var(--accent);animation:blink .8s steps(2, end) infinite;margin-left:4px;height:.9em;vertical-align:-0.1em}@keyframes blink{50%{opacity:0}}.chapter-meta{display:flex;align-items:center;justify-content:center;gap:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint)}.chapter-meta .dot{color:var(--accent)}.scroll-cue{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);font-family:var(--font-mono);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-faint);display:flex;flex-direction:column;align-items:center;gap:10px;animation:bob 2.5s ease-in-out infinite}.scroll-cue::after{content:"";width:1px;height:32px;background:linear-gradient(to bottom, var(--accent), transparent)}@keyframes bob{0%,100%{transform:translate(-50%, 0);opacity:.6}50%{transform:translate(-50%, 6px);opacity:1}}.chapter-body{margin:0 auto;position:relative}.chapter-body .column-container{margin:0 auto;padding:0 40px;max-width:680px}.chapter-body .column-container:first-of-type{padding-top:120px}.chapter-body .column-container:last-of-type{padding-top:60px}.chapter-body p{font-family:var(--font-body);font-size:21px;line-height:1.75;color:var(--ink);margin-bottom:1.6em;text-wrap:pretty}.prose.capitalise p:first-of-type::first-letter{font-family:var(--font-display);font-size:5.5em;font-style:italic;font-weight:400;float:left;line-height:.85;margin:.05em .12em 0 -0.05em;color:var(--accent)}.chapter-body .pull{font-family:var(--font-display);font-size:38px;font-style:italic;font-weight:400;line-height:1.25;color:var(--paper);margin:80px -40px;padding:0 40px;position:relative;text-wrap:balance}.chapter-body .pull::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--accent)}.chapter-body .key-line,.chapter-body em{font-style:italic;color:var(--accent-bright)}.pinned-section{height:250vh;position:relative}.pinned-stage{position:-webkit-sticky;position:sticky;top:0;height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--bg-2)}.pinned-bg{position:absolute;inset:-15% 0;background-size:cover;background-position:center;opacity:.5;filter:contrast(1.2) brightness(0.5)}.pinned-bg.t1{background:radial-gradient(circle at 20% 80%, rgba(185, 28, 28, 0.3), transparent 40%),radial-gradient(circle at 80% 20%, rgba(40, 12, 12, 0.8), transparent 50%),linear-gradient(180deg, #0a0707 0%, #1a0a0a 50%, #0a0707 100%)}.pinned-overlay{position:absolute;inset:0;background-image:repeating-linear-gradient(90deg, transparent 0, transparent 80px, rgba(232, 226, 214, 0.02) 80px, rgba(232, 226, 214, 0.02) 81px)}.pinned-text{position:relative;z-index:2;max-width:800px;padding:0 40px;text-align:center}.pinned-text h2{font-family:var(--font-display);font-size:clamp(40px,6vw,72px);font-style:italic;font-weight:400;line-height:1.1;color:var(--paper);margin-bottom:32px;text-wrap:balance}.pinned-text p{font-family:var(--font-display);font-size:22px;font-style:italic;color:var(--ink-dim);max-width:520px;margin:0 auto;line-height:1.5}.section-label{display:flex;align-items:center;gap:16px;max-width:680px;margin:0 auto 40px;padding:0 40px;font-family:var(--font-mono);font-size:11px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent)}.section-label::before{content:"";width:24px;height:1px;background:var(--accent)}.texture-slot{width:100%;height:60vh;margin:80px 0;position:relative;overflow:hidden}.texture-slot.t-rust{background:radial-gradient(ellipse at 30% 50%, rgba(120, 30, 20, 0.4), transparent 60%),radial-gradient(ellipse at 70% 30%, rgba(40, 10, 10, 0.6), transparent 50%),linear-gradient(135deg, #1a0a0a, #0a0707)}.texture-slot.t-concrete{background:radial-gradient(circle at 20% 80%, rgba(60, 40, 35, 0.3), transparent 50%),radial-gradient(circle at 80% 20%, rgba(20, 14, 14, 0.8), transparent 60%),#0d0908}.texture-slot::after{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.015' numOctaves='4'/><feColorMatrix values='0 0 0 0 0.3 0 0 0 0 0.1 0 0 0 0 0.05 0 0 0 0.7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");mix-blend-mode:multiply;opacity:.6}.texture-slot .texture-caption{position:absolute;bottom:20px;left:24px;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim);z-index:2}.note{margin:60px auto;padding:32px 40px;border-left:2px solid var(--accent-deep);background:rgba(185,28,28,.04)}.note,.note p{font-family:var(--font-mono);font-size:13px;line-height:1.7;color:var(--ink-dim);letter-spacing:.02em}.note .note-label{display:block;font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent);margin-bottom:12px} .chapter-page{position:relative}.chapter-hero{height:100vh;min-height:700px;display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden}.chapter-hero-bg{position:absolute;inset:-10%;background:radial-gradient(ellipse at 30% 40%, rgba(90, 14, 14, 0.6) 0%, transparent 50%),radial-gradient(ellipse at 70% 60%, rgba(20, 8, 8, 0.8) 0%, transparent 60%),var(--bg);will-change:transform}.chapter-hero-grain{position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.02' numOctaves='3' seed='3'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.5 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");opacity:.4;mix-blend-mode:multiply}.chapter-hero-content{position:relative;z-index:2;text-align:center;max-width:800px;padding:0 40px}.chapter-numeral-frame{position:relative;width:280px;height:280px;margin:0 auto 48px;display:flex;align-items:center;justify-content:center}.chapter-numeral-frame svg.ring{position:absolute;inset:0;width:100%;height:100%;animation:slow-rotate 120s linear infinite}.chapter-numeral{font-family:var(--font-display);font-size:180px;font-weight:300;font-style:italic;color:var(--accent);line-height:1;letter-spacing:-0.02em;text-shadow:0 0 40px rgba(185,28,28,.4);position:relative;z-index:2}@keyframes slow-rotate{to{transform:rotate(360deg)}}.chapter-kicker{font-family:var(--font-mono);font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--ink-dim);margin-bottom:16px}.chapter-kicker .accent{color:var(--accent)}.chapter-title{font-family:var(--font-display);font-size:clamp(48px,7vw,96px);font-style:italic;font-weight:400;font-weight:400;line-height:1.05;letter-spacing:-0.02em;color:var(--paper);margin-bottom:32px}.chapter-title .typed-cursor{display:inline-block;width:.5ch;background:var(--accent);animation:blink .8s steps(2, end) infinite;margin-left:4px;height:.9em;vertical-align:-0.1em}@keyframes blink{50%{opacity:0}}.chapter-meta{display:flex;align-items:center;justify-content:center;gap:24px;font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint)}.chapter-meta .dot{color:var(--accent)}.scroll-cue{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);font-family:var(--font-mono);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-faint);display:flex;flex-direction:column;align-items:center;gap:10px;animation:bob 2.5s ease-in-out infinite}.scroll-cue::after{content:"";width:1px;height:32px;background:linear-gradient(to bottom, var(--accent), transparent)}@keyframes bob{0%,100%{transform:translate(-50%, 0);opacity:.6}50%{transform:translate(-50%, 6px);opacity:1}}.chapter-body{margin:0 auto;position:relative}.chapter-body .column-container{margin:0 auto;padding:0 40px;max-width:680px}.chapter-body p{font-family:var(--font-body);font-size:21px;line-height:1.75;color:var(--ink);margin-bottom:1.6em;text-wrap:pretty;position:relative}.chapter-body .pull{font-family:var(--font-display);font-size:38px;font-style:italic;font-weight:400;font-weight:400;line-height:1.25;color:var(--paper);margin:80px -40px;padding:0 40px;position:relative;text-wrap:balance}.chapter-body .pull::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--accent)}.chapter-body .key-line,.chapter-body em{font-style:italic;color:var(--accent-bright)}.prose.capitalise{padding-top:120px}.prose.capitalise p:first-of-type::first-letter{font-family:var(--font-display);font-size:5.5em;font-style:italic;font-weight:400;font-weight:400;float:left;line-height:.85;margin:.05em .12em 0 -0.05em;color:var(--accent)}.pinned-text-section{height:250vh;position:relative;margin:var(--section-margin-bottom) 0}.pinned-text-stage{position:-webkit-sticky;position:sticky;top:0;height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--bg-2)}.pinned-text-bg{position:absolute;inset:0;background-size:cover;background-position:center;opacity:.5;filter:contrast(1.2) brightness(0.5)}.pinned-text-bg.t1{background:radial-gradient(circle at 20% 80%, rgba(185, 28, 28, 0.3), transparent 40%),radial-gradient(circle at 80% 20%, rgba(40, 12, 12, 0.8), transparent 50%),linear-gradient(180deg, #0a0707 0%, #1a0a0a 50%, #0a0707 100%)}.pinned-text-overlay{position:absolute;inset:0;background-image:repeating-linear-gradient(90deg, transparent 0, transparent 80px, rgba(232, 226, 214, 0.02) 80px, rgba(232, 226, 214, 0.02) 81px)}.pinned-text-copy{position:relative;z-index:2;max-width:800px;padding:0 40px;text-align:center}.pinned-text-copy h2{font-family:var(--font-display);font-size:clamp(40px,6vw,72px);font-style:italic;font-weight:400;font-weight:400;line-height:1.1;color:var(--paper);margin-bottom:32px;text-wrap:balance}.pinned-text-copy p{font-family:var(--font-display);font-size:22px;font-style:italic;font-weight:400;color:var(--ink-dim);max-width:520px;margin:0 auto;line-height:1.5}.pinned-image-section{position:relative;-webkit-clip-path:inset(0);clip-path:inset(0);margin:var(--section-margin-bottom) 0}.pinned-image-stage{position:-webkit-sticky;position:sticky;top:0;height:100vh;overflow:hidden;margin-bottom:-100vh}.pinned-image-bg{position:absolute;inset:0;background-size:cover;background-position:center;filter:brightness(0.5)}.pinned-image-overlay{position:absolute;inset:0;background:linear-gradient(to bottom, transparent 30%, rgba(10, 7, 7, 0.85) 100%)}.pinned-image-content{position:relative;z-index:1;padding:50vh 40px 50vh;max-width:680px;margin:0 auto}.pinned-image-content p{font-family:var(--font-body);font-size:21px;line-height:1.75;color:var(--ink);margin-bottom:1.6em;text-wrap:pretty}.section-label{display:flex;align-items:center;gap:16px;max-width:680px;margin:0 auto 40px;padding:0 40px;font-family:var(--font-mono);font-size:11px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent)}.section-label::before{content:"";width:24px;height:1px;background:var(--accent)}.texture-slot{width:100%;height:60vh;margin:var(--section-margin-bottom) 0;position:relative;overflow:hidden}.texture-slot.t-rust{background:radial-gradient(ellipse at 30% 50%, rgba(120, 30, 20, 0.4), transparent 60%),radial-gradient(ellipse at 70% 30%, rgba(40, 10, 10, 0.6), transparent 50%),linear-gradient(135deg, #1a0a0a, #0a0707)}.texture-slot.t-concrete{background:radial-gradient(circle at 20% 80%, rgba(60, 40, 35, 0.3), transparent 50%),radial-gradient(circle at 80% 20%, rgba(20, 14, 14, 0.8), transparent 60%),#0d0908}.texture-slot::after{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='n'><feTurbulence type='turbulence' baseFrequency='0.015' numOctaves='4'/><feColorMatrix values='0 0 0 0 0.3 0 0 0 0 0.1 0 0 0 0 0.05 0 0 0 0.7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");mix-blend-mode:multiply;opacity:.6}.texture-slot .texture-caption{position:absolute;bottom:20px;left:24px;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim);z-index:2}.note{margin:60px auto;padding:32px 40px;border-left:2px solid var(--accent-deep);background:rgba(185,28,28,.04)}.note,.note p{font-family:var(--font-mono);font-size:13px;line-height:1.7;color:var(--ink-dim);letter-spacing:.02em}.note .note-label{display:block;font-family:var(--font-mono);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent);margin-bottom:12px}
/*# sourceMappingURL=chapter.css.map */ /*# sourceMappingURL=chapter.css.map */
\ No newline at end of file
{"version":3,"sources":["../../../../src/css/templates/chapter.scss"],"names":[],"mappings":"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","file":"chapter.css"} {"version":3,"sources":["../../../../src/css/templates/chapter.scss","../../../../src/css/_mixins.scss"],"names":[],"mappings":"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","file":"chapter.css"}
\ No newline at end of file \ No newline at end of file
.cover-hero{min-height:100vh;position:relative;display:flex;flex-direction:column;overflow:hidden}.cover-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 30% 30%, rgba(90, 14, 14, 0.4) 0%, transparent 55%),radial-gradient(ellipse at 80% 70%, rgba(120, 20, 20, 0.25) 0%, transparent 50%),radial-gradient(ellipse at 50% 100%, rgb(20, 8, 8) 0%, transparent 60%),var(--bg)}.cover-bg::after{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='600'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='8'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");mix-blend-mode:multiply;opacity:.5}.cover-bg .brush{position:absolute;left:-5%;right:-5%;top:56%;height:220px;pointer-events:none;opacity:.55}.cover-content{position:relative;z-index:2;flex:1;display:grid;grid-template-rows:1fr auto;padding:140px 80px 60px}.cover-titleblock{align-self:center;max-width:1100px}.cover-eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--accent);margin-bottom:40px;display:flex;align-items:center;gap:16px}.cover-eyebrow::before{content:"";width:32px;height:1px;background:var(--accent)}.cover-title{font-family:var(--font-display);font-size:clamp(72px,11vw,168px);font-weight:300;line-height:.95;letter-spacing:-0.03em;color:var(--paper);margin-bottom:32px;text-wrap:balance}.cover-title em{font-style:italic;font-weight:400;color:var(--accent-bright);display:block}.cover-tagline{font-family:var(--font-display);font-size:clamp(20px,2vw,26px);font-style:italic;color:var(--ink-dim);max-width:540px;line-height:1.4;margin-bottom:48px}.cover-meta{display:flex;align-items:center;gap:32px;font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim)}.cover-meta .pip{color:var(--accent)}.cover-bottom{align-self:end;display:grid;grid-template-columns:auto 1fr auto;gap:60px;align-items:end;padding-top:60px;border-top:1px solid var(--rule)}.cover-cta{display:inline-flex;align-items:center;gap:16px;font-family:var(--font-mono);font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--paper);text-decoration:none;padding:18px 28px;border:1px solid var(--accent);background:rgba(185,28,28,.08);transition:background .3s,border-color .3s,transform .3s}.cover-cta:hover{background:rgba(185,28,28,.2);border-color:var(--accent-bright);transform:translateX(4px)}.cover-cta .arr{color:var(--accent)}.cover-warning{font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);line-height:1.8;max-width:280px;text-align:right}.cover-warning .label{color:var(--accent);display:block;margin-bottom:6px}.cover-stamp{font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);line-height:1.8}.index-section{position:relative;padding:160px 80px 120px;background:var(--bg-2);border-top:1px solid var(--rule)}.index-header{display:grid;grid-template-columns:1fr 1fr;gap:80px;margin-bottom:100px;max-width:1400px;margin-left:auto;margin-right:auto}.index-header h2{font-family:var(--font-display);font-size:clamp(56px,7vw,96px);font-style:italic;font-weight:300;line-height:1;color:var(--paper);letter-spacing:-0.02em}.index-header .text{font-family:var(--font-display);font-size:22px;font-style:italic;color:var(--ink-dim);line-height:1.5;max-width:36ch;align-self:end}.index-list{max-width:1400px;margin:0 auto;list-style:none}.index-list li{border-top:1px solid var(--rule)}.index-list li:last-child{border-bottom:1px solid var(--rule)}.index-list a{display:grid;grid-template-columns:100px 1fr 200px 80px;align-items:center;gap:40px;padding:36px 24px;text-decoration:none;color:var(--ink);transition:padding .4s,background .4s;position:relative}.index-list a:hover{background:rgba(185,28,28,.06);padding-left:48px}.index-list a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:0;background:var(--accent);transition:width .4s}.index-list a:hover::before{width:3px}.index-num{font-family:var(--font-mono);font-size:14px;letter-spacing:.2em;color:var(--accent)}.index-title{font-family:var(--font-display);font-size:clamp(28px,3vw,42px);font-style:italic;font-weight:400;line-height:1.1;color:var(--paper)}.index-list a:hover .index-title{color:var(--accent-bright)}.index-meta{font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}.index-arrow{text-align:right;font-family:var(--font-mono);font-size:12px;letter-spacing:.2em;color:var(--ink-faint);transition:color .3s,transform .3s}.index-list a:hover .index-arrow{color:var(--accent-bright);transform:translateX(8px)}.cover-footer{padding:80px 80px 60px;border-top:1px solid var(--rule);display:grid;grid-template-columns:1fr auto 1fr;gap:40px;align-items:center;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint)}.cover-footer .center{color:var(--accent);text-align:center}.cover-footer .right{text-align:right}.cover-numerals{position:absolute;inset:0;pointer-events:none;z-index:1;overflow:hidden}.cover-numerals span{position:absolute;font-family:var(--font-display);font-style:italic;font-weight:300;color:rgba(185,28,28,.05);-webkit-user-select:none;-moz-user-select:none;user-select:none}.cover-numerals span:nth-child(1){font-size:320px;top:8%;left:-40px}.cover-numerals span:nth-child(2){font-size:200px;top:60%;right:6%;color:rgba(232,226,214,.025)}@media(max-width: 900px){.cover-content{padding:120px 32px 40px}.cover-bottom{grid-template-columns:1fr;gap:32px}.cover-warning,.cover-footer .right{text-align:left}.index-section{padding:100px 32px}.index-list a{grid-template-columns:60px 1fr 60px;gap:20px}.index-meta{display:none}.index-header{grid-template-columns:1fr;gap:24px;margin-bottom:60px}.cover-footer{grid-template-columns:1fr}.cover-footer .center,.cover-footer .right{text-align:left}} .cover-hero{min-height:100vh;position:relative;display:flex;flex-direction:column;overflow:hidden}.cover-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 30% 30%, rgba(90, 14, 14, 0.4) 0%, transparent 55%),radial-gradient(ellipse at 80% 70%, rgba(120, 20, 20, 0.25) 0%, transparent 50%),radial-gradient(ellipse at 50% 100%, rgb(20, 8, 8) 0%, transparent 60%),var(--bg)}.cover-bg::after{content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='600'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='8'/><feColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.05 0 0 0 0 0.05 0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");mix-blend-mode:multiply;opacity:.5}.cover-bg .brush{position:absolute;left:-5%;right:-5%;top:56%;height:220px;pointer-events:none;opacity:.55}.cover-content{position:relative;z-index:2;flex:1;display:grid;grid-template-rows:1fr auto;padding:140px 80px 60px}.cover-titleblock{align-self:center;max-width:1100px}.cover-eyebrow{font-family:var(--font-mono);font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--accent);margin-bottom:40px;display:flex;align-items:center;gap:16px}.cover-eyebrow::before{content:"";width:32px;height:1px;background:var(--accent)}.cover-title{font-family:var(--font-display);font-size:clamp(72px,11vw,168px);font-weight:300;line-height:.95;letter-spacing:-0.03em;color:var(--paper);margin-bottom:32px;text-wrap:balance}.cover-title em{font-style:italic;font-weight:400;color:var(--accent-bright);display:block}.cover-tagline{font-family:var(--font-display);font-size:clamp(20px,2vw,26px);font-style:italic;font-weight:400;color:var(--ink-dim);max-width:540px;line-height:1.4;margin-bottom:48px}.cover-meta{display:flex;align-items:center;gap:32px;font-family:var(--font-mono);font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-dim)}.cover-meta .pip{color:var(--accent)}.cover-bottom{align-self:end;display:grid;grid-template-columns:auto 1fr auto;gap:60px;align-items:end;padding-top:60px;border-top:1px solid var(--rule)}.cover-cta{display:inline-flex;align-items:center;gap:16px;font-family:var(--font-mono);font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--paper);text-decoration:none;padding:18px 28px;border:1px solid var(--accent);background:rgba(185,28,28,.08);transition:background .3s,border-color .3s,transform .3s}.cover-cta:hover{background:rgba(185,28,28,.2);border-color:var(--accent-bright);transform:translateX(4px)}.cover-cta .arr{color:var(--accent)}.cover-warning{font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);line-height:1.8;max-width:280px;text-align:right}.cover-warning .label{color:var(--accent);display:block;margin-bottom:6px}.cover-stamp{font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint);line-height:1.8}.index-section{position:relative;padding:160px 80px 120px;background:var(--bg-2);border-top:1px solid var(--rule)}.index-header{display:grid;grid-template-columns:1fr 1fr;gap:80px;margin-bottom:100px;max-width:1400px;margin-left:auto;margin-right:auto}.index-header h2{font-family:var(--font-display);font-size:clamp(56px,7vw,96px);font-style:italic;font-weight:300;line-height:1;color:var(--paper);letter-spacing:-0.02em}.index-header .text{font-family:var(--font-display);font-size:22px;font-style:italic;font-weight:400;color:var(--ink-dim);line-height:1.5;max-width:36ch;align-self:end}.index-list{max-width:1400px;margin:0 auto;list-style:none}.index-list li{border-top:1px solid var(--rule)}.index-list li:last-child{border-bottom:1px solid var(--rule)}.index-list a{display:grid;grid-template-columns:100px 1fr 200px 80px;align-items:center;gap:40px;padding:36px 24px;text-decoration:none;color:var(--ink);transition:padding .4s,background .4s;position:relative}.index-list a:hover{background:rgba(185,28,28,.06);padding-left:48px}.index-list a:hover::before{width:3px}.index-list a:hover .index-title{color:var(--accent-bright)}.index-list a:hover .index-arrow{color:var(--accent-bright);transform:translateX(8px)}.index-list a::before{content:"";position:absolute;left:0;top:0;bottom:0;width:0;background:var(--accent);transition:width .4s}.index-num{font-family:var(--font-mono);font-size:14px;letter-spacing:.2em;color:var(--accent)}.index-title{font-family:var(--font-display);font-size:clamp(28px,3vw,42px);font-style:italic;font-weight:400;font-weight:400;line-height:1.1;color:var(--paper)}.index-meta{font-family:var(--font-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}.index-arrow{text-align:right;font-family:var(--font-mono);font-size:12px;letter-spacing:.2em;color:var(--ink-faint);transition:color .3s,transform .3s}.cover-footer{padding:80px 80px 60px;border-top:1px solid var(--rule);display:grid;grid-template-columns:1fr auto 1fr;gap:40px;align-items:center;font-family:var(--font-mono);font-size:10px;letter-spacing:.25em;text-transform:uppercase;color:var(--ink-faint)}.cover-footer .center{color:var(--accent);text-align:center}.cover-footer .right{text-align:right}.cover-numerals{position:absolute;inset:0;pointer-events:none;z-index:1;overflow:hidden}.cover-numerals span{position:absolute;font-family:var(--font-display);font-style:italic;font-weight:300;color:rgba(185,28,28,.05);-webkit-user-select:none;-moz-user-select:none;user-select:none}.cover-numerals span:nth-child(1){font-size:320px;top:8%;left:-40px}.cover-numerals span:nth-child(2){font-size:200px;top:60%;right:6%;color:rgba(232,226,214,.025)}@media(max-width: 900px){.cover-content{padding:120px 32px 40px}.cover-bottom{grid-template-columns:1fr;gap:32px}.cover-warning{text-align:left}.index-section{padding:100px 32px}.index-list a{grid-template-columns:60px 1fr 60px;gap:20px}.index-meta{display:none}.index-header{grid-template-columns:1fr;gap:24px;margin-bottom:60px}.cover-footer{grid-template-columns:1fr}.cover-footer .center,.cover-footer .right{text-align:left}}
/*# sourceMappingURL=home.css.map */ /*# sourceMappingURL=home.css.map */
\ No newline at end of file
{"version":3,"sources":["../../../../src/css/templates/home.scss"],"names":[],"mappings":"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","file":"home.css"} {"version":3,"sources":["../../../../src/css/templates/home.scss","../../../../src/css/_mixins.scss"],"names":[],"mappings":"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","file":"home.css"}
\ No newline at end of file \ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><title>Discord</title><path d="M6.552,6.712a.891.891,0,0,0,0,1.776A.852.852,0,0,0,7.368,7.6.847.847,0,0,0,6.552,6.712Zm2.92,0a.891.891,0,1,0,.816.888A.852.852,0,0,0,9.472,6.712Z"/><path d="M13.36,0H2.64A1.644,1.644,0,0,0,1,1.648V12.464a1.644,1.644,0,0,0,1.64,1.648h9.072l-.424-1.48,1.024.952.968.9L15,16V1.648A1.644,1.644,0,0,0,13.36,0ZM10.272,10.448S9.984,10.1,9.744,9.8a2.524,2.524,0,0,0,1.448-.952,4.578,4.578,0,0,1-.92.472,5.265,5.265,0,0,1-1.16.344A5.6,5.6,0,0,1,7.04,9.656a6.716,6.716,0,0,1-1.176-.344,4.683,4.683,0,0,1-.912-.472,2.488,2.488,0,0,0,1.4.944c-.24.3-.536.664-.536.664a2.9,2.9,0,0,1-2.44-1.216A10.713,10.713,0,0,1,4.528,4.568a3.956,3.956,0,0,1,2.248-.84l.08.1a5.4,5.4,0,0,0-2.1,1.048s.176-.1.472-.232a6.008,6.008,0,0,1,1.816-.5.788.788,0,0,1,.136-.016A6.769,6.769,0,0,1,8.792,4.1a6.521,6.521,0,0,1,2.408.768A5.324,5.324,0,0,0,9.208,3.856l.112-.128a3.956,3.956,0,0,1,2.248.84A10.713,10.713,0,0,1,12.72,9.232,2.924,2.924,0,0,1,10.272,10.448Z" /></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><title>Instagram</title><circle cx="12.145" cy="3.892" r="0.96"/><path d="M8,12c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S10.206,12,8,12z M8,6C6.897,6,6,6.897,6,8 s0.897,2,2,2s2-0.897,2-2S9.103,6,8,6z"/><path d="M12,16H4c-2.056,0-4-1.944-4-4V4c0-2.056,1.944-4,4-4h8c2.056,0,4,1.944,4,4v8C16,14.056,14.056,16,12,16z M4,2C3.065,2,2,3.065,2,4v8c0,0.953,1.047,2,2,2h8c0.935,0,2-1.065,2-2V4c0-0.935-1.065-2-2-2H4z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><title>Mastodon</title><path d="M14.943 3.935c-.215-1.591-1.612-2.845-3.268-3.088-.28-.041-1.338-.19-3.79-.19h-.019c-2.453 0-2.979.148-3.258.19-1.61.236-3.08 1.363-3.437 2.973-.172.793-.19 1.672-.158 2.478.045 1.157.054 2.311.16 3.463.073.765.2 1.524.382 2.27.339 1.38 1.711 2.53 3.056 2.998 1.44.488 2.988.57 4.472.234.163-.038.325-.081.484-.131.36-.114.783-.241 1.093-.465a.036.036 0 0 0 .015-.027v-1.116a.033.033 0 0 0-.041-.031c-.951.225-1.925.338-2.902.336-1.682 0-2.134-.792-2.264-1.122a3.463 3.463 0 0 1-.196-.884.032.032 0 0 1 .04-.033c.935.224 1.893.337 2.855.336.231 0 .461 0 .693-.006.967-.027 1.986-.076 2.938-.26l.067-.015c1.501-.286 2.93-1.184 3.075-3.458.005-.09.018-.938.018-1.03.001-.316.103-2.24-.015-3.422Zm-2.31 5.674h-1.578V5.772c0-.808-.339-1.22-1.028-1.22-.758 0-1.138.488-1.138 1.45v2.1H7.32v-2.1c0-.962-.38-1.45-1.138-1.45-.686 0-1.029.412-1.03 1.22v3.837H3.577V5.656c0-.808.208-1.45.623-1.926.429-.474.991-.718 1.689-.718.808 0 1.418.308 1.825.924l.393.655.393-.655c.407-.616 1.017-.924 1.823-.924.698 0 1.26.244 1.69.718.415.475.623 1.117.623 1.926l-.002 3.953Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><title>YouTube</title><path d="M15.8 4.8c-.2-1.3-.8-2.2-2.2-2.4C11.4 2 8 2 8 2s-3.4 0-5.6.4C1 2.6.3 3.5.2 4.8 0 6.1 0 8 0 8s0 1.9.2 3.2c.2 1.3.8 2.2 2.2 2.4C4.6 14 8 14 8 14s3.4 0 5.6-.4c1.4-.3 2-1.1 2.2-2.4C16 9.9 16 8 16 8s0-1.9-.2-3.2zM6 11V5l5 3-5 3z"/></svg>
!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";!function(){const e=new IntersectionObserver((t=>{t.forEach((t=>{t.isIntersecting&&(t.target.classList.add("in"),e.unobserve(t.target))}))}),{threshold:.15,rootMargin:"0px 0px -10% 0px"});function t(e){if(!e)return;const t=document.documentElement;null!=e.grain&&t.style.setProperty("--grain-opacity",e.grain),null!=e.effects&&(t.dataset.effects=e.effects?"on":"off"),e.mode&&(t.dataset.mode=e.mode)}document.addEventListener("DOMContentLoaded",(()=>{document.querySelectorAll(".reveal").forEach((t=>e.observe(t))),function(){const e=document.querySelector(".progress");if(!e)return;const t=()=>{const t=document.documentElement,n=t.scrollTop,o=t.scrollHeight-t.clientHeight;e.style.width=o>0?n/o*100+"%":"0%"};window.addEventListener("scroll",t,{passive:!0}),t()}(),function(){const e=document.querySelectorAll("[data-parallax]");if(!e.length)return;const t=()=>{e.forEach((e=>{const t=parseFloat(e.dataset.parallax)||.4,n=e.closest(".pinned-section");if(n){const o=n.getBoundingClientRect(),s=n.offsetHeight-window.innerHeight;if(s<=0)return;const c=(Math.max(0,Math.min(1,-o.top/s))-.5)*t*400;e.style.transform=`translate3d(0, ${c}px, 0)`}else{const n=-e.getBoundingClientRect().top*t;e.style.transform=`translate3d(0, ${n}px, 0)`}}))};window.addEventListener("scroll",t,{passive:!0}),t()}(),function(){const e=document.querySelector("[data-typewriter]");if(!e)return;const t=e.textContent.trim();e.innerHTML='<span class="typed"></span><span class="typed-cursor">&nbsp;</span>';const n=e.querySelector(".typed");let o=0;const s=()=>{o<=t.length?(n.textContent=t.slice(0,o),o++,setTimeout(s,55)):setTimeout((()=>{const t=e.querySelector(".typed-cursor");t&&(t.style.opacity="0")}),1500)};setTimeout(s,600)}(),function(){const e=document.querySelector(".menu-btn"),t=document.querySelector(".menu-overlay"),n=document.querySelector(".menu-close");if(!e||!t)return;const o=()=>{t.classList.remove("open"),document.body.style.overflow=""};e.addEventListener("click",(()=>{t.classList.add("open"),document.body.style.overflow="hidden"})),n&&n.addEventListener("click",o),document.addEventListener("keydown",(e=>{"Escape"===e.key&&o()})),t.addEventListener("click",(e=>{e.target===t&&o()}))}(),function(){const e=document.querySelector(".menu-filter"),t=document.querySelector(".menu-list");if(!e||!t)return;let n=t.querySelector(".menu-empty");n||(n=document.createElement("div"),n.className="menu-empty",n.textContent="No chapters match.",t.appendChild(n)),e.addEventListener("input",(()=>{const n=e.value.trim().toLowerCase();let o=!1;t.querySelectorAll(".menu-chapters li").forEach((e=>{const t=e.textContent.toLowerCase(),s=!n||t.includes(n);e.classList.toggle("hidden",!s),s&&(o=!0)})),t.querySelectorAll(".menu-part").forEach((e=>{const t=e.querySelectorAll(".menu-chapters li:not(.hidden)").length;e.style.display=t?"":"none"})),t.classList.toggle("is-empty",!o)}))}(),function(){window.addEventListener("message",(e=>{const n=e.data;n&&"object"==typeof n&&"__re_tweaks_apply"===n.type&&t(n.tweaks)}));try{const e=localStorage.getItem("re_tweaks");e&&t(JSON.parse(e))}catch(e){}}()}))}()})); !function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";!function(){const e=new IntersectionObserver((t=>{t.forEach((t=>{t.isIntersecting&&(t.target.classList.add("in"),e.unobserve(t.target))}))}),{threshold:.15,rootMargin:"0px 0px -10% 0px"});document.addEventListener("DOMContentLoaded",(()=>{document.querySelectorAll(".reveal").forEach((t=>e.observe(t))),function(){const e=document.querySelector(".progress");if(!e)return;const t=()=>{const t=document.documentElement,n=t.scrollTop,o=t.scrollHeight-t.clientHeight;e.style.width=o>0?n/o*100+"%":"0%"};window.addEventListener("scroll",t,{passive:!0}),t()}(),function(){const e=document.querySelectorAll("[data-parallax]");if(!e.length)return;const t=()=>{e.forEach((e=>{const t=parseFloat(e.dataset.parallax)||.4,n=e.closest(".pinned-text-section");if(n){const t=n.getBoundingClientRect(),o=n.offsetHeight-window.innerHeight;if(o<=0)return;const s=Math.max(0,Math.min(1,-t.top/o));e.style.backgroundPosition=`center ${(100*s).toFixed(2)}%`}else{const n=e.getBoundingClientRect();e.style.transform=`translate3d(0, ${-n.top*t}px, 0)`}}))};window.addEventListener("scroll",t,{passive:!0}),t()}(),function(){const e=document.querySelector("[data-typewriter]");if(!e)return;const t=e.textContent.trim();e.innerHTML='<span class="typed"></span><span class="typed-cursor">&nbsp;</span>';const n=e.querySelector(".typed");let o=0;const s=()=>{o<=t.length?(n.textContent=t.slice(0,o),o++,setTimeout(s,55)):setTimeout((()=>{const t=e.querySelector(".typed-cursor");t&&(t.style.opacity="0")}),1500)};setTimeout(s,600)}(),function(){const e=document.querySelector(".menu-btn"),t=document.querySelector(".menu-overlay"),n=document.querySelector(".menu-close");if(!e||!t)return;const o=()=>{t.classList.remove("open"),document.body.style.overflow=""};e.addEventListener("click",(()=>{t.classList.add("open"),document.body.style.overflow="hidden"})),n&&n.addEventListener("click",o),document.addEventListener("keydown",(e=>{"Escape"===e.key&&o()})),t.addEventListener("click",(e=>{e.target===t&&o()}))}(),function(){const e=document.querySelector(".menu-filter"),t=document.querySelector(".menu-list");if(!e||!t)return;let n=t.querySelector(".menu-empty");n||(n=document.createElement("div"),n.className="menu-empty",n.textContent="No chapters match.",t.appendChild(n)),e.addEventListener("input",(()=>{const n=e.value.trim().toLowerCase();let o=!1;t.querySelectorAll(".menu-chapters li").forEach((e=>{const t=e.textContent.toLowerCase(),s=!n||t.includes(n);e.classList.toggle("hidden",!s),s&&(o=!0)})),t.querySelectorAll(".menu-part").forEach((e=>{const t=e.querySelectorAll(".menu-chapters li:not(.hidden)").length;e.style.display=t?"":"none"})),t.classList.toggle("is-empty",!o)}))}()}))}()}));
//# sourceMappingURL=shared.js.map //# sourceMappingURL=shared.js.map
\ No newline at end of file
{"version":3,"names":["io","IntersectionObserver","entries","forEach","e","isIntersecting","target","classList","add","unobserve","threshold","rootMargin","applyTweaks","t","root","document","documentElement","grain","style","setProperty","effects","dataset","mode","addEventListener","querySelectorAll","el","observe","bar","querySelector","onScroll","h","scrolled","scrollTop","max","scrollHeight","clientHeight","width","window","passive","initProgress","bgs","length","bg","speed","parseFloat","parallax","section","closest","r","getBoundingClientRect","scrollable","offsetHeight","innerHeight","shift","Math","min","top","transform","offset","initParallax","text","textContent","trim","innerHTML","i","tick","slice","setTimeout","c","opacity","initTypewriter","btn","overlay","close","shut","remove","body","overflow","key","initMenu","input","list","empty","createElement","className","appendChild","q","value","toLowerCase","any","li","match","includes","toggle","p","visible","display","initMenuFilter","d","data","type","tweaks","saved","localStorage","getItem","JSON","parse","initTweaksListener"],"sources":["../../../src/js/shared.js"],"sourcesContent":["// Shared interactivity — The Friedrichshof Account\n\n(function() {\n // ----- Reveal on scroll ----- \n const io = new IntersectionObserver((entries) => {\n entries.forEach(e => {\n if (e.isIntersecting) {\n e.target.classList.add('in');\n io.unobserve(e.target);\n }\n });\n }, { threshold: 0.15, rootMargin: '0px 0px -10% 0px' });\n\n function bindReveals() {\n document.querySelectorAll('.reveal').forEach(el => io.observe(el));\n }\n\n // ----- Progress bar -----\n function initProgress() {\n const bar = document.querySelector('.progress');\n if (!bar) return;\n const onScroll = () => {\n const h = document.documentElement;\n const scrolled = h.scrollTop;\n const max = h.scrollHeight - h.clientHeight;\n bar.style.width = max > 0 ? (scrolled / max * 100) + '%' : '0%';\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll();\n }\n\n // ----- Parallax on hero bg -----\n function initParallax() {\n const bgs = document.querySelectorAll('[data-parallax]');\n if (!bgs.length) return;\n const onScroll = () => {\n bgs.forEach(bg => {\n const speed = parseFloat(bg.dataset.parallax) || 0.4;\n const section = bg.closest('.pinned-section');\n if (section) {\n // Inside sticky container: getBoundingClientRect on the bg itself is always\n // ~0 because the sticky parent pins it. Track the outer section's scroll\n // progress instead. The bg has inset:-15% 0 so it extends beyond the stage;\n // overflow:hidden clips the edges, giving the image room to travel.\n const r = section.getBoundingClientRect();\n const scrollable = section.offsetHeight - window.innerHeight;\n if (scrollable <= 0) return;\n const progress = Math.max(0, Math.min(1, -r.top / scrollable));\n const shift = (progress - 0.5) * speed * 400;\n bg.style.transform = `translate3d(0, ${shift}px, 0)`;\n } else {\n const r = bg.getBoundingClientRect();\n const offset = -r.top * speed;\n bg.style.transform = `translate3d(0, ${offset}px, 0)`;\n }\n });\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll();\n }\n\n // ----- Typewriter for chapter title -----\n function initTypewriter() {\n const el = document.querySelector('[data-typewriter]');\n if (!el) return;\n const text = el.textContent.trim();\n el.innerHTML = '<span class=\"typed\"></span><span class=\"typed-cursor\">&nbsp;</span>';\n const target = el.querySelector('.typed');\n let i = 0;\n const speed = 55;\n const tick = () => {\n if (i <= text.length) {\n target.textContent = text.slice(0, i);\n i++;\n setTimeout(tick, speed);\n } else {\n setTimeout(() => {\n const c = el.querySelector('.typed-cursor');\n if (c) c.style.opacity = '0';\n }, 1500);\n }\n };\n setTimeout(tick, 600);\n }\n\n // ----- Hamburger menu -----\n function initMenu() {\n const btn = document.querySelector('.menu-btn');\n const overlay = document.querySelector('.menu-overlay');\n const close = document.querySelector('.menu-close');\n if (!btn || !overlay) return;\n const open = () => { overlay.classList.add('open'); document.body.style.overflow = 'hidden'; };\n const shut = () => { overlay.classList.remove('open'); document.body.style.overflow = ''; };\n btn.addEventListener('click', open);\n if (close) close.addEventListener('click', shut);\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') shut();\n });\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) shut();\n });\n }\n\n // ----- Menu chapter filter -----\n function initMenuFilter() {\n const input = document.querySelector('.menu-filter');\n const list = document.querySelector('.menu-list');\n if (!input || !list) return;\n let empty = list.querySelector('.menu-empty');\n if (!empty) {\n empty = document.createElement('div');\n empty.className = 'menu-empty';\n empty.textContent = 'No chapters match.';\n list.appendChild(empty);\n }\n input.addEventListener('input', () => {\n const q = input.value.trim().toLowerCase();\n let any = false;\n list.querySelectorAll('.menu-chapters li').forEach(li => {\n const t = li.textContent.toLowerCase();\n const match = !q || t.includes(q);\n li.classList.toggle('hidden', !match);\n if (match) any = true;\n });\n list.querySelectorAll('.menu-part').forEach(p => {\n const visible = p.querySelectorAll('.menu-chapters li:not(.hidden)').length;\n p.style.display = visible ? '' : 'none';\n });\n list.classList.toggle('is-empty', !any);\n });\n }\n\n // ----- Tweaks integration -----\n function initTweaksListener() {\n window.addEventListener('message', (e) => {\n const d = e.data;\n if (!d || typeof d !== 'object') return;\n if (d.type === '__re_tweaks_apply') applyTweaks(d.tweaks);\n });\n try {\n const saved = localStorage.getItem('re_tweaks');\n if (saved) applyTweaks(JSON.parse(saved));\n } catch(e) {}\n }\n\n function applyTweaks(t) {\n if (!t) return;\n const root = document.documentElement;\n if (t.grain != null) root.style.setProperty('--grain-opacity', t.grain);\n if (t.effects != null) root.dataset.effects = t.effects ? 'on' : 'off';\n if (t.mode) root.dataset.mode = t.mode;\n }\n\n // ----- Init -----\n document.addEventListener('DOMContentLoaded', () => {\n bindReveals();\n initProgress();\n initParallax();\n initTypewriter();\n initMenu();\n initMenuFilter();\n initTweaksListener();\n });\n})();\n"],"mappings":"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","ignoreList":[]} {"version":3,"names":["io","IntersectionObserver","entries","forEach","e","isIntersecting","target","classList","add","unobserve","threshold","rootMargin","document","addEventListener","querySelectorAll","el","observe","bar","querySelector","onScroll","h","documentElement","scrolled","scrollTop","max","scrollHeight","clientHeight","style","width","window","passive","initProgress","bgs","length","bg","speed","parseFloat","dataset","parallax","section","closest","r","getBoundingClientRect","scrollable","offsetHeight","innerHeight","progress","Math","min","top","backgroundPosition","toFixed","transform","initParallax","text","textContent","trim","innerHTML","i","tick","slice","setTimeout","c","opacity","initTypewriter","btn","overlay","close","shut","remove","body","overflow","key","initMenu","input","list","empty","createElement","className","appendChild","q","value","toLowerCase","any","li","t","match","includes","toggle","p","visible","display","initMenuFilter"],"sources":["../../../src/js/shared.js"],"sourcesContent":["// Shared interactivity — The Friedrichshof Account\n\n(function() {\n // ----- Reveal on scroll ----- \n const io = new IntersectionObserver((entries) => {\n entries.forEach(e => {\n if (e.isIntersecting) {\n e.target.classList.add('in');\n io.unobserve(e.target);\n }\n });\n }, { threshold: 0.15, rootMargin: '0px 0px -10% 0px' });\n\n function bindReveals() {\n document.querySelectorAll('.reveal').forEach(el => io.observe(el));\n }\n\n // ----- Progress bar -----\n function initProgress() {\n const bar = document.querySelector('.progress');\n if (!bar) return;\n const onScroll = () => {\n const h = document.documentElement;\n const scrolled = h.scrollTop;\n const max = h.scrollHeight - h.clientHeight;\n bar.style.width = max > 0 ? (scrolled / max * 100) + '%' : '0%';\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll();\n }\n\n // ----- Parallax on hero bg -----\n function initParallax() {\n const bgs = document.querySelectorAll('[data-parallax]');\n if (!bgs.length) return;\n const onScroll = () => {\n bgs.forEach(bg => {\n const speed = parseFloat(bg.dataset.parallax) || 0.4;\n const section = bg.closest('.pinned-text-section');\n if (section) {\n const r = section.getBoundingClientRect();\n const scrollable = section.offsetHeight - window.innerHeight;\n if (scrollable <= 0) return;\n const progress = Math.max(0, Math.min(1, -r.top / scrollable));\n bg.style.backgroundPosition = `center ${(progress * 100).toFixed(2)}%`;\n } else {\n const r = bg.getBoundingClientRect();\n bg.style.transform = `translate3d(0, ${-r.top * speed}px, 0)`;\n }\n });\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll();\n }\n\n // ----- Typewriter for chapter title -----\n function initTypewriter() {\n const el = document.querySelector('[data-typewriter]');\n if (!el) return;\n const text = el.textContent.trim();\n el.innerHTML = '<span class=\"typed\"></span><span class=\"typed-cursor\">&nbsp;</span>';\n const target = el.querySelector('.typed');\n let i = 0;\n const speed = 55;\n const tick = () => {\n if (i <= text.length) {\n target.textContent = text.slice(0, i);\n i++;\n setTimeout(tick, speed);\n } else {\n setTimeout(() => {\n const c = el.querySelector('.typed-cursor');\n if (c) c.style.opacity = '0';\n }, 1500);\n }\n };\n setTimeout(tick, 600);\n }\n\n // ----- Hamburger menu -----\n function initMenu() {\n const btn = document.querySelector('.menu-btn');\n const overlay = document.querySelector('.menu-overlay');\n const close = document.querySelector('.menu-close');\n if (!btn || !overlay) return;\n const open = () => { overlay.classList.add('open'); document.body.style.overflow = 'hidden'; };\n const shut = () => { overlay.classList.remove('open'); document.body.style.overflow = ''; };\n btn.addEventListener('click', open);\n if (close) close.addEventListener('click', shut);\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') shut();\n });\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) shut();\n });\n }\n\n // ----- Menu chapter filter -----\n function initMenuFilter() {\n const input = document.querySelector('.menu-filter');\n const list = document.querySelector('.menu-list');\n if (!input || !list) return;\n let empty = list.querySelector('.menu-empty');\n if (!empty) {\n empty = document.createElement('div');\n empty.className = 'menu-empty';\n empty.textContent = 'No chapters match.';\n list.appendChild(empty);\n }\n input.addEventListener('input', () => {\n const q = input.value.trim().toLowerCase();\n let any = false;\n list.querySelectorAll('.menu-chapters li').forEach(li => {\n const t = li.textContent.toLowerCase();\n const match = !q || t.includes(q);\n li.classList.toggle('hidden', !match);\n if (match) any = true;\n });\n list.querySelectorAll('.menu-part').forEach(p => {\n const visible = p.querySelectorAll('.menu-chapters li:not(.hidden)').length;\n p.style.display = visible ? '' : 'none';\n });\n list.classList.toggle('is-empty', !any);\n });\n }\n\n // ----- Init -----\n document.addEventListener('DOMContentLoaded', () => {\n bindReveals();\n initProgress();\n initParallax();\n initTypewriter();\n initMenu();\n initMenuFilter();\n });\n})();\n"],"mappings":"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","ignoreList":[]}
\ No newline at end of file \ No newline at end of file
// Tweaks app — adds an in-page panel for grain/effects/mode controls.
// Loaded on every page after React + the tweaks-panel starter.
const RE_DEFAULTS = /*EDITMODE-BEGIN*/{
"grain": 0.18,
"effects": true,
"mode": "dark"
}/*EDITMODE-END*/;
function applyAll(t) {
const root = document.documentElement;
if (t.grain != null) root.style.setProperty('--grain-opacity', t.grain);
root.dataset.effects = t.effects ? 'on' : 'off';
root.dataset.mode = t.mode || 'dark';
try { localStorage.setItem('re_tweaks', JSON.stringify(t)); } catch(e) {}
}
// Apply persisted tweaks immediately so the page doesn't flash defaults
try {
const saved = JSON.parse(localStorage.getItem('re_tweaks') || 'null');
if (saved) applyAll({ ...RE_DEFAULTS, ...saved });
else applyAll(RE_DEFAULTS);
} catch(e) { applyAll(RE_DEFAULTS); }
function ReTweaks() {
const [tweaks, setTweak] = useTweaks(RE_DEFAULTS);
React.useEffect(() => { applyAll(tweaks); }, [tweaks]);
return (
<TweaksPanel title="Tweaks">
<TweakSection title="Atmosphere">
<TweakSlider
label="Brush / grain density"
value={tweaks.grain}
min={0} max={0.45} step={0.01}
onChange={(v) => setTweak('grain', v)}
/>
<TweakToggle
label="Scroll & ambient effects"
value={tweaks.effects}
onChange={(v) => setTweak('effects', v)}
/>
</TweakSection>
<TweakSection title="Mode">
<TweakRadio
label="Tone"
value={tweaks.mode}
options={[
{ value: 'dark', label: 'Dark' },
{ value: 'dim', label: 'Dim' },
]}
onChange={(v) => setTweak('mode', v)}
/>
</TweakSection>
</TweaksPanel>
);
}
const reTweaksRoot = document.createElement('div');
reTweaksRoot.id = 're-tweaks-root';
document.body.appendChild(reTweaksRoot);
ReactDOM.createRoot(reTweaksRoot).render(<ReTweaks />);
// tweaks-panel.jsx
// Reusable Tweaks shell + form-control helpers.
//
// Owns the host protocol (listens for __activate_edit_mode / __deactivate_edit_mode,
// posts __edit_mode_available / __edit_mode_set_keys / __edit_mode_dismissed) so
// individual prototypes don't re-roll it. Ships a consistent set of controls so you
// don't hand-draw <input type="range">, segmented radios, steppers, etc.
//
// Usage (in an HTML file that loads React + Babel):
//
// const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
// "primaryColor": "#D97757",
// "fontSize": 16,
// "density": "regular",
// "dark": false
// }/*EDITMODE-END*/;
//
// function App() {
// const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
// return (
// <div style={{ fontSize: t.fontSize, color: t.primaryColor }}>
// Hello
// <TweaksPanel>
// <TweakSection label="Typography" />
// <TweakSlider label="Font size" value={t.fontSize} min={10} max={32} unit="px"
// onChange={(v) => setTweak('fontSize', v)} />
// <TweakRadio label="Density" value={t.density}
// options={['compact', 'regular', 'comfy']}
// onChange={(v) => setTweak('density', v)} />
// <TweakSection label="Theme" />
// <TweakColor label="Primary" value={t.primaryColor}
// onChange={(v) => setTweak('primaryColor', v)} />
// <TweakToggle label="Dark mode" value={t.dark}
// onChange={(v) => setTweak('dark', v)} />
// </TweaksPanel>
// </div>
// );
// }
//
// ─────────────────────────────────────────────────────────────────────────────
const __TWEAKS_STYLE = `
.twk-panel{position:fixed;right:16px;bottom:16px;z-index:2147483646;width:280px;
max-height:calc(100vh - 32px);display:flex;flex-direction:column;
transform:scale(var(--dc-inv-zoom,1));transform-origin:bottom right;
background:rgba(250,249,247,.78);color:#29261b;
-webkit-backdrop-filter:blur(24px) saturate(160%);backdrop-filter:blur(24px) saturate(160%);
border:.5px solid rgba(255,255,255,.6);border-radius:14px;
box-shadow:0 1px 0 rgba(255,255,255,.5) inset,0 12px 40px rgba(0,0,0,.18);
font:11.5px/1.4 ui-sans-serif,system-ui,-apple-system,sans-serif;overflow:hidden}
.twk-hd{display:flex;align-items:center;justify-content:space-between;
padding:10px 8px 10px 14px;cursor:move;user-select:none}
.twk-hd b{font-size:12px;font-weight:600;letter-spacing:.01em}
.twk-x{appearance:none;border:0;background:transparent;color:rgba(41,38,27,.55);
width:22px;height:22px;border-radius:6px;cursor:default;font-size:13px;line-height:1}
.twk-x:hover{background:rgba(0,0,0,.06);color:#29261b}
.twk-body{padding:2px 14px 14px;display:flex;flex-direction:column;gap:10px;
overflow-y:auto;overflow-x:hidden;min-height:0;
scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) transparent}
.twk-body::-webkit-scrollbar{width:8px}
.twk-body::-webkit-scrollbar-track{background:transparent;margin:2px}
.twk-body::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:4px;
border:2px solid transparent;background-clip:content-box}
.twk-body::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25);
border:2px solid transparent;background-clip:content-box}
.twk-row{display:flex;flex-direction:column;gap:5px}
.twk-row-h{flex-direction:row;align-items:center;justify-content:space-between;gap:10px}
.twk-lbl{display:flex;justify-content:space-between;align-items:baseline;
color:rgba(41,38,27,.72)}
.twk-lbl>span:first-child{font-weight:500}
.twk-val{color:rgba(41,38,27,.5);font-variant-numeric:tabular-nums}
.twk-sect{font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
color:rgba(41,38,27,.45);padding:10px 0 0}
.twk-sect:first-child{padding-top:0}
.twk-field{appearance:none;width:100%;height:26px;padding:0 8px;
border:.5px solid rgba(0,0,0,.1);border-radius:7px;
background:rgba(255,255,255,.6);color:inherit;font:inherit;outline:none}
.twk-field:focus{border-color:rgba(0,0,0,.25);background:rgba(255,255,255,.85)}
select.twk-field{padding-right:22px;
background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='rgba(0,0,0,.5)' d='M0 0h10L5 6z'/></svg>");
background-repeat:no-repeat;background-position:right 8px center}
.twk-slider{appearance:none;-webkit-appearance:none;width:100%;height:4px;margin:6px 0;
border-radius:999px;background:rgba(0,0,0,.12);outline:none}
.twk-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
width:14px;height:14px;border-radius:50%;background:#fff;
border:.5px solid rgba(0,0,0,.12);box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:default}
.twk-slider::-moz-range-thumb{width:14px;height:14px;border-radius:50%;
background:#fff;border:.5px solid rgba(0,0,0,.12);box-shadow:0 1px 3px rgba(0,0,0,.2);cursor:default}
.twk-seg{position:relative;display:flex;padding:2px;border-radius:8px;
background:rgba(0,0,0,.06);user-select:none}
.twk-seg-thumb{position:absolute;top:2px;bottom:2px;border-radius:6px;
background:rgba(255,255,255,.9);box-shadow:0 1px 2px rgba(0,0,0,.12);
transition:left .15s cubic-bezier(.3,.7,.4,1),width .15s}
.twk-seg.dragging .twk-seg-thumb{transition:none}
.twk-seg button{appearance:none;position:relative;z-index:1;flex:1;border:0;
background:transparent;color:inherit;font:inherit;font-weight:500;min-height:22px;
border-radius:6px;cursor:default;padding:4px 6px;line-height:1.2;
overflow-wrap:anywhere}
.twk-toggle{position:relative;width:32px;height:18px;border:0;border-radius:999px;
background:rgba(0,0,0,.15);transition:background .15s;cursor:default;padding:0}
.twk-toggle[data-on="1"]{background:#34c759}
.twk-toggle i{position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;
background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .15s}
.twk-toggle[data-on="1"] i{transform:translateX(14px)}
.twk-num{display:flex;align-items:center;height:26px;padding:0 0 0 8px;
border:.5px solid rgba(0,0,0,.1);border-radius:7px;background:rgba(255,255,255,.6)}
.twk-num-lbl{font-weight:500;color:rgba(41,38,27,.6);cursor:ew-resize;
user-select:none;padding-right:8px}
.twk-num input{flex:1;min-width:0;height:100%;border:0;background:transparent;
font:inherit;font-variant-numeric:tabular-nums;text-align:right;padding:0 8px 0 0;
outline:none;color:inherit;-moz-appearance:textfield}
.twk-num input::-webkit-inner-spin-button,.twk-num input::-webkit-outer-spin-button{
-webkit-appearance:none;margin:0}
.twk-num-unit{padding-right:8px;color:rgba(41,38,27,.45)}
.twk-btn{appearance:none;height:26px;padding:0 12px;border:0;border-radius:7px;
background:rgba(0,0,0,.78);color:#fff;font:inherit;font-weight:500;cursor:default}
.twk-btn:hover{background:rgba(0,0,0,.88)}
.twk-btn.secondary{background:rgba(0,0,0,.06);color:inherit}
.twk-btn.secondary:hover{background:rgba(0,0,0,.1)}
.twk-swatch{appearance:none;-webkit-appearance:none;width:56px;height:22px;
border:.5px solid rgba(0,0,0,.1);border-radius:6px;padding:0;cursor:default;
background:transparent;flex-shrink:0}
.twk-swatch::-webkit-color-swatch-wrapper{padding:0}
.twk-swatch::-webkit-color-swatch{border:0;border-radius:5.5px}
.twk-swatch::-moz-color-swatch{border:0;border-radius:5.5px}
`;
// ── useTweaks ───────────────────────────────────────────────────────────────
// Single source of truth for tweak values. setTweak persists via the host
// (__edit_mode_set_keys → host rewrites the EDITMODE block on disk).
function useTweaks(defaults) {
const [values, setValues] = React.useState(defaults);
// Accepts either setTweak('key', value) or setTweak({ key: value, ... }) so a
// useState-style call doesn't write a "[object Object]" key into the persisted
// JSON block.
const setTweak = React.useCallback((keyOrEdits, val) => {
const edits = typeof keyOrEdits === 'object' && keyOrEdits !== null
? keyOrEdits : { [keyOrEdits]: val };
setValues((prev) => ({ ...prev, ...edits }));
window.parent.postMessage({ type: '__edit_mode_set_keys', edits }, '*');
}, []);
return [values, setTweak];
}
// ── TweaksPanel ─────────────────────────────────────────────────────────────
// Floating shell. Registers the protocol listener BEFORE announcing
// availability — if the announce ran first, the host's activate could land
// before our handler exists and the toolbar toggle would silently no-op.
// The close button posts __edit_mode_dismissed so the host's toolbar toggle
// flips off in lockstep; the host echoes __deactivate_edit_mode back which
// is what actually hides the panel.
function TweaksPanel({ title = 'Tweaks', children }) {
const [open, setOpen] = React.useState(false);
const dragRef = React.useRef(null);
const offsetRef = React.useRef({ x: 16, y: 16 });
const PAD = 16;
const clampToViewport = React.useCallback(() => {
const panel = dragRef.current;
if (!panel) return;
const w = panel.offsetWidth, h = panel.offsetHeight;
const maxRight = Math.max(PAD, window.innerWidth - w - PAD);
const maxBottom = Math.max(PAD, window.innerHeight - h - PAD);
offsetRef.current = {
x: Math.min(maxRight, Math.max(PAD, offsetRef.current.x)),
y: Math.min(maxBottom, Math.max(PAD, offsetRef.current.y)),
};
panel.style.right = offsetRef.current.x + 'px';
panel.style.bottom = offsetRef.current.y + 'px';
}, []);
React.useEffect(() => {
if (!open) return;
clampToViewport();
if (typeof ResizeObserver === 'undefined') {
window.addEventListener('resize', clampToViewport);
return () => window.removeEventListener('resize', clampToViewport);
}
const ro = new ResizeObserver(clampToViewport);
ro.observe(document.documentElement);
return () => ro.disconnect();
}, [open, clampToViewport]);
React.useEffect(() => {
const onMsg = (e) => {
const t = e?.data?.type;
if (t === '__activate_edit_mode') setOpen(true);
else if (t === '__deactivate_edit_mode') setOpen(false);
};
window.addEventListener('message', onMsg);
window.parent.postMessage({ type: '__edit_mode_available' }, '*');
return () => window.removeEventListener('message', onMsg);
}, []);
const dismiss = () => {
setOpen(false);
window.parent.postMessage({ type: '__edit_mode_dismissed' }, '*');
};
const onDragStart = (e) => {
const panel = dragRef.current;
if (!panel) return;
const r = panel.getBoundingClientRect();
const sx = e.clientX, sy = e.clientY;
const startRight = window.innerWidth - r.right;
const startBottom = window.innerHeight - r.bottom;
const move = (ev) => {
offsetRef.current = {
x: startRight - (ev.clientX - sx),
y: startBottom - (ev.clientY - sy),
};
clampToViewport();
};
const up = () => {
window.removeEventListener('mousemove', move);
window.removeEventListener('mouseup', up);
};
window.addEventListener('mousemove', move);
window.addEventListener('mouseup', up);
};
if (!open) return null;
return (
<>
<style>{__TWEAKS_STYLE}</style>
<div ref={dragRef} className="twk-panel" data-noncommentable=""
style={{ right: offsetRef.current.x, bottom: offsetRef.current.y }}>
<div className="twk-hd" onMouseDown={onDragStart}>
<b>{title}</b>
<button className="twk-x" aria-label="Close tweaks"
onMouseDown={(e) => e.stopPropagation()}
onClick={dismiss}></button>
</div>
<div className="twk-body">{children}</div>
</div>
</>
);
}
// ── Layout helpers ──────────────────────────────────────────────────────────
function TweakSection({ label, children }) {
return (
<>
<div className="twk-sect">{label}</div>
{children}
</>
);
}
function TweakRow({ label, value, children, inline = false }) {
return (
<div className={inline ? 'twk-row twk-row-h' : 'twk-row'}>
<div className="twk-lbl">
<span>{label}</span>
{value != null && <span className="twk-val">{value}</span>}
</div>
{children}
</div>
);
}
// ── Controls ────────────────────────────────────────────────────────────────
function TweakSlider({ label, value, min = 0, max = 100, step = 1, unit = '', onChange }) {
return (
<TweakRow label={label} value={`${value}${unit}`}>
<input type="range" className="twk-slider" min={min} max={max} step={step}
value={value} onChange={(e) => onChange(Number(e.target.value))} />
</TweakRow>
);
}
function TweakToggle({ label, value, onChange }) {
return (
<div className="twk-row twk-row-h">
<div className="twk-lbl"><span>{label}</span></div>
<button type="button" className="twk-toggle" data-on={value ? '1' : '0'}
role="switch" aria-checked={!!value}
onClick={() => onChange(!value)}><i /></button>
</div>
);
}
function TweakRadio({ label, value, options, onChange }) {
const trackRef = React.useRef(null);
const [dragging, setDragging] = React.useState(false);
const opts = options.map((o) => (typeof o === 'object' ? o : { value: o, label: o }));
const idx = Math.max(0, opts.findIndex((o) => o.value === value));
const n = opts.length;
// The active value is read by pointer-move handlers attached for the lifetime
// of a drag — ref it so a stale closure doesn't fire onChange for every move.
const valueRef = React.useRef(value);
valueRef.current = value;
const segAt = (clientX) => {
const r = trackRef.current.getBoundingClientRect();
const inner = r.width - 4;
const i = Math.floor(((clientX - r.left - 2) / inner) * n);
return opts[Math.max(0, Math.min(n - 1, i))].value;
};
const onPointerDown = (e) => {
setDragging(true);
const v0 = segAt(e.clientX);
if (v0 !== valueRef.current) onChange(v0);
const move = (ev) => {
if (!trackRef.current) return;
const v = segAt(ev.clientX);
if (v !== valueRef.current) onChange(v);
};
const up = () => {
setDragging(false);
window.removeEventListener('pointermove', move);
window.removeEventListener('pointerup', up);
};
window.addEventListener('pointermove', move);
window.addEventListener('pointerup', up);
};
return (
<TweakRow label={label}>
<div ref={trackRef} role="radiogroup" onPointerDown={onPointerDown}
className={dragging ? 'twk-seg dragging' : 'twk-seg'}>
<div className="twk-seg-thumb"
style={{ left: `calc(2px + ${idx} * (100% - 4px) / ${n})`,
width: `calc((100% - 4px) / ${n})` }} />
{opts.map((o) => (
<button key={o.value} type="button" role="radio" aria-checked={o.value === value}>
{o.label}
</button>
))}
</div>
</TweakRow>
);
}
function TweakSelect({ label, value, options, onChange }) {
return (
<TweakRow label={label}>
<select className="twk-field" value={value} onChange={(e) => onChange(e.target.value)}>
{options.map((o) => {
const v = typeof o === 'object' ? o.value : o;
const l = typeof o === 'object' ? o.label : o;
return <option key={v} value={v}>{l}</option>;
})}
</select>
</TweakRow>
);
}
function TweakText({ label, value, placeholder, onChange }) {
return (
<TweakRow label={label}>
<input className="twk-field" type="text" value={value} placeholder={placeholder}
onChange={(e) => onChange(e.target.value)} />
</TweakRow>
);
}
function TweakNumber({ label, value, min, max, step = 1, unit = '', onChange }) {
const clamp = (n) => {
if (min != null && n < min) return min;
if (max != null && n > max) return max;
return n;
};
const startRef = React.useRef({ x: 0, val: 0 });
const onScrubStart = (e) => {
e.preventDefault();
startRef.current = { x: e.clientX, val: value };
const decimals = (String(step).split('.')[1] || '').length;
const move = (ev) => {
const dx = ev.clientX - startRef.current.x;
const raw = startRef.current.val + dx * step;
const snapped = Math.round(raw / step) * step;
onChange(clamp(Number(snapped.toFixed(decimals))));
};
const up = () => {
window.removeEventListener('pointermove', move);
window.removeEventListener('pointerup', up);
};
window.addEventListener('pointermove', move);
window.addEventListener('pointerup', up);
};
return (
<div className="twk-num">
<span className="twk-num-lbl" onPointerDown={onScrubStart}>{label}</span>
<input type="number" value={value} min={min} max={max} step={step}
onChange={(e) => onChange(clamp(Number(e.target.value)))} />
{unit && <span className="twk-num-unit">{unit}</span>}
</div>
);
}
function TweakColor({ label, value, onChange }) {
return (
<div className="twk-row twk-row-h">
<div className="twk-lbl"><span>{label}</span></div>
<input type="color" className="twk-swatch" value={value}
onChange={(e) => onChange(e.target.value)} />
</div>
);
}
function TweakButton({ label, onClick, secondary = false }) {
return (
<button type="button" className={secondary ? 'twk-btn secondary' : 'twk-btn'}
onClick={onClick}>{label}</button>
);
}
Object.assign(window, {
useTweaks, TweaksPanel, TweakSection, TweakRow,
TweakSlider, TweakToggle, TweakRadio, TweakSelect,
TweakText, TweakNumber, TweakColor, TweakButton,
});
...@@ -34,7 +34,7 @@ Part-name: Below the Surface ...@@ -34,7 +34,7 @@ Part-name: Below the Surface
---- ----
Sections: [{"content":{"section_label":"THE DESCENT","text":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>","capitalise":"true","content":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>"},"id":"afb489ff-98c5-4ed9-b5be-095e64f99183","isHidden":false,"type":"prose"},{"content":{"text":"The Kanalwerk Friedrichshof Station always smelled like rot. Not the sharp, animal kind, but the slow decay of infrastructure — oil, rust, moss, time."},"id":"62113cb8-a5c7-49cb-aa78-0ebd30cd329a","isHidden":false,"type":"pull"},{"content":{"section_label":"","text":"<p>And tonight, something else. Not strong, but present. Chemical. Artificial.</p><p>He exhaled sharply through his nose and switched on his helmet lamp. The beam cut across the curved concrete, catching glints of water droplets and age-darkened moss. Thin roots dangled from a crack above his head like hair from a wound.</p>","capitalise":"false"},"id":"d698b583-5131-41b6-904b-01f159d8d023","isHidden":false,"type":"prose"},{"content":{"style":"t-rust","caption":"The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him."},"id":"06a5dd57-cc95-4159-bc27-5c57aa90ecf9","isHidden":false,"type":"texture"},{"content":{"heading":"<h2>He took a step.<br>Then another.</h2>","body":"<p>His knees ached more than usual — long shifts, poor sleep. He was pushing fifty and felt every year of it in weather like this.</p>","image":["file://gtg5lx76p316mdyd"]},"id":"557fb97e-e0c7-4f7d-8681-ef9bbb3c9b55","isHidden":false,"type":"pinned"},{"content":{"section_label":"II · THE NAMED TUNNELS","text":"<p>He had worked these tunnels for over a decade, knew them better than the apartment where he barely slept anymore. Some stretches had earned nicknames: <em>The Cathedral</em>, <em>The Gut</em>, <em>The Dead Loop</em>.</p>","capitalise":"true"},"id":"cd4cbadc-ba12-43af-8be3-c319dbf088c1","isHidden":false,"type":"prose"},{"content":{"text":"Friedrichshof didn't get a name. It didn't really deserve one. It just dragged on and got worse with time."},"id":"2a2b5830-645c-4a89-ba77-b06159b220d3","isHidden":false,"type":"pull"},{"content":{"section_label":"","text":"<p>The chemical smell strengthened the further he walked, settling on the back of his tongue. He stopped, let the lamp sweep slowly along the right-hand wall, and listened to the way the silence had begun to organize itself — into something less like absence and more like attention.</p>","capitalise":"false"},"id":"6fb69dee-68a1-427e-a1f7-5b724318ab6a","isHidden":false,"type":"prose"},{"content":{"note_label":"FIELD LOG · MARKUS N.","text":"<p>Note for shift report — odor at K-FH between marker 14 and 17, sharp, possibly solvent. Not in the daily release schedule. Recommend retest before sign-off. Will check again on the way back. <em>(He would not check again on the way back.)</em></p>","content":"<p>Hallo capiditio</p>"},"id":"536e8771-b5e7-4346-9002-852f24aa917b","isHidden":false,"type":"note"}] Sections: [{"content":{"section_label":"THE DESCENT","text":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>","capitalise":"true","content":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>"},"id":"afb489ff-98c5-4ed9-b5be-095e64f99183","isHidden":false,"type":"prose"},{"content":{"text":"The Kanalwerk Friedrichshof Station always smelled like rot. Not the sharp, animal kind, but the slow decay of infrastructure — oil, rust, moss, time."},"id":"62113cb8-a5c7-49cb-aa78-0ebd30cd329a","isHidden":false,"type":"pull"},{"content":{"image":["file://mvgubc51yumjedpl"],"text":"<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p><p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p><p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>"},"id":"6937651a-c8c6-40d1-819a-4e953bb9d3ff","isHidden":false,"type":"pinned-image"},{"content":{"section_label":"THE DESCENT","text":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>","capitalise":"true","content":"<p>Rain hissed softly above the manhole cover, the sound filtered through layers of wet concrete and dripping steel. Markus Neumann wiped a gloved hand across his forehead and adjusted his helmet light. <em>Here we go again.</em> He muttered under his breath, the words echoing along the tunnel like a prayer no one would answer. Another leak complaint — it was the third this week.</p><p>The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him.</p>"},"id":"43ce2c42-9c9f-4997-96fa-fa1caefe4de6","isHidden":false,"type":"prose"},{"content":{"section_label":"","text":"<p>And tonight, something else. Not strong, but present. Chemical. Artificial.</p><p>He exhaled sharply through his nose and switched on his helmet lamp. The beam cut across the curved concrete, catching glints of water droplets and age-darkened moss. Thin roots dangled from a crack above his head like hair from a wound.</p>","capitalise":"false"},"id":"d698b583-5131-41b6-904b-01f159d8d023","isHidden":false,"type":"prose"},{"content":{"style":"t-rust","caption":"The tunnel swallowed him in the way they always did — quietly, without acknowledgment. He climbed down the iron ladder steps, each one slick with condensation. His boots hit the ground with a soft splash. For a second, he just stood there. Letting his eyes adjust. Letting the place settle around him."},"id":"06a5dd57-cc95-4159-bc27-5c57aa90ecf9","isHidden":false,"type":"texture"},{"content":{"heading":"<h2>He took a step.<br>Then another.</h2>","body":"<p>His knees ached more than usual — long shifts, poor sleep. He was pushing fifty and felt every year of it in weather like this.</p>","image":["file://gtg5lx76p316mdyd"]},"id":"557fb97e-e0c7-4f7d-8681-ef9bbb3c9b55","isHidden":false,"type":"pinned-text"},{"content":{"section_label":"II · THE NAMED TUNNELS","text":"<p>He had worked these tunnels for over a decade, knew them better than the apartment where he barely slept anymore. Some stretches had earned nicknames: <em>The Cathedral</em>, <em>The Gut</em>, <em>The Dead Loop</em>.</p>","capitalise":"true"},"id":"cd4cbadc-ba12-43af-8be3-c319dbf088c1","isHidden":false,"type":"prose"},{"content":{"text":"Friedrichshof didn't get a name. It didn't really deserve one. It just dragged on and got worse with time."},"id":"2a2b5830-645c-4a89-ba77-b06159b220d3","isHidden":false,"type":"pull"},{"content":{"section_label":"","text":"<p>The chemical smell strengthened the further he walked, settling on the back of his tongue. He stopped, let the lamp sweep slowly along the right-hand wall, and listened to the way the silence had begun to organize itself — into something less like absence and more like attention.</p>","capitalise":"false"},"id":"6fb69dee-68a1-427e-a1f7-5b724318ab6a","isHidden":false,"type":"prose"},{"content":{"note_label":"FIELD LOG · MARKUS N.","text":"<p>Note for shift report — odor at K-FH between marker 14 and 17, sharp, possibly solvent. Not in the daily release schedule. Recommend retest before sign-off. Will check again on the way back. <em>(He would not check again on the way back.)</em></p>","content":"<p>Hallo capiditio</p>"},"id":"536e8771-b5e7-4346-9002-852f24aa917b","isHidden":false,"type":"note"}]
---- ----
......
name: Pinned Image
icon: image
preview: fields
fields:
image:
label: Background Image
type: files
max: 1
required: true
text:
label: Scrolling Text
type: writer
name: Pinned Section name: Pinned Text
icon: layers icon: layers
preview: fields preview: fields
fields: fields:
......
...@@ -4,5 +4,5 @@ preview: fields ...@@ -4,5 +4,5 @@ preview: fields
fields: fields:
text: text:
label: Quote Text label: Quote Text
type: textarea type: writer
required: true required: true
...@@ -49,7 +49,8 @@ tabs: ...@@ -49,7 +49,8 @@ tabs:
- pull - pull
- note - note
- texture - texture
- pinned - pinned-text
- pinned-image
seo: seo:
label: SEO label: SEO
......
<?php
/**
* Collections help with keeping your code DRY
* if you need to reuse the same set up pages, files or users in multiple places across your site.
*
* More about collections:
* https://getkirby.com/docs/guide/templates/collections
*/
return function () {
return page('notes')
->children()
->listed()
->sortBy('date', 'desc');
};
<?php
/**
* Controllers allow you to separate the logic of your templates from your markup.
* This is especially useful for complex logic, but also in general to keep your templates clean.
*
* In this example, we define the `$gallery` variable which is passed to the template
*
* More about controllers:
* https://getkirby.com/docs/guide/templates/controllers
*/
return function ($page) {
$gallery = $page->images()->sortBy('sort', 'filename');
return [
'gallery' => $gallery
];
};
<?php
/**
* Controllers allow you to separate the logic of your templates from your markup.
* This is especially useful for complex logic, but also in general to keep your templates clean.
*
* In this example, we split the tags from the tags field to create a nice tag list
*
* More about controllers:
* https://getkirby.com/docs/guide/templates/controllers
*/
return function ($page) {
return [
'tags' => $page->tags()->split(','),
];
};
<?php
/**
* Controllers allow you to separate the logic of your templates from your markup.
* This is especially useful for complex logic, but also in general to keep your templates clean.
*
* In this example, we handle tag filtering and paginating notes in the controller,
* before we pass the currently active tag and the notes to the template.
*
* More about controllers:
* https://getkirby.com/docs/guide/templates/controllers
*/
return function ($page) {
/**
* We use the collection helper to fetch the notes collection defined in `/site/collections/notes.php`
*
* More about collections:
* https://getkirby.com/docs/guide/templates/collections
*/
$notes = collection('notes');
$tag = param('tag');
if (empty($tag) === false) {
$notes = $notes->filterBy('tags', $tag, ',');
}
return [
'tag' => $tag,
'notes' => $notes->paginate(6)
];
};
<?php
/**
* Page models extend Kirby's default page object.
*
* In page models you can define methods that are then available
* everywhere in Kirby where you call a page of the extended type.
*
* In this example, we define the cover method that either returns
* an image selected in the cover field or the first image in the folder.
*
* You can see the method in use in the `home.php` and `photography.php` templates
* and in the `site/blueprints/sections/albums.yml` image query
*
* More about models: https://getkirby.com/docs/guide/templates/page-models
*/
class AlbumPage extends Page
{
public function cover()
{
return $this->content()->get('cover')->toFile() ?? $this->image();
}
}
<?php
/**
* Page models extend Kirby's default page object.
*
* In page models you can define methods that are then available
* everywhere in Kirby where you call a page of the extended type.
*
* In this example, we define the cover method that either returns
* an image selected in the cover field or the first image in the folder.
*
* You can see the method in use in the `note.php` snippet.
* and in the `site/blueprints/sections/notes.yml` image query
*
* We also define a custom date handler here, which keeps date formatting
* for the published date consistent in templates, snippets and blueprints.
*
* More about models: https://getkirby.com/docs/guide/templates/page-models
*/
class NotePage extends Page
{
public function cover()
{
return $this->content()->cover()->toFile() ?? $this->image();
}
public function published($format = null)
{
return parent::date()->toDate($format ?? 'd M, Y');
}
}
<?php
$bg = $block->image()->toFile();
?>
<section class="pinned-image-section">
<div class="pinned-image-stage">
<?php if ($bg): ?>
<div class="pinned-image-bg" style="background-image: url('<?= $bg->url() ?>')"></div>
<?php endif ?>
<div class="pinned-image-overlay"></div>
</div>
<?php if ($block->text()->isNotEmpty()): ?>
<div class="pinned-image-content">
<?= $block->text() ?>
</div>
<?php endif ?>
</section>
<?php <?php
/**
* Block snippet: pinned
* Renders a sticky full-viewport pinned scroll section.
*/
$bg = $block->image()->toFile(); $bg = $block->image()->toFile();
?> ?>
<section class="pinned-section"> <section class="pinned-text-section">
<div class="pinned-stage"> <div class="pinned-text-stage">
<div class="pinned-bg<?= $bg ? '' : ' t1' ?>" data-parallax="0.2"<?= $bg ? ' style="background-image: url(\'' . $bg->url() . '\')"' : '' ?>></div> <div class="pinned-text-bg<?= $bg ? '' : ' t1' ?>" data-parallax="1"<?= $bg ? ' style="background-image: url(\'' . $bg->url() . '\')"' : '' ?>></div>
<div class="pinned-overlay"></div> <div class="pinned-text-overlay"></div>
<div class="pinned-text"> <div class="pinned-text-copy">
<h2><?= $block->heading() ?></h2> <h2><?= $block->heading() ?></h2>
<?php if ($block->body()->isNotEmpty()): ?> <?php if ($block->body()->isNotEmpty()): ?>
<?= $block->body() ?> <?= $block->body() ?>
......
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
This footer snippet is reused in all templates.
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
</main>
<footer class="footer">
<div class="grid">
<div class="column" style="--columns: 8">
<h2><a href="https://getkirby.com">Made with Kirby</a></h2>
<p>
Kirby: the file-based CMS that adapts to any project, loved by developers and editors alike
</p>
</div>
<div class="column" style="--columns: 2">
<h2>Pages</h2>
<ul>
<?php foreach ($site->children()->listed() as $example): ?>
<li><a href="<?= $example->url() ?>"><?= $example->title()->esc() ?></a></li>
<?php endforeach ?>
</ul>
</div>
<div class="column" style="--columns: 2">
<h2>Kirby</h2>
<ul>
<li><a href="https://getkirby.com">Website</a></li>
<li><a href="https://getkirby.com/docs">Docs</a></li>
<li><a href="https://forum.getkirby.com">Forum</a></li>
<li><a href="https://chat.getkirby.com">Chat</a></li>
<li><a href="https://github.com/getkirby">GitHub</a></li>
</ul>
</div>
</div>
</footer>
<?= js([
'assets/js/prism.js',
'assets/js/lightbox.js',
'assets/js/index.js',
'@auto'
]) ?>
</body>
</html>
<?php
$attrs = attr([
'data-lightbox' => $lightbox ?? false,
'href' => $href ?? $src,
]);
?>
<a <?= $attrs ?>>
<img
src="<?= esc($src, 'attr') ?>"
alt="<?= esc($alt, 'attr') ?>"
style="
aspect-ratio: <?= $ratio ?? 'auto' ?>;
object-fit: <?= ($contain ?? false) ? 'contain' : 'cover' ?>
"
>
</a>
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
This intro snippet is reused in multiple templates.
While it does not contain much code, it helps to keep your
code DRY and thus facilitate maintenance when you have
to make changes.
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
<header class="h1">
<h1><?= $page->headline()->or($page->title())->esc() ?></h1>
<?php if ($page->subheadline()->isNotEmpty()): ?>
<p class="color-grey"><?= $page->subheadline()->esc() ?></p>
<?php endif ?>
</header>
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
The note snippet renders an excerpt of a blog article.
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
<article class="note-excerpt">
<a href="<?= $note->url() ?>">
<header>
<figure class="img" style="--w: 16; --h:9">
<?php if ($cover = $note->cover()): ?>
<img src="<?= $cover->crop(320, 180)->url() ?>" alt="<?= $cover->alt()->esc() ?>">
<?php endif ?>
</figure>
<h2 class="note-excerpt-title"><?= $note->title()->esc() ?></h2>
<time class="note-excerpt-date" datetime="<?= $note->published('c') ?>"><?= $note->published() ?></time>
</header>
<?php if (($excerpt ?? true) !== false): ?>
<div class="note-excerpt-text">
<?= $note->text()->toBlocks()->excerpt(280) ?>
</div>
<?php endif ?>
</a>
</article>
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
The pagination snippet renders prev/next links in the
blog, when articles spread across multiple pages
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
<?php if ($pagination->hasPages()): ?>
<nav class="pagination">
<?php if ($pagination->hasPrevPage()): ?>
<a class="pagination-prev" href="<?= $pagination->prevPageUrl() ?>">&larr;</a>
<?php else: ?>
<span class="pagination-prev">&larr;</span>
<?php endif ?>
<?php if ($pagination->hasNextPage()): ?>
<a class="pagination-next" href="<?= $pagination->nextPageUrl() ?>">&rarr;</a>
<?php else: ?>
<span class="pagination-next">&rarr;</span>
<?php endif ?>
</nav>
<?php endif ?>
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
The prevnext snippet renders the nice "keep on reading"
section below each article in the blog, to jump between
articles. It reuses the note snippet to render a full
excerpt of the article.
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
<nav class="blog-prevnext">
<h2 class="h2">Keep on reading</h2>
<div class="autogrid" style="--gutter: 1.5rem">
<?php if ($prev = $page->prevListed()): ?>
<?php snippet('note', ['note' => $prev, 'excerpt' => false]) ?>
<?php endif ?>
<?php if ($next = $page->nextListed()): ?>
<?php snippet('note', ['note' => $next, 'excerpt' => false]) ?>
<?php endif ?>
</div>
</nav>
<?php <?php
/** /**
* Snippet: scripts * Snippet: scripts
* Includes shared JS and the React tweaks panel. * Includes shared JS.
* Params: none
*/ */
?> ?>
<?= js('assets/js/shared.js') ?> <?= js('assets/js/shared.js') ?>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
<script type="text/babel" src="<?= url('assets/js/tweaks-panel.js') ?>"></script>
<script type="text/babel" src="<?= url('assets/js/tweaks-app.js') ?>"></script>
<?php
/*
Snippets are a great way to store code snippets for reuse
or to keep your templates clean.
In this snippet the svg() helper is a great way to embed SVG
code directly in your HTML. Pass the path to your SVG
file to load it.
More about snippets:
https://getkirby.com/docs/guide/templates/snippets
*/
?>
<span class="social">
<a href="https://mastodon.social/@getkirby" aria-label="Follow us on Mastodon">
<?= svg('assets/icons/mastodon.svg') ?>
</a>
<a href="https://instagram.com/getkirby" aria-label="Follow us on Instagram">
<?= svg('assets/icons/instagram.svg') ?>
</a>
<a href="https://youtube.com/kirbycasts" aria-label="Watch our videos on YouTube">
<?= svg('assets/icons/youtube.svg') ?>
</a>
<a href="https://chat.getkirby.com" aria-label="Chat with us on Discord">
<?= svg('assets/icons/discord.svg') ?>
</a>
</span>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment