Theme Portfolio — Improvement & Growth Plan
Package: capell-app/theme-portfolio · Kind: theme · Tier: premium · Product group: Capell Themes · Bundle: themes · Status: Complete
1. Snapshot
Section titled “1. Snapshot”Theme key portfolio is registered in src/PortfolioThemeServiceProvider.php via ThemeRegistry::register() with a single BladeThemeRenderer (layout capell-theme-portfolio::page) and one preset (portfolio, warm-clay #7c2d12 / rose #f43f5e). The definition declares 17 includedSections; 16 ship as real resources/views/sections/*.blade.php templates (navigation is delegated to foundation and its local template is a near-empty stub) — namely hero, about-bio, features, proof, content-listing, work-grid, case-studies, case-study-detail, process, services, testimonials, speaking-media-kit, availability, newsletter, cta, footer. The demo command capell:theme-portfolio-demo (src/Console/Commands/DemoCommand.php) delegates to InstallPortfolioThemeDemoAction, which calls foundation’s shared ThemeDemoPageInstaller (seeds ≥7 route-backed pages with Unsplash media); demo “layouts” are driven by foundation, not declared per-layout in this package. The theme overrides every standard section with portfolio-specific Blade and inherits foundation behaviour (definition extends: 'default'). Marketplace and Composer copy now use buyer-facing creator/consultant case-study positioning. Health checks now verify provider, package file, manifest, and screenshot boundaries. Screenshots: capell.json declares 6 committed assets: the extension-card and hero JPG previews plus 3 route-backed PNG captures for homepage, case-study, and services/enquiry workflows. docs/screenshots.json declares 9 deployment captures, all committed under docs/screenshots/.
Completed Improvement Slices
Section titled “Completed Improvement Slices”- 2026-06-03: Rewrote marketplace/Composer copy, replaced the critical health-check stub with real diagnostics, and documented the intentional split between runtime
extends: defaultand manifest dependencyextends: capell-app/foundation-theme. - 2026-06-04: Moved newsletter chrome into translations, removed the inert
action="#"fallback, added hydratedformAction/formMethodsupport, and covered static/hydrated newsletter rendering in tests. - 2026-06-05: Reconciled product-group docs to
Capell Themes, documented the manifest/runtimeextendssplit in README and overview docs, and added manifest/docs assertions for both boundaries. - 2026-06-05: Made testimonials and speaking/media-kit sections read
$section->itemsfirst, with translated fallback summary/card/quote defaults for unhydrated demo states. - 2026-06-06: Replaced the 3 SVG marketplace layout diagrams with Capell runner PNG captures and fulfilled the 9-entry
docs/screenshots.jsoncontract. - 2026-06-07: Wired Newsletter’s public subscribe route into the Portfolio newsletter section automatically when the Newsletter package is installed, preserving hydrated form overrides while giving theme captures a real package-owned action.
2. Improvements (existing functionality)
Section titled “2. Improvements (existing functionality)”- Shipped 2026-06-05: Make testimonials data-driven — testimonials now render supplied
$section->itemsfirst and fall back to translated demo quotes/attribution only when empty —resources/views/sections/testimonials.blade.php— Done - Shipped 2026-06-05: Make speaking/media-kit data-driven — speaking/media-kit cards now render supplied
$section->itemsfirst and fall back to translated demo cards only when empty —resources/views/sections/speaking-media-kit.blade.php— Done - Shipped 2026-06-05: Translate hardcoded copy in services/stats — services fallback labels/cards plus hero and work-grid stat pills now use
capell-theme-portfolio::generictranslations, with render coverage proving the same defaults still output and source guards keeping those literals out of Blade —resources/views/sections/services.blade.php,hero.blade.php,work-grid.blade.php— Done - Shipped 2026-06-07: Translate newsletter chrome and connect package capture — newsletter labels, placeholder, form label, and button copy come from
generic.php; the section renders a real form when hydrated withformAction, and now automatically falls back to Newsletter’scapell-newsletter.subscriberoute when the Newsletter package is installed. Static states still show a translated CTA instead of posting toaction="#". —resources/views/sections/newsletter.blade.php,src/PortfolioThemeServiceProvider.php,resources/lang/en/generic.php— Done - Hero/work-grid stats translated and overrideable. Vanity stat copy is no longer hard-coded in Blade; translated defaults and hydrated section data keep demo output editable. —
resources/views/sections/hero.blade.php,resources/views/sections/work-grid.blade.php— Done - Empty-state strategy unified. Case studies, work grid, services, testimonials, and speaking/media-kit now use shared dashed premium-layout placeholders when section items are empty. —
resources/views/sections/{case-studies,work-grid,services,testimonials,speaking-media-kit}.blade.php— Done - Dark preset/variant shipped. The theme now registers
portfolio-darkand ships scoped.dark .portfolio-shellsurface/card/border/text overrides. —resources/css/theme-portfolio.css,src/PortfolioThemeServiceProvider.php— Done - Reduced-motion users are guarded from theme motion.
theme-portfolio.cssdisables portfolio-shell animation/transition duration, removes carousel snap motion, and neutralizes hover translate/scale effects inside@media (prefers-reduced-motion: reduce)while preserving the skip-link focus reveal. —resources/css/theme-portfolio.css— Done - Shipped 2026-06-07: promote raw hex to design tokens. Recurring section palette colours now use semantic
portfolio-*token classes backed by--portfolio-*/--theme-*custom properties, and tests guard section Blade against raw hex colour utilities. —resources/css/theme-portfolio.css+ section blades — Done - Navigation inheritance accepted. The local navigation view remains a deliberate foundation-delegated stub; the real public navigation is inherited rather than duplicated. —
resources/views/sections/navigation.blade.php— Done
3. Missing Features (gaps)
Section titled “3. Missing Features (gaps)”Manifest capabilities[] = ["theme-portfolio", "theme-portfolio-frontend"] (frontend rendering only — no editor/authoring capability declared).
Table-stakes for a portfolio vertical are now present at the theme boundary:
- Work/project showcase grid shipped. Work-grid/content-listing render portfolio work with translated defaults, hydrated data, image attributes, empty states, and render-budget coverage.
- Case-study detail shipped. Case-study sections remain the strongest differentiator, with outcome-led scope/role/timeline/result framing.
- About / bio shipped. The
about-biosection gives creators a first-person/studio-story lane with supplied item cards first and translated creator-profile defaults when empty. - Skills / capabilities matrix covered. Services/process/media-kit sections cover sellable capabilities; a dedicated tools/stack section would be future polish.
- Gallery / lightbox shipped.
gallery-lightboxrenders hydrated media with image attributes, empty states, and public-output coverage. - Contact / enquiry covered by availability/newsletter. Availability, footer, services, and Newsletter-connected capture cover current renderer scope; a dedicated project enquiry package/form remains future product depth.
- Resume / CV shipped.
resume-cvrenders hydrated experience/timeline data with safe empty states. - Client logos shipped.
client-logosgives logo-wall proof as a distinct section. - Functional newsletter capture shipped. Portfolio passes Newsletter’s named public subscribe route into the newsletter section when
capell-app/newsletteris installed; hydratedformActionstill wins for custom implementations.
Differentiator vs table-stakes: Portfolio now owns the personal/creator lane through first-person bio, single-operator availability, media kit, audience/newsletter growth, gallery, resume/CV, and logo proof, while Agency owns team/campaign/services positioning.
4. Issues / Risks
Section titled “4. Issues / Risks”- Shipped 2026-06-05: Doc/manifest product-group drift —
capell.json,README.md, anddocs/overview.mdnow agree onproduct.group: "Capell Themes"and tests assert the docs stay aligned with the manifest. - Shipped 2026-06-05: Dual
extendsmeaning tested and documented — runtime definition usesextends: 'default', whilecapell.json.extends = "capell-app/foundation-theme"; the README, overview, provider comment, and manifest tests now preserve that distinction. - Health check shipped, keep expanding diagnostics as the package grows —
ThemePortfolioHealthChecknow verifies provider, package file, manifest, and screenshot boundaries. Add future sections/assets to those diagnostics instead of letting the critical check drift back into a shallow compatibility-only assertion —src/Health/ThemePortfolioHealthCheck.php. - Stub management contribution —
src/Manifest/ThemeManagementPageContribution.phpis a bare contract shell (compatibleCapellApiVersion()only); confirmThemeExtensionPageneeds nothing more, or it is dead surface area —src/Manifest/ThemeManagementPageContribution.php. - Shipped 2026-06-07: Newsletter package capture route connected — Newsletter now exposes
capell-newsletter.subscribe, and Portfolio resolves it at render time when the package is installed. Public submissions are site-scoped through the frontend context, create pending/subscribed subscribers through Newsletter Actions, record consent evidence, and request double opt-in by default.resources/views/sections/newsletter.blade.php,src/PortfolioThemeServiceProvider.php,../newsletter/routes/web.php,../newsletter/src/Actions/SubscribeFromPublicRequestAction.php. - Public Blade DB-query safety: good —
page.blade.phponly echoes pre-hydrated$contentand brand tokens; section templates read$section->itemsarrays and__()strings, never Eloquent.tests/Unit/PublicOutputSafetyTest.phpstring-scans all views + lang for::query(,DB::,loadMissing(,wire:,Filament,capell-app/theme-portfolio, model/field markers — solid coverage, no leak found. - Shipped 2026-06-06: hero/work image alt and LCP hints are wired. Hero media now falls back to an informative alt string, declares intrinsic dimensions, and uses eager/high-priority async decoding for first-viewport media. Content-listing project images derive alt text from item metadata/title, declare intrinsic dimensions, and lazy-load with async decoding. Remaining WCAG follow-up: carousel button visibility/affordance. —
resources/views/sections/{hero,content-listing}.blade.php,resources/lang/en/generic.php. - Cache safety —
capell.json.performance.cacheSafety.cacheable = false,variesBy: ["site","locale"],sensitiveOutput: false. Consistent with locale-dependent__()output and no per-user data. The inlinestyle="…tokens…"inpage.blade.phpis brand-derived (site-scoped), matchingvariesBy. No issue, but document why a visual theme is non-cacheable if a future perf pass questions it. - Performance budget covered. Every Portfolio-owned section now renders anonymously inside the manifest 20ms budget with zero select queries and public-output safety assertions. —
capell.json,tests/Unit/PortfolioThemeDefinitionTest.php. - Render test gaps closed for current roadmap. Footer plus services, testimonials, speaking/media-kit, newsletter, gallery-lightbox, resume-cv, client-logos, and empty-section placeholder branches have focused coverage; navigation is inherited from Foundation. —
tests/Unit/.
5. Marketplace & Selling
Section titled “5. Marketplace & Selling”The manifest and Composer description now use this buyer-facing 1-sentence summary:
A premium portfolio theme for creators and consultants — turn selected work into outcome-driven case studies, sell your services and media kit, and grow your audience from one polished site.
The manifest marketplace description now uses this buyer-facing product story:
Theme Portfolio gives independent creators, consultants, and studios a credibility-first website built around proof, not just pretty pictures. Lead with a work-led hero, walk visitors through outcome-rich case studies (scope, role, timeline, measurable results), and present your services, process, and media kit as things people can actually buy. Connect Media Library for real project imagery, Content Sections for deep case studies, and Newsletter for audience capture — every section degrades gracefully when an integration is not installed. Where an agency theme sells a team and campaigns, Theme Portfolio sells you: your work, your authority, and your availability.
Media status: the live capture set is now committed — docs/screenshots.json declares 9 required screenshots and all 9 PNGs exist under docs/screenshots/. The 3 hand-made SVG marketplace mockups have been removed and replaced with real workflow captures. Remaining media depth is optional polish: add refreshed dark-mode marketplace pairs if the gallery needs more variation.
Completed 2026-06-07. Every prioritized roadmap row is closed. Theme Portfolio now has aligned product docs, dual-extends coverage, buyer-facing marketplace copy, route-backed captures, real health diagnostics, translated/data-driven creator sections, Newsletter integration, dark preset/CSS, reduced-motion guards, gallery-lightbox, resume/CV, client-logo sections, semantic colour tokens, per-section render coverage, and 20ms/no-query public-output guards.
Differentiation & target buyer: target = solo creator / freelance consultant / one-to-three-person studio who needs to win premium work on credibility. Differentiate from theme-agency by owning first-person voice, single-operator availability/booking, media kit + speaking, and audience growth — not team rosters or multi-service campaign funnels.
8–12 keywords/tags: portfolio, case studies, personal brand, creator, consultant, freelancer, work showcase, media kit, studio, outcomes, newsletter, premium theme.
6. Prioritized Roadmap
Section titled “6. Prioritized Roadmap”| Item | Bucket | Effort | Impact | Section ref |
|---|---|---|---|---|
Generate the 9 declared screenshots.json captures (+ dark pair) | Done | M | High | §5 — closed 2026-06-06: 9 route-backed PNG captures are committed and marketplace SVG diagrams were replaced with real workflow screenshots; dark pair remains after dark preset work. |
Shipped 2026-06-05: Reconcile product-group drift (overview.md vs capell.json) + document dual extends | Done | S | Med | §4 |
| Shipped 2026-06-05: Make testimonials + speaking/media-kit data-driven | Done | M | High | §2.1, §2.2 |
| Shipped 2026-06-05: Translate hardcoded copy (services, newsletter, stats) + add missing lang keys | Done | M | Med | §2.3, §2.4, §2.5 |
| Add About/Bio section (creator lane differentiator vs agency) | Done | M | High | §3 |
| Shipped 2026-06-05: Implement real health-check probes | Done | S | Med | §4 — ThemePortfolioHealthCheck verifies the Theme Studio definition, required package files, manifest wiring, health-check registration, marketplace copy, and screenshot assets. |
| Add image LCP hints (dimensions, lazy/eager, srcset) + fix alt handling | Done | M | Med | §4 |
| Unify empty-state strategy across sections | Done | M | Med | §2.6 — closed 2026-06-07: case-studies, work-grid, services, testimonials, and speaking/media-kit now use the shared dashed premium-layout placeholder when section items are empty. |
| Add render tests for footer/nav/services/testimonials/speaking/newsletter | Done | M | Med | §4 — closed 2026-06-07: focused registry tests cover footer plus services, testimonials, speaking/media-kit, newsletter, and empty-section placeholder branches. |
| Wire Newsletter integration to provide real capture actions automatically | Done | M | High | §2.4, §4 — closed 2026-06-07: Newsletter exposes capell-newsletter.subscribe; Portfolio automatically targets that route when installed while preserving hydrated formAction overrides. |
| Ship a dark preset + dark CSS | Done | L | High | §2.7, §5 — closed 2026-06-07: the theme now ships a portfolio-dark preset plus scoped .dark .portfolio-shell surface/card/border/text overrides. |
| Add reduced-motion guards for carousels + hover transforms | Done | S | Med | §2.8 |
| Add gallery/lightbox + resume/CV + client-logo sections | Done | L | Med | §3 — closed 2026-06-07: gallery-lightbox, resume-cv, and client-logos now render hydrated data with image attributes, empty states, and public-output coverage. |
| Promote raw hex to design tokens for full theme-editor propagation | Done | M | Med | §2.9 — closed 2026-06-07: section Blade now uses semantic Portfolio token classes for recurring palette colours, with a no-hex Blade guard. |
| Add a frontend render-budget guardrail test (20ms) | Done | M | Low | §4 — closed 2026-06-07: every Portfolio-owned section now renders anonymously inside the manifest 20ms budget with zero select queries and public-output safety assertions. |