From 8f845092dba85f7441e1d79aa252951b843e386f Mon Sep 17 00:00:00 2001 From: Melvin Carvalho Date: Thu, 11 Jun 2026 02:31:26 +0200 Subject: [PATCH] Design: Quotation typographic quote poster layout --- app.css | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/app.css b/app.css index 591674d..5813f32 100644 --- a/app.css +++ b/app.css @@ -3280,6 +3280,69 @@ footer a:hover { color: var(--accent-2); } .tweet-actions { border-top-color: #333; } } + +/* ── Per-type bespoke: Quotation — typographic quote poster ── */ + +.card.quote-poster { background: #fff; border-color: rgba(0,0,0,.06); } +.card.quote-poster .hd.hidden { display: none; } +.card.quote-poster .bd { padding: 2.5rem 2rem 2rem; background: #fff; } +.card.quote-poster .bd::before { display: none; } + +.quote-mark { + font-family: Georgia, "Times New Roman", serif; + font-size: 6rem; + line-height: 1; + color: var(--accent, #7c2d12); + opacity: .18; + margin-bottom: -.8rem; + user-select: none; +} + +.quote-text { + font-family: Georgia, "Times New Roman", serif; + font-size: 1.4rem; + font-style: italic; + line-height: 1.6; + color: #1a1a1a; + margin: 0 0 1.4rem; + padding: 0; + border: none; + quotes: none; +} + +.quote-attribution { + font-variant: small-caps; + font-size: .9rem; + letter-spacing: .04em; + color: #444; + margin-bottom: .3rem; +} + +.quote-date { + font-size: .75rem; + color: #aaa; + margin-bottom: 1.4rem; +} + +.quote-footnote { + font-size: .78rem; + line-height: 1.5; + color: #888; + border-top: 1px solid #eee; + padding-top: .8rem; + margin: 0; +} + +/* Dark mode quote poster */ +@media (prefers-color-scheme: dark) { + .card.quote-poster { background: #1c1c1e; border-color: rgba(255,255,255,.06); } + .card.quote-poster .bd { background: #1c1c1e; } + .quote-text { color: #e8e8e8; } + .quote-attribution { color: #aaa; } + .quote-date { color: #555; } + .quote-footnote { color: #666; border-top-color: #333; } +} + /* ────────────────────────────────────────────── Responsive / Mobile — small-screen polish. Stacks label/value grid, scales header, diff --git a/app.js b/app.js index 4e8b942..b8cecaf 100644 --- a/app.js +++ b/app.js @@ -2211,6 +2211,63 @@ handled.add("articleBody"); handled.add("author"); handled.add("datePublished"); handled.add("url"); } + // ── QUOTATION (typographic quote poster) ── + if (cfg.type === "Quotation") { + const card = document.querySelector(".card"); + if (card) card.classList.add("quote-poster"); + + // Hide normal header + const hd = document.querySelector(".hd"); + if (hd) hd.classList.add("hidden"); + + // Remove generic hero if present + const heroMount = document.getElementById("hero-mount"); + if (heroMount) heroMount.querySelector(".hero")?.remove(); + + // Huge opening quotation mark + const mark = document.createElement("div"); mark.className = "quote-mark"; + mark.textContent = "\u201C"; + view.appendChild(mark); + + // The quotation text — large serif italic + const text = data["text"]; + if (text) { + const q = document.createElement("blockquote"); q.className = "quote-text"; + q.textContent = text; + view.appendChild(q); + } + + // Attribution line: em-dash + author in small-caps + const authorRaw = data["author"]; + const authorName = (typeof authorRaw === "object" && authorRaw !== null) ? (authorRaw.name || "") : (authorRaw || ""); + if (authorName) { + const attr = document.createElement("div"); attr.className = "quote-attribution"; + attr.textContent = "\u2014 " + authorName; + view.appendChild(attr); + } + + // Subtle date below attribution + const dateCreated = data["dateCreated"]; + if (dateCreated) { + const d = new Date(dateCreated); + const year = isNaN(d.getTime()) ? dateCreated : d.getFullYear().toString(); + const dateEl = document.createElement("div"); dateEl.className = "quote-date"; + dateEl.textContent = year; + view.appendChild(dateEl); + } + + // Description as a small footnote + const desc = data["description"]; + if (desc) { + const fn = document.createElement("p"); fn.className = "quote-footnote"; + fn.textContent = desc; + view.appendChild(fn); + } + + handled.add("name"); handled.add("image"); handled.add("description"); + handled.add("text"); handled.add("author"); handled.add("dateCreated"); + } + return handled; }