Commit Graph

5 Commits

Author SHA1 Message Date
thejayman77 d8d665ee35 Crisp hero (prefer og:image), 7-card Highlights, no-recycle Replace + session History
- Hero blur fix: brief enrichment now prefers a page's og:image even when a
  feed thumbnail exists (feed thumbs are often tiny; the hero is shown large).
  Verified: BBC hero upgrades to the 1024px share image, ScienceDaily to 1920px.
- Today is now 'Highlights from Today' — hero + 6 (brief size 7), which also
  makes the secondary grid a balanced 3+3 instead of an orphaned 3+1.
- Replace now excludes every article seen this session (a client-side seen-set),
  so it never cycles back to something already shown.
- New session History panel (this tab only, no account): lists everything seen,
  including swapped-away stories, so they stay recoverable. Persistent
  history/favorites are tabled for sign-in later.

Tests: og:image upgrade of an existing feed image (86 total).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 12:56:57 +00:00
thejayman77 bfd612eb9b Paywall awareness (#6) + replace-an-article (#7)
- paywall.py: conservative domain-level paywall detection (New Scientist,
  Nature, and common hard/soft paywalls). Never fetches pages — an honest hint.
- API: Article gains a 'paywalled' flag; the brief now leads with a gentle AND
  readable story (paywalled/charged stories stay in the five, just not first).
- New GET /api/replacement returns the next-best readable, unshown article
  (honors mood+prefs via the merged prefs param; gentle=true for hero swaps).
- UI: paywalled cards show 'May need a subscription'; a Replace / 'Find one I
  can read' action (always visible, while tuning actions stay tucked) swaps the
  card for a readable alternative, with a gentle notice when none remain.
- Tests: paywall detection + replacement behavior (77 total).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:39:13 +00:00
thejayman77 06c2704ae0 Home: Today shows only the five; categories behind mood selection; big view heading
- Today is just the day's five highlights (hero + four) — the preview lanes are
  gone; other categories appear only when their mood is selected.
- Each view leads with a large serif heading (Today / Wonder / ...) and a
  subtitle, with a quiet sage rule — switching moods retitles the page.
- Drop the now-unused Lane usage from the home.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:22:34 +00:00
thejayman77 b9ecebffde Add Boundaries panel to the UI: precise personal avoid-terms first
- New BoundariesPanel.svelte: gentle, device-local controls. Avoid words/phrases
  first (the trust-critical piece), then 'Paused for now' and 'Always hidden',
  each with easy remove. Reassures 'nothing leaves this device'; adding a term
  refreshes the brief/feed immediately.
- Quiet 'Boundaries' toggle (active indicator) replaces the old calm bar, keeping
  the first viewport calm.
- Wording stays gentle throughout: avoid / pause / hide / boundaries — never
  blocked/banned/blacklist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 22:50:11 +00:00
thejayman77 5601022cf7 Build the SvelteKit frontend: calm home with mood modes
- New frontend/ SvelteKit static SPA (Svelte 5), served by FastAPI from
  frontend/build (falls back to the legacy page if unbuilt).
- Calm design system: cream/sage palette, serif headlines, generous space,
  no urgency colors, gentle motion (respects prefers-reduced-motion).
- Home screen: mood-mode nav (Today/Wonder/People Helping/Solutions/Light
  Only/Grounded), the daily brief as a hero + remaining four, browsable mood
  lanes, an explicit calm end-state, inline Not today / Less like this / Hide
  affordances, and device-local Calm Filters mirroring goodnews/filters.py.
- Backend: moods.py + GET /api/moods (single source of truth for the modes);
  FilterPrefs gains max_cortisol/max_ragebait ceilings (for Light Only).
- Push categorical filters (include/mute topics+flavors, ceilings) into SQL in
  queries.feed so low-ranked-but-matching items (e.g. discovery for Wonder)
  are not truncated by ranking; only avoid-terms stay a Python pass.
- PWA manifest + icon (installable; offline deferred per plan).
- Multi-stage Dockerfile builds the site then serves it from the API.
- Tests: queries.feed categorical filters (63 total). README updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 22:27:46 +00:00