diff --git a/GEMINI.md b/GEMINI.md
index c6fc956..49b7fe2 100644
--- a/GEMINI.md
+++ b/GEMINI.md
@@ -75,6 +75,7 @@ PostFundManagement/
├── PostFundManagement.Tests/ # Unit & Integration test suite (xUnit, Coverlet)
├── PostFundManagement.ConsoleUI/ # Internal Staff & Admin Web Portal (React 19 + Vite 6 + Tailwind 4)
├── PostFundManagement.PartnerUI/ # External Grantee / Partner Portal (React 19 + Vite 8 + Tailwind 4)
+├── PostFundManagement.ShowcaseUI/ # Public Facing Showcase App (React 19 + Vite 6 + Tailwind 4)
└── docker-compose.yml # Container orchestration for API and Frontends
```
@@ -115,6 +116,13 @@ PostFundManagement/
* **Exports & Utilities**: `jspdf`, `xlsx`, `hashids`
* **Target Users**: Grantee / Partner Project Directors, Financial Controllers, Field Officers submitting evidence and disbursement drawdown requests.
+#### **`PostFundManagement.ShowcaseUI`** (Public-Facing Product & Experience Showcase Portal)
+* **Package Manager**: **Yarn** (`yarn.lock` is authoritative; `npm` must not be used)
+* **Runtime & Bundler**: React 19.0.1, TypeScript 5.8.2, Vite 6.2.3
+* **Styling**: Tailwind CSS v4.1.14 (`@tailwindcss/vite`)
+* **Animation & Icons**: `motion` (Framer Motion) 12.23.24, `lucide-react` 0.546.0, `canvas-confetti`
+* **Purpose**: Public-facing showcase and product experience portal for prospective funders, development institutions, partner organizations, and stakeholders. Integrates high-resolution screenshots and marketing posters to demonstrate both **ConsoleUI** (Funder Backoffice) and **PartnerUI** (Grantee Delivery Hub), along with an interactive 5-phase fiduciary lifecycle simulator and ROI calculator.
+
### 2.3 Infrastructure, Storage & Security Topology
* **Database**: PostgreSQL 14+ (Separate connection strings for primary transactional store `pfm` and scheduler store `pfm-scheduler`).
* **Object / Evidence Store**: S3-compatible storage (e.g., Garage S3 / AWS S3) with pre-signed upload URLs and CDN acceleration.
diff --git a/PostFundManagement.ShowcaseUI/.dockerignore b/PostFundManagement.ShowcaseUI/.dockerignore
new file mode 100644
index 0000000..fcc4b25
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/.dockerignore
@@ -0,0 +1,6 @@
+node_modules
+dist
+.git
+.gitignore
+*.log
+
diff --git a/PostFundManagement.ShowcaseUI/.gitignore b/PostFundManagement.ShowcaseUI/.gitignore
new file mode 100644
index 0000000..d18825c
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+dist
+.env
+.env.local
+*.log
+
diff --git a/PostFundManagement.ShowcaseUI/Dockerfile b/PostFundManagement.ShowcaseUI/Dockerfile
new file mode 100644
index 0000000..e81c168
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/Dockerfile
@@ -0,0 +1,42 @@
+# Stage 1: Build stage
+FROM node:20-alpine AS builder
+
+WORKDIR /app
+
+# Enable corepack to use Yarn
+RUN corepack enable
+
+# Copy dependency definitions from the Showcase subdirectory
+COPY PostFundManagement.ShowcaseUI/package*.json PostFundManagement.ShowcaseUI/yarn.lock* ./
+
+# Install dependencies via Yarn
+RUN yarn install --frozen-lockfile || yarn install
+
+# Copy application source from the Showcase subdirectory
+COPY PostFundManagement.ShowcaseUI/ ./
+
+# Build Vite application for production
+RUN yarn build
+
+# Stage 2: Production Nginx Server
+FROM nginx:alpine
+
+WORKDIR /usr/share/nginx/html
+
+# Copy nginx configuration
+COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf
+
+# Copy compiled static assets from build stage
+COPY --from=builder /app/dist ./
+
+# Copy entrypoint script
+COPY --from=builder /app/docker-entrypoint.sh /docker-entrypoint.sh
+RUN chmod +x /docker-entrypoint.sh
+
+# Expose port 3000
+EXPOSE 3000
+
+# Set entrypoint and default command
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["nginx", "-g", "daemon off;"]
+
diff --git a/PostFundManagement.ShowcaseUI/README.md b/PostFundManagement.ShowcaseUI/README.md
new file mode 100644
index 0000000..68e9ee0
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/README.md
@@ -0,0 +1,27 @@
+# PostFundManagement.ShowcaseUI
+
+The **PFM Platform Showcase** is a public-facing, interactive web application designed to showcase **PFM Console** (Funder & Executive Management Suite) and **PFM Partner** (Implementing Partner & Grantee Suite).
+
+## Core Capabilities
+- **Dual Portal Experience**: Interactive previews of both PFM Console and PFM Partner with live hotspot explanations.
+- **Milestone & Evidence Lifecycle Simulator**: Interactive 5-phase simulation walking visitors through award intake, SSO onboarding, evidence upload to Garage S3, statutory gate checks, and covenant-tied tranche release.
+- **Marketing Campaign Deck (6 Posters)**: Full visual gallery and lightbox viewer for the official 6-page marketing posters.
+- **Enterprise Architecture Assurance**: Deep dive into the Clean DDD architecture, .NET 10, React 19, Quartz.NET background worker, Garage S3 vault, and Duende IdentityServer SSO.
+- **Fiduciary ROI & Governance Calculator**: Real-time estimations of audit hours saved and unverified capital exposure mitigated.
+
+## Running Locally
+
+```bash
+cd PostFundManagement.ShowcaseUI
+yarn install
+yarn dev
+```
+
+App runs on `http://localhost:3002`.
+
+## Building for Production
+
+```bash
+yarn build
+```
+
diff --git a/PostFundManagement.ShowcaseUI/docker-entrypoint.sh b/PostFundManagement.ShowcaseUI/docker-entrypoint.sh
new file mode 100644
index 0000000..b5cf59e
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/docker-entrypoint.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -e
+
+TARGET_DIR="/usr/share/nginx/html"
+
+if [ ! -d "$TARGET_DIR" ]; then
+ if [ -d "./dist" ]; then
+ TARGET_DIR="./dist"
+ elif [ -d "./public" ]; then
+ TARGET_DIR="./public"
+ fi
+fi
+
+echo "[docker-entrypoint] PFM Showcase UI ready in $TARGET_DIR."
+exec "$@"
+
diff --git a/PostFundManagement.ShowcaseUI/index.html b/PostFundManagement.ShowcaseUI/index.html
new file mode 100644
index 0000000..1d6ee42
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Post Fund Management (PFM) • Executive Console & Partner Suite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PostFundManagement.ShowcaseUI/nginx.conf b/PostFundManagement.ShowcaseUI/nginx.conf
new file mode 100644
index 0000000..0ee82cb
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/nginx.conf
@@ -0,0 +1,38 @@
+server {
+ listen 3000;
+ server_name localhost;
+
+ root /usr/share/nginx/html;
+ index index.html;
+
+ # Gzip Compression
+ gzip on;
+ gzip_vary on;
+ gzip_min_length 1024;
+ gzip_proxied expired no-cache no-store private auth;
+ gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/json image/svg+xml;
+
+ # Never cache dynamic runtime configuration files or index.html
+ location ~* ^/(?:config\.json|env-config\.js|index\.html)$ {
+ expires -1;
+ add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
+ }
+
+ # Cache control for static assets (CSS, JS, fonts, images)
+ location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff|woff2|ttf|eot)$ {
+ expires 1y;
+ access_log off;
+ add_header Cache-Control "public, immutable";
+ }
+
+ # HTML5 SPA History Mode Support
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+}
+
diff --git a/PostFundManagement.ShowcaseUI/package.json b/PostFundManagement.ShowcaseUI/package.json
new file mode 100644
index 0000000..312dc96
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "post-fund-management-showcase",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite --port=3002 --host=0.0.0.0",
+ "build": "vite build",
+ "preview": "vite preview --port=3002",
+ "clean": "rm -rf dist",
+ "lint": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@tailwindcss/vite": "^4.1.14",
+ "canvas-confetti": "^1.9.4",
+ "lucide-react": "^0.546.0",
+ "motion": "^12.23.24",
+ "react": "^19.0.1",
+ "react-dom": "^19.0.1",
+ "tailwindcss": "^4.1.14"
+ },
+ "devDependencies": {
+ "@types/canvas-confetti": "^1.9.0",
+ "@types/node": "^22.14.0",
+ "@types/react": "^19.3.0",
+ "@types/react-dom": "^19.3.0",
+ "@vitejs/plugin-react": "^5.0.4",
+ "typescript": "~5.8.2",
+ "vite": "^6.2.3"
+ }
+}
+
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/1.jpeg b/PostFundManagement.ShowcaseUI/public/assets/marketing/1.jpeg
new file mode 100644
index 0000000..0582fcf
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/1.jpeg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/2.jpeg b/PostFundManagement.ShowcaseUI/public/assets/marketing/2.jpeg
new file mode 100644
index 0000000..6426d7b
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/2.jpeg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/3.jpeg b/PostFundManagement.ShowcaseUI/public/assets/marketing/3.jpeg
new file mode 100644
index 0000000..9284575
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/3.jpeg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/4.jpg b/PostFundManagement.ShowcaseUI/public/assets/marketing/4.jpg
new file mode 100644
index 0000000..9410571
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/4.jpg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/5.jpg b/PostFundManagement.ShowcaseUI/public/assets/marketing/5.jpg
new file mode 100644
index 0000000..c72c753
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/5.jpg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/6.jpeg b/PostFundManagement.ShowcaseUI/public/assets/marketing/6.jpeg
new file mode 100644
index 0000000..1ae92b9
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/6.jpeg differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/marketing/PFM Platform Marketing Posters (6-Page Campaign Deck).pdf b/PostFundManagement.ShowcaseUI/public/assets/marketing/PFM Platform Marketing Posters (6-Page Campaign Deck).pdf
new file mode 100644
index 0000000..a8e3651
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/marketing/PFM Platform Marketing Posters (6-Page Campaign Deck).pdf differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/1.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/1.png
new file mode 100644
index 0000000..b9a84f5
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/1.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/10.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/10.png
new file mode 100644
index 0000000..2492513
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/10.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/2.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/2.png
new file mode 100644
index 0000000..d8a547f
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/2.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/3.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/3.png
new file mode 100644
index 0000000..83d5f4f
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/3.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/4.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/4.png
new file mode 100644
index 0000000..790850e
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/4.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/6.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/6.png
new file mode 100644
index 0000000..a88e1cb
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/6.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/7.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/7.png
new file mode 100644
index 0000000..28997b5
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/7.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/8.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/8.png
new file mode 100644
index 0000000..75d77a8
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/8.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/9.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/9.png
new file mode 100644
index 0000000..4f0acba
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/9.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/console.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/console.png
new file mode 100644
index 0000000..d9de0b2
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/console.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/assets/screenshots/partner.png b/PostFundManagement.ShowcaseUI/public/assets/screenshots/partner.png
new file mode 100644
index 0000000..2fe762c
Binary files /dev/null and b/PostFundManagement.ShowcaseUI/public/assets/screenshots/partner.png differ
diff --git a/PostFundManagement.ShowcaseUI/public/favicon.svg b/PostFundManagement.ShowcaseUI/public/favicon.svg
new file mode 100644
index 0000000..8dbe454
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/public/favicon.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PostFundManagement.ShowcaseUI/src/App.tsx b/PostFundManagement.ShowcaseUI/src/App.tsx
new file mode 100644
index 0000000..6c3009a
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/App.tsx
@@ -0,0 +1,73 @@
+import React, { useState } from 'react';
+import { HeroSection } from './components/hero/HeroSection';
+import { ConsoleShowcase } from './components/console/ConsoleShowcase';
+import { PartnerShowcase } from './components/partner/PartnerShowcase';
+import { LifecycleSimulator } from './components/simulator/LifecycleSimulator';
+import { CampaignDeckGallery } from './components/gallery/CampaignDeckGallery';
+import { DualExperienceComparison } from './components/comparison/DualExperienceComparison';
+import { ArchitectureAssurance } from './components/architecture/ArchitectureAssurance';
+import { ImpactRoiCalculator } from './components/calculator/ImpactRoiCalculator';
+import { Footer } from './components/layout/Footer';
+import { ScreenshotViewerModal } from './components/modal/ScreenshotViewerModal';
+import { PosterModal } from './components/modal/PosterModal';
+import { ScreenshotItem, PosterItem } from './data/showcaseData';
+
+export function App() {
+ const [selectedScreenshot, setSelectedScreenshot] = useState(null);
+ const [selectedPoster, setSelectedPoster] = useState(null);
+
+ return (
+
+ {/* Main Content Area */}
+
+ {/* 1. Hero Section & Interactive Dual-Device Showcase with spacious Brand Header */}
+ setSelectedScreenshot(item)}
+ />
+
+ {/* 2. PFM Console Showcase (Executive Funder Backoffice) */}
+ setSelectedScreenshot(item)}
+ />
+
+ {/* 3. PFM Partner Showcase (Grantee Field Delivery & Evidence) */}
+ setSelectedScreenshot(item)}
+ />
+
+ {/* 4. Interactive 5-Phase Fiduciary Lifecycle Simulator */}
+
+
+ {/* 5. Strategic 6-Poster Campaign Deck Gallery */}
+ setSelectedPoster(poster)}
+ />
+
+ {/* 6. Dual Experience Comparison Matrix */}
+
+
+ {/* 7. Enterprise Architecture & 10 Cardinal Business Rules */}
+
+
+ {/* 8. Interactive Governance & ROI Calculator */}
+
+
+
+ {/* Footer */}
+
+
+ {/* Interactive Lightboxes & Modals */}
+
setSelectedScreenshot(null)}
+ />
+
+ setSelectedPoster(null)}
+ />
+
+ );
+}
+
+export default App;
diff --git a/PostFundManagement.ShowcaseUI/src/components/architecture/ArchitectureAssurance.tsx b/PostFundManagement.ShowcaseUI/src/components/architecture/ArchitectureAssurance.tsx
new file mode 100644
index 0000000..63de5c2
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/architecture/ArchitectureAssurance.tsx
@@ -0,0 +1,105 @@
+import React from 'react';
+import {
+ Layers,
+ Cpu,
+ HardDrive,
+ ShieldCheck,
+ Database,
+ Atom,
+ Sparkles,
+ CheckCircle2,
+ Terminal,
+ Server
+} from 'lucide-react';
+import { ARCHITECTURE_HIGHLIGHTS } from '../../data/showcaseData';
+
+export const ArchitectureAssurance: React.FC = () => {
+ return (
+
+ {/* Background ambient lighting */}
+
+
+
+ {/* Section Header */}
+
+
+
+ Enterprise Architecture Assurance
+
+
+ High-Performance &{' '}
+
+ Tamper-Evident Engineering
+
+
+
+ Derived directly from PFM System Requirements Specification v2.0. Built on modern Clean Architecture, .NET 10, React 19, Quartz.NET, and Garage S3 object storage.
+
+
+
+ {/* 6 Tech Highlight Cards */}
+
+ {ARCHITECTURE_HIGHLIGHTS.map((item, idx) => (
+
+
+
+ {item.subtitle}
+
+
+
+
+ {item.title}
+
+
+ {item.description}
+
+
+ ))}
+
+
+ {/* Master Business Rules Banner */}
+
+
+
+
+ Fiduciary Guarantee
+
+
+ The 10 Cardinal Business Rules (BR-001 – BR-010)
+
+
+
+
+ Strict Domain Invariant Enforcement
+
+
+
+
+
+ BR-001: Approval is Entry Point. No contract or project exists without external award reference.
+
+
+ BR-002: Automatic Contract Initiation. Award captures immediately spawn draft agreements.
+
+
+ BR-003: No Uncontrolled Disbursement. Zero capital release without verified evidence proofs.
+
+
+ BR-004: Evidence-Based Performance. Uploaded files must substantiate milestone deliverables.
+
+
+ BR-005: Single Source of Truth. Recipient KYC and bank details captured once, referenced immutably.
+
+
+ BR-010: Automated Portfolio Roll-Up. Activity metrics roll up to Programme, Portfolio, and Donor tiers.
+
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/calculator/ImpactRoiCalculator.tsx b/PostFundManagement.ShowcaseUI/src/components/calculator/ImpactRoiCalculator.tsx
new file mode 100644
index 0000000..d6fd33c
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/calculator/ImpactRoiCalculator.tsx
@@ -0,0 +1,196 @@
+import React, { useState } from 'react';
+import {
+ Calculator,
+ TrendingUp,
+ Clock,
+ ShieldCheck,
+ Sparkles,
+ DollarSign
+} from 'lucide-react';
+
+export const ImpactRoiCalculator: React.FC = () => {
+ const [portfolioCapital, setPortfolioCapital] = useState(50); // in Millions (ZAR)
+ const [projectCount, setProjectCount] = useState(25);
+ const [milestonesPerProject, setMilestonesPerProject] = useState(6);
+
+ // Calculations
+ const totalMilestones = projectCount * milestonesPerProject;
+ const hoursSavedPerYear = Math.round(totalMilestones * 4.5); // 4.5 hours saved per manual audit/evidence verification cycle
+ const riskMitigatedZar = (portfolioCapital * 0.18).toFixed(1); // Avg 18% unverified leakage prevented
+ const turnaroundSpeedMultiplier = '3.8x';
+
+ return (
+
+
+ {/* Section Header */}
+
+
+
+ Interactive Governance & ROI Calculator
+
+
+ Calculate Your{' '}
+
+ Fiduciary Savings & Efficiency
+
+
+
+ Estimate how automated statutory gate checks, direct milestone proof uploads, and Quartz.NET SLA monitors reduce administrative overhead and mitigate capital exposure.
+
+
+
+ {/* Calculator Main Grid */}
+
+ {/* Controls Column */}
+
+ {/* Slider 1: Capital */}
+
+
+ Total Portfolio Capital Under Management
+
+ R {portfolioCapital} Million
+
+
+
setPortfolioCapital(Number(e.target.value))}
+ className="w-full h-2 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-emerald-500"
+ />
+
+ R 5M
+ R 100M
+ R 250M+
+
+
+
+ {/* Slider 2: Projects */}
+
+
+ Number of Funded Projects / Grantees
+
+ {projectCount} Projects
+
+
+
setProjectCount(Number(e.target.value))}
+ className="w-full h-2 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-cyan-500"
+ />
+
+ 3
+ 50
+ 100+
+
+
+
+ {/* Slider 3: Milestones */}
+
+
+ Contractual Milestones per Grant Award
+
+ {milestonesPerProject} Milestones
+
+
+
setMilestonesPerProject(Number(e.target.value))}
+ className="w-full h-2 bg-slate-800 rounded-lg appearance-none cursor-pointer accent-indigo-500"
+ />
+
+ 2
+ 8
+ 15
+
+
+
+
+ Underlying Model: Estimates based on independent development finance audits comparing manual spreadsheet evidence gathering against PFM automated gate clearances.
+
+
+
+ {/* Results Output Column */}
+
+
+ {/* Metric 1 */}
+
+
+ Risk Exposure Avoided
+
+
+
+ R {riskMitigatedZar}M
+
+
+ Uncontrolled tranches shielded by BR-003 condition precedent gates.
+
+
+
+ {/* Metric 2 */}
+
+
+ Annual Audit Hours Saved
+
+
+
+ {hoursSavedPerYear.toLocaleString()} hrs
+
+
+ Manual document chasing and reconciliation automated.
+
+
+
+ {/* Metric 3 */}
+
+
+ Tranche Velocity
+
+
+
+ {turnaroundSpeedMultiplier} Faster
+
+
+ From partner evidence submission to verified tranche release.
+
+
+
+ {/* Metric 4 */}
+
+
+ Auditable Proof Artifacts
+
+
+
+ {totalMilestones} Proofs
+
+
+ Indexed with immutable SHA signatures in Garage S3 vault.
+
+
+
+
+ {/* Telemetry pill */}
+
+
+
+ Automated Statutory Governance Protection
+
+
BR-001 — BR-010 Enforced
+
+
+
+
+
+ );
+};
diff --git a/PostFundManagement.ShowcaseUI/src/components/comparison/DualExperienceComparison.tsx b/PostFundManagement.ShowcaseUI/src/components/comparison/DualExperienceComparison.tsx
new file mode 100644
index 0000000..e20982d
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/comparison/DualExperienceComparison.tsx
@@ -0,0 +1,82 @@
+import React from 'react';
+import {
+ ShieldCheck,
+ FileCheck2,
+ Check,
+ ArrowRight,
+ ExternalLink,
+ Sparkles
+} from 'lucide-react';
+import { COMPARISON_FEATURES } from '../../data/showcaseData';
+
+export const DualExperienceComparison: React.FC = () => {
+ return (
+
+
+ {/* Section Header */}
+
+
+
+ Dual Experience Matrix
+
+
+ PFM Console vs.{' '}
+
+ PFM Partner
+
+
+
+ Engineered with clear separation of duties. Backoffice fiduciary gatekeepers govern portfolios, while field implementation teams deliver verified outcomes.
+
+
+
+ {/* Comparison Table */}
+
+
+
+
+
+ Functional Dimension
+
+
+
+
+ PFM Console (Funders & DFIs)
+
+
+
+
+
+ PFM Partner (Grantees & Contractors)
+
+
+
+
+
+ {COMPARISON_FEATURES.map((row, idx) => (
+
+
+ {row.feature}
+
+
+
+
+ {row.console}
+
+
+
+
+
+ {row.partner}
+
+
+
+ ))}
+
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/console/ConsoleShowcase.tsx b/PostFundManagement.ShowcaseUI/src/components/console/ConsoleShowcase.tsx
new file mode 100644
index 0000000..7391c9d
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/console/ConsoleShowcase.tsx
@@ -0,0 +1,214 @@
+import React, { useState } from 'react';
+import {
+ ShieldCheck,
+ BarChart3,
+ Layers,
+ Calendar,
+ FileCheck,
+ Lock,
+ AlertTriangle,
+ TrendingUp,
+ Users,
+ ExternalLink,
+ ChevronRight,
+ Maximize2
+} from 'lucide-react';
+import { SCREENSHOTS, ScreenshotItem } from '../../data/showcaseData';
+
+interface ConsoleShowcaseProps {
+ onOpenScreenshot: (item: ScreenshotItem) => void;
+}
+
+export const ConsoleShowcase: React.FC = ({ onOpenScreenshot }) => {
+ const consoleScreenshots = SCREENSHOTS.filter((s) => s.platform === 'PFM Console');
+ const [selectedCategory, setSelectedCategory] = useState('All');
+
+ const categories = ['All', 'Dashboard', 'WBS & Gantt', 'Governance & Gate'];
+
+ const filteredScreens = selectedCategory === 'All'
+ ? consoleScreenshots
+ : consoleScreenshots.filter((s) => s.category === selectedCategory);
+
+ return (
+
+ {/* Background ambient glow */}
+
+
+
+
+ {/* Section Header */}
+
+
+
+
+ Institutional Funder Backoffice Suite
+
+
+ PFM Console •{' '}
+
+ Executive Portfolio Command
+
+
+
+ Equip investment committees, CFOs, and programme directors with real-time capital deployment telemetry, automated statutory gate checks, and direct beneficiary impact verification.
+
+
+
+
+
+
+ {/* 3 Core Pillar Cards */}
+
+ {/* Pillar 1 */}
+
+
+
+
+
+ PILLAR 01
+ •
+ Capital Scale
+
+
+ Multi-Portfolio Capital Deployment
+
+
+ Filter commitments, released tranches (R 150k deployed), and active awards dynamically by programme, sector, and financial period with automated rollups.
+
+
+ R 21.0m Governed
+ BR-010 Compliant
+
+
+
+ {/* Pillar 2 */}
+
+
+
+
+
+ PILLAR 02
+ •
+ Fiduciary Gating
+
+
+ 100% Statutory Gate Enforcement
+
+
+ Enforce Business Rule BR-003: no payment or disbursement is approved without verified banking KYC, signed legal agreements, and timestamped proofs.
+
+
+ 0% Exposure
+ BR-003 Hard Gate
+
+
+
+ {/* Pillar 3 */}
+
+
+
+
+
+ PILLAR 03
+ •
+ WBS & Gantt
+
+
+ Chronological Gantt & Variance Audits
+
+
+ 55-day span milestone chronology with automated variance detection comparing work breakdown task actuals against allocated budgets.
+
+
+ Realized Actuals vs Budget
+ SLA Alerts
+
+
+
+
+ {/* Screenshot Category Filter & Grid */}
+
+
+ {categories.map((cat) => (
+ setSelectedCategory(cat)}
+ className={`px-3 py-1.5 rounded-lg text-xs font-semibold transition-all ${
+ selectedCategory === cat
+ ? 'bg-blue-600 text-white shadow-sm'
+ : 'text-slate-400 hover:text-slate-200'
+ }`}
+ >
+ {cat}
+
+ ))}
+
+
+
+ Showing {filteredScreens.length} Console Views
+
+
+
+ {/* Screenshot Cards Grid */}
+
+ {filteredScreens.map((screen) => (
+
onOpenScreenshot(screen)}
+ className="group cursor-pointer rounded-2xl bg-slate-900/60 border border-slate-800 hover:border-blue-500/50 overflow-hidden shadow-xl transition-all duration-300 hover:-translate-y-1"
+ >
+
+
+
+
+
+
+
+
+ {screen.category}
+
+
+
+
+
+
+ {screen.title}
+
+
+ {screen.description}
+
+
+
+ {screen.tags.map((tag) => (
+
+ #{tag}
+
+ ))}
+
+
+
+ ))}
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/gallery/CampaignDeckGallery.tsx b/PostFundManagement.ShowcaseUI/src/components/gallery/CampaignDeckGallery.tsx
new file mode 100644
index 0000000..46f885f
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/gallery/CampaignDeckGallery.tsx
@@ -0,0 +1,187 @@
+import React, { useState } from 'react';
+import {
+ FileText,
+ Maximize2,
+ ChevronRight,
+ Download,
+ CheckCircle2,
+ Users,
+ Sparkles,
+ ExternalLink
+} from 'lucide-react';
+import { CAMPAIGN_POSTERS, PosterItem } from '../../data/showcaseData';
+
+interface CampaignDeckGalleryProps {
+ onOpenPosterModal: (poster: PosterItem) => void;
+}
+
+export const CampaignDeckGallery: React.FC = ({ onOpenPosterModal }) => {
+ const [selectedPosterId, setSelectedPosterId] = useState(1);
+
+ const currentPoster = CAMPAIGN_POSTERS.find((p) => p.id === selectedPosterId) || CAMPAIGN_POSTERS[0];
+
+ return (
+
+ {/* Ambient background glow */}
+
+
+
+ {/* Section Header */}
+
+
+
+
+ Official 6-Page Campaign Deck
+
+
+ PFM Platform Marketing Posters •{' '}
+
+ Strategic Campaign
+
+
+
+ Explore the official marketing campaign series showcasing field-level milestone proof, fiduciary portfolio command, institutional SSO security, and interactive WBS Gantt oversight.
+
+
+
+
+
+
+ {/* Poster Tabs Selector */}
+
+ {CAMPAIGN_POSTERS.map((poster) => {
+ const isSelected = poster.id === selectedPosterId;
+ return (
+
setSelectedPosterId(poster.id)}
+ className={`p-3 rounded-xl border text-left transition-all ${
+ isSelected
+ ? 'bg-purple-950/40 border-purple-500/60 shadow-lg shadow-purple-500/10'
+ : 'bg-slate-900/60 border-slate-800/80 hover:bg-slate-800/60'
+ }`}
+ >
+
+
+ POSTER {poster.number.split('/')[0]}
+
+
+ {poster.platform === 'PFM Console' ? 'Console' : 'Partner'}
+
+
+
+ {poster.badge}
+
+
+ );
+ })}
+
+
+ {/* Selected Poster Showcase Card */}
+
+ {/* Poster Image Preview */}
+
onOpenPosterModal(currentPoster)}>
+
+
+
+
+ {/* Zoom pill */}
+
+
+ Zoom Poster
+
+
+
+
+ {/* Poster Narrative & Highlights */}
+
+
+
+
+ {currentPoster.number}
+
+ •
+
+ {currentPoster.platform}
+
+
+
+ {currentPoster.title}
+
+
+ {currentPoster.subtitle}
+
+
+
+ {/* Poster Metrics Grid */}
+
+ {currentPoster.metrics.map((metric, idx) => (
+
+
{metric.label}
+
{metric.value}
+
{metric.detail}
+
+ ))}
+
+
+ {/* 3 Numbered Key Takeaways */}
+
+ {currentPoster.keyHighlights.map((hl) => (
+
+
+ {hl.number}
+
+
+
{hl.title}
+
{hl.description}
+
+
+ ))}
+
+
+ {/* Target Market Tags */}
+
+
+
+ Target Market Audience
+
+
+ {currentPoster.targetMarket.map((item, idx) => (
+
+ {item}
+
+ ))}
+
+
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/hero/HeroSection.tsx b/PostFundManagement.ShowcaseUI/src/components/hero/HeroSection.tsx
new file mode 100644
index 0000000..103481c
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/hero/HeroSection.tsx
@@ -0,0 +1,125 @@
+import React, { useState } from 'react';
+import {
+ ShieldCheck,
+ Sparkles,
+ ArrowRight,
+ CheckCircle2,
+ Layers,
+ ExternalLink,
+ Laptop,
+ Users2,
+ FileCheck2,
+ Compass
+} from 'lucide-react';
+import { BrandLogo } from '../ui/BrandLogo';
+import { InteractiveDeviceFrame } from './InteractiveDeviceFrame';
+import { SHOWCASE_STATS, ScreenshotItem } from '../../data/showcaseData';
+
+interface HeroSectionProps {
+ onOpenScreenshot: (item: ScreenshotItem) => void;
+}
+
+export const HeroSection: React.FC = ({ onOpenScreenshot }) => {
+ const [activeMode, setActiveMode] = useState<'console' | 'partner' | 'unified'>('console');
+
+ return (
+
+ {/* Background ambient lighting */}
+
+
+
+
+ {/* Grid overlay */}
+
+
+
+ {/* Spacious, uncrowded brand header */}
+
+
+
+ {/* Clean minimal CTA to jump straight into the experience */}
+
+
+
+ {/* Main Hero Header */}
+
+ {/* Pill Badge */}
+
+
+
+ Post-Fund Management, Performance & Impact Platform
+
+ •
+ SRS v2.0 Production Suite
+
+
+ {/* Main Title */}
+
+ Two Portals.{' '}
+
+ One Unified Fiduciary Lifecycle.
+
+
+
+ {/* Subtitle */}
+
+ From sanctioned award intake to audited field delivery. PFM bridges the gap between{' '}
+ Institutional Funders (PFM Console) and{' '}
+ Implementing Grantees (PFM Partner) with zero uncontrolled disbursements.
+
+
+ {/* CTAs */}
+
+
+
+ {/* Live Device Showcase */}
+
+
+
+
+ {/* Stats Ticker */}
+
+ {SHOWCASE_STATS.map((stat, idx) => (
+
+
+ {stat.value}
+
+
+ {stat.label}
+
+
+ {stat.detail}
+
+
+ ))}
+
+
+
+ );
+};
diff --git a/PostFundManagement.ShowcaseUI/src/components/hero/InteractiveDeviceFrame.tsx b/PostFundManagement.ShowcaseUI/src/components/hero/InteractiveDeviceFrame.tsx
new file mode 100644
index 0000000..02e248b
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/hero/InteractiveDeviceFrame.tsx
@@ -0,0 +1,221 @@
+import React, { useState } from 'react';
+import {
+ Maximize2,
+ ShieldCheck,
+ FileCheck2,
+ Layers,
+ ExternalLink,
+ CheckCircle2,
+ ChevronRight,
+ Sparkles,
+ Info
+} from 'lucide-react';
+import { SCREENSHOTS, ScreenshotItem } from '../../data/showcaseData';
+
+interface InteractiveDeviceFrameProps {
+ onOpenScreenshot: (item: ScreenshotItem) => void;
+ activeMode: 'console' | 'partner' | 'unified';
+ setActiveMode: (mode: 'console' | 'partner' | 'unified') => void;
+}
+
+export const InteractiveDeviceFrame: React.FC = ({
+ onOpenScreenshot,
+ activeMode,
+ setActiveMode,
+}) => {
+ const [activeHotspot, setActiveHotspot] = useState(null);
+
+ const consoleItem = SCREENSHOTS.find((s) => s.id === 'console-primary') || SCREENSHOTS[0];
+ const partnerItem = SCREENSHOTS.find((s) => s.id === 'partner-primary') || SCREENSHOTS[1];
+
+ const currentItem = activeMode === 'partner' ? partnerItem : consoleItem;
+
+ return (
+
+ {/* Platform Switcher Controls */}
+
+
+ setActiveMode('console')}
+ className={`flex items-center gap-2 px-4 py-2 rounded-lg text-xs sm:text-sm font-semibold transition-all ${
+ activeMode === 'console'
+ ? 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white shadow-md shadow-blue-500/20'
+ : 'text-slate-400 hover:text-slate-200'
+ }`}
+ >
+
+ PFM Console (Funder Suite)
+
+ setActiveMode('partner')}
+ className={`flex items-center gap-2 px-4 py-2 rounded-lg text-xs sm:text-sm font-semibold transition-all ${
+ activeMode === 'partner'
+ ? 'bg-gradient-to-r from-emerald-600 to-teal-600 text-white shadow-md shadow-emerald-500/20'
+ : 'text-slate-400 hover:text-slate-200'
+ }`}
+ >
+
+ PFM Partner (Grantee Suite)
+
+
+
+
+
+
+ Live Application Telemetry
+
+ onOpenScreenshot(currentItem)}
+ className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-slate-900/80 border border-slate-800 hover:bg-slate-800 text-slate-300 hover:text-white transition-colors"
+ >
+
+ Full Lightbox
+
+
+
+
+ {/* Modern Device Shell */}
+
+ {/* Glow ambient background behind the frame */}
+
+
+ {/* Browser Top Bar */}
+
+
+
+ {/* Browser Address Bar */}
+
+
+ https://
+
+ {activeMode === 'partner' ? 'partner.ifri.khongisa.co.za' : 'console.ifri.khongisa.co.za'}
+
+ /workspace
+
+
+
+
+ {activeMode === 'partner' ? 'PORT 8077' : 'PORT 8076'}
+
+
+
+ {/* Browser Viewport with Image & Interactive Hotspots */}
+
+
+
+ {/* Interactive Hotspots Overlay */}
+ {currentItem.hotspots?.map((hotspot, idx) => (
+
+
setActiveHotspot(activeHotspot === idx ? null : idx)}
+ onMouseEnter={() => setActiveHotspot(idx)}
+ onMouseLeave={() => setActiveHotspot(null)}
+ className="relative flex items-center justify-center w-7 h-7 rounded-full bg-cyan-500/90 text-slate-950 font-bold text-xs shadow-lg shadow-cyan-500/50 hover:scale-125 transition-transform"
+ aria-label={`Hotspot ${hotspot.title}`}
+ >
+
+ {idx + 1}
+
+
+ {/* Tooltip Card */}
+ {activeHotspot === idx && (
+
+
+
+ {hotspot.title}
+
+
+ {hotspot.description}
+
+
+ )}
+
+ ))}
+
+ {/* Bottom Bar Info Overlay */}
+
+
+
+
+ {currentItem.platform}
+
+
+ {currentItem.category}
+
+
+
+ {currentItem.title}
+
+
+ {currentItem.subtitle}
+
+
+
+
onOpenScreenshot(currentItem)}
+ className="px-3.5 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 backdrop-blur-md border border-white/20 text-xs font-semibold text-white transition-all flex items-center gap-1.5 shadow-lg"
+ >
+ Explore High-Res
+
+
+
+
+
+
+ {/* Hotspots Quick Guide */}
+
+ {currentItem.hotspots?.map((hotspot, idx) => (
+
setActiveHotspot(idx)}
+ onMouseLeave={() => setActiveHotspot(null)}
+ className={`p-3 rounded-xl border transition-all cursor-pointer ${
+ activeHotspot === idx
+ ? 'bg-slate-900 border-cyan-500/60 shadow-lg shadow-cyan-500/10'
+ : 'bg-slate-950/50 border-slate-800/80 hover:bg-slate-900/60'
+ }`}
+ >
+
+
+ {idx + 1}
+
+
+ {hotspot.title}
+
+
+
+ {hotspot.description}
+
+
+ ))}
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/layout/Footer.tsx b/PostFundManagement.ShowcaseUI/src/components/layout/Footer.tsx
new file mode 100644
index 0000000..3fda34b
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/layout/Footer.tsx
@@ -0,0 +1,130 @@
+import React from 'react';
+import {
+ ShieldCheck,
+ Layers,
+ ExternalLink,
+ FileText,
+ Code2,
+ Cpu,
+ HardDrive,
+ Sparkles
+} from 'lucide-react';
+import { BrandLogo } from '../ui/BrandLogo';
+
+export const Footer: React.FC = () => {
+ return (
+
+
+
+ {/* Brand Col */}
+
+
+
+ The enterprise post-fund management, performance, and impact governance suite. Bridging institutional funders and field implementing partners with zero uncontrolled disbursements.
+
+
+
+ SRS v2.0 Specification
+
+
+ Production Architecture
+
+
+
+
+ {/* Col 1: Applications */}
+
+
+ Application Portals
+
+
+
+
+ {/* Col 2: Modules & Capabilities */}
+
+
+ Core Modules
+
+
+ M01 Award Intake & Registration
+ M02 Contract & Agreement Versioning
+ M03 Recipient Onboarding & KYC
+ M04 Project WBS & Gantt Scheduling
+ M06 Disbursement & Gate Control
+ M07 Milestone Evidence Vault
+
+
+
+ {/* Col 3: Architecture */}
+
+
+ Technology Core
+
+
+ .NET 10 (C# 13) Clean DDD
+ React 19 + TypeScript 5.8
+ Quartz.NET Dedicated Daemon Host
+ Garage S3 Pre-Signed Storage
+ Duende IdentityServer SSO
+ PostgreSQL 14+ & HybridCache
+
+
+
+
+ {/* Bottom Bar */}
+
+
+ © 2026 Post Fund Management Platform (PFM). All rights reserved.
+
+
+ Security by Duende STS
+ •
+ BR-001 to BR-010 Compliant
+ •
+ POPIA Safeguards
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/modal/PosterModal.tsx b/PostFundManagement.ShowcaseUI/src/components/modal/PosterModal.tsx
new file mode 100644
index 0000000..726cf1d
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/modal/PosterModal.tsx
@@ -0,0 +1,82 @@
+import React, { useEffect } from 'react';
+import { X, Download, Maximize2, ExternalLink } from 'lucide-react';
+import { PosterItem } from '../../data/showcaseData';
+
+interface PosterModalProps {
+ poster: PosterItem | null;
+ onClose: () => void;
+}
+
+export const PosterModal: React.FC = ({ poster, onClose }) => {
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === 'Escape') onClose();
+ };
+ if (poster) {
+ document.body.style.overflow = 'hidden';
+ window.addEventListener('keydown', handleKeyDown);
+ }
+ return () => {
+ document.body.style.overflow = 'auto';
+ window.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [poster, onClose]);
+
+ if (!poster) return null;
+
+ return (
+
+
e.stopPropagation()}
+ >
+ {/* Top Bar */}
+
+
+
+ {poster.number}
+
+ •
+
+ {poster.title}
+
+
+
+
+
+
+ {/* Poster Image */}
+
+
+
+
+ {/* Bottom Banner */}
+
+ {poster.coreProposition}
+ {poster.platform}
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/modal/ScreenshotViewerModal.tsx b/PostFundManagement.ShowcaseUI/src/components/modal/ScreenshotViewerModal.tsx
new file mode 100644
index 0000000..86bb587
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/modal/ScreenshotViewerModal.tsx
@@ -0,0 +1,92 @@
+import React, { useEffect } from 'react';
+import { X, ExternalLink, ShieldCheck, FileCheck2, Tag } from 'lucide-react';
+import { ScreenshotItem } from '../../data/showcaseData';
+
+interface ScreenshotViewerModalProps {
+ item: ScreenshotItem | null;
+ onClose: () => void;
+}
+
+export const ScreenshotViewerModal: React.FC = ({ item, onClose }) => {
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === 'Escape') onClose();
+ };
+ if (item) {
+ document.body.style.overflow = 'hidden';
+ window.addEventListener('keydown', handleKeyDown);
+ }
+ return () => {
+ document.body.style.overflow = 'auto';
+ window.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [item, onClose]);
+
+ if (!item) return null;
+
+ return (
+
+
e.stopPropagation()}
+ >
+ {/* Top Header */}
+
+
+
+ {item.platform}
+
+
+ {item.title}
+
+
+
+
+
+
+
+
+ {/* Image Content */}
+
+
+
+
+ {/* Footer Details */}
+
+
+
+ {item.subtitle}
+
+
+ {item.description}
+
+
+
+
+ {item.tags.map((tag) => (
+
+ #{tag}
+
+ ))}
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/partner/PartnerShowcase.tsx b/PostFundManagement.ShowcaseUI/src/components/partner/PartnerShowcase.tsx
new file mode 100644
index 0000000..5531540
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/partner/PartnerShowcase.tsx
@@ -0,0 +1,212 @@
+import React, { useState } from 'react';
+import {
+ FileCheck2,
+ UploadCloud,
+ MessageSquare,
+ KeyRound,
+ CheckCircle,
+ Clock,
+ ShieldAlert,
+ ExternalLink,
+ Maximize2,
+ FileSignature
+} from 'lucide-react';
+import { SCREENSHOTS, ScreenshotItem } from '../../data/showcaseData';
+
+interface PartnerShowcaseProps {
+ onOpenScreenshot: (item: ScreenshotItem) => void;
+}
+
+export const PartnerShowcase: React.FC = ({ onOpenScreenshot }) => {
+ const partnerScreenshots = SCREENSHOTS.filter((s) => s.platform === 'PFM Partner');
+ const [selectedCategory, setSelectedCategory] = useState('All');
+
+ const categories = ['All', 'Dashboard', 'Evidence & Proof', 'Communications', 'Onboarding'];
+
+ const filteredScreens = selectedCategory === 'All'
+ ? partnerScreenshots
+ : partnerScreenshots.filter((s) => s.category === selectedCategory);
+
+ return (
+
+ {/* Background ambient glow */}
+
+
+
+
+ {/* Section Header */}
+
+
+
+
+ Grantee & Implementing Partner Suite
+
+
+ PFM Partner •{' '}
+
+ Field Delivery & Evidence Hub
+
+
+
+ Empower implementing teams to manage sanctioned grant agreements, execute work-breakdown activities, and upload tamper-evident proofs directly against funding covenants.
+
+
+
+
+
+
+ {/* 3 Core Partner Pillars */}
+
+ {/* Pillar 1 */}
+
+
+
+
+
+ PILLAR 01
+ •
+ Evidence Vault
+
+
+ Granular Activity Proof Uploads
+
+
+ Attach statutory documents, invoices, and geotagged photographs directly to milestones with pre-signed S3 storage and immediate SHA verification.
+
+
+ 100% Traceable
+ Garage S3 Vault
+
+
+
+ {/* Pillar 2 */}
+
+
+
+
+
+ PILLAR 02
+ •
+ Direct Comms
+
+
+ Direct Programme Officer Comms
+
+
+ Eliminate lost email chains. Built-in contextual messaging links every query, revision request, and milestone note directly into an auditable project thread.
+
+
+ Direct Inbox
+ Audit Logged
+
+
+
+ {/* Pillar 3 */}
+
+
+
+
+
+ PILLAR 03
+ •
+ Rapid Mobilization
+
+
+ Statutory SSO Onboarding & Tranches
+
+
+ Single-token statutory onboarding invitations allow instant portal mobilization, KYC compliance verification, and clear visibility into covenant-tied tranches.
+
+
+ Zero Friction
+ Duende STS Auth
+
+
+
+
+ {/* Screenshot Category Filter & Grid */}
+
+
+ {categories.map((cat) => (
+ setSelectedCategory(cat)}
+ className={`px-3 py-1.5 rounded-lg text-xs font-semibold transition-all ${
+ selectedCategory === cat
+ ? 'bg-emerald-600 text-white shadow-sm'
+ : 'text-slate-400 hover:text-slate-200'
+ }`}
+ >
+ {cat}
+
+ ))}
+
+
+
+ Showing {filteredScreens.length} Partner Views
+
+
+
+ {/* Screenshot Cards Grid */}
+
+ {filteredScreens.map((screen) => (
+
onOpenScreenshot(screen)}
+ className="group cursor-pointer rounded-2xl bg-slate-900/60 border border-slate-800 hover:border-emerald-500/50 overflow-hidden shadow-xl transition-all duration-300 hover:-translate-y-1"
+ >
+
+
+
+
+
+
+
+
+ {screen.category}
+
+
+
+
+
+
+ {screen.title}
+
+
+ {screen.description}
+
+
+
+ {screen.tags.map((tag) => (
+
+ #{tag}
+
+ ))}
+
+
+
+ ))}
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/simulator/LifecycleSimulator.tsx b/PostFundManagement.ShowcaseUI/src/components/simulator/LifecycleSimulator.tsx
new file mode 100644
index 0000000..16539fd
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/simulator/LifecycleSimulator.tsx
@@ -0,0 +1,273 @@
+import React, { useState } from 'react';
+import {
+ Play,
+ RotateCcw,
+ CheckCircle2,
+ ShieldCheck,
+ FileCheck2,
+ Lock,
+ DollarSign,
+ ArrowRight,
+ Sparkles,
+ CheckCircle,
+ FileText,
+ Clock,
+ Layers
+} from 'lucide-react';
+import confetti from 'canvas-confetti';
+import { SIMULATION_STEPS } from '../../data/showcaseData';
+
+export const LifecycleSimulator: React.FC = () => {
+ const [currentStepIndex, setCurrentStepIndex] = useState(0);
+ const [completedSteps, setCompletedSteps] = useState([0]);
+
+ const activeStep = SIMULATION_STEPS[currentStepIndex];
+
+ const handleNextStep = () => {
+ if (currentStepIndex < SIMULATION_STEPS.length - 1) {
+ const nextIndex = currentStepIndex + 1;
+ setCurrentStepIndex(nextIndex);
+ if (!completedSteps.includes(nextIndex)) {
+ setCompletedSteps([...completedSteps, nextIndex]);
+ }
+
+ // If reaching the final step (Disbursement Release), launch celebratory confetti!
+ if (nextIndex === SIMULATION_STEPS.length - 1) {
+ confetti({
+ particleCount: 100,
+ spread: 70,
+ origin: { y: 0.6 },
+ colors: ['#06b6d4', '#10b981', '#3b82f6', '#8b5cf6'],
+ });
+ }
+ }
+ };
+
+ const handleReset = () => {
+ setCurrentStepIndex(0);
+ setCompletedSteps([0]);
+ };
+
+ return (
+
+ {/* Background ambient lighting */}
+
+
+
+ {/* Header */}
+
+
+
+ Interactive Lifecycle Simulator
+
+
+ Experience the Complete{' '}
+
+ Fiduciary Lifecycle
+
+
+
+ Follow a R 1,000,000 sanctioned award across both PFM Console and PFM Partner. See how business rules BR-001 through BR-010 guarantee zero uncontrolled capital release.
+
+
+
+ {/* Stepper Progress Bar */}
+
+
+
+
+ {SIMULATION_STEPS.map((step, idx) => {
+ const isCurrent = currentStepIndex === idx;
+ const isCompleted = completedSteps.includes(idx);
+
+ return (
+
{
+ setCurrentStepIndex(idx);
+ if (!completedSteps.includes(idx)) {
+ setCompletedSteps([...completedSteps, idx]);
+ }
+ }}
+ className={`flex md:flex-col items-center gap-3 p-3 md:p-2 rounded-xl transition-all text-left md:text-center ${
+ isCurrent
+ ? 'bg-slate-900 md:bg-transparent scale-105'
+ : 'opacity-70 hover:opacity-100'
+ }`}
+ >
+
+ {isCompleted && !isCurrent ? (
+
+ ) : (
+ idx + 1
+ )}
+
+
+
+ {step.step}
+
+
+ {step.title}
+
+
+
+ );
+ })}
+
+
+
+ {/* Step Card Details & Interactive Console View */}
+
+ {/* Left Column: Context & Narrative */}
+
+
+
+ {activeStep.actor}
+
+
+ Phase {currentStepIndex + 1} of 5
+
+
+
+
+
+ {activeStep.title}
+
+
+ {activeStep.summary}
+
+
+
+
+
+
+ Statutory Rule Enforcement
+
+
+ {activeStep.details}
+
+
+
+
+ System Trace: {activeStep.systemAction}
+
+
+ {/* Stepper Buttons */}
+
+ {currentStepIndex < SIMULATION_STEPS.length - 1 ? (
+
+ Proceed to Next Step
+
+
+ ) : (
+
+
+ Restart Simulation
+
+ )}
+
+
+
+ Reset
+
+
+
+
+ {/* Right Column: Visual Telemetry Display */}
+
+
+ {/* Terminal-like Header */}
+
+
+
+
+
+
pfm-runtime-telemetry.log
+
+
+
+ SYNCED
+
+
+
+ {/* Dynamic State Telemetry Block */}
+
+
+ AWARD_ID:
+ PFM-2026-AWD-0091
+
+
+ SANCTIONED_AMOUNT:
+ ZAR 1,000,000.00
+
+
+ DISBURSEMENT_GATE:
+ = 4 ? 'text-emerald-400 font-bold' : 'text-amber-400 font-bold'}>
+ {currentStepIndex >= 4 ? 'CLEARED (BR-003 ENFORCED)' : 'LOCKED (PENDING EVIDENCE)'}
+
+
+
+ GARAGE_S3_EVIDENCE_PROOFS:
+ = 2 ? 'text-emerald-400' : 'text-slate-600'}>
+ {currentStepIndex >= 2 ? '2 VERIFIED SHA-256 ARTIFACTS' : '0 UPLOADED'}
+
+
+
+ RECIPIENT_KYC_STATUS:
+ = 1 ? 'text-emerald-400' : 'text-slate-600'}>
+ {currentStepIndex >= 1 ? 'VERIFIED (SSO AUTHENTICATED)' : 'AWAITING INVITATION ACCEPTANCE'}
+
+
+
+ DEPLOYED_TRANCHE:
+ = 4 ? 'text-emerald-400 font-bold' : 'text-slate-500'}>
+ {currentStepIndex >= 4 ? 'ZAR 350,000.00 (TRANCHE 1 RELEASED)' : 'ZAR 0.00 (EXPOSURE MITIGATED)'}
+
+
+
+
+ {/* Interactive Visual Status Bar */}
+
+
+ FIDUCIARY INTEGRITY INDEX:
+
+ {Math.min(100, (currentStepIndex + 1) * 20)}%
+
+
+
+
+
+
+
+
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/components/ui/BrandLogo.tsx b/PostFundManagement.ShowcaseUI/src/components/ui/BrandLogo.tsx
new file mode 100644
index 0000000..3265fd4
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/components/ui/BrandLogo.tsx
@@ -0,0 +1,161 @@
+import React, { useId } from 'react';
+
+export interface BrandLogoProps {
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
+ variant?: 'icon-only' | 'full';
+ showGlow?: boolean;
+ className?: string;
+ animateOnHover?: boolean;
+}
+
+const sizeMap = {
+ xs: 24,
+ sm: 32,
+ md: 44,
+ lg: 56,
+ xl: 72,
+};
+
+export const BrandLogo: React.FC = ({
+ size = 'lg',
+ variant = 'full',
+ showGlow = true,
+ className = '',
+ animateOnHover = true,
+}) => {
+ const uniqueId = useId().replace(/:/g, '');
+ const pixelSize = typeof size === 'number' ? size : sizeMap[size] || 56;
+
+ const glowId = `pfm-ambient-${uniqueId}`;
+ const topGradId = `pfm-top-${uniqueId}`;
+ const leftGradId = `pfm-left-${uniqueId}`;
+ const rightGradId = `pfm-right-${uniqueId}`;
+ const coreGradId = `pfm-core-${uniqueId}`;
+ const filterId = `pfm-filter-${uniqueId}`;
+
+ return (
+
+
+ {showGlow && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Deep Contrast Foundation Disk */}
+
+
+
+
+ {/* Top Facet */}
+
+
+ {/* Left Facet */}
+
+
+ {/* Right Facet */}
+
+
+ {/* Inner Central Star */}
+
+
+
+
+ {variant === 'full' && (
+
+
+
+ Post Fund Management
+
+
+ PFM Suite
+
+
+
+ Performance, Governance & Impact Platform
+
+
+ )}
+
+ );
+};
+
diff --git a/PostFundManagement.ShowcaseUI/src/data/showcaseData.ts b/PostFundManagement.ShowcaseUI/src/data/showcaseData.ts
new file mode 100644
index 0000000..545f631
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/data/showcaseData.ts
@@ -0,0 +1,531 @@
+export interface PosterItem {
+ id: number;
+ number: string;
+ badge: string;
+ title: string;
+ subtitle: string;
+ platform: 'PFM Console' | 'PFM Partner';
+ image: string;
+ coreProposition: string;
+ metrics: { label: string; value: string; detail: string }[];
+ keyHighlights: { number: string; title: string; description: string }[];
+ targetMarket: string[];
+}
+
+export interface ScreenshotItem {
+ id: string;
+ title: string;
+ subtitle: string;
+ platform: 'PFM Console' | 'PFM Partner';
+ category: 'Dashboard' | 'WBS & Gantt' | 'Governance & Gate' | 'Evidence & Proof' | 'Communications' | 'Onboarding';
+ image: string;
+ description: string;
+ hotspots?: { x: number; y: number; title: string; description: string }[];
+ tags: string[];
+}
+
+export interface FeatureHighlight {
+ id: string;
+ title: string;
+ subtitle: string;
+ description: string;
+ iconName: string;
+ platform: 'console' | 'partner' | 'both';
+ metric: string;
+ metricLabel: string;
+ bulletPoints: string[];
+}
+
+export const SHOWCASE_STATS = [
+ {
+ value: 'R 21.0M+',
+ label: 'Statutory Capital Governed',
+ detail: 'Under active fiduciary management',
+ highlight: 'text-indigo-400',
+ },
+ {
+ value: '0% Exposure',
+ label: 'Unverified Disbursements',
+ detail: 'Strict statutory gate enforcement',
+ highlight: 'text-emerald-400',
+ },
+ {
+ value: '100% Traceable',
+ label: 'Milestone Evidence Trails',
+ detail: 'Tamper-evident S3 object vault',
+ highlight: 'text-cyan-400',
+ },
+ {
+ value: '1.2k+ Lives',
+ label: 'M&E Verified Beneficiaries',
+ detail: 'POPIA-compliant direct telemetry',
+ highlight: 'text-purple-400',
+ },
+];
+
+export const CAMPAIGN_POSTERS: PosterItem[] = [
+ {
+ id: 1,
+ number: '01 / 06',
+ badge: 'PARTNER COLLABORATION',
+ title: 'Implementing Partner Suite',
+ subtitle: 'Real-Time Milestone Oversight, Direct Programme Officer Comms & Live Capital Analytics',
+ platform: 'PFM Partner',
+ image: '/assets/marketing/1.jpeg',
+ coreProposition: 'Connect field-level contractors and recipient NGOs directly with funding administrators for seamless project execution.',
+ metrics: [
+ { label: 'Access Control', value: 'SSO Ready', detail: 'Statutory Invitation Verified' },
+ { label: 'Comms Channel', value: 'Direct Inbox', detail: 'Programme Officer Messaging' },
+ { label: 'Audited Proofs', value: '100% Traceable', detail: 'Substantiating Indicator Outcomes' },
+ { label: 'Tranche Release', value: 'Covenant-Tied', detail: 'Automated Precedent Checks' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Contract Clarity',
+ description: 'View approved grant capital, governing portfolios, linked projects, and countersigned PDF agreements in one unified workspace.',
+ },
+ {
+ number: '02',
+ title: 'Proof Workflows',
+ description: 'Attach statutory documents, financial invoices, and field receipts directly to contractual milestones with real-time review badges.',
+ },
+ {
+ number: '03',
+ title: 'Risk Visibility',
+ description: 'Automated overdue milestone indicators and sector compliance tags keep field coordinators ahead of audit covenants.',
+ },
+ ],
+ targetMarket: ['Fieldwork Coordinators', 'Grant Recipients', 'Engineering & Infrastructure Contractors', 'Community Development NGOs'],
+ },
+ {
+ id: 2,
+ number: '02 / 06',
+ badge: 'EVIDENCE & GOVERNANCE',
+ title: 'Field-Level Activity Oversight & Evidence Verification',
+ subtitle: 'From Sanctioned Grant Award to Verified Field Delivery: Turn Contractual Milestones into Auditable Proof',
+ platform: 'PFM Partner',
+ image: '/assets/marketing/2.jpeg',
+ coreProposition: 'Empower implementing teams to manage sanctioned grant agreements, execute work-breakdown activities, and upload tamper-evident proofs.',
+ metrics: [
+ { label: 'Sanctioned Capital', value: 'R 1 000 000', detail: 'Binding Grant Agreement v1' },
+ { label: 'Fulfillment Pace', value: '33% Verified', detail: '1 / 1 Statutory Gate Signed' },
+ { label: 'Evidence Trail', value: '2 Proofs', detail: 'Timestamped & Status-Tracked' },
+ { label: 'Contract Execution', value: 'Countersigned', detail: 'Instant PDF Agreement Access' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Sanctioned Award Alignment',
+ description: 'Access binding legal agreements, project scopes, and tranche disbursements mapped directly to approved award letters.',
+ },
+ {
+ number: '02',
+ title: 'Granular Activity Evidence',
+ description: 'Upload verifiable proofs against work breakdown items with immediate SHA hashing and tamper-evident storage.',
+ },
+ {
+ number: '03',
+ title: 'Proactive Compliance Alerts',
+ description: 'Keep projects on schedule with automated milestone reminders, overdue notifications, and SLA warnings.',
+ },
+ ],
+ targetMarket: ['Field Coordinators', 'Financial Controllers', 'Compliance Officers', 'Infrastructure Engineers'],
+ },
+ {
+ id: 3,
+ number: '03 / 06',
+ badge: 'ONBOARDING & VELOCITY',
+ title: 'Statutory Onboarding, SSO Access & Live Portfolio Analytics',
+ subtitle: 'Zero-Friction Partner Mobilization & Transparency',
+ platform: 'PFM Partner',
+ image: '/assets/marketing/3.jpeg',
+ coreProposition: 'Accelerate post-award mobilization from statutory invitation approval to authenticated portal access with live tranche visibility.',
+ metrics: [
+ { label: 'Access Control', value: 'SSO Ready', detail: 'Institutional Identity Gate' },
+ { label: 'Comms Channel', value: 'Direct Inbox', detail: 'Direct Funder-Partner Chat' },
+ { label: 'Audited Proofs', value: '100% Traceable', detail: 'Zero Unsubstantiated Claims' },
+ { label: 'Tranche Release', value: 'Covenant-Tied', detail: 'Milestone-Gated Releases' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Rapid Mobilization',
+ description: 'Formal onboarding invitations grant immediate portal access to complete KYC compliance, review contracts, and start delivery.',
+ },
+ {
+ number: '02',
+ title: 'Capital Transparency',
+ description: 'Eliminate payment guesswork with transparent tranche release indicators tied directly to verified milestone deliverables.',
+ },
+ {
+ number: '03',
+ title: 'Strict Multi-Tenant Isolation',
+ description: 'Every partner organization operates in an encrypted tenant boundary with immutable audit logs protecting sensitive data.',
+ },
+ ],
+ targetMarket: ['Social Impact Enterprises', 'Research Consortia', 'Municipal Agencies', 'Non-Profit Finance Leads'],
+ },
+ {
+ id: 4,
+ number: '04 / 06',
+ badge: 'ENTERPRISE SECURITY & SSO',
+ title: 'Enterprise Security & Governance Architecture',
+ subtitle: 'Enterprise SSO Identity Management, Encrypted Multi-Tenant Isolation & Tamper-Evident Audit Trails',
+ platform: 'PFM Console',
+ image: '/assets/marketing/4.jpg',
+ coreProposition: 'The foundational security infrastructure ensuring institutional funders and government development portfolios remain unbreachable.',
+ metrics: [
+ { label: 'Architecture', value: 'Clean DDD', detail: '.NET 10 + React 19' },
+ { label: 'Storage Vault', value: 'Garage S3', detail: 'Pre-Signed Object Security' },
+ { label: 'Identity Gate', value: 'Duende STS', detail: 'OIDC / OAuth 2.0 PKCE' },
+ { label: 'Scheduler', value: 'Quartz.NET', detail: 'Dedicated Daemon Host' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Institutional-Grade Identity',
+ description: 'Integrated with Skoruba Duende IdentityServer for multi-factor SSO, role-based access control, and granular tenant claims.',
+ },
+ {
+ number: '02',
+ title: 'Encrypted Multi-Tenancy',
+ description: 'Strict database tenant isolation with automatic global query filters, ensuring complete data sovereignty across portfolios.',
+ },
+ {
+ number: '03',
+ title: 'Immutable Decision Logs',
+ description: 'Every status transition, budget adjustment, evidence review, and disbursement approval writes an auditable record.',
+ },
+ ],
+ targetMarket: ['System Architects', 'CISO & InfoSec Teams', 'Compliance Auditors', 'Government Portfolio IT Leads'],
+ },
+ {
+ id: 5,
+ number: '05 / 06',
+ badge: 'EXECUTIVE COMMAND',
+ title: 'Executive Portfolio Command & Fiduciary Governance',
+ subtitle: 'Real-Time Fiduciary Command Across Every Programme & Sector: Total Portfolio Visibility, Zero Unverified Disbursements',
+ platform: 'PFM Console',
+ image: '/assets/marketing/5.jpg',
+ coreProposition: 'Equip executive funders, investment committees, and development agencies with live capital deployment telemetry and statutory gate checks.',
+ metrics: [
+ { label: 'Portfolio Value', value: 'R 21.0m', detail: 'Statutory Total Commitments' },
+ { label: 'Budget At Risk', value: 'R 0 Exposure', detail: '100% Statutory Gate Requirement' },
+ { label: 'Delivery Pace', value: '67% On Track', detail: 'Milestones Verified Index' },
+ { label: 'Verified Impact', value: '1.2k Lives', detail: 'M&E Verified Direct Beneficiaries' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Multi-Portfolio Capital Deployment',
+ description: 'Filter commitments, released tranches, and active awards dynamically by programme, sector, and financial period.',
+ },
+ {
+ number: '02',
+ title: '100% Statutory Gate Enforcement',
+ description: 'Enforce mandatory governance gates before capital release—automatically flagging at-risk budgets and unverified deliverables.',
+ },
+ {
+ number: '03',
+ title: 'M&E Impact Roll-Up',
+ description: 'Aggregate project-level results directly into executive impact metrics, connecting every rand disbursed to verified human outcomes.',
+ },
+ ],
+ targetMarket: ['Institutional Funders', 'Science Councils', 'DFIs', 'Chief Financial Officers', 'Portfolio Investment Committees'],
+ },
+ {
+ id: 6,
+ number: '06 / 06',
+ badge: 'WBS & SCHEDULE CONTROL',
+ title: 'Interactive WBS Console, Gantt Timeline & Variance Governance',
+ subtitle: 'Granular Operational Oversight From Award Intake to Final Close-Out',
+ platform: 'PFM Console',
+ image: '/assets/marketing/6.jpeg',
+ coreProposition: 'Give programme managers and M&E specialists an interactive Work Breakdown Structure console, chronological Gantt, and variance detection.',
+ metrics: [
+ { label: 'WBS Precision', value: 'Live Gantt', detail: '55-Day Span Chronology' },
+ { label: 'Cost Oversight', value: 'Variance Alerts', detail: 'Realized Actuals vs Budget' },
+ { label: 'Scope Control', value: 'Locked Gates', detail: 'Statutory Clearance Enforced' },
+ { label: 'M&E Tracking', value: 'KPI Matrices', detail: 'Site Visits & Change Control' },
+ ],
+ keyHighlights: [
+ {
+ number: '01',
+ title: 'Chronological Gantt & Milestone Mapping',
+ description: 'Visualize verified milestones, pending reviews, contractual deliverables, and work activities along an interactive timeline.',
+ },
+ {
+ number: '02',
+ title: 'Realized Actuals & Cost Audits',
+ description: 'Automatically compare work breakdown task costs against allocated project budgets to expose cost overruns and schedule slippage.',
+ },
+ {
+ number: '03',
+ title: 'Integrated Change & Site Visit Control',
+ description: 'Manage scope locks, evidence queues, beneficiary registries, and formal change requests from a single governance console.',
+ },
+ ],
+ targetMarket: ['Programme Directors', 'M&E Specialists', 'Grant Operations Managers', 'Risk & Compliance Auditors'],
+ },
+];
+
+export const SCREENSHOTS: ScreenshotItem[] = [
+ {
+ id: 'console-primary',
+ title: 'PFM Console — Executive Dashboard',
+ subtitle: 'Fiduciary Portfolio Command & Statutory Gate Overview',
+ platform: 'PFM Console',
+ category: 'Dashboard',
+ image: '/assets/screenshots/console.png',
+ description: 'Executive birds-eye view of portfolio commitments (R21.0M), active awards, disbursement progress, sector allocations, and statutory compliance status.',
+ hotspots: [
+ { x: 22, y: 18, title: 'Portfolio Capital Ticker', description: 'Real-time roll-up of total commitments and released tranches across all programmes.' },
+ { x: 50, y: 35, title: 'Compliance Radar', description: 'Visual breakdown of projects satisfying statutory conditions precedent vs at-risk.' },
+ { x: 80, y: 22, title: 'Quick Action Center', description: 'One-click award registration, disbursement approvals, and compliance export.' },
+ ],
+ tags: ['Executive', 'Fiduciary', 'Capital Allocation', 'Real-time'],
+ },
+ {
+ id: 'partner-primary',
+ title: 'PFM Partner — Grantee Workspace',
+ subtitle: 'Active Grants, Milestone Fulfilment & Evidence Hub',
+ platform: 'PFM Partner',
+ category: 'Dashboard',
+ image: '/assets/screenshots/partner.png',
+ description: 'The recipient portal where implementing partners review contract scopes, upload required milestone proofs, and track disbursement releases.',
+ hotspots: [
+ { x: 30, y: 25, title: 'Binding Contract Cards', description: 'Overview of sanctioned awards, active project phases, and contractual covenants.' },
+ { x: 70, y: 40, title: 'Milestone Fulfilment Bar', description: 'Visual progress bar tracking verified deliverables against statutory disbursement gates.' },
+ { x: 88, y: 15, title: 'Direct Comms Inbox', description: 'Direct messaging channel with the assigned Programme Officer.' },
+ ],
+ tags: ['Grantee', 'Partner', 'Evidence Upload', 'Milestones'],
+ },
+ {
+ id: 'screen-1',
+ title: 'Console: Portfolio Telemetry & Sector Breakdown',
+ subtitle: 'Capital distribution by Agriculture, Mining, ICT, and Energy',
+ platform: 'PFM Console',
+ category: 'Dashboard',
+ image: '/assets/screenshots/1.png',
+ description: 'Dynamic portfolio analytics slicing sanctioned capital across industrial sectors and monitoring regional development impacts.',
+ tags: ['Analytics', 'Sectors', 'Reporting'],
+ },
+ {
+ id: 'screen-2',
+ title: 'Console: WBS & Project Directory',
+ subtitle: 'Multi-level project hierarchy with variance detection',
+ platform: 'PFM Console',
+ category: 'WBS & Gantt',
+ image: '/assets/screenshots/2.png',
+ description: 'Interactive directory of all funded projects, work packages, task budgets, and real-time variance calculations against contractual baselines.',
+ tags: ['WBS', 'Projects', 'Variance Detection'],
+ },
+ {
+ id: 'screen-3',
+ title: 'Console: Chronological Gantt Timeline',
+ subtitle: '55-Day span milestone chronology and critical paths',
+ platform: 'PFM Console',
+ category: 'WBS & Gantt',
+ image: '/assets/screenshots/3.png',
+ description: 'Interactive timeline modal mapping activity dependencies, milestone due dates, and automated overdue warning flags.',
+ tags: ['Gantt', 'Timelines', 'SLA Monitoring'],
+ },
+ {
+ id: 'screen-4',
+ title: 'Console: Fiduciary Governance & Gate Checks',
+ subtitle: 'Automated conditions precedent verification engine',
+ platform: 'PFM Console',
+ category: 'Governance & Gate',
+ image: '/assets/screenshots/4.png',
+ description: 'Enforces Business Rule BR-003: prevents any payment or disbursement release unless mandatory KYC, tax clearances, and milestone proofs are locked.',
+ tags: ['Governance', 'BR-003', 'Disbursement Gate'],
+ },
+ {
+ id: 'screen-6',
+ title: 'Partner: Project Delivery & Milestones',
+ subtitle: 'Transparent deliverable tracking for field teams',
+ platform: 'PFM Partner',
+ category: 'Evidence & Proof',
+ image: '/assets/screenshots/6.png',
+ description: 'Fieldwork teams manage deliverables, view assigned officer comments, and track the exact verification status of submitted documents.',
+ tags: ['Fieldwork', 'Verification', 'Milestones'],
+ },
+ {
+ id: 'screen-7',
+ title: 'Partner: Milestone Evidence Upload Queue',
+ subtitle: 'Granular file attachment directly to contractual items',
+ platform: 'PFM Partner',
+ category: 'Evidence & Proof',
+ image: '/assets/screenshots/7.png',
+ description: 'Implementing teams attach invoices, geotagged photos, and technical reports with instant preview and upload validation.',
+ tags: ['Evidence Queue', 'S3 Upload', 'Validation'],
+ },
+ {
+ id: 'screen-8',
+ title: 'Partner: Evidence Submission Modal',
+ subtitle: 'Pre-signed S3 storage upload with metadata tagging',
+ platform: 'PFM Partner',
+ category: 'Evidence & Proof',
+ image: '/assets/screenshots/8.png',
+ description: 'Upload modal with progress indicators, file size checks, and automated checksum generation for tamper-evident storage.',
+ tags: ['Upload Modal', 'Security', 'File Integrity'],
+ },
+ {
+ id: 'screen-9',
+ title: 'Partner: In-App Direct Communications',
+ subtitle: 'Instant messaging between Partner and Programme Officer',
+ platform: 'PFM Partner',
+ category: 'Communications',
+ image: '/assets/screenshots/9.png',
+ description: 'Eliminates lost emails and unrecorded WhatsApp conversations. All milestone clarifications and feedback are logged in an immutable thread.',
+ tags: ['Direct Comms', 'Audit Trail', 'Messaging'],
+ },
+ {
+ id: 'screen-10',
+ title: 'Partner: Statutory Onboarding & SSO Login',
+ subtitle: 'Instant mobilization via single sign-on invitation',
+ platform: 'PFM Partner',
+ category: 'Onboarding',
+ image: '/assets/screenshots/10.png',
+ description: 'Secure, seamless invitation acceptance. Grantees sign in with institutional SSO, accept terms, and configure their bank accounts.',
+ tags: ['SSO', 'KYC', 'Rapid Mobilization'],
+ },
+];
+
+export const SIMULATION_STEPS = [
+ {
+ id: 1,
+ step: 'Step 01',
+ actor: 'PFM Console (Funder)',
+ title: 'Sanctioned Award Intake',
+ summary: 'Funding award letter captured. Contract v1 initialized automatically (BR-001 & BR-002).',
+ details: 'Award of R1,000,000 registered with external committee reference. Initial conditions precedent generated.',
+ systemAction: 'Contract generated in DRAFT -> Counter-signed -> Tranche 1 pre-conditions locked.',
+ badgeColor: 'bg-indigo-500/20 text-indigo-300 border-indigo-500/30',
+ },
+ {
+ id: 2,
+ step: 'Step 02',
+ actor: 'PFM Partner (Grantee)',
+ title: 'SSO Onboarding & Banking KYC',
+ summary: 'Partner receives statutory invitation, authenticates via Duende SSO, and validates bank details.',
+ details: 'Bank confirmation letter and tax compliance certificate submitted. BR-005 single source of truth established.',
+ systemAction: 'Hashed recipient credentials locked into encrypted tenant boundary.',
+ badgeColor: 'bg-emerald-500/20 text-emerald-300 border-emerald-500/30',
+ },
+ {
+ id: 3,
+ step: 'Step 03',
+ actor: 'PFM Partner (Grantee)',
+ title: 'Milestone Execution & Proof Upload',
+ summary: 'Field team completes Activity 1.1 and uploads geotagged site photos & contractor invoices.',
+ details: 'Files uploaded directly to Garage S3 via pre-signed HTTPS URLs. Metadata & SHA-256 signatures generated.',
+ systemAction: 'Evidence record linked to Milestone #M01 in UNDER_REVIEW status.',
+ badgeColor: 'bg-cyan-500/20 text-cyan-300 border-cyan-500/30',
+ },
+ {
+ id: 4,
+ step: 'Step 04',
+ actor: 'PFM Console (Funder)',
+ title: 'Evidence Review & Gate Clearance',
+ summary: 'Programme Officer inspects proofs, verifies M&E indicators, and certifies condition precedent.',
+ details: 'Milestone marked VERIFIED (100%). System checks all gate conditions for Tranche 1 release.',
+ systemAction: 'Quartz.NET job triggers automated statutory audit log & notification dispatch.',
+ badgeColor: 'bg-purple-500/20 text-purple-300 border-purple-500/30',
+ },
+ {
+ id: 5,
+ step: 'Step 05',
+ actor: 'Unified System',
+ title: 'Fiduciary Tranche Disbursement Release',
+ summary: 'BR-003 Gate cleared. R350,000 initial drawdown released with zero uncontrolled exposure.',
+ details: 'Capital utilization telemetry updated across both Console and Partner dashboards in real time.',
+ systemAction: 'Disbursement instruction approved; partner notified in-app; M&E beneficiary count updated.',
+ badgeColor: 'bg-amber-500/20 text-amber-300 border-amber-500/30',
+ },
+];
+
+export const COMPARISON_FEATURES = [
+ {
+ feature: 'Primary Target User',
+ console: 'Institutional Funders, CFOs, Programme Managers, M&E Specialists',
+ partner: 'Field Coordinators, Grantee CEOs, Non-Profit Finance Leads, Contractors',
+ },
+ {
+ feature: 'Core Fiduciary Goal',
+ console: 'Capital control, risk mitigation, gate enforcement, portfolio roll-up',
+ partner: 'Activity execution, milestone evidence uploads, tranche visibility',
+ },
+ {
+ feature: 'Project Tracking View',
+ console: 'Interactive WBS, multi-project Gantt chronology, variance audits',
+ partner: 'Focused milestone deliverables list, task statuses, due dates',
+ },
+ {
+ feature: 'Financial Controls',
+ console: 'Budget allocation, covenant conditions precedent, tranche approvals',
+ partner: 'Drawdown requests, payment transparency, expenditure reconciliation',
+ },
+ {
+ feature: 'Evidence Management',
+ console: 'Multi-stakeholder verification, review notes, statutory audits',
+ partner: 'Drag-and-drop file upload to Garage S3, geotagging, progress notes',
+ },
+ {
+ feature: 'Communications Channel',
+ console: 'Official directives, formal compliance notices, query resolutions',
+ partner: 'Direct in-app messaging with assigned Programme Officer',
+ },
+ {
+ feature: 'Identity & Access',
+ console: 'Duende STS backoffice roles, multi-tenant portfolio administration',
+ partner: 'Statutory onboarding invitation token, one-click SSO login',
+ },
+];
+
+export const ARCHITECTURE_HIGHLIGHTS = [
+ {
+ title: '.NET 10 & Clean Architecture',
+ subtitle: 'Domain-Driven Design (DDD)',
+ description: 'Clear separation of Domain, Infrastructure, Application (CQRS via Mediator), and Presentation slices. Zero leaky abstractions.',
+ icon: 'Layers',
+ color: 'from-blue-500/20 to-indigo-500/20 border-blue-500/30',
+ },
+ {
+ title: 'React 19 & Vite 6/8 Frontend',
+ subtitle: 'Modern TypeScript Web Apps',
+ description: 'ConsoleUI and PartnerUI built on React 19, Tailwind CSS v4, Motion animations, and TanStack React Query for zero-stale reads.',
+ icon: 'Atom',
+ color: 'from-cyan-500/20 to-teal-500/20 border-cyan-500/30',
+ },
+ {
+ title: 'Distributed Background Host',
+ subtitle: 'Quartz.NET & PostFundManagement.Jobs',
+ description: 'Dedicated background daemon executing milestone sweeps, overdue alerts, risk score recalculations, and SMTP email notifications.',
+ icon: 'Cpu',
+ color: 'from-amber-500/20 to-orange-500/20 border-amber-500/30',
+ },
+ {
+ title: 'Garage S3 Object Storage',
+ subtitle: 'Tamper-Evident Evidence Vault',
+ description: 'Pre-signed secure upload URLs, SHA checksum verification, and accelerated CDN delivery for millions of statutory proof documents.',
+ icon: 'HardDrive',
+ color: 'from-emerald-500/20 to-teal-500/20 border-emerald-500/30',
+ },
+ {
+ title: 'Duende IdentityServer SSO',
+ subtitle: 'Institutional Security & RBAC',
+ description: 'OAuth 2.0 / OIDC PKCE flow with Skoruba administration, encrypted multi-tenant claims, and hashed ID persistence.',
+ icon: 'ShieldCheck',
+ color: 'from-purple-500/20 to-pink-500/20 border-purple-500/30',
+ },
+ {
+ title: 'PostgreSQL 14+ & HybridCache',
+ subtitle: 'Segregated Relational Data',
+ description: 'Segregated transactional (pfm) and scheduler (pfm-scheduler) databases paired with Redis output caching for sub-millisecond reads.',
+ icon: 'Database',
+ color: 'from-sky-500/20 to-blue-500/20 border-sky-500/30',
+ },
+];
+
diff --git a/PostFundManagement.ShowcaseUI/src/index.css b/PostFundManagement.ShowcaseUI/src/index.css
new file mode 100644
index 0000000..2e0ecbc
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/index.css
@@ -0,0 +1,116 @@
+@import "tailwindcss";
+
+@theme {
+ --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+}
+
+:root {
+ color-scheme: dark;
+}
+
+@layer base {
+ html {
+ scroll-behavior: smooth;
+ background-color: #020617;
+ color: #f8fafc;
+ font-family: var(--font-sans);
+ }
+
+ body {
+ background-color: #020617;
+ color: #f8fafc;
+ overflow-x: hidden;
+ }
+
+ code, pre, .font-mono {
+ font-family: var(--font-mono);
+ }
+}
+
+/* Custom modern scrollbar */
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: #020617;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #1e293b;
+ border-radius: 9999px;
+ border: 2px solid #020617;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #334155;
+}
+
+/* Glassmorphism utilities */
+.glass-panel {
+ background: rgba(15, 23, 42, 0.7);
+ backdrop-filter: blur(16px);
+ -webkit-backdrop-filter: blur(16px);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+}
+
+.glass-panel-elevated {
+ background: rgba(30, 41, 59, 0.65);
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ border: 1px solid rgba(255, 255, 255, 0.12);
+ box-shadow: 0 20px 50px -10px rgba(0, 0, 0, 0.5);
+}
+
+.glass-card-hover {
+ transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
+}
+
+.glass-card-hover:hover {
+ transform: translateY(-3px);
+ border-color: rgba(56, 189, 248, 0.35);
+ box-shadow: 0 12px 30px -10px rgba(14, 165, 233, 0.25);
+}
+
+/* Ambient glow effects */
+.radial-glow-cyan {
+ background: radial-gradient(circle, rgba(6, 182, 212, 0.15) 0%, rgba(2, 6, 23, 0) 70%);
+}
+
+.radial-glow-indigo {
+ background: radial-gradient(circle, rgba(99, 102, 241, 0.15) 0%, rgba(2, 6, 23, 0) 70%);
+}
+
+.radial-glow-emerald {
+ background: radial-gradient(circle, rgba(16, 185, 129, 0.15) 0%, rgba(2, 6, 23, 0) 70%);
+}
+
+/* Animated gradient text */
+.text-gradient-cyan {
+ background: linear-gradient(135deg, #38bdf8 0%, #06b6d4 50%, #10b981 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+.text-gradient-funder {
+ background: linear-gradient(135deg, #60a5fa 0%, #818cf8 50%, #c084fc 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+.text-gradient-partner {
+ background: linear-gradient(135deg, #34d399 0%, #2dd4bf 50%, #38bdf8 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+/* Subtle dot grid pattern */
+.bg-grid-pattern {
+ background-size: 32px 32px;
+ background-image:
+ linear-gradient(to right, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
+ linear-gradient(to bottom, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
+}
+
diff --git a/PostFundManagement.ShowcaseUI/src/main.tsx b/PostFundManagement.ShowcaseUI/src/main.tsx
new file mode 100644
index 0000000..0c657b5
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/main.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+import './index.css';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+);
+
diff --git a/PostFundManagement.ShowcaseUI/src/vite-env.d.ts b/PostFundManagement.ShowcaseUI/src/vite-env.d.ts
new file mode 100644
index 0000000..ed77210
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/src/vite-env.d.ts
@@ -0,0 +1,2 @@
+///
+
diff --git a/PostFundManagement.ShowcaseUI/tsconfig.json b/PostFundManagement.ShowcaseUI/tsconfig.json
new file mode 100644
index 0000000..0c53780
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "experimentalDecorators": true,
+ "useDefineForClassFields": false,
+ "module": "ESNext",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+ "allowImportingTsExtensions": true,
+ "noEmit": true
+ },
+ "include": ["src"]
+}
+
diff --git a/PostFundManagement.ShowcaseUI/vite.config.ts b/PostFundManagement.ShowcaseUI/vite.config.ts
new file mode 100644
index 0000000..44b62ad
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/vite.config.ts
@@ -0,0 +1,20 @@
+import tailwindcss from '@tailwindcss/vite';
+import react from '@vitejs/plugin-react';
+import path from 'path';
+import { defineConfig } from 'vite';
+
+export default defineConfig(() => {
+ return {
+ plugins: [react(), tailwindcss()],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+ server: {
+ port: 3002,
+ host: '0.0.0.0',
+ },
+ };
+});
+
diff --git a/PostFundManagement.ShowcaseUI/yarn.lock b/PostFundManagement.ShowcaseUI/yarn.lock
new file mode 100644
index 0000000..ab731f3
--- /dev/null
+++ b/PostFundManagement.ShowcaseUI/yarn.lock
@@ -0,0 +1,1098 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7"
+ integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.29.7"
+ js-tokens "^4.0.0"
+ picocolors "^1.1.1"
+
+"@babel/compat-data@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629"
+ integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==
+
+"@babel/core@^7.29.0":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.7.tgz#80c10b17248082968b57a857b91640971f2070f7"
+ integrity sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/generator" "^7.29.7"
+ "@babel/helper-compilation-targets" "^7.29.7"
+ "@babel/helper-module-transforms" "^7.29.7"
+ "@babel/helpers" "^7.29.7"
+ "@babel/parser" "^7.29.7"
+ "@babel/template" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+ "@jridgewell/remapping" "^2.3.5"
+ convert-source-map "^2.0.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.3"
+ semver "^6.3.1"
+
+"@babel/generator@^7.29.7", "@babel/generator@^7.29.8":
+ version "7.29.8"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.8.tgz#4b0b887885422643339e09022148a4c4ebaa4979"
+ integrity sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==
+ dependencies:
+ "@babel/parser" "^7.29.8"
+ "@babel/types" "^7.29.8"
+ "@jridgewell/gen-mapping" "^0.3.12"
+ "@jridgewell/trace-mapping" "^0.3.28"
+ jsesc "^3.0.2"
+
+"@babel/helper-compilation-targets@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042"
+ integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==
+ dependencies:
+ "@babel/compat-data" "^7.29.7"
+ "@babel/helper-validator-option" "^7.29.7"
+ browserslist "^4.24.0"
+ lru-cache "^5.1.1"
+ semver "^6.3.1"
+
+"@babel/helper-globals@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz#f04a96fbd8473241b1079243f5b3f03a3010ab7b"
+ integrity sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==
+
+"@babel/helper-module-imports@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396"
+ integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==
+ dependencies:
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
+"@babel/helper-module-transforms@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae"
+ integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==
+ dependencies:
+ "@babel/helper-module-imports" "^7.29.7"
+ "@babel/helper-validator-identifier" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+
+"@babel/helper-plugin-utils@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz#c0a0766f1a13617d8a17407d7ab8f9d486225ea4"
+ integrity sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==
+
+"@babel/helper-string-parser@^7.29.11":
+ version "7.29.11"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.11.tgz#59d76b6193f61e0303b40991cabbedfadcbd5b63"
+ integrity sha512-snZbO7MEDOof+hvNa97EjEY7qD7h2kwvQr5AJC3ZhQudKW5dnej6k3kP9NQV88hJwaS8vDqRLFo9rivLEhle2g==
+
+"@babel/helper-validator-identifier@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2"
+ integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==
+
+"@babel/helper-validator-option@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a"
+ integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==
+
+"@babel/helpers@^7.29.7":
+ version "7.29.10"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.10.tgz#d662b4a2d66cc6cf02bc50e8aced023fbc8649e9"
+ integrity sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==
+ dependencies:
+ "@babel/template" "^7.29.7"
+ "@babel/types" "^7.29.8"
+
+"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.29.7", "@babel/parser@^7.29.8", "@babel/parser@^7.29.9":
+ version "7.29.11"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.11.tgz#afa959e9d16c40d4d95012553cab363fc86cbcb7"
+ integrity sha512-OZ6+oaK7GMyg3IfCpj8JOmn8n+w2rJbDT0LLfVDTLb1ZFeKDh3AiNELgCMUw175IJHSkLl74hG0M0VLsvx+gag==
+ dependencies:
+ "@babel/types" "^7.29.11"
+
+"@babel/plugin-transform-react-jsx-self@^7.27.1":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz#c24424527858220624fd59a5b1eab4fa413c803a"
+ integrity sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.29.7"
+
+"@babel/plugin-transform-react-jsx-source@^7.27.1":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz#5cf25a3689906b58e2f0a2f2b374789e6627b15f"
+ integrity sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.29.7"
+
+"@babel/template@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700"
+ integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/parser" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
+"@babel/traverse@^7.29.7":
+ version "7.29.10"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.10.tgz#08ab387639b4a67304511259c7da6cf23a82e91c"
+ integrity sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/generator" "^7.29.8"
+ "@babel/helper-globals" "^7.29.7"
+ "@babel/parser" "^7.29.9"
+ "@babel/template" "^7.29.7"
+ "@babel/types" "^7.29.8"
+ debug "^4.3.1"
+
+"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.29.11", "@babel/types@^7.29.7", "@babel/types@^7.29.8":
+ version "7.29.11"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.11.tgz#774cffe8cac2ca494f1334e4052002c96bf628fc"
+ integrity sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ==
+ dependencies:
+ "@babel/helper-string-parser" "^7.29.11"
+ "@babel/helper-validator-identifier" "^7.29.7"
+
+"@emnapi/core@^1.11.1":
+ version "1.11.3"
+ resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.11.3.tgz#5e95348a42cd1e06f0b9aa380cd74091daa4d520"
+ integrity sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==
+ dependencies:
+ "@emnapi/wasi-threads" "1.2.3"
+ tslib "^2.4.0"
+
+"@emnapi/runtime@^1.11.1":
+ version "1.11.3"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.11.3.tgz#84257ae3b0531eb2aec1ffa23d70700da007ba95"
+ integrity sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==
+ dependencies:
+ tslib "^2.4.0"
+
+"@emnapi/wasi-threads@1.2.3", "@emnapi/wasi-threads@^1.2.2":
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz#c9bf72fd4be5b928aee894820e8d814ed73916e9"
+ integrity sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==
+ dependencies:
+ tslib "^2.4.0"
+
+"@esbuild/aix-ppc64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz#80fcbe36130e58b7670511e888b8e88a259ed76c"
+ integrity sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==
+
+"@esbuild/android-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz#8aa4965f8d0a7982dc21734bf6601323a66da752"
+ integrity sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==
+
+"@esbuild/android-arm@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz#300712101f7f50f1d2627a162e6e09b109b6767a"
+ integrity sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==
+
+"@esbuild/android-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz#87dfb27161202bdc958ef48bb61b09c758faee16"
+ integrity sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==
+
+"@esbuild/darwin-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz#79197898ec1ff745d21c071e1c7cc3c802f0c1fd"
+ integrity sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==
+
+"@esbuild/darwin-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz#146400a8562133f45c4d2eadcf37ddd09718079e"
+ integrity sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==
+
+"@esbuild/freebsd-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz#1c5f9ba7206e158fd2b24c59fa2d2c8bb47ca0fe"
+ integrity sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==
+
+"@esbuild/freebsd-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz#ea631f4a36beaac4b9279fa0fcc6ca29eaeeb2b3"
+ integrity sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==
+
+"@esbuild/linux-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz#e1066bce58394f1b1141deec8557a5f0a22f5977"
+ integrity sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==
+
+"@esbuild/linux-arm@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz#452cd66b20932d08bdc53a8b61c0e30baf4348b9"
+ integrity sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==
+
+"@esbuild/linux-ia32@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz#b24f8acc45bcf54192c7f2f3be1b53e6551eafe0"
+ integrity sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==
+
+"@esbuild/linux-loong64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz#f9cfffa7fc8322571fbc4c8b3268caf15bd81ad0"
+ integrity sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==
+
+"@esbuild/linux-mips64el@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz#575a14bd74644ffab891adc7d7e60d275296f2cd"
+ integrity sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==
+
+"@esbuild/linux-ppc64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz#75b99c70a95fbd5f7739d7692befe60601591869"
+ integrity sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==
+
+"@esbuild/linux-riscv64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz#2e3259440321a44e79ddf7535c325057da875cd6"
+ integrity sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==
+
+"@esbuild/linux-s390x@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz#17676cabbfe5928da5b2a0d6df5d58cd08db2663"
+ integrity sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==
+
+"@esbuild/linux-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz#0583775685ca82066d04c3507f09524d3cd7a306"
+ integrity sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==
+
+"@esbuild/netbsd-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz#f04c4049cb2e252fe96b16fed90f70746b13f4a4"
+ integrity sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==
+
+"@esbuild/netbsd-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz#77da0d0a0d826d7c921eea3d40292548b258a076"
+ integrity sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==
+
+"@esbuild/openbsd-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz#6296f5867aedef28a81b22ab2009c786a952dccd"
+ integrity sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==
+
+"@esbuild/openbsd-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz#f8d23303360e27b16cf065b23bbff43c14142679"
+ integrity sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==
+
+"@esbuild/openharmony-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz#49e0b768744a3924be0d7fd97dd6ce9b2923d88d"
+ integrity sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==
+
+"@esbuild/sunos-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz#a6ed7d6778d67e528c81fb165b23f4911b9b13d6"
+ integrity sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==
+
+"@esbuild/win32-arm64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz#9ac14c378e1b653af17d08e7d3ce34caef587323"
+ integrity sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==
+
+"@esbuild/win32-ia32@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz#918942dcbbb35cc14fca39afb91b5e6a3d127267"
+ integrity sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==
+
+"@esbuild/win32-x64@0.25.12":
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz#9bdad8176be7811ad148d1f8772359041f46c6c5"
+ integrity sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==
+
+"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5":
+ version "0.3.13"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
+ integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/remapping@^2.3.5":
+ version "2.3.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
+ integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/resolve-uri@^3.1.0":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz#f4c663e862f06dc98ca4d453862c46902789a18d"
+ integrity sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==
+
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
+ version "0.3.31"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
+ integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
+"@napi-rs/lzma-linux-x64-gnu@1.5.1":
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz#e57d4306966078662038094fb38eb9146dc3aea9"
+ integrity sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==
+
+"@napi-rs/wasm-runtime@^1.1.4":
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.6.tgz#bc856c4ab60cd9c6c8e4432b5d6f50ceba0ca8f4"
+ integrity sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==
+ dependencies:
+ "@tybys/wasm-util" "^0.10.3"
+
+"@rolldown/pluginutils@1.0.0-rc.3":
+ version "1.0.0-rc.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz#8a88cc92a0f741befc7bc109cb1a4c6b9408e1c5"
+ integrity sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==
+
+"@rollup/rollup-android-arm-eabi@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.66.0.tgz#8cd747d7e1b0d67f71ff7b5747f09f0f722692ea"
+ integrity sha512-7y4XeoUHPecjfUDRmap8U0q6bjfLAPn7uOGT8BKyqy8uNDOjsGS8rlBhOx6sZLVwwjN6hapvGl2mW9/IS6UNww==
+
+"@rollup/rollup-android-arm64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.66.0.tgz#2be214b1545d5315932d8488aa890ecbe980a53b"
+ integrity sha512-e8WugYZXpgqrlMXLCudYVRAxAcK7AIY36JxRDwFRD38L9q62G1VsEUW6ijXxzjxYjNB8i1zo3B/ycIQ/qjLC/Q==
+
+"@rollup/rollup-darwin-arm64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.66.0.tgz#334090b129bc289ea5dba17853b341251f5e8b2d"
+ integrity sha512-6vkDCfyDjNLokh+Rt1D2KtNgFFMEPdkWha/mbtP4cSjh9xiN8T/JBS/A7nDYKjmMAXHrvR9J3AzUk2LtFbIBLg==
+
+"@rollup/rollup-darwin-x64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.66.0.tgz#37bf3c3d1c583b9c176f730ec340aa10e65dccb9"
+ integrity sha512-/mzZAX0+Q6eXxvkR0HB0RZCCrsbmFD8DpsvCQoMYABDfq/DjqkbfytuJ7GvZ4AhR/Mgis2fXbZrGqfbcK2Z5fA==
+
+"@rollup/rollup-freebsd-arm64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.66.0.tgz#e10b5084c236da288ec541cf98c89d83dcc7496e"
+ integrity sha512-JQJx9E8tUjGqed1RevDmoHaS3V30ODdV8uyvGxlwd4K5se6bkPrMeltSybqAtpJ+ltDRfo7FORQaJG2Hd5nGog==
+
+"@rollup/rollup-freebsd-x64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.66.0.tgz#9c955678f40562a31131ae8ab6b425deccb17520"
+ integrity sha512-GEaUQQjMaG7X1304qMgqLjzCKv6CdDirzJSS+UqUs3xhJ9X2Kjzu0JDbLoUU42FWxwmZqz+SsgU1SlQv9GNRVA==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.66.0.tgz#fefaa69f26eff600b01679506029b5474fb38253"
+ integrity sha512-DgmAU9N0NhDQDzHgFUocDio7zRO8jR/nY/obDGvCR8zbJ6J77Fg6X49yPuExJUpYPbC82EOaRhG969pWzUSnHQ==
+
+"@rollup/rollup-linux-arm-musleabihf@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.66.0.tgz#614e473cf3161821865b562b929616d8f6157217"
+ integrity sha512-zG09YZ+sk/HoHq+P9gYB0EseQ3M20RbDuKGWey6fbiMDV1LxfXvhgSW9jDaCcvFPMgfLXpimzXY+UYvA8R2mLQ==
+
+"@rollup/rollup-linux-arm64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.66.0.tgz#f3e9a6e71f0e10da0c9277e213db35f99cdc4f5d"
+ integrity sha512-vlArhgyXbcVc1D4WZPoiYuqJIaMiSHBj6etRXua0KlfjlZeuiQyVAPYi0/N49O4mSp3u1iGUBLEjNa8ec81XZg==
+
+"@rollup/rollup-linux-arm64-musl@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.66.0.tgz#6b17309599e6967d859721bc041bab37519b8928"
+ integrity sha512-RxJZtk0G87YPotDaRDvRqStV8cbqLSC5TroHvQHHKsqBg0ok64RxKgtXeFsa7FBcy7mb4crBrG3xK8USWIqWNA==
+
+"@rollup/rollup-linux-loong64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.66.0.tgz#6da7afc24aae4efcfa0f750a9ac879b3c69bcc9a"
+ integrity sha512-qlGcw959PrLLkZhiBxF3OZ6SQvj+OKY85mCqGNgSRs4LZlDJ6ICqmz6UdxtINdhcXYwNIbZoapQVBAmZlD2hUQ==
+
+"@rollup/rollup-linux-loong64-musl@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.66.0.tgz#b1de25a2e609d495129c2d7cd71c2e71d1dfe1de"
+ integrity sha512-TvTI/7Cy0WvRA1SXgwzu6bwXBnMpmeT/ln5q7WvSpqmXy1VbmEnY8HVIDQNBiaHJvoWqRr0M4FNo7qiqtyMaFw==
+
+"@rollup/rollup-linux-ppc64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.66.0.tgz#667d49412359f61801f28e51107badf654cbf570"
+ integrity sha512-UZEDkSoDRZ50NyLj70nO6mpIK3dvs2cPTTvQb1bA/PBDmr9fvn5KiESuGfh6srd7Zi6Lt9Sv2sVrFr1QoHLvPQ==
+
+"@rollup/rollup-linux-ppc64-musl@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.66.0.tgz#c7cb9d151bc3b5aef1c898e9fdb95beb86554c1a"
+ integrity sha512-VRbxTvagLh3HRcysx1CNq+HHcvJbSebNI6fCbk7jwmmWHkXjrSIV3igXBpRHUTFdg0pagWGu50xoSZXnrZHjVQ==
+
+"@rollup/rollup-linux-riscv64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.66.0.tgz#7f5f3bf0626389a69b0b78f172d3728b629c1810"
+ integrity sha512-uWdJpvYqh0LE/i+YBL3sMX0a2kUkICENjmrPmyBmMOFc3jMrs6MSQH/pMD+VIpGEoUcr3XkHGLLfymzIqPSRRg==
+
+"@rollup/rollup-linux-riscv64-musl@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.66.0.tgz#f82ccd7b6592fd7faec667ddcb8c1e6083cb86f0"
+ integrity sha512-3FUd88pxgWAjK60OgCrika1AcNG+u8zaCdWjg4TlcZTDkt5TGyci8ZU64l3OJ9ax0MEjw3P80B/3PoSQDCLwJQ==
+
+"@rollup/rollup-linux-s390x-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.66.0.tgz#9e221bc8ea2307e8dc3724302173b523f4ee702e"
+ integrity sha512-qT2rMmgyej62g5AdwktK+Bt2lBu497pzWZe12TTQ5JmZjOYPnEwcPEAOSLTBxBV+6gIES75rXm219v/QkT397A==
+
+"@rollup/rollup-linux-x64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.66.0.tgz#168f9030e8f2de9348efc7dc4388792b1dfa7efc"
+ integrity sha512-E46rnZgp7J84Qwe8RMlF+rgimnDo/9fuiGbUArGB0ZkMWf97O7yeSCfKls5x/YJOF0RcuSe9RctuKe1hlxICiA==
+
+"@rollup/rollup-linux-x64-musl@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.66.0.tgz#1224c6b6900c10f9cea2b280aeb869c6fd4c8a78"
+ integrity sha512-Uz1HiZe+qBzqgdPsON+z0wRx3WdATuyzwvGT6cr2VZVrqqko0ZJVfkrQJtwDMuDcAfXYdo7XucaxJ7lTLjEcgg==
+
+"@rollup/rollup-openbsd-x64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.66.0.tgz#abec4ba3031469e134a6c495f374b5d7bad41743"
+ integrity sha512-Ph7TX3Ex5qdfcb7Tc6eEPugVkRfJ501eTovO4T5029YObfpZ7dzn3RiwpFvGp50nk2QUhvBMZ0PFGlEj6pOYTg==
+
+"@rollup/rollup-openharmony-arm64@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.66.0.tgz#6c24217ea90a5c50f891d31573b555460668aa12"
+ integrity sha512-nZYPEya7ZkeNxUEiF7qmNZbyLTyRN3MK5cO22KqsaoneUzXJuzBIQRw+7BEQy9LGj2O5vrCE9V3EpK06FYo1tQ==
+
+"@rollup/rollup-win32-arm64-msvc@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.66.0.tgz#386aabe6cda4b3fea4335a248ec0462d7462bd1a"
+ integrity sha512-u7aTfS3R6C4hRsqXSzaO6qLZYLVuMkHMvcWlux4IM8IJif1VCl2cgPBSo5gSNoFoStQypQP+qwq8W1IyFBf1QQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.66.0.tgz#a7bf86f9f4715c614bd1a44cf3ea9895f93f95fd"
+ integrity sha512-e+i9ueHrH1Bafb0cf0woAIVJbYcoC8vRaD+vz+Xi8w6jz9cYJSV3vyKO6ELGSZ6g4W4MJOm2WPLN4/nQf77h7w==
+
+"@rollup/rollup-win32-x64-gnu@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.66.0.tgz#8b43b07afb49681c0ab460d91b7ad7196ffbe827"
+ integrity sha512-KfTCbrtr2zXTqH2E1F+uYlFTrYibxHKqPAHobpd8Kfg49cEHmuHebOidCTDRgqG1suaPFX7oejFQeGE71zWKfA==
+
+"@rollup/rollup-win32-x64-msvc@4.66.0":
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.66.0.tgz#e3ee87512d43918fe2962765b3c0298979cf5bf9"
+ integrity sha512-xA+neBh1bqkqaS3b48T2UHZnDsTIpb9B0h+TdBzynjF/ymCpYndhfY10RqW0qSKB1HqqQA83mINVhAdwA+mETg==
+
+"@tailwindcss/node@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/node/-/node-4.3.3.tgz#38ff04309ff036ea3589a7bad9069c44ec9d3883"
+ integrity sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==
+ dependencies:
+ "@jridgewell/remapping" "^2.3.5"
+ enhanced-resolve "^5.24.1"
+ jiti "^2.7.0"
+ lightningcss "1.32.0"
+ magic-string "^0.30.21"
+ source-map-js "^1.2.1"
+ tailwindcss "4.3.3"
+
+"@tailwindcss/oxide-android-arm64@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz#848f93034155daf7892185028dfb18143bfc7d07"
+ integrity sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==
+
+"@tailwindcss/oxide-darwin-arm64@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz#5c779e32c1c361beb75136fd8e2c627fcb9a5b28"
+ integrity sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==
+
+"@tailwindcss/oxide-darwin-x64@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz#ba292ff52fa3264139f7fe7874719ce0a4666875"
+ integrity sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==
+
+"@tailwindcss/oxide-freebsd-x64@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz#07e589487b9a636235a4ade48cefc1f9eeeec57f"
+ integrity sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==
+
+"@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz#0c8abc228d9e19e0065ddb707eba52e21855b3ff"
+ integrity sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==
+
+"@tailwindcss/oxide-linux-arm64-gnu@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz#5067dc7afd15d2b97adc77a91177dc4bec8d1b8b"
+ integrity sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==
+
+"@tailwindcss/oxide-linux-arm64-musl@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz#29ae5f279be2ce64db368711985b6ad8e4562e57"
+ integrity sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==
+
+"@tailwindcss/oxide-linux-x64-gnu@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz#7d693b40f69875744b499481359b227fd3ac3a3c"
+ integrity sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==
+
+"@tailwindcss/oxide-linux-x64-musl@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz#6a55d664f47c5ff9ad3f46bf05fe07d410b8cfd8"
+ integrity sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==
+
+"@tailwindcss/oxide-wasm32-wasi@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz#408a9bc620e68f1aaf0dfea33da7bd3b65f9e2ef"
+ integrity sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==
+ dependencies:
+ "@emnapi/core" "^1.11.1"
+ "@emnapi/runtime" "^1.11.1"
+ "@emnapi/wasi-threads" "^1.2.2"
+ "@napi-rs/wasm-runtime" "^1.1.4"
+ "@tybys/wasm-util" "^0.10.2"
+ tslib "^2.8.1"
+
+"@tailwindcss/oxide-win32-arm64-msvc@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz#3d582b00180fa4680e0b6c90be69fa5f4a209092"
+ integrity sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==
+
+"@tailwindcss/oxide-win32-x64-msvc@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz#ce4c663fef3b4fde67611a4c1391866f8c0aa79b"
+ integrity sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==
+
+"@tailwindcss/oxide@4.3.3":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide/-/oxide-4.3.3.tgz#6266109d025cfcb04f8e4c58954a6f630a415b7f"
+ integrity sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==
+ optionalDependencies:
+ "@tailwindcss/oxide-android-arm64" "4.3.3"
+ "@tailwindcss/oxide-darwin-arm64" "4.3.3"
+ "@tailwindcss/oxide-darwin-x64" "4.3.3"
+ "@tailwindcss/oxide-freebsd-x64" "4.3.3"
+ "@tailwindcss/oxide-linux-arm-gnueabihf" "4.3.3"
+ "@tailwindcss/oxide-linux-arm64-gnu" "4.3.3"
+ "@tailwindcss/oxide-linux-arm64-musl" "4.3.3"
+ "@tailwindcss/oxide-linux-x64-gnu" "4.3.3"
+ "@tailwindcss/oxide-linux-x64-musl" "4.3.3"
+ "@tailwindcss/oxide-wasm32-wasi" "4.3.3"
+ "@tailwindcss/oxide-win32-arm64-msvc" "4.3.3"
+ "@tailwindcss/oxide-win32-x64-msvc" "4.3.3"
+
+"@tailwindcss/vite@^4.1.14":
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/vite/-/vite-4.3.3.tgz#1f4037badcb5e6c6bb574d3d8a0172c83f26b97f"
+ integrity sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==
+ dependencies:
+ "@tailwindcss/node" "4.3.3"
+ "@tailwindcss/oxide" "4.3.3"
+ tailwindcss "4.3.3"
+
+"@tybys/wasm-util@^0.10.2", "@tybys/wasm-util@^0.10.3":
+ version "0.10.4"
+ resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.4.tgz#3e85ecb266f9d1722250e89bc69528615720b154"
+ integrity sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==
+ dependencies:
+ tslib "^2.4.0"
+
+"@types/babel__core@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
+ integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==
+ dependencies:
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
+ "@types/babel__generator" "*"
+ "@types/babel__template" "*"
+ "@types/babel__traverse" "*"
+
+"@types/babel__generator@*":
+ version "7.27.0"
+ resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9"
+ integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==
+ dependencies:
+ "@babel/types" "^7.0.0"
+
+"@types/babel__template@*":
+ version "7.4.4"
+ resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f"
+ integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==
+ dependencies:
+ "@babel/parser" "^7.1.0"
+ "@babel/types" "^7.0.0"
+
+"@types/babel__traverse@*":
+ version "7.28.0"
+ resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74"
+ integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==
+ dependencies:
+ "@babel/types" "^7.28.2"
+
+"@types/canvas-confetti@^1.9.0":
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/@types/canvas-confetti/-/canvas-confetti-1.9.0.tgz#d1077752e046413c9881fbb2ba34a70ebe3c1773"
+ integrity sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg==
+
+"@types/estree@1.0.9":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24"
+ integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==
+
+"@types/node@^22.14.0":
+ version "22.20.5"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.20.5.tgz#afa7bde6da81b8b83ea4e2f020487e9b148c11fd"
+ integrity sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==
+ dependencies:
+ undici-types "~6.21.0"
+
+"@types/react-dom@^19.3.0":
+ version "19.3.0"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.3.0.tgz#90294a9266efd928a5266f2110d60d5dba5015d2"
+ integrity sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==
+
+"@types/react@^19.3.0":
+ version "19.3.0"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-19.3.0.tgz#3b3ce8d8c1627fb5ccd4dadd57ef445c5a153b77"
+ integrity sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==
+ dependencies:
+ csstype "^3.2.2"
+
+"@vitejs/plugin-react@^5.0.4":
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz#108bd0f566f288ce3566982df4eff137ded7b15f"
+ integrity sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==
+ dependencies:
+ "@babel/core" "^7.29.0"
+ "@babel/plugin-transform-react-jsx-self" "^7.27.1"
+ "@babel/plugin-transform-react-jsx-source" "^7.27.1"
+ "@rolldown/pluginutils" "1.0.0-rc.3"
+ "@types/babel__core" "^7.20.5"
+ react-refresh "^0.18.0"
+
+baseline-browser-mapping@^2.11.33:
+ version "2.11.34"
+ resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.34.tgz#d97a3dc0edb2f139758f7f2b1ae89552f391b35f"
+ integrity sha512-Aqr8mA1kIvyJ3UY5YAY7ib8LSo1DmDMbMnVqGPtsKW1LxaFQFwn9Eb3yvq2fUKJsRvaXjnAV7R5osqETapzNiA==
+
+browserslist@^4.24.0:
+ version "4.29.5"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.29.5.tgz#e835ff9a00f683305b33f02828c908b397410d4a"
+ integrity sha512-khTmKu5NGYTotqcYo8Bew2k4RAE9PuXRSFRXG2lQBrCEQHyeQ/vX6gKMxfokwywBsLiXZMnHsmWMG1pnO8J7uQ==
+ dependencies:
+ baseline-browser-mapping "^2.11.33"
+ caniuse-lite "^1.0.30001819"
+ electron-to-chromium "^1.5.464"
+ node-releases "^2.0.60"
+ update-browserslist-db "^1.3.4"
+
+caniuse-lite@^1.0.30001819:
+ version "1.0.30001820"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001820.tgz#bbed68c45bb4c4316084594ba044ba56e68bfae7"
+ integrity sha512-gfWD6MxqVCqAOwmODfZf7DchWvlrA+SRdNX7ceLfg3xRqe5ssjjpF7EgslC/0tiLiNTajdaNN/q8c/5u/7Gz8w==
+
+canvas-confetti@^1.9.4:
+ version "1.9.4"
+ resolved "https://registry.yarnpkg.com/canvas-confetti/-/canvas-confetti-1.9.4.tgz#4412a5daa96afd0b4d70ecd66b65ce8db3022b2b"
+ integrity sha512-yxQbJkAVrFXWNbTUjPqjF7G+g6pDotOUHGbkZq2NELZUMDpiJ85rIEazVb8GTaAptNW2miJAXbs1BtioA251Pw==
+
+convert-source-map@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
+ integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
+
+csstype@^3.2.2:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a"
+ integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==
+
+debug@^4.1.0, debug@^4.3.1:
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
+ integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
+ dependencies:
+ ms "^2.1.3"
+
+detect-libc@^2.0.3:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
+ integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
+
+electron-to-chromium@^1.5.464:
+ version "1.5.467"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.467.tgz#7a3db88a95f09304a47ca0d838a1504fa048664a"
+ integrity sha512-Nw9X371rtZmYcBSnEijnCDONILjs93biCZO34juC7MBOmK8E+GFnyD4T/WvyrlJkppul7oxg6TwvtKst9SODTw==
+
+enhanced-resolve@^5.24.1:
+ version "5.26.0"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz#9dfb47d050ed6c87f2c6d43b4d7e30f8c0a91ed7"
+ integrity sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==
+ dependencies:
+ graceful-fs "^4.2.4"
+ tapable "^2.3.3"
+
+esbuild@^0.25.0:
+ version "0.25.12"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.12.tgz#97a1d041f4ab00c2fce2f838d2b9969a2d2a97a5"
+ integrity sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.25.12"
+ "@esbuild/android-arm" "0.25.12"
+ "@esbuild/android-arm64" "0.25.12"
+ "@esbuild/android-x64" "0.25.12"
+ "@esbuild/darwin-arm64" "0.25.12"
+ "@esbuild/darwin-x64" "0.25.12"
+ "@esbuild/freebsd-arm64" "0.25.12"
+ "@esbuild/freebsd-x64" "0.25.12"
+ "@esbuild/linux-arm" "0.25.12"
+ "@esbuild/linux-arm64" "0.25.12"
+ "@esbuild/linux-ia32" "0.25.12"
+ "@esbuild/linux-loong64" "0.25.12"
+ "@esbuild/linux-mips64el" "0.25.12"
+ "@esbuild/linux-ppc64" "0.25.12"
+ "@esbuild/linux-riscv64" "0.25.12"
+ "@esbuild/linux-s390x" "0.25.12"
+ "@esbuild/linux-x64" "0.25.12"
+ "@esbuild/netbsd-arm64" "0.25.12"
+ "@esbuild/netbsd-x64" "0.25.12"
+ "@esbuild/openbsd-arm64" "0.25.12"
+ "@esbuild/openbsd-x64" "0.25.12"
+ "@esbuild/openharmony-arm64" "0.25.12"
+ "@esbuild/sunos-x64" "0.25.12"
+ "@esbuild/win32-arm64" "0.25.12"
+ "@esbuild/win32-ia32" "0.25.12"
+ "@esbuild/win32-x64" "0.25.12"
+
+escalade@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
+ integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
+
+fdir@^6.4.4, fdir@^6.5.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
+ integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
+
+framer-motion@^12.43.0:
+ version "12.43.0"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.43.0.tgz#f7f7f0cf792959ca6a0a7ccd2d55269e68061bc4"
+ integrity sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==
+ dependencies:
+ motion-dom "^12.43.0"
+ motion-utils "^12.39.0"
+ tslib "^2.4.0"
+
+fsevents@~2.3.2, fsevents@~2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
+gensync@^1.0.0-beta.2:
+ version "1.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
+ integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
+
+graceful-fs@^4.2.4:
+ version "4.2.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
+ integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+
+jiti@^2.7.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.7.0.tgz#974228f2f4ca2bc21885a1797b45fea68e950c64"
+ integrity sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==
+
+js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+jsesc@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
+ integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
+
+json5@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
+ integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+
+lightningcss-android-arm64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz#f033885116dfefd9c6f54787523e3514b61e1968"
+ integrity sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==
+
+lightningcss-darwin-arm64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz#50b71871b01c8199584b649e292547faea7af9b5"
+ integrity sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==
+
+lightningcss-darwin-x64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz#35f3e97332d130b9ca181e11b568ded6aebc6d5e"
+ integrity sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==
+
+lightningcss-freebsd-x64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz#9777a76472b64ed6ff94342ad64c7bafd794a575"
+ integrity sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==
+
+lightningcss-linux-arm-gnueabihf@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz#13ae652e1ab73b9135d7b7da172f666c410ad53d"
+ integrity sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==
+
+lightningcss-linux-arm64-gnu@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz#417858795a94592f680123a1b1f9da8a0e1ef335"
+ integrity sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==
+
+lightningcss-linux-arm64-musl@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz#6be36692e810b718040802fd809623cffe732133"
+ integrity sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==
+
+lightningcss-linux-x64-gnu@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz#0b7803af4eb21cfd38dd39fe2abbb53c7dd091f6"
+ integrity sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==
+
+lightningcss-linux-x64-musl@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz#88dc8ba865ddddb1ac5ef04b0f161804418c163b"
+ integrity sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==
+
+lightningcss-win32-arm64-msvc@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz#4f30ba3fa5e925f5b79f945e8cc0d176c3b1ab38"
+ integrity sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==
+
+lightningcss-win32-x64-msvc@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz#141aa5605645064928902bb4af045fa7d9f4220a"
+ integrity sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==
+
+lightningcss@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9"
+ integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==
+ dependencies:
+ detect-libc "^2.0.3"
+ optionalDependencies:
+ lightningcss-android-arm64 "1.32.0"
+ lightningcss-darwin-arm64 "1.32.0"
+ lightningcss-darwin-x64 "1.32.0"
+ lightningcss-freebsd-x64 "1.32.0"
+ lightningcss-linux-arm-gnueabihf "1.32.0"
+ lightningcss-linux-arm64-gnu "1.32.0"
+ lightningcss-linux-arm64-musl "1.32.0"
+ lightningcss-linux-x64-gnu "1.32.0"
+ lightningcss-linux-x64-musl "1.32.0"
+ lightningcss-win32-arm64-msvc "1.32.0"
+ lightningcss-win32-x64-msvc "1.32.0"
+
+lru-cache@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
+ integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+ dependencies:
+ yallist "^3.0.2"
+
+lucide-react@^0.546.0:
+ version "0.546.0"
+ resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.546.0.tgz#d9fdc232b47fe652e06401b7ee846bf82b4f7de8"
+ integrity sha512-Z94u6fKT43lKeYHiVyvyR8fT7pwCzDu7RyMPpTvh054+xahSgj4HFQ+NmflvzdXsoAjYGdCguGaFKYuvq0ThCQ==
+
+magic-string@^0.30.21:
+ version "0.30.21"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91"
+ integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.5"
+
+motion-dom@^12.43.0:
+ version "12.43.0"
+ resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.43.0.tgz#65f618a520c4eacf49b6b1bbd023abceff8fb5dd"
+ integrity sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==
+ dependencies:
+ motion-utils "^12.39.0"
+
+motion-utils@^12.39.0:
+ version "12.39.0"
+ resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.39.0.tgz#e1c66f0e912999804bc5e69b4630c3bc794ef29f"
+ integrity sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==
+
+motion@^12.23.24:
+ version "12.43.0"
+ resolved "https://registry.yarnpkg.com/motion/-/motion-12.43.0.tgz#6f68b70aeb48045a294617d3673f3a997fea3bd7"
+ integrity sha512-BQgQbSa9Hn3/mtbib0MK53y6JSANa+YKUKlaYnWzAVDH424RYQ5LVpV3pNiWH00BA2z4ojsSdMzqT7g2FQwjuQ==
+ dependencies:
+ framer-motion "^12.43.0"
+ tslib "^2.4.0"
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.20:
+ version "3.3.20"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.20.tgz#dfd4444d85aa10111ef66ba85ed72e08ba0855d8"
+ integrity sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==
+
+node-releases@^2.0.60:
+ version "2.0.61"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.61.tgz#83531ed93275c9d487fbd0bdeea0ad24c62dd5d5"
+ integrity sha512-5NUN6QCxNFrS9oEA9RPS+d0AP+ooGBzzovY2JhIpDRHacPvOhHjXjUsUMX9qp4nLHZ+5jVgXB2jj/P4arGOE/g==
+
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+picomatch@^4.0.2, picomatch@^4.0.4:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.7.tgz#6313360034ccb36b3dc61ecbdff78121f90fe21f"
+ integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==
+
+postcss@^8.5.3:
+ version "8.5.32"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.32.tgz#fbccef8388a0c77508c713bfd37728d646595803"
+ integrity sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==
+ dependencies:
+ nanoid "^3.3.20"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.2"
+
+react-dom@^19.0.1:
+ version "19.3.1"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.3.1.tgz#b384c53cfcbe9c2a5d09d863b98455de9d68afe2"
+ integrity sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==
+ dependencies:
+ scheduler "^0.28.0"
+
+react-refresh@^0.18.0:
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.18.0.tgz#2dce97f4fe932a4d8142fa1630e475c1729c8062"
+ integrity sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==
+
+react@^19.0.1:
+ version "19.3.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-19.3.1.tgz#26e9523fc36ea06be5050ebb780249a133260ad7"
+ integrity sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==
+
+rollup@^4.34.9:
+ version "4.66.0"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.66.0.tgz#de6b85adfeedac7718adb66370b7be1d07bab6ad"
+ integrity sha512-Onq6/qO4ARhxIs+jYiHE0pYehadLyMECAiGEqQ+0/aWND3+2PmifJIIqBLYtuBODqHTlOUEQFtIVPyCy0Lck7A==
+ dependencies:
+ "@types/estree" "1.0.9"
+ optionalDependencies:
+ "@napi-rs/lzma-linux-x64-gnu" "1.5.1"
+ "@rollup/rollup-android-arm-eabi" "4.66.0"
+ "@rollup/rollup-android-arm64" "4.66.0"
+ "@rollup/rollup-darwin-arm64" "4.66.0"
+ "@rollup/rollup-darwin-x64" "4.66.0"
+ "@rollup/rollup-freebsd-arm64" "4.66.0"
+ "@rollup/rollup-freebsd-x64" "4.66.0"
+ "@rollup/rollup-linux-arm-gnueabihf" "4.66.0"
+ "@rollup/rollup-linux-arm-musleabihf" "4.66.0"
+ "@rollup/rollup-linux-arm64-gnu" "4.66.0"
+ "@rollup/rollup-linux-arm64-musl" "4.66.0"
+ "@rollup/rollup-linux-loong64-gnu" "4.66.0"
+ "@rollup/rollup-linux-loong64-musl" "4.66.0"
+ "@rollup/rollup-linux-ppc64-gnu" "4.66.0"
+ "@rollup/rollup-linux-ppc64-musl" "4.66.0"
+ "@rollup/rollup-linux-riscv64-gnu" "4.66.0"
+ "@rollup/rollup-linux-riscv64-musl" "4.66.0"
+ "@rollup/rollup-linux-s390x-gnu" "4.66.0"
+ "@rollup/rollup-linux-x64-gnu" "4.66.0"
+ "@rollup/rollup-linux-x64-musl" "4.66.0"
+ "@rollup/rollup-openbsd-x64" "4.66.0"
+ "@rollup/rollup-openharmony-arm64" "4.66.0"
+ "@rollup/rollup-win32-arm64-msvc" "4.66.0"
+ "@rollup/rollup-win32-ia32-msvc" "4.66.0"
+ "@rollup/rollup-win32-x64-gnu" "4.66.0"
+ "@rollup/rollup-win32-x64-msvc" "4.66.0"
+ fsevents "~2.3.2"
+
+scheduler@^0.28.0:
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.28.0.tgz#03d3ca348aeaf8b7502f64468f217b27523f9695"
+ integrity sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==
+
+semver@^6.3.1:
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+
+source-map-js@^1.2.1, source-map-js@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.2.tgz#79fb88d97535a21cb27162cb05d211b67acea4ab"
+ integrity sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==
+
+tailwindcss@4.3.3, tailwindcss@^4.1.14:
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.3.3.tgz#c006861611c213c1877893ab5b23daa16be2bb55"
+ integrity sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==
+
+tapable@^2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160"
+ integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==
+
+tinyglobby@^0.2.13:
+ version "0.2.17"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.17.tgz#562a9a6c9eb2b3b123d39719f9af5bb44fcd7631"
+ integrity sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==
+ dependencies:
+ fdir "^6.5.0"
+ picomatch "^4.0.4"
+
+tslib@^2.4.0, tslib@^2.8.1:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+ integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
+typescript@~5.8.2:
+ version "5.8.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
+ integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
+
+undici-types@~6.21.0:
+ version "6.21.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
+ integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
+
+update-browserslist-db@^1.3.4:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz#e8bd4596f6900805f9f12c5a5200c83c59c38faf"
+ integrity sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==
+ dependencies:
+ escalade "^3.2.0"
+ picocolors "^1.1.1"
+
+vite@^6.2.3:
+ version "6.4.5"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-6.4.5.tgz#8da9987120422f92e432b6d25535b82cee867dad"
+ integrity sha512-4enwjFfi4IwtEh0w+jPzpLVOFQiPHmmzPxcHXQOyEur47o6u0jE573DmGpjA+7irXoMLYRZD5ZaFUEneS3abPg==
+ dependencies:
+ esbuild "^0.25.0"
+ fdir "^6.4.4"
+ picomatch "^4.0.2"
+ postcss "^8.5.3"
+ rollup "^4.34.9"
+ tinyglobby "^0.2.13"
+ optionalDependencies:
+ fsevents "~2.3.3"
+
+yallist@^3.0.2:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
+ integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
diff --git a/docker-compose.yml b/docker-compose.yml
index 6d558ce..4e0d3c8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -162,3 +162,13 @@ services:
# Backend API Configuration
- VITE_API_BASE_URL=${API_BASE_URL:-https://api.ifri.khongisa.co.za/}
restart: unless-stopped
+ pfm-showcase:
+ image: pfm-showcase
+ build:
+ context: .
+ dockerfile: ./PostFundManagement.ShowcaseUI/Dockerfile
+ container_name: pfm-showcase
+ ports:
+ - "8078:3000"
+ restart: unless-stopped
+