home3 news: typographic category cover for pictureless articles
~half the brief has no image, leaving a blank well above the headline. When an article has no image_url, fill the well with the topic word (e.g. "science") in lowercase Newsreader on a soft topic-tinted field, color-coded per topic (science/tech/environment/health/community/culture/world/space + neutral default). Same 5:4 footprint as the photo, so card height stays consistent. Threads `topic` through the news object. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,24 @@
|
||||
// /home3 — the Claude Design "Frame A" direction (editorial, with colour), rebuilt in
|
||||
// our codebase with our real logo + self-hosted fonts, wired to live data. Hidden
|
||||
// prototype (noindex), alongside /home2 so we can compare.
|
||||
let news = $state(null); // {id, title, summary, image}
|
||||
let news = $state(null); // {id, title, summary, image, topic, ...}
|
||||
let art = $state(null); // {title, artist, year, image}
|
||||
let newsFit = $state('cover'); // 'cover' = full-bleed photo; 'contain' = framed-plate figure
|
||||
|
||||
// Pictureless articles (~half the feed) get a typographic category cover instead of a blank
|
||||
// well: the topic word on a soft topic-tinted field, color-coded across the feed.
|
||||
const TOPIC_TINT = {
|
||||
science: { bg: '#e2edf1', ink: '#2f6d86' },
|
||||
technology: { bg: '#e8e9f4', ink: '#5a5fa0' },
|
||||
environment: { bg: '#e6efe2', ink: '#3a7d5b' },
|
||||
health: { bg: '#f4e8e8', ink: '#a8566a' },
|
||||
community: { bg: '#f3ece0', ink: '#a9763f' },
|
||||
culture: { bg: '#ece5f3', ink: '#7e51b0' },
|
||||
world: { bg: '#e6ecf3', ink: '#4a6da0' },
|
||||
space: { bg: '#e7e7f2', ink: '#4a4e8a' },
|
||||
};
|
||||
const TOPIC_DEFAULT = { bg: '#e6edef', ink: '#3f6378' };
|
||||
let topicTint = $derived(TOPIC_TINT[(news?.topic || '').toLowerCase()] || TOPIC_DEFAULT);
|
||||
let word = $state(null); // /api/word/today
|
||||
let quote = $state(null); // /api/quote/today
|
||||
let fact = $state(null); // /api/onthisday/today
|
||||
@@ -91,7 +106,7 @@
|
||||
} catch { /* global brief */ }
|
||||
try {
|
||||
const it = (await getJSON(`/api/brief?limit=1${homeq}`))?.items?.[0];
|
||||
if (it) news = { id: it.id, title: it.title, summary: it.summary || it.description || '', image: it.image_url || null, source_read_minutes: it.source_read_minutes };
|
||||
if (it) news = { id: it.id, title: it.title, summary: it.summary || it.description || '', image: it.image_url || null, topic: it.topic || null, source_read_minutes: it.source_read_minutes };
|
||||
// Photos display full (cover); only wide/tall figures (diagrams) get the framed plate.
|
||||
if (news?.image) {
|
||||
const probe = new Image();
|
||||
@@ -159,9 +174,16 @@
|
||||
<!-- Good News (tall) — a card with TWO links, so it's a div, not a single anchor -->
|
||||
<div class="card news">
|
||||
<a class="news-photo-a" href={news?.id ? `/a/${news.id}` : '/'} aria-label="Read this article">
|
||||
<div class="news-photo {newsFit}">
|
||||
<div class="news-plate" style={news?.image ? `background-image:url(${news.image})` : ''}></div>
|
||||
</div>
|
||||
{#if news?.image}
|
||||
<div class="news-photo {newsFit}">
|
||||
<div class="news-plate" style={`background-image:url(${news.image})`}></div>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- pictureless: typographic category cover -->
|
||||
<div class="news-typo" style={`background:${topicTint.bg}`}>
|
||||
<span class="news-typo-word" style={`color:${topicTint.ink}`}>{news?.topic || 'good news'}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
<div class="news-body">
|
||||
<span class="label" style="color:#0083ad">GOOD NEWS</span>
|
||||
@@ -371,6 +393,13 @@
|
||||
box-shadow: 0 6px 18px -10px rgba(30, 60, 70, 0.28);
|
||||
background-size: contain; background-origin: content-box;
|
||||
}
|
||||
/* pictureless fallback: topic word on a soft topic-tinted field, same footprint as the photo */
|
||||
.news-typo { aspect-ratio: 5/4; display: flex; align-items: center; justify-content: center; padding: 16px; box-sizing: border-box; }
|
||||
.news-typo-word {
|
||||
font-family: 'Newsreader', Georgia, serif; font-weight: 500; font-size: clamp(1.9rem, 5vw, 2.9rem);
|
||||
line-height: 1.05; letter-spacing: -0.01em; text-transform: lowercase; text-align: center; max-width: 100%;
|
||||
}
|
||||
|
||||
.news-body { padding: 24px 26px; flex: 1; display: flex; flex-direction: column; }
|
||||
.news h2 {
|
||||
font-size: clamp(1.55rem, 2.6vw, 30px); line-height: 1.14; margin: 12px 0 0;
|
||||
|
||||
Reference in New Issue
Block a user