Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Foundation/Join/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
other ways to <a href="#support">support the technology</a>-->.
</p>
<div class="flex justify-center items-center pt-10">
<a href="membership-form" class="button-outline px-10">Join</a>
<a href="join-now" class="button-outline px-10">Join</a>
</div>'
redirect_from:
- /Foundation/Join/home.pml
Expand Down Expand Up @@ -239,7 +239,7 @@ <h2 class="h2-size text-center" id="tiers">Membership Tiers</h2>
<div class="mt-4 border-t pt-4 text-sm">
<p>Free</p>
<div class="mt-3">
For non-profits, open source projects, and government entities.
For non-profits and government entities.
</div>
</div>'
%}
Expand Down
168 changes: 168 additions & 0 deletions Foundation/Join/join-now.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
# Copyright 2026 seL4 Project a Series of LF Projects, LLC.
# SPDX-License-Identifier: CC-BY-SA-4.0
title: "Join the seL4 Foundation"
pre: "Become a Member"
sub: '
Join the seL4 Foundation (a Swiss Association under the legal name "seL4
International") by entering your organisation&apos;s details below. We will review the information
provided and send you a Membership Agreement for signature.
'
pre_link: "./"
layout: card
---

{% include section-start.html
id = "agreement"
heading = "Agreements and Governance"
intro = '
<p>
Before joining, please review the <a href="seL4_Association_Membership_Agreement.pdf">Membership
Agreement</a> (for review only, not for signing), and the <a title="Articles of Association"
href="../Governance/seL4_Association_AoA.pdf"> Articles of Association</a>, the <a title="Rules of Operations" href="../Governance/seL4_Association_RoO.pdf"> Rules of Operations</a>, and
the <a title="Good Standing Policy" href="../Governance/seL4_good_standing_policy.pdf">Good Standing Policy</a>. If you have any questions, please contact <a title="foundation@sel4.systems" href="mailto:foundation@sel4.systems">foundation@sel4.systems</a>.
</p>'
%}

{% include section-end.html %}

{% include section-start.html
id = "details"
heading = "Organisation Details"
intro = '
<p>
Please enter your organisation&apos;s details below to generate a membership agreement.
</p>
<p>
The information submitted will be used to assess, approve and manage the membership of the entity, namely to (a) generate the contract, which will be sent to the provided signatory contact; (b) send invoices to the provided billing contact; (c) send AGM and voting notices to the primary contact; for the duration that the entity is a Member of seL4 International. This information can be updated anytime by contacting <a title="foundation@sel4.systems" href="mailto:foundation@sel4.systems">foundation@sel4.systems</a>.
</p>
'
%}

{% include section-end.html %}

{% include section-start.html
id = "join"
heading = "Join Now"
%}

<div class="my-20 section-max-w md:min-w-2xl">

<!-- TAB 1: PREMIUM & GENERAL - INPUT & LABEL -->
<input type="radio" id="tab-general" name="membership-toggle" class="peer/gen hidden" checked />
<label for="tab-general" class="inline-block select-none cursor-pointer transition-all duration-200 ml-5 mr-1
px-3.5 py-2 text-sm font-semibold rounded-t-md !rounded-b-none border border-gray-200 bg-gray-50 text-gray-700
peer-checked/gen:!bg-accentdark peer-checked/gen:!text-white peer-checked/gen:!border-gray-200 peer-checked/gen:!shadow-none
relative z-10 -mb-px
peer-checked/gen:after:content-[''] peer-checked/gen:after:absolute peer-checked/gen:after:bottom-0 peer-checked/gen:after:left-0 peer-checked/gen:after:right-0 peer-checked/gen:after:h-[2px] peer-checked/gen:after:bg-accent-dark">
Premium & General
</label>

<!-- TAB 2: ASSOCIATE - INPUT & LABEL -->
<input type="radio" id="tab-associate" name="membership-toggle" class="peer/assoc hidden" />
<label for="tab-associate" class="inline-block select-none cursor-pointer transition-all duration-200
px-3.5 py-2 text-sm font-semibold rounded-t-md !rounded-b-none border border-gray-200 bg-gray-50 text-gray-700
peer-checked/assoc:!bg-accentdark peer-checked/assoc:!text-white peer-checked/assoc:!border-gray-200 peer-checked/assoc:!shadow-none
relative z-10 -mb-px
peer-checked/assoc:after:content-[''] peer-checked/assoc:after:absolute peer-checked/assoc:after:bottom-0 peer-checked/assoc:after:left-0 peer-checked/assoc:after:right-0 peer-checked/assoc:after:h-[2px] peer-checked/assoc:after:bg-accent-dark">
Associate
</label>


<!-- PREMIUM AND GENERAL -->
<div class="hidden peer-checked/gen:block bg-white border border-gray-200 rounded-b-md rounded-tr-md p-4 relative z-0">

<p class="mb-2 text-sm mx-2">
For premium and general members
</p>
<p class="mb-10 text-sm mx-2">
<a href="../Join#tiers" target="_blank">Membership Tiers</a>
</p>
{% include membership-question.html
heading = "Company name"
info = "Legal name of the entity applying for membership"
type = "text"
%}

{% include membership-tiers.html %}

{% include membership-question.html
heading = "Primary contact"
info = "The who person will act as the primary voting contact unless a different assignment is requested by email at a later date."
label1 = "Name"
type1 = "text"
label2 = "Email"
type2 = "email"
%}

{% include membership-question.html
heading = "Legal (signatory) contact"
info = "The person who will officially execute or sign the membership agreement."
label1 = "Name"
type1 = "text"
label2 = "Title"
type2 = "text"
label3 = "Email"
type3 = "email"
%}

{% include membership-question.html
heading = "Billing contact"
info = "The person who will handle billing and payments."
label1 = "Name"
type1 = "text"
label2 = "Email"
type2 = "email"
address = "Address"

%}

{% include membership-po.html %}

<!-- CAPTCHA -->
{% include membership-captcha.html %}

{% include membership-submit-general.html %}

</div>

<!-- ASSOCIATE -->
<div class="hidden peer-checked/assoc:block bg-white border border-gray-200 rounded-b-md rounded-tr-md p-4 relative z-0">
<p class="mb-10 text-sm mx-2">
For non-profits and government entities.
</p>

{% include membership-question.html
heading = "Company name"
info = "Legal name of the entity applying for membership"
type = "text"
%}

{% include membership-question.html
heading = "Primary contact"
info = "The who person will act as the primary voting contact unless a different assignment is requested by email at a later date."
label1 = "Name"
type1 = "text"
label2 = "Email"
type2 = "email"
%}

{% include membership-question.html
heading = "Legal (signatory) contact"
info = "The person who will officially execute or sign the membership agreement."
label1 = "Name"
type1 = "text"
label2 = "Title"
type2 = "text"
label3 = "Email"
type3 = "email"
%}

<!-- CAPTCHA -->
{% include membership-captcha.html %}

{% include membership-submit-associate.html %}
</div>
</div>

{% include section-end.html %}
1 change: 1 addition & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ path = [
"_data/menu.json",
"_data/footer.json",
"_data/members.json",
"_data/memberships.json",
"_data/platforms.json",
"_data/sponsors.json",
"_data/benchmarks.json",
Expand Down
38 changes: 38 additions & 0 deletions _data/memberships.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[
{
"id": 1,
"tier": "Premium",
"employees": "--",
"fees": "CHF 100,000"
},
{
"id": 2,
"tier": "General",
"employees": "5,000 and above",
"fees": "CHF 35,000"
},
{
"id": 3,
"tier": "General",
"employees": "Between 500 and 4,999",
"fees": "CHF 20,000"
},
{
"id": 4,
"tier": "General",
"employees": "Between 100 and 499",
"fees": "CHF 10,000"
},
{
"id": 5,
"tier": "General",
"employees": "Between 21 and 99",
"fees": "CHF 4,000"
},
{
"id": 6,
"tier": "General",
"employees": "Up to 20",
"fees": "CHF 2,500"
}
]
75 changes: 75 additions & 0 deletions _includes/membership-captcha.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{%- comment %}
Copyright 2026 seL4 Project a Series of LF Projects, LLC
SPDX-License-Identifier: CC-BY-SA-4.0
{% endcomment -%}


<!-- Friendly Captcha v2 SDK -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.2.0/site.min.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@friendlycaptcha/sdk@0.2.0/site.compat.min.js" async defer></script>

<!-- Captcha Widget Component -->
<div class="flex items-center justify-center my-10">
<div
class="frc-captcha"
data-sitekey="{{ site.friendly_captcha_sitekey | default: 'FCMQDHD5NMOKR1Q0' }}"
data-start="auto">
</div>
</div>

<script>
document.addEventListener("DOMContentLoaded", function () {
// Locate the parent form containing this captcha component
const captchaElement = document.querySelector(".frc-captcha");
if (!captchaElement) return;

const parentForm = captchaElement.closest("form");
if (!parentForm) return;

parentForm.addEventListener("submit", async function (e) {
e.preventDefault();

const formData = new FormData(parentForm);
// Friendly Captcha inserts this response parameter into the form automatically
const solutionToken = formData.get("frc-captcha-response");

if (!solutionToken) {
alert("Please complete the captcha challenge before submitting.");
return;
}

// Convert FormData into a standard JSON payload
const payload = Object.fromEntries(formData.entries());
payload.solutionToken = solutionToken;

try {
// Point this to your running Node.js endpoint / serverless route
const response = await fetch("http://localhost:3000/api/verify-membership", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});

const result = await response.json();

if (response.ok && result.success) {
alert("Membership submission received successfully!");
parentForm.reset();
} else {
alert("Verification failed: " + (result.message || "Invalid Captcha Token"));
return response.status(400).json({
success: false,
message: "Captcha verification failed.",
error_code: verifyData.error?.error_code,
detail: verifyData.error?.detail
});
}
} catch (err) {
console.error("Submission error:", err);
alert("An error occurred while attempting to submit the form.");
}
});
});
</script>
23 changes: 23 additions & 0 deletions _includes/membership-po.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{%- comment %}
Copyright 2026 seL4 Project a Series of LF Projects, LLC
SPDX-License-Identifier: CC-BY-SA-4.0
{% endcomment -%}
<div class="flex gap-4 mt-10 text-sm justify-center items-center">
<div class="font-semibold">PO required:</div>
<div>
<input
type="radio"
name="po_selection" class="accent-green-700"
value='1'
/>
<span>Yes</span>
</div>
<div>
<input
type="radio"
name="po_selection" class="accent-green-700"
value='2'
/>
<span>No</span>
</div>
</div>
Loading