diff --git a/docs/superpowers/specs/2026-08-16-portfolio-2026-design.md b/docs/superpowers/specs/2026-08-16-portfolio-2026-design.md new file mode 100644 index 0000000..f80f0a8 --- /dev/null +++ b/docs/superpowers/specs/2026-08-16-portfolio-2026-design.md @@ -0,0 +1,240 @@ +--- +name: Portfolio 2026 Theme Design +description: Surface overhaul, conflict resolution, and template build-out for the ks-portfolio WordPress theme. +created: 2026-08-16 +status: approved +--- + +# Portfolio 2026 Theme — Design Spec + +## 1. Purpose + +Rebuild the surface of `ks-portfolio` (WordPress theme at `wp-content/themes/ks-portfolio/`) to match the **Portfolio 2026** identity defined in `notes/DESIGN.md`, `notes/TOKENS.md`, and the three mockups (`home-screen.png`, `archive-screen.png`, `single-screen.png`). Resolve the documented conflicts in `notes/DESIGN.md` §12. Keep the SoloFrame Evo architecture and the installed `projects-portfolio` plugin as-is; build only the presentation layer. + +## 2. Source hierarchy + +When sources disagree, follow `notes/DESIGN.md` §1. In short: + +1. `style.css` for current identity. +2. `notes/Projects Plugin Design.md` for content model. +3. `notes/Background Gradient.md` for atmospheric field. +4. `theme.json`, `styles/`, ACF JSON, templates for implemented tokens. +5. `README.md` and `docs/` for inherited architecture. + +User decisions (locked at brainstorm time): + +- **Projects source**: theme renders templates against the `projects` CPT provided by the installed `projects-portfolio` plugin. The theme does NOT re-register the CPT. +- **Mockup content**: live `projects` CPT with empty-state fallbacks ("Nothing here yet..."). The mockups are layout references, not content sources. +- **Test scope**: Chromium + axe only. Firefox / WebKit / mobile are out of scope. +- **Pen-test**: static security audit (PHPCS + grep + manual review). No OWASP ZAP. + +## 3. Identity & naming + +- `style.css` keeps `Theme Name: Portfolio 2026`, `Text Domain: ks-portfolio`. +- PHP namespace `SoloFrameEvo` → `KsPortfolio` across all PHP files (composer script + manual review). +- Drop `screenshot.png` (Basic WP) at the end; replace with a Carbon-Blue-themed capture. + +## 4. Visual system + +### 4.1 Body surface + +```css +body { + background-color: #100e0b; /* Carbon Blue page base */ + color: var(--color-on-surface); /* #e3e1e9 — ~14:1 on dark */ +} +``` + +The existing rule `main#maincontent { background: var(--color-background); }` is removed. Sections paint directly on the dark body; there is no light block underneath content. + +### 4.2 Carbon Blue atmospheric field + +Implemented as a `views/partials/aura-bg.php` partial loaded on the home and project archive templates (per mockup: dark atmospheric field on hero surfaces, plain dark surface elsewhere). + +- Layer 1: linear 138deg `#05070c → #0f172a → #172554 → #1e3a8a`. `mix-blend-mode: normal`. `transform: translateZ(0)`. +- Layer 2: radial ellipse `45% 50% at 72% 40%`, `rgba(96,165,250,0.20)` → transparent 68%. `mix-blend-mode: screen`. `filter: blur(105px)` mobile, `151px` desktop. +- Layer 3: inline SVG `feTurbulence baseFrequency="0.7" numOctaves="4" stitchTiles="stitch"`, `mix-blend-mode: overlay`, `opacity: 0.85`. +- All three: `position: absolute; inset: 0;`, `pointer-events: none;`, `aria-hidden="true"`. +- Parent container: `position: relative; overflow: hidden; min-height: 100vh;` with NO `background-color` (per the blend-mode architecture warning in `notes/Background Gradient.md`). +- Content wrapper: `position: relative; z-index: 1`. + +### 4.3 Tokens + +Resolve the unresolved tokens from `notes/DESIGN.md` §12: + +- Define `--font-headings: var(--font-sans)` in `styles/base/typography.css`. +- Update `theme.json` `styles` block to reference the existing palette slugs (`theme-bg`, `theme-text`) — currently references `background` / `text` which don't exist. +- Add Carbon-Blue editor palette entries in `theme.json`: `theme-surface` (#121318), `theme-on-surface` (#e3e1e9), `theme-outline` (#8f909d), `theme-outline-variant` (#444651), `theme-primary` (#b6c4ff), `theme-on-primary` (#05297a). +- Add 100–900 mix tokens for `theme-primary` if not already present. +- Remove legacy hex values (`#3857BC`, `#ddd`) from pagination CSS; replace with `var(--color-outline-variant)` / `var(--color-primary)`. + +Keep the implemented light tokens in `styles/base/colors.css` for any block-editor surface that still wants light, but default new portfolio-facing CSS to the dark surface. + +## 5. Template → mockup mapping + +### 5.1 `front-page.php` — matches `notes/home-screen.png` + +- Header: `WP_DEV_2026` logo, top nav (Plugins, Themes, Open Source, Documentation, Blog), `Download CV` button (right-aligned). +- Hero on Carbon Blue: heading + intro + two CTAs (`Download CV`, `View Repositories`) pulled from ACF Homepage Hero fields. No hardcoded sample text. +- "Recent Projects" section: queries `projects` CPT, max 3, rendered as 3-column grid on `lg`, single column on mobile. + - Each card: type badge (Plugin / Theme / Pattern), title, excerpt, `Download` + `View Repo` links when both URLs exist (provider-agnostic labels). +- Empty state when zero published projects: "Nothing here yet..." + "No published projects found." centered in the grid area. +- Footer: copyright + GitHub / Privacy / License / Site Status links. + +### 5.2 `archive-projects.php` (new) — matches `notes/archive-screen.png` + +- Hero: `Project Archive` heading + intro from ACF option (or page-derived intro). +- Grid: project cards 3-up on `lg`, 2-up on `md`, 1-up on mobile. +- Each card: type label (PLUGIN / THEME FRAMEWORK / INTEGRATION, uppercase tracking-wide), title, excerpt, language pill + star count, `View Repo →` link. +- Pagination via `the_posts_pagination` styled against dark surface. + +### 5.3 `single-projects.php` (new) — matches `notes/single-screen.png` + +- Hero: provider icon + type pill, project title + version suffix (from `projects_portfolio_get_latest_version()`), excerpt. +- Primary `Download vX.Y.Z` button + secondary `View Repo` link. +- Two-column body below: featured image / project content on the left; sidebar (Maintainer, Repository Details table, four stat cards) on the right. +- Owner avatar: 40px square using `background-image` with explicit `width: 40px; height: 40px; background-size: 40px 40px;` (per `notes/Projects Plugin Design.md` §9 — host CSS quirk workaround). +- Below columns: `Architecture & Implementation` (post body content), `Key Features` (list), `Installation` (code block) — all from WordPress content. + +### 5.4 `taxonomy-project-type.php` (new) + +- Same template as `archive-projects.php` with taxonomy-aware title: `

{project-type label}

` plus a back link to the full archive. + +### 5.5 Other templates + +- `index.php` (post archive), `search.php`, `single.php` (post), `page.php`, `404.php`: keep structure, recolor surfaces to dark, remove `picsum.photos` fallback URLs, ensure empty-state copy matches existing `Nothing here yet...` / `No published posts found.` / `Page Not Found` patterns. +- Keep `Resources` CPT and `resource_type` taxonomy styling independent from `projects`. + +## 6. Components + +### 6.1 Buttons + +Keep the existing token-driven button block (Primary / Secondary / White / Black × Default / Outline × Small / Medium / Large × Auto / Small / Wide / Full Width). The Primary button in the mockup maps to the existing default-styled Primary button (3px border, semibold 16px, 200ms transitions, focus outline offset, 99% active press). + +### 6.2 Project card + +New `views/components/project-card.php`: + +- Border `1px solid var(--color-outline-variant)`. +- Background `var(--color-surface-container)` (#1e1f25). +- Radius `lg` (1rem). +- Padding `1.5rem`. +- Type badge top-left (small, uppercase, tracking-wide). +- Provider icon top-right (decorative if visible text label is present). +- Title (h3 if in archive, h2 on home), excerpt (line-clamp), action row at bottom with `Download` and `View Repo`. +- Hover: subtle border tint to `var(--color-primary)`. +- Focus-visible: 2px primary outline, 3px offset. + +### 6.3 Stat card + +New `views/components/project-stat-card.php`: + +- Square surface with `var(--color-surface-container)`, radius `lg`, padding `1rem`. +- Icon (decorative), large value, uppercase label below. + +### 6.4 Navigation + +Keep `views/components/nav-main.php`, `nav-aux.php`, `nav-main__toggle.php`. Recolor links to `var(--color-on-surface)`. Preserve skip link, dropdown behavior, focus visibility, mobile variants. + +### 6.5 Header layout + +Switch from `grid-cols-[83px_auto]` to a three-region responsive layout (logo | main nav | aux action button). The `Download CV` button is in the right region on `lg`, collapses into the mobile menu below. + +## 7. Accessibility (WCAG 2.1 AA) + +- Skip-to-main link: preserved (`#f6ff00` on black, yellow focus outline). +- Body text contrast: `#e3e1e9` on `#100e0b` ≈ 14:1 — passes AA. +- Primary buttons: `#b6c4ff` background with `#05297a` text ≈ 9:1 — passes AA. +- All decorative layers `aria-hidden="true"` + `pointer-events: none`. +- Heading order: each template has exactly one `

`. Mockup headings map to page `

`; lower-level headings step down in order. +- Provider icons supplement text (GitHub, Gitea, Download, View Repo) — never replace them. +- Keyboard: tab order header → hero → projects → footer; focus-visible on every interactive element. +- `prefers-reduced-motion`: media-query guard around hover scale on cards / media. + +## 8. Security + +- All forms use `wp_nonce_field`; state-changing requests use `wp_verify_nonce`. +- Dynamic output escaped with the right `esc_*` function for its context (`esc_html`, `esc_attr`, `esc_url`, `wp_kses_post`). +- Post meta access via `get_post_meta( $id, $key, true )` with explicit defaults. +- No `$_GET` / `$_POST` / `$_REQUEST` without `sanitize_*` + `wp_unslash`. +- External URLs (Download / View Repo) use `esc_url` and add `rel="noopener noreferrer"` when `target="_blank"`. + +## 9. Testing plan + +### 9.1 Unit / static (composer) + +- `composer run lint` (PHPCS with WordPress + WPCS ruleset) must pass clean across all theme PHP. +- Fix any violations inline. + +### 9.2 Static security audit + +- PHPCS `WordPress.Security` ruleset (`NonceVerification`, `ValidatedSanitizedInput`, `EscapeOutput`). +- Grep audit for `$_GET` / `$_POST` / `$_REQUEST` without `sanitize_*` / `wp_unslash` / `esc_*`. +- Manual review of every new template for nonce, sanitize, escape coverage. +- Severity-ranked written report (Critical / High / Medium / Low / Info) with `file:line` citations and remediation per finding. + +### 9.3 Browser / functional (Playwright) + +- `playwright.config.js`: chromium project only, base URL `http://portfolio.test` (matches `.env`). +- New `tests/home.spec.js`: home renders Carbon Blue hero, project grid or empty state, no axe violations. +- New `tests/archive.spec.js`: project archive grid renders, no axe violations. +- New `tests/single.spec.js`: project detail hero + sidebar + Download button visible, no axe violations. +- Keep existing `tests/site-a11y.spec.js` (homepage, blog index, 404). +- axe tags: `wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22a, wcag22aa`. +- Full-page screenshots saved to `test-results/` per test. + +## 10. File-level changes + +### Modified + +- `style.css` (already correct — verify) +- `functions.php` (namespace swap, project helper include) +- `header.php`, `footer.php` (namespace swap, dark surface) +- `index.php`, `single.php`, `page.php`, `search.php`, `404.php`, `front-page.php` (namespace swap, dark surface, remove `picsum.photos`) +- `lib/*.php` (11 files: `activation.php`, `class-acf.php`, `class-breadcrumbs.php`, `class-enqueue.php`, `class-menuitems.php`, `class-resources.php`, `extras.php`, `helpers.php`, `hooks.php`, `search-features.php`, `show-template.php` — namespace swap + dark surface tweaks) +- `views/blocks/*/block.json` and any block PHP that uses a namespace (light touch — only what axe or the new templates require) +- `views/forms/search.php` (light touch — escape review only, no behavior change) +- `theme.json` (fix preset references, add dark palette) +- `styles/base/colors.css` (add Carbon Blue tokens) +- `styles/base/typography.css` (define `--font-headings`) +- `styles/base/global.css` (dark body, remove light main rule) +- `views/components/nav-*.php`, `views/partials/*.php` (namespace swap, dark overrides) + +### New + +- `archive-projects.php` +- `single-projects.php` +- `taxonomy-project-type.php` +- `views/partials/aura-bg.php` (Carbon Blue layers + grain) +- `views/components/project-card.php` +- `views/components/project-stat-card.php` +- `lib/class-projects.php` (thin wrapper around plugin helpers: `get_provider_label()`, `get_release_url()`, `get_repo_browse_url()`, `get_repo_data()`, `get_owner_data()`, `get_download_url()` with provider-agnostic fallbacks) +- `tests/home.spec.js` +- `tests/archive.spec.js` +- `tests/single.spec.js` +- `docs/superpowers/specs/2026-08-16-portfolio-2026-design.md` (this file) +- `docs/superpowers/specs/2026-08-16-portfolio-2026-testing-report.md` (final report) + +### Removed + +- `screenshot.png` (Basic WP) — replaced at the end +- `picsum.photos` fallback URLs in `index.php`, `search.php` +- Legacy hex values in pagination CSS + +## 11. Out of scope + +- Migrating existing content (site has minimal published content — no destructive cleanup). +- Changing `projects-portfolio` plugin behavior (we only consume its helpers). +- Removing the `Resources` CPT (per notes: keep both, don't conflate). +- Block-editor UI polish (follow-up). +- Firefox / WebKit / mobile browser testing (out of scope per user choice). +- OWASP ZAP scan (out of scope per user choice). + +## 12. Definition of done + +- `composer run lint` exits 0. +- Playwright suite passes locally (Chromium, axe-core zero violations across all four specs). +- Static security audit produced with no Critical or High findings (Medium+ requires remediation before sign-off). +- All three mockups (home, archive, single project) reachable on `http://portfolio.test` and visually consistent with their reference screenshot. +- `screenshot.png` replaced with a Carbon-Blue capture. +- Final testing report committed to `docs/superpowers/specs/2026-08-16-portfolio-2026-testing-report.md`.