import { useState, useEffect, useRef } from “react”;
const STRIPE_LINK = “YOUR_STRIPE_LINK_HERE”;
const AFFIRMATIONS = [
“I affirm sole, undivided belief in One God.”,
“I stand in unity under One God.”,
“I affirm one universal, undivided source above all.”,
];
const EDITIONS = [“Genesis Edition”, “Standard Edition”, “Founding Edition”];
function todayLine() {
return new Date().toLocaleDateString(“en-US”, {
year: “numeric”, month: “long”, day: “numeric”,
});
}
function wrapTextLines(ctx, text, maxWidth) {
const words = text.split(” “);
let line = “”;
const lines = [];
for (let n = 0; n < words.length; n++) {
const testLine = line + words[n] + “ “;
if (ctx.measureText(testLine).width > maxWidth && n > 0) {
lines.push(line.trim());
line = words[n] + “ “;
} else {
line = testLine;
}
}
lines.push(line.trim());
return lines;
}
function roundedRect(ctx, x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
function drawCard(canvas, name, affirmation, edition) {
const ctx = canvas.getContext(“2d”);
canvas.width = 1600;
canvas.height = 2200;
const w = canvas.width, h = canvas.height;
// Background
const grad = ctx.createLinearGradient(0, 0, 0, h);
grad.addColorStop(0, “#f4ead2”);
grad.addColorStop(1, “#f0e2bf”);
ctx.fillStyle = grad;
ctx.fillRect(0, 0, w, h);
// Top glow
const glow = ctx.createRadialGradient(w / 2, 170, 20, w / 2, 170, 420);
glow.addColorStop(0, “rgba(255,255,255,.35)”);
glow.addColorStop(1, “rgba(255,255,255,0)”);
ctx.fillStyle = glow;
ctx.fillRect(0, 0, w, h);
// Outer border
ctx.strokeStyle = “#b88a2a”;
ctx.lineWidth = 8;
roundedRect(ctx, 16, 16, w - 32, h - 32, 32);
ctx.stroke();
// Inner border
ctx.strokeStyle = “rgba(184,138,42,.62)”;
ctx.lineWidth = 3;
roundedRect(ctx, 62, 62, w - 124, h - 124, 18);
ctx.stroke();
// Icon
ctx.font = “120px Georgia”;
ctx.textAlign = “center”;
ctx.fillStyle = “#b88a2a”;
ctx.fillText(“💡”, w / 2, 240);
// Brand
ctx.fillStyle = “#1d160d”;
ctx.font = “700 102px Georgia”;
ctx.fillText(“ONEGODIAN”, w / 2, 405);
// Divider line
ctx.strokeStyle = “rgba(184,138,42,.62)”;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(260, 470);
ctx.lineTo(w - 260, 470);
ctx.stroke();
// Star ornament
ctx.fillStyle = “#b88a2a”;
ctx.font = “30px Georgia”;
ctx.fillText(“✦”, w / 2, 493);
// Affirmation text
ctx.fillStyle = “#2b2116”;
ctx.font = “58px Georgia”;
const lines = wrapTextLines(ctx, affirmation, 980);
const lineH = 82;
const affTop = 640;
lines.forEach((l, i) => ctx.fillText(l, w / 2, affTop + i * lineH));
const ruleY = affTop + lines.length * lineH + 42;
// Dashed rule
ctx.setLineDash([10, 10]);
ctx.strokeStyle = “rgba(184,138,42,.65)”;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(180, ruleY);
ctx.lineTo(w - 180, ruleY);
ctx.stroke();
ctx.setLineDash([]);
// Signature
ctx.fillStyle = “#3b2416”;
ctx.font = “88px cursive”;
ctx.fillText(name, w / 2, ruleY + 120);
// Sig underline
ctx.setLineDash([4, 8]);
ctx.strokeStyle = “rgba(184,138,42,.65)”;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(380, ruleY + 155);
ctx.lineTo(w - 380, ruleY + 155);
ctx.stroke();
ctx.setLineDash([]);
// Date
ctx.fillStyle = “#463722”;
ctx.font = “38px Georgia”;
ctx.fillText(todayLine(), w / 2, ruleY + 240);
// Footer
ctx.fillStyle = “#6f5a33”;
ctx.font = “30px Georgia”;
ctx.fillText(edition + “ • OneGodian™ Declaration Card”, w / 2, h - 90);
}
function drawSeal(canvas, name, edition) {
const ctx = canvas.getContext(“2d”);
canvas.width = 1600;
canvas.height = 1600;
const w = canvas.width, h = canvas.height;
const cx = w / 2, cy = h / 2;
// Background
ctx.fillStyle = “#05070a”;
ctx.fillRect(0, 0, w, h);
// Center glow
const glow = ctx.createRadialGradient(cx, cy, 40, cx, cy, 420);
glow.addColorStop(0, “rgba(255,216,107,.95)”);
glow.addColorStop(0.16, “rgba(212,175,55,.55)”);
glow.addColorStop(0.45, “rgba(212,175,55,.10)”);
glow.addColorStop(1, “rgba(212,175,55,0)”);
ctx.fillStyle = glow;
ctx.beginPath();
ctx.arc(cx, cy, 500, 0, Math.PI * 2);
ctx.fill();
// Rings
ctx.strokeStyle = “rgba(212,175,55,.82)”;
ctx.lineWidth = 5;
[620, 560, 500].forEach(r => {
ctx.beginPath();
ctx.arc(cx, cy, r, 0, Math.PI * 2);
ctx.stroke();
});
// Diamond marks at cardinal points
const marks = [
[cx, cy - 638], [cx, cy + 638],
[cx - 638, cy], [cx + 638, cy],
];
marks.forEach(([mx, my]) => {
ctx.save();
ctx.translate(mx, my);
ctx.rotate(Math.PI / 4);
const mg = ctx.createLinearGradient(-10, -10, 10, 10);
mg.addColorStop(0, “#f0d67a”);
mg.addColorStop(1, “#d4af37”);
ctx.fillStyle = mg;
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();
});
// Radial rays
ctx.save();
ctx.translate(cx, cy);
[0, 45, 90, 135].forEach(deg => {
ctx.save();
ctx.rotate((deg * Math.PI) / 180);
const rayGrad = ctx.createLinearGradient(-400, 0, 400, 0);
rayGrad.addColorStop(0, “rgba(255,218,123,0)”);
rayGrad.addColorStop(0.5, “rgba(255,218,123,.95)”);
rayGrad.addColorStop(1, “rgba(255,218,123,0)”);
ctx.strokeStyle = rayGrad;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(-400, 0);
ctx.lineTo(400, 0);
ctx.stroke();
ctx.restore();
});
ctx.restore();
// Core 12-pointed polygon
const coreR = 260;
const pts = 12;
ctx.save();
ctx.translate(cx, cy);
ctx.beginPath();
for (let i = 0; i < pts; i++) {
const angle = (i * 2 * Math.PI) / pts - Math.PI / 2;
const r = i % 2 === 0 ? coreR : coreR * 0.78;
const x = Math.cos(angle) * r;
const y = Math.sin(angle) * r;
i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
}
ctx.closePath();
const coreGrad = ctx.createLinearGradient(-coreR, -coreR, coreR, coreR);
coreGrad.addColorStop(0, “#030303”);
coreGrad.addColorStop(0.58, “#0d0d0d”);
coreGrad.addColorStop(1, “#151515”);
ctx.fillStyle = coreGrad;
ctx.fill();
ctx.strokeStyle = “rgba(212,175,55,.55)”;
ctx.lineWidth = 4;
ctx.stroke();
// Inner core glow
const innerGlow = ctx.createRadialGradient(0, 0, 10, 0, 0, 160);
innerGlow.addColorStop(0, “rgba(255,216,107,1)”);
innerGlow.addColorStop(0.18, “rgba(212,175,55,.88)”);
innerGlow.addColorStop(0.46, “rgba(212,175,55,.12)”);
innerGlow.addColorStop(0.65, “rgba(212,175,55,0)”);
ctx.fillStyle = innerGlow;
ctx.beginPath();
ctx.arc(0, 0, 160, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
// ONEGODIAN label
ctx.fillStyle = “#f0d67a”;
ctx.font = “700 76px Georgia”;
ctx.textAlign = “center”;
ctx.fillText(“ONEGODIAN”, cx, h - 180);
// Sub label
ctx.fillStyle = “rgba(255,255,255,.70)”;
ctx.font = “32px Georgia”;
ctx.letterSpacing = “0.12em”;
ctx.fillText((edition + “ • Personalized Preview”).toUpperCase(), cx, h - 120);
// Name
ctx.fillStyle = “rgba(255,255,255,.52)”;
ctx.font = “28px Georgia”;
ctx.fillText(name, cx, h - 68);
}
export default function OneGodianGenerator() {
const [name, setName] = useState(“Gregory Lamar Jones”);
const [affirmation, setAffirmation] = useState(AFFIRMATIONS[0]);
const [edition, setEdition] = useState(EDITIONS[0]);
const [view, setView] = useState(“card”);
const [isPaid, setIsPaid] = useState(false);
const [generated, setGenerated] = useState(true);
const canvasRef = useRef(null);
useEffect(() => {
const params = new URLSearchParams(window.location.search);
if (params.get(“paid”) === “1”) setIsPaid(true);
}, []);
useEffect(() => {
if (generated) renderCanvas();
}, [generated, view]);
function renderCanvas() {
const canvas = canvasRef.current;
if (!canvas) return;
if (view === “card”) drawCard(canvas, name, affirmation, edition);
else drawSeal(canvas, name, edition);
}
function handleGenerate() {
setGenerated(false);
setTimeout(() => setGenerated(true), 10);
}
function handleReset() {
setName(“Gregory Lamar Jones”);
setAffirmation(AFFIRMATIONS[0]);
setEdition(EDITIONS[0]);
setView(“card”);
setTimeout(() => setGenerated(true), 10);
}
function handleUnlock() {
if (!STRIPE_LINK || STRIPE_LINK === “YOUR_STRIPE_LINK_HERE”) {
alert(“Add your Stripe payment link in the script first.”);
return;
}
window.location.href = STRIPE_LINK;
}
function handleDownload() {
if (!isPaid) {
handleUnlock();
return;
}
const canvas = canvasRef.current;
if (!canvas) return;
const link = document.createElement(“a”);
link.download = view === “card”
? `onegodian-declaration-card-${name.replace(/\s+/g, "-").toLowerCase()}.png`
: `onegodian-seal-${edition.replace(/\s+/g, "-").toLowerCase()}.png`;
link.href = canvas.toDataURL(“image/png”);
link.click();
}
const css = `@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700;900&family=Lato:wght@300;400;700&display=swap'); .og-wrap{ font-family: 'Lato', sans-serif; color: #eef4fb; background: linear-gradient(180deg, #07131f, #0d2236); border-radius: 24px; padding: 28px; box-shadow: 0 24px 60px rgba(0,0,0,.28); overflow: hidden; } .og-wrap * { box-sizing: border-box; } .og-grid { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: 400px 1fr; gap: 24px; } @media (max-width: 980px) { .og-grid { grid-template-columns: 1fr; } } .og-panel { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); border-radius: 22px; padding: 22px; backdrop-filter: blur(8px); } .og-eyebrow { display: inline-block; padding: 8px 12px; border: 1px solid rgba(255,255,255,.14); border-radius: 999px; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: #f0d67a; margin-bottom: 12px; } .og-h2 { margin: 0 0 8px; font-family: 'Cinzel', serif; font-size: 34px; line-height: 1.08; font-weight: 900; color: #fff; } .og-sub { margin: 0 0 18px; color: rgba(238,244,251,.72); line-height: 1.7; font-size: 14px; } .og-field { margin-bottom: 14px; } .og-label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: #f0d67a; margin-bottom: 7px; font-weight: 700; } .og-input, .og-select { width: 100%; padding: 13px 14px; border-radius: 14px; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.06); color: #fff; font-size: 15px; outline: none; font-family: inherit; transition: border-color .18s, box-shadow .18s; } .og-input::placeholder { color: rgba(255,255,255,.38); } .og-input:focus, .og-select:focus { border-color: rgba(212,175,55,.75); box-shadow: 0 0 0 3px rgba(212,175,55,.14); } .og-select option { background: #0d2236; } .og-tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; } .og-tab { padding: 9px 14px; border-radius: 999px; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.04); color: #fff; font-size: 13px; font-weight: 700; cursor: pointer; transition: .18s ease; font-family: inherit; } .og-tab.active { background: linear-gradient(180deg, #f0d67a, #d4af37); color: #111; border-color: rgba(212,175,55,.65); } .og-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; } @media (max-width: 560px) { .og-btns { grid-template-columns: 1fr; } } .og-btn { padding: 13px 16px; border: none; border-radius: 999px; cursor: pointer; font-weight: 700; font-size: 15px; transition: .18s ease; font-family: inherit; } .og-btn:hover { transform: translateY(-1px); } .og-btn.primary { background: linear-gradient(180deg, #f0d67a, #d4af37); color: #111; } .og-btn.secondary { background: rgba(255,255,255,.08); color: #fff; border: 1px solid rgba(255,255,255,.12); } .og-lockbox { margin-top: 16px; padding: 13px; border-radius: 14px; background: rgba(212,175,55,.08); border: 1px solid rgba(212,175,55,.22); color: #f4e7bd; font-size: 13px; line-height: 1.6; } .og-paywall { margin-top: 12px; padding: 13px; background: rgba(0,0,0,.18); border: 1px solid rgba(255,255,255,.12); border-radius: 14px; font-size: 13px; color: rgba(238,244,251,.72); line-height: 1.65; } .og-paywall code { background: rgba(255,255,255,.1); padding: 2px 6px; border-radius: 5px; font-size: 11px; } .og-preview-shell { background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.03)); border: 1px solid rgba(255,255,255,.12); border-radius: 24px; padding: 20px; min-height: 700px; position: relative; display: flex; flex-direction: column; } .og-preview-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 10px; } .og-preview-title { font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: #f0d67a; font-weight: 700; } .og-status { padding: 7px 12px; border-radius: 999px; font-size: 12px; font-weight: 700; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.05); } .og-status.locked { color: #ffdd85; } .og-status.unlocked { color: #93f0bf; } .og-stage { flex: 1; display: flex; justify-content: center; align-items: flex-start; padding: 10px 0; overflow: hidden; } .og-canvas-preview { max-width: 100%; max-height: 640px; border-radius: 14px; box-shadow: 0 18px 48px rgba(0,0,0,.38); object-fit: contain; } .og-dl-bar { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; }`;
const [previewSrc, setPreviewSrc] = useState(””);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
if (view === “card”) drawCard(canvas, name, affirmation, edition);
else drawSeal(canvas, name, edition);
setPreviewSrc(canvas.toDataURL(“image/png”));
}, [generated, view, name, affirmation, edition]);
// Re-render on load
useEffect(() => {
handleGenerate();
}, []);
return (
<>
>
```
);
}
{/* Left panel */}
Create Your
{/* Right preview */}
OneGodian™ Generator
Create Your
Declaration
Generate a personalized Declaration Card and{” “} Obsidian Seal preview on-site. Download is locked until purchase.
```
setName(e.target.value)}
/>
Locked download: users preview on-page for free, but downloading the final image requires purchase. Connect your Stripe payment link in the script.
Stripe link: replace
YOUR_STRIPE_LINK_HERE with your live checkout URL. After payment, redirect back with ?paid=1.
Example:
https://omos.onegodian.com/create?paid=1
Live Preview
{isPaid ? "✓ Download Unlocked" : "🔒 Download Locked"}
{previewSrc && (
)}

