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 @@