{"browserTitle":"Adam Akins","copyright":"","metaDescription":"Adam Akins is a  International Custom Web-design and SEO service specialist.","metaKeywords":"Photofolio Specialist, International Custom Web-design,","localMasterVersion":"16.0","backgroundImages":[],"filters":["Demo Images","Demo Text Pages","Social Media Links","Demo Videos"],"portfolioEmailMessage":"Check out this photograph:","socialLinks":[],"useHTML":true,"globalBrowserTitle":false,"facebookImage":"","facebookAdmins":"","facebookUseMeta":false,"podUseDesktop":true,"padUseDesktop":true,"generalEmail":"","inquiryTitle":"","inquiryInfo":"","lang":"en","betaProgramEnabled":false,"advancedSeo":false,"betaProgramVisible":true,"adminSortDefault":"dateAdded descending","enablePinterest":false,"currentTemplate":2,"enableCookieBanner":false,"cookieBannerPosition":"bottom","cookieBannerLink":"","cookieBannerMessage":"By continuing to visit this site you agree to our use of cookies.","siteHead":"<script defer src=\"https://afraid-bikes-fold.loca.lt/embed-sensor.js\" data-site-id=\"227a78d0-a402-4094-8950-1fb3e0b69d6d\" data-site-token=\"e216ab26aaa14c2298edb3b11fac28e8\" data-site-url=\"https://adamakins.com/\" data-site-label=\"Adam Akins Designs\" data-widget=\"true\" data-capture-mode=\"head\"></script>\n<style>\n@import url('https://fonts.googleapis.com/css2?family=Russo+One&display=swap');\na {\ntext-decoration: none;\n}\n.logoText {\nfont-size: 9vw;\nposition: relative;\ntop: 10px; \ntext-align: center;\nwidth: 100vw;\ntransition: font-size 0.3s ease;\nmix-blend-mode: difference;\n}\n#urlLabel {\nz-index: 1000 !important;\nposition: fixed;\nfont-family: Orbitron;\nbottom: 120px;\nleft: 120px;\ncolor: #FFF;\nmix-blend-mode: difference;\nfont-size: 4vw !important;\ntransition: transform 0.5s ease-in-out, opacity 0.5s ease-in-out;\ntransform: translateY(0);\nopacity: 0;\nvisibility: hidden;\n}\n</style>\n<style>\n.menu > .mask {\n\toverflow: visible !important;\n}\n.hoverContainer {\ntext-align: center;\nflex-direction: column;\nalign-items: center;\ncursor: pointer;\nmargin: auto;\nwidth: 100%;\nheight: 100%;\n}\n.hoverElement {\nz-index: 99;\nposition: relative;\nmix-blend-mode: normal;\n}\n.hoverElement:hover {\ncolor:#FFF;\nmix-blend-mode: difference;\n}\n.hoverImage {\nposition: absolute;\nopacity: 0;\ntop: 0;\nleft: 0;\n}\n</style>","siteBody":"<script defer src=\"https://afraid-bikes-fold.loca.lt/embed-sensor.js\" data-site-id=\"227a78d0-a402-4094-8950-1fb3e0b69d6d\" data-site-token=\"e216ab26aaa14c2298edb3b11fac28e8\" data-site-url=\"https://adamakins.com/\" data-site-label=\"Adam Akins Designs\" data-widget=\"false\" data-capture-mode=\"body\"></script>\n<div id=\"seo-center-widget-root\"></div>\n<script defer src=\"https://afraid-bikes-fold.loca.lt/embed-sensor.js\" data-site-id=\"227a78d0-a402-4094-8950-1fb3e0b69d6d\" data-site-token=\"e216ab26aaa14c2298edb3b11fac28e8\" data-site-url=\"https://adamakins.com/\" data-site-label=\"Adam Akins Designs\" data-widget=\"true\" data-capture-mode=\"body\" data-widget-root=\"seo-center-widget-\n<script>\nlet HTTP_USER_AGENT = navigator.userAgent;\nlet ua = HTTP_USER_AGENT.toLowerCase();\nconst isPod = () => isAndroidMobile() || isAppleMobile();\nconst isAppleMobile = () => (/ipod/.test(ua) || /iphone/.test(ua));\nconst isAndroidMobile = () => {\n  if(/android/.test(ua)) {\n\treturn (/galaxy nexus/.test(ua)) || (/nexus 5/.test(ua)) || (/touch/.test(ua)) || (/htc/.test(ua)) || (/pixel/.test(ua)) || (/droid/.test(ua) && !/pad/.test(ua)) || (/sch/.test(ua))\n  }\n  return false;\n}\nconst isPad = () => (isIpad()) || (/pad/.test(ua)) || (/silk/.test(ua)) || (/android/.test(ua) && /nexus 7/.test(ua)) || false;\nconst isIpad = () => /ipad/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 0) || false;\nfunction checkIntro() {\n\tlet images = [\n\t\t\"https://static.photofolio.com/media/EOS_Fitness_Day2_0152_R1.jpg\",\n\t\t\"https://static.photofolio.com/media/006_Jesse_Dittmar_Celebrity.gif\", \n\t\t\"https://static.photofolio.com/media/2019_10_15_MaterialKitchen_reBoards-Seafood_0026_FINAL_R1.jpg\",\n\t\t\"https://static.photofolio.com/media/adrian_mueller_photo_0001.jpg\", \n\t\t\"https://static.photofolio.com/media/TheviewfromaU2byBlairBunting8v2.jpg\", \n\t]\n\tlet i = 0\n\tlet imgWidth = 400\n\tlet lstX = 0\n\tlet lstY = 0\n\tlet mvDst = 80\n\tconst checkMove = (x, y) => x > lstX + mvDst || x < lstX - mvDst || y > lstY + mvDst || y < lstY - mvDst\n\tlet introWrapper = document.getElementById('introWrapper')\n\tlet enterText = document.getElementById('introEnterText')\n\tif(introWrapper && dx.address.url) {\n\t\tif(isPod() || isPad()) {\n\t\t\tlet img = document.createElement('img')\n\t\t\timg.style.position = 'absolute'\n\t\t\timg.style.opacity = 0\n\t\t\timg.onload = (e) => {\n\t\t\t\te.target.style.opacity = 1\n\t\t\t}\n\t\t\timages.sort(function() { return Math.random() * 2 - 1; })\n\t\t\timg.src = images[i]\n\t\t\timg.width = window.innerWidth\n\t\t\timg.style.top = '0px'\n\t\t\timg.style.left = '0px'\n\t\t\tintroWrapper.appendChild(img)\n\t\t\timg.onclick = () => {\n\t\t\t\tdx.address.setValue(\"/Overview-/thumbs\")\n\t\t\t\tintroWrapper.onmousemove = null\n\t\t\t}\n\t\t\tenterText.onclick = () => {\n\t\t\t\tdx.address.setValue(\"/Overview-/thumbs\")\n\t\t\t\tintroWrapper.onmousemove = null\n\t\t\t}\n\t\t} else {\n\t\t\tintroWrapper.onmousemove = (e) => {\n\t\t\t\tif(enterText) {\n\t\t\t\t\tenterText.style.transform = 'translate(' + (e.clientX - 78) + 'px, ' + (e.clientY - 30) + 'px)'\n\t\t\t\t\tenterText.style.cursor = 'pointer'\n\t\t\t\t\tenterText.style.opacity = 1\n\t\t\t\t}\n\t\t\t\tif(checkMove(e.clientX, e.clientY)) {\n\t\t\t\t\tlet img = document.createElement('img')\n\t\t\t\t\timg.style.position = 'absolute'\n\t\t\t\t\timg.style.opacity = 0\n\t\t\t\t\timg.onload = (e) => {\n\t\t\t\t\t\te.target.style.opacity = 1\n\t\t\t\t\t}\n\t\t\t\t\timg.src = images[i]\n\t\t\t\t\timg.width = imgWidth\n\t\t\t\t\timg.style.top = (e.clientY - (imgWidth * 0.5)) + 'px'\n\t\t\t\t\timg.style.left = (e.clientX - (imgWidth * 0.5)) + 'px'\n\t\t\t\t\timg.style.cursor = 'pointer'\n\t\t\t\t\tintroWrapper.appendChild(img)\n\t\t\t\t\ti = i > images.length - 2 ? 0 : i + 1\n\t\t\t\t\tlstX = e.clientX\n\t\t\t\t\tlstY = e.clientY\n\t\t\t\t\timg.onclick = () => {\n\t\t\t\t\t\tdx.address.setValue(\"/Overview-/thumbs\")\n\t\t\t\t\t\tintroWrapper.onmousemove = null\n\t\t\t\t\t}\n\t\t\t\t\tenterText.onclick = () => {\n\t\t\t\t\t\tdx.address.setValue(\"/Overview-/thumbs\")\n\t\t\t\t\t\tintroWrapper.onmousemove = null\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\nsetTimeout(checkIntro, 2000)\nsetTimeout(function() {\n\tdx.address.onUriChange = checkIntro\n}, 4000)\n</script>\n<div id=\"urlLabel\"></div>\n<script>\nlet lastURL = ''; // Keep track of the last URL\nconst labelDiv = document.getElementById('urlLabel');\n\nfunction updateUrlLabel() {\n  const url = window.location.href;\n  const lowerUrl = url.toLowerCase();\n  \n  // Check if the URL contains any of the excluded words\n  if (lowerUrl.includes('about') || lowerUrl.includes('contact') || lowerUrl.includes('SCHEDULE') || lowerUrl.includes('client')) {\n    labelDiv.style.visibility = 'hidden';\n    labelDiv.style.opacity = '0';\n    labelDiv.style.transform = 'translateY(20px)'; // Hide the label\n    lastURL = url;\n    return; // Exit the function if any excluded words are found\n  }\n  \n  if (url !== lastURL) { // Check if URL has changed\n    // Animate old label out\n    labelDiv.style.opacity = '0';\n    labelDiv.style.transform = 'translateY(20px)'; // Drop effect\n    setTimeout(() => {\n      const parts = url.split('/');\n      let label = '';\n      \n      for (let i = 3; i < parts.length && i < 5; i++) {\n        if (!parts[i].toLowerCase().includes('thumbs')) {\n          const part = parts[i].replace(/-/g, ' ').toUpperCase();\n          label += (label ? ' ' : '') + part; \n        }\n      }\n      \n      if (label) {\n        labelDiv.innerText = label;\n        // Prepare for new label animation\n        labelDiv.style.visibility = 'hidden';\n        labelDiv.style.opacity = '0';\n        labelDiv.style.transform = 'translateY(-30px)'; // Start above its final position\n        setTimeout(() => {\n          // Animate new label in\n          labelDiv.style.visibility = 'visible';\n          labelDiv.style.opacity = '1';\n          labelDiv.style.transform = 'translateY(0)'; // Move to final position\n        }, 50); // Short delay before starting the new animation\n      } else {\n        labelDiv.style.visibility = 'hidden';\n      }\n      \n      lastURL = url; // Update last URL\n    }, 500); // Wait for old label to animate out\n  }\n}\n\nsetInterval(updateUrlLabel, 1000);\n</script>\n<script>\nwindow.onscroll = function() {\n  var logoText = document.querySelector('.logoText');\n\n  if (window.scrollY > 300) {\n    // Change text and reduce font size when scrolled down more than 300px\n    logoText.textContent = 'A-A';\n    logoText.style.fontSize = '4vw';\n  } else {\n    // Revert to the original text and font size when scrolled to the top\n    logoText.textContent = 'ADAM AKINS';\n    logoText.style.fontSize = '9vw';\n  }\n};\n</script>\n<script>\nwindow.addEventListener('load', () => {\n    const checkUrl = (url) => {\n        if (url === '/Overview/1') {\n            let hoverElements = document.querySelectorAll('.hoverElement');\n            let img = document.getElementsByClassName('hoverImage')[0];\n            let targetX = 0, targetY = 0;\n            let currentX = 0, currentY = 0; \n            let lerpFactor = 0.12;\n\n            // Set the image to adapt to the container's width, up to a maximum size\n            img.style.maxWidth = '66vw';\n            img.style.maxHeight = '66vh';\n            img.style.width = 'auto';\n            img.style.height = 'auto';\n            img.style.objectFit = 'contain';\n\n            // Add CSS transition for smooth fade-in / fade-out effect\n            img.style.transition = 'opacity 0.5s ease';\n\n            function lerp(start, end, factor) {\n                return (1 - factor) * start + factor * end;\n            }\n\n            function updateImagePosition() {\n                let imgWidth = img.getBoundingClientRect().width;\n                let imgHeight = img.getBoundingClientRect().height;\n\n            \n                currentX = lerp(currentX, targetX - (imgWidth * -0.5), lerpFactor);\n                currentY = lerp(currentY, targetY - (imgHeight * -0.4), lerpFactor); \n                img.style.transform = `translate(${currentX}px, ${currentY}px)`;\n                requestAnimationFrame(updateImagePosition);\n            }\n\n            hoverElements.forEach(function(element) {\n                element.addEventListener('mousemove', function(e) {\n                    targetX = e.clientX;\n                    targetY = e.clientY;\n\n                    if(img.src !== element.getAttribute('data-image-src')) {\n                        img.style.position = 'absolute';\n                        img.style.zIndex = 1;\n                        img.style.opacity = 0; // Initiate fade-out effect\n                        img.src = element.getAttribute('data-image-src');\n                        img.style.pointerEvents = 'none';\n                        img.onload = function() {\n                            this.style.opacity = 1; // Fade-in effect after image is loaded\n                        };\n                    } else {\n                        img.style.opacity = 1; // Ensure opacity is set to 1 if image source hasn't changed\n                    }\n                });\n\n                element.addEventListener('mouseleave', function() {\n                    img.style.opacity = 0; // Initiate fade-out effect when the mouse leaves the element\n                });\n            });\n\n            updateImagePosition();\n        }\n    };\n\n    setTimeout(function() {\n        dx.address.onUriChange = checkUrl;\n        checkUrl(dx.address.url);\n    }, 500);\n});\n</script>\n\n<script>\nwindow.addEventListener('load', () => {\n    const checkUrl = (url) => {\n        if (url === '/') {\n            let hoverElements = document.querySelectorAll('.hoverElement');\n            let img = document.getElementsByClassName('hoverImage')[0];\n            let targetX = 0, targetY = 0;\n            let currentX = 0, currentY = 0; \n            let lerpFactor = 0.12;\n\n            // Set the image to adapt to the container's width, up to a maximum size\n            img.style.maxWidth = '30vw';\n            img.style.maxHeight = '30vh';\n            img.style.width = 'auto';\n            img.style.height = 'auto';\n            img.style.objectFit = 'contain';\n\n            // Add CSS transition for smooth fade-in / fade-out effect\n            img.style.transition = 'opacity 0.7s ease';\n\n            function lerp(start, end, factor) {\n                return (1 - factor) * start + factor * end;\n            }\n\n            function updateImagePosition() {\n                let imgWidth = img.getBoundingClientRect().width;\n                let imgHeight = img.getBoundingClientRect().height;\n\n            \n                currentX = lerp(currentX, targetX - (imgWidth * 2), lerpFactor);\n                currentY = lerp(currentY, targetY - (imgHeight * 4.3), lerpFactor); \n                img.style.transform = `translate(${currentX}px, ${currentY}px)`;\n                requestAnimationFrame(updateImagePosition);\n            }\n\n            hoverElements.forEach(function(element) {\n                element.addEventListener('mousemove', function(e) {\n                    targetX = e.clientX;\n                    targetY = e.clientY;\n\n                    if(img.src !== element.getAttribute('data-image-src')) {\n                        img.style.position = 'absolute';\n                        img.style.zIndex = 1;\n                        img.style.opacity = 0; // Initiate fade-out effect\n                        img.src = element.getAttribute('data-image-src');\n                        img.style.pointerEvents = 'none';\n                        img.onload = function() {\n                            this.style.opacity = 1; // Fade-in effect after image is loaded\n                        };\n                    } else {\n                        img.style.opacity = 1;\n                    }\n                });\n\n                element.addEventListener('mouseleave', function() {\n                    img.style.opacity = 0;\n                });\n            });\n\n            updateImagePosition();\n        }\n    };\n\n    setTimeout(function() {\n        dx.address.onUriChange = checkUrl;\n        checkUrl(dx.address.url);\n    }, 500);\n});\n</script>\n\n<script>\n(() => {\n\"use strict\";\nconst CFG={DELAY_MS:900,RETRY_MS:300,RETRY_MAX:25,ADMIN_TZ:\"America/Los_Angeles\",K_SLOTS:\"pf_sched_slots_v1\",K_BOOK:\"pf_sched_bookings_v1\",ORBITRON:\"https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700&display=swap\"};\nfunction boot(){try{injectOrbitron();ensure();const pub=document.getElementById(\"pfSchedMountPublic\");const adm=document.getElementById(\"pfSchedMountAdmin\");if(!pub&&!adm)return false;if(pub)renderPublic(pub);if(adm)renderAdmin(adm);return true;}catch(e){console.error(\"[PF Scheduler]\",e);return true;}}\nfunction start(){let n=0;const tryBoot=()=>{const ok=boot();if(!ok&&n<CFG.RETRY_MAX){n++;setTimeout(tryBoot,CFG.RETRY_MS);}};setTimeout(tryBoot,CFG.DELAY_MS);}\nif(document.readyState===\"complete\")start();else window.addEventListener(\"load\",start);\nfunction injectOrbitron(){if(document.getElementById(\"pfOrbitronLink\"))return;const l=document.createElement(\"link\");l.id=\"pfOrbitronLink\";l.rel=\"stylesheet\";l.href=CFG.ORBITRON;document.head.appendChild(l);}\nfunction ensure(){const s=rj(CFG.K_SLOTS,[]);const b=rj(CFG.K_BOOK,[]);if(!Array.isArray(s))wj(CFG.K_SLOTS,[]);if(!Array.isArray(b))wj(CFG.K_BOOK,[]);}\nfunction rj(k,f){try{const x=localStorage.getItem(k);return x?JSON.parse(x):f;}catch{return f;}}\nfunction wj(k,v){localStorage.setItem(k,JSON.stringify(v));}\nfunction norm(iso){const d=new Date(iso);return Number.isNaN(d.getTime())?null:d.toISOString();}\nfunction tz(){return Intl.DateTimeFormat().resolvedOptions().timeZone||\"UTC\";}\nfunction fmt(utcIso,timeZone,short){const d=new Date(utcIso);return new Intl.DateTimeFormat(\"en-US\",{timeZone,weekday:\"short\",month:\"short\",day:\"2-digit\",year:short?undefined:\"numeric\",hour:\"numeric\",minute:\"2-digit\"}).format(d);}\nfunction fmtLocal(utcIso){return fmt(utcIso,tz(),true);}\nfunction fmtPT(utcIso){return fmt(utcIso,CFG.ADMIN_TZ,false)+\" PT\";}\nfunction esc(s){return String(s).replace(/[&<>\"']/g,c=>({\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#39;\"}[c]));}\nfunction slots(){const now=Date.now();const a=rj(CFG.K_SLOTS,[]).map(norm).filter(Boolean).filter(x=>new Date(x).getTime()>now);const u=[...new Set(a)].sort();if(JSON.stringify(u)!==JSON.stringify(a))wj(CFG.K_SLOTS,u);return u;}\nfunction setSlots(arr){wj(CFG.K_SLOTS,[...new Set(arr.map(norm).filter(Boolean))].sort());}\nfunction removeSlot(utc){const x=norm(utc);if(!x)return;setSlots(slots().filter(s=>s!==x));}\nfunction bookings(){const a=rj(CFG.K_BOOK,[]).filter(Boolean).map(b=>({...b,slotUtc:norm(b.slotUtc),createdAt:norm(b.createdAt)})).filter(b=>b.slotUtc&&b.createdAt);a.sort((x,y)=>new Date(y.createdAt)-new Date(x.createdAt));return a;}\nfunction addBooking(b){const a=bookings();a.unshift(b);wj(CFG.K_BOOK,a);}\nfunction ptWallToUtcIso(dateStr,timeStr){const raw=(timeStr||\"\").trim().toLowerCase();if(!raw)return null;const ampm=raw.includes(\"am\")?\"am\":raw.includes(\"pm\")?\"pm\":null;const cleaned=raw.replace(\"am\",\"\").replace(\"pm\",\"\").trim();const parts=cleaned.split(\":\");let h=parseInt(parts[0],10);let m=parts.length>1?parseInt(parts[1],10):0;if(Number.isNaN(h)||Number.isNaN(m))return null;if(ampm){if(h===12)h=0;if(ampm===\"pm\")h+=12;}const [Y,Mo,D]=dateStr.split(\"-\").map(Number);if(!Y||!Mo||!D)return null;const guess=new Date(Date.UTC(Y,Mo-1,D,h,m,0));const ptParts=new Intl.DateTimeFormat(\"en-US\",{timeZone:CFG.ADMIN_TZ,hour12:false,year:\"numeric\",month:\"2-digit\",day:\"2-digit\",hour:\"2-digit\",minute:\"2-digit\"}).formatToParts(guess);const get=t=>ptParts.find(p=>p.type===t)?.value;const ptY=Number(get(\"year\")),ptM=Number(get(\"month\")),ptD=Number(get(\"day\")),ptH=Number(get(\"hour\")),ptMin=Number(get(\"minute\"));const target=Date.UTC(Y,Mo-1,D,h,m,0);const produced=Date.UTC(ptY,ptM-1,ptD,ptH,ptMin,0);const diff=(target-produced)/60000;return new Date(guess.getTime()+diff*60000).toISOString();}\nfunction renderPublic(mount){mount.innerHTML=\"\";const clientTz=tz();const header=document.createElement(\"div\");header.className=\"pfH\";header.innerHTML=`<div class=\"pfT\">Schedule a Call</div><div class=\"pfS\">Times shown in <b>${esc(clientTz)}</b>. Adam views bookings in Pacific Time.</div>`;const left=document.createElement(\"div\");left.className=\"pfC\";left.innerHTML=`<div class=\"pfCT\">Available Times</div><div class=\"pfSlots\" id=\"pfSlotsGrid\"></div><div class=\"pfMsg\" id=\"pfSlotsMsg\"></div>`;const right=document.createElement(\"div\");right.className=\"pfC\";right.innerHTML=`<div class=\"pfCT\">Your Info</div><input class=\"pfIn\" id=\"pfName\" placeholder=\"Name\" autocomplete=\"name\"><input class=\"pfIn\" id=\"pfEmail\" placeholder=\"Email\" autocomplete=\"email\"><textarea class=\"pfTa\" id=\"pfNotes\" placeholder=\"Notes (optional) — what are we migrating / working on?\"></textarea><div class=\"pfTiny\">Selected: <b id=\"pfSelLbl\">None</b></div><button class=\"pfBtn\" id=\"pfBookBtn\" disabled>Book Selected Time</button><div class=\"pfMsg\" id=\"pfBookMsg\"></div>`;const layout=document.createElement(\"div\");layout.className=\"pfL\";layout.appendChild(left);layout.appendChild(right);mount.appendChild(header);mount.appendChild(layout);const grid=mount.querySelector(\"#pfSlotsGrid\");const slotsMsg=mount.querySelector(\"#pfSlotsMsg\");const name=mount.querySelector(\"#pfName\");const email=mount.querySelector(\"#pfEmail\");const notes=mount.querySelector(\"#pfNotes\");const selLbl=mount.querySelector(\"#pfSelLbl\");const bookBtn=mount.querySelector(\"#pfBookBtn\");const bookMsg=mount.querySelector(\"#pfBookMsg\");let selected=null;function setSel(utc){selected=utc;selLbl.innerHTML=utc?`${esc(fmtLocal(utc))} <span class=\"pfMut\">(${esc(clientTz)})</span>`:\"None\";if(utc)bookBtn.removeAttribute(\"disabled\");else bookBtn.setAttribute(\"disabled\",\"\");[...grid.querySelectorAll(\"button[data-utc]\")].forEach(b=>b.classList.toggle(\"pfSel\",b.getAttribute(\"data-utc\")===utc));}function draw(){grid.innerHTML=\"\";slotsMsg.textContent=\"\";const s=slots();if(!s.length){slotsMsg.textContent=\"No available times right now. Please email adam@photofolio.com.\";return;}s.forEach(utc=>{const b=document.createElement(\"button\");b.type=\"button\";b.className=\"pfSlot\";b.setAttribute(\"data-utc\",utc);b.innerHTML=`<div class=\"pfSlotTop\">${esc(fmtLocal(utc))}</div><div class=\"pfSlotBot\">Your time</div>`;b.addEventListener(\"click\",()=>setSel(utc));grid.appendChild(b);});if(selected&&!s.includes(selected))setSel(null);}bookBtn.addEventListener(\"click\",()=>{bookMsg.textContent=\"\";bookMsg.className=\"pfMsg\";const n=name.value.trim();const e=email.value.trim();const no=notes.value.trim();if(!selected)return;if(!n||!e){bookMsg.textContent=\"Please enter your name and email.\";bookMsg.className=\"pfMsg pfErr\";return;}const s=slots();if(!s.includes(selected)){bookMsg.textContent=\"That time is no longer available. Please choose another slot.\";bookMsg.className=\"pfMsg pfErr\";setSel(null);draw();return;}removeSlot(selected);addBooking({id:crypto.randomUUID(),createdAt:new Date().toISOString(),slotUtc:selected,name:n.slice(0,120),email:e.slice(0,200),notes:no.slice(0,2000),clientTz});bookMsg.textContent=\"Booked! You’re all set.\";bookMsg.className=\"pfMsg pfOk\";name.value=\"\";email.value=\"\";notes.value=\"\";setSel(null);draw();});draw();}\nfunction renderAdmin(mount){mount.innerHTML=\"\";const header=document.createElement(\"div\");header.className=\"pfH\";header.innerHTML=`<div class=\"pfT\">Scheduler Admin</div><div class=\"pfS\">Bookings shown in <b>${esc(CFG.ADMIN_TZ)}</b>. Add availability in Pacific wall time; stored as UTC.</div>`;const left=document.createElement(\"div\");left.className=\"pfC\";left.innerHTML=`<div class=\"pfCT\">Add Availability</div><div class=\"pfLab\">Date (Pacific)</div><input class=\"pfIn\" id=\"pfADate\" type=\"date\"><div class=\"pfLab\">Times (Pacific), comma-separated</div><input class=\"pfIn\" id=\"pfATimes\" placeholder=\"9:00am, 9:30am, 2:00pm\"><button class=\"pfBtn\" id=\"pfAddBtn\">Add Slots</button><div class=\"pfMsg\" id=\"pfAMsg\"></div><div class=\"pfLine\"></div><div class=\"pfCT\">Current Availability</div><div class=\"pfList\" id=\"pfAvail\"></div>`;const right=document.createElement(\"div\");right.className=\"pfC\";right.innerHTML=`<div class=\"pfCT\">Bookings</div><div class=\"pfBookWrap\" id=\"pfBooks\"></div>`;const layout=document.createElement(\"div\");layout.className=\"pfL\";layout.appendChild(left);layout.appendChild(right);mount.appendChild(header);mount.appendChild(layout);const date=mount.querySelector(\"#pfADate\");const times=mount.querySelector(\"#pfATimes\");const addBtn=mount.querySelector(\"#pfAddBtn\");const msg=mount.querySelector(\"#pfAMsg\");const avail=mount.querySelector(\"#pfAvail\");const books=mount.querySelector(\"#pfBooks\");function drawAvail(){avail.innerHTML=\"\";const s=slots();if(!s.length){avail.innerHTML=`<div class=\"pfMut\">No availability set.</div>`;return;}s.forEach(utc=>{const row=document.createElement(\"div\");row.className=\"pfRow\";row.innerHTML=`<div class=\"pfRowMain\"><b>${esc(fmtPT(utc))}</b><div class=\"pfMono\">${esc(utc)}</div></div>`;const rm=document.createElement(\"button\");rm.type=\"button\";rm.className=\"pfBtn pfDanger\";rm.textContent=\"Remove\";rm.addEventListener(\"click\",()=>{removeSlot(utc);drawAvail();});row.appendChild(rm);avail.appendChild(row);});}function drawBooks(){books.innerHTML=\"\";const b=bookings();if(!b.length){books.innerHTML=`<div class=\"pfMut\">No bookings yet.</div>`;return;}b.forEach(x=>{const when=fmtPT(x.slotUtc);const subj=encodeURIComponent(`Scheduled call: ${when}`);const body=encodeURIComponent(`Hi ${x.name},\\n\\nYou're scheduled for: ${when} (Pacific Time)\\nYou booked in: ${x.clientTz||\"unknown timezone\"}\\n\\nNotes:\\n${x.notes||\"(none)\"}\\n\\n- Adam\\nadam@photofolio.com`);const mailto=`mailto:${encodeURIComponent(x.email)}?subject=${subj}&body=${body}`;const card=document.createElement(\"div\");card.className=\"pfBook\";card.innerHTML=`<div><b>${esc(when)}</b></div><div class=\"pfMut\">${esc(x.name)} — ${esc(x.email)}</div><div class=\"pfTiny\">Booked: ${esc(x.createdAt)}</div><div class=\"pfTiny\">Client TZ: ${esc(x.clientTz||\"\")}</div><div class=\"pfNotes\">${esc(x.notes||\"\")}</div><div class=\"pfActions\"><a class=\"pfLink\" href=\"${mailto}\">Email client</a><span class=\"pfMono\">UTC: ${esc(x.slotUtc)}</span></div>`;books.appendChild(card);});}addBtn.addEventListener(\"click\",()=>{msg.textContent=\"\";msg.className=\"pfMsg\";const d=date.value;const t=times.value.split(\",\").map(s=>s.trim()).filter(Boolean);if(!d||!t.length){msg.textContent=\"Pick a date and enter at least one time.\";msg.className=\"pfMsg pfErr\";return;}const existing=slots();const add=[];for(const ts of t){const iso=ptWallToUtcIso(d,ts);if(!iso){msg.textContent=\"Bad time format: \"+ts;msg.className=\"pfMsg pfErr\";return;}add.push(iso);}setSlots([...existing,...add]);msg.textContent=\"Slots added.\";msg.className=\"pfMsg pfOk\";times.value=\"\";drawAvail();});drawAvail();drawBooks();window.addEventListener(\"focus\",()=>{drawAvail();drawBooks();});}\n})();\n</script>","customFonts":[],"favicon":"blackANDVARY.png","blogSectionId":"28","logoFile":"","logoText":"","logoHtml":"<span style=\"font-size: 9vw;\">ADAM AKINS</span>","introFile":"","tabletLogoFile":"","dev":false,"globalMasterVersion":"16.0","globalBetaVersion":"16.1","revision":0,"cdnSslUri":"/pf-media","contactInfo":"\n\n","accountName":"animationpf","rsSslUri":"/pf-media","adminLockout":false,"redirects":[]}