Compare commits

24 Commits

Author SHA1 Message Date
Nathan Schneider
0bc9d26ad0 UX adjustments to the contact buttons on main page 2025-08-03 23:12:35 -06:00
Nathan Schneider
d7d68f874a Small UX tweaks 2025-07-31 16:35:53 -06:00
1d964277b2 Added E2CC support link to footer 2025-07-28 20:37:55 +00:00
Nathan Schneider
49e8196fe8 Various UX improvements to index and dropdowns 2025-07-21 21:25:24 -06:00
afee96c7a2 Added Matomo tracking code 2025-07-21 00:05:06 +00:00
4ce406d3de Moved domain to e2c.how 2025-07-20 23:43:46 +00:00
Nathan Schneider
0bf0e02f40 Aesthetic adjustments throughout 2025-07-20 00:06:09 -06:00
Nathan Schneider
57cd3fe19b Moved JS from baseof 2025-07-19 21:49:44 -06:00
Nathan Schneider
e7d02211a3 Moved CSS from baseof 2025-07-19 21:46:51 -06:00
Nathan Schneider
0060c18793 Improvements to responsiveness on menu and index page 2025-07-19 21:41:38 -06:00
e8fac6be10 Deleting misspelled file 2025-07-19 15:19:17 +00:00
1cd7ee77a0 Spelling Signalise right on banner filename! 2025-07-19 15:19:02 +00:00
ee4bc3a3eb Replaced Signalese banner 2025-07-19 15:17:48 +00:00
Nathan Schneider
7480231a58 Fixes to h2 headers caused by Action Network form handling 2025-06-27 21:37:43 -06:00
Nathan Schneider
d2cd3e6c24 Added favicon and got Action Network forms working 2025-06-27 14:19:17 -06:00
91356f7a0b Updated README development and deployment wording 2025-06-27 16:45:10 +00:00
d78abae61f Adjusted color of h2 in intro section on main page 2025-06-27 16:08:38 +00:00
Nathan Schneider
aea2038ba5 Added featured cases to index, other improvements 2025-06-26 11:34:30 -07:00
Nathan Schneider
dfda606591 Various improvements to directories and design 2025-06-25 21:20:28 -07:00
Nathan Schneider
975158ad0c Resources are now real 2025-06-25 16:44:42 -07:00
Nathan Schneider
deb7b4f1b8 Fixed main page typo 2025-06-25 13:17:03 -07:00
Nathan Schneider
9648921133 Adjusted main page bullet points 2025-06-25 13:07:33 -07:00
Nathan Schneider
4e00b0d93e Increased logo size for visibility 2025-06-25 13:05:36 -07:00
Nathan Schneider
70131b40a5 Now publishes on commit to main branch 2025-06-25 13:00:31 -07:00
96 changed files with 2179 additions and 1102 deletions

View File

@@ -8,7 +8,7 @@ variables:
# Tells GitLab Runner to initialize and update submodules recursively
GIT_SUBMODULE_STRATEGY: recursive
# TODO: the Surfer server base url (ex: "https://www.example.com/")
SURFER_SERVER: "https://e2c.medlab.host/"
SURFER_SERVER: "https://e2c.how/"
stages:
- build # Added build stage
@@ -30,7 +30,7 @@ build_site:
# Define when this job runs (e.g., only on the main branch)
# Adjust 'only' or 'rules' as needed for your workflow
only:
- publish # the script will only run on the branch 'publish'
- main # the script will only run on the branch 'main'
# Job to deploy the built site using cloudron-surfer
deploy_site:
@@ -58,5 +58,5 @@ deploy_site:
public/* /
- echo "Deployment completed successfully"
only:
- publish # Example: Run only on the main branch
- main # Example: Run only on the main branch

View File

@@ -1,23 +1,29 @@
# Exit to Community Hugo Site
# E2C.how website
**An informational website by the Exit to Community Collective.**
This is a Hugo static site that migrated content from a Notion database to create the Exit to Community documentation site.
This is a Hugo static site that migrated content from the earlier site that was built with a Notion database, with assistance from Claude Code.
## Project Overview
The site documents case studies, legal snippets, and resources related to "Exit to Community" - the practice of converting startups into community-owned cooperatives.
The site documents case studies, legal snippets, and resources related to "Exit to Community"the practice of converting startups into community ownership and governance.
## How to contribute
To contribute to this project, use the contact form at E2C.how to request edit access to the repository. With such access, the public site automatically updates whenever changes are pushed to the `main` branch of this repository. Changes may be pushed either by:
* Editing files directly via the GUI edit tools at `https://git.medlab.host/e2c/e2c-how/`
* Pushing from a local clone via git
## Key Technical Details
### Site Structure
- **Hugo static site generator** with custom layouts
- **No CMS** - Decap CMS was removed due to login issues
- **Content in Markdown** with YAML frontmatter
- **Custom CSS styling** with E2C yellow branding (#F4D03F)
### Content Types
- **Case Studies** (`/content/case-studies/`) - 24 case studies with logos and descriptions
- **Case Studies** (`/content/case-studies/`) - Case studies with logos and descriptions
- **Legal Snippets** (`/content/legal-snippets/`) - Legal documents and frameworks
- **Resources** (`/content/resources/`) - Media, education, and primer content
- **Main Pages** - Homepage, contact, add-your-story with integrated forms
@@ -69,7 +75,8 @@ The site documents case studies, legal snippets, and resources related to "Exit
4. Visit http://localhost:1313
### Deployment
Set up deployment following: https://git.medlab.host/dhorn/medlab-hugo-template
To deploy changes, simply push them to the `main` branch and they should automatically publish. Deployment occurs through GitLab and Surfer on the MEDLab server, making use of Drew Hornbein's [template](https://git.medlab.host/dhorn/medlab-hugo-template).
## External Dependencies
- Hugo static site generator
@@ -81,4 +88,3 @@ Set up deployment following: https://git.medlab.host/dhorn/medlab-hugo-template
- Content updates should maintain the clean YAML structure
- New case studies should follow the established pattern with logos
- Consider adding search functionality if the content grows significantly
- Form submissions need backend integration for actual processing

View File

@@ -1,8 +0,0 @@
{
"permissions": {
"allow": [
"WebFetch(domain:actionnetwork.org)"
],
"deny": []
}
}

View File

@@ -7,52 +7,41 @@ hero_alt: "Exit to Community concept illustration"
<div class="hero-section">
<div class="hero-content">
<img src="/img/Frame_1_(6).png" alt="Exit to Community concept illustration" class="hero-image" />
<div class="hero-text">
<h1>Stories and strategies for community ownership</h1>
</div>
<img src="/img/Frame_1_(6).png" alt="Exit to Community concept illustration" class="hero-image" />
</div>
</div>
<div class="intro-section">
<h2>What is Exit to Community?</h2>
<p>Most startups aim for one of two "exit" options: an acquisition by another company or a public stock offering. Both often pit founders and investors against the communities they claim to serve.</p>
Most startups aim for one of two "exit" options: an acquisition by another company or a public stock offering. Both often pit founders and investors against the communities they claim to serve.
<p>Exit to Community is a search for another way—a path where organizations can mature toward accountability and shared prosperity.</p>
Exit to Community is a search for another way—a path where organizations can mature toward accountability and shared prosperity.
<ul>
<li>Business purpose can align with ownership</li>
<li>Founding can teams let go at the right time</li>
<li>Communities can grow the business they value</li>
<li>Allies in consulting, policy, and academia can help advance economic democracy</li>
<li>Founders and investors can let go when they need to</li>
<li>Communities can protect the businesses they value</li>
</ul>
<p>This is a strategy that we are exploring together. Here, you can find cases and documents about experiments with E2C so far.</p>
</div>
<div class="main-sections">
<h2>Explore E2C</h2>
<div class="primary-cards">
<div class="primary-card">
<h3>Case Studies</h3>
<p>Real examples of companies that have attempted or achieved community ownership transitions</p>
<a href="/case-studies/" class="button">Explore Cases</a>
</div>
<div class="primary-card">
<h3>Legal Snippets</h3>
<p>Legal documents and frameworks for implementing community ownership structures</p>
<a href="/legal-snippets/" class="button">View Legal Resources</a>
</div>
<div class="primary-card">
<h3>Resources</h3>
<p>Educational materials, primers, and guides for Exit to Community transitions</p>
<a href="/resources/" class="button">Access Resources</a>
</div>
<div class="featured-cases-section">
<div class="featured-cases-grid" id="featuredCasesGrid">
<!-- Featured cases will be loaded here -->
</div>
<div style="text-align: center; margin-top: 2rem;">
<a href="/case-studies/" class="btn">View All Case Studies</a>
</div>
</div>
<div style="text-align: center; margin: 3rem 0;">
<img src="/img/Screenshot_2023-12-13_at_1.55.04_PM.png" alt="Partnership handshake illustration" class="partnership-image" />
</div>
@@ -60,16 +49,16 @@ hero_alt: "Exit to Community concept illustration"
<div class="secondary-actions">
<h3>Get Involved</h3>
<div class="secondary-cards">
<div class="secondary-card">
<h4>Plan Your E2C</h4>
<p>Connect with our team to discuss your organization's future</p>
<a href="/contact/" class="secondary-button">Get in Touch</a>
</div>
<div class="secondary-card">
<h4>Share Your Story</h4>
<p>Help others learn by contributing your organization's E2C experience</p>
<a href="/add-your-story/" class="secondary-button">Add Your Story</a>
</div>
<div class="secondary-card">
<h4>Get in Touch</h4>
<p>Connect with the Exit to Community project team</p>
<a href="/contact/" class="secondary-button">Contact Us</a>
</div>
</div>
</div>

View File

@@ -8,10 +8,17 @@ We're curating stories from founding teams and allies to help people learn from
Help us share it with people who can benefit from its lessons.
<div class="contact-form-container">
<form class="e2c-contact-form" action="#" method="post">
<!-- Action Network Form Embed -->
<link href='https://actionnetwork.org/css/style-embed-v3.css' rel='stylesheet' type='text/css' />
<script src='https://actionnetwork.org/widgets/v3/form/e2c-website-story-form?format=js&source=widget&clear_id=true'></script>
<div id='can-form-area-e2c-website-story-form' style='width: 100%'></div>
<!-- Fallback form for cases where JS is disabled -->
<noscript>
<form class="e2c-contact-form" action="https://actionnetwork.org/forms/e2c-website-story-form" method="post">
<div class="form-group">
<label for="country">Country *</label>
<select id="country" name="country" required>
<select id="country" name="person[country]" required>
<option value="">Select your country</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
@@ -40,19 +47,19 @@ Help us share it with people who can benefit from its lessons.
</div>
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required>
<input type="email" id="email" name="person[email]" required>
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name">
<input type="text" id="name" name="person[given_name]">
</div>
<div class="form-group">
<label for="organization">Organization</label>
<input type="text" id="organization" name="organization">
<input type="text" id="organization" name="person[employer]">
</div>
<div class="form-group">
<label for="role">Role</label>
<input type="text" id="role" name="role">
<input type="text" id="role" name="person[occupation]">
</div>
<div class="form-group">
<label for="experience_description">Briefly describe your experience with community ownership</label>
@@ -83,5 +90,6 @@ Help us share it with people who can benefit from its lessons.
</div>
<button type="submit" class="submit-btn">Submit</button>
</form>
</noscript>
</div>

View File

@@ -12,6 +12,7 @@ tags:
- music
url_external: https://ampled.com/
image: /img/logos/ampled.svg
banner: /img/banners/ampled.png
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- underway
url_external: https://are.na/
image: /img/logos/arena.png
banner: /img/banners/arena.webp
---
### Summary
@@ -34,4 +35,4 @@ At present, Are.ca could take one of two paths. First, it could seek majority co
- E2C conversation with founding team
- [Charles Broskoski: How do you describe are.na at a party? Are.na](https://www.are.na/charles-broskoski/how-do-you-describe-are-na-at-a-party)
- [Can the Internet Feel Better? Early Magazine](https://www.earlymagazine.com/articles/can-the-internet-feel-better)
- [Meet are.na ArtNews](https://www.artnews.com/art-news/artists/doesnt-produce-anxiety-meet-na-social-network-created-artists-10207/)
- [Meet are.na ArtNews](https://www.artnews.com/art-news/artists/doesnt-produce-anxiety-meet-na-social-network-created-artists-10207/)

View File

@@ -12,6 +12,7 @@ tags:
- utilities
url_external: https://buytwitter.org/
image: /img/logos/buytwitter.png
banner: /img/banners/buytwitter.jpg
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- services
url_external: https://cmxhub.com
image: /img/logos/cmx.jpg
banner: /img/banners/cmx.webp
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- underway
url_external: https://dadacoin.com
image: /img/logos/dada.jpg
banner: /img/banners/dada.png
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- success
url_external: https://debian.org/
image: /img/logos/debian.png
banner: /img/banners/debian.png
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- worker-owned
url_external: https://defector.com/
image: /img/logos/defector.png
banner: /img/banners/defector.jpg
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- success
url_external: https://ens.domains/
image: /img/logos/ens.jpg
banner: /img/banners/ens.jpg
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://forwardaction.uk/
image: /img/logos/forward.jpg
banner: /img/banners/forward.webp
---
### Summary
@@ -31,4 +32,4 @@ Because the transition was so recent, it may be too soon to gauge its long-term
### Sources
- [A New Chapter for Forward Action](https://forwardaction.uk/2022/09/new-chapter/)
- [Forward Action  About Us](https://forwardaction.uk/2022/04/about-forward-action-our-job-benefits/)
- [Forward Action  About Us](https://forwardaction.uk/2022/04/about-forward-action-our-job-benefits/)

View File

@@ -9,6 +9,7 @@ tags:
- crypto
url_external: https://gitcoin.co/
image: /img/logos/gitcoin.png
banner: /img/banners/gitcoin.png
---
### Summary

View File

@@ -13,6 +13,7 @@ tags:
- worker-owned
url_external: https://groupmuse.com/
image: /img/logos/groupmuse.png
banner: /img/banners/groupmuse.jpg
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://hackernoon.com/
image: /img/logos/hackernoon.jpg
banner: /img/banners/hackernoon.png
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- services
url_external: https://www.crunchbase.com/organization/josephine
image: /img/logos/josephine.png
banner: /img/banners/josephine.webp
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- software
url_external: https://en.wikipedia.org/wiki/Juno_(company)
image: /img/logos/juno.png
banner: /img/banners/juno.jpg
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- worker-owned
url_external: https://namastesolar.com
image: /img/logos/namaste.png
banner: /img/banners/namaste.jpg
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- trust
url_external: https://nio.com
image: /img/logos/nio.jpg
banner: /img/banners/nio.webp
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://python.org/
image: /img/logos/python.jpg
banner: /img/banners/python.jpg
---
### Summary

View File

@@ -12,6 +12,7 @@ tags:
- success
url_external: https://signalise.coop/
image: /img/logos/signalise.jpg
banner: /img/banners/signalise.jpg
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://songaday.world/
image: /img/logos/songadao.png
banner: /img/banners/songadao.jpg
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://theappeal.org/
image: /img/logos/the-appeal.jpg
banner: /img/banners/the-appeal.jpg
---
### Summary

View File

@@ -11,6 +11,7 @@ tags:
- worker-owned
url_external: https://thebrick.house/
image: /img/logos/the-brick-house.jpg
banner: /img/banners/the-brick-house.png
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://well.com/
image: /img/logos/the-well.png
banner: /img/banners/the-well.png
---
### Summary

View File

@@ -10,6 +10,7 @@ tags:
- success
url_external: https://tridentcafe.com/
image: /img/logos/trident-booksellers.png
banner: /img/banners/trident-booksellers.jpg
---
### Summary

View File

@@ -9,6 +9,7 @@ tags:
- crypto
url_external: https://uniswap.org
image: /img/logos/uniswap.jpg
banner: /img/banners/uniswap.png
---
### Summary

View File

@@ -7,21 +7,24 @@ The E2C Collective is a group of practitioners, researchers, and allies who coll
Want to contribute to this resource library? Have a story to share or questions about community ownership transitions? Are you looking for support for your own E2C process? We'd love to hear from you.
## Add your story
If you know of a company that has attempted or achieved an exit to community transition, we'd love to include it in our case study library.
<a class="btn" href="/add-your-story/">Contribute a story</a>
## Get involved or get support
Want to plan your community exit strategy? Got experience or legal snippets you'd like to share? We'd love to hear from you!
<div class="contact-form-container">
<form class="e2c-contact-form" action="#" method="post">
<!-- Action Network Form Embed -->
<link href='https://actionnetwork.org/css/style-embed-v3.css' rel='stylesheet' type='text/css' />
<script src='https://actionnetwork.org/widgets/v3/form/e2c-website-join-form?format=js&source=widget&clear_id=true'></script>
<div id='can-form-area-e2c-website-join-form' style='width: 100%'></div>
<!-- Fallback form for cases where JS is disabled -->
<noscript>
<form class="e2c-contact-form" action="https://actionnetwork.org/forms/e2c-website-join-form" method="post">
<div class="form-group">
<label for="country">Country *</label>
<select id="country" name="country" required>
<select id="country" name="person[country]" required>
<option value="">Select your country</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
@@ -50,19 +53,19 @@ Want to plan your community exit strategy? Got experience or legal snippets you'
</div>
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required>
<input type="email" id="email" name="person[email]" required>
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name">
<input type="text" id="name" name="person[given_name]">
</div>
<div class="form-group">
<label for="organization">Organization</label>
<input type="text" id="organization" name="organization">
<input type="text" id="organization" name="person[employer]">
</div>
<div class="form-group">
<label for="organization_url">Organization URL</label>
<input type="url" id="organization_url" name="organization_url" placeholder="https://">
<input type="url" id="organization_url" name="person[website]" placeholder="https://">
</div>
<div class="form-group">
<label>Interests in E2C</label>
@@ -97,5 +100,6 @@ Want to plan your community exit strategy? Got experience or legal snippets you'
</div>
<button type="submit" class="submit-btn">Submit</button>
</form>
</noscript>
</div>

View File

@@ -6,8 +6,6 @@ tags:
- Filing
- Public-policy
- United-States
type: legal-snippet
layout: single
external_url: https://www.sec.gov/comments/s7-18-18/s71818-4403356-175575.pdf
files_media: ../../Exit%20to%20Community%20Stories%20&%20Strategies%202ee6f9c491af45648511f5df33c5cfc5/s71818-4403356-175575.pdf
---

View File

@@ -5,8 +5,6 @@ tags:
- Investment
- Netherlands
- Steward-ownership
type: legal-snippet
layout: single
external_url: https://www.alkemio.org/structure/
files_media:
- ../../Exit%20to%20Community%20Stories%20&%20Strategies%202ee6f9c491af45648511f5df33c5cfc5/Alkemio-PurchaseAgreement.pdf,

View File

@@ -5,7 +5,5 @@ tags:
- Australia
- Bylaws
- Cooperative
type: legal-snippet
layout: single
external_url: https://bccm.coop/co-op-builder-tool/
---

View File

@@ -6,7 +6,5 @@ tags:
- Cooperative
- LCA
- United-States
type: legal-snippet
layout: single
external_url: https://help.collab.land/governance/charter
---

View File

@@ -4,7 +4,5 @@ description: Aiming to find a middle ground between a for-profit and not-for-pro
tags:
- Investment
- UK
type: legal-snippet
layout: single
files_media: ../../Exit%20to%20Community%20Stories%20&%20Strategies%202ee6f9c491af45648511f5df33c5cfc5/Sample_term_sheet__guardian_share.docx
---

View File

@@ -4,7 +4,5 @@ description: How policymakers can support the financing of shared ownership acro
tags:
- Public-policy
- United-States
type: legal-snippet
layout: single
external_url: https://democracypolicy.network/the-agenda/policy_kit/financing-shared-ownership
---

View File

@@ -4,7 +4,5 @@ description: IPO with Class B Common Stock which grants employees and directors
tags:
- Filing
- United-States
type: legal-snippet
layout: single
external_url: https://www.sec.gov/Archives/edgar/data/1830214/000119312521275407/d172577d424b3.htm#rom172577_78
---

View File

@@ -4,7 +4,5 @@ description: Revenue-based equity financing term sheet with a 3x cap on return t
tags:
- Investment
- United-States
type: legal-snippet
layout: single
external_url: https://github.com/indievc/terms
---

View File

@@ -4,7 +4,5 @@ description: Legal framework for enabling worker-ownership buyouts of endangered
tags:
- Italy
- Public-policy
type: legal-snippet
layout: single
external_url: https://www.researchgate.net/profile/Marcelo-Vieta/publication/316360529_THE_ITALIAN_ROAD_TO_RECUPERATING_ENTERPRISES_AND_THE_LEGGE_MARCORA_FRAMEWORK_Italy's_Worker_Buyouts_in_Times_of_Crisis/links/58fb664e0f7e9ba3ba5237d4/THE-ITALIAN-ROAD-TO-RECUPERATING-ENTERPRISES-AND-THE-LEGGE-MARCORA-FRAMEWORK-Italys-Worker-Buyouts-in-Times-of-Crisis.pdf
---

View File

@@ -7,7 +7,5 @@ tags:
- Investment
- LCA
- United-States
type: legal-snippet
layout: single
external_url: https://www.dropbox.com/scl/fo/20gqmeee9j2zgn4sibt4r/AIEsVgetO6b4HJ7pGUfmHFI?rlkey=os0dz2a3pevaodbnj7btdwag8&e=7&st=lr1yadcj&dl=0
---

View File

@@ -3,7 +3,5 @@ title: 'Right To Own: A Policy Framework to Catalyze Worker Ownership Transition
description: Reviews and proposes polices to encourage employee ownership conversions.
tags:
- Public-policy
type: legal-snippet
layout: single
external_url: https://thenextsystem.org/rto
---

View File

@@ -3,7 +3,5 @@ title: Shared Earnings Agreement (SEAL)
description: “The goal of a SEAL is to align the interests of investors and founders in a wide variety of outcomes, while giving founders full control of their business and keeping as much optionality as possible open for the business.”
tags:
- Investment
type: legal-snippet
layout: single
external_url: https://calmfund.com/shared-earnings-agreement
---

View File

@@ -5,8 +5,6 @@ tags:
- Bylaws
- Finland
- Investment
type: legal-snippet
layout: single
external_url: https://drive.google.com/drive/u/1/folders/138TkcSEVCyjOXByM0QUR7M4iWch8u6tM
files_media: ../../Exit%20to%20Community%20Stories%20&%20Strategies%202ee6f9c491af45648511f5df33c5cfc5/Sharetribes_Articles_of_Association_and_Shareholders_Agreement-20240522T043504Z-001.zip
---

View File

@@ -4,8 +4,6 @@ description: Term sheet provision with a government-backed venture firm with an
tags:
- Investment
- Italy
type: legal-snippet
layout: single
---
## Exit dallInvestimento

View File

@@ -0,0 +1,5 @@
---
title: Resources
description: "Educational materials, media coverage, and tools for Exit to Community"
---

View File

@@ -0,0 +1,11 @@
---
title: "Exit to Community Calculators"
date: 2024-02-01
description: "Post on tool development for assessing E2C readiness"
url_external: https://medium.com/metagov/exit-to-community-calculators-a-framework-and-tool-to-help-organizations-assess-their-e2c-5fcbd006d227
tags:
- publication
- tool
#image:
---

View File

@@ -0,0 +1,12 @@
---
title: "Interview with Tara Merk on E2C"
date: 2023-12-18
description: "Featuring Merk on Alana Podrx's Friday Futures series"
url_external: https://podrx.substack.com/p/exit-to-community
tags:
- academic
- press
#image:
---
<iframe width="560" height="315" src="https://www.youtube.com/embed/bm9rItK4_VA?si=kdGOg3gfQkE7-M0l" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

View File

@@ -0,0 +1,10 @@
---
title: "Digital Kelsoism: Employee Stock Ownership as a Pattern for the Online Economy"
date: 2020-10-19
external_url: https://osf.io/preprints/mediarxiv/m82zx_v1
description: "Article by Nathan Schneider on lessons from employee stock ownership plans for E2C"
tags:
- publications
- academic
- policy
---

View File

@@ -0,0 +1,11 @@
---
title: "E2C @ MEDLab"
description: "E2C publications and events at the University of Colorado Boulder's Media Economies Design Lab"
url_external: https://www.colorado.edu/lab/medlab/exit-to-community
tags:
- academic
- publication
- events
#image:
---

View File

@@ -0,0 +1,9 @@
---
title: "Noema intro to E2C"
date: 2020-08-27
external_url: https://www.noemamag.com/exit-to-community/
description: "Essay on the basics of E2C in Noema magazine by Nathan Schneider"
tags:
- publications
- getting-started
---

View File

@@ -2,10 +2,11 @@
title: E2C Primer
date: '2025-06-24'
draft: false
type: resource
section: resources
layout: resource
description: "A comprehensive introduction to Exit to Community concepts and strategies"
tags:
- primer
- education
- getting-started
---
## Introduction to Exit to Community

View File

@@ -0,0 +1,11 @@
---
title: "Exit To Community: Strategies for Multi-Stakeholder Ownership in the Platform Economy"
description: "Law review article on the legal and regulatory possibilities of E2C, by Morshed Mannan and Nathan Schneider"
url_external: https://georgetownlawtechreview.org/exit-to-community-strategies-for-multi-stakeholder-ownership-in-the-platform-economy/GLTR-05-2021/
tags:
- academic
- publication
- policy
#image:
---

View File

@@ -1,86 +0,0 @@
---
title: Education
date: '2025-06-24'
draft: false
type: resource
section: resources
layout: resource
description: "Educational resources, courses, and learning materials for Exit to Community"
---
## Learning Pathways
**Getting Started**
- [E2C Primer](/resources/e2c-primer/) - Comprehensive introduction to Exit to Community concepts
- Overview of cooperative governance models
- Understanding legal structures and requirements
**For Founders and Organizations**
- Assessing readiness for E2C transition
- Community engagement strategies
- Financial planning for ownership transition
- Legal frameworks and implementation
**For Communities and Users**
- Rights and responsibilities in community ownership
- Democratic governance participation
- Understanding cooperative economics
## Case Study Learning
**Real-World Examples**
- [Browse all case studies](/case-studies/) to learn from actual E2C transitions
- Industry-specific examples across tech, media, and social platforms
- Lessons learned from successful and challenging transitions
**Legal Framework Examples**
- [Explore legal snippets](/legal-snippets/) for practical documentation
- Bylaws, governance structures, and policy templates
- Multi-jurisdictional approaches and considerations
## Educational Partnerships
**Academic Collaborations**
- Research partnerships with universities
- Student projects and thesis opportunities
- Faculty resources for cooperative economics courses
**Professional Development**
- Workshops for lawyers, consultants, and advisors
- Training for organizational development professionals
- Certification programs for E2C specialists
## Tools and Templates
**Planning Resources**
- E2C readiness assessment frameworks
- Community engagement toolkits
- Transition timeline templates
- Governance structure guides
**Implementation Support**
- Legal document templates
- Financial modeling resources
- Communication strategy guides
- Stakeholder mapping tools
## Research and Publications
**Academic Resources**
- Working papers on community ownership models
- Economic analysis of cooperative transitions
- Comparative studies across industries and regions
- Policy recommendations and advocacy resources
## Community Learning
**Peer Networks**
- Connect with other organizations exploring E2C
- Mentorship opportunities with successful transitions
- Regular webinars and discussion forums
- Regional meetups and conferences
## Get Involved
Ready to learn more? [Contact us](/contact/) about educational opportunities, or [share your story](/add-your-story/) to contribute to the E2C learning community.

View File

@@ -0,0 +1,9 @@
---
title: "Financing Shared Ownership"
date: 2025-06-16
external_url: https://democracypolicy.network/agenda/open-country/open-economy/financing-shared-ownership
description: "Policy report for state legislators on shared ownership strategies, including E2C"
tags:
- publications
- policy
---

View File

@@ -1,52 +0,0 @@
---
title: Media
date: '2025-06-24'
draft: false
type: resource
section: resources
layout: resource
description: "Media coverage, publications, and press resources about Exit to Community"
---
## Featured Coverage
**Exit to Community in the News**
- Recent articles and coverage of E2C transitions
- Analysis pieces on community ownership models
- Interviews with founders who chose E2C paths
## Academic Publications
**Research and Analysis**
- [The Italian Road to Creating Worker Cooperatives](/legal-snippets/the-italian-road-to-creating-worker-cooperatives/) - Academic research on worker buyouts
- Policy papers on alternative exit strategies
- Comparative studies of cooperative governance models
## Media Case Studies
**Journalism and Media Organizations**
- [Defector Media](/case-studies/defector-media/) - Sports journalism as a worker cooperative
- [The Appeal](/case-studies/the-appeal/) - Criminal justice reporting as a worker-led nonprofit
**Creative Platforms**
- [Are.na](/case-studies/are-na/) - Social platform for artists and students exploring community ownership
## Press Kit
**For Journalists and Researchers**
- High-resolution logos and brand assets
- Key statistics about community ownership
- Expert contacts for interviews
- Fact sheets on E2C models
## Media Partnerships
**Collaborative Coverage**
- Working with media organizations exploring E2C
- Supporting journalism on cooperative economics
- Facilitating connections between E2C practitioners and reporters
## Get in Touch
Interested in covering Exit to Community stories? [Contact us](/contact/) for press resources, expert interviews, and story leads.

View File

@@ -0,0 +1,12 @@
---
title: "Interview with Tara Merk on E2C"
date: 2023-12-18
description: "Featuring Merk on Alana Podrx's Friday Futures series"
url_external: https://podrx.substack.com/p/exit-to-community
tags:
- academic
- press
#image:
---
<iframe width="560" height="315" src="https://www.youtube.com/embed/bm9rItK4_VA?si=kdGOg3gfQkE7-M0l" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

View File

@@ -0,0 +1,10 @@
---
title: "Exit to Community: A Community Primer"
description: "Collaborative zine published in 2020 introducing the E2C idea"
url_external: https://www.colorado.edu/lab/medlab/2020/08/31/exit-community-community-primer
tags:
- getting-started
- publication
#image:
---

View File

@@ -0,0 +1,9 @@
---
title: "To Community"
description: "From Metagov, a set of strategies for bonding companies to communities"
url_external: https://to.community/
tags:
- tool
#image:
---

View File

@@ -0,0 +1,12 @@
---
title: "Why to DAO: a narrative analysis of the drivers of tokenized Exit to Community"
date: 2024-07-19
description: "Research paper by Tara Merk on motivations for community ownership"
url_external: https://arxiv.org/abs/2407.14327
tags:
- academic
- crypto
- publication
#image:
---

View File

@@ -10,6 +10,10 @@ title = 'Exit to Community'
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
[markup.goldmark.extensions]
[markup.goldmark.extensions.typographer]
leftdoublequote = '&ldquo;'
rightdoublequote = '&rdquo;'
[menu]
[[menu.main]]

View File

@@ -3,757 +3,43 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ if .Title }}{{ .Title }} - {{ end }}{{ .Site.Title }}</title>
<title>{{ if and .Title (ne .Title .Site.Title) }}{{ .Title }} - {{ end }}{{ .Site.Title }}</title>
<meta name="description" content="{{ .Description | default .Site.Params.description }}">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
<style>
@import url('/fonts/space-grotesk-local.css');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--e2c-yellow: #F4D03F;
--e2c-dark-yellow: #E8C547;
--text-primary: #2C3E50;
--text-secondary: #7F8C8D;
--background: #FEFEFE;
--card-background: #FFFFFF;
--border: #E5E8E8;
--shadow: rgba(0, 0, 0, 0.08);
}
body {
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: var(--text-primary);
background: var(--background);
font-weight: 400;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px;
}
.site-header {
background-image: url('/img/notion_bg-1.png');
background-size: cover;
background-position: center top;
background-repeat: no-repeat;
border-bottom: 1px solid var(--border);
padding: 16px 0;
position: sticky;
top: 0;
z-index: 100;
min-height: 80px;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
text-decoration: none;
color: var(--text-primary);
font-weight: 600;
font-size: 1.2rem;
background: rgba(255, 255, 255, 0.9);
padding: 8px 16px;
border-radius: 24px;
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.logo img {
height: 36px;
margin-right: 10px;
}
.nav-links {
display: flex;
list-style: none;
gap: 16px;
margin: 0;
}
.nav-links a {
text-decoration: none;
color: var(--text-primary);
font-weight: 500;
font-size: 14px;
padding: 8px 16px;
border-radius: 20px;
transition: all 0.2s ease;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.nav-links a:hover {
background: var(--e2c-yellow);
border-color: var(--e2c-yellow);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
main {
padding: 48px 0;
min-height: calc(100vh - 200px);
}
footer {
background: var(--card-background);
border-top: 1px solid var(--border);
padding: 48px 0 32px 0;
color: var(--text-secondary);
font-size: 14px;
}
.footer-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
}
.footer-section h3 {
color: var(--text-primary);
font-size: 1.25rem;
margin-bottom: 16px;
font-weight: 600;
}
.footer-section p {
margin-bottom: 16px;
line-height: 1.6;
}
.newsletter-signup {
margin-top: 24px;
}
.custom-newsletter-form .form-group {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.email-input {
flex: 1;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 400;
font-size: 14px;
padding: 10px 16px;
border: 1px solid var(--border);
border-radius: 24px;
background: rgba(255, 255, 255, 0.9);
color: var(--text-primary);
transition: all 0.2s ease;
}
.email-input:focus {
outline: none;
border-color: var(--e2c-yellow);
box-shadow: 0 0 0 2px rgba(244, 208, 63, 0.2);
}
.email-input::placeholder {
color: var(--text-secondary);
}
.subscribe-btn {
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 500;
font-size: 14px;
padding: 10px 20px;
background: var(--e2c-yellow);
color: var(--text-primary);
border: 2px solid var(--e2c-yellow);
border-radius: 24px;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
}
.subscribe-btn:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
transform: translateY(-1px);
}
.form-note {
font-size: 12px;
color: var(--text-secondary);
margin: 0;
font-style: italic;
}
.footer-links {
text-align: right;
}
.footer-links p {
margin-bottom: 8px;
}
h1, h2, h3, h4, h5, h6 {
margin-bottom: 16px;
color: var(--text-primary);
font-weight: 600;
line-height: 1.3;
}
h1 {
font-size: 2.5rem;
font-weight: 700;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
p {
margin-bottom: 16px;
color: var(--text-secondary);
line-height: 1.7;
}
a {
color: var(--text-primary);
text-decoration: underline;
text-decoration-color: var(--e2c-yellow);
text-underline-offset: 3px;
transition: all 0.2s ease;
}
a:hover {
color: var(--text-primary);
text-decoration-color: var(--e2c-dark-yellow);
}
.btn {
display: inline-block;
padding: 12px 24px;
background: var(--e2c-yellow);
color: var(--text-primary);
text-decoration: none;
border-radius: 24px;
margin: 8px 0;
font-weight: 500;
font-size: 15px;
transition: all 0.2s ease;
border: 2px solid var(--e2c-yellow);
}
.btn:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
color: var(--text-primary);
transform: translateY(-1px);
}
.card {
background: var(--card-background);
border: 1px solid var(--border);
border-radius: 16px;
padding: 24px;
margin-bottom: 24px;
box-shadow: 0 4px 12px var(--shadow);
transition: all 0.2s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px var(--shadow);
}
.grid {
display: grid;
gap: 24px;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.hero {
text-align: center;
padding: 64px 0;
background: linear-gradient(135deg, var(--background) 0%, #F8F9FA 100%);
border-radius: 24px;
margin-bottom: 48px;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 24px;
background: linear-gradient(135deg, var(--text-primary) 0%, var(--text-secondary) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero p {
font-size: 1.25rem;
max-width: 600px;
margin: 0 auto 32px;
}
.hero-section {
background: var(--e2c-yellow);
padding: 4rem 2rem;
margin: 0 0 3rem 0;
border-radius: 24px;
}
<!-- Open Graph / Social Media Meta Tags -->
<meta property="og:title" content="{{ if and .Title (ne .Title .Site.Title) }}{{ .Title }} - {{ end }}{{ .Site.Title }}">
<meta property="og:description" content="{{ .Description | default .Site.Params.description }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ .Permalink }}">
{{ if .Params.image }}<meta property="og:image" content="{{ .Site.BaseURL }}{{ .Params.image }}">{{ end }}
{{ if .Params.banner }}<meta property="og:image" content="{{ .Site.BaseURL }}{{ .Params.banner }}">{{ end }}
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ if and .Title (ne .Title .Site.Title) }}{{ .Title }} - {{ end }}{{ .Site.Title }}">
<meta name="twitter:description" content="{{ .Description | default .Site.Params.description }}">
{{ if .Params.image }}<meta name="twitter:image" content="{{ .Site.BaseURL }}{{ .Params.image }}">{{ end }}
{{ if .Params.banner }}<meta name="twitter:image" content="{{ .Site.BaseURL }}{{ .Params.banner }}">{{ end }}
<link rel="stylesheet" href="/css/main.css">
.hero-content {
display: flex;
align-items: center;
gap: 3rem;
max-width: 1200px;
margin: 0 auto;
}
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.medlab.host/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '6']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
.hero-image {
width: 300px;
height: auto;
border-radius: 16px;
}
.hero-text h1 {
font-size: 3rem;
margin: 0 0 1rem 0;
color: var(--text-primary);
}
.hero-text p {
font-size: 1.25rem;
margin: 0;
color: var(--text-primary);
}
.intro-section {
margin: 3rem 0;
text-align: center;
}
.intro-section h2 {
color: var(--e2c-yellow);
margin-bottom: 1rem;
}
.intro-section ul {
list-style: none;
padding: 0;
margin: 2rem 0;
display: grid;
gap: 12px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
.intro-section ul li {
background: var(--e2c-yellow);
color: var(--text-primary);
padding: 16px 20px;
border-radius: 12px;
font-weight: 500;
text-align: center;
line-height: 1.4;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}
.intro-section ul li:hover {
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
.cards-grid {
display: grid;
gap: 24px;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
margin: 3rem 0;
}
.card .button {
display: inline-block;
padding: 12px 24px;
background: var(--e2c-yellow);
color: var(--text-primary);
text-decoration: none;
border-radius: 24px;
margin-top: 16px;
font-weight: 500;
font-size: 15px;
transition: all 0.2s ease;
border: 2px solid var(--e2c-yellow);
}
.card .button:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
transform: translateY(-1px);
}
.partnership-section {
text-align: center;
margin: 4rem 0;
padding: 2rem;
background: #F8F9FA;
border-radius: 16px;
}
.partnership-image {
width: 200px;
height: auto;
border-radius: 16px;
margin-bottom: 1rem;
}
.main-sections {
margin: 4rem 0;
}
.main-sections h2 {
text-align: center;
color: var(--text-primary);
margin-bottom: 2rem;
font-size: 2.5rem;
}
.primary-cards {
display: grid;
gap: 32px;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
margin-bottom: 2rem;
}
.primary-card {
background: var(--card-background);
border: 2px solid var(--e2c-yellow);
border-radius: 20px;
padding: 32px;
text-align: center;
box-shadow: 0 8px 24px var(--shadow);
transition: all 0.3s ease;
}
.primary-card:hover {
transform: translateY(-4px);
box-shadow: 0 16px 40px var(--shadow);
border-color: var(--e2c-dark-yellow);
}
.primary-card h3 {
font-size: 1.5rem;
color: var(--text-primary);
margin-bottom: 1rem;
}
.primary-card p {
color: var(--text-secondary);
margin-bottom: 1.5rem;
}
.secondary-actions {
margin: 3rem 0;
padding: 2rem;
background: #F8F9FA;
border-radius: 16px;
}
.secondary-actions h3 {
text-align: center;
color: var(--text-primary);
margin-bottom: 1.5rem;
font-size: 1.5rem;
}
.secondary-cards {
display: grid;
gap: 24px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.secondary-card {
background: var(--card-background);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
text-align: center;
transition: all 0.2s ease;
}
.secondary-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px var(--shadow);
}
.secondary-card h4 {
font-size: 1.1rem;
color: var(--text-primary);
margin-bottom: 0.5rem;
}
.secondary-card p {
color: var(--text-secondary);
margin-bottom: 1rem;
font-size: 0.9rem;
}
.secondary-button {
display: inline-block;
padding: 8px 16px;
background: transparent;
color: var(--text-primary);
text-decoration: none;
border: 1px solid var(--border);
border-radius: 16px;
font-weight: 500;
font-size: 14px;
transition: all 0.2s ease;
}
.secondary-button:hover {
background: var(--e2c-yellow);
border-color: var(--e2c-yellow);
transform: translateY(-1px);
}
/* Hide auto-generated cards on homepage only */
.home .grid {
display: none !important;
}
/* Case study logo styling */
.case-logo {
width: 64px;
height: 64px;
object-fit: contain;
border-radius: 8px;
margin-bottom: 16px;
background: rgba(255, 255, 255, 0.9);
padding: 8px;
border: 1px solid var(--border);
}
/* Case study detail page logo */
.case-detail-logo {
width: 120px;
height: 120px;
object-fit: contain;
border-radius: 16px;
margin-bottom: 24px;
background: rgba(255, 255, 255, 0.9);
padding: 16px;
border: 1px solid var(--border);
box-shadow: 0 4px 12px var(--shadow);
}
@media (max-width: 768px) {
.nav-links {
gap: 6px;
flex-wrap: wrap;
}
.nav-links a {
padding: 6px 10px;
font-size: 12px;
border-radius: 16px;
}
.logo {
font-size: 0.9rem;
padding: 5px 10px;
}
.logo img {
height: 24px;
margin-right: 5px;
}
.site-header {
padding: 8px 0;
min-height: 48px;
}
.hero h1 {
font-size: 2.5rem;
}
.hero p {
font-size: 1.1rem;
}
.container {
padding: 0 16px;
}
.hero-content {
flex-direction: column;
text-align: center;
}
.hero-image {
width: 200px;
}
.hero-text h1 {
font-size: 2rem;
}
.hero-section {
margin: 0 0.5rem 2rem 0.5rem;
padding: 2rem 1rem;
}
.primary-cards {
grid-template-columns: 1fr;
}
.footer-content {
grid-template-columns: 1fr;
gap: 32px;
text-align: center;
}
.footer-links {
text-align: center;
}
.custom-newsletter-form .form-group {
flex-direction: column;
gap: 12px;
}
.subscribe-btn {
align-self: center;
min-width: 120px;
}
}
@media (min-width: 769px) and (max-width: 1024px) {
.primary-cards {
grid-template-columns: 1fr;
}
}
/* Contact Form Styling */
.contact-form-container {
max-width: 500px;
margin: 2rem auto;
padding: 2rem;
background: var(--card-background);
border-radius: 16px;
box-shadow: 0 4px 12px var(--shadow);
border: 1px solid var(--border);
}
.e2c-contact-form .form-group {
margin-bottom: 1.5rem;
}
.e2c-contact-form label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: var(--text-primary);
font-size: 14px;
}
.e2c-contact-form input[type="text"],
.e2c-contact-form input[type="email"],
.e2c-contact-form input[type="url"],
.e2c-contact-form select,
.e2c-contact-form textarea {
width: 100%;
padding: 12px 16px;
border: 1px solid var(--border);
border-radius: 8px;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
background: var(--background);
color: var(--text-primary);
transition: all 0.2s ease;
}
.e2c-contact-form input:focus,
.e2c-contact-form select:focus,
.e2c-contact-form textarea:focus {
outline: none;
border-color: var(--e2c-yellow);
box-shadow: 0 0 0 2px rgba(244, 208, 63, 0.2);
}
.e2c-contact-form textarea {
resize: vertical;
min-height: 100px;
}
.checkbox-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.checkbox-label {
display: flex !important;
align-items: center;
gap: 0.5rem;
font-weight: 400 !important;
margin-bottom: 0 !important;
cursor: pointer;
}
.e2c-contact-form input[type="checkbox"],
.e2c-contact-form input[type="radio"] {
width: auto;
margin: 0;
accent-color: var(--e2c-yellow);
}
.submit-btn {
width: 100%;
padding: 14px 24px;
background: var(--e2c-yellow);
color: var(--text-primary);
border: 2px solid var(--e2c-yellow);
border-radius: 24px;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 600;
font-size: 16px;
cursor: pointer;
transition: all 0.2s ease;
}
.submit-btn:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
@media (max-width: 768px) {
.contact-form-container {
margin: 1rem;
padding: 1.5rem;
}
}
</style>
</head>
<body>
<header class="site-header">
@@ -762,6 +48,11 @@
<a href="/" class="logo">
<img src="/img/yellow_e2c.png" alt="Exit to Community" />
</a>
<button class="mobile-menu-toggle" aria-label="Toggle mobile menu">
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
<span class="hamburger-line"></span>
</button>
<ul class="nav-links">
<li><a href="/case-studies/">Case Studies</a></li>
<li><a href="/legal-snippets/">Legal Snippets</a></li>
@@ -772,6 +63,8 @@
</div>
</header>
<div class="mobile-menu-overlay"></div>
<main>
<div class="container">
{{ block "main" . }}{{ end }}
@@ -786,30 +79,35 @@
<div class="newsletter-signup">
<!-- Action Network Email Subscription Form -->
<div id="e2c-newsletter-form">
<form class="custom-newsletter-form" action="#" method="post">
<div class="form-group">
<input type="email" name="email" placeholder="Enter your email" required class="email-input">
<button type="submit" class="subscribe-btn">Subscribe</button>
</div>
</form>
<link href='https://actionnetwork.org/css/style-embed-v3.css' rel='stylesheet' type='text/css' />
<script src='https://actionnetwork.org/widgets/v3/form/e2c-website-newsletter-form?format=js&source=widget&clear_id=true'></script>
<div id='can-form-area-e2c-website-newsletter-form' style='width: 100%'></div>
<!-- Fallback for no-JS -->
<noscript>
<form class="custom-newsletter-form" action="https://actionnetwork.org/forms/e2c-website-newsletter-form" method="post">
<div class="form-group">
<input type="email" name="person[email]" placeholder="Enter your email" required class="email-input">
<button type="submit" class="subscribe-btn">Subscribe</button>
</div>
</form>
</noscript>
</div>
<!-- Replace the above form with actual Action Network embed code -->
<!--
<link href='https://actionnetwork.org/css/style-embed-v3.css' rel='stylesheet' type='text/css' />
<script src='https://actionnetwork.org/widgets/v3/form/YOUR_FORM_ID?format=js&source=widget&clear_id=true'></script>
<div id='can-form-area-YOUR_FORM_ID' style='width: 100%'></div>
-->
</div>
</div>
<div class="footer-section">
<div class="footer-links">
<p>&copy; {{ now.Year }} <a href="/contact">E2C Collective</a><br />
<p>&copy; {{ now.Year }} E2C Collective<br />
<a href="https://opencollective.com/e2c-c">Learn more and support us &#128151;</a><br />
In collaboration with <a href="https://www.colorado.edu/lab/medlab/exit-to-community">MEDLab at CU Boulder</a><br />
This work is licensed under a Creative Commons Attribution 4.0 License</p>
<p><a href="/contact">Connect with us</a></p>
</div>
</div>
</div>
</div>
</footer>
<script src="/js/mobile-menu.js"></script>
</body>
</html>

View File

@@ -9,14 +9,37 @@
{{ if .Pages }}
<div class="filter-controls">
<div class="filter-row">
<input type="text" id="searchInput" placeholder="Search titles and descriptions..." class="search-input">
<select id="tagFilter" class="tag-filter">
<option value="">All tags</option>
</select>
<select id="sortBy" class="sort-select">
<option value="title">Sort by Title</option>
<option value="date">Sort by Date</option>
</select>
<input type="text" id="searchInput" placeholder="Search full text..." class="search-input">
<div class="tag-filter-container">
<div id="tagDropdown" class="tag-dropdown">
<div class="tag-dropdown-trigger">
<span class="dropdown-label">Select tags</span>
<div class="selected-tags" id="selectedTags"></div>
<svg class="dropdown-arrow" width="12" height="8" viewBox="0 0 12 8" fill="none">
<path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="tag-dropdown-menu" id="tagDropdownMenu">
<div class="tag-options" id="tagOptions">
<!-- Tags will be populated here -->
</div>
</div>
</div>
</div>
<div class="sort-container">
<div id="sortDropdown" class="sort-dropdown">
<div class="sort-dropdown-trigger">
<span class="sort-label">Sort by Title</span>
<svg class="dropdown-arrow" width="12" height="8" viewBox="0 0 12 8" fill="none">
<path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="sort-dropdown-menu" id="sortDropdownMenu">
<div class="sort-option" data-value="title">Sort by Title</div>
<div class="sort-option" data-value="date">Sort by Date</div>
</div>
</div>
</div>
</div>
</div>
<div class="grid" id="cardGrid">
@@ -24,12 +47,24 @@
<div class="card"
data-title="{{ .Title }}"
data-description="{{ if .Description }}{{ .Description }}{{ else if .Summary }}{{ .Summary | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}{{ else }}{{ .Content | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" | truncate 200 }}{{ end }}"
data-content="{{ .Content | plainify | replaceRE "^### \\*\\*Summary\\*\\*\\s*" "" }}"
data-tags="{{ if .Params.tags }}{{ delimit .Params.tags "," }}{{ end }}"
data-date="{{ .Date.Format "2006-01-02" }}">
{{ if .Params.image }}
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-logo" />
{{ if .Params.banner }}
<a href="{{ .RelPermalink }}" class="card-banner-link">
<div class="card-banner">
<img src="{{ .Params.banner }}" alt="{{ .Title }} banner" class="case-banner" />
{{ if .Params.image }}
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-logo-overlay" />
{{ end }}
</div>
</a>
{{ else if .Params.image }}
<a href="{{ .RelPermalink }}" class="card-logo-link">
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-logo" />
</a>
{{ end }}
<h3><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
<h3><a href="{{ .RelPermalink }}" class="card-title-link">{{ .Title }}</a></h3>
{{ if .Description }}
<p>{{ .Description }}</p>
{{ else if .Summary }}
@@ -40,11 +75,10 @@
{{ if .Params.tags }}
<div class="tags">
{{ range .Params.tags }}
<span class="tag">{{ . }}</span>
<a href="?tag={{ . | urlize }}" class="tag">{{ . }}</a>
{{ end }}
</div>
{{ end }}
<a href="{{ .RelPermalink }}" class="btn">Read More</a>
</div>
{{ end }}
</div>
@@ -73,9 +107,9 @@
align-items: center;
}
.search-input, .tag-filter, .sort-select {
.search-input {
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 500;
font-weight: 400;
font-size: 14px;
padding: 10px 16px;
border: 1px solid var(--border);
@@ -84,14 +118,11 @@
backdrop-filter: blur(8px);
transition: all 0.2s ease;
color: var(--text-primary);
}
.search-input {
flex: 1;
min-width: 280px;
}
.search-input:focus, .tag-filter:focus, .sort-select:focus {
.search-input:focus {
outline: none;
border-color: var(--e2c-yellow);
background: var(--e2c-yellow);
@@ -100,14 +131,230 @@
}
.search-input::placeholder {
color: var(--text-secondary);
color: var(--text-primary);
font-weight: 400;
}
.tag-filter, .sort-select {
/* Custom Multi-Select Dropdown */
.tag-filter-container {
position: relative;
min-width: 200px;
}
.tag-dropdown {
position: relative;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.tag-dropdown-trigger {
display: flex;
align-items: center;
padding: 10px 16px;
border: 1px solid var(--border);
border-radius: 24px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(8px);
cursor: pointer;
transition: all 0.2s ease;
color: var(--text-primary);
font-size: 14px;
font-weight: 400;
min-height: 20px;
}
.tag-dropdown-trigger:hover, .tag-dropdown.open .tag-dropdown-trigger {
border-color: var(--e2c-yellow);
background: var(--e2c-yellow);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.dropdown-label {
flex: 1;
color: var(--text-primary);
font-weight: 400;
white-space: nowrap;
}
.tag-dropdown.has-selection .dropdown-label {
display: none;
}
.selected-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
flex: 1;
min-height: 20px;
}
.selected-tag {
background: var(--text-primary);
color: white;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
display: flex;
align-items: center;
gap: 4px;
}
.selected-tag .remove {
cursor: pointer;
font-weight: bold;
font-size: 14px;
line-height: 1;
opacity: 0.8;
}
.selected-tag .remove:hover {
opacity: 1;
}
.dropdown-arrow {
margin-left: 8px;
transition: transform 0.2s ease;
flex-shrink: 0;
}
.tag-dropdown.open .dropdown-arrow {
transform: rotate(180deg);
}
.tag-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--card-background);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 8px 24px var(--shadow);
z-index: 1000;
max-height: 200px;
overflow-y: auto;
opacity: 0;
visibility: hidden;
transform: translateY(-4px);
transition: all 0.2s ease;
margin-top: 4px;
}
.tag-dropdown.open .tag-dropdown-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.tag-option {
display: flex;
align-items: center;
padding: 8px 12px;
cursor: pointer;
font-size: 14px;
color: var(--text-primary);
transition: background-color 0.15s ease;
}
.tag-option:hover {
background: rgba(244, 208, 63, 0.1);
}
.tag-option input[type="checkbox"] {
margin-right: 8px;
accent-color: var(--e2c-yellow);
}
.tag-option.selected {
background: rgba(244, 208, 63, 0.15);
font-weight: 500;
}
/* Custom Sort Dropdown */
.sort-container {
position: relative;
min-width: 160px;
}
.sort-dropdown {
position: relative;
font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.sort-dropdown-trigger {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border: 1px solid var(--border);
border-radius: 24px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(8px);
cursor: pointer;
transition: all 0.2s ease;
color: var(--text-primary);
font-size: 14px;
font-weight: 400;
min-height: 20px;
}
.sort-dropdown-trigger:hover, .sort-dropdown.open .sort-dropdown-trigger {
border-color: var(--e2c-yellow);
background: var(--e2c-yellow);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.sort-label {
flex: 1;
white-space: nowrap;
}
.sort-dropdown.open .dropdown-arrow {
transform: rotate(180deg);
}
.sort-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--card-background);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 8px 24px var(--shadow);
z-index: 1000;
opacity: 0;
visibility: hidden;
transform: translateY(-4px);
transition: all 0.2s ease;
margin-top: 4px;
}
.sort-dropdown.open .sort-dropdown-menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.sort-option {
padding: 8px 12px;
cursor: pointer;
font-size: 14px;
color: var(--text-primary);
transition: background-color 0.15s ease;
}
.sort-option:hover {
background: rgba(244, 208, 63, 0.1);
}
.sort-option.selected {
background: rgba(244, 208, 63, 0.15);
font-weight: 500;
}
.tags {
margin-top: 0.5rem;
}
@@ -120,6 +367,36 @@
margin: 0.25rem 0.25rem 0 0;
border-radius: 0.25rem;
font-size: 0.875rem;
text-decoration: none;
transition: all 0.2s ease;
}
.tag:hover {
background: var(--e2c-yellow);
color: var(--text-primary);
transform: translateY(-1px);
}
.card-title-link {
display: inline-block;
padding: 8px 16px;
background: var(--e2c-yellow);
color: var(--text-primary) !important;
text-decoration: none !important;
border-radius: 12px;
margin: 8px 0;
font-weight: 600;
font-size: 1.25rem;
transition: all 0.2s ease;
border: 2px solid var(--e2c-yellow);
}
.card-title-link:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
color: var(--text-primary) !important;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.card {
@@ -130,6 +407,40 @@
display: none;
}
.card-banner {
position: relative;
margin-bottom: 1rem;
border-radius: 12px;
overflow: hidden;
aspect-ratio: 16/9;
}
.case-banner {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.card-banner-link, .card-logo-link {
display: block;
text-decoration: none;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.card-banner-link:hover, .card-logo-link:hover {
transform: translateY(-2px);
}
.card-banner-link:hover .card-banner {
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.card-logo-link:hover .case-logo {
transform: scale(1.05);
}
@media (max-width: 768px) {
.filter-controls {
margin-bottom: 32px;
@@ -142,23 +453,65 @@
gap: 12px;
}
.search-input, .tag-filter, .sort-select {
.search-input {
width: 100%;
min-width: unset;
padding: 8px 14px;
font-size: 12px;
}
.tag-filter-container, .sort-container {
min-width: unset;
width: 100%;
}
.sort-dropdown-trigger {
padding: 8px 14px;
font-size: 12px;
}
.tag-dropdown-trigger {
padding: 8px 14px;
font-size: 12px;
}
.selected-tag {
font-size: 11px;
padding: 1px 6px;
}
.tag-dropdown-menu {
left: -4px;
right: -4px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('searchInput');
const tagFilter = document.getElementById('tagFilter');
const sortBy = document.getElementById('sortBy');
const tagDropdown = document.getElementById('tagDropdown');
const tagDropdownTrigger = tagDropdown.querySelector('.tag-dropdown-trigger');
const tagDropdownMenu = document.getElementById('tagDropdownMenu');
const tagOptions = document.getElementById('tagOptions');
const selectedTagsContainer = document.getElementById('selectedTags');
const sortDropdown = document.getElementById('sortDropdown');
const sortDropdownTrigger = sortDropdown.querySelector('.sort-dropdown-trigger');
const sortDropdownMenu = document.getElementById('sortDropdownMenu');
const sortLabel = sortDropdown.querySelector('.sort-label');
const cardGrid = document.getElementById('cardGrid');
const cards = Array.from(cardGrid.querySelectorAll('.card'));
let selectedTags = new Set();
let currentSort = 'title';
// Check for URL parameter to pre-filter by tag
const urlParams = new URLSearchParams(window.location.search);
const preSelectedTag = urlParams.get('tag');
if (preSelectedTag) {
selectedTags.add(preSelectedTag);
}
// Collect all unique tags
const allTags = new Set();
cards.forEach(card => {
@@ -168,35 +521,154 @@ document.addEventListener('DOMContentLoaded', function() {
}
});
// Populate tag filter dropdown
Array.from(allTags).sort().forEach(tag => {
const option = document.createElement('option');
option.value = tag;
option.textContent = tag;
tagFilter.appendChild(option);
// Populate tag dropdown
function populateTagOptions() {
tagOptions.innerHTML = '';
Array.from(allTags).sort().forEach(tag => {
const option = document.createElement('div');
option.className = 'tag-option';
option.innerHTML = `
<input type="checkbox" ${selectedTags.has(tag) ? 'checked' : ''}>
<span>${tag}</span>
`;
const checkbox = option.querySelector('input');
checkbox.addEventListener('change', function() {
if (checkbox.checked) {
selectedTags.add(tag);
} else {
selectedTags.delete(tag);
}
updateSelectedTagsDisplay();
filterAndSort();
updateURL();
});
tagOptions.appendChild(option);
});
}
// Update selected tags display
function updateSelectedTagsDisplay() {
selectedTagsContainer.innerHTML = '';
if (selectedTags.size > 0) {
tagDropdown.classList.add('has-selection');
selectedTags.forEach(tag => {
const tagElement = document.createElement('div');
tagElement.className = 'selected-tag';
tagElement.innerHTML = `
<span>${tag}</span>
<span class="remove">×</span>
`;
tagElement.querySelector('.remove').addEventListener('click', function(e) {
e.stopPropagation();
selectedTags.delete(tag);
updateSelectedTagsDisplay();
updateTagOptionStates();
filterAndSort();
updateURL();
});
selectedTagsContainer.appendChild(tagElement);
});
} else {
tagDropdown.classList.remove('has-selection');
}
}
// Update checkbox states in dropdown
function updateTagOptionStates() {
const checkboxes = tagOptions.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach((checkbox, index) => {
const tag = Array.from(allTags).sort()[index];
checkbox.checked = selectedTags.has(tag);
checkbox.parentElement.classList.toggle('selected', selectedTags.has(tag));
});
}
// Toggle dropdown
tagDropdownTrigger.addEventListener('click', function(e) {
e.stopPropagation();
tagDropdown.classList.toggle('open');
});
// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
if (!tagDropdown.contains(e.target)) {
tagDropdown.classList.remove('open');
}
if (!sortDropdown.contains(e.target)) {
sortDropdown.classList.remove('open');
}
});
// Sort dropdown functionality
sortDropdownTrigger.addEventListener('click', function(e) {
e.stopPropagation();
sortDropdown.classList.toggle('open');
tagDropdown.classList.remove('open'); // Close other dropdown
});
// Sort option selection
sortDropdownMenu.addEventListener('click', function(e) {
if (e.target.classList.contains('sort-option')) {
const value = e.target.dataset.value;
const text = e.target.textContent;
// Update current sort
currentSort = value;
sortLabel.textContent = text;
// Update selected state
sortDropdownMenu.querySelectorAll('.sort-option').forEach(option => {
option.classList.remove('selected');
});
e.target.classList.add('selected');
// Close dropdown and filter
sortDropdown.classList.remove('open');
filterAndSort();
}
});
// Update URL with selected tags
function updateURL() {
const url = new URL(window.location);
if (selectedTags.size > 0) {
url.searchParams.set('tag', Array.from(selectedTags)[0]); // For simplicity, just use first tag in URL
} else {
url.searchParams.delete('tag');
}
window.history.replaceState({}, '', url);
}
function filterAndSort() {
const searchTerm = searchInput.value.toLowerCase();
const selectedTag = tagFilter.value;
const sortCriteria = sortBy.value;
const sortCriteria = currentSort;
// Filter cards
const filteredCards = cards.filter(card => {
const title = card.dataset.title.toLowerCase();
const description = card.dataset.description.toLowerCase();
const content = card.dataset.content.toLowerCase();
const tags = card.dataset.tags;
// Text search
// Full text search - search in title, description, and content
const matchesSearch = !searchTerm ||
title.includes(searchTerm) ||
description.includes(searchTerm);
description.includes(searchTerm) ||
content.includes(searchTerm);
// Tag filter
const matchesTag = !selectedTag ||
(tags && tags.split(',').map(t => t.trim()).includes(selectedTag));
// Tag filter - must match ALL selected tags
const matchesTags = selectedTags.size === 0 ||
(tags && Array.from(selectedTags).every(selectedTag =>
tags.split(',').map(t => t.trim()).includes(selectedTag)
));
return matchesSearch && matchesTag;
return matchesSearch && matchesTags;
});
// Sort filtered cards
@@ -223,10 +695,15 @@ document.addEventListener('DOMContentLoaded', function() {
// Event listeners
searchInput.addEventListener('input', filterAndSort);
tagFilter.addEventListener('change', filterAndSort);
sortBy.addEventListener('change', filterAndSort);
// Initial sort by title
// Initialize
populateTagOptions();
updateSelectedTagsDisplay();
updateTagOptionStates();
// Initialize sort dropdown
sortDropdownMenu.querySelector('[data-value="title"]').classList.add('selected');
filterAndSort();
});
</script>

View File

@@ -1,7 +1,14 @@
{{ define "main" }}
<article>
<header class="article-header">
{{ if .Params.image }}
{{ if .Params.banner }}
<div class="article-banner">
<img src="{{ .Params.banner }}" alt="{{ .Title }} banner" class="case-detail-banner" />
{{ if .Params.image }}
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-detail-logo-overlay" />
{{ end }}
</div>
{{ else if .Params.image }}
<img src="{{ .Params.image }}" alt="{{ .Title }} logo" class="case-detail-logo" />
{{ end }}
<h1>{{ .Title }}</h1>
@@ -14,80 +21,27 @@
{{ if .Date }}
<p><small>Last updated: {{ .Date.Format "January 2, 2006" }}</small></p>
{{ end }}
{{ if .Params.tags }}
<div class="tags">
{{ range .Params.tags }}
<span class="tag">{{ . }}</span>
<div class="tags-and-button">
{{ if .Params.external_url }}
<div class="article-external-button"><a href="{{ .Params.external_url }}" target="_blank" class="btn">Website</a></div>
{{ else if .Params.url_external }}
<div class="article-external-button"><a href="{{ .Params.url_external }}" target="_blank" class="btn">Website</a></div>
{{ end }}
{{ if .Params.tags }}
<div class="tags">
{{ range .Params.tags }}
<a href="/{{ $.Section }}/?tag={{ . | urlize }}" class="tag">{{ . }}</a>
{{ end }}
</div>
{{ end }}
</div>
{{ end }}
</header>
<div class="article-content">
{{ .Content }}
</div>
{{ if .Params.external_url }}
<p><a href="{{ .Params.external_url }}" target="_blank" class="btn">Visit External Site</a></p>
{{ end }}
</article>
{{ partial "explore-e2c.html" . }}
<style>
.lead {
font-size: 1.125rem;
color: #666;
margin-bottom: 1rem;
}
.article-header {
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid #e9ecef;
}
.article-content {
margin-bottom: 2rem;
}
.article-content h2,
.article-content h3,
.article-content h4 {
margin-top: 2rem;
margin-bottom: 1rem;
}
.article-nav {
display: flex;
justify-content: space-between;
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid #e9ecef;
}
.article-nav a {
text-decoration: none;
color: #007bff;
padding: 0.5rem 0;
}
.article-nav a:hover {
color: #0056b3;
}
.tags {
margin: 0.5rem 0;
}
.tag {
display: inline-block;
background: #e9ecef;
color: #495057;
padding: 0.25rem 0.5rem;
margin: 0.25rem 0.25rem 0 0;
border-radius: 0.25rem;
font-size: 0.875rem;
}
</style>
{{ end }}

View File

@@ -1,3 +1,146 @@
{{ define "main" }}
{{ .Content }}
{{ partial "explore-e2c.html" . }}
<style>
.featured-cases-section {
margin: 4rem 0;
padding: 3rem 0;
background: rgba(244, 208, 63, 0.05);
border-radius: 24px;
}
.featured-cases-section h2 {
text-align: center;
margin-bottom: 1rem;
color: var(--text-primary);
font-size: 2.5rem;
font-weight: 600;
}
.featured-cases-section p {
text-align: center;
margin-bottom: 2.5rem;
color: var(--text-secondary);
font-size: 1.125rem;
}
.featured-cases-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
.featured-case-card {
background: var(--card-background);
border-radius: 16px;
overflow: hidden;
box-shadow: 0 4px 12px var(--shadow);
transition: opacity 0.3s ease, transform 0.3s ease;
position: relative;
border: 1px solid var(--border);
}
.featured-case-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
.featured-card-banner {
position: relative;
margin-bottom: 1rem;
border-radius: 12px;
overflow: hidden;
aspect-ratio: 16/9;
}
.featured-case-banner {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.featured-case-logo {
width: 100%;
height: 200px;
object-fit: contain;
display: block;
padding: 1rem;
background: #f8f9fa;
}
.featured-case-content {
padding: 0 1.5rem 1.5rem 1.5rem;
}
.featured-case-title {
display: inline-block;
padding: 8px 16px;
background: var(--e2c-yellow);
color: var(--text-primary);
text-decoration: none;
border-radius: 12px;
margin: 8px 0;
font-weight: 600;
font-size: 1.1rem;
transition: all 0.2s ease;
border: 2px solid var(--e2c-yellow);
}
.featured-case-title:hover {
background: var(--e2c-dark-yellow);
border-color: var(--e2c-dark-yellow);
color: var(--text-primary);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.featured-case-description {
color: var(--text-secondary);
font-size: 0.95rem;
line-height: 1.5;
margin-top: 1rem;
}
.featured-case-link {
display: block;
text-decoration: none;
color: inherit;
}
.featured-banner-link {
display: block;
text-decoration: none;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.featured-banner-link:hover {
transform: translateY(-2px);
}
@media (max-width: 768px) {
.featured-cases-grid {
grid-template-columns: 1fr;
gap: 1.5rem;
padding: 0 1rem;
}
.featured-cases-section {
margin: 2rem 0;
padding: 2rem 0;
}
.featured-cases-section h2 {
font-size: 2rem;
}
}
</style>
{{ partial "homepage-scripts.html" . }}
{{ end }}

View File

@@ -0,0 +1,20 @@
<div class="main-sections">
<h2>Explore E2C</h2>
<div class="primary-cards">
<div class="primary-card">
<h3>Case Studies</h3>
<p>Real examples of companies that have attempted or achieved community ownership transitions</p>
<a href="/case-studies/" class="btn">Explore Cases</a>
</div>
<div class="primary-card">
<h3>Legal Snippets</h3>
<p>Legal documents and frameworks for implementing community ownership structures</p>
<a href="/legal-snippets/" class="btn">Explore Legal Snippets</a>
</div>
<div class="primary-card">
<h3>Resources</h3>
<p>Educational materials, primers, and guides for Exit to Community transitions</p>
<a href="/resources/" class="btn">Explore Resources</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,65 @@
<script>
document.addEventListener('DOMContentLoaded', function() {
// Case studies data - this will be populated by Hugo
const caseStudies = [
{{ range where .Site.Pages "Section" "case-studies" }}
{{ if and .Params.image .Title (ne .Title "Case Studies") }}
{
title: "{{ .Title | replaceRE `"` `\"` }}",
description: "{{ if .Description }}{{ .Description | replaceRE `"` `\"` }}{{ else }}{{ .Summary | plainify | truncate 150 | replaceRE `"` `\"` }}{{ end }}",
url: "{{ .RelPermalink }}",
image: "{{ .Params.image }}",
banner: {{ if .Params.banner }}"{{ .Params.banner }}"{{ else }}null{{ end }}
},
{{ end }}
{{ end }}
].filter(study => study.title); // Remove any empty entries
// Function to shuffle array and get random selection
function getRandomCases(cases, count = 3) {
const shuffled = [...cases].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
}
// Function to create case card HTML
function createCaseCard(caseStudy) {
const hasImage = caseStudy.image && caseStudy.image !== 'null' && caseStudy.image !== null;
const hasBanner = caseStudy.banner && caseStudy.banner !== 'null' && caseStudy.banner !== null;
let imageHTML = '';
if (hasBanner) {
imageHTML = `
<a href="${caseStudy.url}" class="featured-banner-link">
<div class="featured-card-banner">
<img src="${caseStudy.banner}" alt="${caseStudy.title} banner" class="featured-case-banner" />
${hasImage ? `<img src="${caseStudy.image}" alt="${caseStudy.title} logo" class="case-logo-overlay" />` : ''}
</div>
</a>
`;
} else if (hasImage) {
imageHTML = `
<a href="${caseStudy.url}" class="featured-banner-link">
<img src="${caseStudy.image}" alt="${caseStudy.title} logo" class="featured-case-logo" />
</a>
`;
}
return `
<div class="featured-case-card">
${imageHTML}
<div class="featured-case-content">
<h3><a href="${caseStudy.url}" class="featured-case-title">${caseStudy.title}</a></h3>
<p class="featured-case-description">${caseStudy.description}</p>
</div>
</div>
`;
}
// Populate featured cases
const featuredCasesGrid = document.getElementById('featuredCasesGrid');
if (featuredCasesGrid && caseStudies.length > 0) {
const randomCases = getRandomCases(caseStudies, 3);
featuredCasesGrid.innerHTML = randomCases.map(createCaseCard).join('');
}
});
</script>

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "e2c-how",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

1
package.json Normal file
View File

@@ -0,0 +1 @@
{}

1080
static/css/main.css Normal file

File diff suppressed because it is too large Load Diff

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

BIN
static/img/banners/cmx.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
static/img/banners/dada.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
static/img/banners/ens.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
static/img/banners/juno.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
static/img/banners/nio.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 KiB

50
static/js/mobile-menu.js Normal file
View File

@@ -0,0 +1,50 @@
// Mobile Menu Functionality
document.addEventListener('DOMContentLoaded', function() {
const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
const navLinks = document.querySelector('.nav-links');
const overlay = document.querySelector('.mobile-menu-overlay');
const body = document.body;
function toggleMenu() {
const isActive = mobileMenuToggle.classList.contains('active');
if (isActive) {
mobileMenuToggle.classList.remove('active');
navLinks.classList.remove('active');
overlay.classList.remove('active');
body.classList.remove('menu-open');
} else {
mobileMenuToggle.classList.add('active');
navLinks.classList.add('active');
overlay.classList.add('active');
body.classList.add('menu-open');
}
}
function closeMenu() {
mobileMenuToggle.classList.remove('active');
navLinks.classList.remove('active');
overlay.classList.remove('active');
body.classList.remove('menu-open');
}
if (mobileMenuToggle && navLinks && overlay) {
mobileMenuToggle.addEventListener('click', toggleMenu);
// Close menu when clicking on overlay
overlay.addEventListener('click', closeMenu);
// Close menu when clicking on a link
const navLinksItems = navLinks.querySelectorAll('a');
navLinksItems.forEach(link => {
link.addEventListener('click', closeMenu);
});
// Close menu on escape key
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeMenu();
}
});
}
});

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB