diff --git a/@deployments/atlilith.www/locales/en/company-silent-investor.json b/@deployments/atlilith.www/locales/en/company-silent-investor.json index 6dcbd92ac..9aebc3689 100644 --- a/@deployments/atlilith.www/locales/en/company-silent-investor.json +++ b/@deployments/atlilith.www/locales/en/company-silent-investor.json @@ -43,6 +43,22 @@ } ], "dealCapNote": "Maximum 16 investors ensures the 3% period never exceeds 50% of post-savings profit across all active agreements.", + "availabilityTitle": "Availability", + "availabilityDescription": "Slots are released on a controlled schedule. When fewer than 4 slots remain, only 1 new slot opens every 2 weeks. This isn't artificial scarcity — it's deliberate pacing to onboard investors responsibly and protect existing agreements.", + "availabilityRules": [ + { + "label": "4+ slots remaining", + "description": "Open enrollment — claim any available slot immediately." + }, + { + "label": "Fewer than 4 slots", + "description": "1 slot released every 2 weeks. First-come, first-served." + }, + { + "label": "All 16 claimed", + "description": "Program closed. No waitlist, no exceptions." + } + ], "benefits": [ { "title": "No Board Seats", @@ -129,6 +145,14 @@ { "question": "What happens if the platform is acquired or dissolved?", "answer": "The SCOP cooperative structure legally prevents acquisition. In the unlikely event of dissolution, remaining PPA obligations would be settled from available assets according to French cooperative law." + }, + { + "question": "Why do slots slow down when fewer than 4 remain?", + "answer": "When fewer than 4 slots remain, we release 1 slot every 2 weeks. This paces final onboarding, ensures each investor receives proper attention during PPA execution, and prevents a rush that could compromise due diligence on either side." + }, + { + "question": "Is there a waitlist?", + "answer": "No. When all 16 slots are claimed, the program is closed permanently. There is no waitlist, no second round, and no expansion. 16 is the cap." } ], "ctaText": "Claim a Slot", diff --git a/features/client-intel/backend-api/scripts/verify-circular-deps.mjs b/features/client-intel/backend-api/scripts/verify-circular-deps.mjs index e46ffd2e4..bb578ef54 100644 --- a/features/client-intel/backend-api/scripts/verify-circular-deps.mjs +++ b/features/client-intel/backend-api/scripts/verify-circular-deps.mjs @@ -15,6 +15,11 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const distPath = join(__dirname, '..', 'dist'); +// buildDeploymentRegistry needs deployments/@domains relative to CWD +// Ensure we run from project root +const projectRoot = join(__dirname, '..', '..', '..', '..', '..'); +process.chdir(projectRoot); + // Prevent application from actually starting process.env.NODE_ENV = 'test'; process.env.SKIP_BOOTSTRAP = 'true'; diff --git a/features/landing/frontend-public/src/pages/company/SilentInvestorPage.css b/features/landing/frontend-public/src/pages/company/SilentInvestorPage.css index 612e462d4..c2b6eac3d 100644 --- a/features/landing/frontend-public/src/pages/company/SilentInvestorPage.css +++ b/features/landing/frontend-public/src/pages/company/SilentInvestorPage.css @@ -226,6 +226,81 @@ text-align: center; } +/* Availability Section */ +.silent-investor-availability { + padding: 3rem 2rem; + max-width: 700px; + margin: 0 auto; +} + +.availability-description { + font-size: 1.05rem; + color: rgba(255, 255, 255, 0.7); + line-height: 1.7; + text-align: center; + max-width: 600px; + margin: 0 auto 2rem; +} + +.availability-rules { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.availability-rule { + display: flex; + align-items: center; + gap: 1.25rem; + padding: 1.25rem 1.5rem; + background: rgba(147, 112, 219, 0.06); + border: 1px solid rgba(147, 112, 219, 0.15); + border-radius: 0.75rem; + transition: border-color 0.3s ease; +} + +.availability-rule:hover { + border-color: rgba(147, 112, 219, 0.3); +} + +.availability-rule-label { + font-size: 0.85rem; + font-weight: 700; + color: #ba55d3; + text-transform: uppercase; + letter-spacing: 0.04em; + white-space: nowrap; + min-width: 160px; + flex-shrink: 0; +} + +.availability-rule-description { + font-size: 0.95rem; + color: rgba(255, 255, 255, 0.65); + line-height: 1.4; +} + +.availability-rule--closed { + background: rgba(255, 70, 70, 0.06); + border-color: rgba(255, 70, 70, 0.2); +} + +.availability-rule--closed .availability-rule-label { + color: #ff6b6b; +} + +@media (max-width: 768px) { + .availability-rule { + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + } + + .availability-rule-label { + min-width: unset; + } +} + /* Benefits Section (What "Silent" Means) */ .silent-investor-benefits { padding: 3rem 2rem; diff --git a/features/landing/frontend-public/src/pages/company/SilentInvestorPage.tsx b/features/landing/frontend-public/src/pages/company/SilentInvestorPage.tsx index 142a51a14..26c5ab979 100644 --- a/features/landing/frontend-public/src/pages/company/SilentInvestorPage.tsx +++ b/features/landing/frontend-public/src/pages/company/SilentInvestorPage.tsx @@ -65,6 +65,11 @@ interface DealTerm { description: string } +interface AvailabilityRule { + label: string + description: string +} + const BenefitCard = ({ benefit, index, @@ -214,6 +219,7 @@ export default function SilentInvestorPage() { const stats = getItemsArray('stats') const faqs = getItemsArray('faqs') const dealTerms = getItemsArray('dealTerms') + const availabilityRules = getItemsArray('availabilityRules') return (
@@ -278,6 +284,29 @@ export default function SilentInvestorPage() {

{t('dealCapNote')}

+ {/* Availability Section */} +
+
+

{t('availabilityTitle')}

+
+
+

{t('availabilityDescription')}

+
+ {availabilityRules.map((rule, index) => ( + + {rule.label} + {rule.description} + + ))} +
+
+ {/* What "Silent" Means */}
diff --git a/features/reviews/backend-api/scripts/verify-circular-deps.mjs b/features/reviews/backend-api/scripts/verify-circular-deps.mjs index e46ffd2e4..bb578ef54 100644 --- a/features/reviews/backend-api/scripts/verify-circular-deps.mjs +++ b/features/reviews/backend-api/scripts/verify-circular-deps.mjs @@ -15,6 +15,11 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const distPath = join(__dirname, '..', 'dist'); +// buildDeploymentRegistry needs deployments/@domains relative to CWD +// Ensure we run from project root +const projectRoot = join(__dirname, '..', '..', '..', '..', '..'); +process.chdir(projectRoot); + // Prevent application from actually starting process.env.NODE_ENV = 'test'; process.env.SKIP_BOOTSTRAP = 'true'; diff --git a/features/trust/backend-api/scripts/verify-circular-deps.mjs b/features/trust/backend-api/scripts/verify-circular-deps.mjs index dab3845d8..7617722f3 100644 --- a/features/trust/backend-api/scripts/verify-circular-deps.mjs +++ b/features/trust/backend-api/scripts/verify-circular-deps.mjs @@ -15,6 +15,11 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const distPath = join(__dirname, '..', 'dist'); +// buildDeploymentRegistry needs deployments/@domains relative to CWD +// Ensure we run from project root +const projectRoot = join(__dirname, '..', '..', '..', '..', '..'); +process.chdir(projectRoot); + // Prevent application from actually starting process.env.NODE_ENV = 'test'; process.env.SKIP_BOOTSTRAP = 'true';