{"product_id":"crunchy-sound-peanut-squishy-toy","title":"Crunchy Peanut Squishy | Squeeze \u0026 Crackle Fidget Toy","description":"\u003cstyle\u003e\n  #aj-peanut-crunch {\n    --ink: #34201a;\n    --muted: #62483d;\n    --cream: #fff8eb;\n    --gold: #ffc66b;\n    --line: #e9cda6;\n    width: 100%;\n    max-width: 1060px;\n    min-width: 0;\n    margin: 24px auto;\n    overflow: hidden;\n    border: 1px solid var(--line);\n    border-radius: 20px;\n    background: var(--cream);\n    color: var(--ink);\n    font: 16px\/1.6 system-ui, sans-serif;\n    container-type: inline-size;\n  }\n\n  #aj-peanut-crunch * { box-sizing: border-box; }\n  #aj-peanut-crunch[hidden],\n  #aj-peanut-crunch [hidden],\n  .aj-pc-overlay[hidden] { display: none !important; }\n\n  #aj-peanut-crunch :is(h2, h3, p, figure) {\n    margin: 0;\n    padding: 0;\n    letter-spacing: normal;\n    text-transform: none;\n  }\n\n  #aj-peanut-crunch :is(h2, h3) {\n    color: inherit;\n    font-family: Georgia, serif;\n    font-weight: 700;\n    line-height: 1.1;\n    text-wrap: balance;\n  }\n\n  #aj-peanut-crunch h2 { font-size: clamp(32px, 6cqi, 64px); }\n  #aj-peanut-crunch h3 { font-size: clamp(24px, 4cqi, 39px); }\n  #aj-peanut-crunch p { color: var(--muted); }\n  #aj-peanut-crunch :is(h2, h3) + p { margin-top: 12px; }\n\n  #aj-peanut-crunch .aj-pc-label {\n    margin-bottom: 10px;\n    color: #833821;\n    font-size: 12px;\n    font-weight: 800;\n    letter-spacing: .11em;\n    text-transform: uppercase;\n  }\n\n  #aj-peanut-crunch :is(.aj-pc-hero, .aj-pc-story) {\n    display: grid;\n    align-items: center;\n    min-width: 0;\n  }\n\n  #aj-peanut-crunch .aj-pc-hero {\n    background: linear-gradient(135deg, #ffdeb0, #ffd08a);\n  }\n\n  #aj-peanut-crunch .aj-pc-copy { padding: clamp(22px, 5cqi, 48px); }\n  #aj-peanut-crunch figure { min-width: 0; overflow: hidden; }\n  #aj-peanut-crunch img {\n    display: block;\n    width: 100%;\n    max-width: 100%;\n    height: auto;\n    margin: 0;\n  }\n\n  #aj-peanut-crunch .aj-pc-strip {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: center;\n    gap: 6px 18px;\n    padding: 12px 16px;\n    border-bottom: 1px solid var(--line);\n    background: #fffdf7;\n    font-size: 14px;\n    font-weight: 700;\n  }\n\n  #aj-peanut-crunch .aj-pc-body {\n    display: grid;\n    gap: clamp(24px, 5cqi, 46px);\n    padding: clamp(17px, 4cqi, 40px);\n  }\n\n  #aj-peanut-crunch .aj-pc-story { gap: 16px clamp(18px, 4cqi, 38px); }\n  #aj-peanut-crunch .aj-pc-body figure { border-radius: 13px; }\n\n  #aj-peanut-crunch .aj-pc-photos {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(min(100%, 145px), 1fr));\n    align-items: start;\n    gap: 10px;\n    margin-top: 14px;\n  }\n\n  #aj-peanut-crunch :is(.aj-pc-demo, .aj-pc-video, .aj-pc-faq) {\n    padding: clamp(16px, 4cqi, 30px);\n    border: 1px solid var(--line);\n    border-radius: 15px;\n    background: #fffdf7;\n  }\n\n  #aj-peanut-crunch .aj-pc-demo { text-align: center; background: #ffeac8; }\n\n  #aj-peanut-crunch .aj-pc-squeeze {\n    display: inline-grid;\n    justify-items: center;\n    gap: 6px;\n    margin: 14px auto 8px;\n    padding: 12px 23px;\n    border: 1px solid #95512e;\n    border-radius: 16px;\n    background: #ffd586;\n    color: var(--ink);\n    font: inherit;\n    font-weight: 800;\n    cursor: pointer;\n    touch-action: manipulation;\n    user-select: none;\n  }\n\n  #aj-peanut-crunch .aj-pc-squeeze svg {\n    width: 130px;\n    height: 72px;\n    transition: transform .18s ease-out;\n  }\n\n  #aj-peanut-crunch .aj-pc-squeeze:active svg { transform: scale(1.13, .69); }\n  #aj-peanut-crunch .aj-pc-status { min-height: 1.6em; font-size: 14px; }\n  #aj-peanut-crunch video {\n    display: block;\n    width: 100%;\n    max-height: 500px;\n    margin-top: 14px;\n    border-radius: 12px;\n    background: #34201a;\n  }\n\n  #aj-peanut-crunch .aj-pc-faq h3 { margin-bottom: 12px; }\n  #aj-peanut-crunch details { border-top: 1px solid var(--line); }\n  #aj-peanut-crunch summary { padding: 11px 0; font-weight: 700; cursor: pointer; }\n  #aj-peanut-crunch details p { padding-bottom: 12px; }\n\n  #aj-peanut-crunch footer {\n    padding: clamp(23px, 5cqi, 45px) 16px;\n    background: #43271f;\n    color: #fff5e5;\n    text-align: center;\n  }\n\n  #aj-peanut-crunch footer p { color: #ffe5c2; }\n\n  #aj-peanut-crunch .aj-pc-cta {\n    display: inline-flex;\n    align-items: center;\n    min-height: 46px;\n    margin-top: 14px;\n    padding: 9px 21px;\n    border-radius: 999px;\n    background: var(--gold);\n    color: #3b231a;\n    text-decoration: none;\n    font-weight: 800;\n  }\n\n  #aj-peanut-crunch .aj-pc-toggle {\n    display: block;\n    min-height: 44px;\n    margin: 4px auto 0;\n    padding: 5px 10px;\n    border: 0;\n    background: transparent;\n    color: inherit;\n    font: inherit;\n    font-size: 13px;\n    text-decoration: underline;\n    cursor: pointer;\n  }\n\n  #aj-peanut-crunch :is(a, button, summary):focus-visible {\n    outline: 2px solid #a85e20;\n    outline-offset: 4px;\n  }\n\n  @container (min-width: 680px) {\n    #aj-peanut-crunch :is(.aj-pc-hero, .aj-pc-story).aj-pc-paired {\n      grid-template-columns: repeat(2, minmax(0, 1fr));\n    }\n    #aj-peanut-crunch .aj-pc-reverse figure { order: 2; }\n  }\n\n  .aj-pc-overlay {\n    position: fixed;\n    inset: 0;\n    z-index: 12;\n    overflow: hidden;\n    pointer-events: none;\n  }\n\n  .aj-pc-overlay * { pointer-events: none; }\n\n  .aj-pc-glow {\n    position: absolute;\n    inset: 0;\n    opacity: 0;\n    background:\n      radial-gradient(ellipse at left 48%, #ffb52f9c, transparent 34%),\n      radial-gradient(ellipse at right 57%, #ffb52f9c, transparent 34%);\n  }\n\n  .aj-pc-stamp {\n    position: absolute;\n    top: 29%;\n    left: 4vw;\n    padding: 9px 13px;\n    border: 2px solid #733a27;\n    border-radius: 10px;\n    background: #ffcf72;\n    color: #50271a;\n    box-shadow: 4px 5px #733a27;\n    font: 900 clamp(19px, 5vw, 48px)\/1 system-ui, sans-serif;\n    opacity: 0;\n    --tilt: -12deg;\n  }\n\n  .aj-pc-stamp--right {\n    top: auto;\n    left: auto;\n    right: 4vw;\n    bottom: max(110px, 22vh);\n    --tilt: 12deg;\n  }\n\n  .aj-pc-chip {\n    position: absolute;\n    left: var(--x);\n    top: var(--y);\n    width: clamp(8px, 1.5vw, 19px);\n    height: clamp(13px, 2vw, 26px);\n    border: 1px solid #a5693d;\n    border-radius: 75% 30% 65% 35%;\n    background: #ffd17e;\n    box-shadow: inset 2px 1px #ffeabb;\n    opacity: 0;\n  }\n\n  .aj-pc-overlay.aj-pc-pop .aj-pc-glow { animation: aj-pc-glow .72s ease-out both; }\n  .aj-pc-overlay.aj-pc-pop .aj-pc-stamp { animation: aj-pc-stamp .92s ease-out both; }\n  .aj-pc-overlay.aj-pc-pop .aj-pc-chip { animation: aj-pc-chip .86s ease-out both; }\n\n  @keyframes aj-pc-glow {\n    0%, 100% { opacity: 0; }\n    23% { opacity: .85; }\n  }\n\n  @keyframes aj-pc-stamp {\n    0% { opacity: 0; transform: scale(.45) rotate(var(--tilt)); }\n    23% { opacity: 1; transform: scale(1.12) rotate(var(--tilt)); }\n    62% { opacity: 1; transform: scale(1) rotate(var(--tilt)); }\n    100% { opacity: 0; transform: translateY(-18px) scale(.95) rotate(var(--tilt)); }\n  }\n\n  @keyframes aj-pc-chip {\n    0% { opacity: 0; transform: scale(.4); }\n    21% { opacity: 1; }\n    100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(155deg); }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    .aj-pc-overlay { display: none; }\n    #aj-peanut-crunch .aj-pc-squeeze svg { transition: none; }\n    #aj-peanut-crunch .aj-pc-squeeze:active svg { transform: none; }\n  }\n\u003c\/style\u003e\n\n\u003csection id=\"aj-peanut-crunch\" aria-labelledby=\"aj-pc-title\"\u003e\n  \u003cheader class=\"aj-pc-hero\"\u003e\n    \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n    \u003cdiv class=\"aj-pc-copy\"\u003e\n      \u003cp class=\"aj-pc-label\"\u003eA crunchy little desk fidget\u003c\/p\u003e\n      \u003ch2 id=\"aj-pc-title\"\u003eSoft Squeeze. Big Little Crunch.\u003c\/h2\u003e\n      \u003cp\u003eGive this peanut-shaped squishy a squeeze and listen for the crackle. Keep it next to your keyboard for the moments when your hands want something to do.\u003c\/p\u003e\n    \u003c\/div\u003e\n  \u003c\/header\u003e\n\n  \u003cdiv class=\"aj-pc-strip\"\u003e\n    \u003cspan\u003eSoft, squeezable feel\u003c\/span\u003e\n    \u003cspan\u003eCrunchy sound\u003c\/span\u003e\n    \u003cspan\u003ePeanut-shaped grip\u003c\/span\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv class=\"aj-pc-body\"\u003e\n    \u003csection class=\"aj-pc-video\" hidden\u003e\n      \u003ch3\u003eWatch a Real Squeeze\u003c\/h3\u003e\n      \u003cp\u003eSee how it compresses in the hand. If the clip has sound, turn it up for the crunch.\u003c\/p\u003e\n    \u003c\/section\u003e\n\n    \u003csection class=\"aj-pc-demo\" hidden\u003e\n      \u003ch3\u003eGive It a Squeeze\u003c\/h3\u003e\n      \u003cp\u003ePress the peanut and release it to see the crunch.\u003c\/p\u003e\n      \u003cbutton type=\"button\" class=\"aj-pc-squeeze\"\u003e\n        \u003csvg viewbox=\"0 0 140 80\" aria-hidden=\"true\" focusable=\"false\"\u003e\n          \u003cpath d=\"M10 47C7 30 22 14 39 16c14 1 21 12 34 10 14-2 20-17 39-12 16 4 23 23 15 37-8 15-24 20-40 13-10-4-18-7-28 0C42 77 15 69 10 47Z\" fill=\"#eca851\" stroke=\"#854822\" stroke-width=\"3\"\u003e\u003c\/path\u003e\n          \u003cpath d=\"M20 44c11-15 24-17 36-9s24 8 36-3c8-8 18-8 27-1M24 55c9-10 21-10 31-5 12 6 22 9 38-1 9-5 17-8 25-6M28 31l8 29m12-34 8 29m15-21 7 23m16-31 8 27m8-31 7 23\" fill=\"none\" stroke=\"#99582d\" stroke-width=\"2\" stroke-linecap=\"round\"\u003e\u003c\/path\u003e\n        \u003c\/svg\u003e\n        \u003cspan\u003eSqueeze Me\u003c\/span\u003e\n      \u003c\/button\u003e\n      \u003cp class=\"aj-pc-status\" role=\"status\"\u003eSilent on-screen demo\u003c\/p\u003e\n    \u003c\/section\u003e\n\n    \u003carticle class=\"aj-pc-story\"\u003e\n      \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n      \u003cdiv\u003e\n        \u003ch3\u003eTwo Ends to Squish\u003c\/h3\u003e\n        \u003cp\u003eCradle it in your palm and press one rounded end with your thumb. Then try a whole-hand squeeze across the middle. The peanut shape gives your fingers a few different places to grip.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/article\u003e\n\n    \u003carticle class=\"aj-pc-story aj-pc-reverse\"\u003e\n      \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n      \u003cdiv\u003e\n        \u003ch3\u003eFor the Friend Who Pops Every Bubble\u003c\/h3\u003e\n        \u003cp\u003eLeave one by the keyboard for a quick desk break, or tuck it into a gift bag for someone who always claims the bubble wrap. The little crackle is the part they’ll want to try for themselves.\u003c\/p\u003e\n      \u003c\/div\u003e\n    \u003c\/article\u003e\n\n    \u003csection class=\"aj-pc-gallery\" hidden\u003e\n      \u003ch3\u003eMeet the Peanut Up Close\u003c\/h3\u003e\n      \u003cdiv class=\"aj-pc-photos\"\u003e\n        \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n        \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n        \u003cfigure data-pc-photo hidden\u003e\u003c\/figure\u003e\n      \u003c\/div\u003e\n    \u003c\/section\u003e\n\n    \u003csection class=\"aj-pc-faq\"\u003e\n      \u003ch3\u003eBefore the First Squeeze\u003c\/h3\u003e\n      \u003cdetails\u003e\n        \u003csummary\u003eDoes it make a sound?\u003c\/summary\u003e\n        \u003cp\u003eYes. Squeezing it produces a crunchy, crackling sound, so it’s best for places where a little fidget noise is welcome.\u003c\/p\u003e\n      \u003c\/details\u003e\n      \u003cdetails\u003e\n        \u003csummary\u003eHow do I use it?\u003c\/summary\u003e\n        \u003cp\u003eHold it in your palm, squeeze gently with your fingers, and release. Try either rounded end or the middle.\u003c\/p\u003e\n      \u003c\/details\u003e\n      \u003cdetails\u003e\n        \u003csummary\u003eIs it edible?\u003c\/summary\u003e\n        \u003cp\u003eNo. It’s a peanut-shaped fidget toy. Keep it out of your mouth.\u003c\/p\u003e\n      \u003c\/details\u003e\n    \u003c\/section\u003e\n  \u003c\/div\u003e\n\n  \u003cfooter\u003e\n    \u003ch3\u003eMake Room for a Little Crunch.\u003c\/h3\u003e\n    \u003cp\u003eYour next desk break has a sound effect.\u003c\/p\u003e\n    \u003ca class=\"aj-pc-cta\" href=\"#top\"\u003eGet My Crunchy Peanut ↑\u003c\/a\u003e\n    \u003cbutton type=\"button\" class=\"aj-pc-toggle\" hidden\u003eTurn off screen effects\u003c\/button\u003e\n  \u003c\/footer\u003e\n\u003c\/section\u003e\n\n\u003cscript\u003e\n(() =\u003e {\n  const root = document.getElementById('aj-peanut-crunch');\n  if (!root || root.dataset.pcReady) return;\n\n  const handle = 'crunchy-sound-peanut-squishy-toy';\n  const path = location.pathname.replace(\/\\\/$\/, '');\n  const productPath = '\/products\/' + handle;\n  const preview = Boolean(window.Shopify?.designMode) ||\n    location.pathname === '\/products_preview';\n\n  if (!path.endsWith(productPath) \u0026\u0026 !preview) {\n    root.hidden = true;\n    return;\n  }\n\n  root.dataset.pcReady = 'true';\n\n  const request = new AbortController();\n  const gallery = root.querySelector('.aj-pc-gallery');\n  const slots = [...root.querySelectorAll('[data-pc-photo]')];\n  const motion = matchMedia('(prefers-reduced-motion: reduce)');\n  const demo = root.querySelector('.aj-pc-demo');\n  const toggle = root.querySelector('.aj-pc-toggle');\n  const feedback = root.querySelector('.aj-pc-status');\n\n  const overlay = document.createElement('div');\n  overlay.className = 'aj-pc-overlay';\n  overlay.hidden = true;\n  overlay.setAttribute('aria-hidden', 'true');\n  overlay.innerHTML =\n    '\u003cspan class=\"aj-pc-glow\"\u003e\u003c\/span\u003e' +\n    '\u003cspan class=\"aj-pc-stamp\"\u003eCRUNCH!\u003c\/span\u003e' +\n    '\u003cspan class=\"aj-pc-stamp aj-pc-stamp--right\"\u003ePOP!\u003c\/span\u003e';\n\n  for (let index = 0; index \u003c 18; index += 1) {\n    const chip = document.createElement('i');\n    const left = index \u003c 9;\n    chip.className = 'aj-pc-chip';\n    chip.style.setProperty('--x', left ? '3vw' : '95vw');\n    chip.style.setProperty('--y', (26 + (index % 9) * 5) + 'vh');\n    chip.style.setProperty('--dx', ((left ? 1 : -1) * (8 + (index % 5) * 4)) + 'vw');\n    chip.style.setProperty('--dy', ((index % 9 - 4) * 4) + 'vh');\n    overlay.append(chip);\n  }\n\n  document.body.append(overlay);\n  demo.hidden = false;\n\n  const preference = 'aj-peanut-effects-off';\n  let paused = false;\n  let count = 0;\n  let timer;\n  try { paused = sessionStorage.getItem(preference) === '1'; } catch {}\n\n  function syncEffects() {\n    overlay.hidden = paused || motion.matches || document.hidden;\n    toggle.hidden = motion.matches;\n    toggle.textContent = paused ? 'Bring back the crunch effects' : 'Turn off screen effects';\n    if (overlay.hidden) overlay.classList.remove('aj-pc-pop');\n  }\n\n  demo.querySelector('button').addEventListener('click', () =\u003e {\n    count += 1;\n    feedback.textContent = `Crunch! ${count} ${count === 1 ? 'squeeze' : 'squeezes'}`;\n    if (overlay.hidden) return;\n    clearTimeout(timer);\n    overlay.classList.remove('aj-pc-pop');\n    void overlay.offsetWidth;\n    overlay.classList.add('aj-pc-pop');\n    timer = setTimeout(() =\u003e overlay.classList.remove('aj-pc-pop'), 950);\n  });\n\n  toggle.addEventListener('click', () =\u003e {\n    paused = !paused;\n    try { sessionStorage.setItem(preference, paused ? '1' : '0'); } catch {}\n    syncEffects();\n  });\n\n  root.querySelector('.aj-pc-cta').addEventListener('click', event =\u003e {\n    event.preventDefault();\n    window.scrollTo({ top: 0, behavior: motion.matches ? 'instant' : 'smooth' });\n  });\n\n  function addVideo(sources, poster) {\n    const urls = sources.filter(url =\u003e typeof url === 'string' \u0026\u0026 url);\n    if (!urls.length) return;\n\n    const block = root.querySelector('.aj-pc-video');\n    const video = document.createElement('video');\n    video.controls = true;\n    video.playsInline = true;\n    video.preload = 'none';\n    video.setAttribute('aria-label', 'Crunchy peanut squishy product demonstration');\n    if (poster) video.poster = poster;\n\n    for (const url of urls) {\n      const source = document.createElement('source');\n      source.src = url;\n      video.append(source);\n    }\n\n    block.append(video);\n    block.hidden = false;\n  }\n\n  async function loadMedia() {\n    let product = {};\n    const timeout = setTimeout(() =\u003e request.abort(), 4500);\n\n    try {\n      const prefix = window.Shopify?.routes?.root || '\/';\n      const endpoint = path.endsWith(productPath)\n        ? path + '.js'\n        : prefix.replace(\/\\\/$\/, '') + productPath + '.js';\n      const response = await fetch(endpoint, {\n        signal: request.signal,\n        headers: { Accept: 'application\/json' }\n      });\n      if (response.ok) product = await response.json();\n    } catch {\n      \/\/ Fall back to the storefront's product gallery.\n    } finally {\n      clearTimeout(timeout);\n    }\n\n    if (!root.isConnected) return;\n\n    const themeGallery = document.querySelector(\n      'main media-gallery, main [id^=\"MediaGallery-\"], main .product__media-list'\n    );\n    const themePhotos = themeGallery\n      ? [...themeGallery.querySelectorAll('img')].map(img =\u003e img.currentSrc || img.getAttribute('src'))\n      : [];\n    const storePhotos = Array.isArray(product.images) ? product.images : [];\n    const seen = new Set();\n    const photos = [];\n\n    for (const value of [...storePhotos, ...themePhotos]) {\n      const source = typeof value === 'string' ? value : value?.src;\n      if (!source) continue;\n      let url;\n      try { url = new URL(source, location.origin); } catch { continue; }\n      if (url.protocol !== 'https:') continue;\n\n      const key = url.pathname.split('\/').pop();\n      if (!key || seen.has(key)) continue;\n      seen.add(key);\n      if (\/\\\/cdn\\\/shop\\\/|\\\/s\\\/files\\\/\/.test(url.pathname) \u0026\u0026 !\/\\.gif$\/i.test(url.pathname)) {\n        url.searchParams.set('width', '1100');\n      }\n\n      photos.push({ url: url.href, alt: value?.alt || '' });\n    }\n\n    const media = Array.isArray(product.media) ? product.media : [];\n    const storeVideo = media.find(item =\u003e\n      item?.media_type === 'video' \u0026\u0026 Array.isArray(item.sources) \u0026\u0026 item.sources.length\n    );\n    const themeVideo = themeGallery?.querySelector('video');\n    const storeSources = storeVideo?.sources.map(source =\u003e source.url).filter(Boolean) || [];\n    const themeSources = themeVideo\n      ? [themeVideo.currentSrc || themeVideo.getAttribute('src'),\n          ...[...themeVideo.querySelectorAll('source')].map(source =\u003e source.src)]\n      : [];\n\n    addVideo(\n      storeSources.length ? storeSources : themeSources,\n      storeVideo?.preview_image?.src || themeVideo?.poster || photos[0]?.url\n    );\n\n    let slotIndex = 0;\n    for (const [index, photo] of photos.entries()) {\n      if (slotIndex === slots.length || !root.isConnected) break;\n\n      const image = new Image();\n      image.alt = photo.alt || (index === 0\n        ? 'Crunchy peanut-shaped squishy toy'\n        : 'Crunchy peanut squishy toy, additional product view');\n      image.decoding = 'async';\n\n      const loaded = new Promise(resolve =\u003e {\n        image.addEventListener('load', () =\u003e resolve(true), { once: true });\n        image.addEventListener('error', () =\u003e resolve(false), { once: true });\n      });\n\n      image.src = photo.url;\n      if (!(await loaded) || !root.isConnected) continue;\n\n      const slot = slots[slotIndex++];\n      slot.append(image);\n      slot.hidden = false;\n      slot.parentElement.classList.add('aj-pc-paired');\n      if (gallery.contains(slot)) gallery.hidden = false;\n    }\n  }\n\n  function unload(event) {\n    if (!event.target.contains(root)) return;\n    request.abort();\n    clearTimeout(timer);\n    overlay.remove();\n    motion.removeEventListener('change', syncEffects);\n    document.removeEventListener('visibilitychange', syncEffects);\n    document.removeEventListener('shopify:section:unload', unload);\n  }\n\n  motion.addEventListener('change', syncEffects);\n  document.addEventListener('visibilitychange', syncEffects);\n  document.addEventListener('shopify:section:unload', unload);\n  syncEffects();\n  loadMedia();\n})();\n\u003c\/script\u003e\n\u003cstyle\u003e\n  .aj-pc-overlay,\n  #aj-peanut-crunch .aj-pc-toggle {\n    display: none !important;\n  }\n\n  .aj-shell-crunch {\n    position: fixed;\n    inset: 0;\n    z-index: 12;\n    overflow: hidden;\n    pointer-events: none;\n  }\n\n  .aj-shell-crunch * { pointer-events: none; }\n\n  .aj-shell-glow {\n    position: absolute;\n    inset: 0;\n    opacity: 0;\n    background:\n      radial-gradient(ellipse at left 36%, #ffc46e99, transparent 32%),\n      radial-gradient(ellipse at right 65%, #ffb34e99, transparent 32%);\n  }\n\n  .aj-shell-word {\n    position: absolute;\n    top: 27%;\n    left: max(12px, 4vw);\n    padding: .24em .4em;\n    border: 2px solid #663219;\n    border-radius: .22em;\n    background: #ffd473;\n    box-shadow: 4px 5px #663219;\n    color: #4b2314;\n    font: 900 clamp(22px, 5vw, 66px)\/1 system-ui, sans-serif;\n    opacity: 0;\n    --tilt: -12deg;\n  }\n\n  .aj-shell-word--right {\n    top: auto;\n    bottom: 27%;\n    left: auto;\n    right: max(12px, 4vw);\n    background: #fff0ba;\n    --tilt: 10deg;\n  }\n\n  .aj-shell-chip {\n    position: absolute;\n    left: var(--x);\n    top: var(--y);\n    width: clamp(8px, 1.4vw, 20px);\n    aspect-ratio: .72;\n    border: 1px solid #925023;\n    border-radius: 70% 30% 62% 38%;\n    background: repeating-linear-gradient(45deg, #fbb955 0 4px, #ffd686 4px 7px);\n    opacity: 0;\n  }\n\n  .aj-shell-crunch.is-playing .aj-shell-glow {\n    animation: aj-shell-glow 1.35s ease-out both;\n  }\n\n  .aj-shell-crunch.is-playing .aj-shell-word {\n    animation: aj-shell-word 1.55s ease-out both;\n  }\n\n  .aj-shell-crunch.is-playing .aj-shell-word--right {\n    animation-delay: .14s;\n  }\n\n  .aj-shell-crunch.is-playing .aj-shell-chip {\n    animation: aj-shell-chip 1.2s ease-out var(--delay) both;\n  }\n\n  @keyframes aj-shell-glow {\n    0%, 100% { opacity: 0; }\n    27% { opacity: .9; }\n  }\n\n  @keyframes aj-shell-word {\n    0% { opacity: 0; transform: rotate(var(--tilt)) scale(.55); }\n    20% { opacity: 1; transform: rotate(var(--tilt)) scale(1.1); }\n    37%, 68% { opacity: 1; transform: rotate(var(--tilt)) scale(1); }\n    100% { opacity: 0; transform: translateY(-18px) rotate(var(--tilt)) scale(.94); }\n  }\n\n  @keyframes aj-shell-chip {\n    0% { opacity: 0; transform: scale(.4); }\n    24% { opacity: 1; }\n    100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(210deg) scale(.75); }\n  }\n\n  .aj-shell-toggle {\n    display: block;\n    min-height: 44px;\n    margin: 5px auto 0;\n    padding: 4px 12px;\n    border: 0;\n    background: transparent;\n    color: inherit;\n    font: inherit;\n    font-size: 13px;\n    text-decoration: underline;\n    text-underline-offset: 3px;\n    cursor: pointer;\n  }\n\n  .aj-shell-toggle[hidden] { display: none; }\n\n  @media (prefers-reduced-motion: reduce) {\n    .aj-shell-crunch, .aj-shell-toggle { display: none; }\n  }\n\u003c\/style\u003e\n\n\u003cdiv data-aj-shell-mount\u003e\u003c\/div\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const mount = document.currentScript?.previousElementSibling;\n  if (!mount?.hasAttribute('data-aj-shell-mount')) return;\n  if (!\/\\\/products\\\/crunchy-sound-peanut-squishy-toy\\\/?$\/.test(location.pathname)) return;\n  if (document.getElementById('aj-shell-crunch-overlay')) return;\n\n  const page = document.getElementById('aj-peanut-crunch');\n  const motion = matchMedia('(prefers-reduced-motion: reduce)');\n  const storageKey = 'aj-peanut-effects-off';\n  const overlay = document.createElement('div');\n  overlay.id = 'aj-shell-crunch-overlay';\n  overlay.className = 'aj-shell-crunch';\n  overlay.setAttribute('aria-hidden', 'true');\n  overlay.innerHTML =\n    '\u003cspan class=\"aj-shell-glow\"\u003e\u003c\/span\u003e' +\n    '\u003cspan class=\"aj-shell-word\"\u003eCRUNCH!\u003c\/span\u003e' +\n    '\u003cspan class=\"aj-shell-word aj-shell-word--right\"\u003ePOP!\u003c\/span\u003e';\n\n  for (let i = 0; i \u003c 18; i += 1) {\n    const chip = document.createElement('span');\n    const left = i \u003c 9;\n    const row = i % 9;\n    chip.className = 'aj-shell-chip';\n    chip.style.setProperty('--x', left ? '4vw' : '94vw');\n    chip.style.setProperty('--y', ((left ? 34 : 61) + (row - 4) * 2) + '%');\n    chip.style.setProperty('--dx', ((left ? 1 : -1) * (8 + row * 1.6)) + 'vw');\n    chip.style.setProperty('--dy', ((row - 4) * 4) + 'vh');\n    chip.style.setProperty('--delay', (row % 3) * 55 + 'ms');\n    overlay.append(chip);\n  }\n\n  document.body.append(overlay);\n\n  const toggle = document.createElement('button');\n  toggle.type = 'button';\n  toggle.className = 'aj-shell-toggle';\n  (page?.querySelector('footer') || mount).append(toggle);\n\n  let paused = false;\n  let nextPlay;\n  let finish;\n  try { paused = sessionStorage.getItem(storageKey) === '1'; } catch {}\n\n  function play() {\n    if (paused || motion.matches || document.hidden) return;\n    clearTimeout(nextPlay);\n    clearTimeout(finish);\n    overlay.classList.remove('is-playing');\n    void overlay.offsetWidth;\n    overlay.classList.add('is-playing');\n    finish = setTimeout(() =\u003e overlay.classList.remove('is-playing'), 1750);\n    nextPlay = setTimeout(play, 12000);\n  }\n\n  function sync() {\n    clearTimeout(nextPlay);\n    clearTimeout(finish);\n    overlay.classList.remove('is-playing');\n    toggle.hidden = motion.matches;\n    toggle.textContent = paused ? 'Bring back the crunch' : 'Turn off crunch effects';\n    if (!paused \u0026\u0026 !motion.matches \u0026\u0026 !document.hidden) {\n      nextPlay = setTimeout(play, 1000);\n    }\n  }\n\n  function handleSqueeze(event) {\n    if (event.target.closest('#aj-peanut-crunch .aj-pc-squeeze')) play();\n  }\n\n  function unload(event) {\n    if (!event.target.contains(mount) \u0026\u0026 !(page \u0026\u0026 event.target.contains(page))) return;\n    clearTimeout(nextPlay);\n    clearTimeout(finish);\n    overlay.remove();\n    toggle.remove();\n    document.removeEventListener('click', handleSqueeze);\n    document.removeEventListener('visibilitychange', sync);\n    document.removeEventListener('shopify:section:unload', unload);\n    motion.removeEventListener('change', sync);\n  }\n\n  toggle.addEventListener('click', () =\u003e {\n    paused = !paused;\n    try { sessionStorage.setItem(storageKey, paused ? '1' : '0'); } catch {}\n    sync();\n  });\n\n  document.addEventListener('click', handleSqueeze);\n  document.addEventListener('visibilitychange', sync);\n  document.addEventListener('shopify:section:unload', unload);\n  motion.addEventListener('change', sync);\n  sync();\n})();\n\u003c\/script\u003e","brand":"zhidou","offers":[{"title":"Default Title","offer_id":68306787205357,"sku":"L2C26110901-面粉花生","price":19.99,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0841\/9354\/2381\/files\/98149732978851841.webp?v=1794627604","url":"https:\/\/alasjoy.com\/products\/crunchy-sound-peanut-squishy-toy","provider":"alasjoy","version":"1.0","type":"link"}