Create my invitationLog in
ॐ శ్రీ గణేశాయ నమః
Hindu wedding invitations in 3D

Invitations that open like a film

A carved temple gate swings open, a gold-edged card glides out and opens like doors. Edit every word yourself, add your photo and music, then send one link on WhatsApp.

Opens on every phone English, Telugu, Hindi RSVP on WhatsApp
Tap the gate

Cinematic opening

The temple gate swings open, the card glides out and unfolds. Guests feel it.

You edit it

Names, dates, venue, photo, colours and fonts. Change anything, any time.

Music and effects

Soft music, gold dust, rose petals or stars floating around the card.

One link to share

Send on WhatsApp. Guests tap RSVP or the map right inside the card.

Our designs

Choose your 3D invitation

Pick a design and look at it first. Then add your names, date, photos and music.

W

Wedding 1

wedding

₹1,499

Opens in 3D. Add your names, photos and music.

B

Book of Love

wedding

₹1,499

Opens in 3D. Add your names, photos and music.

A

Anniversary

anniversary

₹1,499

Opens in 3D. Add your names, photos and music.

L

Lotus Bloom

wedding

₹1,499

Opens in 3D. Add your names, photos and music.

See all designs
Start with a design

Six looks, all editable

Pick the one that feels like your family. You can change colours, fonts and every word later.

Full cinematic invitations

Six models, six ways to scroll

Each model is a full invitation page with its own opening and its own 3D scroll animation. Tap one to see it full screen with your own studio details inside.

Temple Gopuram

Temple Gopuram

Carved doors open. You fly forward through the temple.

Royal Palace

Royal Palace

Curtains draw apart. Sections swing like palace doors.

Marigold Mandap

Marigold Mandap

A circle opens. Sections turn like a drum, petals fall.

Lotus Bloom

Lotus Bloom

A lotus blooms. Soft layers float and sway.

Night of Diyas

Night of Diyas

Lamps light one by one. Sections swing down into the light.

Book of Love

Book of Love

A book cover opens. Sections turn like pages.

More designs

14 occasion websites, your own 3D invitation

Weddings, birthdays, baby functions, Griha Pravesham, Upanayanam, puja and more. Each website has its own opening and 3D scroll. "My details" fills it from your studio.

Full websites for every occasion

Build your own 3D invitation

Pick how it opens, a 3D card, your story, countdown, gallery and how guests reply. Every choice comes alive with your own names, date and venue, and you see it all on a phone before you decide.

Invite Studio
Edit your details
Design studio

Make it yours

Type on the left. The 3D invitation on the right changes as you type. Tap the gate to open it.

Simple

Ready in three steps

Pick a design

Choose one of the six looks. Switch to Telugu or Hindi with one tap.

Fill your details

Add names, date, venue, events, photo and music. Watch the card change live.

Share the link

Send it on WhatsApp. Guests open the envelope and reply with one tap.

Pricing

Simple pricing

Every design has its own price, shown on its card. One payment. No monthly fee.

Every design includes

  • Your own 3D invitation and link
  • Your names, date, venue and events
  • Music and floating effects
  • Your photos
  • English, Telugu and Hindi
  • WhatsApp sharing, map link and RSVP
  • Change your details any time
See designs and prices

Fully custom design

Made just for you
  • A design made only for your family
  • A personal designer
  • Price after we talk
Message us on WhatsApp
Questions

Good to know

Can I change my invitation after sharing?

Yes. Edit in the studio and share the new link. Anyone who opens the link sees the latest version.

Does it work on every phone?

It works on any phone with a modern browser. If 3D is not available, guests see a flat version of the same card.

Can guests reply?

Yes. The RSVP button opens WhatsApp with a ready message to your number.

Can I use my own music?

Yes. Choose the built-in soft music or upload your own song in the Extras tab.

`; } // ---------- details for a template preview ---------- function tdata(c) { const rows = c.s.split(';').map(a => a.split('|')); return { k:c.k, nm:c.pair && c.p2 ? c.p1 + ' & ' + c.p2 : c.p1, ho:!c.pair && c.p2 ? (c.h ? c.h + ' ' : '') + c.p2 : '', nt:c.note, date:'2026-11-28', tm:rows[0][0], vn:c.v, cy:c.ci, mp:'', wa:'', sc:rows, im:c.im, ph:'' }; } var CNd=function(){return window.__CN?window.__CN.getD():null}; function nmz(D){var x=D.lang!=='en';return [x&&D.groomX?D.groomX:D.groom,x&&D.brideX?D.brideX:D.bride]} function evrows(D){return (D.events||[]).filter(function(e){return e.t||e.tm}).slice(0,4).map(function(e){return [e.tm||'',e.t||'']})} function myD(c){var D=CNd(),n=nmz(D);return{k:c.k,nm:n[0]+' & '+n[1],ho:'',nt:D.msg||c.note,date:D.date,tm:D.time,vn:D.venue,cy:D.city,mp:D.maps,wa:D.phone,sc:evrows(D),im:c.im,ph:D.photo||''}} function sdata(th){var D=CNd(),n=nmz(D),rows=evrows(D).slice(0,3);return Object.assign({k:esc('Wedding Invitation'),nm:esc(n[0]+' & '+n[1]),ho:'',nt:esc(D.msg||'Together with their families, invite you to celebrate their wedding ceremony.'),tm:esc(D.time),vn:esc(D.venue),cy:esc(D.city),ini:esc((Array.from(n[0]||'')[0]||'')+'&'+(Array.from(n[1]||'')[0]||'')),sc:schedHtml(rows),th:th,im:'1519741497674-611481863552'},dateParts(D.date))} var $e=function(i){return document.getElementById(i)},curTh='kumkum',curSite=null,curMine=0; /* 14 occasion websites */ function buildSites(){ $e('siteGrid').innerHTML=(window.IV_ALL?TPS:TPS.slice(0,4)).map(function(t){var c=CATS.filter(function(x){return x.id===t.occ})[0];return '

'+esc(t.nm)+'

'+esc(c.n)+'

'+esc(t.tag)+'

'}).join(''); var io=new IntersectionObserver(function(es){es.forEach(function(en){if(!en.isIntersecting)return;var el=en.target;io.unobserve(el);var t=TPm[el.dataset.t],c=CATS.filter(function(x){return x.id===t.occ})[0],f=document.createElement('iframe');f.setAttribute('sandbox','allow-scripts');f.setAttribute('scrolling','no');f.tabIndex=-1;f.setAttribute('aria-hidden','true');f.srcdoc=siteDoc(t,tdata(c),true,true);el.appendChild(f);f.style.transform='scale('+(el.clientWidth/390)+')'})},{rootMargin:'200px'}); $$('.thumb[data-t]').forEach(function(el){var t=TPm[el.dataset.t],ph=document.createElement('button');ph.type='button';ph.className='ph';ph.setAttribute('aria-label','Load live preview');ph.innerHTML='▶Tap to load the live preview';ph.querySelector('.ph-n').textContent=(t&&t.nm)||'';ph.style.backgroundImage='url(/posters/'+el.dataset.t+'.webp),linear-gradient(160deg,#fff6e0,#f3dfae 60%,#e6c98a)';ph.addEventListener('click',function(e){e.stopPropagation();ph.remove();io.observe(el)});el.appendChild(ph)}); addEventListener('resize',function(){$$('.thumb iframe').forEach(function(f){f.style.transform='scale('+(f.parentNode.clientWidth/390)+')'})}); $e('siteGrid').addEventListener('click',function(e){var b=e.target.closest('[data-s]');if(!b){var th=e.target.closest('.thumb');if(th)openSite(th.dataset.t,0);return}openSite(b.dataset.s,+b.dataset.m)})} function $$(s){return [].slice.call(document.querySelectorAll(s))} function openSite(id,mine){curSite=id;curOwn=null;$e('sv-mode').style.display='flex';$e('sv-edit').style.display='';var t=TPm[id],c=CATS.filter(function(x){return x.id===t.occ})[0];$e('sv-title').textContent=t.nm+(mine?' - with your details':' - preview'); $$('#sv-mode button').forEach(function(b){b.classList.toggle('on',+b.dataset.m===mine)}); curMine=mine;var fr=$e('sv-fr');fr.setAttribute('sandbox','allow-scripts allow-same-origin');fr.onload=null;fr.srcdoc=siteDoc(t,mine?myD(c):tdata(c),true,false);$e('sv').classList.add('on');document.documentElement.style.overflow='hidden'} function closeSite(){setDesign(false);curOwn=null;$e('sv').classList.remove('on');$e('sv-fr').srcdoc='';document.documentElement.style.overflow=''} function startMore(){buildSites();initEdit();initStudio(); $e('sv-close').addEventListener('click',closeSite);document.addEventListener('keydown',function(e){if(e.key==='Escape'&&$e('sv').classList.contains('on'))closeSite()}); $e('sv-mode').addEventListener('click',function(e){var b=e.target.closest('button');if(b&&curSite)openSite(curSite,+b.dataset.m)}); $e('sv-w').addEventListener('click',function(e){var b=e.target.closest('button');if(b)$e('sv-fr').style.width=b.dataset.w}); } /* edit panel for the websites and the 3D cards (changes the shared studio details) */ /* Invite Studio: opens full screen, gets your details, saves the pick */ function initStudio(){ var ORDER_WA=''; /* put the number that receives orders here, e.g. '919876543210'. Empty = no WhatsApp message */ var ov=$e('isv'),fr=$e('isv-fr'),ready=false; function to24(t){var m=/(\d{1,2}):(\d{2})\s*(AM|PM)?/i.exec(t||'');if(!m)return '18:30';var H=+m[1];if(m[3]){var p=m[3].toUpperCase();if(p==='PM'&&H<12)H+=12;if(p==='AM'&&H===12)H=0}return (H<10?'0':'')+H+':'+m[2]} function details(){var D=CNd(),n=nmz(D);return {groom:n[0],bride:n[1],date:D.date,time24:to24(D.time),venue:D.venue,city:D.city,msg:D.msg||'',wa:D.phone||'',maps:D.maps||'',program:evrows(D)}} function say(m){var t=document.getElementById('toast');if(!t)return;t.textContent=m;t.classList.add('on');clearTimeout(say.t);say.t=setTimeout(function(){t.classList.remove('on')},2800)} function send(){try{fr.contentWindow.postMessage({type:'coonett-details',data:details()},location.origin)}catch(e){}} function open(){ov.classList.add('on');document.documentElement.style.overflow='hidden';if(!fr.getAttribute('src')){fr.src='/invite-studio/studio.html?embed=1'}else send()} function close(){ov.classList.remove('on');document.documentElement.style.overflow=''} $e('isOpen').addEventListener('click',open); $e('isv-close').addEventListener('click',close); document.addEventListener('keydown',function(e){if(e.key==='Escape'&&ov.classList.contains('on'))close()}); window.addEventListener('message',function(e){ if(e.origin!==location.origin||e.source!==fr.contentWindow)return;var m=e.data||{}; if(m.type==='coonett-studio-ready'){ready=true;send()} if(m.type==='coonett-choose'){ try{localStorage.setItem('coonett_invite_pick',JSON.stringify({pick:m.pick,pal:m.pal,names:m.names,studio:m.studio,at:Date.now()}))}catch(x){} close();say('Your design is saved. Opening your details...');setTimeout(function(){location.href='/invites/start?model=custom-studio'},700); if(ORDER_WA&&m.message){var a=document.createElement('a');a.href='https://wa.me/'+ORDER_WA+'?text='+encodeURIComponent(m.message);a.target='_blank';a.rel='noopener';document.body.appendChild(a);a.click();a.remove()} } }); } var edT2=0; function fv(l,k,v,t){return ''} function buildEdp(){var D=CNd(),h='

Names

'+fv('First name','groom',D.groom)+'
'+fv('Second name','bride',D.bride)+'

Telugu and Hindi letters work too.

Message

When and where

'+fv('Date','date',D.date,'date')+'
'+fv('Time','time',D.time)+'
'+fv('Venue','venue',D.venue)+fv('Town or city','city',D.city)+fv('Google Maps link','maps',D.maps)+fv('WhatsApp number with country code','phone',D.phone)+'

Programme

'+(D.events||[]).slice(0,4).map(function(e,i){return '
'}).join('')+'

Photo

Changes show at once and are also saved in the design studio.

';$e('edpb').innerHTML=h} function refreshAfterEdit(){clearTimeout(edT2);edT2=setTimeout(function(){if($e('sv').classList.contains('on')&&curSite){var fr=$e('sv-fr'),y=0;try{y=fr.contentWindow.scrollY}catch(e){}var t=TPm[curSite],c=CATS.filter(function(x){return x.id===t.occ})[0];fr.onload=function(){try{fr.contentWindow.scrollTo(0,y)}catch(e){}};fr.srcdoc=siteDoc(t,curMine?myD(c):tdata(c),true,true)}},380)} function initEdit(){ var open=function(){buildEdp();$e('edp').classList.add('on')}; $e('cardEdit').addEventListener('click',open); $e('sv-edit').addEventListener('click',function(){if(!curMine&&curSite)openSite(curSite,1);open()}); $e('edpx').addEventListener('click',function(){$e('edp').classList.remove('on')}); $e('edpb').addEventListener('input',function(e){var t=e.target;if(!CNd())return; if(t.dataset.k){var o={};o[t.dataset.k]=t.value;if(t.dataset.k==='phone')o.phone=t.value.replace(/\D/g,'');window.__CN.set(o);refreshAfterEdit()} else if(t.dataset.ev){var m=t.dataset.ev.split('_'),ev=JSON.parse(JSON.stringify(CNd().events||[]));if(!ev[+m[0]])return;ev[+m[0]][m[1]]=t.value;window.__CN.set({events:ev});refreshAfterEdit()}}); $e('edpb').addEventListener('change',function(e){var t=e.target;if(t.id!=='edpPh')return;var f=t.files[0];if(!f)return;var rd=new FileReader();rd.onload=function(){var im=new Image();im.onload=function(){var m=Math.min(1,1100/Math.max(im.width,im.height)),c=document.createElement('canvas');c.width=Math.round(im.width*m);c.height=Math.round(im.height*m);c.getContext('2d').drawImage(im,0,0,c.width,c.height);window.__CN.photo(c.toDataURL('image/jpeg',.82));refreshAfterEdit()};im.src=rd.result};rd.readAsDataURL(f)}); $e('edpb').addEventListener('click',function(e){if(e.target.id==='edpPhDel'){window.__CN.photo(null);refreshAfterEdit()}}); document.addEventListener('keydown',function(e){if(e.key==='Escape')$e('edp').classList.remove('on')})} var tries=0;(function wait(){if(window.__CN&&window.__CN.getD()&&window.__CN.getD().events){startMore()}else if(tries++<80)setTimeout(wait,150)})(); /* ===== Edit design: move / resize pictures, backgrounds, text, shapes, motion, undo / redo, preview, download ===== */ var designOn=false,curOwn=null,curKey=''; function CNEDIT(opt){ var doc=document,win=window,HK=null; try{if(win.parent&&win.parent!==win&&win.parent.__cnDesign)HK=win.parent.__cnDesign;}catch(e){} if(win.__cnEd)return; var TP=['translate','scale','width','height','top','left','max-width','object-fit','object-position','aspect-ratio','justify-self','align-self','visibility','background-color','background-image','background-size','background-position','background-repeat','--edbw','--edbh','--edar','animation','display','color','font-size','--ac','--ac2','--ov','--ob']; var SKIPT={SCRIPT:1,STYLE:1,LINK:1,NOSCRIPT:1,TEMPLATE:1,META:1,HEAD:1,TITLE:1}; var INERT={IMG:1,SVG:1,CANVAS:1,VIDEO:1,AUDIO:1,IFRAME:1,INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,HTML:1,BODY:1,BR:1,HR:1,PATH:1}; function qa(s,r){return [].slice.call((r||doc).querySelectorAll(s));} function bad(e){return !!(SKIPT[e.tagName]||(e.closest&&e.closest('.ed-ui,#op,script,style,svg,canvas')));} function clamp(v,a,b){return Math.max(a,Math.min(b,v));} /* ---------- index every picture, section and text so edits can be saved and re-applied ---------- */ var ELS={},IM=[],AR=[],TX=[]; function isTx(e){ if(bad(e)||INERT[(e.tagName||'').toUpperCase()])return false; if(!e.textContent.trim())return false; return e.querySelector(':not(b):not(i):not(em):not(strong):not(span):not(small):not(br):not(u):not(sup):not(sub)')===null; } function index(){ qa('img').forEach(function(e){if(bad(e))return;var n=IM.length;IM.push(e);e._eid='i'+n;ELS['i'+n]=e;var p=e.parentElement;if(p){p._feid='f'+n;ELS['f'+n]=p;}}); qa('body > section,body > header,body > footer,body > main,body > article,body > div').forEach(function(e){if(bad(e))return;var n=AR.length;AR.push(e);e._eid='a'+n;ELS['a'+n]=e;}); var sc0=doc.querySelector('.pv > .sc');if(sc0){sc0._eid='s0';ELS['s0']=sc0;} var last=null; qa('body *').forEach(function(e){if(last&&last.contains(e))return;if(!isTx(e))return;last=e;var n=TX.length;TX.push(e);e._eid='t'+n;e._tx=1;ELS['t'+n]=e;}); } /* ---------- saved changes (only what you changed) ---------- */ var ADD=[]; var SHAPES={square:'',circle:'border-radius:50%;',round:'border-radius:26px;',heart:'clip-path:path("M60 108C10 70 0 40 20 20C38 4 58 14 60 30C62 14 82 4 100 20C120 40 110 70 60 108Z");',star:'clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);',diamond:'clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);',triangle:'clip-path:polygon(50% 0,100% 100%,0 100%);'}; function readTP(el){var o={};TP.forEach(function(p){var v=curP(el,p);if(v!=='')o[p]=v;});return o;} function mkAdd(rec){ var host=AR[rec.a]||doc.body,e; if(host!==doc.body&&win.getComputedStyle(host).position==='static')host.style.position='relative'; if(rec.k==='img'){e=doc.createElement('img');e.src=rec.v;e.alt='';}else{e=doc.createElement('div');if(rec.k==='text')e.innerHTML=rec.h||'';} e.setAttribute('data-edadd','1');e._edadd=1;e.style.cssText=rec.b||''; var st=rec.st||{};Object.keys(st).forEach(function(k){setRaw(e,k,st[k]);}); if(rec.k==='text'&&on)e.setAttribute('contenteditable','true'); host.appendChild(e);return e; } function rebuildAdds(list){ADD.forEach(function(x){x.el.remove();});ADD=[];(list||[]).forEach(function(r){var rec={a:r.a,k:r.k,v:r.v,b:r.b,st:r.st||{},h:r.h};ADD.push({el:mkAdd(rec),rec:rec});});} var O={}; function curP(el,p){return el.style.getPropertyValue(p)+(el.style.getPropertyPriority(p)?'!':'');} function cap(id){ if(!O[id]){var el=ELS[id],o={st:{}};TP.forEach(function(p){o.st[p]=curP(el,p);}); if(el.tagName==='IMG'){o.src=el.getAttribute('src');o.ss=el.getAttribute('srcset');} if(el._tx&&id.charAt(0)==='t')o.h=el.innerHTML; O[id]=o;} return O[id]; } function setRaw(el,k,v){if(v==null||v==='')el.style.removeProperty(k);else if(v.charAt(v.length-1)==='!')el.style.setProperty(k,v.slice(0,-1),'important');else el.style.setProperty(k,v,'');} function setP(id,prop,val,imp){cap(id);var el=ELS[id];if(val==null||val==='')el.style.removeProperty(prop);else el.style.setProperty(prop,String(val),imp?'important':'');} function setSrc(id,u){cap(id);var el=ELS[id];el.setAttribute('src',u);el.removeAttribute('srcset');} function collect(){ var s={}; Object.keys(O).forEach(function(id){ var el=ELS[id],o=O[id],p={},st={},ch=0; TP.forEach(function(k){var v=curP(el,k);if(v!==o.st[k]){st[k]=v;ch=1;}}); if(ch)p.st=st; if(el.tagName==='IMG'&&el.getAttribute('src')!==o.src){p.src=el.getAttribute('src');ch=1;} if(o.h!=null&&el.innerHTML!==o.h){p.h=el.innerHTML;ch=1;} if(ch)s[id]=p; }); if(ADD.length)s['+']=ADD.map(function(x){return {a:x.rec.a,k:x.rec.k,v:x.rec.v,b:x.rec.b,st:readTP(x.el),h:x.rec.k==='text'?x.el.innerHTML:undefined};}); return s; } function apply(s){ var ids={};Object.keys(O).forEach(function(k){ids[k]=1;});Object.keys(s).forEach(function(k){ids[k]=1;}); Object.keys(ids).forEach(function(id){ var el=ELS[id];if(!el)return;cap(id);var o=O[id],p=s[id]||{},st=p.st||{}; TP.forEach(function(k){setRaw(el,k,(k in st)?st[k]:o.st[k]);}); if(el.tagName==='IMG'){ var u=('src' in p)?p.src:o.src; if(el.getAttribute('src')!==u){if(u==null)el.removeAttribute('src');else el.setAttribute('src',u);} if('src' in p)el.removeAttribute('srcset');else if(o.ss!=null)el.setAttribute('srcset',o.ss); } if(o.h!=null){var h=('h' in p)?p.h:o.h;if(el.innerHTML!==h)el.innerHTML=h;} }); rebuildAdds(s['+']); } function revert(id){var el=ELS[id],o=O[id];if(!o)return;TP.forEach(function(k){setRaw(el,k,o.st[k]);});if(el.tagName==='IMG'){if(o.src==null)el.removeAttribute('src');else el.setAttribute('src',o.src);if(o.ss!=null)el.setAttribute('srcset',o.ss);}} (function(){if(doc.getElementById('ed-kf'))return;var k=doc.createElement('style');k.id='ed-kf';k.textContent='@keyframes edzi{from{transform:scale(1)}to{transform:scale(1.25)}}@keyframes edzo{from{transform:scale(1.25)}to{transform:scale(1)}}@keyframes edml{from{transform:scale(1.2) translateX(6%)}to{transform:scale(1.2) translateX(-6%)}}@keyframes edmr{from{transform:scale(1.2) translateX(-6%)}to{transform:scale(1.2) translateX(6%)}}@keyframes edmt{from{transform:scale(1.2) translateY(6%)}to{transform:scale(1.2) translateY(-6%)}}@keyframes edmb{from{transform:scale(1.2) translateY(-6%)}to{transform:scale(1.2) translateY(6%)}}';doc.head.appendChild(k);})(); index(); if(opt.state){try{apply(JSON.parse(opt.state));}catch(e){}} /* ================= editing screen ================= */ var built=false,on=false,prev=false,cur=null,op=null,PW=340; var bar,panel,box,grip,blabel,pb,undoB,redoB,H=document.documentElement; var BIG={},BIGR={},bigN=0,hist=[],hidx=0,histT=null,saveT=null; function el_(t,c,x){var e=doc.createElement(t);if(c)e.className=c;if(x!=null)e.textContent=x;return e;} function btn(txt,fn,cls){var b=el_('button',cls||'ed-btn',txt);b.type='button';b.onclick=fn;return b;} function lab(t){return el_('div','ed-lab',t);} function slider(min,max,step,val,fn){var s=doc.createElement('input');s.type='range';s.min=min;s.max=max;s.step=step;s.value=val;s.className='ed-range';s.oninput=function(){fn(parseFloat(s.value));};return s;} function check(txt,val,fn){var cb=doc.createElement('input');cb.type='checkbox';cb.checked=!!val;cb.onchange=function(){fn(cb.checked);};var l=el_('label','ed-check');l.appendChild(cb);l.appendChild(doc.createTextNode(' '+txt));return l;} function colorInput(val,fn){var c=doc.createElement('input');c.type='color';c.value=val;c.className='ed-color';c.oninput=function(){fn(c.value);};return c;} function isWide(){return win.innerWidth>=900;} function vis(){var tb=bar.offsetHeight+6;return isWide()?{l:14,t:tb,r:win.innerWidth-PW-14,b:win.innerHeight-14}:{l:14,t:tb,r:win.innerWidth-14,b:win.innerHeight*0.62};} function reveal(e){var r=e.getBoundingClientRect(),V=vis();win.scrollBy(0,r.top+Math.min(r.height,V.b-V.t)/2-(V.t+(V.b-V.t)/2));} var CSS='.ed-ui,.ed-ui *{box-sizing:border-box;font-family:system-ui,Segoe UI,Arial,sans-serif}' +'.ed-bar{position:fixed;top:0;left:0;right:0;z-index:2147483000;display:flex;flex-wrap:wrap;gap:6px;justify-content:center;align-items:center;padding:8px;background:#3f0c15;border-bottom:2px solid #c9932f}' +'.ed-bbtn{background:#c9932f;color:#3f0c15;border:0;border-radius:999px;padding:7px 13px;font-size:13px;cursor:pointer;font-weight:600}.ed-bbtn:disabled{opacity:.4;cursor:default}' +'.ed-hint{flex-basis:100%;text-align:center;color:#f5d68a;font-size:11px;line-height:1.3}' +'.ed-panel{position:fixed;left:0;right:0;bottom:0;z-index:2147483000;max-height:44vh;overflow:auto;background:#fffaf0;border-top:3px solid #c9932f;padding:10px 14px 18px;color:#4a0f19;box-shadow:0 -8px 24px rgba(0,0,0,.25);font-size:14px}' +'@media(min-width:900px){.ed-panel{left:auto;width:'+PW+'px;top:var(--ed-pt,70px);max-height:none;border-top:0;border-left:3px solid #c9932f;box-shadow:-8px 0 24px rgba(0,0,0,.2)}html.ed-on{padding-right:'+PW+'px!important}}' +'html.ed-on{padding-top:var(--ed-pt,0)!important}' +'html.ed-prev{padding:0!important}html.ed-prev .ed-bar,html.ed-prev .ed-panel,html.ed-prev .ed-box{display:none!important}html.ed-prev .ed-prevback{display:block!important}html.ed-prev [contenteditable=true]{outline:none!important}' +'.ed-prevback{display:none;position:fixed;left:14px;bottom:14px;z-index:2147483000;background:#6b1c23;color:#fbebb3;border:2px solid #c9932f;border-radius:999px;padding:10px 16px;font-size:14px;cursor:pointer}' +'.ed-ph{display:flex;align-items:center;gap:8px;margin-bottom:6px}.ed-ph b{flex:1;font-size:16px}' +'.ed-x{background:none;border:1px solid #c9932f;border-radius:999px;color:#6b1c23;padding:3px 10px;cursor:pointer;font-size:14px}' +'.ed-btn{display:block;width:100%;margin:8px 0 0;background:#6b1c23;color:#fbebb3;border:0;border-radius:999px;padding:10px 14px;font-size:14px;cursor:pointer;text-align:center}.ed-btn.ed-ghost{background:#fff;color:#6b1c23;border:1px solid #c9932f}' +'.ed-lab{margin:12px 0 2px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:#9a6b1f}.ed-note{margin:4px 0;font-size:13px;color:#6b5a3a}' +'.ed-range{width:100%}.ed-check{display:block;margin-top:10px;font-size:13px}.ed-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}' +'.ed-sw{width:30px;height:30px;border-radius:50%;border:2px solid #c9932f;cursor:pointer;padding:0}.ed-color{width:34px;height:30px;border:0;padding:0;background:none}' +'.ed-on [contenteditable=true]{outline:1px dashed rgba(201,147,47,.9);outline-offset:2px;cursor:text}.ed-on [contenteditable=true]:focus{background:rgba(255,255,255,.35)}' +'.ed-on #op{display:none!important}html.ed-freeze .sc,html.ed-freeze .sc *{animation-play-state:paused!important}' +'.ed-box{display:none;position:fixed;z-index:2147482000;pointer-events:none;border:2px solid #e2b44f;box-shadow:0 0 0 1px rgba(63,12,21,.6);touch-action:none}' +'.ed-bmove{position:absolute;inset:0;pointer-events:auto;cursor:move;touch-action:none}.ed-box.ed-big .ed-bmove{pointer-events:none}' +'.ed-h{position:absolute;width:20px;height:20px;margin:-10px 0 0 -10px;background:#fff;border:2px solid #6b1c23;border-radius:4px;pointer-events:auto;touch-action:none}' +'.ed-h-nw{left:0;top:0;cursor:nwse-resize}.ed-h-n{left:50%;top:0;cursor:ns-resize}.ed-h-ne{left:100%;top:0;cursor:nesw-resize}.ed-h-e{left:100%;top:50%;cursor:ew-resize}.ed-h-se{left:100%;top:100%;cursor:nwse-resize}.ed-h-s{left:50%;top:100%;cursor:ns-resize}.ed-h-sw{left:0;top:100%;cursor:nesw-resize}.ed-h-w{left:0;top:50%;cursor:ew-resize}' +'.ed-grip{display:none;position:absolute;left:44px;top:calc(100% - 44px);width:46px;height:46px;margin:-23px 0 0 -23px;border-radius:50%;background:#6b1c23;color:#fbebb3;font-size:22px;line-height:42px;text-align:center;border:2px solid #e2b44f;pointer-events:auto;cursor:move;touch-action:none}.ed-box.ed-big .ed-grip{display:block}' +'.ed-tabs{flex-basis:100%;display:flex;gap:6px;justify-content:center;flex-wrap:wrap}.ed-tab{background:#6b1c23;color:#fbebb3;border:1px solid #c9932f;border-radius:8px;padding:5px 12px;font-size:12px;cursor:pointer}' +'.ed-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:10px}.ed-th{width:100%;aspect-ratio:1;object-fit:cover;border:2px solid #c9932f;border-radius:8px;cursor:pointer}.ed-shp{aspect-ratio:1;border:2px solid #c9932f;border-radius:8px;background:#fff;cursor:pointer;font-size:26px;color:#6b1c23}' +'[data-edadd]{box-sizing:border-box}' +'.ed-blabel{position:absolute;left:50%;top:100%;transform:translate(-50%,8px);background:#3f0c15;color:#fbebb3;font-size:11px;padding:1px 8px;border-radius:999px;white-space:nowrap;pointer-events:none}'; function build(){ if(built)return;built=true; var st=doc.createElement('style');st.className='ed-ui';st.id='ed-css';st.textContent=CSS;doc.head.appendChild(st); bar=el_('div','ed-ui ed-bar'); bar.appendChild(btn('✔ Done',function(){if(HK&&HK.done)HK.done();else stop();},'ed-bbtn')); undoB=btn('↶ Undo',function(){go(-1);},'ed-bbtn');redoB=btn('↷ Redo',function(){go(1);},'ed-bbtn');bar.appendChild(undoB);bar.appendChild(redoB); bar.appendChild(btn('👁 Preview',function(){setPrev(true);},'ed-bbtn')); bar.appendChild(el_('div','ed-hint','Tap any text to type · tap a picture, then drag it or pull its squares · tap an empty part of a section to change its background')); var tabs=el_('div','ed-tabs');[['🖼 Media',mediaPanel],['🔤 Text',textPanel],['◆ Elements',shapePanel],['✨ Motion',motionPanel]].forEach(function(t){tabs.appendChild(btn(t[0],t[1],'ed-tab'));}); if(ELS.s0){tabs.appendChild(btn('🎨 Colours',colourPanel,'ed-tab'));tabs.appendChild(btn('⏯ Pause / Play',function(){H.classList.toggle('ed-freeze');},'ed-tab'));} bar.appendChild(tabs); panel=el_('div','ed-ui ed-panel');panel.style.display='none'; box=el_('div','ed-ui ed-box');var bm=el_('div','ed-bmove');box.appendChild(bm); ['nw','n','ne','e','se','s','sw','w'].forEach(function(h){var d=el_('div','ed-h ed-h-'+h);d.setAttribute('data-h',h);box.appendChild(d);}); grip=el_('div','ed-grip','✥');grip.setAttribute('data-h','move');box.appendChild(grip); blabel=el_('div','ed-blabel');box.appendChild(blabel); pb=el_('button','ed-ui ed-prevback','← Back to editing');pb.type='button';pb.onclick=function(){setPrev(false);}; [bar,panel,box,pb].forEach(function(n){doc.body.appendChild(n);}); wire(); hist=[snap()];hidx=0;sync(); (function loop(){ if(on&&cur){var e=curEl(),r=e&&e.getBoundingClientRect(); if(r&&r.width>1&&r.height>1){ var vl=r.left,vt=r.top,vr=r.right,vb=r.bottom,V=vis(); var big=r.width*r.height>win.innerWidth*win.innerHeight*0.55||cur.k==='area'||(cur.k==='x'&&ADD[cur.n].rec.k==='text'); if(big||r.width>V.r-V.l||r.height>V.b-V.t){vl=Math.max(r.left,V.l);vr=Math.min(r.right,V.r);vt=Math.max(r.top,V.t);vb=Math.min(r.bottom,V.b);if(vr-vl<60)vr=vl+60;if(vb-vt<60)vb=vt+60;} box.classList.toggle('ed-big',big); box.style.visibility='visible';box.style.left=vl+'px';box.style.top=vt+'px';box.style.width=(vr-vl)+'px';box.style.height=(vb-vt)+'px';blabel.textContent=Math.round(r.width)+' × '+Math.round(r.height); }else box.style.visibility='hidden'; }else if(box)box.style.visibility='hidden'; win.requestAnimationFrame(loop); })(); } function layout(){var h=on&&!prev?bar.offsetHeight:0;H.style.setProperty('--ed-pt',h+'px');H.style.scrollPaddingTop=h?(h+8)+'px':'';} function setPrev(v){prev=v;if(v)H.classList.remove('ed-freeze');H.classList.toggle('ed-prev',v);layout();} function start(){ if(on)return;build();on=true;H.classList.add('ed-on'); var o=doc.getElementById('op');if(o)o.remove();doc.body.classList.remove('lock'); TX.forEach(function(e){e.setAttribute('contenteditable','true');e.setAttribute('spellcheck','false');}); ADD.forEach(function(x){if(x.rec.k==='text')x.el.setAttribute('contenteditable','true');}); bar.style.display='flex';layout();if(isWide())home(); } function stop(){ if(!on)return;flush();on=false;prev=false;H.classList.remove('ed-on');H.classList.remove('ed-prev');H.classList.remove('ed-freeze'); TX.forEach(function(e){e.removeAttribute('contenteditable');e.removeAttribute('spellcheck');}); ADD.forEach(function(x){x.el.removeAttribute('contenteditable');}); deselect();panel.style.display='none';bar.style.display='none';box.style.display='none';layout(); } win.addEventListener('resize',function(){if(built)layout();}); /* ---------- panels ---------- */ function openPanel(title,back){panel.innerHTML='';panel.style.display='block';var h=el_('div','ed-ph');if(back)h.appendChild(btn('←',back,'ed-x'));h.appendChild(el_('b',null,title));h.appendChild(btn('✕',closePanel,'ed-x'));panel.appendChild(h);} function closePanel(){panel.innerHTML='';deselect();if(on&&isWide())home();else panel.style.display='none';} function home(){ panel.innerHTML='';panel.style.display='block';panel.style.maxHeight=''; var h=el_('div','ed-ph');h.appendChild(el_('b',null,'Edit this page'));panel.appendChild(h); panel.appendChild(el_('p','ed-note','1. Tap any text on the page and type.')); panel.appendChild(el_('p','ed-note','2. Tap any picture, then drag it or pull its squares to change width and height.')); panel.appendChild(el_('p','ed-note','3. Tap an empty part of a section to change its background.')); panel.appendChild(el_('p','ed-note','Use Media, Text, Elements and Motion above to add pictures, words and shapes, or to make a picture move.')); panel.appendChild(el_('p','ed-note','Undo and Redo are above. Preview shows the clean page. Download saves the finished page.')); } function showBox(){box.style.display='block';if(!isWide())panel.style.maxHeight='34vh';} function deselect(){cur=null;op=null;if(box)box.style.display='none';if(panel)panel.style.maxHeight='';} function xel(){return cur.k==='x'?ADD[cur.n].el:IM[cur.n];} function curEl(){if(!cur)return null;if(cur.k==='x')return ADD[cur.n].el;if(cur.k==='frame')return cur.fr;if(cur.k==='img')return IM[cur.n];return AR[cur.n];} function frameOf(im){ var P=im.parentElement;if(!P||P===doc.body||P===doc.documentElement||!P._feid)return null; var cs=win.getComputedStyle(P);if(cs.position==='absolute'||cs.position==='fixed'||cs.display==='inline'||cs.display==='contents')return null; var a=im.getBoundingClientRect(),b=P.getBoundingClientRect(); if(Math.abs(a.width-b.width)>4||Math.abs(a.height-b.height)>4)return null; if(P.querySelectorAll('img').length>1)return null; return P; } function num(el,p,d){var v=parseFloat(el.style.getPropertyValue(p));return isNaN(v)?d:v;} function getXf(im){var sc=(im.style.scale||'1').split(/\s+/),tr=(im.style.translate||'0% 0%').split(/\s+/);var sx=parseFloat(sc[0])||1,sy=parseFloat(sc[1]||sc[0])||1;return {sx:sx,sy:sy,tx:parseFloat(tr[0])||0,ty:parseFloat(tr[1])||0};} function setXf(e,c){if(e._edadd){e.style.scale=c.sx+' '+c.sy;e.style.translate=c.tx+'% '+c.ty+'%';}else{setP(e._eid,'scale',c.sx+' '+c.sy);setP(e._eid,'translate',c.tx+'% '+c.ty+'%');}} function getFr(n){var im=IM[n],fr=cur.fr,op_=(im.style.objectPosition||'50% 50%').split(/\s+/);return {bw:num(fr,'--edbw',100),bh:num(fr,'--edbh',100),ox:parseFloat(op_[0]),oy:parseFloat(op_[1]),contain:im.style.objectFit==='contain'};} function setFr(n,c){ var im=IM[n],fr=cur.fr,fid=fr._feid,iid=im._eid; if(!fr._ar0){var a=parseFloat(fr.style.getPropertyValue('--edar'));if(!a){var r=fr.getBoundingClientRect();a=r.width/Math.max(1,r.height);}fr._ar0=a;} setP(fid,'--edar',fr._ar0);setP(fid,'--edbw',c.bw);setP(fid,'--edbh',c.bh); setP(fid,'width',c.bw+'%');setP(fid,'height','auto',1);setP(fid,'aspect-ratio',String(fr._ar0*c.bw/c.bh));setP(fid,'justify-self','center');setP(fid,'align-self','center'); setP(iid,'width','100%',1);setP(iid,'height','100%',1);setP(iid,'top','0',1);setP(iid,'left','0',1);setP(iid,'max-width','100%',1);setP(iid,'visibility','visible',1); setP(iid,'object-fit',c.contain?'contain':'cover',1);setP(iid,'object-position',(isNaN(c.ox)?50:c.ox)+'% '+(isNaN(c.oy)?50:c.oy)+'%',1); changed(); } function pickFile(cb){ var f=doc.createElement('input');f.type='file';f.accept='image/*'; f.onchange=function(){var file=f.files[0];if(!file)return;var rd=new FileReader();rd.onload=function(){var im=new Image();im.onload=function(){ var m=Math.min(1,1600/Math.max(im.width,im.height)),c=doc.createElement('canvas');c.width=Math.max(1,Math.round(im.width*m));c.height=Math.max(1,Math.round(im.height*m)); c.getContext('2d').drawImage(im,0,0,c.width,c.height);cb(c.toDataURL(/png|gif|svg/i.test(file.type)?'image/png':'image/jpeg',.88));};im.src=rd.result;};rd.readAsDataURL(file);}; f.click(); } function selImg(n){var im=IM[n],fr=frameOf(im);cur={k:fr?'frame':'img',n:n,fr:fr,sync:null};showBox();imgPanel(n);reveal(fr||im);} function imgPanel(n){ var S={},fr=cur.k==='frame'; openPanel('Picture '+(n+1),closePanel); if(fr){ panel.appendChild(el_('p','ed-note','This is a box. Pull the squares to make the box wider or taller. Drag the picture to move it inside the box. A picture you upload fills the box.')); var c=getFr(n); function one(label,key,min,max,get,set){panel.appendChild(lab(label));S[key]=slider(min,max,1,Math.round(get()),function(v){var q=getFr(n);set(q,v);setFr(n,q);});panel.appendChild(S[key]);} one('Box width %','w',20,100,function(){return c.bw;},function(q,v){q.bw=v;}); one('Box height %','h',20,300,function(){return c.bh;},function(q,v){q.bh=v;}); one('Show more left / right','x',0,100,function(){return isNaN(c.ox)?50:c.ox;},function(q,v){q.ox=v;}); one('Show more top / bottom','y',0,100,function(){return isNaN(c.oy)?50:c.oy;},function(q,v){q.oy=v;}); panel.appendChild(check('Show the whole picture (no cropping)',c.contain,function(v){var q=getFr(n);q.contain=v;setFr(n,q);})); cur.sync=function(){var q=getFr(n);S.w.value=Math.round(q.bw);S.h.value=Math.round(q.bh);S.x.value=Math.round(isNaN(q.ox)?50:q.ox);S.y.value=Math.round(isNaN(q.oy)?50:q.oy);}; }else{ panel.appendChild(el_('p','ed-note','Drag the picture on the page to move it. Pull the squares on its edges to change width or height; corners keep the shape (hold Shift to change freely).')); var x=getXf(IM[n]); function two(label,key,min,max,get,set){panel.appendChild(lab(label));S[key]=slider(min,max,1,Math.round(get()),function(v){var q=getXf(IM[n]);set(q,v);setXf(IM[n],q);changed();});panel.appendChild(S[key]);} two('Width %','w',10,300,function(){return x.sx*100;},function(q,v){q.sx=v/100;}); two('Height %','h',10,300,function(){return x.sy*100;},function(q,v){q.sy=v/100;}); two('Move left / right','x',-100,100,function(){return x.tx;},function(q,v){q.tx=v;}); two('Move up / down','y',-100,100,function(){return x.ty;},function(q,v){q.ty=v;}); cur.sync=function(){var q=getXf(IM[n]);S.w.value=Math.round(q.sx*100);S.h.value=Math.round(q.sy*100);S.x.value=Math.round(q.tx);S.y.value=Math.round(q.ty);}; } panel.appendChild(btn('✨ Inside Motion',motionPanel,'ed-btn ed-ghost')); panel.appendChild(btn('⬆ Upload my own picture',function(){pickFile(function(u){setSrc(IM[n]._eid,u);if(cur&&cur.k==='frame'){var q=getFr(n);setFr(n,q);}else changed();imgPanel(n);});})); panel.appendChild(btn('↺ Back to original picture',function(){revert(IM[n]._eid);if(cur&&cur.fr)revert(cur.fr._feid);changed();imgPanel(n);},'ed-btn ed-ghost')); panel.appendChild(btn('🗑 Hide this picture',function(){setP(IM[n]._eid,'display','none',1);changed();closePanel();},'ed-btn ed-ghost')); } var COLS=['#fbebb3','#fff8e1','#f6e6c8','#7a1f2b','#3f0c15','#35563b','#1f2f4f','#111111','#ffffff']; function selArea(n){cur={k:'area',n:n,sync:null};showBox();areaPanel(n);reveal(AR[n]);} function areaPanel(n){ var id=AR[n]._eid;openPanel('Section background',closePanel); panel.appendChild(el_('p','ed-note','Pick a colour, or upload a picture to fill this section.')); panel.appendChild(lab('Colour')); var row=el_('div','ed-row'); COLS.forEach(function(c){var b=el_('button','ed-sw');b.type='button';b.style.background=c;b.onclick=function(){setP(id,'background-image','none',1);setP(id,'background-color',c,1);changed();};row.appendChild(b);}); row.appendChild(colorInput('#fbebb3',function(v){setP(id,'background-image','none',1);setP(id,'background-color',v,1);changed();})); panel.appendChild(row); panel.appendChild(btn('⬆ Upload a background picture',function(){pickFile(function(u){setP(id,'background-image','url("'+u+'")',1);setP(id,'background-size','cover',1);setP(id,'background-position','center',1);setP(id,'background-repeat','no-repeat',1);changed();});})); panel.appendChild(btn('↺ Back to original background',function(){revert(id);changed();},'ed-btn ed-ghost')); } /* ---------- tap / drag / pull squares ---------- */ function calcRect(h,r0,dx,dy,free){ var l=r0.left,r=r0.right,t=r0.top,b=r0.bottom,M=24; if(h.indexOf('w')>-1)l+=dx;if(h.indexOf('e')>-1)r+=dx;if(h.indexOf('n')>-1)t+=dy;if(h.indexOf('s')>-1)b+=dy; if(h.length===2&&!free){var k=Math.max(.05,((r-l)/r0.width+(b-t)/r0.height)/2),w=r0.width*k,hh=r0.height*k; if(h.indexOf('w')>-1)l=r0.right-w;else r=r0.left+w;if(h.indexOf('n')>-1)t=r0.bottom-hh;else b=r0.top+hh;} if(r-l-1)l=r-M;else r=l+M;}if(b-t-1)t=b-M;else b=t+M;} return {l:l,t:t,w:r-l,h:b-t}; } function pickAt(x,y){ var best=-1,ba=1e12; IM.forEach(function(e,n){var cs=win.getComputedStyle(e);if(cs.display==='none'||cs.visibility==='hidden'||(parseFloat(cs.opacity)||0)<.03)return; var r=e.getBoundingClientRect();if(r.width<8||r.height<8||xr.right||yr.bottom)return;var a=r.width*r.height;if(a=0)return {k:'i',n:best}; var t=doc.elementFromPoint(x,y);if(t){for(var i=0;i-1){if(!(cur&&cur.k==='x'&&cur.n===ix))selX(ix);return;}} if(t.closest('[contenteditable=true]'))return; var h=pickAt(e.clientX,e.clientY);if(!h){deselect();if(isWide())home();return;} if(h.k==='i')selImg(h.n);else selArea(h.n); },true); box.addEventListener('pointerdown',function(e){ if(!cur)return;var e0=curEl();if(!e0)return; var h=e.target.getAttribute('data-h')||'move',r0=e0.getBoundingClientRect(); var c0=cur.k==='area'?null:(cur.k==='frame'?getFr(cur.n):getXf(xel())); op={h:h,x0:e.clientX,y0:e.clientY,r0:r0,lw:e0.offsetWidth||r0.width,lh:e0.offsetHeight||r0.height,c0:c0}; try{box.setPointerCapture(e.pointerId);}catch(_){} e.preventDefault();e.stopPropagation(); }); box.addEventListener('pointermove',function(e){ if(!op||!cur||cur.k==='area')return;var dx=e.clientX-op.x0,dy=e.clientY-op.y0,r0=op.r0,c0=op.c0; if(cur.k==='frame'){ var q={bw:c0.bw,bh:c0.bh,ox:c0.ox,oy:c0.oy,contain:c0.contain}; if(op.h==='move'){q.ox=clamp((isNaN(c0.ox)?50:c0.ox)-dx/r0.width*130,0,100);q.oy=clamp((isNaN(c0.oy)?50:c0.oy)-dy/r0.height*130,0,100);} else{var hh=op.h,kx=1,ky=1,sgx=hh.indexOf('e')>-1?1:(hh.indexOf('w')>-1?-1:0),sgy=hh.indexOf('s')>-1?1:(hh.indexOf('n')>-1?-1:0); if(sgx)kx=(r0.width+2*sgx*dx)/r0.width;if(sgy)ky=(r0.height+2*sgy*dy)/r0.height; if(sgx&&sgy&&!e.shiftKey){var kk=(kx+ky)/2;kx=kk;ky=kk;} q.bw=clamp(Math.round(c0.bw*kx),20,100);q.bh=clamp(Math.round(c0.bh*ky),20,300);} setFr(cur.n,q); }else{ var q2={sx:c0.sx,sy:c0.sy,tx:c0.tx,ty:c0.ty}; if(op.h==='move'){q2.tx=c0.tx+dx/op.lw*100;q2.ty=c0.ty+dy/op.lh*100;} else{var n2=calcRect(op.h,r0,dx,dy,e.shiftKey);q2.sx=c0.sx*n2.w/r0.width;q2.sy=c0.sy*n2.h/r0.height; q2.tx=c0.tx+((n2.l+n2.w/2)-(r0.left+r0.width/2))/op.lw*100;q2.ty=c0.ty+((n2.t+n2.h/2)-(r0.top+r0.height/2))/op.lh*100;} setXf(xel(),q2);changed(); } if(cur.sync)cur.sync(); }); function endOp(){op=null;} box.addEventListener('pointerup',endOp);box.addEventListener('pointercancel',endOp); /* links and buttons do nothing while editing */ doc.addEventListener('click',function(e){if(!on||prev)return;var t=e.target;if(!t.closest||t.closest('.ed-ui'))return;if(t.closest('a,button,summary,label,[onclick]'))e.preventDefault();e.stopPropagation();},true); doc.addEventListener('focusin',function(e){if(!on)return;var t=e.target.closest&&e.target.closest('[contenteditable=true]');if(t&&t._eid)cap(t._eid);}); doc.addEventListener('beforeinput',function(e){if(!on)return;var t=e.target.closest&&e.target.closest('[contenteditable=true]');if(t&&t._eid)cap(t._eid);}); doc.addEventListener('input',function(e){if(on&&e.target.closest&&e.target.closest('[contenteditable=true]'))changed();}); doc.addEventListener('keydown',function(e){ if(!on||prev)return;var inTx=e.target.closest&&e.target.closest('[contenteditable=true]'); if(e.key==='Enter'&&inTx){e.preventDefault();return;} if((e.key==='Delete')&&!inTx&&cur&&cur.k==='x'){e.preventDefault();removeX(cur.n);return;} if(!(e.ctrlKey||e.metaKey)||inTx)return;var k=(e.key||'').toLowerCase(); if(k==='z'&&!e.shiftKey){e.preventDefault();go(-1);}else if(k==='y'||(k==='z'&&e.shiftKey)){e.preventDefault();go(1);} }); doc.addEventListener('paste',function(e){if(on&&e.target.closest&&e.target.closest('[contenteditable=true]')){e.preventDefault();var t=(e.clipboardData||win.clipboardData).getData('text');doc.execCommand('insertText',false,t);}}); } function toHex(v){v=(v||'').trim();if(v.charAt(0)==='#'){if(v.length===4)v='#'+v.charAt(1)+v.charAt(1)+v.charAt(2)+v.charAt(2)+v.charAt(3)+v.charAt(3);return v.slice(0,7);}var m=v.match(/\d+(\.\d+)?/g);if(m&&m.length>=3)return '#'+m.slice(0,3).map(function(n){return ('0'+Math.round(+n).toString(16)).slice(-2);}).join('');return '#d8b25a';} function colourPanel(){ openPanel('Card colours',closePanel); panel.appendChild(el_('p','ed-note','Change the colours of this card. Use Pause / Play above to freeze the animation while you edit.')); [['Main gold colour','--ac'],['Shine colour (small words)','--ac2'],['Card face colour','--ov'],['Back colour (envelope, doors)','--ob']].forEach(function(c){ panel.appendChild(lab(c[0]));var cs=win.getComputedStyle(ELS.s0).getPropertyValue(c[1]); panel.appendChild(colorInput(toHex(cs),function(v){setP('s0',c[1],v);changed();})); }); panel.appendChild(btn('↺ Back to original colours',function(){revert('s0');changed();colourPanel();},'ed-btn ed-ghost')); } /* ---------- add pictures, text, shapes; motion ---------- */ var MEDIA=[]; function visibleArea(){var mid=win.innerHeight/2,best=0,bd=1e12;AR.forEach(function(a,i){var r=a.getBoundingClientRect(),d=(r.top<=mid&&r.bottom>=mid)?0:Math.min(Math.abs(r.top-mid),Math.abs(r.bottom-mid));if(d0||histT);redoB.disabled=!(hidx40)hist.shift();hidx=hist.length-1;}sync();toParent();} function changed(){clearTimeout(histT);histT=setTimeout(commit,500);sync();} function flush(){if(histT){clearTimeout(histT);commit();}} function toParent(){clearTimeout(saveT);saveT=setTimeout(function(){if(HK&&HK.save){try{HK.save(JSON.stringify(collect()));}catch(e){}}},300);} function go(d){flush();var n=hidx+d;if(n<0||n>=hist.length)return;hidx=n;apply(unsnap(hist[n]));sync();toParent();closePanel();} win.__cnEd={start:start,stop:stop}; if(opt.mode==='edit')start(); } var EDSRC=CNEDIT.toString().replace(/<\//g,'<\\/'); function dsKey(){return curOwn?(curOwn.key||('own:'+curOwn.name+':'+curOwn.html.length)):('site:'+curSite+':'+curMine)} function dsLoad(k){try{return localStorage.getItem('cn-design-'+k)}catch(e){return null}} function dsSave(k,s){try{if(s&&s!=='{}')localStorage.setItem('cn-design-'+k,s);else localStorage.removeItem('cn-design-'+k)}catch(e){}} function dsBoot(mode,state){return '('+EDSRC+')('+JSON.stringify({mode:mode,state:state||null}).replace(/'+dsBoot('apply',state)+'<'+'/script>',i=html.lastIndexOf(''); html=i>-1?html.slice(0,i)+inj+html.slice(i):html+inj; var a=document.createElement('a');a.href=URL.createObjectURL(new Blob([html],{type:'text/html'})); a.download=(curOwn?curOwn.name.replace(/\.html?$/i,'').replace(/[^\w\u0900-\u0DFF-]+/g,'-')+'-edited':'my-invitation')+'.html'; document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(a.href);a.remove()},1500)} function openOwn(name,html,key){ curSite=null;curMine=0;curOwn={name:name,html:html,key:key};var fr=$e('sv-fr'); fr.setAttribute('sandbox','allow-scripts allow-same-origin');fr.onload=null; $e('sv-title').textContent=name;$e('sv-mode').style.display='none';$e('sv-edit').style.display='none'; designOn=true;$e('sv-design').classList.add('on'); fr.srcdoc=html;$e('sv').classList.add('on');document.documentElement.style.overflow='hidden'} $e('sv-fr').addEventListener('load',injectDesign); $e('sv-design').addEventListener('click',function(){setDesign(!designOn)}); $e('ownOpen').addEventListener('click',function(){$e('ownIn').click()}); $e('ownIn').addEventListener('change',function(){var f=this.files[0];if(!f)return;var rd=new FileReader();rd.onload=function(){openOwn(f.name,String(rd.result))};rd.readAsText(f);this.value=''}); })();