feat: restructure application form (10 steps), add sponsorship tiers, consolidate CTAs
- Restructure apply form: landing screen, pricing at step 1, theme picker, belief update, review & pay step, localStorage autosave, warm success state - Add 7 new DB columns (migration-004): selected_weeks, top_themes, belief_update, volunteer_interest, coupon_code, food_preference, accessibility_needs - Update confirmation emails: 1-week review timeline, warmer tone - Add sponsorship tiers page (Friend/Symbiont/Spore/Mycelium) - Consolidate all "Apply Now" → "Register Now", remove duplicate CTAs - Add new fields to admin panel display Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
707bdc3d53
commit
79141b7142
46
admin.html
46
admin.html
|
|
@ -791,6 +791,52 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<h3>Themes & Beliefs</h3>
|
||||||
|
<div class="detail-grid">
|
||||||
|
<div class="detail-item full-width">
|
||||||
|
<label>Top Themes</label>
|
||||||
|
<div class="chip-list">
|
||||||
|
${(app.top_themes || []).map(t => `<span class="chip">${t}</span>`).join('') || '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item full-width">
|
||||||
|
<label>Belief Update</label>
|
||||||
|
<div class="long-text">${app.belief_update || '-'}</div>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item full-width">
|
||||||
|
<label>Selected Weeks</label>
|
||||||
|
<div class="chip-list">
|
||||||
|
${(app.selected_weeks || []).map(w => `<span class="chip">${w}</span>`).join('') || '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-section">
|
||||||
|
<h3>Practical Needs</h3>
|
||||||
|
<div class="detail-grid">
|
||||||
|
<div class="detail-item">
|
||||||
|
<label>Food Preference</label>
|
||||||
|
<p>${app.food_preference || '-'}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item">
|
||||||
|
<label>Volunteer Interest</label>
|
||||||
|
<p>${app.volunteer_interest ? '✓ Yes' : 'No'}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail-item full-width">
|
||||||
|
<label>Accessibility Needs</label>
|
||||||
|
<div class="long-text">${app.accessibility_needs || '-'}</div>
|
||||||
|
</div>
|
||||||
|
${app.coupon_code ? `
|
||||||
|
<div class="detail-item">
|
||||||
|
<label>Coupon Code</label>
|
||||||
|
<p>${app.coupon_code}</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="detail-section">
|
<div class="detail-section">
|
||||||
<h3>Financial & Practical</h3>
|
<h3>Financial & Practical</h3>
|
||||||
<div class="detail-grid">
|
<div class="detail-grid">
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,12 @@ const confirmationEmail = (application) => {
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subject: 'Application Received - Valley of the Commons',
|
subject: 'Welcome to the Process - Valley of the Commons',
|
||||||
html: `
|
html: `
|
||||||
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
|
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
|
||||||
<h1 style="color: #2d5016; margin-bottom: 24px;">Thank You for Applying!</h1>
|
<h1 style="color: #2d5016; margin-bottom: 24px;">We're glad you're here, ${application.first_name}!</h1>
|
||||||
|
|
||||||
<p>Dear ${application.first_name},</p>
|
<p>Your application to <strong>Valley of the Commons</strong> (August 24 – September 20, 2026) has been received. We're excited to read about what you'll bring to the village.</p>
|
||||||
|
|
||||||
<p>We've received your application to join <strong>Valley of the Commons</strong> (August 24 - September 20, 2026).</p>
|
|
||||||
|
|
||||||
<div style="background: #f5f5f0; padding: 20px; border-radius: 8px; margin: 24px 0;">
|
<div style="background: #f5f5f0; padding: 20px; border-radius: 8px; margin: 24px 0;">
|
||||||
<h3 style="margin-top: 0; color: #2d5016;">Your Booking Summary</h3>
|
<h3 style="margin-top: 0; color: #2d5016;">Your Booking Summary</h3>
|
||||||
|
|
@ -99,10 +97,9 @@ const confirmationEmail = (application) => {
|
||||||
<h3 style="margin-top: 0; color: #2d5016;">What happens next?</h3>
|
<h3 style="margin-top: 0; color: #2d5016;">What happens next?</h3>
|
||||||
<ol style="margin-bottom: 0;">
|
<ol style="margin-bottom: 0;">
|
||||||
<li><a href="${process.env.BASE_URL || 'https://valleyofthecommons.com'}/api/mollie/resume?id=${application.id}" style="color: #2d5016; font-weight: 600;">Complete your registration payment</a> (if you haven't already)</li>
|
<li><a href="${process.env.BASE_URL || 'https://valleyofthecommons.com'}/api/mollie/resume?id=${application.id}" style="color: #2d5016; font-weight: 600;">Complete your registration payment</a> (if you haven't already)</li>
|
||||||
<li>Our team will review your application</li>
|
<li>Our team will review your application within <strong>1 week</strong></li>
|
||||||
<li>We may reach out with follow-up questions</li>
|
<li>We may reach out with follow-up questions</li>
|
||||||
<li>You'll receive a decision within 2-3 weeks</li>
|
${accomType ? '<li>Your accommodation will be allocated and details sent to you shortly after payment is confirmed</li>' : ''}
|
||||||
${accomType ? '<li>Your bed will be assigned automatically once payment is confirmed</li>' : ''}
|
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -112,7 +109,7 @@ const confirmationEmail = (application) => {
|
||||||
<li><a href="https://valleyofthecommons.com/">Valley of the Commons</a></li>
|
<li><a href="https://valleyofthecommons.com/">Valley of the Commons</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>If you have any questions, reply to this email and we'll get back to you.</p>
|
<p>If you have any questions, just reply to this email — we'd love to hear from you.</p>
|
||||||
|
|
||||||
<p style="margin-top: 32px;">
|
<p style="margin-top: 32px;">
|
||||||
With warmth,<br>
|
With warmth,<br>
|
||||||
|
|
@ -212,7 +209,7 @@ module.exports = async function handler(req, res) {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
|
|
||||||
// Validate required fields
|
// Validate required fields
|
||||||
const required = ['first_name', 'last_name', 'email', 'motivation', 'code_of_conduct_accepted', 'privacy_policy_accepted'];
|
const required = ['first_name', 'last_name', 'email', 'motivation', 'belief_update', 'privacy_policy_accepted'];
|
||||||
for (const field of required) {
|
for (const field of required) {
|
||||||
if (!data[field]) {
|
if (!data[field]) {
|
||||||
return res.status(400).json({ error: `Missing required field: ${field}` });
|
return res.status(400).json({ error: `Missing required field: ${field}` });
|
||||||
|
|
@ -244,6 +241,10 @@ module.exports = async function handler(req, res) {
|
||||||
const governance = Array.isArray(data.governance_interest) ? data.governance_interest : (data.governance_interest ? [data.governance_interest] : null);
|
const governance = Array.isArray(data.governance_interest) ? data.governance_interest : (data.governance_interest ? [data.governance_interest] : null);
|
||||||
const previousEvents = Array.isArray(data.previous_events) ? data.previous_events : (data.previous_events ? [data.previous_events] : null);
|
const previousEvents = Array.isArray(data.previous_events) ? data.previous_events : (data.previous_events ? [data.previous_events] : null);
|
||||||
|
|
||||||
|
// Prepare new array fields
|
||||||
|
const selectedWeeks = Array.isArray(data.weeks) ? data.weeks : (data.weeks ? [data.weeks] : []);
|
||||||
|
const topThemes = Array.isArray(data.top_themes) ? data.top_themes : (data.top_themes ? [data.top_themes] : null);
|
||||||
|
|
||||||
// Insert application
|
// Insert application
|
||||||
const result = await pool.query(
|
const result = await pool.query(
|
||||||
`INSERT INTO applications (
|
`INSERT INTO applications (
|
||||||
|
|
@ -255,11 +256,14 @@ module.exports = async function handler(req, res) {
|
||||||
how_heard, referral_name, previous_events, emergency_name, emergency_phone,
|
how_heard, referral_name, previous_events, emergency_name, emergency_phone,
|
||||||
emergency_relationship, code_of_conduct_accepted, privacy_policy_accepted,
|
emergency_relationship, code_of_conduct_accepted, privacy_policy_accepted,
|
||||||
photo_consent, scholarship_needed, scholarship_reason, contribution_amount,
|
photo_consent, scholarship_needed, scholarship_reason, contribution_amount,
|
||||||
ip_address, user_agent, need_accommodation, want_food, accommodation_type
|
ip_address, user_agent, need_accommodation, want_food, accommodation_type,
|
||||||
|
selected_weeks, top_themes, belief_update, volunteer_interest, coupon_code,
|
||||||
|
food_preference, accessibility_needs
|
||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17,
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17,
|
||||||
$18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32,
|
$18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32,
|
||||||
$33, $34, $35, $36, $37, $38, $39, $40, $41, $42, $43, $44
|
$33, $34, $35, $36, $37, $38, $39, $40, $41, $42, $43, $44,
|
||||||
|
$45, $46, $47, $48, $49, $50, $51
|
||||||
) RETURNING id, submitted_at`,
|
) RETURNING id, submitted_at`,
|
||||||
[
|
[
|
||||||
data.first_name?.trim(),
|
data.first_name?.trim(),
|
||||||
|
|
@ -305,11 +309,17 @@ module.exports = async function handler(req, res) {
|
||||||
req.headers['user-agent'] || null,
|
req.headers['user-agent'] || null,
|
||||||
data.need_accommodation || false,
|
data.need_accommodation || false,
|
||||||
data.want_food || false,
|
data.want_food || false,
|
||||||
data.accommodation_type || null
|
data.accommodation_type || null,
|
||||||
|
selectedWeeks.length > 0 ? selectedWeeks : null,
|
||||||
|
topThemes,
|
||||||
|
data.belief_update?.trim() || null,
|
||||||
|
data.volunteer_interest || false,
|
||||||
|
data.coupon_code?.trim() || null,
|
||||||
|
data.food_preference?.trim() || null,
|
||||||
|
data.accessibility_needs?.trim() || null
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const weeksSelected = Array.isArray(data.weeks) ? data.weeks : [];
|
|
||||||
const application = {
|
const application = {
|
||||||
id: result.rows[0].id,
|
id: result.rows[0].id,
|
||||||
submitted_at: result.rows[0].submitted_at,
|
submitted_at: result.rows[0].submitted_at,
|
||||||
|
|
@ -328,7 +338,7 @@ module.exports = async function handler(req, res) {
|
||||||
referral_name: data.referral_name,
|
referral_name: data.referral_name,
|
||||||
arrival_date: data.arrival_date,
|
arrival_date: data.arrival_date,
|
||||||
departure_date: data.departure_date,
|
departure_date: data.departure_date,
|
||||||
weeks: weeksSelected,
|
weeks: selectedWeeks,
|
||||||
need_accommodation: data.need_accommodation || false,
|
need_accommodation: data.need_accommodation || false,
|
||||||
accommodation_preference: data.accommodation_preference || null,
|
accommodation_preference: data.accommodation_preference || null,
|
||||||
accommodation_type: data.accommodation_type || null,
|
accommodation_type: data.accommodation_type || null,
|
||||||
|
|
@ -342,7 +352,7 @@ module.exports = async function handler(req, res) {
|
||||||
// Add to Listmonk newsletter
|
// Add to Listmonk newsletter
|
||||||
addToListmonk(application.email, `${application.first_name} ${application.last_name}`, {
|
addToListmonk(application.email, `${application.first_name} ${application.last_name}`, {
|
||||||
source: 'application',
|
source: 'application',
|
||||||
weeks: weeksSelected,
|
weeks: selectedWeeks,
|
||||||
contributionAmount: data.contribution_amount,
|
contributionAmount: data.contribution_amount,
|
||||||
}).catch(err => console.error('[Listmonk] Application sync failed:', err.message));
|
}).catch(err => console.error('[Listmonk] Application sync failed:', err.message));
|
||||||
|
|
||||||
|
|
@ -382,17 +392,17 @@ module.exports = async function handler(req, res) {
|
||||||
|
|
||||||
// Create Mollie payment for registration + accommodation fee
|
// Create Mollie payment for registration + accommodation fee
|
||||||
let checkoutUrl = null;
|
let checkoutUrl = null;
|
||||||
if (weeksSelected.length > 0 && process.env.MOLLIE_API_KEY) {
|
if (selectedWeeks.length > 0 && process.env.MOLLIE_API_KEY) {
|
||||||
try {
|
try {
|
||||||
const paymentResult = await createPayment(
|
const paymentResult = await createPayment(
|
||||||
application.id,
|
application.id,
|
||||||
'registration',
|
'registration',
|
||||||
weeksSelected.length,
|
selectedWeeks.length,
|
||||||
application.email,
|
application.email,
|
||||||
application.first_name,
|
application.first_name,
|
||||||
application.last_name,
|
application.last_name,
|
||||||
application.accommodation_type,
|
application.accommodation_type,
|
||||||
weeksSelected
|
selectedWeeks
|
||||||
);
|
);
|
||||||
checkoutUrl = paymentResult.checkoutUrl;
|
checkoutUrl = paymentResult.checkoutUrl;
|
||||||
console.log(`Mollie payment created: ${paymentResult.paymentId} (€${paymentResult.amount})`);
|
console.log(`Mollie payment created: ${paymentResult.paymentId} (€${paymentResult.amount})`);
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ const paymentConfirmationEmail = (application, bookingResult) => {
|
||||||
|
|
||||||
${bookingHtml}
|
${bookingHtml}
|
||||||
|
|
||||||
<p>Your application is now complete. Our team will review it and get back to you within 2-3 weeks.</p>
|
<p>Your application is now complete. Our team will review it and get back to you within 1 week.</p>
|
||||||
|
|
||||||
<p>If you have any questions, reply to this email and we'll get back to you.</p>
|
<p>If you have any questions, reply to this email and we'll get back to you.</p>
|
||||||
|
|
||||||
|
|
|
||||||
1407
apply.html
1407
apply.html
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,11 @@
|
||||||
|
-- Migration 004: Form restructure — add columns for new application flow
|
||||||
|
-- selected_weeks, top_themes, belief_update, volunteer_interest, coupon_code, food_preference, accessibility_needs
|
||||||
|
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD COLUMN IF NOT EXISTS selected_weeks TEXT[],
|
||||||
|
ADD COLUMN IF NOT EXISTS top_themes TEXT[],
|
||||||
|
ADD COLUMN IF NOT EXISTS belief_update TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS volunteer_interest BOOLEAN DEFAULT FALSE,
|
||||||
|
ADD COLUMN IF NOT EXISTS coupon_code TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS food_preference TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS accessibility_needs TEXT;
|
||||||
10
index.html
10
index.html
|
|
@ -51,9 +51,8 @@
|
||||||
<span class="nav-speakers-short">Collaborators</span>
|
<span class="nav-speakers-short">Collaborators</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="#explore">Explore the Valley</a>
|
<a href="#explore">Explore the Valley</a>
|
||||||
<a href="#register" class="nav-get-involved">Register</a>
|
|
||||||
<a href="game.html" target="_blank" rel="noopener noreferrer" class="nav-rabbit">🐰</a>
|
<a href="game.html" target="_blank" rel="noopener noreferrer" class="nav-rabbit">🐰</a>
|
||||||
<a href="/apply.html" class="nav-cta-button">APPLY NOW</a>
|
<a href="/apply.html" class="nav-cta-button">REGISTER NOW</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -78,7 +77,7 @@
|
||||||
<h2 class="event-title">Pop-Up Event to Seed the Valley</h2>
|
<h2 class="event-title">Pop-Up Event to Seed the Valley</h2>
|
||||||
<p class="event-dates">24 August 2026 – 20 September 2026</p>
|
<p class="event-dates">24 August 2026 – 20 September 2026</p>
|
||||||
</div>
|
</div>
|
||||||
<a href="/apply.html" class="cta-button">APPLY NOW</a>
|
<a href="/apply.html" class="cta-button">REGISTER NOW</a>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
|
|
@ -202,9 +201,6 @@
|
||||||
<div id="partners-container" class="partners-container">
|
<div id="partners-container" class="partners-container">
|
||||||
<!-- Partners will be dynamically loaded here -->
|
<!-- Partners will be dynamically loaded here -->
|
||||||
</div>
|
</div>
|
||||||
<p style="text-align: center; margin-top: var(--spacing-md);">
|
|
||||||
<a href="#register" class="explore-link">Register →</a>
|
|
||||||
</p>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Explore the Valley Section -->
|
<!-- Explore the Valley Section -->
|
||||||
|
|
@ -226,7 +222,6 @@
|
||||||
<span>from €120 / 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>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -238,6 +233,7 @@
|
||||||
<input type="email" id="newsletter-email" name="email" placeholder="your@email.com" required aria-label="Email address">
|
<input type="email" id="newsletter-email" name="email" placeholder="your@email.com" required aria-label="Email address">
|
||||||
<button type="submit">Subscribe</button>
|
<button type="submit">Subscribe</button>
|
||||||
</form>
|
</form>
|
||||||
|
<p class="cta-note">You'll be added to our mailing list to stay updated.</p>
|
||||||
<div id="newsletter-message" class="newsletter-message" role="status" aria-live="polite"></div>
|
<div id="newsletter-message" class="newsletter-message" role="status" aria-live="polite"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@
|
||||||
switch (data.paymentStatus) {
|
switch (data.paymentStatus) {
|
||||||
case 'paid':
|
case 'paid':
|
||||||
showStatus('success', 'Payment Confirmed!',
|
showStatus('success', 'Payment Confirmed!',
|
||||||
'Your payment has been received. We\'ll review your application and get back to you within 2-3 weeks.', true);
|
'Your payment has been received. We\'ll review your application and get back to you within 1 week.', true);
|
||||||
break;
|
break;
|
||||||
case 'pending':
|
case 'pending':
|
||||||
case 'open':
|
case 'open':
|
||||||
|
|
|
||||||
12
server.js
12
server.js
|
|
@ -87,6 +87,18 @@ async function runMigrations() {
|
||||||
ADD COLUMN IF NOT EXISTS accommodation_type VARCHAR(50)
|
ADD COLUMN IF NOT EXISTS accommodation_type VARCHAR(50)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Form restructure columns (migration 004)
|
||||||
|
await pool.query(`
|
||||||
|
ALTER TABLE applications
|
||||||
|
ADD COLUMN IF NOT EXISTS selected_weeks TEXT[],
|
||||||
|
ADD COLUMN IF NOT EXISTS top_themes TEXT[],
|
||||||
|
ADD COLUMN IF NOT EXISTS belief_update TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS volunteer_interest BOOLEAN DEFAULT FALSE,
|
||||||
|
ADD COLUMN IF NOT EXISTS coupon_code TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS food_preference TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS accessibility_needs TEXT
|
||||||
|
`);
|
||||||
|
|
||||||
// Rename resend_id → message_id in email_log (legacy column name)
|
// Rename resend_id → message_id in email_log (legacy column name)
|
||||||
const colCheck = await pool.query(`
|
const colCheck = await pool.query(`
|
||||||
SELECT column_name FROM information_schema.columns
|
SELECT column_name FROM information_schema.columns
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
--color-bg: #ffffff;
|
--color-bg: #ffffff;
|
||||||
--color-accent: #000;
|
--color-accent: #000;
|
||||||
--color-link: #000;
|
--color-link: #000;
|
||||||
|
--color-forest: #2d5016;
|
||||||
--font-sans: 'Urbanist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
--font-sans: 'Urbanist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,7 +40,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-container {
|
.header-container {
|
||||||
max-width: 900px;
|
max-width: 1100px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -59,15 +60,15 @@
|
||||||
.header a:hover { text-decoration: underline; }
|
.header a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
max-width: 900px;
|
max-width: 1100px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 4rem 2rem;
|
padding: 3rem 2rem 4rem;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
}
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
.page-header {
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin-bottom: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
|
@ -81,21 +82,177 @@
|
||||||
.subtitle {
|
.subtitle {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
color: var(--color-text-light);
|
color: var(--color-text-light);
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.coming-soon {
|
.intro-text {
|
||||||
font-size: 1.1rem;
|
font-size: 1.05rem;
|
||||||
color: var(--color-text-light);
|
color: var(--color-text-light);
|
||||||
max-width: 500px;
|
max-width: 650px;
|
||||||
margin-bottom: 2rem;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact {
|
/* Tier cards */
|
||||||
font-size: 1rem;
|
.tiers {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 1.25rem;
|
||||||
|
margin-bottom: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact a {
|
.tier-card {
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-card.featured {
|
||||||
|
border-color: var(--color-forest);
|
||||||
|
box-shadow: 0 4px 16px rgba(45, 80, 22, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-header {
|
||||||
|
padding: 1.5rem 1.25rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-card.featured .tier-header {
|
||||||
|
background: var(--color-forest);
|
||||||
|
border-bottom-color: var(--color-forest);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-card.featured .tier-name,
|
||||||
|
.tier-card.featured .tier-price,
|
||||||
|
.tier-card.featured .tier-limit {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-name {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-price {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-text);
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-limit {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--color-text-light);
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-body {
|
||||||
|
padding: 1.25rem;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-perk {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-perk .perk-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--color-forest);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-perk .perk-label {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: var(--color-text-light);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-perk.empty {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-footer {
|
||||||
|
padding: 1.25rem;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-cta {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.6rem 1.5rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
border: 1px solid var(--color-text);
|
||||||
|
color: var(--color-text);
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-cta:hover {
|
||||||
|
background: var(--color-text);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-card.featured .tier-cta {
|
||||||
|
background: var(--color-forest);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--color-forest);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tier-card.featured .tier-cta:hover {
|
||||||
|
background: #3a6b1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footnote */
|
||||||
|
.footnote {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--color-text-light);
|
||||||
|
font-style: italic;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CTA */
|
||||||
|
.cta-section {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2.5rem;
|
||||||
|
background: #f9f9f6;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section p {
|
||||||
|
color: var(--color-text-light);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section a {
|
||||||
color: var(--color-link);
|
color: var(--color-link);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
@ -114,25 +271,202 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer a:hover { text-decoration: underline; }
|
.footer a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.tiers {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 550px) {
|
||||||
|
.tiers {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.content { padding: 2rem 1rem; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<a href="/">Valley of the Commons</a>
|
<a href="/">Valley of the Commons</a>
|
||||||
<a href="/apply.html">Apply Now</a>
|
<a href="/apply.html">Register Now</a>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h1>Sponsorships</h1>
|
<div class="page-header">
|
||||||
<p class="subtitle">Aug 24 – Sep 20, 2026 · Höllental, Austrian Alps</p>
|
<h1>Sponsorship Tiers</h1>
|
||||||
<p class="coming-soon">Details coming soon. We're finalizing sponsorship packages for Valley of the Commons and will share more here shortly.</p>
|
<p class="subtitle">Aug 24 – Sep 20, 2026 · Höllental, Austrian Alps</p>
|
||||||
<p class="contact">Interested? Reach out at <a href="mailto:team@valleyofthecommons.com">team@valleyofthecommons.com</a></p>
|
<p class="intro-text">Support the commons and gain visibility with a community of practitioners, researchers, and builders shaping life beyond extractive systems.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tiers">
|
||||||
|
<!-- Friend of the Commons -->
|
||||||
|
<div class="tier-card">
|
||||||
|
<div class="tier-header">
|
||||||
|
<div class="tier-name">Friend of<br>the Commons</div>
|
||||||
|
<div class="tier-price">€1,000</div>
|
||||||
|
<div class="tier-limit">Unlimited spots</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-body">
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Ticket Voucher</span>€250</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Visibility</span>Name on sponsor list</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Public Gratitude</span>Social media recognition</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Stage Access</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Video Assets</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Branded Handouts</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-footer">
|
||||||
|
<a href="mailto:team@valleyofthecommons.com?subject=Sponsorship%20—%20Friend%20of%20the%20Commons" class="tier-cta">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Symbiont Supporter -->
|
||||||
|
<div class="tier-card">
|
||||||
|
<div class="tier-header">
|
||||||
|
<div class="tier-name">Symbiont<br>Supporter</div>
|
||||||
|
<div class="tier-price">€2,500</div>
|
||||||
|
<div class="tier-limit">10 spots</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-body">
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Ticket Voucher</span>€625</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Visibility</span>Small logo on website</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Public Gratitude</span>Social media recognition</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Stage Access</span>25 min exclusive session (no competing sessions)</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Video Assets</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Branded Handouts</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-footer">
|
||||||
|
<a href="mailto:team@valleyofthecommons.com?subject=Sponsorship%20—%20Symbiont%20Supporter" class="tier-cta">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Spore Partner -->
|
||||||
|
<div class="tier-card featured">
|
||||||
|
<div class="tier-header">
|
||||||
|
<div class="tier-name">Spore<br>Partner</div>
|
||||||
|
<div class="tier-price">€5,000</div>
|
||||||
|
<div class="tier-limit">5 spots</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-body">
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Ticket Voucher</span>€1,250</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Visibility</span>Mid-sized logo on website & signage</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Public Gratitude</span>Social media recognition + naming in opening & closing ceremony</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Stage Access</span>45 min exclusive session</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Video Assets</span>Short clip for your socials</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk empty">
|
||||||
|
<span class="perk-icon">—</span>
|
||||||
|
<div>Branded Handouts</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-footer">
|
||||||
|
<a href="mailto:team@valleyofthecommons.com?subject=Sponsorship%20—%20Spore%20Partner" class="tier-cta">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mycelium Partner -->
|
||||||
|
<div class="tier-card">
|
||||||
|
<div class="tier-header">
|
||||||
|
<div class="tier-name">Mycelium<br>Partner</div>
|
||||||
|
<div class="tier-price">€10,000</div>
|
||||||
|
<div class="tier-limit">3 spots</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-body">
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Ticket Voucher</span>€2,500</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Visibility</span>Central logo on website & signage</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Public Gratitude</span>Social media recognition + naming in opening & closing ceremony</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Stage Access</span>2× 45 min exclusive session</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Video Assets</span>Extended feature</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-perk">
|
||||||
|
<span class="perk-icon">✓</span>
|
||||||
|
<div><span class="perk-label">Branded Handouts</span>Cosmo-local gimmicks* produced in our fablab</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tier-footer">
|
||||||
|
<a href="mailto:team@valleyofthecommons.com?subject=Sponsorship%20—%20Mycelium%20Partner" class="tier-cta">Get in Touch</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="footnote">* Customized to your specific needs</p>
|
||||||
|
|
||||||
|
<div class="cta-section">
|
||||||
|
<h2>Interested in sponsoring?</h2>
|
||||||
|
<p>We'd love to discuss how we can work together. Every tier is customizable.</p>
|
||||||
|
<p><a href="mailto:team@valleyofthecommons.com">team@valleyofthecommons.com</a></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<p>© 2026 Commons Hub · <a href="mailto:team@valleyofthecommons.com">team@valleyofthecommons.com</a> · <a href="/privacy.html">Privacy Policy</a> · <a href="/">Home</a></p>
|
<p>© 2026 Commons Hub · <a href="mailto:team@valleyofthecommons.com">team@valleyofthecommons.com</a> · <a href="/privacy.html">Privacy Policy</a> · <a href="/">Home</a></p>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue