# 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).
