Skip to content

Foundation Theme — Improvement & Growth Plan

Package: capell-app/foundation-theme · Kind: theme · Tier: free · Product group: Capell Foundation · Bundle: foundation · Status: Complete

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.

  1. Health check probes shipped.Shipped 2026-06-04: FoundationThemeHealthCheck now 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.phpDone

  2. Demo subsystem wired.Shipped 2026-06-05: capell:foundation-theme-demo now calls InstallFoundationThemeDemoAction, which wraps the existing ThemeDemoPageInstaller; capell.json advertises both commands.demo and actions.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.jsonDone

  3. Remove the no-op admin providerShipped 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

  4. Public-Blade data-loading guard closed.Shipped 2026-06-04: SafeOutputTest now covers public Blade getMeta() 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.phpDone

  5. Token sources consolidated.Shipped 2026-06-07: ResolveFoundationThemeTokensAction now owns the shared palette/default token resolution, FoundationThemeTokensData carries 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.phpDone

  6. 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.phpDone

  7. Tailwind package import detection is origin-driven.Shipped 2026-06-07: vendor Tailwind imports now receive their VendorAssetData origin when deciding whether an import is a node-module specifier or a package-local file. Package-owned resources/* imports still resolve into the installed package path, while package-owned module imports such as swiper/css stay as module specifiers without hard-coded package-name guesses. — src/Support/Tailwind/TailwindAssetsGenerator.php, tests/Unit/FoundationThemeCoveragePushTest.phpDone

  8. Reconcile the README “At A Glance” surfaces with the manifestShipped 2026-06-04: README and overview now describe the shipped admin/frontend surfaces 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.jsonS

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 and dir="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. FoundationThemeSettings now persists heading_scale, the settings schema exposes compact/balanced/expressive options, FoundationThemeTokensData carries 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-content landmark plus a polite role="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-blocking contract 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

  • Health check false-green risk closed. FoundationThemeHealthCheck now 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, and src/Data/ThemeDemoInstallData.php now have a command/action entrypoint via capell: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.php and resources/views/components/footer/index.blade.php:18,34,45 emit --color-…: {{ ColorConverterAction::run(...) }} inside <style>. The palette loop is gated by the inline $isSafeToken closure, but $brandColor, $linkColor, $linkColorActive, $dividerColor, and the footer/index.blade.php footer colours are passed through ColorConverterAction only — not through $isSafeToken/isSafeThemeColor — before being printed into a CSS context. The safety therefore depends entirely on ColorConverterAction never returning a string containing ;/}/<. Route every value emitted inside <style> through the same [\x00-\x1F\x7F;{}<>] safe-list the palette loop and TailwindAssetsGenerator::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.php now provides the skip link, matching main#main-content landmark, and a screen-reader-only polite role="status" live region for Theme Studio-rendered pages, with focused boundary coverage. Note: widget-level a11y is tested (LightboxAccessibilityTest, language-flag dimensions and alt="" in SafeOutputTest).

  • Shipped 2026-06-07: Foundation performance budgets have focused guards. PerformanceBudgetTest renders the shared Theme Studio wrapper inside the manifest frontendRenderBudgetMs with zero database queries, and builds the Foundation settings admin schema inside the manifest adminQueryBudget. Keep broader route/browser performance work with screenshot and runtime QA, but the manifest budgets are no longer untested placeholders.

  • cacheSafety.cacheable: false with variesBy: ["site", "locale"] is broad. The whole theme is marked non-cacheable. Given most of the output is static chrome and only Actions/CSRF widgets are truly per-request (correctly marked cacheable: false at 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 in SafeOutputTest assertions, e.g. scroll_to_top). The shell now emits dir from 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: 0 tw: occurrences). The tw:-prefix convention is a host-frontend rule and must not be applied to this package.

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.

ItemBucketEffortImpactSection ref
Replace stub health check with real probesDoneMHigh§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-listDoneSHigh§4 — closed 2026-06-04: public Blade colour tokens now resolve through ResolveSafeCssColorTokenAction before CSS output.
Add getMeta(/->translation-> to public-Blade guardDoneSHigh§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 surfacesDoneSMed§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 actionDoneMHigh§2.2, §4
Recapture generated Tailwind asset output review as an actual generated-assets report before marketplace promotionDoneSMed§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 ActionDoneMHigh§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 objectDoneMMed§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 testDoneMHigh§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)DoneMHigh§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 screenshotsDoneMMed§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 manifestDoneSMed§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 conventionsDoneLMed§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 settingDoneMMed§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 heuristicDoneMLow§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 descriptionDoneSMed§5 — capell.json and composer.json now use the improved Foundation/child-theme positioning from §5.