2.9 KiB
Context
The site renders multiple card-like UI elements today:
- videos/podcast listings use
site/src/components/ContentCard.astro - blog listings use
site/src/components/BlogPostCard.astro
These cards have different layouts and metadata placement. This change standardizes the card information architecture so all cards feel consistent.
The site is statically generated (Astro). Card layout consistency should be enforced primarily through shared components and shared CSS rather than copy/paste per page.
Goals / Non-Goals
Goals:
- Define and implement a single, consistent card structure:
- media (image/placeholder) at top
- title
- trimmed summary/excerpt
- meta row: date (left) + views (right, if available)
- footer: source label (youtube/podcast/blog/etc.)
- Apply to all existing card surfaces:
/videoslisting cards/podcastlisting cards/blogpost cards (and category listings)
- Keep the layout resilient when fields are missing (no views, no image, no summary).
Non-Goals:
- Redesigning non-card list links (e.g., simple navigation links) into cards unless needed for consistency.
- Changing Umami tracking taxonomy (attributes stay intact).
- Large typographic or theme redesign beyond card structure/spacing.
Decisions
-
Decision: Implement a shared Card component used by existing card components.
- Rationale: Centralizes markup and ensures layout stays consistent across surfaces.
- Approach:
- Create a new component (e.g.,
Card.astro) with props for:href,title,summary,imageUrl,dateLabel,viewsLabel,sourceLabel- optional tracking attributes pass-through (keep existing
data-umami-*behavior)
- Update
ContentCard.astroandBlogPostCard.astroto render the shared Card component.
- Create a new component (e.g.,
-
Decision: Add an optional
summaryfield to normalized items.- Rationale: Enables the standard card layout to show trimmed summaries for videos/podcast, similar to blog excerpts.
- Approach:
- Extend the normalized content schema/types with
summary?: string. - Populate it during ingestion where available (YouTube description snippet; podcast episode summary/description).
- Extend the normalized content schema/types with
-
Decision: Views are optional and shown only when available.
- Rationale: Not all sources provide views; the layout should be consistent without forcing synthetic values.
Risks / Trade-offs
-
[Risk] Ingestion sources may provide very long summaries.
- Mitigation: Standardize trimming logic in the card component (single truncation helper).
-
[Risk] CSS regressions across multiple pages.
- Mitigation: Add tests that assert key card structure/classes exist; verify build outputs for
/videos,/podcast,/blog.
- Mitigation: Add tests that assert key card structure/classes exist; verify build outputs for
-
[Risk] Blog post cards and content cards have different link targets (internal vs outbound).
- Mitigation: Shared Card component should be able to render both internal links and external links (target/rel configurable).