Update all pricing to new tiered structure

Registration: Early Bird €120/wk (before May 15), Standard €200/wk
(before Jul 15), Last Minute €240/wk. Full month rates: €300/€500/€600.

Accommodation: flat rates — Commons Hub multi €275/wk, double €350/wk;
Herrnhof living €315/wk, triple €350/wk, single-in-double €420/wk,
single €665/wk, couple €700/wk.

Sponsorship pass values updated to match (based on last-minute rate).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-13 19:39:35 +00:00
parent 618de35793
commit 67c9fc0fb9
6 changed files with 90 additions and 75 deletions

View File

@ -22,7 +22,7 @@
| **Expected Attendance** | 60100 participants | | **Expected Attendance** | 60100 participants |
| **Format** | Four-week structured pop-up village | | **Format** | Four-week structured pop-up village |
| **Organizers** | Commons Hub | | **Organizers** | Commons Hub |
| **Pass Value** | €300/week (€1,200 for full 4 weeks) | | **Pass Value** | €120240/week depending on tier (€300600 for full 4 weeks) |
--- ---
@ -111,7 +111,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of
- Logo on participant materials and signage - Logo on participant materials and signage
**Engagement** **Engagement**
- **4 complimentary full passes** (4 weeks each — €4,800 value) - **4 complimentary full passes** (4 weeks each — €2,400 value)
- Dedicated 60-minute sponsored session slot - Dedicated 60-minute sponsored session slot
- Private dinner with organizers and community leaders - Private dinner with organizers and community leaders
- First access to participant list (with consent) for networking - First access to participant list (with consent) for networking
@ -133,7 +133,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of
- Acknowledgment at ceremonies - Acknowledgment at ceremonies
**Engagement** **Engagement**
- **2 complimentary full passes** (€2,400 value) - **2 complimentary full passes** (€1,200 value)
- 30-minute workshop or presentation slot - 30-minute workshop or presentation slot
- Access to participant introductions (with consent) - Access to participant introductions (with consent)
@ -152,7 +152,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of
- Social media mention - Social media mention
**Engagement** **Engagement**
- **1 complimentary full pass** (€1,200 value) - **1 complimentary full pass** (€600 value)
- Priority registration access - Priority registration access
**Content & Media** **Content & Media**
@ -168,7 +168,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of
- Social media thank-you post - Social media thank-you post
**Engagement** **Engagement**
- **1 discounted pass** (50% off — €600 value) - **1 discounted pass** (50% off — €300 value)
--- ---
@ -267,8 +267,8 @@ We'd love to discuss how a partnership could work for your organization.
| Date | Milestone | | Date | Milestone |
|------|-----------| |------|-----------|
| **Now** | Sponsorship discussions open | | **Now** | Sponsorship discussions open |
| **May 31, 2026** | Early bird registration closes | | **May 15, 2026** | Early bird registration closes |
| **July 31, 2026** | Regular registration closes | | **July 15, 2026** | Standard registration closes |
| **August 1, 2026** | Final sponsor deliverables due | | **August 1, 2026** | Final sponsor deliverables due |
| **Aug 24 Sep 20, 2026** | Valley of the Commons 2026 | | **Aug 24 Sep 20, 2026** | Valley of the Commons 2026 |
| **October 2026** | Post-event report and media shared | | **October 2026** | Post-event report and media shared |

View File

@ -4,7 +4,7 @@
const { Pool } = require('pg'); const { Pool } = require('pg');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const { syncApplication } = require('./google-sheets'); const { syncApplication } = require('./google-sheets');
const { createPayment, TICKET_LABELS, PRICE_PER_WEEK, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, PROCESSING_FEE_PERCENT, calculateAmount } = require('./mollie'); const { createPayment, TICKET_LABELS, REGISTRATION_PRICING, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, PROCESSING_FEE_PERCENT, calculateAmount, getPricingTier } = require('./mollie');
const { addToListmonk } = require('./listmonk'); const { addToListmonk } = require('./listmonk');
// Initialize PostgreSQL connection pool // Initialize PostgreSQL connection pool
@ -44,11 +44,14 @@ const confirmationEmail = (application) => {
let accomHtml = ''; let accomHtml = '';
if (accomType && ACCOMMODATION_PRICES[accomType]) { if (accomType && ACCOMMODATION_PRICES[accomType]) {
const label = ACCOMMODATION_LABELS[accomType] || accomType; const label = ACCOMMODATION_LABELS[accomType] || accomType;
const perWeek = ACCOMMODATION_PRICES[accomType]; const accomPrices = ACCOMMODATION_PRICES[accomType];
const accomDisplay = weeksCount === 4
? `${label} — &euro;${accomPrices.perMonth} (full month)`
: `${label} — &euro;${accomPrices.perWeek}/week &times; ${weeksCount} week${weeksCount > 1 ? 's' : ''} = &euro;${pricing.accommodation}`;
accomHtml = ` accomHtml = `
<tr> <tr>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Accommodation:</strong></td> <td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Accommodation:</strong></td>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">${label}<br>&euro;${perWeek.toFixed(2)}/week &times; ${weeksCount} week${weeksCount > 1 ? 's' : ''} = &euro;${pricing.accommodation}</td> <td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">${accomDisplay}</td>
</tr>`; </tr>`;
} }
@ -72,7 +75,7 @@ const confirmationEmail = (application) => {
<table style="width: 100%; border-collapse: collapse;"> <table style="width: 100%; border-collapse: collapse;">
<tr> <tr>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Registration:</strong></td> <td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;"><strong>Registration:</strong></td>
<td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">&euro;${PRICE_PER_WEEK}/week &times; ${weeksCount} week${weeksCount > 1 ? 's' : ''} = &euro;${pricing.registration}</td> <td style="padding: 6px 0; border-bottom: 1px solid #e0e0e0;">${weeksCount === 4 ? `&euro;${pricing.registration} (full month)` : `&euro;${REGISTRATION_PRICING[pricing.tier].perWeek}/week &times; ${weeksCount} week${weeksCount > 1 ? 's' : ''} = &euro;${pricing.registration}`} (${pricing.tier === 'early' ? 'Early Bird' : pricing.tier === 'standard' ? 'Standard' : 'Last Minute'} rate)</td>
</tr> </tr>
${accomHtml} ${accomHtml}
<tr> <tr>

View File

@ -29,41 +29,39 @@ const smtp = nodemailer.createTransport({
tls: { rejectUnauthorized: false }, tls: { rejectUnauthorized: false },
}); });
// Base registration price per week (EUR) // Tiered registration pricing (EUR)
const PRICE_PER_WEEK = 300.00; // Early Bird: before May 15 | Standard: before July 15 | Last Minute: after July 15
const REGISTRATION_PRICING = {
early: { perWeek: 120, perMonth: 300 },
standard: { perWeek: 200, perMonth: 500 },
lastMin: { perWeek: 240, perMonth: 600 },
};
// Processing fee percentage (added on top of subtotal) // Processing fee percentage (added on top of subtotal)
const PROCESSING_FEE_PERCENT = 0.02; const PROCESSING_FEE_PERCENT = 0.02;
// Pricing tier — override with a fixed tier, or set to null to use date-based logic // Date-based tier cutoffs
const CURRENT_PRICING_TIER = 'standard';
// Date-based tier cutoffs (used when CURRENT_PRICING_TIER is null)
// Set ISO date strings, e.g. '2026-05-01'
const PRICING_TIER_DATES = { const PRICING_TIER_DATES = {
earlyEnd: null, // before this date → 'early' earlyEnd: '2026-05-15', // before this date → 'early'
standardEnd: null, // before this date → 'standard'; after → 'lastMin' standardEnd: '2026-07-15', // before this date → 'standard'; after → 'lastMin'
}; };
function getPricingTier() { function getPricingTier() {
if (CURRENT_PRICING_TIER) return CURRENT_PRICING_TIER;
const now = new Date(); const now = new Date();
if (PRICING_TIER_DATES.earlyEnd && now < new Date(PRICING_TIER_DATES.earlyEnd)) return 'early'; if (now < new Date(PRICING_TIER_DATES.earlyEnd)) return 'early';
if (PRICING_TIER_DATES.standardEnd && now < new Date(PRICING_TIER_DATES.standardEnd)) return 'standard'; if (now < new Date(PRICING_TIER_DATES.standardEnd)) return 'standard';
return 'lastMin'; return 'lastMin';
} }
// Accommodation prices (EUR) — tiered by duration and booking window // Accommodation prices (EUR) — flat rates (per week and per month/4-week)
// 1week = per-week rate (multiply by weeks for 13 week stays)
// 4week = flat total for a full 4-week stay
const ACCOMMODATION_PRICES = { const ACCOMMODATION_PRICES = {
'ch-multi': { '1week': { early: 395, standard: 475, lastMin: 515 }, '4week': { early: 1400, standard: 1600, lastMin: 1700 } }, 'ch-multi': { perWeek: 275, perMonth: 1100 },
'ch-double': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, 'ch-double': { perWeek: 350, perMonth: 1400 },
'hh-living': { '1week': { early: 435, standard: 515, lastMin: 555 }, '4week': { early: 1560, standard: 1760, lastMin: 1860 } }, 'hh-living': { perWeek: 315, perMonth: 1260 },
'hh-triple': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, 'hh-triple': { perWeek: 350, perMonth: 1400 },
'hh-twin': { '1week': { early: 540, standard: 620, lastMin: 660 }, '4week': { early: 1980, standard: 2180, lastMin: 2280 } }, 'hh-twin': { perWeek: 420, perMonth: 1680 },
'hh-single': { '1week': { early: 785, standard: 865, lastMin: 905 }, '4week': { early: 2960, standard: 3160, lastMin: 3260 } }, 'hh-single': { perWeek: 665, perMonth: 2660 },
'hh-couple': { '1week': { early: 940, standard: 1100, lastMin: 1180 }, '4week': { early: 3400, standard: 3800, lastMin: 4000 } }, 'hh-couple': { perWeek: 700, perMonth: 2800 },
}; };
// Human-readable labels for accommodation types // Human-readable labels for accommodation types
@ -72,7 +70,7 @@ const ACCOMMODATION_LABELS = {
'ch-double': 'Commons Hub — Bed in Double Room', 'ch-double': 'Commons Hub — Bed in Double Room',
'hh-living': 'Herrnhof Villa — Bed in Living Room', 'hh-living': 'Herrnhof Villa — Bed in Living Room',
'hh-triple': 'Herrnhof Villa — Bed in Triple Room', 'hh-triple': 'Herrnhof Villa — Bed in Triple Room',
'hh-twin': 'Herrnhof Villa — Bed in Twin Room', 'hh-twin': 'Herrnhof Villa — Single Bed in Double Room',
'hh-single': 'Herrnhof Villa — Single Room', 'hh-single': 'Herrnhof Villa — Single Room',
'hh-couple': 'Herrnhof Villa — Couple Room', 'hh-couple': 'Herrnhof Villa — Couple Room',
}; };
@ -92,16 +90,15 @@ const TICKET_LABELS = {
function calculateAmount(ticketType, weeksCount, accommodationType) { function calculateAmount(ticketType, weeksCount, accommodationType) {
const weeks = weeksCount || 1; const weeks = weeksCount || 1;
const tier = getPricingTier(); const tier = getPricingTier();
const registration = PRICE_PER_WEEK * weeks; const regPricing = REGISTRATION_PRICING[tier];
// Full month (4 weeks) gets the month rate; otherwise per-week
const registration = weeks === 4 ? regPricing.perMonth : regPricing.perWeek * weeks;
let accommodation = 0; let accommodation = 0;
if (accommodationType && ACCOMMODATION_PRICES[accommodationType]) { if (accommodationType && ACCOMMODATION_PRICES[accommodationType]) {
const prices = ACCOMMODATION_PRICES[accommodationType]; const prices = ACCOMMODATION_PRICES[accommodationType];
if (weeks === 4) { accommodation = weeks === 4 ? prices.perMonth : prices.perWeek * weeks;
accommodation = prices['4week'][tier];
} else {
accommodation = prices['1week'][tier] * weeks;
}
} }
const subtotal = registration + accommodation; const subtotal = registration + accommodation;
@ -439,7 +436,7 @@ async function getPaymentStatus(req, res) {
module.exports = { module.exports = {
createPayment, handleWebhook, getPaymentStatus, createPayment, handleWebhook, getPaymentStatus,
PRICE_PER_WEEK, PROCESSING_FEE_PERCENT, REGISTRATION_PRICING, PROCESSING_FEE_PERCENT,
ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS,
TICKET_LABELS, calculateAmount, getPricingTier, TICKET_LABELS, calculateAmount, getPricingTier,
}; };

View File

@ -655,13 +655,13 @@
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('ch-multi')"> <label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('ch-multi')">
<input type="radio" name="room_type" value="ch-multi" style="display:none;"> <input type="radio" name="room_type" value="ch-multi" style="display:none;">
<h4>Bed in Multi-Room <span style="float:right; color: var(--forest); font-weight: 600;">475/wk</span></h4> <h4>Bed in Multi-Room <span style="float:right; color: var(--forest); font-weight: 600;">275/wk</span></h4>
<div class="desc">Bed in a shared multi-bed room. The most affordable option.</div> <div class="desc">Bed in a shared multi-bed room. The most affordable option.</div>
</label> </label>
<label class="week-card" style="cursor: pointer;" onclick="selectRoom('ch-double')"> <label class="week-card" style="cursor: pointer;" onclick="selectRoom('ch-double')">
<input type="radio" name="room_type" value="ch-double" style="display:none;"> <input type="radio" name="room_type" value="ch-double" style="display:none;">
<h4>Bed in Double Room <span style="float:right; color: var(--forest); font-weight: 600;">550/wk</span></h4> <h4>Bed in Double Room <span style="float:right; color: var(--forest); font-weight: 600;">350/wk</span></h4>
<div class="desc">Shared with one other person.</div> <div class="desc">Shared with one other person.</div>
</label> </label>
</div> </div>
@ -672,31 +672,31 @@
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-living')"> <label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-living')">
<input type="radio" name="room_type" value="hh-living" style="display:none;"> <input type="radio" name="room_type" value="hh-living" style="display:none;">
<h4>Bed in Living Room <span style="float:right; color: var(--forest); font-weight: 600;">515/wk</span></h4> <h4>Bed in Living Room <span style="float:right; color: var(--forest); font-weight: 600;">315/wk</span></h4>
<div class="desc">Shared living space with flexible sleeping arrangement.</div> <div class="desc">Shared living space with flexible sleeping arrangement.</div>
</label> </label>
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-triple')"> <label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-triple')">
<input type="radio" name="room_type" value="hh-triple" style="display:none;"> <input type="radio" name="room_type" value="hh-triple" style="display:none;">
<h4>Bed in Triple Room <span style="float:right; color: var(--forest); font-weight: 600;">550/wk</span></h4> <h4>Bed in Triple Room <span style="float:right; color: var(--forest); font-weight: 600;">350/wk</span></h4>
<div class="desc">Room shared between three people.</div> <div class="desc">Room shared between three people.</div>
</label> </label>
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-twin')"> <label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-twin')">
<input type="radio" name="room_type" value="hh-twin" style="display:none;"> <input type="radio" name="room_type" value="hh-twin" style="display:none;">
<h4>Bed in Twin Room <span style="float:right; color: var(--forest); font-weight: 600;">620/wk</span></h4> <h4>Single Bed in Double Room <span style="float:right; color: var(--forest); font-weight: 600;">420/wk</span></h4>
<div class="desc">Room shared with one other person, separate beds.</div> <div class="desc">Your own bed in a room shared with one other person.</div>
</label> </label>
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-single')"> <label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectRoom('hh-single')">
<input type="radio" name="room_type" value="hh-single" style="display:none;"> <input type="radio" name="room_type" value="hh-single" style="display:none;">
<h4>Single Room <span style="float:right; color: var(--forest); font-weight: 600;">865/wk</span></h4> <h4>Single Room <span style="float:right; color: var(--forest); font-weight: 600;">665/wk</span></h4>
<div class="desc">Private room for one person.</div> <div class="desc">Private room for one person.</div>
</label> </label>
<label class="week-card" style="cursor: pointer;" onclick="selectRoom('hh-couple')"> <label class="week-card" style="cursor: pointer;" onclick="selectRoom('hh-couple')">
<input type="radio" name="room_type" value="hh-couple" style="display:none;"> <input type="radio" name="room_type" value="hh-couple" style="display:none;">
<h4>Couple Room <span style="float:right; color: var(--forest); font-weight: 600;">1,100/wk</span></h4> <h4>Couple Room <span style="float:right; color: var(--forest); font-weight: 600;">700/wk</span></h4>
<div class="desc">Private room with double bed for couples.</div> <div class="desc">Private room with double bed for couples.</div>
</label> </label>
</div> </div>
@ -776,21 +776,35 @@
<script> <script>
let currentStep = 1; let currentStep = 1;
const totalSteps = 12; const totalSteps = 12;
const PRICE_PER_WEEK = 300;
const PROCESSING_FEE_PERCENT = 0.02; const PROCESSING_FEE_PERCENT = 0.02;
// Current pricing tier (must match api/mollie.js) // Tiered registration pricing (must match api/mollie.js)
const CURRENT_PRICING_TIER = 'standard'; const REGISTRATION_PRICING = {
early: { perWeek: 120, perMonth: 300 },
standard: { perWeek: 200, perMonth: 500 },
lastMin: { perWeek: 240, perMonth: 600 },
};
// Accommodation prices — tiered by duration and booking window (must match api/mollie.js) function getPricingTier() {
const now = new Date();
if (now < new Date('2026-05-15')) return 'early';
if (now < new Date('2026-07-15')) return 'standard';
return 'lastMin';
}
const currentTier = getPricingTier();
const tierPricing = REGISTRATION_PRICING[currentTier];
const TIER_LABELS = { early: 'Early Bird', standard: 'Standard', lastMin: 'Last Minute' };
// Accommodation prices — flat rates (must match api/mollie.js)
const ACCOMMODATION_PRICES = { const ACCOMMODATION_PRICES = {
'ch-multi': { '1week': { early: 395, standard: 475, lastMin: 515 }, '4week': { early: 1400, standard: 1600, lastMin: 1700 } }, 'ch-multi': { perWeek: 275, perMonth: 1100 },
'ch-double': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, 'ch-double': { perWeek: 350, perMonth: 1400 },
'hh-living': { '1week': { early: 435, standard: 515, lastMin: 555 }, '4week': { early: 1560, standard: 1760, lastMin: 1860 } }, 'hh-living': { perWeek: 315, perMonth: 1260 },
'hh-triple': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, 'hh-triple': { perWeek: 350, perMonth: 1400 },
'hh-twin': { '1week': { early: 540, standard: 620, lastMin: 660 }, '4week': { early: 1980, standard: 2180, lastMin: 2280 } }, 'hh-twin': { perWeek: 420, perMonth: 1680 },
'hh-single': { '1week': { early: 785, standard: 865, lastMin: 905 }, '4week': { early: 2960, standard: 3160, lastMin: 3260 } }, 'hh-single': { perWeek: 665, perMonth: 2660 },
'hh-couple': { '1week': { early: 940, standard: 1100, lastMin: 1180 }, '4week': { early: 3400, standard: 3800, lastMin: 4000 } }, 'hh-couple': { perWeek: 700, perMonth: 2800 },
}; };
const ACCOMMODATION_LABELS = { const ACCOMMODATION_LABELS = {
@ -798,7 +812,7 @@
'ch-double': 'Commons Hub — Bed in Double Room', 'ch-double': 'Commons Hub — Bed in Double Room',
'hh-living': 'Herrnhof Villa — Bed in Living Room', 'hh-living': 'Herrnhof Villa — Bed in Living Room',
'hh-triple': 'Herrnhof Villa — Bed in Triple Room', 'hh-triple': 'Herrnhof Villa — Bed in Triple Room',
'hh-twin': 'Herrnhof Villa — Bed in Twin Room', 'hh-twin': 'Herrnhof Villa — Single Bed in Double Room',
'hh-single': 'Herrnhof Villa — Single Room', 'hh-single': 'Herrnhof Villa — Single Room',
'hh-couple': 'Herrnhof Villa — Couple Room', 'hh-couple': 'Herrnhof Villa — Couple Room',
}; };
@ -806,9 +820,8 @@
function getAccommodationPrice(accomType, weeksCount) { function getAccommodationPrice(accomType, weeksCount) {
if (!accomType || !ACCOMMODATION_PRICES[accomType]) return 0; if (!accomType || !ACCOMMODATION_PRICES[accomType]) return 0;
const prices = ACCOMMODATION_PRICES[accomType]; const prices = ACCOMMODATION_PRICES[accomType];
const tier = CURRENT_PRICING_TIER; if (weeksCount === 4) return prices.perMonth;
if (weeksCount === 4) return prices['4week'][tier]; return prices.perWeek * weeksCount;
return prices['1week'][tier] * weeksCount;
} }
function updateProgress() { function updateProgress() {
@ -966,23 +979,25 @@
return; return;
} }
const registration = PRICE_PER_WEEK * weeksCount; const registration = weeksCount === 4 ? tierPricing.perMonth : tierPricing.perWeek * weeksCount;
const accomType = document.getElementById('accommodation_type').value; const accomType = document.getElementById('accommodation_type').value;
const accommodation = getAccommodationPrice(accomType, weeksCount); const accommodation = getAccommodationPrice(accomType, weeksCount);
const subtotal = registration + accommodation; const subtotal = registration + accommodation;
const fee = subtotal * PROCESSING_FEE_PERCENT; const fee = subtotal * PROCESSING_FEE_PERCENT;
const total = subtotal + fee; const total = subtotal + fee;
const tierLabel = { early: 'Early Bird', standard: 'Standard', lastMin: 'Last Minute' }[CURRENT_PRICING_TIER]; const tierLabel = TIER_LABELS[currentTier];
let html = `<strong>Registration:</strong> €${PRICE_PER_WEEK} × ${weeksCount} wk = €${registration.toFixed(2)}`; let html = weeksCount === 4
? `<strong>Registration:</strong> €${tierPricing.perMonth} (full month, ${tierLabel})`
: `<strong>Registration:</strong> €${tierPricing.perWeek} × ${weeksCount} wk = €${registration.toFixed(2)} (${tierLabel})`;
if (accommodation > 0) { if (accommodation > 0) {
const label = ACCOMMODATION_LABELS[accomType] || accomType; const label = ACCOMMODATION_LABELS[accomType] || accomType;
const prices = ACCOMMODATION_PRICES[accomType];
if (weeksCount === 4) { if (weeksCount === 4) {
html += `<br><strong>Accommodation:</strong> ${label}<br>&nbsp;&nbsp;4-week ${tierLabel} rate = €${accommodation.toFixed(2)}`; html += `<br><strong>Accommodation:</strong> ${label}<br>&nbsp;&nbsp;€${prices.perMonth} (full month)`;
} else { } else {
const perWeek = ACCOMMODATION_PRICES[accomType]['1week'][CURRENT_PRICING_TIER]; html += `<br><strong>Accommodation:</strong> ${label}<br>&nbsp;&nbsp;€${prices.perWeek} × ${weeksCount} wk = €${accommodation.toFixed(2)}`;
html += `<br><strong>Accommodation:</strong> ${label}<br>&nbsp;&nbsp;€${perWeek.toFixed(2)} × ${weeksCount} wk (${tierLabel}) = €${accommodation.toFixed(2)}`;
} }
} }

View File

@ -223,7 +223,7 @@
<div class="cta-details"> <div class="cta-details">
<span>Aug 24 Sep 20, 2026</span> <span>Aug 24 Sep 20, 2026</span>
<span>Höllental, Austrian Alps</span> <span>Höllental, Austrian Alps</span>
<span>€300 / week</span> <span>from €120 / week</span>
</div> </div>
<a href="/apply.html" class="register-button">REGISTER NOW</a> <a href="/apply.html" class="register-button">REGISTER NOW</a>
<p class="cta-note">You'll be added to our mailing list to stay updated.</p> <p class="cta-note">You'll be added to our mailing list to stay updated.</p>

View File

@ -253,7 +253,7 @@
</div> </div>
<p class="tier-tagline">Become part of the Valley ecosystem</p> <p class="tier-tagline">Become part of the Valley ecosystem</p>
<ul> <ul>
<li><span class="highlight">4 complimentary full passes</span> (4 weeks each — €4,800 value)</li> <li><span class="highlight">4 complimentary full passes</span> (4 weeks each — €2,400 value)</li>
<li>60-minute sponsored session slot</li> <li>60-minute sponsored session slot</li>
<li>Private dinner with organizers and community leaders</li> <li>Private dinner with organizers and community leaders</li>
<li>Logo on hero section, all pages, and signage</li> <li>Logo on hero section, all pages, and signage</li>
@ -269,7 +269,7 @@
</div> </div>
<p class="tier-tagline">Plant seeds for regenerative futures</p> <p class="tier-tagline">Plant seeds for regenerative futures</p>
<ul> <ul>
<li><span class="highlight">2 complimentary full passes</span> (€2,400 value)</li> <li><span class="highlight">2 complimentary full passes</span> (€1,200 value)</li>
<li>30-minute workshop slot</li> <li>30-minute workshop slot</li>
<li>Logo on sponsor section and signage</li> <li>Logo on sponsor section and signage</li>
<li>Social media recognition</li> <li>Social media recognition</li>
@ -283,7 +283,7 @@
</div> </div>
<p class="tier-tagline">Support commons-building infrastructure</p> <p class="tier-tagline">Support commons-building infrastructure</p>
<ul> <ul>
<li><span class="highlight">1 complimentary full pass</span> (€1,200 value)</li> <li><span class="highlight">1 complimentary full pass</span> (€600 value)</li>
<li>Priority registration</li> <li>Priority registration</li>
<li>Logo on sponsor section</li> <li>Logo on sponsor section</li>
<li>Newsletter mention</li> <li>Newsletter mention</li>
@ -297,7 +297,7 @@
</div> </div>
<p class="tier-tagline">Show solidarity with the movement</p> <p class="tier-tagline">Show solidarity with the movement</p>
<ul> <ul>
<li><span class="highlight">1 discounted pass</span> (50% off — €600 value)</li> <li><span class="highlight">1 discounted pass</span> (50% off — €300 value)</li>
<li>Name on supporters section</li> <li>Name on supporters section</li>
<li>Social media thank-you</li> <li>Social media thank-you</li>
</ul> </ul>