contents(app-shop): move the free printables into the 'Sticker packs' entry
The sticker + poster were their own 'Free to print' section, which made the shop read as two lists. They now live inside the 'Sticker packs' card in the 'In the works' grid (full-width, FREE badge, compact previews + Print/Save), between Decks and Shop tools — so a category shows what it already offers. Verified: no 'Free to print' heading remains, both printables still render, and the page reads hero -> in the works (5 entries) -> how buying works.
This commit is contained in:
parent
263ce11073
commit
5b770dc79b
2 changed files with 96 additions and 71 deletions
|
|
@ -361,7 +361,9 @@ session with **no other memory of this project**. So:
|
|||
'nothing is for sale' note — removed on request). **Do not add prices/fake urgency/buy buttons until
|
||||
there is real stock**; when items exist, model them as listings and take
|
||||
Lightning/Cashu payment. The page reads the live stock strip as 0/None/Nothing
|
||||
— keep it honest if that changes. It also serves two **free printables**
|
||||
— keep it honest if that changes. It also serves two **free printables** (rendered INSIDE the 'Sticker packs'
|
||||
entry of the 'In the works' grid — deliberately not a separate section, per the
|
||||
owner: the free sticker + poster belong under their merch category)
|
||||
(`public/images/print/skatespots-sticker.svg` 55×86 mm, `…-poster.svg` A3),
|
||||
regenerated with `node scripts/make-print-art.mjs` (output is committed). Those
|
||||
SVGs are self-contained: brand fonts + logo embedded as data URIs and a real
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ const FREE_PRINT = [
|
|||
const PLANNED = [
|
||||
{ icon: Shirt, label: 'Tees & hoodies' },
|
||||
{ icon: Package, label: 'Decks' },
|
||||
{ icon: Sticker, label: 'Sticker packs' },
|
||||
// 'Sticker packs' is rendered separately in the grid, because it is the one
|
||||
// entry that already contains something real: the free printables.
|
||||
{ icon: Hammer, label: 'Shop tools' },
|
||||
];
|
||||
|
||||
|
|
@ -157,7 +158,97 @@ export default function AppShopPage() {
|
|||
</div>
|
||||
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
{PLANNED.map(({ icon: Icon, label }) => (
|
||||
{PLANNED.slice(0, 2).map(({ icon: Icon, label }) => (
|
||||
<div
|
||||
key={label}
|
||||
className="group relative overflow-hidden rounded-2xl border-2 border-dashed border-white/12 bg-white/[0.02] p-4 transition-colors hover:border-[#ccff00]/30"
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[#ccff00]/10 text-[#ccff00]">
|
||||
<Icon className="h-5 w-5" />
|
||||
</span>
|
||||
<p className="min-w-0 self-center font-black uppercase tracking-wide text-white">
|
||||
{label}
|
||||
</p>
|
||||
</div>
|
||||
<span className="absolute right-3 top-3 rounded-full border border-white/12 px-2 py-0.5 text-[9px] font-black uppercase tracking-widest text-gray-500">
|
||||
soon
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Sticker packs — the only thing you can actually GET today: the free
|
||||
printables. Kept inside its category (not a separate section) so the
|
||||
shop reads as one list of merch, free stuff included. */}
|
||||
<div className="rounded-2xl border-2 border-dashed border-[#ccff00]/35 bg-[#ccff00]/[0.04] p-4 sm:col-span-2">
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[#ccff00]/10 text-[#ccff00]">
|
||||
<Sticker className="h-5 w-5" />
|
||||
</span>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="font-black uppercase tracking-wide text-white">Sticker packs</p>
|
||||
<p className="mt-0.5 text-xs leading-relaxed text-gray-400">
|
||||
The packs are coming. The designs are not — print these two right now, free.
|
||||
</p>
|
||||
</div>
|
||||
<span className="shrink-0 rounded-full bg-[#ccff00] px-2 py-0.5 text-[9px] font-black uppercase tracking-widest text-black">
|
||||
Free
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 grid gap-3 sm:grid-cols-2">
|
||||
{FREE_PRINT.map((item) => (
|
||||
<div
|
||||
key={item.title}
|
||||
className="overflow-hidden rounded-xl border border-white/10 bg-black/40"
|
||||
>
|
||||
<div className="flex h-36 items-center justify-center p-3">
|
||||
<img
|
||||
src={item.file}
|
||||
alt={`SkateSpots ${item.title} — printable`}
|
||||
className="max-h-full max-w-full drop-shadow-[0_4px_14px_rgba(0,0,0,0.6)]"
|
||||
/>
|
||||
</div>
|
||||
<div className="border-t border-white/8 p-3">
|
||||
<div className="flex items-baseline justify-between gap-2">
|
||||
<p className="font-bold uppercase tracking-wide text-white">{item.title}</p>
|
||||
<span className="shrink-0 text-[10px] font-bold uppercase tracking-widest text-gray-500">
|
||||
{item.size}
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 flex items-start gap-1.5 text-[11px] leading-relaxed text-gray-500">
|
||||
<Scissors className="mt-0.5 h-3 w-3 shrink-0 text-gray-600" />
|
||||
{item.tip}
|
||||
</p>
|
||||
<div className="mt-2.5 flex flex-wrap gap-2">
|
||||
<Button
|
||||
asChild
|
||||
size="sm"
|
||||
className="gap-1.5 bg-[#ccff00] font-bold text-black hover:bg-[#ccff00]/90"
|
||||
>
|
||||
<a href={item.file} target="_blank" rel="noopener noreferrer">
|
||||
<Printer className="h-3.5 w-3.5" /> Print
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild size="sm" variant="outline" className="gap-1.5 border-white/15">
|
||||
<a href={item.file} download>
|
||||
<Download className="h-3.5 w-3.5" /> Save
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="mt-3 text-[11px] leading-relaxed text-gray-600">
|
||||
Print at <strong className="text-gray-400">100% / “Actual size”</strong> so the size is
|
||||
exact and the QR stays sharp — it points at skate-spots.org. Vector files, so they
|
||||
scale without going fuzzy.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{PLANNED.slice(2).map(({ icon: Icon, label }) => (
|
||||
<div
|
||||
key={label}
|
||||
className="group relative overflow-hidden rounded-2xl border-2 border-dashed border-white/12 bg-white/[0.02] p-4 transition-colors hover:border-[#ccff00]/30"
|
||||
|
|
@ -178,74 +269,6 @@ export default function AppShopPage() {
|
|||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Free to print ────────────────────────────────────────────────── */}
|
||||
<section className="mt-10">
|
||||
<div className="mb-4 flex items-center gap-3">
|
||||
<h3 className="flex items-center gap-2 text-sm font-black uppercase tracking-widest text-white">
|
||||
<Printer className="h-4 w-4 text-[#ccff00]" />
|
||||
Free to print
|
||||
</h3>
|
||||
<div className="h-px flex-1 bg-white/10" />
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-[#ccff00]">
|
||||
no sats needed
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 sm:grid-cols-2">
|
||||
{FREE_PRINT.map((item) => (
|
||||
<div
|
||||
key={item.title}
|
||||
className="overflow-hidden rounded-2xl border border-white/8 bg-white/[0.03]"
|
||||
>
|
||||
<div className="relative flex h-56 items-center justify-center bg-black/40 p-4">
|
||||
<img
|
||||
src={item.file}
|
||||
alt={`SkateSpots ${item.title} — printable`}
|
||||
className="max-h-full max-w-full drop-shadow-[0_6px_20px_rgba(0,0,0,0.6)]"
|
||||
/>
|
||||
<span className="absolute left-3 top-3 rounded-full bg-[#ccff00] px-2 py-0.5 text-[9px] font-black uppercase tracking-widest text-black">
|
||||
Free
|
||||
</span>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<div className="flex items-baseline justify-between gap-2">
|
||||
<p className="font-black uppercase tracking-wide text-white">{item.title}</p>
|
||||
<span className="shrink-0 text-[10px] font-bold uppercase tracking-widest text-gray-500">
|
||||
{item.size}
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 flex items-start gap-1.5 text-xs leading-relaxed text-gray-400">
|
||||
<Scissors className="mt-0.5 h-3.5 w-3.5 shrink-0 text-gray-600" />
|
||||
{item.tip}
|
||||
</p>
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
<Button
|
||||
asChild
|
||||
size="sm"
|
||||
className="gap-2 bg-[#ccff00] font-bold text-black hover:bg-[#ccff00]/90"
|
||||
>
|
||||
<a href={item.file} target="_blank" rel="noopener noreferrer">
|
||||
<Printer className="h-3.5 w-3.5" /> Open & print
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild size="sm" variant="outline" className="gap-2 border-white/15">
|
||||
<a href={item.file} download>
|
||||
<Download className="h-3.5 w-3.5" /> Save file
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="mt-3 text-[11px] leading-relaxed text-gray-600">
|
||||
Print at <strong className="text-gray-400">100% / “Actual size”</strong> so the size is
|
||||
exact and the QR stays sharp — it points at skate-spots.org. These are vector files, so
|
||||
they scale to any size without going fuzzy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* ── How it'll work ───────────────────────────────────────────────── */}
|
||||
<section className="mt-10">
|
||||
<div className="mb-4 flex items-center gap-3">
|
||||
|
|
|
|||
Loading…
Reference in a new issue