SasuNaru Art

Comic Illustration Agreement

A premium two-phase contract workflow for comic adaptations and long-form illustration projects. Complete the agreement, download it as a document, save it as a PDF, and unlock the payment options.

Client contract form

This version uses your original layout, but with working calculations, document download, PDF save support, and Stripe payment unlock.

Seal of
Agreement

Stripe payment options

These payment buttons will appear after the agreement is completed and validated.

Initial payment — 2000 €

Use this button to activate the commission and begin Phase 1 storyboard production.

Installment payment — 500 €

Use this button for the agreed 500 € installment payments.

`; } function downloadDoc(){ updateSummary(); if (!validateForm(true)) return; const blob = new Blob(['\ufeff', getAgreementHTML()], { type: 'application/msword' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); const safeName = (fields.clientName.value || 'client').replace(/[^a-z0-9]+/gi, '-').replace(/^-+|-+$/g, ''); link.href = url; link.download = 'sasunaru-comic-agreement-' + safeName + '.doc'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); setStatus('ok', 'Agreement document downloaded successfully.'); } function printPdf(){ updateSummary(); if (!validateForm(true)) return; setStatus('ok', 'Use your browser print window to save the agreement as PDF.'); window.print(); } function ensureStripeScript(callback){ if (window.customElements && window.customElements.get('stripe-buy-button')) { callback(); return; } const existing = document.querySelector('script[data-sas-stripe-script="1"]'); if (existing) { existing.addEventListener('load', callback, { once: true }); setTimeout(callback, 1200); return; } const script = document.createElement('script'); script.src = 'https://js.stripe.com/v3/buy-button.js'; script.async = true; script.setAttribute('data-sas-stripe-script', '1'); script.onload = callback; document.head.appendChild(script); } function mountStripeButtons(){ const box2000 = $('sasStripe2000'); const box500 = $('sasStripe500'); if (!box2000 || !box500 || box2000.dataset.mounted === '1') return; box2000.innerHTML = ''; box500.innerHTML = ''; box2000.dataset.mounted = '1'; } function unlockPayments(){ updateSummary(); if (!validateForm(true)) { paymentGrid.classList.remove('active'); paymentBox.classList.remove('active'); return; } paymentGrid.classList.add('active'); paymentBox.classList.add('active'); ensureStripeScript(mountStripeButtons); setStatus('ok', 'Agreement completed successfully. The Stripe payment buttons are now unlocked.'); paymentBox.scrollIntoView({ behavior: 'smooth', block: 'start' }); } root.querySelectorAll('input, textarea, select').forEach(function(node){ node.addEventListener('input', updateSummary); node.addEventListener('change', updateSummary); node.addEventListener('keyup', updateSummary); }); $('sasGenerateBtn').addEventListener('click', function(){ updateSummary(); validateForm(true); }); $('sasDocBtn').addEventListener('click', downloadDoc); $('sasPrintBtn').addEventListener('click', printPdf); $('sasUnlockBtn').addEventListener('click', unlockPayments); form.addEventListener('submit', function(event){ event.preventDefault(); updateSummary(); validateForm(true); }); if (fields.signDate && !fields.signDate.value) { fields.signDate.value = new Date().toISOString().slice(0,10); } updateSummary(); })();