Foundation Theme — Improvement & Growth Plan
Package: capell-app/foundation-theme · Kind: theme · Tier: free · Product group: Capell Foundation · Bundle: foundation · Status: Complete
1. Snapshot
Section titled “1. Snapshot”Foundation Theme is the base theme every vertical theme builds on. It registers a single Theme Studio definition (themeKey: "default", Blade runtime) with seven view section renderers (navigation, hero, features, proof, content-listing, cta, footer) via BladeThemeRenderer against capell-foundation-theme::theme.page, and contributes the shared capell:: Blade namespace, anonymous component path, Layout Builder widget views, the header Layout Builder area, an SVG media sanitiser, a CapellUrlGenerator, Blade directives (@buildAssets, @capellBuffer), and the TailwindAssetsGenerator that aggregates @import/@plugin/@source/@theme into one frontend CSS entrypoint (src/Providers/FoundationThemeServiceProvider.php). Design tokens are split between a Spatie settings class (FoundationThemeSettings — colour, spacing, radius, dark-mode, and heading-scale fields) emitted as CSS custom properties at runtime by resources/views/components/app/head/tokens.blade.php, and a default-colors palette from core’s DefaultColorEnum. Surfaces are ["admin", "frontend"]; capabilities are ["frontend-assets", "cache-blocking"]. Marketplace summary now leads with Foundation Theme as the base every Capell site and child theme builds on. The generated Tailwind output review has been recaptured as a developer command-report artifact and retained as screenshot-runner evidence; route-backed layout captures remain promoted. Completion review on 2026-06-07 closed the remaining Foundation rows: the base shell now emits dir, shared Theme Studio sections use logical direction utilities, heading scale is a settings-backed token contract, and Tailwind import resolution uses vendor asset package origin instead of hard-coded package guesses.
2. Improvements (existing functionality)
Section titled “2. Improvements (existing functionality)”-
Health check probes shipped. — Shipped 2026-06-04:
FoundationThemeHealthChecknow performs real install, provider, Theme Studio registration, render-view, asset, config/token, and provider-registration probes instead of returning a false-green compatibility-only result. —src/Health/FoundationThemeHealthCheck.php,tests/Feature/FoundationThemeHealthCheckTest.php— Done -
Demo subsystem wired. — Shipped 2026-06-05:
capell:foundation-theme-demonow callsInstallFoundationThemeDemoAction, which wraps the existingThemeDemoPageInstaller;capell.jsonadvertises bothcommands.demoandactions.demo. The demo support is now a discoverable package surface for route-backed Foundation captures instead of orphaned internal code. —src/Console/Commands/DemoCommand.php,src/Actions/InstallFoundationThemeDemoAction.php,src/Support/Demo/*,capell.json— Done -
Remove the no-op admin provider — Shipped 2026-06-04: The unregistered empty provider class was removed, provider discovery is pinned by manifest/composer tests, and the README no longer lists it as a service provider. — S
-
Public-Blade data-loading guard closed. — Shipped 2026-06-04:
SafeOutputTestnow covers public BladegetMeta()and translation relation reads, and the footer/site-info path documents its hydrated relation boundary so future edits do not reintroduce lazy-load/N+1 behavior. —tests/Feature/SafeOutputTest.php,resources/views/components/footer/site-info.blade.php— Done -
Token sources consolidated. — Shipped 2026-06-07:
ResolveFoundationThemeTokensActionnow owns the shared palette/default token resolution,FoundationThemeTokensDatacarries the runtime CSS token contract, and both the head token partial and Tailwind default colour registration consume the same sanitized palette path. Vendor-registered build colours still pass through the generator’s render-time safety check. —src/Actions/ResolveFoundationThemeTokensAction.php,src/Data/FoundationThemeTokensData.php,src/Support/Tailwind/TailwindAssetsGenerator.php,resources/views/components/app/head/tokens.blade.php— Done -
Runtime token contract typed. — Shipped 2026-06-07: the head token partial no longer owns the settings lookup, fallbacks, palette merge, or sanitisation logic. It calls the token Action and only echoes pre-resolved values from
FoundationThemeTokensData, keeping public Blade focused on presentation. —src/Actions/ResolveFoundationThemeTokensAction.php,src/Data/FoundationThemeTokensData.php,resources/views/components/app/head/tokens.blade.php— Done -
Tailwind package import detection is origin-driven. — Shipped 2026-06-07: vendor Tailwind imports now receive their
VendorAssetDataorigin when deciding whether an import is a node-module specifier or a package-local file. Package-ownedresources/*imports still resolve into the installed package path, while package-owned module imports such asswiper/cssstay as module specifiers without hard-coded package-name guesses. —src/Support/Tailwind/TailwindAssetsGenerator.php,tests/Unit/FoundationThemeCoveragePushTest.php— Done -
Reconcile the README “At A Glance” surfaces with the manifest — Shipped 2026-06-04: README and overview now describe the shipped
admin/frontendsurfaces and the single registered runtime provider. Updated 2026-06-06: the media contract now documents 12 deployment capture targets and keeps generated Tailwind output review unpromoted until the runner captures an actual generated-assets report. —README.md,docs/overview.md,capell.json— S
3. Missing Features (gaps)
Section titled “3. Missing Features (gaps)”Tied to capabilities: ["frontend-assets", "cache-blocking"] and theme-foundation norms. As the base every child theme inherits, each gap below is multiplied across the whole theme line.
-
RTL shell support shipped. The base app shell now emits
dir="rtl"for known RTL language roots from the active frontend language/app locale anddir="ltr"otherwise. Shared Theme Studio shell/section controls use logical utilities (start,end,text-start,pe) where Foundation owned physical left/right alignment. Broader legacy widget-template logical-property conversion remains optional polish outside the current Theme Studio renderer scope. — table-stakes closed -
Dark token layer shipped. Foundation now emits tokenized dark-mode values through the shared runtime token contract and keeps dark evidence in the screenshot/report contract without over-promoting mock SVGs. Further child-theme-specific dark treatments belong to each child theme. — differentiator closed
-
Child-theme override surface documented. README/overview now publish the stable section keys, shared views, runtime token names, and chrome areas that child themes can rely on, with boundary coverage pinning the public contract. — differentiator closed
-
Typography scale tokens shipped.
FoundationThemeSettingsnow persistsheading_scale, the settings schema exposes compact/balanced/expressive options,FoundationThemeTokensDatacarries heading sizes/line height, and the public head partial emits--foundation-heading-*CSS variables consumed by the base theme CSS. — table-stakes closed -
Base shell accessibility primitives shipped for Theme Studio pages. The shared Theme Studio page wrapper now renders a skip link with a matching
main#main-contentlandmark plus a politerole="status"live region, so child themes using the Foundation renderer inherit the basic shell accessibility primitives instead of re-implementing them. Lower-level non-Theme Studio routes can add route-specific status regions when they own dynamic updates. — table-stakes -
cache-blockingcontract documented. Foundation documents the cache-blocking capability surface and keeps the reachable component-level render contributions intact for child themes and widgets. — table-stakes closed
4. Issues / Risks
Section titled “4. Issues / Risks”-
Health check false-green risk closed.
FoundationThemeHealthChecknow runs real package, registration, view, asset, config/token, and provider probes. (See §2.1.) -
Demo subsystem is wired, but still needs broader runtime coverage.
src/Support/Demo/ThemeDemoPageInstaller.php(869),ThemeDemoMedia.php(296),ThemeDemoPageDefinition.php,src/Contracts/InstallsThemeDemo.php, andsrc/Data/ThemeDemoInstallData.phpnow have a command/action entrypoint viacapell:foundation-theme-demo; keep deeper route-backed capture and installer coverage on the screenshot/demo pass. -
Public-Blade data-loading guard closed.
getMeta(and translation relation access now have reviewed guard coverage, and public views use hydrated relation data rather than lazy-loading in templates. (See §2.4.) -
Colour tokens written into
<style>via{{ }}(HTML escaping, not CSS escaping).resources/views/components/app/head/tokens.blade.phpandresources/views/components/footer/index.blade.php:18,34,45emit--color-…: {{ ColorConverterAction::run(...) }}inside<style>. The palette loop is gated by the inline$isSafeTokenclosure, but$brandColor,$linkColor,$linkColorActive,$dividerColor, and thefooter/index.blade.phpfooter colours are passed throughColorConverterActiononly — not through$isSafeToken/isSafeThemeColor— before being printed into a CSS context. The safety therefore depends entirely onColorConverterActionnever returning a string containing;/}/<. Route every value emitted inside<style>through the same[\x00-\x1F\x7F;{}<>]safe-list the palette loop andTailwindAssetsGenerator::isSafeThemeColor()already use. — render/output safety -
Coverage closed for current roadmap. Focused tests cover health diagnostics, demo command/action wiring, public-output safety, token resolution, child-theme override contracts, shell accessibility, performance budgets, RTL/logical utilities, typography tokens, and Tailwind import resolution. Deeper demo-installer fixture coverage remains future hardening rather than an active theme-plan row.
-
Closed 2026-06-04: the no-op admin provider was removed and the misleading README provider/surface claims were corrected. (See §2.3.)
-
Shipped 2026-06-07: Theme Studio shell accessibility primitives.
theme/page.blade.phpnow provides the skip link, matchingmain#main-contentlandmark, and a screen-reader-only politerole="status"live region for Theme Studio-rendered pages, with focused boundary coverage. Note: widget-level a11y is tested (LightboxAccessibilityTest, language-flag dimensions andalt=""inSafeOutputTest). -
Shipped 2026-06-07: Foundation performance budgets have focused guards.
PerformanceBudgetTestrenders the shared Theme Studio wrapper inside the manifestfrontendRenderBudgetMswith zero database queries, and builds the Foundation settings admin schema inside the manifestadminQueryBudget. Keep broader route/browser performance work with screenshot and runtime QA, but the manifest budgets are no longer untested placeholders. -
cacheSafety.cacheable: falsewithvariesBy: ["site", "locale"]is broad. The whole theme is marked non-cacheable. Given most of the output is static chrome and onlyActions/CSRF widgets are truly per-request (correctly markedcacheable: falseat the component level), a blanket theme-level non-cacheable flag may defeat HTML caching the platform offers. Confirm whether the manifest flag is intended to disable caching theme-wide or is redundant with the component-level contributions. -
i18n/RTL: translation files exist (
resources/lang/en/{form,generic}.php) and user-facing strings use__()(verified inSafeOutputTestassertions, e.g.scroll_to_top). The shell now emitsdirfrom the active language/app locale; additional bundled locales are future content depth, not an open Foundation renderer gap. -
Tailwind
tw:prefix: N/A here. This package owns its own@import "tailwindcss"entrypoint (resources/css/foundation-theme.css) with no Bootstrap to collide with; it correctly uses unprefixed utilities (grep: 0tw:occurrences). Thetw:-prefix convention is a host-frontend rule and must not be applied to this package.
5. Marketplace & Positioning
Section titled “5. Marketplace & Positioning”Current manifest summary: “Default Capell page foundations, layout areas, content widgets, media, forms, and package-aware frontend states.” — Reads as an undifferentiated feature list (“foundations… states”) and buries the single most important fact: this is the base every other theme extends. “Forms” and “package-aware frontend states” over-promise relative to what this package actually owns (it renders layouts whose data comes from other packages).
Improved summary: “The base theme every Capell site and child theme builds on: shared Blade layouts, a runtime design-token system (colours, spacing, radius), the Tailwind asset pipeline, an SVG sanitiser, and the section/area contracts that vertical themes override.”
Current composer description: “Capell default theme — ships the standard Tailwind asset pipeline, Blade directives, URL generator, and SVG media component.” — Accurate but narrow; omits the design-token system and the child-theme foundation role that are the real value.
Improved composer description: “Capell’s foundation theme — base Blade layouts, runtime design tokens, the Tailwind asset pipeline, Blade directives, media/SVG handling, and the override contracts that all vertical Capell themes extend.”
Quality gates the whole line: Because every theme inherits capell:: views, Foundation now carries the shared quality floor for the catalogue: real health diagnostics, public-Blade data-loading guards, RTL direction support, dark/heading tokens, a documented child-theme override surface, and a single typed token contract that paid themes can extend.
Design-system/token consistency: Runtime and build-time colour handling now share a typed token contract and safe token boundary; settings cover colour, spacing, radius, dark mode, and heading scale, giving child themes a consistent design-system base.
Screenshot/media status: the manifest now lists the extension card, Foundation settings light/dark, the generated Tailwind output review report, and the 8 route-backed layout workflows. The generated Tailwind output review now targets capell:frontend-tailwind-assets --report as a console-command capture with a committed Markdown report and light/dark PNG evidence; it remains developer evidence rather than buyer-facing marketplace media. The prior SVG layout mockups were removed from marketplace media.
Completed 2026-06-07. Every prioritized roadmap row is closed. Foundation Theme now ships real health diagnostics, demo command/action wiring, safe public CSS token output, public-Blade data-loading guards, consolidated typed token resolution, documented child-theme override contracts, Theme Studio shell accessibility primitives, dark tokens, render/admin budget guards, RTL direction/logical shell support, settings-backed typography scale tokens, origin-driven Tailwind package import detection, and route-backed screenshot/report evidence.
Keywords/tags: capell-cms, base-theme, theme-foundation, design-tokens, css-custom-properties, tailwind-pipeline, blade-layouts, child-theme-extends, svg-sanitizer, layout-builder-areas, dark-mode, accessibility.
6. Prioritized Roadmap
Section titled “6. Prioritized Roadmap”| Item | Bucket | Effort | Impact | Section ref |
|---|---|---|---|---|
| Replace stub health check with real probes | Done | M | High | §2.1, §4 — closed 2026-06-04: health check now probes install state, manifest/provider wiring, Theme Studio registration, render views, assets, config/tokens, and provider registrations. |
Route all <style> token values through the CSS safe-list | Done | S | High | §4 — closed 2026-06-04: public Blade colour tokens now resolve through ResolveSafeCssColorTokenAction before CSS output. |
Add getMeta(/->translation-> to public-Blade guard | Done | S | High | §2.4, §4 — closed 2026-06-04: public Blade getMeta() and translation relation reads now have reviewed guard coverage, with footer site info using hydrated relation data explicitly. |
| Delete no-op admin provider + fix README surfaces | Done | S | Med | §2.3, §2.8 — closed 2026-06-04: removed the unregistered no-op provider, pinned provider discovery in tests, and aligned README/overview surface and screenshot claims with shipped files. |
Shipped 2026-06-05: wire capell:foundation-theme-demo command and demo action | Done | M | High | §2.2, §4 |
| Recapture generated Tailwind asset output review as an actual generated-assets report before marketplace promotion | Done | S | Med | §1, §5 — closed 2026-06-07: the screenshot contract now targets the Tailwind report command, with committed report Markdown plus light/dark report PNG evidence retained outside marketplace media. |
| Consolidate the two token sources into one typed Action | Done | M | High | §2.5, §5 — closed 2026-06-07: ResolveFoundationThemeTokensAction owns shared palette/default token resolution for runtime head tokens and Tailwind default colour registration. |
| Move head-token prologue into a hydrated Data object | Done | M | Med | §2.6 — closed 2026-06-07: FoundationThemeTokensData carries the resolved runtime token contract and the Blade partial only emits CSS variables. |
| Publish documented child-theme override surface + arch test | Done | M | High | §3, §5 — closed 2026-06-07: README/overview now document section keys, shared views, runtime tokens, and chrome areas, with boundary coverage pinning the contract. |
| Add base-shell a11y primitives (skip-link, landmarks, aria-live) | Done | M | High | §3, §4 — closed 2026-06-07: Theme Studio wrapper now has a skip link, matching main#main-content, and polite role="status" live region. |
| Ship a full dark token layer or drop dark screenshots | Done | M | Med | §3 — closed 2026-06-07: Foundation now emits a shared .dark:root token layer from settings-backed dark surface, band, card, image, action, and body foreground tokens. |
| Add render-budget + admin query-count assertions vs manifest | Done | S | Med | §4 — closed 2026-06-07: focused tests assert shared wrapper render time/zero queries and settings schema query count against capell.json budgets. |
Add RTL: dir emission + logical-property conventions | Done | L | Med | §3 — closed 2026-06-07: the app shell emits dir from the active frontend language/app locale, and Foundation-owned Theme Studio shell controls use logical direction utilities. |
Add typography-scale tokens + back headingScale setting | Done | M | Med | §3 — closed 2026-06-07: heading_scale is settings-backed, exposed in the settings schema, carried through typed token data, emitted as --foundation-heading-*, and consumed by base CSS. |
Make isNodeModuleImport() origin-driven, not heuristic | Done | M | Low | §2.7 — closed 2026-06-07: vendor Tailwind imports now receive VendorAssetData so package-owned module imports stay module specifiers while package-local resources/* imports resolve to files. |
Shipped 2026-06-06: Rewrite marketplace summary + composer description | Done | S | Med | §5 — capell.json and composer.json now use the improved Foundation/child-theme positioning from §5. |