307 lines
8.6 KiB
Vue
307 lines
8.6 KiB
Vue
<template>
|
||
<div>
|
||
<!-- HERO -->
|
||
<div class="hero">
|
||
<h1>Ghost Guild is where game developers practice cooperative business models.</h1>
|
||
<p>Resources, events, and a community of people figuring it out. Three circles, no hierarchy. $0–50/mo, pay what you can.</p>
|
||
<div class="hero-links">
|
||
<NuxtLink to="/join" class="hero-link primary">Become a member</NuxtLink>
|
||
<NuxtLink to="/wiki" class="hero-link">Read the wiki</NuxtLink>
|
||
<NuxtLink to="/about" class="hero-link">What is this?</NuxtLink>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- THREE CIRCLES -->
|
||
<div class="content-row">
|
||
<div v-for="circle in circleData" :key="circle.value" class="content-block">
|
||
<div class="label" :style="{ color: `var(--c-${circle.value})` }">{{ circle.label }}</div>
|
||
<h2>{{ circle.metaphor }}</h2>
|
||
<p>{{ circle.blurb }}</p>
|
||
<details>
|
||
<summary>What's included?</summary>
|
||
<p>{{ circle.included }}</p>
|
||
</details>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- UPCOMING EVENTS + WIKI (full-bleed row dividers: border on full-width row, padding on inset only) -->
|
||
<div class="content-row two-col">
|
||
<div class="content-block">
|
||
<div class="block-inset">
|
||
<div class="label">Upcoming Events</div>
|
||
</div>
|
||
<div v-if="events?.length" class="event-list">
|
||
<div v-for="event in events" :key="event._id" class="event-item">
|
||
<div class="block-inset event-item-inner">
|
||
<span class="event-date">{{ formatDate(event.date) }}</span>
|
||
<span class="event-title">
|
||
<NuxtLink :to="`/events/${event._id}`">{{ event.title }}</NuxtLink>
|
||
</span>
|
||
<CircleBadge v-if="event.circle" :circle="event.circle" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div v-else class="block-inset">
|
||
<p class="empty">No upcoming events</p>
|
||
</div>
|
||
</div>
|
||
<div class="content-block">
|
||
<div class="block-inset">
|
||
<div class="label">Recently in the Wiki</div>
|
||
</div>
|
||
<div class="wiki-list">
|
||
<div class="wiki-item">
|
||
<div class="block-inset wiki-item-inner">
|
||
<a href="/wiki">Revenue sharing models</a>
|
||
</div>
|
||
</div>
|
||
<div class="wiki-item">
|
||
<div class="block-inset wiki-item-inner">
|
||
<a href="/wiki">What is a cooperative studio?</a>
|
||
</div>
|
||
</div>
|
||
<div class="wiki-item">
|
||
<div class="block-inset wiki-item-inner">
|
||
<a href="/wiki">Governance structures</a>
|
||
</div>
|
||
</div>
|
||
<div class="wiki-item">
|
||
<div class="block-inset wiki-item-inner">
|
||
<a href="/wiki">Legal incorporation guide</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PARCHMENT INSET -->
|
||
<ParchmentInset>
|
||
<div class="label" style="color: var(--candle-faint); opacity: 0.6; margin-bottom: 12px;">From the Wiki</div>
|
||
<h2>What is a cooperative studio?</h2>
|
||
<p>A cooperative studio is a game development company owned and governed by the people who work there. Decisions are made collectively. Profits are shared according to contribution, not ownership stake.</p>
|
||
<p>The games industry is full of stories about crunch, layoffs, and studios that extract value from workers. Cooperatives are one alternative — not the only one, but one worth <a href="/wiki">practicing together</a>.</p>
|
||
<p><a href="/wiki">Read more in the wiki →</a></p>
|
||
</ParchmentInset>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
definePageMeta({
|
||
layout: "default",
|
||
})
|
||
|
||
const { data: events } = await useFetch('/api/events', {
|
||
query: { limit: 4, upcoming: true },
|
||
default: () => [],
|
||
})
|
||
|
||
const circleData = [
|
||
{
|
||
value: 'community',
|
||
label: 'Community',
|
||
metaphor: 'The open hall',
|
||
blurb: 'Arrival, curiosity, orientation. For anyone exploring cooperative models in game development. Access the wiki, public events, and Slack.',
|
||
included: 'Wiki access, public events, Slack community, monthly guild meetings. Free or pay-what-you-can.',
|
||
},
|
||
{
|
||
value: 'founder',
|
||
label: 'Founder',
|
||
metaphor: 'The workshop',
|
||
blurb: 'For people actively building cooperatives. Structured practice, peer support, templates, and hands-on resources.',
|
||
included: 'Everything in Community plus the peer accelerator, 1:1 mentorship matching, and Founder-only workshops.',
|
||
},
|
||
{
|
||
value: 'practitioner',
|
||
label: 'Practitioner',
|
||
metaphor: 'The alcove',
|
||
blurb: 'Where experience is shared and knowledge given back. Teaching, advising, shaping the program itself.',
|
||
included: 'Everything in Founder plus the ability to mentor, propose events, contribute to the wiki, and help govern the Guild.',
|
||
},
|
||
]
|
||
|
||
const formatDate = (dateStr) => {
|
||
if (!dateStr) return ''
|
||
const d = new Date(dateStr)
|
||
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* ---- HERO ---- */
|
||
.hero {
|
||
padding: 48px 32px;
|
||
border-bottom: 1px dashed var(--border);
|
||
}
|
||
.hero h1 {
|
||
font-family: 'Brygada 1918', serif;
|
||
font-size: 36px;
|
||
font-weight: 600;
|
||
color: var(--text-bright);
|
||
line-height: 1.15;
|
||
letter-spacing: -0.01em;
|
||
margin-bottom: 16px;
|
||
max-width: 540px;
|
||
}
|
||
.hero p {
|
||
color: var(--text-dim);
|
||
max-width: 460px;
|
||
line-height: 1.7;
|
||
margin-bottom: 20px;
|
||
}
|
||
.hero-links {
|
||
display: flex;
|
||
gap: 16px;
|
||
font-size: 13px;
|
||
}
|
||
.hero-link {
|
||
color: var(--candle);
|
||
padding: 6px 16px;
|
||
border: 1px dashed var(--candle-faint);
|
||
transition: all 0.2s;
|
||
text-decoration: none;
|
||
}
|
||
.hero-link:hover {
|
||
border-color: var(--candle);
|
||
border-style: solid;
|
||
text-decoration: none;
|
||
}
|
||
.hero-link.primary {
|
||
background: var(--candle);
|
||
color: var(--bg);
|
||
border-color: var(--candle);
|
||
border-style: solid;
|
||
}
|
||
.hero-link.primary:hover {
|
||
background: var(--candle-dim);
|
||
border-color: var(--candle-dim);
|
||
}
|
||
|
||
/* ---- CONTENT GRID ---- */
|
||
.content-row {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||
align-items: stretch;
|
||
border-bottom: 1px dashed var(--border);
|
||
}
|
||
.content-row.two-col {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
}
|
||
.content-block {
|
||
padding: 24px 28px;
|
||
border-right: 1px dashed var(--border);
|
||
min-width: 0;
|
||
overflow-wrap: break-word;
|
||
align-self: stretch;
|
||
}
|
||
.content-row.two-col .content-block {
|
||
padding: 24px 0;
|
||
}
|
||
.content-row.two-col .block-inset {
|
||
padding-left: 28px;
|
||
padding-right: 28px;
|
||
}
|
||
.content-block:last-child { border-right: none; }
|
||
.content-block h2 {
|
||
font-family: 'Brygada 1918', serif;
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: var(--text-bright);
|
||
margin-bottom: 8px;
|
||
}
|
||
.content-block p {
|
||
color: var(--text-dim);
|
||
font-size: 12px;
|
||
line-height: 1.65;
|
||
}
|
||
.content-block .label {
|
||
font-size: 10px;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--text-faint);
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* ---- DETAILS ---- */
|
||
details {
|
||
margin-top: 12px;
|
||
}
|
||
details summary {
|
||
font-size: 12px;
|
||
color: var(--candle-dim);
|
||
cursor: pointer;
|
||
list-style: none;
|
||
}
|
||
details summary::before {
|
||
content: '+ ';
|
||
}
|
||
details[open] summary::before {
|
||
content: '− ';
|
||
}
|
||
details p {
|
||
margin-top: 8px;
|
||
}
|
||
|
||
/* ---- EVENT LIST ---- */
|
||
.event-item {
|
||
border-bottom: 1px dashed var(--border);
|
||
}
|
||
.event-list .event-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.event-item-inner {
|
||
display: grid;
|
||
grid-template-columns: 80px 1fr auto;
|
||
gap: 16px;
|
||
align-items: baseline;
|
||
padding-top: 10px;
|
||
padding-bottom: 10px;
|
||
transition: padding-left 0.2s;
|
||
}
|
||
.content-row.two-col .event-item:hover .event-item-inner {
|
||
padding-left: calc(28px + 4px);
|
||
}
|
||
.event-date { color: var(--text-faint); font-size: 12px; }
|
||
.event-title { color: var(--text); font-size: 13px; }
|
||
.event-title a { color: var(--text); text-decoration: none; }
|
||
.event-title a:hover { color: var(--candle); }
|
||
|
||
/* ---- WIKI LIST ---- */
|
||
.wiki-item {
|
||
border-bottom: 1px dashed var(--border);
|
||
font-size: 13px;
|
||
}
|
||
.wiki-list .wiki-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.wiki-item-inner {
|
||
padding-top: 8px;
|
||
padding-bottom: 8px;
|
||
}
|
||
.wiki-item a { color: var(--text); text-decoration: none; }
|
||
.wiki-item a:hover { color: var(--candle); }
|
||
|
||
.empty {
|
||
color: var(--text-faint);
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* ---- RESPONSIVE ---- */
|
||
@media (max-width: 768px) {
|
||
.content-row,
|
||
.content-row.two-col {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.content-block {
|
||
border-right: none;
|
||
border-bottom: 1px dashed var(--border);
|
||
}
|
||
.content-block:last-child { border-bottom: none; }
|
||
.hero-links {
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
}
|
||
.hero-link {
|
||
text-align: center;
|
||
}
|
||
}
|
||
</style>
|