Replace direct post.isEvent/eventDate/eventLocation reads with
getPostEventInfo() helper that derives info from the resolved
calendarItem reference. Loaders now resolve "calendarItem" and request
that field instead of legacy flat properties.
Also regenerate iconify mdi subset (map-marker-outline, download,
google, calendar-search, refresh).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Palette: gray/zinc/slate/neutral → stein, red → fire, amber → erde,
sky → himmel, green → wald
- Footer: replaced raw rgb with stein tokens
- Radius: unified to rounded-xs across cards, buttons, inputs, pagination
- Buttons: .btn-primary/.btn-secondary now font-medium; added secondary
- Card hover: -translate-y-0.5 + shadow + wald-300 border
- Header active link: wald border-bottom + wald-700 text
- Mobile nav: bigger touch targets + wald active accent
- Pagination: prev/next text labels + wald-500 active state with
separated shape/color classes to avoid Tailwind conflicts
- Lead paragraph: scoped .markdown > p:first-child for top-level
MarkdownBlock only via [data-block-type="markdown"]
- Section dividers: subtle wald-200 gradient between content rows
- Global focus-visible ring (wald-500)
- Inline hex → palette tokens (Badge amber, Tag custom-color contrast)
- Font weights snapped to design system (300/400/500/600/700)
- transition-all → transition-colors where only color changes
- Removed em-dashes from user-visible templates
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The plain `<time>` was visually weak next to the headline. Reuse the
`EventBadges` component from the post card so the date renders as a
proper wald-tinted pill — same shape as event posts. Drops the local
`formatEventDate` since EventBadges does the localization itself
(weekday + time included, matching post cards).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`main ul:not(.not-prose) li` injects a disc bullet on every list under
`main`, which the upcoming-events list inherited. Mark the ul `not-prose`
+ `list-none` so the rule doesn't match. Also bump the calendar-clock
icon from `h-4 w-4` to `size-5` so it visually matches the heading
ascender.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Hides Header / HeaderOverlay / Footer / TopBanner / Breadcrumbs and
the comment accordion when printing. Action toolbar already had
`print:hidden`.
- Adds @media print rules in app.css: 1.5cm page margins, 11pt body,
forced black-on-white, expand link URLs after anchor text inside
articles, keep images and headings together at page breaks.
- PostCard now renders the count pill whenever a value is known (incl.
zero); previously hidden for `count === 0`, so posts whose comments
are still pending always looked empty.
- Extracts the bulk-fetch helper to `lib/comment-counts.ts`
(`fetchCommentCounts` + `postSlugForComments`) and uses it from both
`BlogOverview` and `PostOverviewBlock`. Homepage / any page with a
post_overview block now shows the badges too — previously only the
paginated /posts/* routes did.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PostCard now shows a small comment-count pill in the top-left of the
image when count > 0. BlogOverview bulk-fetches counts for the visible
posts via the new `/api/comments/counts?ids=…` endpoint and passes
them down. One request per page render, regardless of card count.
- New helper `getCommentCounts()` in `cms.ts`
- `BlogOverview.svelte` derives slugs from posts, fires bulk fetch
in `$effect`, hands the result map to `PostCard`
- `PostCard.svelte` accepts `commentCount?: number | null`, renders
pill only when value is a positive number
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Set trailingSlash='always' globally via root layout.
- Update postHref, pageHref, Pagination, tag/breadcrumb hrefs, blog→posts
redirects to emit trailing slash.
- Match old Astro canonical so indexed URLs hit 200 directly instead of
308-redirect.