feat(posts): plain bold titles; reserve View-original to the post card; provenance links to the posts feed

- Post titles arrived as stored HTML (e.g. <strong>…</strong>) rendering as
  literal markup. New toPlainText() strips tags; titles render plain + bold
  (ProvenancePanel and PostCard).
- Removed "View original post" from the provenance panel (modal) — the
  open-original button lives on the PostCard (the post view).
- Provenance "View post" now navigates to the /posts feed (post_id query),
  not the gallery image grid. (Feed in-context landing lands next.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-28 18:18:34 -04:00
parent 42ddac9996
commit 75b6b8056e
3 changed files with 34 additions and 15 deletions
+11 -7
View File
@@ -56,8 +56,8 @@
</div>
<div class="fc-post-card__text">
<h3 v-if="post.post_title" class="fc-post-card__title">
{{ post.post_title }}
<h3 v-if="plainTitle" class="fc-post-card__title">
{{ plainTitle }}
</h3>
<h3 v-else class="fc-post-card__title fc-post-card__title--missing">
Post {{ post.external_post_id }}
@@ -80,8 +80,8 @@
<!-- Expanded body: title, full mosaic, full sanitized HTML description,
attachments. Lazy-loaded detail via getPostFull. -->
<div v-else class="fc-post-card__expanded">
<h2 v-if="post.post_title" class="fc-post-card__title-full">
{{ post.post_title }}
<h2 v-if="plainTitle" class="fc-post-card__title-full">
{{ plainTitle }}
</h2>
<h2 v-else class="fc-post-card__title-full fc-post-card__title--missing">
Post {{ post.external_post_id }}
@@ -125,7 +125,7 @@ import { computed, ref } from 'vue'
import { RouterLink } from 'vue-router'
import { usePostsStore } from '../../stores/posts.js'
import { sanitizeHtml } from '../../utils/htmlSanitize.js'
import { sanitizeHtml, toPlainText } from '../../utils/htmlSanitize.js'
import PostEmptyThumbs from './PostEmptyThumbs.vue'
import PostImageGrid from './PostImageGrid.vue'
@@ -149,6 +149,10 @@ const merged = computed(() => detail.value || props.post)
const images = computed(() => merged.value.thumbnails || [])
const attachments = computed(() => merged.value.attachments || [])
// Titles can arrive as stored HTML (e.g. "<strong>…</strong>"); render as
// plain text — the CSS makes the title bold.
const plainTitle = computed(() => toPlainText(props.post.post_title))
// Compact-view hero+rail derived from the feed-shape (capped 6).
const hero = computed(() => props.post.thumbnails?.[0])
const rail = computed(() => (props.post.thumbnails || []).slice(1, 4))
@@ -312,7 +316,7 @@ function formatBytes (n) {
.fc-post-card__title {
font-family: 'Fraunces', Georgia, serif;
font-size: 18px; font-weight: 500;
font-size: 18px; font-weight: 700;
margin: 0 0 8px 0;
color: rgb(var(--v-theme-on-surface));
display: -webkit-box;
@@ -369,7 +373,7 @@ function formatBytes (n) {
.fc-post-card__title-full {
font-family: 'Fraunces', Georgia, serif;
font-size: 22px;
font-weight: 500;
font-weight: 700;
margin: 0;
color: rgb(var(--v-theme-on-surface));
}