// Showcase: section headers, game cards grid, product grid, mystery packs, events, vault feed const { useState: useSt, useEffect: useEf } = React; function SectionHead({ eyebrow, title, italicWord, unified, desc, link }) { return (
{eyebrow}

{unified ? {title} : <>{title} {italicWord && {italicWord}}}

{desc &&

{desc}

}
{link && e.preventDefault()}>{link} →}
); } function GameCardGrid() { const cards = [ { cls: 'mtg', Sigil: window.SigilMagic, tag: '5,400+ Singles', title: 'Magic: The Gathering', desc: 'Standard, Pioneer, Modern, Commander — and every set back to Alpha.', stats: [['All','Formats'],['Daily','Restocks']] }, { cls: 'poke', Sigil: window.SigilPokemon, tag: '3,800+ Singles', title: 'Pokémon TCG', desc: 'From base set Charizard to the latest Scarlet & Violet pulls.', stats: [['S&V','Current format'],['Vintage','In stock']] }, { cls: 'rift', Sigil: window.SigilRiftbound, tag: '1,200+ Singles', title: 'Riftbound', desc: 'The rising star in TCG. Get in early — we stock every set on day one.', stats: [['Day 1','Releases'],['Free','Starter w/ entry']] }, { cls: 'onepiece', Sigil: window.SigilOnePiece, tag: '2,100+ Singles', title: 'One Piece TCG', desc: 'All Ops, all leaders, every alt-art. Build your dream crew.', stats: [['OP1-9','All sets'],['Weekly','Tournaments']] }, ]; return (
{cards.map((c, i) => { const SigilComp = c.Sigil; return ( e.preventDefault()}>
{SigilComp ? : null} {c.tag}
{c.title}
{c.desc}
{c.stats.map(([v,l]) => (
{v}
{l}
))}
Browse {c.title.split(':')[0].split(' ')[0]}
); })}
); } function ProductCard({ p, onAdd }) { const game = window.WW_DATA.games[p.game]; const [src, setSrc] = useSt(null); const SigilFallback = ({ mtg: window.SigilMagic, poke: window.SigilPokemon, rift: window.SigilRiftbound, op: window.SigilOnePiece, })[p.game]; useEf(() => { let cancelled = false; // — Magic via Scryfall if (p.scryfall) { const q = `https://api.scryfall.com/cards/named?exact=${encodeURIComponent(p.scryfall.name)}${p.scryfall.set ? '&set=' + p.scryfall.set : ''}`; fetch(q).then(r => r.ok ? r.json() : Promise.reject()) .then(card => { if (cancelled) return; const url = (card.image_uris && card.image_uris.normal) || (card.card_faces && card.card_faces[0].image_uris && card.card_faces[0].image_uris.normal); if (url) setSrc(url); }).catch(() => {}); } // — Pokémon via pokemontcg.io direct CDN (instant; falls back to API) else if (p.pokemon) { const [setId, num] = p.pokemon.id.split('-'); const direct = `https://images.pokemontcg.io/${setId}/${num}_hires.png`; const img = new Image(); img.onload = () => !cancelled && setSrc(direct); img.onerror = () => {}; img.src = direct; } // — One Piece via weserv-proxied Bandai EN cardlist else if (p.onepiece) { const id = p.onepiece.id; const sources = [ `https://images.weserv.nl/?url=en.onepiece-cardgame.com/images/cardlist/card/${id}.png`, `https://images.weserv.nl/?url=en.onepiece-cardgame.com/images/cardlist/card/${id}_p1.png`, `https://en.onepiece-cardgame.com/images/cardlist/card/${id}.png`, ]; let i = 0; const tryNext = () => { if (cancelled || i >= sources.length) return; const probe = new Image(); probe.onload = () => !cancelled && setSrc(sources[i]); probe.onerror = () => { i++; tryNext(); }; probe.src = sources[i]; }; tryNext(); } return () => { cancelled = true; }; }, [p.id]); return (
{p.badges.includes('hot') && Hot} {p.badges.includes('new') && New} {p.badges.includes('rare') && Rare} {p.badges.includes('sale') && Sale} {p.badges.includes('foil') && Foil}
{/* Sigil fallback — always rendered; image overlays on load */}
{SigilFallback ? : null}
{src && {p.name}}
{game.label}
{p.name}
{p.set}
{p.was && ${p.was.toFixed(2)}} ${p.price.toFixed(2)}
{p.stock}
); } function TrendingSection({ onAdd }) { const [filter, setFilter] = useSt('all'); const list = filter === 'all' ? window.WW_DATA.products : window.WW_DATA.products.filter(p => p.game === filter); const tabs = [ ['all', '✦ Trending'], ['mtg', '⚔️ Magic'], ['poke','⚡ Pokémon'], ['rift','🌊 Riftbound'], ['op', '☠️ One Piece'], ]; return (
{tabs.map(([k, l]) => ( ))}
{list.map(p => )}
); } // ── MYSTERY PACKS — preview/cards-mystery.html port ───────────────── // Tier ladder strip on top, rich art-deco card grid with arcane circles, // constellations, spacedust, smoke wisps, gilded corners + crest. const MYSTERY_TIER_CLS = { common: 't-common', uncommon: 't-uncommon', rare: 't-rare', 'very-rare': 't-very-rare', legendary: 't-legendary', }; const MYSTERY_TIER_CONFIG = { common: { wisps: 2, density: 22, bright: 3, circle: 'small', constellation: 'triangle' }, uncommon: { wisps: 2, density: 28, bright: 4, circle: 'small', constellation: 'triangle' }, rare: { wisps: 3, density: 34, bright: 6, circle: 'medium', constellation: 'pentagram' }, 'very-rare': { wisps: 3, density: 44, bright: 10, circle: 'medium', constellation: 'pentagram' }, legendary: { wisps: 4, density: 55, bright: 14, circle: 'large', constellation: 'heptagram' }, }; function MysteryCard({ pack, onOpen }) { const game = window.WW_DATA.games[pack.game]; const tierCls = MYSTERY_TIER_CLS[pack.tier] || ''; const cfg = MYSTERY_TIER_CONFIG[pack.tier] || MYSTERY_TIER_CONFIG.common; return (
{pack.tierLabel} {game.label.toUpperCase()}
{pack.name}
{pack.sub} · min ${pack.min}
Conjure ${pack.price.toFixed(2)}
); } function TierLadder() { const rungs = [ ['t-common', 'Common', '$4.99'], ['t-uncommon', 'Uncommon', '$9.99'], ['t-rare', 'Rare', '$24.99'], ['t-very-rare', 'Very Rare', '$49.99'], ['t-legendary', 'Legendary', '$99.99'], ]; return (
{rungs.map(([cls, name, price]) => (
{name} {price}
))}
); } function MysterySection({ onOpen }) { const rootRef = useEf ? React.useRef(null) : null; React.useEffect(() => { const root = rootRef && rootRef.current; if (!root) return; // Art-deco corner + crest SVGs const cornerSvg = (cls) => ` `; const crestSvg = ` `; root.querySelectorAll('.mystery .gilded-corners').forEach(el => { el.innerHTML = cornerSvg('tl') + cornerSvg('tr') + cornerSvg('bl') + cornerSvg('br'); }); root.querySelectorAll('.mystery .gilded-crest').forEach(el => { el.innerHTML = crestSvg; }); // Spacedust particle clouds root.querySelectorAll('.mystery .spacedust').forEach(box => { const card = box.closest('.mystery'); if (!card) return; const cs = getComputedStyle(card); const tierBright = cs.getPropertyValue('--tier-bright').trim(); const total = parseInt(box.dataset.density || '24', 10); const bright = parseInt(box.dataset.bright || '4', 10); const frag = document.createDocumentFragment(); for (let i = 0; i < total; i++) { const p = document.createElement('div'); p.className = 'p'; const r = Math.pow(Math.random(), 0.55) * 38; const a = Math.random() * Math.PI * 2; const sz = Math.random() * 1.4 + 0.4; p.style.left = (50 + Math.cos(a) * r) + '%'; p.style.top = (50 + Math.sin(a) * r) + '%'; p.style.width = sz + 'px'; p.style.height = sz + 'px'; p.style.background = i < bright ? tierBright : 'white'; p.style.color = tierBright; if (i < bright) p.classList.add('bright'); p.style.setProperty('--dur', (1.6 + Math.random() * 4) + 's'); p.style.setProperty('--delay', (Math.random() * 4) + 's'); p.style.setProperty('--min', (Math.random() * 0.1 + 0.05).toFixed(2)); p.style.setProperty('--max', (Math.random() * 0.4 + 0.6).toFixed(2)); frag.appendChild(p); } box.appendChild(frag); }); // Smoke wisps rising from base root.querySelectorAll('.mystery .smoke').forEach(s => { const n = parseInt(s.dataset.wisps || '3', 10); const frag = document.createDocumentFragment(); for (let i = 0; i < n; i++) { const w = document.createElement('div'); w.className = 'w'; w.style.left = (30 + Math.random() * 40) + '%'; w.style.setProperty('--drift', (Math.random() * 20 - 10) + '%'); w.style.setProperty('--dur', (6 + Math.random() * 4) + 's'); w.style.setProperty('--delay', (Math.random() * 6) + 's'); const sz = 60 + Math.random() * 60; w.style.width = sz + 'px'; w.style.height = sz + 'px'; frag.appendChild(w); } s.appendChild(frag); }); // Arcane summoning circle const SVGNS = 'http://www.w3.org/2000/svg'; root.querySelectorAll('.mystery .arcane-circle').forEach(box => { const svg = document.createElementNS(SVGNS, 'svg'); svg.setAttribute('viewBox', '0 0 100 100'); const ring = document.createElementNS(SVGNS, 'circle'); ring.setAttribute('cx', '50'); ring.setAttribute('cy', '50'); ring.setAttribute('r', '46'); ring.setAttribute('stroke-dasharray', '1.6 3'); svg.appendChild(ring); const ring2 = document.createElementNS(SVGNS, 'circle'); ring2.setAttribute('cx', '50'); ring2.setAttribute('cy', '50'); ring2.setAttribute('r', '40'); ring2.setAttribute('stroke-opacity', '0.4'); svg.appendChild(ring2); for (let i = 0; i < 12; i++) { const angle = (i * 30) * Math.PI / 180; const x1 = 50 + Math.cos(angle) * 42; const y1 = 50 + Math.sin(angle) * 42; const x2 = 50 + Math.cos(angle) * 46; const y2 = 50 + Math.sin(angle) * 46; const tick = document.createElementNS(SVGNS, 'line'); tick.setAttribute('x1', x1); tick.setAttribute('y1', y1); tick.setAttribute('x2', x2); tick.setAttribute('y2', y2); svg.appendChild(tick); } const glyphs = [['M',50,8],['☆',92,50],['M',50,92],['☆',8,50]]; glyphs.forEach(([ch,x,y]) => { const t = document.createElementNS(SVGNS, 'text'); t.setAttribute('class', 'glyph'); t.setAttribute('x', x); t.setAttribute('y', y + 2.5); t.setAttribute('text-anchor', 'middle'); t.textContent = ch; svg.appendChild(t); }); [[28,28],[72,28],[28,72],[72,72]].forEach(([x,y]) => { const c = document.createElementNS(SVGNS, 'circle'); c.setAttribute('class', 'dot'); c.setAttribute('cx', x); c.setAttribute('cy', y); c.setAttribute('r', '0.8'); svg.appendChild(c); }); box.appendChild(svg); }); // Constellations inside the orb const constellations = { triangle: [[50,18],[18,72],[82,72]], pentagram: [[50,12],[78,80],[10,42],[90,42],[22,80]], heptagram: [[50,8],[88,32],[78,82],[22,82],[12,32],[68,90],[32,90]], }; root.querySelectorAll('.mystery .constellation').forEach(box => { const pattern = box.dataset.pattern || 'triangle'; const pts = constellations[pattern] || constellations.triangle; const svg = document.createElementNS(SVGNS, 'svg'); svg.setAttribute('viewBox', '0 0 100 100'); const path = document.createElementNS(SVGNS, 'path'); let d = `M ${pts[0][0]} ${pts[0][1]} `; for (let i = 1; i < pts.length; i++) d += `L ${pts[i][0]} ${pts[i][1]} `; d += 'Z'; path.setAttribute('d', d); path.setAttribute('stroke-opacity', '0.8'); svg.appendChild(path); pts.forEach(([x,y]) => { const c = document.createElementNS(SVGNS, 'circle'); c.setAttribute('cx', x); c.setAttribute('cy', y); c.setAttribute('r', '1.4'); svg.appendChild(c); }); box.appendChild(svg); }); }, []); return (
{window.WW_DATA.mysteryPacks.map(pack => ( ))}
Every pack guarantees a hit. Declared minimum values are real — if your pack falls short, we'll make it right. Cards inspected, sleeved, and shipped with care.
); } function VaultFeed() { const [items, setItems] = useSt(() => window.WW_DATA.vaultEvents.slice(0, 5).map((e, i) => ({ ...e, id: i, t: 'just now' }))); useEf(() => { const id = setInterval(() => { setItems(prev => { const next = window.WW_DATA.vaultEvents[Math.floor(Math.random() * window.WW_DATA.vaultEvents.length)]; return [{ ...next, id: Date.now(), t: 'just now' }, ...prev.slice(0, 4).map(it => ({ ...it, t: typeof it.t === 'string' && it.t === 'just now' ? '12s' : it.t }))]; }); }, 4200); return () => clearInterval(id); }, []); return (
Live From the Vault

Real cards. Real pulls. right now.

Watch the vault breathe in real-time. Every sale, every new listing, every trade — pulled live from our inventory feed.

e.preventDefault()}>✦ Browse the Vault e.preventDefault()}>◈ View Sold Listings
✦ Recent Activity
Live
{items.map(it => (
{it.who.slice(0,2).toUpperCase()}
{it.who} {it.action} {it.product}
{it.t}
))}
); } function BuylistBanner({ onClick }) { return (
Buylist Open Now

Turn your collection into store credit or cash.

We pay top dollar for singles, bulk, sealed product, and entire collections. Get an instant quote online — or bring 'em into the shop. Yes, we want that binder.

Instant online quotes
30% bonus in store credit
Free shipping label
{ e.preventDefault(); onClick(); }}>✦ Get a Quote
); } function EventsSection() { return (
{window.WW_DATA.events.map((ev, i) => (
{ev.day}
{ev.month}
{ev.tag}
{ev.name}
{ev.body}
⏰ {ev.time}
💵 {ev.fee}
))}
); } function Newsletter() { const [email, setEmail] = useSt(''); const [done, setDone] = useSt(false); return (

Join the Inner Circle

First access to new singles, restocks, tournament announcements, and members-only deals.

{ e.preventDefault(); setDone(true); }}> setEmail(e.target.value)} />
Early restocks Event alerts Member deals No spam — ever
); } Object.assign(window, { SectionHead, GameCardGrid, ProductCard, TrendingSection, MysteryCard, MysterySection, VaultFeed, BuylistBanner, EventsSection, Newsletter });