ghostguild-org/app/pages/index.vue

186 lines
5.3 KiB
Vue

<template>
<div class="max-w-6xl mx-auto px-6 md:px-8">
<!-- Hero Section -->
<section class="py-16 md:py-24 ink-grain">
<div class="max-w-2xl">
<h1
class="text-display-xl font-light text-guild-100 leading-tight mb-2"
>
Build your co-op studio
</h1>
<p
class="text-display-xl font-light text-guild-500 leading-tight mb-8"
>
with people who get it.
</p>
<p class="text-lg text-guild-400 leading-relaxed mb-8 max-w-xl">
Ghost Guild is a peer community for game developers exploring
cooperative models. Find support, share knowledge, grow together.
</p>
<!-- Signup Form -->
<form @submit.prevent="handleJoinSubmit" class="mb-4">
<div class="flex flex-col sm:flex-row gap-3">
<UInput
v-model="joinEmail"
type="email"
placeholder="your.email@example.com"
size="lg"
class="flex-1"
:disabled="isSubmitting"
/>
<UButton
type="submit"
size="lg"
:loading="isSubmitting"
:disabled="!isEmailValid"
>
Join Us
</UButton>
</div>
</form>
<p class="text-sm text-guild-600">Free to join. Pay what you can.</p>
<!-- Success/Error Messages -->
<div
v-if="submitSuccess"
class="mt-4 p-3 bg-primary-500/10 border border-primary-500/30 rounded-lg"
>
<p class="text-primary-400 text-sm">
Check your email to complete signup!
</p>
</div>
<div
v-if="submitError"
class="mt-4 p-3 bg-ember-900/20 border border-ember-500/30 rounded-lg"
>
<p class="text-ember-400 text-sm">{{ submitError }}</p>
</div>
</div>
</section>
<GuildDivider variant="woodcut" />
<!-- Value Props Section -->
<section class="py-16">
<div class="grid md:grid-cols-3 gap-8 md:gap-12">
<div>
<p class="text-ui-label text-candlelight-400 mb-3">Peer Support</p>
<p class="text-guild-400 leading-relaxed">
Connect with founders at your stage and practitioners who've been
there. Real conversations, real help.
</p>
</div>
<div>
<p class="text-ui-label text-candlelight-400 mb-3">
Shared Knowledge
</p>
<p class="text-guild-400 leading-relaxed">
Templates, governance docs, financial models—tools built by co-ops,
for co-ops. All members get full access.
</p>
</div>
<div>
<p class="text-ui-label text-candlelight-400 mb-3">
Solidarity Economics
</p>
<p class="text-guild-400 leading-relaxed">
Those who can, support those who can't. No tiers, no gatekeeping.
Everyone gets everything.
</p>
</div>
</div>
</section>
<GuildDivider variant="woodcut" />
<!-- Circles Section -->
<section class="py-16">
<p class="text-ui-label text-guild-600 mb-8">Find your people</p>
<div class="space-y-4 mb-8">
<NuxtLink
v-for="circle in circles"
:key="circle.value"
to="/about/circles"
class="flex items-baseline gap-8 group py-2"
>
<span
class="text-guild-300 group-hover:text-guild-100 transition-colors w-32 md:w-40"
>
{{ circle.label }}
</span>
<span class="text-guild-600">
{{ circle.shortDescription }}
</span>
</NuxtLink>
</div>
<p class="text-sm text-guild-600 italic">
These reflect your journey, not your status. Move between them as you
grow.
</p>
</section>
<GuildDivider variant="woodcut" />
<!-- Bottom CTA Section -->
<section class="py-24 text-center">
<p class="text-ui-label text-guild-600 mb-4">Part of the Baby Ghosts family</p>
<h2 class="text-display font-light text-guild-200 mb-8">
Ready to find your people?
</h2>
<UButton
to="/join"
variant="outline"
size="lg"
class="hover:bg-primary-500/10"
>
Become a Ghostie
</UButton>
</section>
</div>
</template>
<script setup>
import { getCircleOptions } from "~/config/circles";
definePageMeta({
layout: "landing",
});
const circles = getCircleOptions();
// Join form state
const joinEmail = ref("");
const isSubmitting = ref(false);
const submitSuccess = ref(false);
const submitError = ref("");
const isEmailValid = computed(() => {
return joinEmail.value && joinEmail.value.includes("@");
});
const handleJoinSubmit = async () => {
if (!isEmailValid.value || isSubmitting.value) return;
isSubmitting.value = true;
submitSuccess.value = false;
submitError.value = "";
try {
// Redirect to join page with email pre-filled
await navigateTo({
path: "/join",
query: { email: joinEmail.value },
});
} catch (err) {
console.error("Join error:", err);
submitError.value = "Something went wrong. Please try again.";
} finally {
isSubmitting.value = false;
}
};
</script>