# Foundation Theme — Improvement & Growth Plan

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

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

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.php` — **Done**

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.json` — **Done**

3. **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**

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.php` — **Done**

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.php` — **Done**

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.php` — **Done**

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.php` — **Done**

8. **Reconcile the README "At A Glance" surfaces with the manifest** — **Shipped 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.json` — **S**

## 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 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**

## 4. Issues / Risks

- **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.

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

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