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 */} +
+ + + + + + + + + + {COMPARISON_FEATURES.map((row, idx) => ( + + + + + + ))} + +
+ Functional Dimension + +
+ + PFM Console (Funders & DFIs) +
+
+
+ + PFM Partner (Grantees & Contractors) +
+
+ {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) => ( + + ))} +
+ + + 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.title} +
+
+ +
+
+ + {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 ( + + ); + })} +
+ + {/* Selected Poster Showcase Card */} +
+ {/* Poster Image Preview */} +
onOpenPosterModal(currentPoster)}> +
+ {currentPoster.title} +
+ + {/* 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 */} +
+
+ + +
+ +
+ + + Live Application Telemetry + + +
+
+ + {/* 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 */} +
+ {currentItem.title} + + {/* Interactive Hotspots Overlay */} + {currentItem.hotspots?.map((hotspot, idx) => ( +
+ + + {/* Tooltip Card */} + {activeHotspot === idx && ( +
+
+ + {hotspot.title} +
+

+ {hotspot.description} +

+
+ )} +
+ ))} + + {/* Bottom Bar Info Overlay */} +
+
+
+ + {currentItem.platform} + + + {currentItem.category} + +
+

+ {currentItem.title} +

+

+ {currentItem.subtitle} +

+
+ + +
+
+
+ + {/* 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 */} + + + {/* 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 */} +
+ {poster.title} +
+ + {/* 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 */} +
+ {item.title} +
+ + {/* 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) => ( + + ))} +
+ + + 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.title} +
+
+ +
+
+ + {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 ( + + ); + })} +
+
+ + {/* 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 ? ( + + ) : ( + + )} + + +
+
+ + {/* 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 +