Apply Illuminated Nocturne style to cover template
Replaces Georgia with Cormorant Garamond (display, 300 italic) + Lora (body) across all cover text. Adds @font-face declarations pointing to fonts/ (same as interior). Updates gold tokens to match interior palette. Visual changes: front title in Cormorant light italic with gold gradient rule below, ❧ ornament replacing ✦, synopsis body in Lora. cover.js now reads 00-front-matter.md to inject author name into spine, front, and removes the [AUTOR] placeholder. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -3,6 +3,7 @@ import { readFile, writeFile, access } from 'fs/promises';
|
|||||||
import { resolve, dirname } from 'path';
|
import { resolve, dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import nunjucks from 'nunjucks';
|
import nunjucks from 'nunjucks';
|
||||||
|
import matter from 'gray-matter';
|
||||||
|
|
||||||
const __dir = dirname(fileURLToPath(import.meta.url));
|
const __dir = dirname(fileURLToPath(import.meta.url));
|
||||||
const root = resolve(__dir, '..');
|
const root = resolve(__dir, '..');
|
||||||
@@ -48,6 +49,10 @@ async function generate() {
|
|||||||
const backImage = await fileExists(resolve(root, 'images/cover/back.png'))
|
const backImage = await fileExists(resolve(root, 'images/cover/back.png'))
|
||||||
? '../images/cover/back.png' : null;
|
? '../images/cover/back.png' : null;
|
||||||
|
|
||||||
|
// Load author / title from front matter
|
||||||
|
const fmRaw = await readFile(resolve(root, 'content', '00-front-matter.md'), 'utf-8');
|
||||||
|
const { data: fm } = matter(fmRaw);
|
||||||
|
|
||||||
// Render HTML from template
|
// Render HTML from template
|
||||||
const env = nunjucks.configure(resolve(root, 'templates'), { autoescape: false });
|
const env = nunjucks.configure(resolve(root, 'templates'), { autoescape: false });
|
||||||
const html = env.render('cover.html', {
|
const html = env.render('cover.html', {
|
||||||
@@ -63,6 +68,9 @@ async function generate() {
|
|||||||
hasSpineText: pageCount >= MIN_SPINE_TEXT,
|
hasSpineText: pageCount >= MIN_SPINE_TEXT,
|
||||||
frontImage,
|
frontImage,
|
||||||
backImage,
|
backImage,
|
||||||
|
author: fm.author || '',
|
||||||
|
title: fm.title || 'Das Kaleidoskop der Schlummerwelten',
|
||||||
|
subtitle: fm.subtitle || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const htmlOut = resolve(root, 'output', 'cover.html');
|
const htmlOut = resolve(root, 'output', 'cover.html');
|
||||||
|
|||||||
+107
-44
@@ -19,18 +19,60 @@
|
|||||||
--spine-left: calc(var(--bleed) + var(--trim-w));
|
--spine-left: calc(var(--bleed) + var(--trim-w));
|
||||||
--front-left: calc(var(--bleed) + var(--trim-w) + var(--spine-w));
|
--front-left: calc(var(--bleed) + var(--trim-w) + var(--spine-w));
|
||||||
|
|
||||||
/* Design tokens */
|
/* Design tokens — matches interior "Illuminated Nocturne" palette */
|
||||||
--color-bg: #080820;
|
--color-bg: #080820;
|
||||||
--color-mid: #111138;
|
--color-mid: #0f0f30;
|
||||||
--color-gold: #c8a84b;
|
--color-gold: #b89a4e;
|
||||||
--color-gold2: #f0d080;
|
--color-gold2: #e8c96a;
|
||||||
--color-text: #e8e4d8;
|
--color-text: #e8e4d8;
|
||||||
--color-muted: rgba(200,168,75,0.45);
|
--color-muted: rgba(184,154,78,0.5);
|
||||||
|
|
||||||
|
--font-display: 'Cormorant Garamond', Georgia, serif;
|
||||||
|
--font-body: 'Lora', Georgia, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Fonts ─────────────────────────────────────────────── */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../fonts/cormorant-garamond-400-normal.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url('../fonts/cormorant-garamond-300-italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../fonts/cormorant-garamond-400-italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Cormorant Garamond';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url('../fonts/cormorant-garamond-600-italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lora';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../fonts/lora-400-normal.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Lora';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('../fonts/lora-400-italic.woff2') format('woff2');
|
||||||
}
|
}
|
||||||
|
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
|
font-family: var(--font-body);
|
||||||
width: var(--total-w);
|
width: var(--total-w);
|
||||||
height: var(--total-h);
|
height: var(--total-h);
|
||||||
background: var(--color-bg);
|
background: var(--color-bg);
|
||||||
@@ -107,18 +149,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.back-headline {
|
.back-headline {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
font-size: 0.22in;
|
font-size: 0.22in;
|
||||||
color: var(--color-gold);
|
color: var(--color-gold);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.03em;
|
||||||
margin-bottom: 0.12in;
|
margin-bottom: 0.14in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-synopsis {
|
.back-synopsis {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-body);
|
||||||
font-size: 0.145in;
|
font-size: 0.138in;
|
||||||
line-height: 1.7;
|
line-height: 1.8;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
@@ -132,12 +175,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.back-tagline {
|
.back-tagline {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.115in;
|
font-weight: 300;
|
||||||
|
font-size: 0.118in;
|
||||||
color: var(--color-muted);
|
color: var(--color-muted);
|
||||||
max-width: 60%;
|
max-width: 60%;
|
||||||
line-height: 1.5;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Barcode placeholder — KDP places the barcode here if left blank */
|
/* Barcode placeholder — KDP places the barcode here if left blank */
|
||||||
@@ -175,23 +219,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.spine-title {
|
.spine-title {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
font-size: 0.13in;
|
font-size: 0.13in;
|
||||||
color: var(--color-gold);
|
color: var(--color-gold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spine-divider {
|
.spine-divider {
|
||||||
|
font-family: var(--font-display);
|
||||||
font-size: 0.1in;
|
font-size: 0.1in;
|
||||||
color: var(--color-muted);
|
color: var(--color-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.spine-author {
|
.spine-author {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
font-size: 0.1in;
|
font-size: 0.1in;
|
||||||
color: var(--color-text);
|
color: rgba(232, 228, 216, 0.7);
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.06em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spine-too-narrow {
|
.spine-too-narrow {
|
||||||
@@ -233,19 +281,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.front-title {
|
.front-title {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.52in;
|
font-weight: 300;
|
||||||
line-height: 1.2;
|
font-size: 0.54in;
|
||||||
|
line-height: 1.18;
|
||||||
color: var(--color-gold2);
|
color: var(--color-gold2);
|
||||||
text-shadow: 0 0 0.15in rgba(200,168,75,0.4), 0 2px 8px rgba(0,0,0,0.8);
|
text-shadow: 0 0 0.18in rgba(184,154,78,0.45), 0 2px 10px rgba(0,0,0,0.9);
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.front-rule {
|
||||||
|
width: 1.6in;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, var(--color-gold), transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-subtitle {
|
.front-subtitle {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-size: 0.18in;
|
font-style: italic;
|
||||||
letter-spacing: 0.08em;
|
font-weight: 300;
|
||||||
color: var(--color-text);
|
font-size: 0.17in;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
color: rgba(232, 228, 216, 0.75);
|
||||||
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,29 +317,33 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: radial-gradient(ellipse at center, #1a1a4a 0%, #080820 70%);
|
background: radial-gradient(ellipse at 50% 40%, #1a1a4a 0%, #080820 70%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-art-placeholder span {
|
.front-art-placeholder span {
|
||||||
font-family: monospace;
|
font-family: var(--font-display);
|
||||||
font-size: 0.12in;
|
font-style: italic;
|
||||||
color: rgba(200,168,75,0.4);
|
font-size: 0.13in;
|
||||||
border: 1px dashed rgba(200,168,75,0.2);
|
color: rgba(184,154,78,0.4);
|
||||||
padding: 0.15in 0.3in;
|
border: 1px solid rgba(184,154,78,0.15);
|
||||||
|
padding: 0.15in 0.35in;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-author {
|
.front-author {
|
||||||
font-family: Georgia, serif;
|
font-family: var(--font-display);
|
||||||
font-size: 0.16in;
|
font-style: italic;
|
||||||
letter-spacing: 0.1em;
|
font-weight: 300;
|
||||||
color: rgba(200,168,75,0.7);
|
font-size: 0.15in;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
color: rgba(184,154,78,0.65);
|
||||||
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-ornament-bottom {
|
.front-ornament {
|
||||||
font-size: 0.14in;
|
font-family: var(--font-display);
|
||||||
|
font-size: 0.16in;
|
||||||
color: var(--color-muted);
|
color: var(--color-muted);
|
||||||
letter-spacing: 0.4em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Safe-zone & bleed guides overlay ───────────────────── */
|
/* ── Safe-zone & bleed guides overlay ───────────────────── */
|
||||||
@@ -372,8 +434,8 @@
|
|||||||
{% if hasSpineText %}
|
{% if hasSpineText %}
|
||||||
<div class="spine-text">
|
<div class="spine-text">
|
||||||
<span class="spine-title">Das Kaleidoskop der Schlummerwelten</span>
|
<span class="spine-title">Das Kaleidoskop der Schlummerwelten</span>
|
||||||
<span class="spine-divider">✦</span>
|
<span class="spine-divider">❧</span>
|
||||||
<span class="spine-author">[AUTOR]</span>
|
{% if author %}<span class="spine-author">{{ author }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="spine-too-narrow">too narrow ({{ pageCount }}p < 79)</span>
|
<span class="spine-too-narrow">too narrow ({{ pageCount }}p < 79)</span>
|
||||||
@@ -393,11 +455,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="front-content">
|
<div class="front-content">
|
||||||
<p class="front-ornament-top">✦ ✦ ✦</p>
|
<p class="front-ornament">❧</p>
|
||||||
<h1 class="front-title">Das Kaleidoskop<br>der Schlummerwelten</h1>
|
<h1 class="front-title">Das Kaleidoskop<br>der Schlummerwelten</h1>
|
||||||
|
<div class="front-rule"></div>
|
||||||
<p class="front-subtitle">Zwölf magische Einschlafgeschichten</p>
|
<p class="front-subtitle">Zwölf magische Einschlafgeschichten</p>
|
||||||
<p class="front-author">[AUTOR]</p>
|
{% if author %}<p class="front-author">{{ author }}</p>{% endif %}
|
||||||
<p class="front-ornament-bottom">· · ·</p>
|
<p class="front-ornament">· · ·</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>{# end front #}
|
</div>{# end front #}
|
||||||
|
|||||||
Reference in New Issue
Block a user