From b172c5eefd6354e22b39e267811a7a166b6366b9 Mon Sep 17 00:00:00 2001 From: jay Date: Sun, 21 Jun 2026 19:46:51 -0400 Subject: [PATCH] home2 round 2: Manrope nav, bigger logo, photo-top news / photo-left art, tinted static cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Self-hosted Manrope (OFL) as the hub sans; nav lighter (weight 500, soft slate, not all "on"). Logo up to 58px. - News card: photo on top + headline below, and it now respects the reader's saved Closer-to-Home filter (goodnews:home/homeScope) so the headline matches their Brief. - Art card: rectangular cover-cropped thumbnail on the LEFT (crops ragged scan edges), text on the right — variety against the photo-top news card. - Play/Daily Moment: tinted backgrounds, bigger centered icon+title, blurb left-aligned. - /fonts/* + /textures/* served immutable (Caddy live + snapshot). Co-Authored-By: Claude Opus 4.8 --- deploy/caddy/Caddyfile.snapshot | 9 +- frontend/src/lib/components/RoomCard.svelte | 122 ++++++++++++-------- frontend/src/lib/rooms.js | 2 + frontend/src/routes/home2/+page.svelte | 37 ++++-- frontend/static/fonts/CREDITS.txt | 3 + frontend/static/fonts/manrope-var.woff2 | Bin 0 -> 24836 bytes 6 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 frontend/static/fonts/CREDITS.txt create mode 100644 frontend/static/fonts/manrope-var.woff2 diff --git a/deploy/caddy/Caddyfile.snapshot b/deploy/caddy/Caddyfile.snapshot index 3d9450f..e5025a2 100644 --- a/deploy/caddy/Caddyfile.snapshot +++ b/deploy/caddy/Caddyfile.snapshot @@ -62,10 +62,10 @@ upbeatbytes.com { @immutable path /_app/immutable/* header @immutable Cache-Control "public, max-age=31536000, immutable" - # Static texture assets (frame wood grain, etc.) — large and unchanging. Cache - # them forever like immutable assets; rename the file if the texture ever changes. - @textures path /textures/* - header @textures Cache-Control "public, max-age=31536000, immutable" + # Static texture + font assets — large/unchanging. Cache them forever like + # immutable assets; rename the file if one ever changes. + @assets path /textures/* /fonts/* + header @assets Cache-Control "public, max-age=31536000, immutable" # The SPA shell: "/" and extensionless client routes (try_files → index.html). # Briefly cacheable at the CDN edge (s-maxage) so a first paint never depends @@ -86,6 +86,7 @@ upbeatbytes.com { @revalidate { not path /_app/immutable/* not path /textures/* + not path /fonts/* path *.* } header @revalidate Cache-Control "no-cache" diff --git a/frontend/src/lib/components/RoomCard.svelte b/frontend/src/lib/components/RoomCard.svelte index 1c8e2bb..5427bab 100644 --- a/frontend/src/lib/components/RoomCard.svelte +++ b/frontend/src/lib/components/RoomCard.svelte @@ -1,72 +1,104 @@ - - {#if room.preview === 'art' && artImg} -
- {/if} +
+ {#if room.preview === 'news'} + {#if newsImg}
{/if} +
+
{room.icon}{room.title}
+ {#if newsHeadline}

“{newsHeadline}”

{:else}

{room.blurb}

{/if} + {room.cta} +
-
-
{room.icon}{room.title}
- - {#if room.preview === 'news' && newsHeadline} -

“{newsHeadline}”

- {:else} + {:else if room.preview === 'art'} + {#if artImg}
{/if} +
+
{room.icon}{room.title}

{room.blurb}

- {/if} + {room.cta} +
- {room.cta} -
+ {:else} +
+ {room.icon} + {room.title} +
+
+

{room.blurb}

+ {room.cta} +
+ {/if}
diff --git a/frontend/src/lib/rooms.js b/frontend/src/lib/rooms.js index 18f8d6b..3180f29 100644 --- a/frontend/src/lib/rooms.js +++ b/frontend/src/lib/rooms.js @@ -32,6 +32,7 @@ export const ROOMS = [ size: 'small', preview: 'static', icon: '🎲', + tint: '#e9f1f9', // soft sky }, { id: 'moment', @@ -42,5 +43,6 @@ export const ROOMS = [ size: 'small', preview: 'static', icon: '🌿', + tint: '#eaf4ea', // soft sage }, ]; diff --git a/frontend/src/routes/home2/+page.svelte b/frontend/src/routes/home2/+page.svelte index 2d9f413..87e736d 100644 --- a/frontend/src/routes/home2/+page.svelte +++ b/frontend/src/routes/home2/+page.svelte @@ -8,12 +8,21 @@ // promote to / and remove this clone — same approach we used for /art. let artImg = $state(null); let newsHeadline = $state(''); + let newsImg = $state(null); onMount(async () => { try { artImg = (await getJSON('/api/art/today'))?.image_url ?? null; } catch { /* card falls back to blurb */ } + // Respect the reader's saved Closer-to-Home filter so the headline matches their Brief. + let homeq = ''; try { - const b = await getJSON('/api/brief?limit=1'); - newsHeadline = b?.items?.[0]?.title ?? ''; + const hv = localStorage.getItem('goodnews:home') || ''; + const hs = localStorage.getItem('goodnews:homeScope') || 'nearby'; + if (hv && hs !== 'world') homeq = `&home=${encodeURIComponent(hv)}&scope=${hs}`; + } catch { /* default global brief */ } + try { + const it = (await getJSON(`/api/brief?limit=1${homeq}`))?.items?.[0]; + newsHeadline = it?.title ?? ''; + newsImg = it?.image_url ?? null; } catch { /* card falls back to blurb */ } }); @@ -51,7 +60,7 @@
{#each ROOMS as r (r.id)} - + {/each}
@@ -60,24 +69,36 @@