Migrate design system from ethereal/cool to warm/craft/guild theme
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.
This commit is contained in:
parent
d588c49946
commit
a62e167876
39 changed files with 1300 additions and 2087 deletions
|
|
@ -1,109 +1,139 @@
|
|||
<template>
|
||||
<div class="relative">
|
||||
<!-- Experimental Hero Section -->
|
||||
<section class="mb-24">
|
||||
<div class="relative">
|
||||
<!-- Large artistic title -->
|
||||
<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-6xl md:text-8xl font-bold text-ghost-100 ethereal-text leading-tight mb-8"
|
||||
class="text-4xl md:text-5xl font-light text-guild-100 leading-tight mb-2"
|
||||
>
|
||||
Become a Ghostie
|
||||
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>
|
||||
|
||||
<!-- Floating subtitle -->
|
||||
<div class="mb-16">
|
||||
<p class="text-ghost-100 text-lg max-w-md">
|
||||
A peer community for creatives and game devs<br />
|
||||
exploring cooperative models
|
||||
<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>
|
||||
|
||||
<!-- Decorative elements -->
|
||||
<div
|
||||
class="absolute top-0 right-0 w-32 h-32 border border-ghost-800 rounded-full opacity-20"
|
||||
/>
|
||||
<div
|
||||
class="absolute top-20 -left-8 w-16 h-px bg-whisper-500 opacity-40"
|
||||
/>
|
||||
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>
|
||||
|
||||
<!-- Join Section - Offset Layout -->
|
||||
<section class="mb-32 relative">
|
||||
<div>
|
||||
<!-- 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
|
||||
to="/join"
|
||||
class="inline-block px-8 py-3 border border-ghost-600 text-ghost-200 hover:bg-ghost-800 hover:border-whisper-500 hover:ethereal-text transition-all duration-500"
|
||||
v-for="circle in circles"
|
||||
:key="circle.value"
|
||||
to="/about/circles"
|
||||
class="flex items-baseline gap-8 group py-2"
|
||||
>
|
||||
Join Us Today →
|
||||
<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>
|
||||
|
||||
<!-- Decorative corner element -->
|
||||
<div
|
||||
class="absolute -right-4 top-0 w-20 h-20 border-t border-r border-ghost-800 opacity-30"
|
||||
/>
|
||||
<p class="text-sm text-guild-600 italic">
|
||||
These reflect your journey, not your status. Move between them as you
|
||||
grow.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Circles - Asymmetrical Grid -->
|
||||
<section class="mb-32">
|
||||
<div class="space-y-8">
|
||||
<div
|
||||
v-for="(circle, index) in circles"
|
||||
:key="circle.value"
|
||||
class="flex gap-8 items-start"
|
||||
>
|
||||
<!-- Content -->
|
||||
<div class="flex-1 max-w-lg">
|
||||
<h3 class="text-xl text-ghost-100 mb-3">{{ circle.label }}</h3>
|
||||
<p class="text-ghost-200 text-sm leading-relaxed mb-4">
|
||||
{{ circle.description }}
|
||||
</p>
|
||||
|
||||
<!-- Features as inline text -->
|
||||
<div class="text-sm text-ghost-400">
|
||||
<span v-for="(feature, i) in circle.features" :key="feature">
|
||||
{{ feature
|
||||
}}<span v-if="i < circle.features.length - 1"> • </span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Side accent -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Why Join? - Diagonal Layout -->
|
||||
<section class="mb-32 relative">
|
||||
<div class="transform -rotate-1">
|
||||
<h2 class="text-3xl font-light text-ghost-200 mb-12">Why Join?</h2>
|
||||
</div>
|
||||
|
||||
<div class="ml-12 relative">
|
||||
<div
|
||||
class="absolute -left-4 top-0 w-32 h-px bg-whisper-500 opacity-30 transform rotate-12"
|
||||
/>
|
||||
|
||||
<div class="max-w-2xl">
|
||||
<p class="text-ghost-300 leading-loose text-lg mb-8">
|
||||
Ghost Guild is Baby Ghosts' membership program, and a community of
|
||||
game makers building studios that center workers, not just profits.
|
||||
</p>
|
||||
|
||||
<p class="text-ghost-400 leading-relaxed ml-8">
|
||||
There's space for you no matter where you are in your cooperative
|
||||
journey and no matter where in the world you are! You'll find peers,
|
||||
resources, and support here.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute -bottom-8 right-0 text-6xl text-ghost-800 opacity-20 font-bold"
|
||||
>
|
||||
?
|
||||
</div>
|
||||
</div>
|
||||
<!-- 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>
|
||||
|
|
@ -111,5 +141,40 @@
|
|||
<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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue