1140 lines
51 KiB
HTML
1140 lines
51 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Apply - Valley of the Commons</title>
|
||
<link rel="icon" type="image/svg+xml" href="icon.svg">
|
||
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;1,400&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--forest: #2d5016;
|
||
--forest-light: #4a7c23;
|
||
--cream: #faf8f5;
|
||
--sand: #f5f5f0;
|
||
--charcoal: #2c2c2c;
|
||
--error: #c53030;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
body {
|
||
font-family: 'Inter', -apple-system, sans-serif;
|
||
background: var(--cream);
|
||
color: var(--charcoal);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.header {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(10px);
|
||
border-bottom: 1px solid rgba(0,0,0,0.1);
|
||
padding: 1rem 2rem;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.header-content {
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.header h1 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.5rem;
|
||
font-weight: 400;
|
||
color: var(--forest);
|
||
}
|
||
|
||
.header a { color: var(--forest); text-decoration: none; }
|
||
|
||
.container {
|
||
max-width: 700px;
|
||
margin: 0 auto;
|
||
padding: 2rem;
|
||
}
|
||
|
||
.intro {
|
||
text-align: center;
|
||
margin-bottom: 2rem;
|
||
padding: 2rem;
|
||
background: white;
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.intro h1 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 2.25rem;
|
||
color: var(--forest);
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.intro p { color: #666; font-size: 0.95rem; }
|
||
|
||
.event-badge {
|
||
display: inline-block;
|
||
background: var(--forest);
|
||
color: white;
|
||
padding: 0.5rem 1rem;
|
||
border-radius: 20px;
|
||
font-size: 0.875rem;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
/* Progress */
|
||
.progress-container {
|
||
margin-bottom: 2rem;
|
||
}
|
||
|
||
.progress-bar {
|
||
height: 4px;
|
||
background: #ddd;
|
||
border-radius: 2px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.progress-fill {
|
||
height: 100%;
|
||
background: var(--forest);
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.progress-text {
|
||
text-align: center;
|
||
font-size: 0.8rem;
|
||
color: #666;
|
||
margin-top: 0.5rem;
|
||
}
|
||
|
||
/* Form */
|
||
.form-section {
|
||
background: white;
|
||
border-radius: 12px;
|
||
padding: 2rem;
|
||
margin-bottom: 1rem;
|
||
display: none;
|
||
}
|
||
|
||
.form-section.active { display: block; animation: fadeIn 0.3s; }
|
||
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; transform: translateY(10px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.question-number {
|
||
font-size: 0.75rem;
|
||
color: #999;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
.form-section h2 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.5rem;
|
||
color: var(--forest);
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
.form-section > p.hint {
|
||
color: #666;
|
||
font-size: 0.9rem;
|
||
margin-bottom: 1.5rem;
|
||
}
|
||
|
||
.form-group { margin-bottom: 1.25rem; }
|
||
|
||
label {
|
||
display: block;
|
||
font-weight: 500;
|
||
margin-bottom: 0.5rem;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
label .required { color: var(--error); }
|
||
label .optional { color: #999; font-weight: 400; font-size: 0.8rem; }
|
||
|
||
input[type="text"],
|
||
input[type="email"],
|
||
textarea,
|
||
select {
|
||
width: 100%;
|
||
padding: 0.75rem 1rem;
|
||
border: 1px solid #ddd;
|
||
border-radius: 8px;
|
||
font-family: inherit;
|
||
font-size: 1rem;
|
||
}
|
||
|
||
input:focus, textarea:focus, select:focus {
|
||
outline: none;
|
||
border-color: var(--forest);
|
||
box-shadow: 0 0 0 3px rgba(45, 80, 22, 0.1);
|
||
}
|
||
|
||
textarea { min-height: 120px; resize: vertical; }
|
||
|
||
.field-hint {
|
||
font-size: 0.8rem;
|
||
color: #666;
|
||
margin-top: 0.25rem;
|
||
}
|
||
|
||
/* Theme ranking */
|
||
.theme-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.theme-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 1rem;
|
||
padding: 0.75rem 1rem;
|
||
background: var(--sand);
|
||
border-radius: 8px;
|
||
cursor: grab;
|
||
user-select: none;
|
||
}
|
||
|
||
.theme-item:active { cursor: grabbing; }
|
||
|
||
.theme-item .emoji { font-size: 1.25rem; }
|
||
.theme-item .text { flex: 1; font-size: 0.9rem; }
|
||
|
||
.theme-item .rank {
|
||
width: 24px;
|
||
height: 24px;
|
||
background: var(--forest);
|
||
color: white;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 0.75rem;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* Week cards */
|
||
.week-cards { display: flex; flex-direction: column; gap: 0.75rem; }
|
||
|
||
.week-card {
|
||
border: 2px solid #ddd;
|
||
border-radius: 10px;
|
||
padding: 1rem;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.week-card:hover { border-color: var(--forest-light); }
|
||
.week-card.selected { border-color: var(--forest); background: rgba(45, 80, 22, 0.05); }
|
||
.week-card input { display: none; }
|
||
|
||
.week-card h4 { font-size: 0.95rem; color: var(--forest); margin-bottom: 0.25rem; }
|
||
.week-card .dates { font-size: 0.8rem; color: #666; margin-bottom: 0.5rem; }
|
||
.week-card .desc { font-size: 0.85rem; color: #555; }
|
||
|
||
/* Select-all card */
|
||
.select-all-card {
|
||
border-style: dashed;
|
||
background: var(--sand);
|
||
}
|
||
.select-all-card.selected {
|
||
border-style: solid;
|
||
}
|
||
|
||
.ticket-note {
|
||
font-size: 0.8rem;
|
||
color: #666;
|
||
background: var(--sand);
|
||
padding: 0.75rem 1rem;
|
||
border-radius: 8px;
|
||
margin-top: 1rem;
|
||
}
|
||
|
||
/* Nav */
|
||
.form-nav {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 1rem;
|
||
margin-top: 2rem;
|
||
}
|
||
|
||
.btn {
|
||
padding: 0.875rem 2rem;
|
||
border: none;
|
||
border-radius: 8px;
|
||
font-family: inherit;
|
||
font-size: 1rem;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.btn-primary { background: var(--forest); color: white; }
|
||
.btn-primary:hover { background: var(--forest-light); }
|
||
.btn-secondary { background: var(--sand); color: var(--charcoal); }
|
||
.btn-secondary:hover { background: #eee; }
|
||
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||
|
||
/* Success */
|
||
.success-message { text-align: center; padding: 2rem; }
|
||
|
||
.success-icon {
|
||
width: 70px;
|
||
height: 70px;
|
||
background: var(--forest);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin: 0 auto 1.5rem;
|
||
}
|
||
|
||
.success-icon svg { width: 35px; height: 35px; stroke: white; }
|
||
|
||
.success-message h2 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.75rem;
|
||
color: var(--forest);
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
/* Error */
|
||
.error-message {
|
||
background: #fef2f2;
|
||
border: 1px solid #fecaca;
|
||
color: var(--error);
|
||
padding: 1rem;
|
||
border-radius: 8px;
|
||
margin-bottom: 1rem;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.field-error { border-color: var(--error) !important; }
|
||
|
||
.footer {
|
||
text-align: center;
|
||
padding: 2rem;
|
||
color: #666;
|
||
font-size: 0.875rem;
|
||
}
|
||
|
||
.footer a { color: var(--forest); }
|
||
|
||
@media (max-width: 600px) {
|
||
.container { padding: 1rem; }
|
||
.form-section { padding: 1.5rem; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header class="header">
|
||
<div class="header-content">
|
||
<h1><a href="/">Valley of the Commons</a></h1>
|
||
<a href="/">← Back</a>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="container">
|
||
<div class="intro">
|
||
<span class="event-badge">August 24 – September 20, 2026</span>
|
||
<h1>Application Form</h1>
|
||
<p>Valley of the Commons is a four-week pop-up village exploring housing, production, decision-making and ownership in community. We ask that you be thoughtful in your answers to help us understand if you are the right fit. We will not penalize you for unfamiliarity with any topic; please be honest.</p>
|
||
</div>
|
||
|
||
<div class="progress-container">
|
||
<div class="progress-bar"><div class="progress-fill" id="progress-fill"></div></div>
|
||
<div class="progress-text"><span id="progress-percent">0</span>% complete</div>
|
||
</div>
|
||
|
||
<form id="application-form">
|
||
<!-- Q1: Contact Information -->
|
||
<div class="form-section active" data-step="1">
|
||
<div class="question-number">Question 1 of 12</div>
|
||
<h2>Contact Information</h2>
|
||
|
||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
|
||
<div>
|
||
<label for="first_name">First Name <span class="required">*</span></label>
|
||
<input type="text" id="first_name" name="first_name" required placeholder="First name">
|
||
</div>
|
||
<div>
|
||
<label for="last_name">Last Name <span class="required">*</span></label>
|
||
<input type="text" id="last_name" name="last_name" required placeholder="Last name">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="email">Email <span class="required">*</span></label>
|
||
<input type="email" id="email" name="email" required placeholder="your@email.com">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="social_media">Social Media Handles <span class="optional">(optional)</span></label>
|
||
<input type="text" id="social_media" name="social_media" placeholder="@handle (please specify which platforms)">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="contact_other">Anything else? <span class="optional">(optional)</span></label>
|
||
<textarea id="contact_other" name="contact_other" rows="2" placeholder="Phone, website, etc."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<div></div>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q2: How did you hear -->
|
||
<div class="form-section" data-step="2">
|
||
<div class="question-number">Question 2 of 12</div>
|
||
<h2>How did you hear about Valley of the Commons? <span class="required">*</span></h2>
|
||
|
||
<div class="form-group">
|
||
<textarea id="how_heard" name="how_heard" required placeholder="Social media, friend referral, newsletter, event..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q3: Referral names -->
|
||
<div class="form-section" data-step="3">
|
||
<div class="question-number">Question 3 of 12</div>
|
||
<h2>Referral name(s) <span class="optional">(optional)</span></h2>
|
||
<p class="hint">Who can vouch for you?</p>
|
||
|
||
<div class="form-group">
|
||
<textarea id="referral_names" name="referral_names" placeholder="Names of people who know you or referred you"></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q4: Affiliations -->
|
||
<div class="form-section" data-step="4">
|
||
<div class="question-number">Question 4 of 12</div>
|
||
<h2>What are your affiliations? <span class="required">*</span></h2>
|
||
<p class="hint">What projects or groups are you affiliated with?</p>
|
||
|
||
<div class="form-group">
|
||
<textarea id="affiliations" name="affiliations" required placeholder="Organizations, DAOs, cooperatives, communities, projects..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q5: Why join -->
|
||
<div class="form-section" data-step="5">
|
||
<div class="question-number">Question 5 of 12</div>
|
||
<h2>Why would you like to join Valley of the Commons, and why are you a good fit? <span class="required">*</span></h2>
|
||
|
||
<div class="form-group">
|
||
<textarea id="why_join" name="why_join" required placeholder="What draws you to this gathering? Why are you a good fit for this community?"></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q6: Current work -->
|
||
<div class="form-section" data-step="6">
|
||
<div class="question-number">Question 6 of 12</div>
|
||
<h2>What are you currently building, researching, or working on? <span class="required">*</span></h2>
|
||
|
||
<div class="form-group">
|
||
<textarea id="current_work" name="current_work" required placeholder="Tell us about your current projects, research, or focus areas..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q7: How contribute -->
|
||
<div class="form-section" data-step="7">
|
||
<div class="question-number">Question 7 of 12</div>
|
||
<h2>How will you contribute to Valley of the Commons? <span class="required">*</span></h2>
|
||
<p class="hint">Villagers co-create their experience. You can start an interest club, lead a discussion or workshop, teach a cooking class, or more.</p>
|
||
|
||
<div class="form-group">
|
||
<textarea id="contribution" name="contribution" required placeholder="What skills, energy, workshops, or perspectives will you bring?"></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q8: Rank themes -->
|
||
<div class="form-section" data-step="8">
|
||
<div class="question-number">Question 8 of 12</div>
|
||
<h2>Please rank your interest in our themes <span class="required">*</span></h2>
|
||
<p class="hint">Drag to reorder from most interested (top) to least interested (bottom).</p>
|
||
|
||
<div class="theme-list" id="theme-list">
|
||
<div class="theme-item" data-theme="valley-future">
|
||
<span class="rank">1</span>
|
||
<span class="emoji">🏞️</span>
|
||
<span class="text">Developing the Future of the Valley</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="cosmo-localism">
|
||
<span class="rank">2</span>
|
||
<span class="emoji">🌐</span>
|
||
<span class="text">Cosmo-localism</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="funding-token">
|
||
<span class="rank">3</span>
|
||
<span class="emoji">🪙</span>
|
||
<span class="text">Funding Models & Token Engineering</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="fablabs">
|
||
<span class="rank">4</span>
|
||
<span class="emoji">👾</span>
|
||
<span class="text">Fablabs & Hackerspaces</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="future-living">
|
||
<span class="rank">5</span>
|
||
<span class="emoji">🌌</span>
|
||
<span class="text">Future Living Design & Development</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="network-governance">
|
||
<span class="rank">6</span>
|
||
<span class="emoji">🧑⚖️</span>
|
||
<span class="text">Network Societies & Decentralized Governance</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="commons-theory">
|
||
<span class="rank">7</span>
|
||
<span class="emoji">⛲️</span>
|
||
<span class="text">Commons Theory & Practice</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="privacy">
|
||
<span class="rank">8</span>
|
||
<span class="emoji">👤</span>
|
||
<span class="text">Privacy & Digital Sovereignty</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="dacc">
|
||
<span class="rank">9</span>
|
||
<span class="emoji">🌏</span>
|
||
<span class="text">d/acc: defensive accelerationism</span>
|
||
</div>
|
||
<div class="theme-item" data-theme="rationality">
|
||
<span class="rank">10</span>
|
||
<span class="emoji">💭</span>
|
||
<span class="text">(Meta)rationality & Cognitive Sovereignty</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q9: Theme familiarity -->
|
||
<div class="form-section" data-step="9">
|
||
<div class="question-number">Question 9 of 12</div>
|
||
<h2>Please explain your familiarity and interest in our themes and event overall <span class="required">*</span></h2>
|
||
<p class="hint">🏞️ Valley Future · 🌐 Cosmo-localism · 🪙 Funding & Token Engineering · 👾 Fablabs · 🌌 Future Living · 🧑⚖️ Network Governance · ⛲️ Commons · 👤 Privacy · 🌏 d/acc · 💭 (Meta)rationality</p>
|
||
|
||
<div class="form-group">
|
||
<textarea id="theme_familiarity" name="theme_familiarity" required placeholder="Share your experience, learning journey, or curiosity about any of these themes..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q10: Belief update -->
|
||
<div class="form-section" data-step="10">
|
||
<div class="question-number">Question 10 of 12</div>
|
||
<h2>Describe a belief you have updated within the last 1-2 years <span class="required">*</span></h2>
|
||
<p class="hint">What was the belief and why did it change?</p>
|
||
|
||
<div class="form-group">
|
||
<textarea id="belief_update" name="belief_update" required placeholder="We value intellectual humility. Share how your thinking has evolved..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q11: Weeks & Options -->
|
||
<div class="form-section" data-step="11">
|
||
<div class="question-number">Question 11 of 12</div>
|
||
<h2>Which week(s) would you like to attend? <span class="required">*</span></h2>
|
||
<p class="hint">Select the weeks you'd like to join. Base registration is €300 per week.</p>
|
||
|
||
<div class="week-cards">
|
||
<label class="week-card select-all-card" onclick="toggleAllWeeks(this)">
|
||
<input type="checkbox" id="select-all-weeks">
|
||
<h4>Select all 4 weeks</h4>
|
||
<div class="desc">Full residency: August 24 – September 20, 2026</div>
|
||
</label>
|
||
|
||
<label class="week-card" onclick="toggleWeek(this)">
|
||
<input type="checkbox" name="weeks" value="week1">
|
||
<h4>Week 1: Return to the Commons</h4>
|
||
<div class="dates">August 24 – 30, 2026</div>
|
||
<div class="desc">A five-day course with Michel Bauwens and Adam Arvidsson exploring the history and future of the commons.</div>
|
||
</label>
|
||
|
||
<label class="week-card" onclick="toggleWeek(this)">
|
||
<input type="checkbox" name="weeks" value="week2">
|
||
<h4>Week 2: Post-Capitalist Production</h4>
|
||
<div class="dates">August 31 – September 6, 2026</div>
|
||
<div class="desc">How global knowledge commons and local production can sustain livelihoods and community resilience.</div>
|
||
</label>
|
||
|
||
<label class="week-card" onclick="toggleWeek(this)">
|
||
<input type="checkbox" name="weeks" value="week3">
|
||
<h4>Week 3: Future Living</h4>
|
||
<div class="dates">September 7 – 13, 2026</div>
|
||
<div class="desc">From vision to scouting: cooperative housing, mapping local resources, ecological design.</div>
|
||
</label>
|
||
|
||
<label class="week-card" onclick="toggleWeek(this)">
|
||
<input type="checkbox" name="weeks" value="week4">
|
||
<h4>Week 4: Governance & Funding Models</h4>
|
||
<div class="dates">September 14 – 20, 2026</div>
|
||
<div class="desc">Participatory governance, cooperative legal structures, and mechanisms for shared assets.</div>
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Accommodation -->
|
||
<div style="margin-top: 2rem;">
|
||
<h3 style="font-family: 'Cormorant Garamond', serif; font-size: 1.25rem; color: var(--forest); margin-bottom: 1rem;">Accommodation</h3>
|
||
|
||
<label class="week-card" onclick="toggleAddon(this, 'accommodation')" style="margin-bottom: 0.75rem;">
|
||
<input type="checkbox" id="need_accommodation">
|
||
<h4>Include accommodation with registration</h4>
|
||
<div class="desc">On-site housing paid upfront with your registration fee.</div>
|
||
</label>
|
||
|
||
<div id="accommodation-options" style="display: none;">
|
||
<!-- Venue selection -->
|
||
<div style="padding: 0.75rem 0; margin-bottom: 0.5rem;">
|
||
<label style="font-weight: 600; margin-bottom: 0.75rem; display: block;">Choose your venue</label>
|
||
|
||
<label class="week-card" style="margin-bottom: 0.5rem; cursor: pointer;" onclick="selectVenue('ch')">
|
||
<input type="radio" name="venue" value="ch" style="display:none;">
|
||
<h4>Commons Hub</h4>
|
||
<div class="desc">Shared community living in the main hub building.</div>
|
||
</label>
|
||
|
||
<label class="week-card" style="cursor: pointer;" onclick="selectVenue('hh')">
|
||
<input type="radio" name="venue" value="hh" style="display:none;">
|
||
<h4>Herrnhof Villa</h4>
|
||
<div class="desc">Private villa rooms with more comfort and privacy.</div>
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Commons Hub room types -->
|
||
<div id="ch-rooms" style="display: none; padding: 0.75rem 0;">
|
||
<label style="font-weight: 600; margin-bottom: 0.75rem; display: block;">Room type — Commons Hub</label>
|
||
|
||
<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;">
|
||
<h4>Bed in Multi-Room <span style="float:right; color: var(--forest); font-weight: 600;">€475/wk</span></h4>
|
||
<div class="desc">Bed in a shared multi-bed room. The most affordable option.</div>
|
||
</label>
|
||
|
||
<label class="week-card" style="cursor: pointer;" onclick="selectRoom('ch-double')">
|
||
<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>
|
||
<div class="desc">Shared with one other person.</div>
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Herrnhof room types -->
|
||
<div id="hh-rooms" style="display: none; padding: 0.75rem 0;">
|
||
<label style="font-weight: 600; margin-bottom: 0.75rem; display: block;">Room type — Herrnhof Villa</label>
|
||
|
||
<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;">
|
||
<h4>Bed in Living Room <span style="float:right; color: var(--forest); font-weight: 600;">€515/wk</span></h4>
|
||
<div class="desc">Shared living space with flexible sleeping arrangement.</div>
|
||
</label>
|
||
|
||
<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;">
|
||
<h4>Bed in Triple Room <span style="float:right; color: var(--forest); font-weight: 600;">€550/wk</span></h4>
|
||
<div class="desc">Room shared between three people.</div>
|
||
</label>
|
||
|
||
<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;">
|
||
<h4>Bed in Twin Room <span style="float:right; color: var(--forest); font-weight: 600;">€620/wk</span></h4>
|
||
<div class="desc">Room shared with one other person, separate beds.</div>
|
||
</label>
|
||
|
||
<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;">
|
||
<h4>Single Room <span style="float:right; color: var(--forest); font-weight: 600;">€865/wk</span></h4>
|
||
<div class="desc">Private room for one person.</div>
|
||
</label>
|
||
|
||
<label class="week-card" style="cursor: pointer;" onclick="selectRoom('hh-couple')">
|
||
<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>
|
||
<div class="desc">Private room with double bed for couples.</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<input type="hidden" id="accommodation_type" name="accommodation_type" value="">
|
||
|
||
<!-- Food add-on -->
|
||
<h3 style="font-family: 'Cormorant Garamond', serif; font-size: 1.25rem; color: var(--forest); margin-bottom: 1rem; margin-top: 2rem;">Food</h3>
|
||
|
||
<label class="week-card" onclick="toggleAddon(this, 'food')">
|
||
<input type="checkbox" id="want_food">
|
||
<h4>I would like to include food for the week</h4>
|
||
<div class="desc">We are exploring co-producing our own meals as a community. More details and costs will be shared soon — checking this box registers your interest so we can plan accordingly.</div>
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Price summary -->
|
||
<div id="price-summary" class="ticket-note" style="margin-top: 1.5rem;">
|
||
<div id="price-calc">Select at least one week</div>
|
||
</div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="button" class="btn btn-primary" onclick="nextStep()">Continue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Q12: Anything else -->
|
||
<div class="form-section" data-step="12">
|
||
<div class="question-number">Question 12 of 12</div>
|
||
<h2>Anything else you'd like to add? <span class="optional">(optional)</span></h2>
|
||
|
||
<div class="form-group">
|
||
<textarea id="anything_else" name="anything_else" placeholder="Questions, accessibility needs, dietary requirements, or anything else..."></textarea>
|
||
</div>
|
||
|
||
<div class="form-group" style="margin-top: 2rem;">
|
||
<label style="display: flex; align-items: flex-start; gap: 0.5rem; cursor: pointer;">
|
||
<input type="checkbox" id="privacy_accepted" name="privacy_accepted" required style="width: 18px; height: 18px; margin-top: 0.2rem;">
|
||
<span>I agree to the <a href="privacy.html" target="_blank">privacy policy</a> and consent to my data being processed for this application <span class="required">*</span></span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="form-error" class="error-message" style="display: none;"></div>
|
||
|
||
<div class="form-nav">
|
||
<button type="button" class="btn btn-secondary" onclick="prevStep()">Back</button>
|
||
<button type="submit" class="btn btn-primary" id="submit-btn">Submit Application</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Success -->
|
||
<div class="form-section" data-step="success" style="display: none;">
|
||
<div class="success-message">
|
||
<div class="success-icon">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path d="M20 6L9 17l-5-5"/>
|
||
</svg>
|
||
</div>
|
||
<h2>Application Submitted!</h2>
|
||
<p>Thank you for applying to Valley of the Commons.</p>
|
||
<p>We've sent a confirmation to <strong id="confirm-email"></strong>.</p>
|
||
<p style="margin-top: 1.5rem; color: #666;">Our team will review your application and get back to you within 2-3 weeks.</p>
|
||
<p style="margin-top: 2rem;">
|
||
<a href="/" class="btn btn-primary">Return to Homepage</a>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<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="/sponsorships.html">Sponsorships</a></p>
|
||
</footer>
|
||
|
||
<script>
|
||
let currentStep = 1;
|
||
const totalSteps = 12;
|
||
const PRICE_PER_WEEK = 300;
|
||
const PROCESSING_FEE_PERCENT = 0.02;
|
||
|
||
// Current pricing tier (must match api/mollie.js)
|
||
const CURRENT_PRICING_TIER = 'standard';
|
||
|
||
// Accommodation prices — tiered by duration and booking window (must match api/mollie.js)
|
||
const ACCOMMODATION_PRICES = {
|
||
'ch-multi': { '1week': { early: 395, standard: 475, lastMin: 515 }, '4week': { early: 1400, standard: 1600, lastMin: 1700 } },
|
||
'ch-double': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } },
|
||
'hh-living': { '1week': { early: 435, standard: 515, lastMin: 555 }, '4week': { early: 1560, standard: 1760, lastMin: 1860 } },
|
||
'hh-triple': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } },
|
||
'hh-twin': { '1week': { early: 540, standard: 620, lastMin: 660 }, '4week': { early: 1980, standard: 2180, lastMin: 2280 } },
|
||
'hh-single': { '1week': { early: 785, standard: 865, lastMin: 905 }, '4week': { early: 2960, standard: 3160, lastMin: 3260 } },
|
||
'hh-couple': { '1week': { early: 940, standard: 1100, lastMin: 1180 }, '4week': { early: 3400, standard: 3800, lastMin: 4000 } },
|
||
};
|
||
|
||
const ACCOMMODATION_LABELS = {
|
||
'ch-multi': 'Commons Hub — Bed in Multi-Room',
|
||
'ch-double': 'Commons Hub — Bed in Double Room',
|
||
'hh-living': 'Herrnhof Villa — Bed in Living Room',
|
||
'hh-triple': 'Herrnhof Villa — Bed in Triple Room',
|
||
'hh-twin': 'Herrnhof Villa — Bed in Twin Room',
|
||
'hh-single': 'Herrnhof Villa — Single Room',
|
||
'hh-couple': 'Herrnhof Villa — Couple Room',
|
||
};
|
||
|
||
function getAccommodationPrice(accomType, weeksCount) {
|
||
if (!accomType || !ACCOMMODATION_PRICES[accomType]) return 0;
|
||
const prices = ACCOMMODATION_PRICES[accomType];
|
||
const tier = CURRENT_PRICING_TIER;
|
||
if (weeksCount === 4) return prices['4week'][tier];
|
||
return prices['1week'][tier] * weeksCount;
|
||
}
|
||
|
||
function updateProgress() {
|
||
const percent = Math.round(((currentStep - 1) / totalSteps) * 100);
|
||
document.getElementById('progress-fill').style.width = percent + '%';
|
||
document.getElementById('progress-percent').textContent = percent;
|
||
}
|
||
|
||
function showStep(step) {
|
||
document.querySelectorAll('.form-section').forEach(s => s.classList.remove('active'));
|
||
const target = document.querySelector(`.form-section[data-step="${step}"]`);
|
||
if (target) {
|
||
target.classList.add('active');
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}
|
||
updateProgress();
|
||
}
|
||
|
||
function validateStep(step) {
|
||
const section = document.querySelector(`.form-section[data-step="${step}"]`);
|
||
const required = section.querySelectorAll('[required]');
|
||
let valid = true;
|
||
|
||
required.forEach(field => {
|
||
field.style.borderColor = '';
|
||
if (field.type === 'checkbox') {
|
||
if (!field.checked) valid = false;
|
||
} else if (!field.value.trim()) {
|
||
valid = false;
|
||
field.style.borderColor = 'var(--error)';
|
||
}
|
||
});
|
||
|
||
// Email validation
|
||
const emailField = section.querySelector('input[type="email"]');
|
||
if (emailField && emailField.value && !emailField.value.includes('@')) {
|
||
valid = false;
|
||
emailField.style.borderColor = 'var(--error)';
|
||
}
|
||
|
||
// Week selection (step 11)
|
||
if (step === 11) {
|
||
const checked = document.querySelectorAll('input[name="weeks"]:checked');
|
||
if (checked.length === 0) {
|
||
valid = false;
|
||
alert('Please select at least one week.');
|
||
}
|
||
}
|
||
|
||
return valid;
|
||
}
|
||
|
||
function nextStep() {
|
||
if (!validateStep(currentStep)) return;
|
||
if (currentStep < totalSteps) {
|
||
currentStep++;
|
||
showStep(currentStep);
|
||
}
|
||
}
|
||
|
||
function prevStep() {
|
||
if (currentStep > 1) {
|
||
currentStep--;
|
||
showStep(currentStep);
|
||
}
|
||
}
|
||
|
||
function toggleWeek(card) {
|
||
const cb = card.querySelector('input');
|
||
cb.checked = !cb.checked;
|
||
card.classList.toggle('selected', cb.checked);
|
||
syncSelectAll();
|
||
updatePriceSummary();
|
||
}
|
||
|
||
function toggleAllWeeks(card) {
|
||
const selectAllCb = card.querySelector('input');
|
||
selectAllCb.checked = !selectAllCb.checked;
|
||
card.classList.toggle('selected', selectAllCb.checked);
|
||
|
||
const weekCbs = document.querySelectorAll('input[name="weeks"]');
|
||
weekCbs.forEach(cb => {
|
||
cb.checked = selectAllCb.checked;
|
||
cb.closest('.week-card').classList.toggle('selected', selectAllCb.checked);
|
||
});
|
||
updatePriceSummary();
|
||
}
|
||
|
||
function syncSelectAll() {
|
||
const weekCbs = document.querySelectorAll('input[name="weeks"]');
|
||
const allChecked = Array.from(weekCbs).every(cb => cb.checked);
|
||
const selectAllCb = document.getElementById('select-all-weeks');
|
||
const selectAllCard = selectAllCb.closest('.week-card');
|
||
selectAllCb.checked = allChecked;
|
||
selectAllCard.classList.toggle('selected', allChecked);
|
||
}
|
||
|
||
function toggleAddon(card, type) {
|
||
const cb = card.querySelector('input');
|
||
cb.checked = !cb.checked;
|
||
card.classList.toggle('selected', cb.checked);
|
||
|
||
if (type === 'accommodation') {
|
||
const opts = document.getElementById('accommodation-options');
|
||
opts.style.display = cb.checked ? 'block' : 'none';
|
||
if (!cb.checked) {
|
||
// Clear accommodation selection
|
||
document.getElementById('accommodation_type').value = '';
|
||
document.querySelectorAll('input[name="venue"]').forEach(r => { r.checked = false; r.closest('.week-card').classList.remove('selected'); });
|
||
document.querySelectorAll('input[name="room_type"]').forEach(r => { r.checked = false; r.closest('.week-card').classList.remove('selected'); });
|
||
document.getElementById('ch-rooms').style.display = 'none';
|
||
document.getElementById('hh-rooms').style.display = 'none';
|
||
}
|
||
}
|
||
|
||
// Always refresh summary (food toggle also affects it)
|
||
updatePriceSummary();
|
||
}
|
||
|
||
function selectVenue(venue) {
|
||
// Update radio + card styling
|
||
document.querySelectorAll('input[name="venue"]').forEach(r => {
|
||
r.checked = (r.value === venue);
|
||
r.closest('.week-card').classList.toggle('selected', r.checked);
|
||
});
|
||
|
||
// Show/hide room type sections
|
||
document.getElementById('ch-rooms').style.display = venue === 'ch' ? 'block' : 'none';
|
||
document.getElementById('hh-rooms').style.display = venue === 'hh' ? 'block' : 'none';
|
||
|
||
// Clear previous room selection
|
||
document.querySelectorAll('input[name="room_type"]').forEach(r => {
|
||
r.checked = false;
|
||
r.closest('.week-card').classList.remove('selected');
|
||
});
|
||
document.getElementById('accommodation_type').value = '';
|
||
updatePriceSummary();
|
||
}
|
||
|
||
function selectRoom(roomType) {
|
||
document.querySelectorAll('input[name="room_type"]').forEach(r => {
|
||
r.checked = (r.value === roomType);
|
||
r.closest('.week-card').classList.toggle('selected', r.checked);
|
||
});
|
||
document.getElementById('accommodation_type').value = roomType;
|
||
updatePriceSummary();
|
||
}
|
||
|
||
function updatePriceSummary() {
|
||
const weeksCount = document.querySelectorAll('input[name="weeks"]:checked').length;
|
||
const el = document.getElementById('price-calc');
|
||
|
||
if (weeksCount === 0) {
|
||
el.textContent = 'Select at least one week';
|
||
return;
|
||
}
|
||
|
||
const registration = PRICE_PER_WEEK * weeksCount;
|
||
const accomType = document.getElementById('accommodation_type').value;
|
||
const accommodation = getAccommodationPrice(accomType, weeksCount);
|
||
const subtotal = registration + accommodation;
|
||
const fee = subtotal * PROCESSING_FEE_PERCENT;
|
||
const total = subtotal + fee;
|
||
|
||
const tierLabel = { early: 'Early Bird', standard: 'Standard', lastMin: 'Last Minute' }[CURRENT_PRICING_TIER];
|
||
let html = `<strong>Registration:</strong> €${PRICE_PER_WEEK} × ${weeksCount} wk = €${registration.toFixed(2)}`;
|
||
|
||
if (accommodation > 0) {
|
||
const label = ACCOMMODATION_LABELS[accomType] || accomType;
|
||
if (weeksCount === 4) {
|
||
html += `<br><strong>Accommodation:</strong> ${label}<br> 4-week ${tierLabel} rate = €${accommodation.toFixed(2)}`;
|
||
} else {
|
||
const perWeek = ACCOMMODATION_PRICES[accomType]['1week'][CURRENT_PRICING_TIER];
|
||
html += `<br><strong>Accommodation:</strong> ${label}<br> €${perWeek.toFixed(2)} × ${weeksCount} wk (${tierLabel}) = €${accommodation.toFixed(2)}`;
|
||
}
|
||
}
|
||
|
||
html += `<br><strong>Processing fee (2%):</strong> €${fee.toFixed(2)}`;
|
||
html += `<br><strong style="font-size: 1.1em;">Total: €${total.toFixed(2)}</strong>`;
|
||
|
||
const wantFood = document.getElementById('want_food').checked;
|
||
if (wantFood) {
|
||
html += `<br><span style="font-size: 0.8rem; color: var(--forest);">Food: interest registered — details & costs coming soon.</span>`;
|
||
}
|
||
|
||
el.innerHTML = html;
|
||
}
|
||
|
||
// Theme ranking drag & drop
|
||
const themeList = document.getElementById('theme-list');
|
||
let draggedItem = null;
|
||
|
||
themeList.addEventListener('dragstart', e => {
|
||
draggedItem = e.target.closest('.theme-item');
|
||
e.dataTransfer.effectAllowed = 'move';
|
||
});
|
||
|
||
themeList.addEventListener('dragover', e => {
|
||
e.preventDefault();
|
||
const target = e.target.closest('.theme-item');
|
||
if (target && target !== draggedItem) {
|
||
const rect = target.getBoundingClientRect();
|
||
const mid = rect.top + rect.height / 2;
|
||
if (e.clientY < mid) {
|
||
themeList.insertBefore(draggedItem, target);
|
||
} else {
|
||
themeList.insertBefore(draggedItem, target.nextSibling);
|
||
}
|
||
}
|
||
});
|
||
|
||
themeList.addEventListener('dragend', () => {
|
||
updateRanks();
|
||
draggedItem = null;
|
||
});
|
||
|
||
// Make items draggable
|
||
document.querySelectorAll('.theme-item').forEach(item => {
|
||
item.draggable = true;
|
||
});
|
||
|
||
function updateRanks() {
|
||
document.querySelectorAll('.theme-item').forEach((item, i) => {
|
||
item.querySelector('.rank').textContent = i + 1;
|
||
});
|
||
}
|
||
|
||
function getThemeRanking() {
|
||
return Array.from(document.querySelectorAll('.theme-item')).map((item, i) => ({
|
||
theme: item.dataset.theme,
|
||
rank: i + 1
|
||
}));
|
||
}
|
||
|
||
function getSelectedWeeks() {
|
||
return Array.from(document.querySelectorAll('input[name="weeks"]:checked')).map(cb => cb.value);
|
||
}
|
||
|
||
function collectFormData() {
|
||
const form = document.getElementById('application-form');
|
||
const weeks = getSelectedWeeks();
|
||
|
||
return {
|
||
first_name: form.first_name.value.trim(),
|
||
last_name: form.last_name.value.trim(),
|
||
email: form.email.value,
|
||
social_links: form.social_media.value,
|
||
contact_other: form.contact_other.value,
|
||
how_heard: form.how_heard.value,
|
||
referral_name: form.referral_names.value,
|
||
affiliations: form.affiliations.value,
|
||
motivation: form.why_join.value,
|
||
current_work: form.current_work.value,
|
||
contribution: form.contribution.value,
|
||
theme_ranking: JSON.stringify(getThemeRanking()),
|
||
theme_familiarity: form.theme_familiarity.value,
|
||
belief_update: form.belief_update.value,
|
||
weeks: weeks,
|
||
attendance_type: weeks.length === 4 ? 'full' : 'partial',
|
||
need_accommodation: document.getElementById('need_accommodation').checked,
|
||
accommodation_type: document.getElementById('accommodation_type').value || null,
|
||
accommodation_preference: document.getElementById('accommodation_type').value || null,
|
||
want_food: document.getElementById('want_food').checked,
|
||
anything_else: form.anything_else.value,
|
||
privacy_policy_accepted: form.privacy_accepted.checked,
|
||
code_of_conduct_accepted: true
|
||
};
|
||
}
|
||
|
||
document.getElementById('application-form').addEventListener('submit', async (e) => {
|
||
e.preventDefault();
|
||
|
||
const errorDiv = document.getElementById('form-error');
|
||
const submitBtn = document.getElementById('submit-btn');
|
||
|
||
if (!document.getElementById('privacy_accepted').checked) {
|
||
errorDiv.textContent = 'Please accept the privacy policy.';
|
||
errorDiv.style.display = 'block';
|
||
return;
|
||
}
|
||
|
||
errorDiv.style.display = 'none';
|
||
submitBtn.disabled = true;
|
||
submitBtn.textContent = 'Submitting...';
|
||
|
||
try {
|
||
const data = collectFormData();
|
||
|
||
const response = await fetch('/api/application', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(data)
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (response.ok && result.success) {
|
||
// Redirect to Mollie checkout if payment URL was returned
|
||
if (result.checkoutUrl) {
|
||
window.location.href = result.checkoutUrl;
|
||
return;
|
||
}
|
||
|
||
// No payment needed - show success directly
|
||
document.getElementById('confirm-email').textContent = data.email;
|
||
document.querySelectorAll('.form-section').forEach(s => s.classList.remove('active'));
|
||
document.querySelector('.form-section[data-step="success"]').style.display = 'block';
|
||
document.querySelector('.form-section[data-step="success"]').classList.add('active');
|
||
document.querySelector('.progress-container').style.display = 'none';
|
||
} else {
|
||
errorDiv.textContent = result.error || 'Something went wrong. Please try again.';
|
||
errorDiv.style.display = 'block';
|
||
submitBtn.disabled = false;
|
||
submitBtn.textContent = 'Submit Application';
|
||
}
|
||
} catch (error) {
|
||
console.error('Submission error:', error);
|
||
errorDiv.textContent = 'Network error. Please check your connection.';
|
||
errorDiv.style.display = 'block';
|
||
submitBtn.disabled = false;
|
||
submitBtn.textContent = 'Submit Application';
|
||
}
|
||
});
|
||
|
||
updateProgress();
|
||
</script>
|
||
</body>
|
||
</html>
|