// Shared design tokens: palette derived from "coin on crystal" hero photo: // kyanite-blue crystals, frosty quartz whites, raspberry tourmaline, and pure gold buffalo coin const PCB_TOKENS = { navy: '#1a3a6e', // kyanite blue (deep) navyDeep: '#0f2348', // shadow blue from crystal cracks navySoft: '#2c5394', // mid kyanite gold: '#d4a64a', // buffalo coin gold goldBright: '#e8c977', // coin highlight goldDeep: '#a87a2e', // coin shadow cream: '#f2ecdf', // frosty quartz paper: '#faf6ec', // off-white quartz highlight ink: '#1a1a1a', raspberry: '#8b3a4e', // tourmaline accent rule: 'rgba(212, 166, 74, 0.35)', ruleSoft: 'rgba(212, 166, 74, 0.18)', }; // Inline SVG: shop building (Victorian): placeholder silhouette const ShopBuilding = ({ style, tone = 'gold' }) => { const c = tone === 'gold' ? PCB_TOKENS.gold : '#fff'; return ( ); }; // Coin SVG: used as decorative element const Coin = ({ size = 60, label = '50', style }) => ( ); // Mountain ridge SVG const MountainRidge = ({ style, color = '#0a1422' }) => ( ); // Stack imagery placeholders const VaultInterior = ({ style }) => ( ); const CoinDisplay = ({ style }) => ( ); const RawSpecimen = ({ style }) => ( ); // Logo / wordmark: uses the bison mark from uploaded logo const PCBLogo = ({ color = '#d4a64a', style, size = 'md' }) => { const s = size === 'lg' ? { mark: 56, gap: 14, title: 28, sub: 11 } : size === 'md' ? { mark: 44, gap: 12, title: 20, sub: 9 } : { mark: 32, gap: 8, title: 16, sub: 8 }; // The PNG has a white background; use mix-blend-mode multiply on light surfaces, // and on dark surfaces wrap it in a light circle so the white doesn't clash. const isLight = color === '#fff' || color === '#ffffff' || color.toLowerCase().startsWith('#f'); return (
Parker Coin & Bullion
); }; // Real photos: local files (uploaded by user) const PCB_PHOTOS = { // Crystal+coin signature image, two tiers: 1280 native (sharpened) and a // Lanczos-upscaled+sharpened 2560 for desktop/retina via srcset. The old // crystal-coin.png (4.4MB) stays on disk as the master but is not shipped. heroMountains: 'images/hero-crystal-1280.jpg', heroMountains2x: 'images/hero-crystal-2560.jpg', // Photos pulled from the client's live Google Site 2026-07-29 (see // parkerbullion/site-images/): storefront w/ clock tower, interior w/ bison // skull, graded gold tray, silver rounds tray. colorado-mountains.jpg is // staged in images/ but not yet placed anywhere. shopBuilding: 'images/storefront.jpg', coinCases: 'images/coin-cases.jpg', shopInterior: 'images/interior-bison.jpg', goldBars: 'images/gold-bars.jpg', gradedGold: 'images/graded-gold.jpg', silverTray: 'images/silver-tray.jpg', bisonLogo: 'images/bison-logo.png', }; // Photo wrappers: TRY real photos, fall back to SVG placeholders if Google's CDN blocks the request. // Google Sites' lh3.googleusercontent.com URLs are referrer-locked, so cross-origin loads from this // preview will fail. We swap to the SVG placeholder on `onError`. const PhotoWithFallback = ({ src, srcSet, sizes, Fallback, style, alt }) => { const [failed, setFailed] = React.useState(false); if (failed) return ; return setFailed(true)} style={{ width: '100%', display: 'block', objectFit: 'cover', ...style }} alt={alt}/>; }; const PhotoShop = ({ style }) => ( ); const PhotoInterior = ({ style }) => ( ); const PhotoCases = ({ style }) => ( ); const PhotoSpread = ({ style }) => ( ); const PhotoCrystal = ({ style }) => ( ); const PhotoGoldBars = ({ style }) => ( ); // Real-photo mountain hero (uses backgroundImage so it can fill an arbitrary box) const PhotoMountainBg = ({ style, children }) => (
{children}
); // Mountain hero with fallback to SVG ridge const PhotoMountainHero = ({ opacity = 1 }) => { const [failed, setFailed] = React.useState(false); if (failed) { return ( <>
); } return ( <> setFailed(true)} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', opacity }} alt=""/>
); }; Object.assign(window, { PCB_TOKENS, PCB_PHOTOS, ShopBuilding, Coin, MountainRidge, VaultInterior, CoinDisplay, RawSpecimen, PCBLogo, PhotoShop, PhotoInterior, PhotoCases, PhotoSpread, PhotoCrystal, PhotoGoldBars, PhotoMountainBg, PhotoMountainHero, });