From 3c519a5f50f17df5390525f926c82f5782545195 Mon Sep 17 00:00:00 2001 From: jay Date: Mon, 22 Jun 2026 10:18:00 -0400 Subject: [PATCH] home3: small-joys rail (WOTD/QOTD crafted + 'good thing today' SOON), whole-word headline clamp, 16px gaps Co-Authored-By: Claude Opus 4.8 --- frontend/src/routes/home3/+page.svelte | 64 +++++++++++++++++--------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/frontend/src/routes/home3/+page.svelte b/frontend/src/routes/home3/+page.svelte index 4bba575..65cd09a 100644 --- a/frontend/src/routes/home3/+page.svelte +++ b/frontend/src/routes/home3/+page.svelte @@ -8,6 +8,15 @@ let news = $state(null); // {id, title, summary, image} let art = $state(null); // {title, artist, year, image} + // headline truncated on a whole-word boundary (no mid-word ellipsis) + function clampWords(s, max = 48) { + if (!s || s.length <= max) return s; + const cut = s.slice(0, max); + const i = cut.lastIndexOf(' '); + return (i > 0 ? cut.slice(0, i) : cut).replace(/[\s,;:.]+$/, '') + '…'; + } + let headline = $derived(clampWords(news?.title ?? 'What went right this week: the good news that actually matters')); + onMount(async () => { try { const a = await getJSON('/api/art/today'); @@ -61,7 +70,7 @@
GOOD NEWS -

{news?.title ?? 'What went right this week: the good news that actually matters'}

+

{headline}

{news?.summary || "We read the week so you don't have to doomscroll it. Five quietly hopeful stories, summarised to the gist."}

Read article @@ -136,18 +145,23 @@
- -
-
+ +
+
WORD OF THE DAY - Serene +

Serene adj · /səˈriːn/

Calm, peaceful, and untroubled.
-
+
QUOTE OF THE DAY - “Very little is needed to make a happy life.” + + Very little is needed to make a happy life. Marcus Aurelius
+
+
A GOOD THING TODAYSOON
+ In 1928, penicillin was discovered by a happy accident. +
@@ -201,12 +215,12 @@ .bento { max-width: 1180px; width: 100%; margin: 0 auto; box-sizing: border-box; padding: 0 clamp(18px, 5vw, 44px) 16px; - display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(0, 1.82fr); gap: 18px; + display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(0, 1.82fr); gap: 16px; } /* right column matches the News height; Art stays pinned to the TOP and the Play/Moment pair to the BOTTOM, with the extra space distributed BETWEEN them (FIX1). The cards themselves keep their natural size and never stretch. */ - .rightcol { display: flex; flex-direction: column; gap: 18px; } + .rightcol { display: flex; flex-direction: column; gap: 16px; } .rightcol .art { flex: none; } /* Art pinned to the top */ .pair-wrap { flex: 1; display: flex; align-items: center; } /* fill the rest; pair vertically centered */ .card { @@ -228,7 +242,7 @@ .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; - display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; + display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; } /* the gist fades out at the bottom (FIX 1) instead of a hard ellipsis — full read on /news */ .summary { @@ -263,7 +277,7 @@ } /* bottom pair */ - .pair { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 18px; } + .pair { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .play { background: #FFF3DC; border: 1px solid #f6e2b8; display: flex; flex-direction: column; } .play-top { padding: 22px 24px 0; } .play h3 { font-size: clamp(1.25rem, 1.9vw, 23px); margin: 14px 0 0; color: #5c3d0c; } @@ -299,15 +313,22 @@ .moment-line { font-family: 'Newsreader', Georgia, serif; font-style: italic; font-size: 18px; line-height: 1.3; color: #214a35; margin: 14px 0 0; } .moment-meta { margin-top: auto; padding-top: 16px; font-size: 13px; color: #6f9683; } - /* skinny Word / Quote of the day strip — warm neutral, two halves split by a divider */ - .wotd { flex: none; display: flex; align-items: stretch; background: #f1ece1; border: 1px solid #e6ddc9; } - .wotd-half { flex: 1; padding: 15px 22px; display: flex; flex-direction: column; justify-content: center; gap: 3px; min-width: 0; } - .wotd-half + .wotd-half { border-left: 1px solid #e6ddc9; } - .wotd .label { color: var(--muted); } - .wotd .word { font-family: 'Newsreader', Georgia, serif; font-weight: 600; font-size: 20px; color: var(--ink); } - .wotd .def { font-size: 13px; color: var(--body); } - .wotd .quote { font-family: 'Newsreader', Georgia, serif; font-style: italic; font-size: 15px; line-height: 1.3; color: #2d2a25; } - .wotd .quote-by { font-size: 12px; color: var(--muted); } + /* "small joys" rail — three evenly-weighted daily delights, each its own quiet tint */ + .joys { flex: none; display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; } + .joy { border-radius: 18px; padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; min-width: 0; } + .joy-word { background: #f1ece1; border: 1px solid #e6ddc9; } + .joy-quote { background: #f2ecf6; border: 1px solid #e4d8ee; } + .joy-fact { background: #e8f2ea; border: 1px solid #cfe5d4; } + .joy .label { color: var(--muted); } + .word-line { margin: 0; display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; } + .joy .word { font-family: 'Newsreader', Georgia, serif; font-weight: 600; font-size: 19px; color: var(--ink); } + .word-meta { font-size: 12px; color: var(--muted); font-style: italic; } + .joy .def { font-size: 12.5px; color: var(--body); line-height: 1.4; } + .qglyph { font-family: 'Newsreader', Georgia, serif; font-size: 26px; line-height: 1; height: 13px; color: #b9a8d6; } + .joy .quote { font-family: 'Newsreader', Georgia, serif; font-style: italic; font-size: 14px; line-height: 1.3; color: #2d2a25; } + .quote-by { font-size: 11.5px; color: var(--muted); } + .joy-fact .joy-top { display: flex; align-items: center; justify-content: space-between; } + .fact { font-size: 13px; line-height: 1.4; color: var(--body); } .foot { text-align: center; max-width: 1180px; width: 100%; margin: 14px auto 0; box-sizing: border-box; @@ -324,7 +345,6 @@ .art { flex-direction: column; } .art-swatch { width: 100%; min-height: 130px; } .pair { grid-template-columns: 1fr; } - .wotd { flex-direction: column; } - .wotd-half + .wotd-half { border-left: none; border-top: 1px solid #e6ddc9; } + .joys { grid-template-columns: 1fr; } }