Compare commits

..

No commits in common. "9f71d346e9a4c9daaaeead732f6d1c2f2b4e3690" and "5cdbb76ab7f2f9a410ddf09f18e0c6613263a749" have entirely different histories.

13 changed files with 46 additions and 32 deletions

View file

@ -6,9 +6,9 @@
* Unseen, always working, connects every entity (the mycelium). * Unseen, always working, connects every entity (the mycelium).
* Flowers the three experiences people actually engage with: * Flowers the three experiences people actually engage with:
* SolLunar Punk Society (city center) a permanent bloom * SolLunar Punk Society (city center) a permanent bloom
* Pop-up Summit Gatherings (travelling) ephemeral cluster * Pop-up Festivals (travelling) ephemeral cluster
* Château du Faune (farm center) a permanent bloom * Château du Faune (farm center) a permanent bloom
* Ghost flowers once the mycelium runs, new locations & summit gatherings sprout * Ghost flowers once the mycelium runs, new locations & festivals sprout
* cheaply, anywhere in the world. * cheaply, anywhere in the world.
* *
* Pure SVG + CSS so it scales crisply on a projector and respects * Pure SVG + CSS so it scales crisply on a projector and respects
@ -290,7 +290,7 @@ const festivalCaps = [
<span class="mt-0.5 text-amber"><Icon name="Sparkles" class="size-5" /></span> <span class="mt-0.5 text-amber"><Icon name="Sparkles" class="size-5" /></span>
<p class="text-fg-muted"> <p class="text-fg-muted">
<span class="font-medium text-fg">Take root anywhere.</span> <span class="font-medium text-fg">Take root anywhere.</span>
Plug into a rich substrate of decentralized tech and grow your own flower a city hub, a travelling summit gathering, a farm. Plug into a rich substrate of decentralized tech and grow your own flower a city hub, a travelling festival, a farm.
</p> </p>
</div> </div>
</div> </div>

View file

@ -5,14 +5,14 @@
* *
* The financials are REAL, from SolLunarSociety.md, and belong exclusively to * The financials are REAL, from SolLunarSociety.md, and belong exclusively to
* the first node SolLunar Society (Austin). Lab 484, Pop-up * the first node SolLunar Society (Austin). Lab 484, Pop-up
* Summit Gatherings and Château du Faune are narrative/vision only and have no * Festivals and Château du Faune are narrative/vision only and have no
* standalone numbers. P&L totals are recomputed from line items; the doc's * standalone numbers. P&L totals are recomputed from line items; the doc's
* own summary totals didn't reconcile (kept in `pnlDocSummary`). * own summary totals didn't reconcile (kept in `pnlDocSummary`).
* *
* Lab 484 is the shared backbone open hardware + sovereign software (the * Lab 484 is the shared backbone open hardware + sovereign software (the
* "mycelium"). Three surface entities run on top of it: * "mycelium"). Three surface entities run on top of it:
* SolLunar Society city members' club, Austin (the funded first node) * SolLunar Society city members' club, Austin (the funded first node)
* Pop-up Summit Gatherings travelling gatherings (e.g. Solarpunk Summit) * Pop-up Festivals travelling gatherings (e.g. Solarpunk Summit)
* Château du Faune regenerative farm center * Château du Faune regenerative farm center
* *
* Currency: all figures are USD unless noted. * Currency: all figures are USD unless noted.
@ -26,7 +26,7 @@ export const brand = {
// Lab 484 — the tech co / shared backbone (also the 45% operating partner). // Lab 484 — the tech co / shared backbone (also the 45% operating partner).
tagline: 'One network. Three ways to experience it.', tagline: 'One network. Three ways to experience it.',
subtagline: subtagline:
'A sovereign network on shared, open infrastructure. The first node — SolLunar Society, a members club in Austin — is live, modeled and raising now; the summit gathering and the farm are next.', 'A sovereign network on shared, open infrastructure. The first node — SolLunar Society, a members club in Austin — is live, modeled and raising now; the festival and the farm are next.',
firstNode: 'SolLunar Society · Austin, TX', firstNode: 'SolLunar Society · Austin, TX',
contactEmail: 'invest@sollunar.example', // PLACEHOLDER contactEmail: 'invest@sollunar.example', // PLACEHOLDER
// Seam for later: an LNbits instance + the founder's nostr npub power the // Seam for later: an LNbits instance + the founder's nostr npub power the
@ -56,7 +56,7 @@ export type Entity = {
kind: string kind: string
accent: Accent accent: Accent
layer: 'backbone' | 'surface' layer: 'backbone' | 'surface'
example?: string // for the generic summit-gathering entity example?: string // for the generic festival entity
blurb: string blurb: string
traits: string[] // what makes THIS entity unique traits: string[] // what makes THIS entity unique
spaces: string[] spaces: string[]
@ -89,18 +89,18 @@ export const entities: Entity[] = [
}, },
{ {
id: 'festivals', id: 'festivals',
name: 'Pop-up Summit Gatherings', name: 'Pop-up Festivals',
role: 'Travelling gatherings', role: 'Travelling gatherings',
kind: 'Travelling · ephemeral', kind: 'Travelling · ephemeral',
accent: 'rose', accent: 'rose',
layer: 'surface', layer: 'surface',
example: 'Solar Punk Summit', example: 'Solar Punk Summit',
blurb: blurb:
'The travelling node: a repeatable summit-gathering format — like Solar Punk Summit — that deploys the entire stack anywhere for a few days, then packs down and moves on.', 'The travelling node: a repeatable festival format — like Solar Punk Summit — that deploys the entire stack anywhere for a few days, then packs down and moves on.',
traits: [ traits: [
'Deploys the full stack from a mobile kit — anywhere', 'Deploys the full stack from a mobile kit — anywhere',
'Proves the network is portable, not tied to a building', 'Proves the network is portable, not tied to a building',
'Turns every summit gathering into a member-onboarding event', 'Turns every festival into a member-onboarding event',
], ],
spaces: ['Main stage', 'Mobile exchange kiosk', 'Mesh & power rig', 'Camp & vendors', 'Workshop tents'], spaces: ['Main stage', 'Mobile exchange kiosk', 'Mesh & power rig', 'Camp & vendors', 'Workshop tents'],
revenue: ['Ticket sales', 'Vendor & bar revenue', 'Sponsorships'], revenue: ['Ticket sales', 'Vendor & bar revenue', 'Sponsorships'],
@ -155,7 +155,7 @@ export const surfaceEntities = entities.filter((e) => e.layer === 'surface')
export const userEcosystem = [ export const userEcosystem = [
{ {
title: 'One membership card', title: 'One membership card',
body: 'A single NFC card is your identity, access and wallet everywhere — the society, a summit gathering, the farm.', body: 'A single NFC card is your identity, access and wallet everywhere — the society, a festival, the farm.',
icon: 'CreditCard', icon: 'CreditCard',
}, },
{ {
@ -222,7 +222,7 @@ export const tech = [
/* /*
SolLunar Society the first node's REAL business (from SolLunar Society the first node's REAL business (from
SolLunarSociety.md). All figures below are SolLunar Society's SolLunarSociety.md). All figures below are SolLunar Society's
only; Lab 484, Summit Gatherings and Château have no only; Lab 484, Festivals and Château have no
standalone numbers yet. Lab 484's economics appear here as standalone numbers yet. Lab 484's economics appear here as
revenue lines INTO SolLunar (~$16k/mo) don't double-count. revenue lines INTO SolLunar (~$16k/mo) don't double-count.
*/ */
@ -486,7 +486,7 @@ export const roadmap = [
}, },
{ {
phase: 'Phase 2', phase: 'Phase 2',
title: 'Add the summit gathering', title: 'Add the festival',
when: '~1218 mo', when: '~1218 mo',
body: 'Deploy the same stack to a travelling Solarpunk Summit — proving the network is portable, not tied to a building.', body: 'Deploy the same stack to a travelling Solarpunk Summit — proving the network is portable, not tied to a building.',
}, },

View file

@ -6,7 +6,7 @@
* *
* src/deck/gallery/city/ City (SolLunar Punk Society) * src/deck/gallery/city/ City (SolLunar Punk Society)
* src/deck/gallery/farm/ Farm (Château du Faune) * src/deck/gallery/farm/ Farm (Château du Faune)
* src/deck/gallery/festival/ Summit Gathering (Pop-up Summit Gatherings) * src/deck/gallery/festival/ Festival (Pop-up Festivals)
* *
* Supported: jpg jpeg png webp avif gif svg. Images show sorted by filename, * Supported: jpg jpeg png webp avif gif svg. Images show sorted by filename,
* so prefix with 01-, 02-, to control order. The seeded *-placeholder.svg * so prefix with 01-, 02-, to control order. The seeded *-placeholder.svg
@ -73,7 +73,7 @@ export const gallerySections: GallerySection[] = [
}, },
{ {
id: 'festival', id: 'festival',
label: 'Summit Gathering', label: 'Festival',
entityName: entityById('festivals').name, entityName: entityById('festivals').name,
accent: 'rose', accent: 'rose',
folder: 'src/deck/gallery/festival/', folder: 'src/deck/gallery/festival/',

View file

@ -7,7 +7,7 @@ they appear automatically** — no code to touch.
| ----------- | -------- | --------------------- | | ----------- | -------- | --------------------- |
| `city/` | City | SolLunar Punk Society | | `city/` | City | SolLunar Punk Society |
| `farm/` | Farm | Château du Faune | | `farm/` | Farm | Château du Faune |
| `festival/` | Summit Gathering | Pop-up Summit Gatherings | | `festival/` | Festival | Pop-up Festivals |
- Supported formats: `jpg` `jpeg` `png` `webp` `avif` `gif` `svg`. - Supported formats: `jpg` `jpeg` `png` `webp` `avif` `gif` `svg`.
- Images display **sorted by filename** — prefix `01-`, `02-`, … to order them. - Images display **sorted by filename** — prefix `01-`, `02-`, … to order them.

View file

@ -9,7 +9,7 @@
<rect width="800" height="800" fill="url(#g)"/> <rect width="800" height="800" fill="url(#g)"/>
<circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/> <circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/>
<circle cx="70" cy="730" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/> <circle cx="70" cy="730" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/>
<text x="400" y="360" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Summit Gathering</text> <text x="400" y="360" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Festival</text>
<text x="400" y="406" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 01</text> <text x="400" y="406" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 01</text>
<text x="400" y="444" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×800</text> <text x="400" y="444" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×800</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1,000 B

After

Width:  |  Height:  |  Size: 992 B

Before After
Before After

View file

@ -9,7 +9,7 @@
<rect width="800" height="560" fill="url(#g)"/> <rect width="800" height="560" fill="url(#g)"/>
<circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/> <circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/>
<circle cx="70" cy="490" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/> <circle cx="70" cy="490" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/>
<text x="400" y="240" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Summit Gathering</text> <text x="400" y="240" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Festival</text>
<text x="400" y="286" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 02</text> <text x="400" y="286" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 02</text>
<text x="400" y="324" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×560</text> <text x="400" y="324" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×560</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1,000 B

After

Width:  |  Height:  |  Size: 992 B

Before After
Before After

View file

@ -9,7 +9,7 @@
<rect width="800" height="1040" fill="url(#g)"/> <rect width="800" height="1040" fill="url(#g)"/>
<circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/> <circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/>
<circle cx="70" cy="970" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/> <circle cx="70" cy="970" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/>
<text x="400" y="480" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Summit Gathering</text> <text x="400" y="480" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Festival</text>
<text x="400" y="526" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 03</text> <text x="400" y="526" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 03</text>
<text x="400" y="564" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×1040</text> <text x="400" y="564" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×1040</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1,005 B

After

Width:  |  Height:  |  Size: 997 B

Before After
Before After

View file

@ -9,7 +9,7 @@
<rect width="800" height="700" fill="url(#g)"/> <rect width="800" height="700" fill="url(#g)"/>
<circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/> <circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/>
<circle cx="70" cy="630" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/> <circle cx="70" cy="630" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/>
<text x="400" y="310" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Summit Gathering</text> <text x="400" y="310" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Festival</text>
<text x="400" y="356" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 04</text> <text x="400" y="356" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 04</text>
<text x="400" y="394" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×700</text> <text x="400" y="394" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×700</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1,000 B

After

Width:  |  Height:  |  Size: 992 B

Before After
Before After

View file

@ -9,7 +9,7 @@
<rect width="800" height="600" fill="url(#g)"/> <rect width="800" height="600" fill="url(#g)"/>
<circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/> <circle cx="740" cy="60" r="120" fill="hsl(256 78% 68%)" opacity="0.12"/>
<circle cx="70" cy="530" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/> <circle cx="70" cy="530" r="90" fill="hsl(256 78% 68%)" opacity="0.10"/>
<text x="400" y="260" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Summit Gathering</text> <text x="400" y="260" text-anchor="middle" fill="hsl(256 78% 68%)" font-size="46" font-weight="bold">Festival</text>
<text x="400" y="306" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 05</text> <text x="400" y="306" text-anchor="middle" fill="hsl(44 30% 90%)" font-size="26" opacity="0.85">Photo 05</text>
<text x="400" y="344" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×600</text> <text x="400" y="344" text-anchor="middle" fill="hsl(150 8% 62%)" font-size="18" letter-spacing="3">PLACEHOLDER · 800×600</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1,000 B

After

Width:  |  Height:  |  Size: 992 B

Before After
Before After

View file

@ -53,7 +53,7 @@ const shares = investorAsk.scenarios.map((s) => ({ equity: s, annual: Math.round
</div> </div>
<p class="mt-9 max-w-xl text-sm text-fg-muted"> <p class="mt-9 max-w-xl text-sm text-fg-muted">
Prove the model in Austin, then replicate it on Lab 484 the summit gathering and the farm are next. Prove the model in Austin, then replicate it on Lab 484 the festival and the farm are next.
</p> </p>
</SlideFrame> </SlideFrame>
</template> </template>

View file

@ -8,7 +8,7 @@ import { userEcosystem, surfaceEntities as entities } from '../data'
<SlideFrame <SlideFrame
kicker="One membership, everywhere" kicker="One membership, everywhere"
title="The same full experience, at every location" title="The same full experience, at every location"
subtitle="Wherever you are in the network — city, summit gathering or farm — the ecosystem is identical. Your card, your money, your identity travel with you." subtitle="Wherever you are in the network — city, festival or farm — the ecosystem is identical. Your card, your money, your identity travel with you."
> >
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"> <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<div <div

View file

@ -10,7 +10,7 @@ const backbone = entityById('lab484')
<SlideFrame <SlideFrame
kicker="The collaboration" kicker="The collaboration"
title="Three experiences, one backbone" title="Three experiences, one backbone"
subtitle="One is funded and opening now — SolLunar Society in Austin. The summit gathering and the farm follow, on the same Lab 484 stack." subtitle="One is funded and opening now — SolLunar Society in Austin. The festival and the farm follow, on the same Lab 484 stack."
> >
<div class="grid gap-5 md:grid-cols-3"> <div class="grid gap-5 md:grid-cols-3">
<div <div

View file

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import SlideFrame from '../components/SlideFrame.vue' import SlideFrame from '../components/SlideFrame.vue'
import Icon from '../components/Icon.vue'
import { partnership, fmtUsd } from '../data' import { partnership, fmtUsd } from '../data'
const barBg: Record<string, string> = { const barBg: Record<string, string> = {
@ -24,9 +25,9 @@ const pct = (e: number) => Math.round(e * 100)
<SlideFrame <SlideFrame
kicker="Ownership" kicker="Ownership"
title="A three-way partnership" title="A three-way partnership"
subtitle="SolLunar Society is a joint venture — investors buy in alongside the two founding partners." subtitle="SolLunar Society is a joint venture. Investors buy in alongside the two operating partners."
> >
<!-- equity split bar --> <!-- equity bar -->
<div class="flex h-5 w-full overflow-hidden rounded-full"> <div class="flex h-5 w-full overflow-hidden rounded-full">
<div <div
v-for="p in partnership.partners" v-for="p in partnership.partners"
@ -39,20 +40,33 @@ const pct = (e: number) => Math.round(e * 100)
</div> </div>
</div> </div>
<!-- the three entities --> <div class="mt-6 grid gap-4 md:grid-cols-3">
<div class="mt-8 grid gap-5 sm:grid-cols-3">
<div <div
v-for="p in partnership.partners" v-for="p in partnership.partners"
:key="p.name" :key="p.name"
class="flex flex-col items-center rounded-2xl border px-6 py-8 text-center" class="flex flex-col rounded-2xl border p-5"
:class="ring[p.accent]" :class="ring[p.accent]"
> >
<span class="font-display text-5xl font-bold" :class="text[p.accent]">{{ pct(p.equity) }}%</span> <div class="flex items-baseline justify-between gap-2">
<h3 class="mt-3 font-display text-lg font-semibold text-fg">{{ p.name }}</h3> <h3 class="font-display text-lg font-semibold text-fg">{{ p.name }}</h3>
<span class="font-display text-2xl font-bold" :class="text[p.accent]">{{ pct(p.equity) }}%</span>
</div>
<p class="text-xs uppercase tracking-wider" :class="text[p.accent]">{{ p.role }}</p>
<ul class="mt-4 flex-1 space-y-1.5">
<li v-for="r in p.responsibilities" :key="r" class="flex items-start gap-2 text-sm text-fg-muted">
<Icon name="Check" class="mt-0.5 size-3.5 shrink-0" :class="text[p.accent]" />
{{ r }}
</li>
</ul>
<p v-if="p.note" class="mt-3 border-t border-line pt-3 text-[11px] leading-relaxed text-fg-muted">
{{ p.note }}
</p>
</div> </div>
</div> </div>
<div class="mt-8 flex flex-wrap items-center justify-center gap-x-6 gap-y-1 text-sm text-fg-muted"> <div class="mt-5 flex flex-wrap items-center justify-center gap-x-6 gap-y-1 text-sm text-fg-muted">
<span>The ask:</span> <span>The ask:</span>
<span class="font-display text-lg font-semibold text-fg"> <span class="font-display text-lg font-semibold text-fg">
{{ fmtUsd(partnership.raiseAmount) }} for {{ pct(partnership.equityOffered) }}% {{ fmtUsd(partnership.raiseAmount) }} for {{ pct(partnership.equityOffered) }}%