Files
CWC/docs/superpowers/specs/2026-07-05-blog-post-card-design.md

129 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 with `git add -f` per project convention.
- PHPCS uses the WordPress coding standard; `composer lint` must 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.php` are explicitly **out of scope** for this change. The working tree currently has the H1 removed and `search.php` untouched; 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 `#90c9e7` background. 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`):
```html
<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:
1. **`.post-list__post`** — Override the gray `border-secondary` so the card border disappears (the blue background extends edge-to-edge inside the card). Keep the rounded corners and shadow. The current classes in `index.php` set `border border-secondary`; we override via CSS to `border-color: var(--color-cwc-blue-03)`.
2. **`.post-list__post`** and **`.post-list__img`** — Set `border: 0` (or `border-color: transparent`) on the figure so the existing `border-b border-secondary` does 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 its `rounded-md` corners; the figure keeps `rounded-t-md` so the image rounds with the card.
3. **`.post-list__title`** — Set `color: var(--color-cwc-blue-01)`, `font-weight: 700` (override the `font-normal` in the markup). Keep the existing `text-25px` size and `line-clamp-4` truncation. The title is the project's standard H2 typography.
4. **`.post-list__byline`** — Set `color: var(--color-cwc-blue-01)`, `font-size: 0.875rem` (smaller than the title, but readable on the blue background). Keep `mt-auto` so the byline sits at the bottom of the available space.
5. **`.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:
```html
<a class="post-list__read-more" href="<?php the_permalink(); ?>">Read more &rarr;</a>
```
No other markup changes. The title link, image, byline, and pagination are untouched.
### What stays the same
- Card structure: `figure` for image, `div.post-list__details` for 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-110` with `duration-500` transition.
- Empty state ("Nothing here yet…").
- Pagination.
- Card padding: `px-4 py-6` on `.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`:
```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 (commit `cb0c886`); 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 `$featimg` case-sensitivity bug. Separate work.
- `static/dist/theme.css` pre-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).