7.7 KiB
Blog Post Card Styling Design
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Restyle the blog post card to match blog-post-card.png — a vertical card with a featured image on top and a solid blue content area below containing the title, byline, and a "Read more" link in orange.
Architecture: A targeted CSS update to styles/components/post-list.css (the card body, title, byline, and a new .post-list__read-more rule), and a one-line markup addition in index.php to render the "Read more" anchor. No template structure changes. No new Playwright tests beyond a single new assertion in the existing tests/blog-page.spec.js.
Tech Stack: WordPress 6.x, PHP 8.x, Tailwind CSS v4, Playwright, axe-core, PHPCS (WordPress standard).
Global Constraints
- Tabs for PHP indentation (project standard).
- The theme's Tailwind build outputs
static/dist/theme.css; that file is gitignored but committed withgit add -fper project convention. - PHPCS uses the WordPress coding standard;
composer lintmust pass. Pre-existing CRLF errors on untouched files are out of scope. - All design colors use the project's existing CSS custom properties from
styles/base/colors.css. No hardcoded hex values for theme colors. - The card width behavior stays the same:
grid-cols-[repeat(auto-fit,minmax(20rem,1fr))]. No layout refactor. - The "Read more" link reuses the post's permalink — it's the same destination as the title link.
- The H1 ("Blog" page title) and
search.phpare explicitly out of scope for this change. The working tree currently has the H1 removed andsearch.phpuntouched; this design does not address either.
Reference Mockup
blog-post-card.png (426×644, vertical 2:3) at the theme root. The mockup shows:
- Image area (top ~38%): light gray placeholder. Real implementation uses the post's featured image via
has_post_thumbnail(). - Content area (bottom ~62%): solid
#90c9e7background. This color is the hex equivalent of--color-cwc-blue-03(oklch(80.63% 0.0724 230.4)). - Title: multi-line, dark blue text (matches
--color-cwc-blue-01). - Byline: smaller dark text near the bottom of the content area.
- "Read more" link: orange (
#d24d32, matches--color-secondary/--color-cwc-orange-01) at the bottom-left of the card.
File Structure
| File | Responsibility | Created/Modified |
|---|---|---|
styles/components/post-list.css |
Add card body, title, byline, and .post-list__read-more styles. |
Modify |
index.php |
Add a "Read more" link after the byline in .post-list__details. |
Modify |
static/dist/theme.css |
Rebuilt via npm run build. |
Modified (committed with git add -f). |
tests/blog-page.spec.js |
Add a single assertion that the "Read more" link exists in the first card. | Modify |
Design Details
CSS additions to styles/components/post-list.css
The card already has the following structure (from index.php):
<div class="post-list__post flex flex-col border border-secondary rounded-md shadow-lg ...">
<figure class="post-list__img aspect-video border-b border-secondary rounded-t-md ...">
<img class="...">
</figure>
<div class="post-list__details px-4 py-6 flex flex-col grow">
<a href="..."><h2 class="post-list__title ...">Title</h2></a>
<div class="post-list__byline mt-auto">
<span class="post-list__author">Author</span>
<span class="post-list__date">Date</span>
</div>
</div>
</div>
The styling changes:
-
.post-list__post— Override the grayborder-secondaryso the card border disappears (the blue background extends edge-to-edge inside the card). Keep the rounded corners and shadow. The current classes inindex.phpsetborder border-secondary; we override via CSS toborder-color: var(--color-cwc-blue-03). -
.post-list__postand.post-list__img— Setborder: 0(orborder-color: transparent) on the figure so the existingborder-b border-secondarydoes not show. The visual change is that the image and the blue content area flow as separate blocks without a divider line between them. The card itself keeps itsrounded-mdcorners; the figure keepsrounded-t-mdso the image rounds with the card. -
.post-list__title— Setcolor: var(--color-cwc-blue-01),font-weight: 700(override thefont-normalin the markup). Keep the existingtext-25pxsize andline-clamp-4truncation. The title is the project's standard H2 typography. -
.post-list__byline— Setcolor: var(--color-cwc-blue-01),font-size: 0.875rem(smaller than the title, but readable on the blue background). Keepmt-autoso the byline sits at the bottom of the available space. -
.post-list__read-more(new) —color: var(--color-secondary),font-weight: 600,margin-top: 0.75rem,text-decoration: none. Hover: underline. The text content is "Read more →" (em dash and arrow, no period).
Markup change in index.php
Inside .post-list__details, after the .post-list__byline div, add:
<a class="post-list__read-more" href="<?php the_permalink(); ?>">Read more →</a>
No other markup changes. The title link, image, byline, and pagination are untouched.
What stays the same
- Card structure:
figurefor image,div.post-list__detailsfor content. - Grid layout:
grid-cols-[repeat(auto-fit,minmax(20rem,1fr))] gap-6. - Image aspect ratio:
aspect-video(16:9). - Image hover effect:
hover:prose-img:scale-110withduration-500transition. - Empty state ("Nothing here yet…").
- Pagination.
- Card padding:
px-4 py-6on.post-list__details. - The H1 /
search.php/ sidebar — all untouched.
Test updates
Add a single assertion to the desktop test in tests/blog-page.spec.js:
// First card has a "Read more" link.
await expect(firstCard.locator(".post-list__read-more")).toBeVisible();
await expect(firstCard.locator(".post-list__read-more")).toHaveAttribute(
"href",
/\/[a-z0-9-]+\/?$/
);
No new spec file. The existing 4 tests stay as they are.
Out of Scope
- The H1 page title — the working tree currently has the H1 markup removed. The previous blog plan added it (commit
66073c0) and the design tokens (commitcb0c886); both are present in git history. Whether to re-add the H1 is a separate decision. search.php— still a separate template, still has the old card structure, still has the$featimgcase-sensitivity bug. Separate work.static/dist/theme.csspre-existing changes from other work in the working tree (header.php,views/partials/page-hero-services.php, etc.) are unrelated and not touched.- Dark mode.
- Animations on the "Read more" link beyond a basic underline-on-hover.
- The H2 font family (Quincy vs sans) — the existing card uses the default font family for the title. The mockup's title appears to be a clean sans-serif weight-700. We do not change the font family.
Self-Review Notes
- Spec coverage: One CSS file, one PHP file, one test file, one dist rebuild. Every spec section is covered.
- Placeholder scan: No "TBD", "TODO", or vague requirements. The "→" arrow and "Read more" text are spelled out explicitly.
- Type consistency: Class names follow the existing BEM convention (
__read-more). - Spec section "Out of Scope" is explicit: H1, search.php, dark mode, font family changes, animations — all out.
- Design tokens: All colors reference existing CSS custom properties. No new colors introduced.
- Indentation: Tabs for PHP (project standard).