/** * Hyperclay Newsletter Form * A self-contained, embeddable newsletter signup form * * Usage: * *
* * * Options: * hyperclayNewsletterify(el, { * tags: ['custom-tag'], // Additional tags for the subscriber * onSuccess: (email) => {}, // Called after successful subscription * onError: (error) => {} // Called on error * }); */ (function(global) { 'use strict'; // Embedded SVG icons as data URIs const ICONS = { // Newsletter icon - stylized envelope with checkmark newsletter: `data:image/svg+xml,${encodeURIComponent(``)}`, // Toast icons toastSuccess: ``, toastError: `` }; // Scoped styles const STYLES = ` .hc-newsletter-form { position: relative; max-width: 400px; margin-left: auto; margin-right: auto; font-family: inherit; box-sizing: border-box; } @media (min-width: 640px) { .hc-newsletter-form { max-width: 500px; } } .hc-newsletter-form *, .hc-newsletter-form *::before, .hc-newsletter-form *::after { box-sizing: border-box; } .hc-newsletter-header { margin-bottom: 15px; text-align: center; color: inherit; font-size: inherit; } .hc-newsletter-icon { position: relative; top: -4px; display: inline-block; height: 24px; vertical-align: middle; margin-left: 4px; } .hc-input-wrapper { position: relative; height: 48px; margin-bottom: 25px; transition: box-shadow 0.15s ease; } .hc-input-wrapper:focus-within { box-shadow: 0 0 0 4px #0B0C12, 0 0 0 6px #fff; } .hc-honeypot { position: absolute; left: -9999px; opacity: 0; pointer-events: none; } .hc-email-input { position: absolute; inset: 0; width: 100%; height: 100%; text-align: center; color: #1e293b; background: #fff; border: none; outline: none; font-family: inherit; font-size: inherit; } .hc-email-input::placeholder { color: #94a3b8; } .hc-corner-tl, .hc-corner-br { position: absolute; pointer-events: none; } .hc-corner-tl { top: 0; left: 0; width: 30px; height: 27px; } .hc-corner-br { bottom: 0; right: 0; width: 30px; height: 27px; } .hc-corner-tl > div, .hc-corner-br > div { position: absolute; background-color: var(--hc-bg, #0B0C12); } /* Top-left corner blocks */ .hc-corner-tl .b1 { left: 0; top: 0; width: 11px; height: 10px; } .hc-corner-tl .b2 { left: 3px; top: 13px; width: 11px; height: 10px; } .hc-corner-tl .b3 { left: 15px; top: 2px; width: 8px; height: 8px; } .hc-corner-tl .b4 { left: 17px; top: 13px; width: 6px; height: 7px; } .hc-corner-tl .b5 { left: 17px; top: 22px; width: 5px; height: 5px; } .hc-corner-tl .b6 { left: 24px; top: 21px; width: 5px; height: 5px; } .hc-corner-tl .b7 { left: 25px; top: 5px; width: 5px; height: 5px; } .hc-corner-tl .b8 { left: 25px; top: 13px; width: 5px; height: 5px; } /* Bottom-right corner blocks (mirror of top-left) */ .hc-corner-br .b1 { right: 0; bottom: 0; width: 11px; height: 10px; } .hc-corner-br .b2 { right: 3px; bottom: 13px; width: 11px; height: 10px; } .hc-corner-br .b3 { right: 15px; bottom: 2px; width: 8px; height: 8px; } .hc-corner-br .b4 { right: 17px; bottom: 13px; width: 6px; height: 7px; } .hc-corner-br .b5 { right: 17px; bottom: 22px; width: 5px; height: 5px; } .hc-corner-br .b6 { right: 24px; bottom: 21px; width: 5px; height: 5px; } .hc-corner-br .b7 { right: 25px; bottom: 5px; width: 5px; height: 5px; } .hc-corner-br .b8 { right: 25px; bottom: 13px; width: 5px; height: 5px; } .hc-button-wrapper { text-align: center; } .hc-submit-btn { font-family: inherit; text-align: center; cursor: pointer; border-width: 3px; border-style: solid; border-top-color: #474C65; border-right-color: #131725; border-bottom-color: #131725; border-left-color: #474C65; background-color: #1D1F2F; padding: 8px 44px 11px; font-size: inherit; color: #fff; transition: background-color 0.1s ease; } @media (min-width: 640px) { .hc-submit-btn { padding: 8px 50px 11px; } } .hc-submit-btn:hover { background-color: #232639; } .hc-submit-btn:active { border-top-color: #131725; border-right-color: #474C65; border-bottom-color: #474C65; border-left-color: #131725; } .hc-submit-btn:active .hc-btn-text { transform: translate(1.5px, 1.5px); } .hc-btn-text { display: inline-block; white-space: nowrap; user-select: none; transition: transform 0.05s ease; } /* Toast styles */ .hc-toast-container { z-index: 9999; position: fixed; top: 20px; right: 20px; display: flex; flex-direction: column; align-items: flex-end; } .hc-toast-container > * + * { margin-top: 18px; } .hc-toast { position: relative; right: 0; display: flex; align-items: center; padding: 10px 19px 11px 17px; cursor: pointer; color: rgba(255,255,255,.8); background-color: #0B0C12; border: 2px dashed rgba(255,255,255,.6); transition: right 0.5s ease-in-out, opacity 0.5s ease-in-out; font-family: inherit; font-size: inherit; } .hc-toast svg { position: relative; top: -1px; width: 17px; height: 17px; margin-right: 13px; flex-shrink: 0; } .hc-toast.hc-hide { right: -300px; opacity: 0; } .hc-toast.hc-success { color: #76C824; border: 2px dashed #589E11; } .hc-toast.hc-error { color: #DD304F; border: 2px dashed #CD2140; } `; // Buttondown API configuration const API_TOKEN = '8b1688f6-5a75-4c45-8da8-09f71d9a5c3b'; const API_URL = 'https://api.buttondown.com/v1/subscribers'; // Inject styles once let stylesInjected = false; function injectStyles() { if (stylesInjected) return; if (document.getElementById('hc-newsletter-styles')) { stylesInjected = true; return; } const styleEl = document.createElement('style'); styleEl.id = 'hc-newsletter-styles'; styleEl.textContent = STYLES; document.head.appendChild(styleEl); stylesInjected = true; } // Toast notification system function showToast(message, type = 'success') { let container = document.querySelector('.hc-toast-container'); if (!container) { container = document.createElement('div'); container.className = 'hc-toast-container'; document.body.appendChild(container); } const icon = type === 'success' ? ICONS.toastSuccess : ICONS.toastError; const toast = document.createElement('div'); toast.className = `hc-toast hc-hide hc-${type}`; toast.innerHTML = `${icon}${message}`; toast.addEventListener('click', () => { toast.classList.add('hc-hide'); setTimeout(() => toast.remove(), 500); }); container.appendChild(toast); setTimeout(() => toast.classList.remove('hc-hide'), 10); setTimeout(() => { toast.classList.add('hc-hide'); setTimeout(() => toast.remove(), 500); }, 6600); } // Generate unique form ID let formCounter = 0; function getUniqueId() { return `hc-newsletter-form-${++formCounter}`; } /** * Insert a fully styled Hyperclay newsletter form into an element * @param {HTMLElement} el - The container element * @param {Object} options - Optional configuration * @param {string[]} options.tags - Additional tags for the subscriber (default: ['embedded-form', 'newsletter']) * @param {Function} options.onSuccess - Called after successful subscription with email * @param {Function} options.onError - Called on error with error object * @returns {HTMLFormElement} The created form element */ function hyperclayNewsletterify(el, options = {}) { if (!el || !(el instanceof HTMLElement)) { console.error('hyperclayNewsletterify: Invalid element provided'); return null; } injectStyles(); const formId = getUniqueId(); const tags = options.tags || ['embedded-form', 'newsletter']; const form = document.createElement('form'); form.id = formId; form.className = 'hc-newsletter-form'; form.innerHTML = `