im trying to change the index.html on the website,
here is link:
here is the code i wanted in index:
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Zapers Cardboard creates playful, handmade cardboard builds and custom creations.">
<title>Zapers Cardboard | Handmade cardboard creations</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Space+Grotesk:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--ink: #20251e;
--forest: #1e432f;
--leaf: #9fbd70;
--paper: #f4eddf;
--kraft: #d9b47a;
--rust: #c95c3b;
--line: rgba(32, 37, 30, .18);
}
\* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
color: var(--ink);
background: var(--paper);
font-family: "Space Grotesk", sans-serif;
}
a { color: inherit; text-decoration: none; }
.eyebrow, .mono, label, .nav-links { font-family: "DM Mono", monospace; }
.eyebrow { font-size: .72rem; letter-spacing: .13em; text-transform: uppercase; }
header {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1240px;
margin: 0 auto;
padding: 25px 32px;
}
.brand { display: flex; align-items: center; gap: 11px; font-weight: 700; font-size: 1.1rem; }
.brand-mark {
display: grid;
width: 35px; height: 35px; place-items: center;
color: var(--paper); background: var(--forest); border-radius: 50% 50% 50% 4px;
font-family: "DM Mono", monospace; font-size: .8rem; transform: rotate(-10deg);
}
nav { display: flex; align-items: center; gap: 34px; }
.nav-links { display: flex; gap: 25px; font-size: .72rem; text-transform: uppercase; }
.nav-links a:hover { color: var(--rust); }
.nav-cta, .button {
display: inline-flex; align-items: center; justify-content: center; gap: 10px;
border: 0; cursor: pointer; font: 500 .76rem "DM Mono", monospace;
text-transform: uppercase; letter-spacing: .04em;
}
.nav-cta { padding: 12px 17px; color: var(--paper); background: var(--rust); }
.hero {
display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(360px, .95fr); gap: 55px;
align-items: center; max-width: 1240px; min-height: 635px; margin: 0 auto; padding: 55px 32px 85px;
}
h1 { max-width: 650px; margin: 18px 0 25px; font-size: clamp(3.8rem, 7vw, 7.4rem); line-height: .88; letter-spacing: -.07em; }
.hero h1 em { color: var(--rust); font-style: normal; }
.hero-copy > p { max-width: 460px; margin: 0 0 31px; color: #5c6258; font-size: 1.05rem; line-height: 1.6; }
.button { padding: 16px 21px; color: var(--paper); background: var(--forest); }
.button:hover, .nav-cta:hover { background: var(--rust); }
.button span { font-size: 1.2rem; line-height: .5; }
.hero-note { display: inline-block; margin-left: 19px; color: #62685e; font: .72rem "DM Mono", monospace; text-transform: uppercase; }
.hero-art { position: relative; min-height: 470px; background: var(--kraft); overflow: hidden; }
.hero-art::before { content: ""; position: absolute; inset: 0; opacity: .22; background-image: repeating-linear-gradient(92deg, transparent 0 8px, #fff 9px 10px, transparent 11px 21px); }
.art-tag { position: absolute; top: 22px; left: 24px; z-index: 2; color: var(--forest); }
.box { position: absolute; width: 280px; height: 182px; background: #b98248; box-shadow: 15px 17px 0 rgba(32,37,30,.13); }
.box::before { content: "Z"; position: absolute; top: 57px; left: 112px; color: rgba(32,37,30,.55); font: 700 4rem "Space Grotesk", sans-serif; }
.box-one { top: 126px; left: 82px; transform: rotate(-9deg) skewY(3deg); }
.box-two { right: -28px; bottom: 86px; transform: rotate(12deg); background: #c99458; }
.tape { position: absolute; width: 31px; height: 210px; top: -12px; left: 126px; background: rgba(244,237,223,.5); transform: rotate(12deg); }
.art-caption { position: absolute; right: 24px; bottom: 22px; width: 150px; color: var(--forest); font-size: .8rem; line-height: 1.3; }
.strip { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.strip div { padding: 20px 28px; border-right: 1px solid var(--line); text-align: center; font-size: .8rem; }
.strip div:last-child { border: 0; }
.strip strong { display: block; margin-bottom: 6px; font-size: 1.2rem; }
section { max-width: 1240px; margin: 0 auto; padding: 105px 32px; }
.section-head { display: flex; justify-content: space-between; align-items: end; margin-bottom: 38px; }
h2 { max-width: 570px; margin: 10px 0 0; font-size: clamp(2.3rem, 4vw, 4.4rem); line-height: .95; letter-spacing: -.06em; }
.section-head p { max-width: 275px; color: #62685e; line-height: 1.5; }
.products { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }
.product { min-height: 280px; padding: 24px; border: 1px solid var(--line); position: relative; }
.product:nth-child(2) { background: var(--leaf); }
.product:nth-child(3) { background: var(--forest); color: var(--paper); }
.product h3 { margin: 64px 0 10px; font-size: 1.65rem; letter-spacing: -.04em; }
.product p { max-width: 270px; margin: 0; color: #5e655b; line-height: 1.45; }
.product:nth-child(3) p { color: #c8d1c0; }
.product-price { display: flex; gap: 8px; align-items: baseline; margin-top: 20px; font: .68rem "DM Mono", monospace; text-transform: uppercase; }
.product-price strong { color: var(--rust); font-size: .76rem; }
.product:nth-child(3) .product-price strong { color: var(--leaf); }
.product-number { position: absolute; right: 23px; top: 20px; font: .8rem "DM Mono", monospace; }
.product-arrow { position: absolute; bottom: 22px; right: 23px; font-size: 1.5rem; }
.studio-preview { display: grid; place-items: center; min-height: 180px; margin-top: 38px; background: rgba(32,37,30,.12); overflow: hidden; perspective: 700px; }
.cube { position: relative; width: 112px; height: 112px; cursor: grab; transform-style: preserve-3d; transform: rotateX(-18deg) rotateY(-35deg); transition: transform .45s ease; animation: float 4s ease-in-out infinite; touch-action: none; }
.cube:active { cursor: grabbing; }
.face { position: absolute; width: var(--box-width, 112px); height: var(--box-height, 112px); border: 1px solid rgba(32,37,30,.2); background: var(--craft-color, #b98248); backface-visibility: visible; transform-style: preserve-3d; }
.face::after { content: var(--label, ""); position: absolute; inset: 0; display: grid; place-items: center; padding: 12px; overflow: hidden; color: rgba(32,37,30,.45); font: 500 .78rem "DM Mono", monospace; letter-spacing: .08em; text-align: center; overflow-wrap: anywhere; }
.front { transform: translateZ(56px); } .back { transform: rotateY(180deg) translateZ(56px); } .right { transform: rotateY(90deg) translateZ(56px); } .left { transform: rotateY(-90deg) translateZ(56px); } .top { transform: rotateX(90deg) translateZ(56px); } .bottom { transform: rotateX(-90deg) translateZ(56px); }
@keyframes float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -8px; } }
.studio-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 28px; }
.studio-controls label { color: #f7ddcf; }
.studio-controls input, .studio-controls select { color: var(--paper); }
.studio-controls input\[type="range"\] { accent-color: var(--paper); }
.studio-controls input\[type="color"\] { height: 38px; padding: 3px; cursor: pointer; }
.studio-controls output { margin-left: 5px; color: #f7ddcf; }
.studio-hint { margin: 12px 0 0; color: #f7ddcf; font: .68rem "DM Mono", monospace; text-transform: uppercase; }
.design-status { display: block; min-height: 1.2em; margin-top: 14px; color: #f7ddcf; font: .68rem "DM Mono", monospace; }
.owner { max-width: 1240px; padding-top: 70px; padding-bottom: 85px; }
.owner-panel { display: grid; grid-template-columns: .8fr 1.2fr; gap: 45px; padding: 30px; border: 1px solid var(--line); background: rgba(255,255,255,.22); }
.owner-panel h2 { font-size: clamp(2rem, 4vw, 3.6rem); }
.owner-copy p { max-width: 360px; color: #62685e; line-height: 1.5; }
.owner-form { display: flex; gap: 12px; align-items: end; }
.owner-form label { flex: 1; color: #62685e; }
.owner-form input { color: var(--ink); border-color: var(--line); text-transform: uppercase; }
.owner-form .button { white-space: nowrap; }
.owner-example { margin-top: 18px; color: #62685e; font: .68rem "DM Mono", monospace; }
.owner-example strong { color: var(--forest); }
.owner-result { display: none; margin-top: 24px; padding: 22px; background: var(--forest); color: var(--paper); }
.owner-result.visible { display: block; }
.owner-result h3 { margin: 0 0 17px; font-size: 1.3rem; }
.owner-result-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; color: #d2dfca; font: .75rem "DM Mono", monospace; }
.owner-result-grid strong { display: block; margin-top: 4px; color: var(--paper); font: 1rem "Space Grotesk", sans-serif; }
.owner-model { display: grid; place-items: center; min-height: 220px; margin-top: 22px; background: rgba(244,237,223,.12); overflow: hidden; perspective: 700px; }
.owner-model .cube { animation: none; cursor: grab; }
.owner-model .cube:active { cursor: grabbing; }
.owner-settings { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.owner-settings button { padding: 10px 13px; border: 1px solid rgba(244,237,223,.5); color: var(--paper); background: transparent; cursor: pointer; font: .68rem "DM Mono", monospace; text-transform: uppercase; }
.owner-settings button:hover { background: var(--rust); }
.owner-note { margin: 18px 0 0; color: #777c72; font: .65rem "DM Mono", monospace; }
.studio { display: grid; grid-template-columns: .8fr 1.2fr; gap: 75px; background: var(--rust); color: var(--paper); max-width: none; padding-left: max(32px, calc((100% - 1176px) / 2)); padding-right: max(32px, calc((100% - 1176px) / 2)); }
.studio .eyebrow { color: #f4d3c2; }
.studio h2 { margin-top: 14px; }
.quote-intro p { max-width: 340px; color: #f3d4c5; line-height: 1.5; }
form { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 18px; align-content: start; }
label { display: grid; gap: 9px; color: #f7ddcf; font-size: .68rem; text-transform: uppercase; }
input, select, textarea { width: 100%; padding: 13px 0; border: 0; border-bottom: 1px solid rgba(244,237,223,.6); outline: 0; background: transparent; color: var(--paper); font: 1rem "Space Grotesk", sans-serif; }
select { cursor: pointer; } option { color: var(--ink); }
textarea { min-height: 60px; resize: vertical; }
.full { grid-column: 1 / -1; }
form .button { width: fit-content; color: var(--ink); background: var(--paper); }
form .button:hover { color: var(--paper); background: var(--forest); }
footer { display: flex; justify-content: space-between; max-width: 1240px; margin: auto; padding: 24px 32px 35px; font-size: .75rem; }
footer span { color: #777c72; }
@media (max-width: 760px) {
header { padding: 19px 20px; } .nav-links { display: none; } nav { gap: 0; }
.hero { grid-template-columns: 1fr; gap: 40px; padding: 45px 20px 65px; } h1 { font-size: clamp(3.7rem, 18vw, 6rem); }
.hero-art { min-height: 330px; } .box { transform: scale(.75) rotate(-9deg); left: 0; top: 95px; } .box-two { right: -70px; bottom: 45px; transform: scale(.68) rotate(12deg); }
.strip { grid-template-columns: 1fr 1fr; } .strip div { padding: 17px 10px; } .strip div:nth-child(2) { border-right: 0; } .strip div:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
section { padding: 75px 20px; } .section-head { display: block; } .section-head p { margin-top: 22px; } .products { grid-template-columns: 1fr; }
.studio { grid-template-columns: 1fr; gap: 35px; padding-left: 20px; padding-right: 20px; } form { grid-template-columns: 1fr; } .full { grid-column: auto; }
footer { padding: 24px 20px; display: block; } footer span { display: block; margin-top: 8px; }
.owner-panel { grid-template-columns: 1fr; padding: 22px; } .owner-form { display: grid; align-items: stretch; } .owner-result-grid { grid-template-columns: 1fr; }
}
</style>
<header>
<a class="brand" href="#top"><span class="brand-mark">ZC</span> Zapers Cardboard</a>
<nav>
<div class="nav-links"><a href="#products">Products</a><a href="#about">Our approach</a><a href="#owner">Owner login</a></div>
<a class="nav-cta" href="#design">Design now <span>↗</span></a>
</nav>
</header>
<main id="top">
<div class="hero">
<div class="hero-copy">
<div class="eyebrow">Cardboard, made playful</div>
<h1>Cut it.<br><em>Shape it.</em><br>Make it.</h1>
<p>Handmade cardboard creations, baked up with patience and built to make people smile.</p>
<a class="button" href="#design">Design now <span>↗</span></a><span class="hero-note">Built to fit<br>your idea</span>
</div>
<div class="hero-art" aria-label="Stacked Zapers cardboard shipping boxes">
<div class="art-tag eyebrow">Made by hand</div><div class="box box-one"><span class="tape"></span></div><div class="box box-two"></div>
<div class="art-caption mono">Strong where it matters. Thoughtful by design.</div>
</div>
</div>
<div class="strip mono"><div><strong>01</strong>Handmade</div><div><strong>02</strong>One of a kind</div><div><strong>03</strong>Recycled cardboard</div><div><strong>04</strong>Made to order</div></div>
<section id="products">
<div class="section-head"><div><div class="eyebrow">What we make</div><h2>Cardboard ideas.<br>Made real.</h2></div><p>Every piece starts as a flat sheet and turns into something playful, useful, and entirely one of a kind.</p></div>
<div class="products">
<article class="product"><span class="product-number">01 / 03</span><h3>Cardboard builds</h3><p>Hand-cut creations with plenty of character, made from sturdy recycled cardboard.</p><div class="product-price">Estimated price <strong>UNAVALIBLE</strong></div><span class="product-arrow">↗</span></article>
<article class="product"><span class="product-number">02 / 03</span><h3>Playful makes</h3><p>Big ideas turned into charming cardboard pieces for play, display, or gifting.</p><div class="product-price">Estimated price <strong>UNAVALIBLE</strong></div><span class="product-arrow">↗</span></article>
<article class="product"><span class="product-number">03 / 03</span><h3>Custom creations</h3><p>Have a cardboard idea? Zapers can shape, layer, and build it from the ground up.</p><div class="product-price">Estimated price <strong>UNAVALIBLE</strong></div><span class="product-arrow">↗</span></article>
</div>
</section>
<section class="studio" id="design">
<div class="quote-intro"><div class="eyebrow">Zapers design studio</div><h2>Make your<br>first draft.</h2><p>Build a quick idea below. This is a pretend design handoff for now, but it gives the Zapers team a clear starting point.</p><div class="studio-preview" aria-label="Interactive 3D cardboard design preview"><div class="cube" id="cube"><span class="face front"></span><span class="face back"></span><span class="face right"></span><span class="face left"></span><span class="face top"></span><span class="face bottom"></span></div></div></div>
<form id="design-form" onsubmit="sendDesign(event)">
<label>Name<input required type="text" placeholder="Your name"></label><label>Email<input required type="email" placeholder="[email protected]"></label>
<div class="studio-controls full"><label>Shape<select id="shape"><option value="box">Classic box</option><option value="cube">Cube build</option><option value="tower">Tall tower</option></select></label><label>Cardboard<input id="color" type="color" value="#b98248"></label><label>Front label <small>(leave blank for no label)</small><input id="front-label" type="text" value="ZAPERS" maxlength="12"></label><label>Back label <small>(leave blank for no label)</small><input id="back-label" type="text" maxlength="12"></label><label>Side labels <small>(leave blank for no label)</small><input id="side-label" type="text" maxlength="12"></label><label>Top label <small>(leave blank for no label)</small><input id="top-label" type="text" maxlength="12"></label><label>Bottom label <small>(leave blank for no label)</small><input id="bottom-label" type="text" maxlength="12"></label><label>Width <output id="width-value">112</output><input id="width" type="range" min="80" max="160" value="112"></label><label>Height <output id="height-value">112</output><input id="height" type="range" min="80" max="160" value="112"></label><label>Depth <output id="depth-value">112</output><input id="depth" type="range" min="80" max="160" value="112"></label></div>
<p class="studio-hint full">Drag the preview to rotate your design</p>
<label class="full">A little more detail<textarea placeholder="Tell the team what you are imagining"></textarea></label><button class="button full" type="submit">Copy design code <span>↗</span></button><span class="design-status full" id="design-status" aria-live="polite"></span>
</form>
</section>
<section class="owner" id="owner">
<div class="owner-panel">
<div class="owner-copy"><div class="eyebrow">Owner access</div><h2>Open the workshop.</h2><p>Paste a design code below to view the saved settings and the exact 3D model sent by a customer. The code contains the design data, so it can be shared with zaper.</p></div>
<div><form class="owner-form" onsubmit="ownerLogin(event)"><label>Design code<input id="owner-code" required placeholder="Paste design code" autocomplete="off"></label><button class="button" type="submit">View <span>↗</span></button></form><div class="owner-result" id="owner-result"><h3>Design loaded ✓</h3><div class="owner-result-grid"><div>DESIGN CODE<strong id="saved-code">---</strong></div><div>SHAPE<strong id="saved-shape">---</strong></div><div>DIMENSIONS<strong id="saved-dimensions">---</strong></div><div>LABELS<strong id="saved-labels">---</strong></div></div><div class="owner-model" aria-label="Saved 3D cardboard design"><div class="cube" id="owner-cube"><span class="face front"></span><span class="face back"></span><span class="face right"></span><span class="face left"></span><span class="face top"></span><span class="face bottom"></span></div></div><div class="owner-settings"><button type="button" onclick="document.getElementById('design').scrollIntoView({ behavior: 'smooth' })">Edit 3D view</button><button type="button" onclick="document.getElementById('owner-message').textContent = 'Workshop settings saved ✓'">Workshop settings</button></div><p class="owner-note" id="owner-message">Front-end demo access only. Real owner authentication needs a server.</p></div></div>
</div>
</section>
</main>
<footer id="about"><strong>Zapers Cardboard</strong><span>Cardboard made with purpose · [email protected]</span><span class="mono">© 2026</span></footer>
<script>
const cube = document.getElementById('cube');
const ownerCube = document.getElementById('owner-cube');
const color = document.getElementById('color');
const labels = {
front: document.getElementById('front-label'),
back: document.getElementById('back-label'),
side: document.getElementById('side-label'),
top: document.getElementById('top-label'),
bottom: document.getElementById('bottom-label')
};
const width = document.getElementById('width');
const height = document.getElementById('height');
const depth = document.getElementById('depth');
const shape = document.getElementById('shape');
const labelFields = Object.values(labels);
let rotationX = -18;
let rotationY = -35;
let dragging = false;
let startX = 0;
let startY = 0;
function enableRotation(target, initialX = -18, initialY = -35) {
let targetRotationX = initialX;
let targetRotationY = initialY;
let targetDragging = false;
let targetStartX = 0;
let targetStartY = 0;
target.addEventListener('pointerdown', event => { targetDragging = true; targetStartX = event.clientX; targetStartY = event.clientY; target.setPointerCapture(event.pointerId); });
target.addEventListener('pointermove', event => { if (!targetDragging) return; targetRotationY += (event.clientX - targetStartX) \* .7; targetRotationX -= (event.clientY - targetStartY) \* .5; targetStartX = event.clientX; targetStartY = event.clientY; const shapeScale = target.dataset.shape === 'tower' ? ' scaleY(1.35)' : ''; target.style.transform = \`rotateX(${targetRotationX}deg) rotateY(${targetRotationY}deg)${shapeScale}\`; });
target.addEventListener('pointerup', () => { targetDragging = false; });
}
function renderModel(target, settings) {
const widthValue = \`${settings.width}px\`;
const heightValue = \`${settings.height}px\`;
const depthValue = \`${settings.depth}px\`;
target.style.width = widthValue;
target.style.height = heightValue;
target.style.setProperty('--box-width', widthValue);
target.style.setProperty('--box-height', heightValue);
target.style.setProperty('--craft-color', settings.color);
const faces = Object.fromEntries(\['front', 'back', 'right', 'left', 'top', 'bottom'\].map(name => \[name, target.querySelector(\`.${name}\`)\]));
\[faces.front, faces.back\].forEach(face => { face.style.width = widthValue; face.style.height = heightValue; });
\[faces.right, faces.left\].forEach(face => { face.style.width = depthValue; face.style.height = heightValue; });
\[faces.top, faces.bottom\].forEach(face => { face.style.width = widthValue; face.style.height = depthValue; });
\[faces.front, faces.back, faces.top, faces.bottom\].forEach(face => { face.style.left = '0'; });
\[faces.right, faces.left\].forEach(face => { face.style.left = \`${(settings.width - settings.depth) / 2}px\`; });
\[faces.front, faces.back, faces.right, faces.left\].forEach(face => { face.style.top = '0'; });
\[faces.top, faces.bottom\].forEach(face => { face.style.top = \`${(settings.height - settings.depth) / 2}px\`; });
faces.front.style.transform = \`translateZ(${settings.depth / 2}px)\`;
faces.back.style.transform = \`rotateY(180deg) translateZ(${settings.depth / 2}px)\`;
faces.right.style.transform = \`rotateY(90deg) translateZ(${settings.width / 2}px)\`;
faces.left.style.transform = \`rotateY(-90deg) translateZ(${settings.width / 2}px)\`;
faces.top.style.transform = \`rotateX(90deg) translateZ(${settings.height / 2}px)\`;
faces.bottom.style.transform = \`rotateX(-90deg) translateZ(${settings.height / 2}px)\`;
Object.entries({ front: settings.labels.front, back: settings.labels.back, right: settings.labels.side, left: settings.labels.side, top: settings.labels.top, bottom: settings.labels.bottom }).forEach((\[name, value\]) => faces\[name\].style.setProperty('--label', value ? \`'${value.replace(/'/g, '')}'\` : '""'));
target.dataset.shape = settings.shape;
const shapeScale = settings.shape === 'tower' ? ' scaleY(1.35)' : '';
target.style.transform = \`rotateX(${settings.rotationX}deg) rotateY(${settings.rotationY}deg)${shapeScale}\`;
}
function currentSettings() {
return { width: Number(width.value), height: Number(height.value), depth: Number(depth.value), color: color.value, shape: shape.value, rotationX, rotationY, labels: Object.fromEntries(Object.entries(labels).map((\[name, field\]) => \[name, field.value\])) };
}
function updateDesign() {
const settings = currentSettings();
renderModel(cube, settings);
\['width', 'height', 'depth'\].forEach(axis => document.getElementById(\`${axis}-value\`).textContent = document.getElementById(axis).value);
}
\[color, ...labelFields, width, height, depth, shape\].forEach(control => control.addEventListener('input', updateDesign));
cube.addEventListener('pointerdown', event => { dragging = true; startX = event.clientX; startY = event.clientY; cube.setPointerCapture(event.pointerId); });
cube.addEventListener('pointermove', event => { if (!dragging) return; rotationY += (event.clientX - startX) \* .7; rotationX -= (event.clientY - startY) \* .5; startX = event.clientX; startY = event.clientY; updateDesign(); });
cube.addEventListener('pointerup', () => { dragging = false; });
enableRotation(ownerCube);
updateDesign();
const HANDOFF_RECIPIENT = 'zaper';
function encodeDesign(settings, email) {
const payload = { version: 1, recipient: HANDOFF_RECIPIENT, email, createdAt: new Date().toISOString(), nonce: Math.random().toString(36).slice(2), settings };
const encoded = btoa(unescape(encodeURIComponent(JSON.stringify(payload)))).replace(/**\\+**/g, '-').replace(/**\\/**/g, '\_').replace(/=+$/, '');
return \`ZAP-${encoded}\`;
}
function decodeDesign(code) {
try {
const encoded = code.replace(/^ZAP-/, '').replace(/-/g, '+').replace(/\_/g, '/');
return JSON.parse(decodeURIComponent(escape(atob(encoded))));
} catch (error) { return null; }
}
async function copyCode(code) {
try { await navigator.clipboard.writeText(code); } catch (error) {
const helper = document.createElement('textarea');
helper.value = code;
document.body.appendChild(helper);
helper.select();
document.execCommand('copy');
helper.remove();
}
}
async function sendDesign(event) {
event.preventDefault();
const email = document.querySelector('#design-form input\[type="email"\]').value;
const settings = currentSettings();
const code = encodeDesign(settings, email);
await copyCode(code);
window.alert(\`Warning: send this code to: ${HANDOFF_RECIPIENT}\\n\\n${code}\`);
document.getElementById('design-status').textContent = \`Design code copied ✓ ${code}\`;
document.querySelector('#design-form .button').textContent = 'Code copied ✓';
}
function ownerLogin(event) {
event.preventDefault();
const enteredCode = document.getElementById('owner-code').value.trim();
const decoded = decodeDesign(enteredCode);
const design = decoded && decoded.settings ? { code: enteredCode, settings: decoded.settings } : null;
const result = document.getElementById('owner-result');
if (!design) { result.classList.remove('visible'); document.getElementById('owner-message').textContent = 'That design code could not be read. Paste the complete copied code.'; return; }
document.getElementById('saved-code').textContent = design.code;
document.getElementById('saved-shape').textContent = design.settings.shape === 'box' ? 'Classic box' : design.settings.shape === 'cube' ? 'Cube build' : 'Tall tower';
document.getElementById('saved-dimensions').textContent = \`${design.settings.width} × ${design.settings.height} × ${design.settings.depth}\`;
const labelCount = Object.values(design.settings.labels).filter(value => value.trim()).length;
document.getElementById('saved-labels').textContent = \`${labelCount} surface${labelCount === 1 ? '' : 's'}\`;
renderModel(document.getElementById('owner-cube'), design.settings);
document.getElementById('owner-message').textContent = 'Settings ready for this demo session.';
result.classList.add('visible');
}
</script>