Replace ghost/whisper/sparkle color palettes with guild/candlelight/parchment/ember/earth tokens. Switch typography from NB Television Pro to Quietism serif. Update all 25 Vue components, layouts, and pages to new design system. Add circle color tokens, typography scale, prose-guild class, and warm texture effects. Clean up stale documentation files.
180 lines
5.2 KiB
Vue
180 lines
5.2 KiB
Vue
<template>
|
|
<div class="max-w-6xl mx-auto px-6 md:px-8">
|
|
<!-- Hero Section -->
|
|
<section class="py-16 md:py-24">
|
|
<div class="max-w-2xl">
|
|
<h1
|
|
class="text-4xl md:text-5xl font-light text-guild-100 leading-tight mb-2"
|
|
>
|
|
Build your co-op studio
|
|
</h1>
|
|
<p
|
|
class="text-4xl md:text-5xl 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-red-500/10 border border-red-500/30 rounded-lg"
|
|
>
|
|
<p class="text-red-400 text-sm">{{ submitError }}</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Value Props Section -->
|
|
<section class="py-16 border-t border-guild-800">
|
|
<div class="grid md:grid-cols-3 gap-8 md:gap-12">
|
|
<div>
|
|
<p class="text-sm font-medium text-primary-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-sm font-medium text-primary-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-sm font-medium text-primary-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>
|
|
|
|
<!-- Circles Section -->
|
|
<section class="py-16 border-t border-guild-800">
|
|
<p class="text-sm 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>
|
|
|
|
<!-- Bottom CTA Section -->
|
|
<section class="py-24 border-t border-guild-800 text-center">
|
|
<p class="text-sm text-guild-600 mb-4">Part of the Baby Ghosts family</p>
|
|
<h2 class="text-3xl md:text-4xl 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>
|