// ============================================= // PrintPro - Main Frontend Script // ============================================= // --- DEFAULT PRICING DATA --- const DEFAULT_PRICING = { products: { 'business-cards': { name: 'Business Cards', icon: 'credit-card', image: 'http://static.photos/office/320x240/42', basePrice: 19.00, sizes: [ { id: '3.5x2', name: '3.5" x 2"', price: 0 }, { id: '3.5x2-rounded', name: '3.5" x 2" Rounded', price: 4 }, { id: '3.5x2-square', name: '3.5" x 3.5" Square', price: 6 } ], paperTypes: [ { id: '14pt-gloss', name: '14pt Gloss', price: 0 }, { id: '16pt-matte', name: '16pt Matte', price: 6 }, { id: '14pt-uncoated', name: '14pt Uncoated', price: 3 }, { id: '16pt-silk', name: '16pt Silk', price: 8 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'matte', name: 'Matte Coating', price: 5 }, { id: 'gloss', name: 'Gloss Coating', price: 5 }, { id: 'uv', name: 'UV Spot Gloss', price: 12 }, { id: 'foil', name: 'Foil Stamp', price: 18 } ], quantityTiers: [ { min: 50, max: 250, multiplier: 1.0, label: '50-250' }, { min: 251, max: 500, multiplier: 0.75, label: '251-500' }, { min: 501, max: 1000, multiplier: 0.55, label: '501-1K' }, { min: 1001, max: 2500, multiplier: 0.40, label: '1K-2.5K' }, { min: 2501, max: 5000, multiplier: 0.30, label: '2.5K-5K' }, { min: 5001, max: 10000, multiplier: 0.22, label: '5K-10K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 15 }, { id: 'express', name: 'Express (1-2 days)', price: 30 } ], defaultQuantity: 500 }, 'flyers': { name: 'Flyers', icon: 'file-text', image: 'http://static.photos/office/320x240/55', basePrice: 35.00, sizes: [ { id: '8.5x11', name: '8.5" x 11"', price: 0 }, { id: '5.5x8.5', name: '5.5" x 8.5"', price: -3 }, { id: '11x17', name: '11" x 17"', price: 8 } ], paperTypes: [ { id: '100lb-gloss', name: '100lb Gloss', price: 0 }, { id: '80lb-matte', name: '80lb Matte', price: -2 }, { id: '100lb-uncoated', name: '100lb Uncoated', price: 2 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'matte', name: 'Matte Coating', price: 8 }, { id: 'gloss', name: 'Gloss Coating', price: 8 } ], quantityTiers: [ { min: 50, max: 250, multiplier: 1.0, label: '50-250' }, { min: 251, max: 500, multiplier: 0.70, label: '251-500' }, { min: 501, max: 1000, multiplier: 0.50, label: '501-1K' }, { min: 1001, max: 5000, multiplier: 0.35, label: '1K-5K' }, { min: 5001, max: 10000, multiplier: 0.25, label: '5K-10K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 20 }, { id: 'express', name: 'Express (1-2 days)', price: 40 } ], defaultQuantity: 250 }, 'brochures': { name: 'Brochures', icon: 'book-open', image: 'http://static.photos/office/320x240/67', basePrice: 55.00, sizes: [ { id: '8.5x11-bi', name: '8.5"x11" Bi-Fold', price: 0 }, { id: '8.5x11-tri', name: '8.5"x11" Tri-Fold', price: 3 }, { id: '11x17-bi', name: '11"x17" Bi-Fold', price: 10 } ], paperTypes: [ { id: '100lb-gloss', name: '100lb Gloss', price: 0 }, { id: '80lb-matte', name: '80lb Matte', price: -3 }, { id: '100lb-silk', name: '100lb Silk', price: 5 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'matte', name: 'Matte Coating', price: 10 }, { id: 'gloss', name: 'Gloss Coating', price: 10 } ], quantityTiers: [ { min: 25, max: 100, multiplier: 1.0, label: '25-100' }, { min: 101, max: 250, multiplier: 0.70, label: '101-250' }, { min: 251, max: 500, multiplier: 0.52, label: '251-500' }, { min: 501, max: 1000, multiplier: 0.40, label: '501-1K' }, { min: 1001, max: 5000, multiplier: 0.30, label: '1K-5K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 25 }, { id: 'express', name: 'Express (1-2 days)', price: 50 } ], defaultQuantity: 100 }, 'banners': { name: 'Banners', icon: 'flag', image: 'http://static.photos/office/320x240/78', basePrice: 45.00, sizes: [ { id: '24x36', name: '24" x 36"', price: 0 }, { id: '36x48', name: '36" x 48"', price: 15 }, { id: '48x72', name: '48" x 72"', price: 35 } ], paperTypes: [ { id: 'vinyl', name: '13oz Vinyl', price: 0 }, { id: 'mesh', name: 'Mesh Vinyl', price: 8 }, { id: 'fabric', name: 'Fabric', price: 20 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'grommets', name: 'Grommets', price: 5 }, { id: 'pole-pockets', name: 'Pole Pockets', price: 10 } ], quantityTiers: [ { min: 1, max: 5, multiplier: 1.0, label: '1-5' }, { min: 6, max: 10, multiplier: 0.80, label: '6-10' }, { min: 11, max: 25, multiplier: 0.65, label: '11-25' }, { min: 26, max: 50, multiplier: 0.50, label: '26-50' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 20 }, { id: 'express', name: 'Express (1-2 days)', price: 45 } ], defaultQuantity: 1 }, 'stickers': { name: 'Stickers & Labels', icon: 'sticky-note', image: 'http://static.photos/office/320x240/91', basePrice: 25.00, sizes: [ { id: '2x2', name: '2" x 2"', price: 0 }, { id: '3x3', name: '3" x 3"', price: 5 }, { id: '4x4', name: '4" x 4"', price: 8 }, { id: 'custom-die', name: 'Custom Die-Cut', price: 15 } ], paperTypes: [ { id: 'white-vinyl', name: 'White Vinyl', price: 0 }, { id: 'clear-vinyl', name: 'Clear Vinyl', price: 5 }, { id: 'metallic', name: 'Metallic', price: 10 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'matte-lam', name: 'Matte Laminate', price: 6 }, { id: 'gloss-lam', name: 'Gloss Laminate', price: 6 } ], quantityTiers: [ { min: 50, max: 250, multiplier: 1.0, label: '50-250' }, { min: 251, max: 500, multiplier: 0.70, label: '251-500' }, { min: 501, max: 1000, multiplier: 0.48, label: '501-1K' }, { min: 1001, max: 2500, multiplier: 0.35, label: '1K-2.5K' }, { min: 2501, max: 5000, multiplier: 0.25, label: '2.5K-5K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 12 }, { id: 'express', name: 'Express (1-2 days)', price: 28 } ], defaultQuantity: 250 }, 'postcards': { name: 'Postcards', icon: 'mail', image: 'http://static.photos/office/320x240/33', basePrice: 28.00, sizes: [ { id: '4x6', name: '4" x 6"', price: 0 }, { id: '5x7', name: '5" x 7"', price: 4 }, { id: '6x9', name: '6" x 9"', price: 7 }, { id: '6x11', name: '6" x 11"', price: 10 } ], paperTypes: [ { id: '14pt-gloss', name: '14pt Gloss', price: 0 }, { id: '16pt-matte', name: '16pt Matte', price: 5 }, { id: '14pt-uncoated', name: '14pt Uncoated', price: 2 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'matte', name: 'Matte Coating', price: 5 }, { id: 'gloss', name: 'Gloss Coating', price: 5 }, { id: 'uv-front', name: 'UV Front Only', price: 8 } ], quantityTiers: [ { min: 100, max: 500, multiplier: 1.0, label: '100-500' }, { min: 501, max: 1000, multiplier: 0.72, label: '501-1K' }, { min: 1001, max: 2500, multiplier: 0.52, label: '1K-2.5K' }, { min: 2501, max: 5000, multiplier: 0.38, label: '2.5K-5K' }, { min: 5001, max: 10000, multiplier: 0.28, label: '5K-10K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 12 }, { id: 'express', name: 'Express (1-2 days)', price: 28 } ], defaultQuantity: 500 }, 'letterhead': { name: 'Letterhead', icon: 'file', image: 'http://static.photos/office/320x240/44', basePrice: 40.00, sizes: [ { id: '8.5x11', name: '8.5" x 11"', price: 0 }, { id: '8.5x14', name: '8.5" x 14"', price: 5 } ], paperTypes: [ { id: '24lb-bond', name: '24lb Bond', price: 0 }, { id: '28lb-bond', name: '28lb Bond', price: 5 }, { id: '32lb-bond', name: '32lb Bond', price: 10 }, { id: 'linen', name: 'Linen Finish', price: 15 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'watermark', name: 'Watermark', price: 8 } ], quantityTiers: [ { min: 100, max: 500, multiplier: 1.0, label: '100-500' }, { min: 501, max: 1000, multiplier: 0.70, label: '501-1K' }, { min: 1001, max: 2500, multiplier: 0.48, label: '1K-2.5K' }, { min: 2501, max: 5000, multiplier: 0.35, label: '2.5K-5K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 18 }, { id: 'express', name: 'Express (1-2 days)', price: 38 } ], defaultQuantity: 500 }, 'envelopes': { name: 'Envelopes', icon: 'mail-open', image: 'http://static.photos/office/320x240/56', basePrice: 32.00, sizes: [ { id: '10-standard', name: '#10 Standard', price: 0 }, { id: 'a7', name: 'A7 (5.25x7.25)', price: 3 }, { id: 'a2', name: 'A2 (4.375x5.75)', price: 0 } ], paperTypes: [ { id: '24lb-white', name: '24lb White Wove', price: 0 }, { id: '28lb-white', name: '28lb White Wove', price: 4 }, { id: 'kraft', name: 'Kraft Brown', price: 3 } ], finishing: [ { id: 'none', name: 'None', price: 0 }, { id: 'window', name: 'Window', price: 5 }, { id: 'peel-seal', name: 'Peel & Seal', price: 4 } ], quantityTiers: [ { min: 100, max: 500, multiplier: 1.0, label: '100-500' }, { min: 501, max: 1000, multiplier: 0.72, label: '501-1K' }, { min: 1001, max: 2500, multiplier: 0.52, label: '1K-2.5K' }, { min: 2501, max: 5000, multiplier: 0.36, label: '2.5K-5K' } ], turnaround: [ { id: 'standard', name: 'Standard (5-7 days)', price: 0 }, { id: 'rush', name: 'Rush (3-4 days)', price: 15 }, { id: 'express', name: 'Express (1-2 days)', price: 32 } ], defaultQuantity: 250 } } }; // --- INITIALIZE PRICING --- function getPricing() { const stored = localStorage.getItem('printpro_pricing'); if (stored) { try { return JSON.parse(stored); } catch (e) { return DEFAULT_PRICING; } } // Set default on first load localStorage.setItem('printpro_pricing', JSON.stringify(DEFAULT_PRICING)); return DEFAULT_PRICING; } // --- STATE --- let pricing = getPricing(); let selectedProduct = 'business-cards'; let selectedSize = null; let selectedPaper = null; let selectedFinishing = null; let selectedTurnaround = null; let currentQuantity = 500; // --- DOM ELEMENTS --- const productGrid = document.getElementById('productGrid'); const productSelector = document.getElementById('productSelector'); const sizeOptions = document.getElementById('sizeOptions'); const paperOptions = document.getElementById('paperOptions'); const finishingOptions = document.getElementById('finishingOptions'); const turnaroundOptions = document.getElementById('turnaroundOptions'); const quantitySlider = document.getElementById('quantitySlider'); const quantityDisplay = document.getElementById('quantityDisplay'); const qtyMin = document.getElementById('qtyMin'); const qtyMax = document.getElementById('qtyMax'); const totalPrice = document.getElementById('totalPrice'); const pricePerUnit = document.getElementById('pricePerUnit'); const heroPrice = document.getElementById('heroPrice'); const toast = document.getElementById('toast'); const toastMsg = document.getElementById('toastMsg'); const mobileMenuBtn = document.getElementById('mobileMenuBtn'); const mobileMenu = document.getElementById('mobileMenu'); // --- MOBILE MENU --- mobileMenuBtn.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); }); // Close mobile menu when clicking a link mobileMenu.querySelectorAll('a').forEach(link => { link.addEventListener('click', () => { mobileMenu.classList.add('hidden'); }); }); // --- RENDER PRODUCT GRID --- function renderProductGrid() { const products = pricing.products; productGrid.innerHTML = Object.entries(products).map(([key, product]) => `
From $${product.basePrice.toFixed(2)}