Handouts v2: kie.ai detailed artwork backgrounds + fixed DOM overlay (mobile layout repaired)
Five full-bleed AI-generated designs (nano-banana-pro) with baked-in stylized headlines matching the banner-kit energy; QR + link + disclaimer now a percentage-scaled DOM overlay (canvas approach removed - it collapsed on mobile and clipped the QR). Lower-right of each artwork kept calm for the QR panel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@@ -40,14 +40,21 @@
|
||||
/* ---- half-sheet handouts (2 per letter page, cut in half, image-based) ---- */
|
||||
.hs-page{margin:0 auto 26px;max-width:680px}
|
||||
.hs{position:relative;aspect-ratio:8.5/5.5;border-radius:14px;overflow:hidden;box-shadow:0 10px 30px rgba(0,0,0,.35);
|
||||
display:flex;align-items:flex-end;justify-content:flex-end;font-family:Inter,system-ui,sans-serif;
|
||||
background-size:cover;background-position:center;font-family:Inter,system-ui,sans-serif;
|
||||
-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
||||
.hs-img-bg{background-size:cover;background-position:center}
|
||||
.hs-canvas{display:block}
|
||||
/* QR overlay panel — % sized so it scales on screen, mobile, and print */
|
||||
.hs-qrov{position:absolute;right:3%;bottom:5.5%;width:22%;background:#fff;border-radius:8%/12%;
|
||||
padding:2% 1.6% 1.4%;text-align:center;color:#10151b;box-shadow:0 5px 18px rgba(0,0,0,.55)}
|
||||
.hs-qrov .q{width:100%;line-height:0}
|
||||
.hs-qrov .q svg{width:100%;height:auto;display:block}
|
||||
.hs-qrov .q .qph{width:100%;aspect-ratio:1;border:2px dashed #99a;border-radius:6px;box-sizing:border-box}
|
||||
.hs-qrov .scan{font-weight:800;letter-spacing:.12em;font-size:clamp(6px,1.4vw,11px);margin-top:5%}
|
||||
.hs-qrov .lnk{font-weight:800;font-size:clamp(6px,1.35vw,10.5px);word-break:break-all;line-height:1.2}
|
||||
.hs-discov{position:absolute;left:2.6%;bottom:2.4%;width:60%;font-size:clamp(5px,1vw,8.5px);line-height:1.35;
|
||||
color:#fff;opacity:.92;text-align:left;text-shadow:0 1px 3px rgba(0,0,0,.95),0 0 8px rgba(0,0,0,.6)}
|
||||
.hs-print{position:absolute;top:10px;right:10px;z-index:10;cursor:pointer}
|
||||
.hs-copy{display:none}
|
||||
.hs-cut{display:none}
|
||||
@media (max-width:560px){.hs{aspect-ratio:auto}.hs-main{flex-direction:column;align-items:stretch}.hs-qrbox{align-self:center}}
|
||||
@media print{
|
||||
@page{size:letter;margin:0}
|
||||
body{background:#fff!important}
|
||||
|
||||
@@ -18,29 +18,15 @@
|
||||
];
|
||||
var TABS = 8;
|
||||
|
||||
// Half-sheet handouts: 2 copies per letter page with a cut line. Vibrant
|
||||
// themes echo the banner kit. Copy mirrors the approved full-page flyers.
|
||||
// Half-sheet handouts: detailed AI artwork backgrounds (headline baked into
|
||||
// the art, banner-kit energy) + a live DOM overlay carrying the member's QR
|
||||
// and link. Prints 2 copies per letter page with a cut line.
|
||||
var HALF = [
|
||||
{ angle: 'pocket', theme: 'h-volt', eye: 'TEAM BUILD · ON POLYGON',
|
||||
h: 'You Already <span class="k">Found the Money.</span>',
|
||||
pitch: 'The pocket change that slips through your fingers every week could be starting something instead. Scan for the 90-second look.',
|
||||
chips: ['ONLY 2 TO QUALIFY', 'SPILLOVER HELPS YOU', 'PAID IN SECONDS'] },
|
||||
{ angle: 'two', theme: 'h-aqua', eye: 'A CRYPTO TEAM BUILD',
|
||||
h: 'You Know <span class="k">Two People.</span> That’s All This Takes.',
|
||||
pitch: 'No big network. Nothing to sell. Get two, help them get theirs, and payments roll up to you on-chain as your team grows.',
|
||||
chips: ['GET YOUR 2', 'HELP THEM GET THEIRS', 'ON-CHAIN · VERIFIABLE'] },
|
||||
{ angle: 'phone', theme: 'h-royal', eye: 'ON-CHAIN · NO MIDDLEMAN',
|
||||
h: 'Your Phone Could <span class="k">Start Paying You.</span>',
|
||||
pitch: 'The device in your hand is the only tool this needs. A public smart contract on Polygon pays people directly — no company holding the money.',
|
||||
chips: ['NO LAPTOP NEEDED', 'PUBLIC SMART CONTRACT', 'PAID IN SECONDS'] },
|
||||
{ angle: 'graveyard', theme: 'h-noir', eye: 'AUTONOMOUS · IMMUTABLE',
|
||||
h: 'Tired of Side Hustles <span class="k">That Die?</span>',
|
||||
pitch: 'This one can’t be shut off. It runs on a public, immutable smart contract — no owner who can pull the plug and take your momentum with them.',
|
||||
chips: ['NO PLUG TO PULL', 'IMMUTABLE CONTRACT', 'RUNS ON POLYGON'] },
|
||||
{ angle: '', theme: 'h-ember', eye: 'VERIFY IT YOURSELF · POLYGON',
|
||||
h: 'Stop <span class="k">Waiting.</span> Start <span class="k">Receiving.</span>',
|
||||
pitch: 'Still researching? The whole system is public code you can check before you ever put in a cent. Due diligence takes an evening, not a year.',
|
||||
chips: ['ONLY 2 TO QUALIFY', 'VERIFY BEFORE YOU JOIN', 'PAID IN SECONDS'] }
|
||||
{ angle: 'pocket', img: '/handout-pocket.png' },
|
||||
{ angle: 'two', img: '/handout-two.png' },
|
||||
{ angle: 'phone', img: '/handout-phone.png' },
|
||||
{ angle: 'graveyard', img: '/handout-graveyard.png' },
|
||||
{ angle: '', img: '/handout-stop-waiting.png' }
|
||||
];
|
||||
|
||||
function getId() {
|
||||
@@ -99,155 +85,33 @@
|
||||
var haveId = /^\d{1,15}$/.test(id);
|
||||
var idLabel = haveId ? id : '____';
|
||||
|
||||
function overlayHtml(url, shortUrl) {
|
||||
var qr = haveId ? qrSvg(url) : '<div class="qph"></div>';
|
||||
return '<div class="hs-qrov"><div class="q">' + qr + '</div>' +
|
||||
'<div class="scan">SCAN ME</div><div class="lnk">' + shortUrl + '</div></div>' +
|
||||
'<div class="hs-discov">Independent team resource. Participation takes real effort and involves cryptocurrency risk. No income is guaranteed. Learn more at rmcircle.team.</div>';
|
||||
}
|
||||
function makeCard(f, url, shortUrl, extraCls) {
|
||||
var card = el('div', 'hs' + (extraCls ? ' ' + extraCls : ''), overlayHtml(url, shortUrl));
|
||||
card.style.backgroundImage = 'url(' + f.img + ')';
|
||||
return card;
|
||||
}
|
||||
|
||||
HALF.forEach(function (f) {
|
||||
var url = 'https://rmcircle.team/join/' + (haveId ? id : '') + (f.angle ? '?v=' + f.angle : '');
|
||||
var shortUrl = 'rmcircle.team/join/' + idLabel;
|
||||
var imgFile = '/handout-' + (f.angle || 'stop-waiting') + '.png';
|
||||
|
||||
var page = el('div', 'hs-page');
|
||||
var card = el('div', 'hs hs-img-bg');
|
||||
card.style.backgroundImage = 'url(' + imgFile + ')';
|
||||
card.style.backgroundSize = 'cover';
|
||||
card.style.backgroundPosition = 'center';
|
||||
card.style.position = 'relative';
|
||||
|
||||
var canvas = el('canvas');
|
||||
canvas.width = 1700;
|
||||
canvas.height = 1100;
|
||||
canvas.className = 'hs-canvas';
|
||||
canvas.style.position = 'absolute';
|
||||
canvas.style.top = '0';
|
||||
canvas.style.left = '0';
|
||||
canvas.style.zIndex = '1';
|
||||
card.appendChild(canvas);
|
||||
|
||||
var pr = el('button', 'hs-print btn btn-teal btn-sm', 'Print (2 per page)');
|
||||
pr.style.position = 'relative';
|
||||
pr.style.zIndex = '2';
|
||||
var card = makeCard(f, url, shortUrl, '');
|
||||
var pr = el('button', 'hs-print btn btn-teal btn-sm', '🖨 Print (2 per page)');
|
||||
card.appendChild(pr);
|
||||
|
||||
// Render QR on canvas
|
||||
(function(canvas, url, shortUrl) {
|
||||
var renderQr = function() {
|
||||
var ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
ctx.fillStyle = 'rgba(30, 30, 40, 0.6)';
|
||||
ctx.fillRect(1020, 550, 680, 550);
|
||||
|
||||
var qrSize = 240;
|
||||
var qrX = 1700 - qrSize - 40;
|
||||
var qrY = 1100 - qrSize - 100;
|
||||
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(qrX - 10, qrY - 10, qrSize + 20, qrSize + 20);
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeRect(qrX - 10, qrY - 10, qrSize + 20, qrSize + 20);
|
||||
|
||||
if (url.indexOf('join/') !== -1) {
|
||||
var qrSvgStr = qrSvg(url);
|
||||
if (qrSvgStr) {
|
||||
var tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = qrSvgStr;
|
||||
var svg = tempDiv.querySelector('svg');
|
||||
if (svg) {
|
||||
var svgData = new XMLSerializer().serializeToString(svg);
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
ctx.drawImage(img, qrX, qrY, qrSize, qrSize);
|
||||
drawLink();
|
||||
};
|
||||
img.onerror = drawLink;
|
||||
img.src = 'data:image/svg+xml;base64,' + btoa(svgData);
|
||||
} else { drawLink(); }
|
||||
} else { drawLink(); }
|
||||
} else { drawLink(); }
|
||||
|
||||
function drawLink() {
|
||||
ctx.font = 'bold 20px Arial';
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.shadowColor = 'rgba(0,0,0,0.8)';
|
||||
ctx.shadowBlur = 4;
|
||||
ctx.shadowOffsetX = 2;
|
||||
ctx.shadowOffsetY = 2;
|
||||
ctx.fillText(shortUrl, 1700 - 120, 1100 - 30);
|
||||
}
|
||||
};
|
||||
setTimeout(renderQr, 100);
|
||||
})(canvas, url, shortUrl);
|
||||
|
||||
page.appendChild(card);
|
||||
page.appendChild(el('div', 'hs-cut', 'cut here'));
|
||||
|
||||
var card2 = el('div', 'hs hs-img-bg hs-copy');
|
||||
card2.style.backgroundImage = 'url(' + imgFile + ')';
|
||||
card2.style.backgroundSize = 'cover';
|
||||
card2.style.backgroundPosition = 'center';
|
||||
card2.style.position = 'relative';
|
||||
var canvas2 = el('canvas');
|
||||
canvas2.width = 1700;
|
||||
canvas2.height = 1100;
|
||||
canvas2.style.position = 'absolute';
|
||||
canvas2.style.top = '0';
|
||||
canvas2.style.left = '0';
|
||||
card2.appendChild(canvas2);
|
||||
|
||||
(function(canvas, url, shortUrl) {
|
||||
var renderQr = function() {
|
||||
var ctx = canvas.getContext('2d');
|
||||
if (!ctx) return;
|
||||
ctx.fillStyle = 'rgba(30, 30, 40, 0.6)';
|
||||
ctx.fillRect(1020, 550, 680, 550);
|
||||
var qrSize = 240;
|
||||
var qrX = 1700 - qrSize - 40;
|
||||
var qrY = 1100 - qrSize - 100;
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(qrX - 10, qrY - 10, qrSize + 20, qrSize + 20);
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.strokeRect(qrX - 10, qrY - 10, qrSize + 20, qrSize + 20);
|
||||
if (url.indexOf('join/') !== -1) {
|
||||
var qrSvgStr = qrSvg(url);
|
||||
if (qrSvgStr) {
|
||||
var tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = qrSvgStr;
|
||||
var svg = tempDiv.querySelector('svg');
|
||||
if (svg) {
|
||||
var svgData = new XMLSerializer().serializeToString(svg);
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
ctx.drawImage(img, qrX, qrY, qrSize, qrSize);
|
||||
drawLink();
|
||||
};
|
||||
img.onerror = drawLink;
|
||||
img.src = 'data:image/svg+xml;base64,' + btoa(svgData);
|
||||
} else { drawLink(); }
|
||||
} else { drawLink(); }
|
||||
} else { drawLink(); }
|
||||
function drawLink() {
|
||||
ctx.font = 'bold 20px Arial';
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.shadowColor = 'rgba(0,0,0,0.8)';
|
||||
ctx.shadowBlur = 4;
|
||||
ctx.shadowOffsetX = 2;
|
||||
ctx.shadowOffsetY = 2;
|
||||
ctx.fillText(shortUrl, 1700 - 120, 1100 - 30);
|
||||
}
|
||||
};
|
||||
setTimeout(renderQr, 100);
|
||||
})(canvas2, url, shortUrl);
|
||||
|
||||
page.appendChild(card2);
|
||||
|
||||
page.appendChild(el('div', 'hs-cut', '✂ cut here ✂'));
|
||||
page.appendChild(makeCard(f, url, shortUrl, 'hs-copy'));
|
||||
pr.addEventListener('click', function () {
|
||||
document.body.classList.add('print-one'); page.classList.add('printing');
|
||||
window.print();
|
||||
setTimeout(function () { document.body.classList.remove('print-one'); page.classList.remove('printing'); }, 400);
|
||||
});
|
||||
|
||||
host.appendChild(page);
|
||||
});
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 2.7 MiB |