Summary briefing layer: Today pre-summarized, /a is the canonical read
Make summaries the core reading experience (summary-first, source-forward): - Cycle pre-warms summaries for Today's 7 (idempotent → only new ones hit the LLM). - /api/brief items carry their cached summary; Today cards (hero + tiles) show it inline, so Today reads as a calm briefing. - Card title/image now open the /a summary page (the canonical artifact), with a visible "Full story" link straight to the source on every card (the escape hatch). - /a gains related-grouping chips + a Copy-link/share control. - Tighten the summary prompt: original, factual, no quotations / no close paraphrase. Long tail stays lazy+cached. No article bodies stored. 129 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,12 @@
|
||||
let safeHref = $derived(
|
||||
typeof article.url === 'string' && /^https?:\/\//.test(article.url) ? article.url : '#'
|
||||
);
|
||||
// Default click → our summary page (the calm gist). Source is one tap further.
|
||||
let summaryHref = $derived('/a/' + article.id);
|
||||
function openedSource() {
|
||||
onview?.(article);
|
||||
track('open', article.id);
|
||||
}
|
||||
|
||||
function act(kind, value) {
|
||||
if (value) onaction?.(kind, value);
|
||||
@@ -87,7 +93,7 @@
|
||||
data-topic={article.topic ?? ''}
|
||||
>
|
||||
{#if showImage}
|
||||
<a class="media" href={safeHref} target="_blank" rel="noopener" onclick={opened}>
|
||||
<a class="media" href={summaryHref} onclick={opened}>
|
||||
<img src={article.image_url} alt="" loading="lazy" referrerpolicy="no-referrer"
|
||||
onerror={() => { failed = true; onimageerror?.(); }} />
|
||||
</a>
|
||||
@@ -108,9 +114,11 @@
|
||||
</div>
|
||||
<div class="src">{article.source}</div>
|
||||
|
||||
<h3><a href={safeHref} target="_blank" rel="noopener" onclick={opened}>{article.title}</a></h3>
|
||||
<h3><a href={summaryHref} onclick={opened}>{article.title}</a></h3>
|
||||
|
||||
{#if hero && article.description}
|
||||
{#if article.summary}
|
||||
<p class="summary">{article.summary}</p>
|
||||
{:else if hero && article.description}
|
||||
<p class="desc">{article.description}</p>
|
||||
{/if}
|
||||
|
||||
@@ -133,10 +141,11 @@
|
||||
{isSaved ? 'Saved' : 'Save'}
|
||||
</button>
|
||||
{/if}
|
||||
<a class="source" href={safeHref} target="_blank" rel="noopener" onclick={openedSource}>
|
||||
{article.paywalled ? 'Full story 🔒' : 'Full story'}
|
||||
</a>
|
||||
{#if onreplace}
|
||||
<button class="replace" onclick={() => onreplace(article)}>
|
||||
{article.paywalled ? 'Find one I can read' : 'Replace'}
|
||||
</button>
|
||||
<button class="replace" onclick={() => onreplace(article)}>Replace</button>
|
||||
{/if}
|
||||
<span class="sharewrap">
|
||||
<button class="share" onclick={() => { shareOpen = !shareOpen; if (shareOpen) warmSummary(); }} aria-expanded={shareOpen}>Share</button>
|
||||
@@ -206,6 +215,11 @@
|
||||
h3 { font-size: 1.18rem; }
|
||||
h3 a:hover { color: var(--accent-deep); }
|
||||
.desc { margin: 2px 0 0; color: #3b4754; }
|
||||
.summary { margin: 2px 0 0; color: var(--ink); font-size: 0.92rem; }
|
||||
.tile .summary {
|
||||
display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; -webkit-line-clamp: 5;
|
||||
}
|
||||
.hero .summary, .herotype .summary { font-size: 1rem; }
|
||||
.paywall {
|
||||
margin: 0; font-size: 0.78rem; color: var(--gold);
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
@@ -235,6 +249,11 @@
|
||||
color: var(--accent-deep); border-bottom-color: var(--accent-soft);
|
||||
}
|
||||
.actions .save.on { color: var(--accent); }
|
||||
.actions .source {
|
||||
color: var(--accent-deep); text-decoration: none; font-size: 0.76rem;
|
||||
border-bottom: 1px dotted var(--accent-soft);
|
||||
}
|
||||
.actions .source:hover { border-bottom-color: var(--accent); }
|
||||
.actions .share { color: var(--accent-deep); border-bottom-color: var(--accent-soft); }
|
||||
.sharewrap { position: relative; display: inline-flex; }
|
||||
.sharemenu {
|
||||
|
||||
Reference in New Issue
Block a user