Skip to content

Date: 2026-03-08 Session: Mini-Apps Platform + Foundation Refactor Status: ✅ Complete


Deployed apps/sd-app to Cloudflare Pages and embedded the live RRSP Gross-Up Calculator in the Template components showcase via auto-resizing iframe. Then performed a comprehensive foundation refactor: security headers, bundled Alpine.js, moved all shared UI/layout components to packages/components/, extracted BaseLayout inline scripts to typed modules, and cleaned up dead code and Windows artifacts.


  • Built and deployed apps/sd-app to Cloudflare Pages at https://sd-app-eu1.pages.dev
  • Added ?embed query param support to +layout.svelte — hides nav header when embedded
  • Implemented ResizeObserver + postMessage auto-resize — iframe height adjusts to content at all viewport widths, no scrollbars
  • Created MiniAppsShowcase.astro following existing showcase pattern
  • Added frame-src CSP to Template’s _headers; added frame-ancestors CSP to sd-app’s _headers
  • Updated components.astro to render the new showcase section
  • Created sites/Template/public/_headers with full CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
  • Created apps/sd-app/static/_headers with frame-ancestors restricted to known domains
  • Removed floating CDN script (cdn.jsdelivr.net/npm/alpinejs@3.x.x)
  • Added alpinejs as pnpm dependency
  • Created sites/Template/src/scripts/alpine-init.ts — imports Alpine, sets window.Alpine, calls Alpine.start()
  • Bundled via Astro’s standard <script> (tree-shaken, versioned, no CDN dependency)
  • Moved 22 UI components from sites/Template/src/components/ui/packages/components/src/ui/ (git mv, history preserved)
  • Moved 4 layout components from sites/Template/src/components/layout/packages/components/src/layout/ (git mv)
  • Updated packages/components/package.json to v0.1.0 with pattern exports (./ui/*, ./layout/*)
  • Added @components Vite alias to sites/Template/astro.config.mjs
  • Added TypeScript paths for @components/ui/* and @components/layout/* in tsconfig.json
  • Updated all imports across 50+ files to use @components/ui/ and @components/layout/
  • Header stayed in Template (brand-specific); Footer moved to packages

P5 — SmartDebt Contrast Test (Proposal Only)

Section titled “P5 — SmartDebt Contrast Test (Proposal Only)”
  • Root cause: aria-hidden="true" decorative elements flagged by axe-core
  • WCAG 1.4.3 explicitly exempts decorative/hidden content from contrast requirements
  • Proposed fix: Update accessibility.spec.ts to configure axe with { rules: { 'color-contrast': { selector: ':not([aria-hidden="true"])' } } } — no visual changes needed
  • Deleted: Layout.astro, ThemeSwitcher.astro, FIXES_APPLIED.md, TESTING_PROGRESS.md, Logo-SDC.png, Windows .lnk shortcuts, astro.svg ×2, background.svg ×2, Welcome.astro, stub package files
  • Moved to docs/: MOBILE_MENU_GUIDE.md, PLAYWRIGHT_MCP_SETUP.md, QUICK_REFERENCE.md, SEARCH_HIGHLIGHTING.md, STRUCTURE.md, TESTING_GUIDE.md
  • Extracted initSmartDebtAnimation()sites/Template/src/scripts/smartdebt-animation.ts
  • Extracted initFaviconSync()sites/Template/src/scripts/favicon-sync.ts
  • is:inline now contains ONLY theme/color init (~20 lines, FOUC prevention)
  • Pagefind highlight script kept is:inline (Vite can’t bundle dynamic runtime import)
  • Both new modules are type-checked, tree-shaken, bundled with Astro
  • Removed all console.log statements from production code
  • Pagefind script cleaned: removed console.log while keeping is:inline tag

FileChange
apps/sd-app/src/routes/+layout.svelte?embed detection, hide nav, ResizeObserver postMessage
apps/sd-app/src/routes/gross-up/+page.svelteCompacted layout for embed viewport
apps/sd-app/static/_headersNew — frame-ancestors CSP
sites/Template/public/_headersNew — full security header suite
sites/Template/src/layouts/BaseLayout.astroRemove CDN Alpine, thin out is:inline, add bundled script imports
sites/Template/src/scripts/alpine-init.tsNew — bundled Alpine init
sites/Template/src/scripts/smartdebt-animation.tsNew — extracted from BaseLayout is:inline
sites/Template/src/scripts/favicon-sync.tsNew — extracted from BaseLayout is:inline
sites/Template/src/env.d.tsAdded Window interface fields
sites/Template/astro.config.mjsAdded @components Vite alias
sites/Template/tsconfig.jsonAdded @components TypeScript paths
sites/Template/src/components/showcase/MiniAppsShowcase.astroNew — showcase section with iframe + auto-resize
sites/Template/src/pages/components.astroAdded MiniAppsShowcase import + render
packages/components/package.jsonv0.1.0, pattern exports for ui/* and layout/*
packages/components/src/ui/ (22 files)Moved from Template (git mv)
packages/components/src/layout/ (4 files)Moved from Template (git mv)
eslint.config.mjsAdded browser globals for *.svelte files
50+ Template component filesUpdated imports to @components/ui/ and @components/layout/

  • sites/Template/src/layouts/Layout.astro (unused duplicate)
  • sites/Template/src/components/ThemeSwitcher.astro (dead code)
  • sites/Template/FIXES_APPLIED.md, TESTING_PROGRESS.md (session cruft)
  • sites/Template/public/Logo-SDC.png (misplaced asset)
  • sites/Template/plan/*.lnk (Windows shortcuts)
  • sites/Template/src/assets/astro.svg, background.svg (Astro scaffold leftovers)
  • sites/sdc.com/src/assets/astro.svg, background.svg
  • sites/Template/src/components/Welcome.astro (Astro scaffold)
  • packages/components/BaseLayout.astro, Header.astro, Footer.astro (stubs)
  • MOBILE_MENU_GUIDE.mddocs/MOBILE_MENU_GUIDE.md
  • PLAYWRIGHT_MCP_SETUP.mddocs/PLAYWRIGHT_MCP_SETUP.md
  • QUICK_REFERENCE.mddocs/QUICK_REFERENCE.md
  • SEARCH_HIGHLIGHTING.mddocs/SEARCH_HIGHLIGHTING.md
  • STRUCTURE.mddocs/STRUCTURE.md
  • TESTING_GUIDE.mddocs/TESTING_GUIDE.md

  • f0c8b76 — feat: world-class foundation refactor (P1-P9)
    • Security headers, bundled Alpine, shared component package, script extraction, cleanup

  • TypeScript: ✅ astro check passes (0 errors after tsconfig paths fix)
  • ESLint: ✅ 0 errors (browser globals added for Svelte files)
  • Build: ✅ pnpm build succeeds in sites/Template/
  • Playwright E2E: Run /test-all to verify full suite after these structural changes
  • sd-app deployment: ✅ https://sd-app-eu1.pages.dev/gross-up → HTTP 200

  • P5 (SmartDebt contrast): aria-hidden elements still flagged by axe — proposed fix is in the session notes above; not implemented yet
  • sdc.com site is a placeholder — foundation work scoped to Template only

  1. Implement P5 — Update accessibility.spec.ts to exclude aria-hidden elements from contrast checks
  2. Run full Playwright suite — Verify all 7 projects still pass after component move (imports changed)
  3. sdc.com integration — Once Template foundation is proven stable, wire sdc.com to consume @components/ui/ and @components/layout/ packages
  4. sd-app custom domain — Point a subdomain (e.g. apps.smartdebtcoach.com) once domain is configured
  5. Add more mini-apps/int-only and /term-loan stubs ready to implement
  6. Proprietary app pattern — Design the SvelteKit + private API pattern for future equity analysis app