mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
207 lines
7.9 KiB
Plaintext
207 lines
7.9 KiB
Plaintext
---
|
|
/**
|
|
* /store — Storefront
|
|
* ---------------------------------------------------------------------------
|
|
* The store home: hero on the animated field, intro, the two product lines,
|
|
* live availability (slots) from store-availability.json, the disclaimer /
|
|
* requirements block, and a CTA to the order page.
|
|
*
|
|
* Reuses the main site's aesthetic (InterestHero-style hero, Reveal, cards)
|
|
* but is rendered through StoreLayout so it gets the store-only nav and
|
|
* noindex by default. No links back to the main site.
|
|
*/
|
|
import StoreLayout from '@layouts/StoreLayout.astro';
|
|
import Reveal from '@components/motion/Reveal.astro';
|
|
import SectionHeader from '@components/layout/SectionHeader.astro';
|
|
import AnimatedBackground from '@components/hero/AnimatedBackground.tsx';
|
|
import StarBurst from '@components/mystic/StarBurst.astro';
|
|
import Icon from '@components/Icon.astro';
|
|
import ProductTile from '@components/store/ProductTile.astro';
|
|
import SlotMeter from '@components/store/SlotMeter.astro';
|
|
import RequirementList from '@components/store/RequirementList.astro';
|
|
import { cardProduct, deckBoxProduct, requirements } from '@data/store-products';
|
|
import { storeAvailability } from '@data/store-availability';
|
|
|
|
const av = storeAvailability;
|
|
const orderHref = '/store/order';
|
|
---
|
|
|
|
<StoreLayout
|
|
title="Store — Proxy MTG Cards & 3D-Printed Deck Boxes"
|
|
>
|
|
{/* --- Hero --- */}
|
|
<section class="relative overflow-hidden pb-8 pt-28 sm:pt-32">
|
|
<AnimatedBackground client:idle className="vt-sky" />
|
|
|
|
<div class="container-prose relative z-10 grid items-center gap-6 py-6 sm:grid-cols-[1.4fr_1fr]">
|
|
<div class="flex flex-col items-start gap-4">
|
|
<Reveal>
|
|
<span
|
|
class="inline-flex items-center gap-1.5 font-mono text-xs uppercase tracking-[0.18em]"
|
|
style="color: var(--color-accent);"
|
|
>
|
|
<Icon name="store" class="h-4 w-4" />
|
|
store.gregkilmer.com
|
|
</span>
|
|
</Reveal>
|
|
|
|
<Reveal delay={60}>
|
|
<span
|
|
class="inline-flex h-12 w-12 items-center justify-center rounded-xl"
|
|
style="background: color-mix(in srgb, var(--color-accent) 18%, transparent); color: var(--color-accent);"
|
|
aria-hidden="true"
|
|
>
|
|
<Icon name="cards" class="h-6 w-6" />
|
|
</span>
|
|
</Reveal>
|
|
|
|
<Reveal delay={100}>
|
|
<h2
|
|
class="font-sans font-bold tracking-tight"
|
|
style="color: var(--color-cream); font-size: clamp(1.75rem, 2vw + 1rem, 2.75rem); line-height: 1.15;"
|
|
>
|
|
Proxy MTG cards & 3D-printed deck boxes
|
|
</h2>
|
|
</Reveal>
|
|
|
|
<Reveal delay={140}>
|
|
<p
|
|
class="max-w-xl border-l-2 pl-4 font-sans text-base italic sm:text-lg"
|
|
style="border-color: var(--color-accent); color: var(--color-cream); opacity: 0.92;"
|
|
>
|
|
Clearly-marked proxies for casual play, and matching 3D-printed storage &
|
|
counters. Hand-made in small batches.
|
|
</p>
|
|
</Reveal>
|
|
|
|
<Reveal delay={180}>
|
|
<a href={orderHref} class="btn btn-primary mt-2">
|
|
<Icon name="clipboard-list" class="h-5 w-5" />
|
|
Start an order request
|
|
</a>
|
|
</Reveal>
|
|
</div>
|
|
|
|
<Reveal delay={80} class="w-full">
|
|
<figure
|
|
class="relative w-full overflow-hidden rounded-2xl border"
|
|
style="border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);"
|
|
>
|
|
<img
|
|
src="/images/proxies.jpg"
|
|
alt="Example printed proxy MTG cards"
|
|
loading="lazy"
|
|
decoding="async"
|
|
class="aspect-[4/3] w-full object-cover"
|
|
/>
|
|
<StarBurst
|
|
class="pointer-events-none absolute left-3 top-3 h-5 w-5 drop-shadow-[0_0_6px_color-mix(in_srgb,var(--color-accent)_60%,transparent)]"
|
|
style="color: var(--color-accent);"
|
|
/>
|
|
</figure>
|
|
</Reveal>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="container-prose flex flex-col gap-20 py-12 sm:py-16">
|
|
{/* --- Intro + limited capacity banner --- */}
|
|
<section class="flex flex-col gap-6">
|
|
<Reveal>
|
|
<SectionHeader kicker="Welcome" icon="store" title="A small workshop, not a factory" />
|
|
</Reveal>
|
|
<Reveal delay={60}>
|
|
<p class="max-w-2xl text-lg leading-relaxed" style="color: var(--color-text-muted);">
|
|
{av.maxNote}
|
|
</p>
|
|
</Reveal>
|
|
<Reveal delay={100}>
|
|
<div
|
|
class="flex flex-col gap-3 rounded-xl border p-5 sm:flex-row sm:items-center sm:justify-between"
|
|
style="border-color: color-mix(in srgb, var(--color-accent) 35%, transparent); background: color-mix(in srgb, var(--color-accent) 8%, transparent);"
|
|
>
|
|
<div class="flex items-center gap-3">
|
|
<Icon name="clock-outline" class="h-6 w-6 shrink-0" style="color: var(--color-accent);" />
|
|
<span class="text-sm sm:text-base" style="color: var(--color-text);">{av.turnaround}</span>
|
|
</div>
|
|
<span class="pill" style={av.ordersOpen ? undefined : 'background: color-mix(in srgb, #e55 15%, transparent); border-color: color-mix(in srgb, #e55 40%, transparent);'}>
|
|
{av.ordersOpen ? 'Orders open' : 'Orders currently closed'}
|
|
</span>
|
|
</div>
|
|
</Reveal>
|
|
</section>
|
|
|
|
{/* --- Product lines --- */}
|
|
<section class="flex flex-col gap-6">
|
|
<Reveal>
|
|
<SectionHeader kicker="Products" icon="cards-outline" title="What I make" />
|
|
</Reveal>
|
|
<div class="grid gap-5 sm:grid-cols-2">
|
|
<Reveal delay={60}>
|
|
<ProductTile product={cardProduct} href="/store/cards" />
|
|
</Reveal>
|
|
<Reveal delay={120}>
|
|
<ProductTile product={deckBoxProduct} href="/store/deck-boxes" />
|
|
</Reveal>
|
|
</div>
|
|
</section>
|
|
|
|
{/* --- Live availability --- */}
|
|
<section class="flex flex-col gap-6">
|
|
<Reveal>
|
|
<SectionHeader kicker="Availability" icon="gauge" title="Current order slots" />
|
|
</Reveal>
|
|
<Reveal delay={60}>
|
|
<p class="max-w-2xl text-base" style="color: var(--color-text-muted);">
|
|
I can only take so many requests at a time. These update as I open and finish orders.
|
|
Last updated {av.lastUpdated}.
|
|
</p>
|
|
</Reveal>
|
|
<Reveal delay={100}>
|
|
<div class="grid gap-4 sm:grid-cols-2">
|
|
<SlotMeter
|
|
label="Card orders"
|
|
icon="cards-playing"
|
|
open={av.slots.cards.open}
|
|
total={av.slots.cards.total}
|
|
/>
|
|
<SlotMeter
|
|
label="3D-print slots"
|
|
icon="printer-3d-nozzle"
|
|
open={av.slots.deckBoxes.open}
|
|
total={av.slots.deckBoxes.total}
|
|
/>
|
|
</div>
|
|
</Reveal>
|
|
</section>
|
|
|
|
{/* --- Requirements / disclaimer --- */}
|
|
<section class="flex flex-col gap-6">
|
|
<Reveal>
|
|
<SectionHeader kicker="Before you order" icon="clipboard-check" title="Requirements & policies" />
|
|
</Reveal>
|
|
<Reveal delay={60}>
|
|
<RequirementList items={requirements} />
|
|
</Reveal>
|
|
</section>
|
|
|
|
{/* --- CTA --- */}
|
|
<section class="flex flex-col items-center gap-4 rounded-2xl border p-8 text-center" style="border-color: var(--color-border); background: var(--color-surface-raised);">
|
|
<Reveal>
|
|
<h3 class="font-sans text-2xl font-bold" style="color: var(--color-text);">Ready to put in a request?</h3>
|
|
</Reveal>
|
|
<Reveal delay={60}>
|
|
<p class="max-w-lg text-sm" style="color: var(--color-text-muted);">
|
|
The order form collects your request and emails it to me. No payment is taken through
|
|
the site. {av.ordersOpen ? '' : 'Orders are currently closed — check back soon.'}
|
|
</p>
|
|
</Reveal>
|
|
<Reveal delay={100}>
|
|
<a href={orderHref} class="btn btn-primary">
|
|
<Icon name="clipboard-list" class="h-5 w-5" />
|
|
Go to the order page
|
|
</a>
|
|
</Reveal>
|
|
</section>
|
|
</div>
|
|
</StoreLayout>
|