{"id":6706,"date":"2026-08-13T18:58:27","date_gmt":"2026-08-13T18:58:27","guid":{"rendered":"https:\/\/lullastudio.com\/?page_id=6706"},"modified":"2026-09-24T20:51:08","modified_gmt":"2026-09-24T20:51:08","slug":"outfitstudio","status":"publish","type":"page","link":"https:\/\/lullastudio.com\/lv\/outfitstudio\/","title":{"rendered":"Outfit Studio"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"6706\" class=\"elementor elementor-6706\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9f38152 e-con-full build-outfit e-flex e-con e-parent\" data-id=\"9f38152\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-4042e5e e-con-full outfit-panel e-flex e-con e-child\" data-id=\"4042e5e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-92cd87d elementor-widget elementor-widget-html\" data-id=\"92cd87d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\n=========================================================\nLULLA \u2014 FINAL SCENE\nPOST \"OUTFIT ADDED\"\n\nOnly adds independent scene layers to .outfit-panel.\nNEVER modifies .outfit-canvas or the canvas engine.\n=========================================================\n-->\n\n<div class=\"lulla-final-scene-root\" aria-hidden=\"true\"><\/div>\n\n<style>\nselector{\n  position:static!important;\n  height:0!important;\n  min-height:0!important;\n  flex:0 0 auto!important;\n  overflow:visible!important;\n}\n\nselector .elementor-widget-container{\n  position:static!important;\n  height:0!important;\n  min-height:0!important;\n  overflow:visible!important;\n}\n\n\n\/* =========================================================\n   PANEL\n========================================================= *\/\n\n.outfit-panel{\n  position:relative!important;\n  z-index:0!important;\n}\n\n\n\/* =========================================================\n   BACKGROUND\n========================================================= *\/\n\n.lulla-scene-bg{\n  position:absolute!important;\n  inset:0!important;\n\n  width:100%!important;\n  height:100%!important;\n\n  background:center\/cover no-repeat;\n\n  opacity:0;\n\n  pointer-events:none;\n\n  z-index:-2!important;\n\n  transition:\n    opacity 1.5s cubic-bezier(.22,.61,.36,1);\n}\n\n\n\/* =========================================================\n   SOFT LIGHT \u2014 STATIC + BEHIND GARMENT\n========================================================= *\/\n\n.lulla-scene-light{\n  position:absolute!important;\n  inset:0!important;\n\n  width:100%!important;\n  height:100%!important;\n\n  background:\n    radial-gradient(\n      ellipse 68% 52% at 72% 8%,\n      rgba(255,244,222,.16),\n      rgba(255,244,222,0) 72%\n    );\n\n  opacity:0;\n\n  pointer-events:none;\n\n  \/* Below the outfit canvas. It can still softly lift\n     transparent\/background areas without whitening\n     the garment itself. *\/\n  z-index:-1!important;\n\n  transform:none!important;\n  animation:none!important;\n\n  transition:\n    opacity 1.5s cubic-bezier(.22,.61,.36,1);\n}\n\n\n\/* =========================================================\n   BOTANICAL SHADOW \u2014 OVER GARMENT\n========================================================= *\/\n\n\n\/* =========================================================\n   BOTANICAL SHADOW TEXTURE\n========================================================= *\/\n\n.lulla-scene-shadow{\n  position:absolute!important;\n\n  left:-5%!important;\n  top:0!important;\n\n  width:105%!important;\n  height:100%!important;\n\n  background:\n    left center\/cover no-repeat;\n\n  pointer-events:none!important;\n\n  opacity:0;\n\n  z-index:199!important;\n\n  mix-blend-mode:multiply;\n\n  filter:none!important;\n\n  transform:translate3d(0,0,0);\n\n  transform-origin:left center;\n\n  will-change:transform;\n\n  transition:\n    opacity 1.5s cubic-bezier(.22,.61,.36,1);\n}\n\n\n\/* =========================================================\n   BOTANICAL SHADOW \u2014 SWAY\n   Kept above the garment for the visible shadow texture.\n========================================================= *\/\n\n.outfit-panel.lulla-scene-active\n.lulla-scene-shadow{\n  opacity:.34;\n\n  animation:\n    lulla-scene-sway\n    12s ease-in-out\n    infinite alternate;\n}\n\n@keyframes lulla-scene-sway{\n\n  0%{\n    transform:translate3d(0,0,0);\n  }\n\n  20%{\n    transform:translate3d(6px,-1px,0);\n  }\n\n  40%{\n    transform:translate3d(-3px,1px,0);\n  }\n\n  60%{\n    transform:translate3d(7px,0,0);\n  }\n\n  80%{\n    transform:translate3d(-4px,-1px,0);\n  }\n\n  100%{\n    transform:translate3d(5px,1px,0);\n  }\n\n}\n\n\n\/* =========================================================\n   GARMENT COLOR GRADE + SHADOW\n========================================================= *\/\n\n\/* The outfit is already visible from the Canvas Engine.\n   Final Scene never hides or fades the garment itself.\n   We only apply the final grade when the scene is activated. *\/\n\n.outfit-panel.lulla-scene-graded\n.lulla-canvas-layer{\n  filter:\n    brightness(1.03)\n    contrast(.94)\n    saturate(.86)\n    sepia(.06)\n    hue-rotate(-4deg)\n    drop-shadow(\n      20px 11px 13px\n      rgba(28,20,12,.34)\n    )\n    drop-shadow(\n      8px 5px 5px\n      rgba(28,20,12,.22)\n    );\n}\n\n.outfit-panel:not(.lulla-scene-graded)\n.lulla-canvas-layer{\n  filter:none;\n}\n\n\n\/* =========================================================\n   CAPTION\n========================================================= *\/\n\n.lulla-scene-caption{\n  position:absolute!important;\n\n  left:50%!important;\n  bottom:5%!important;\n\n  transform:\n    translate3d(-50%,0,0);\n\n  font-family:\n    \"Playfair Display\",\n    Georgia,\n    serif;\n\n  font-style:italic;\n  font-weight:500;\n\n  font-size:\n    clamp(15px,2.2vw,20px);\n\n  color:#2A2620;\n\n  letter-spacing:-.8px;\n\n  white-space:nowrap;\n\n  text-align:center;\n\n  pointer-events:none;\n\n  opacity:0;\n\n  z-index:220!important;\n\n  transition:\n    opacity .35s ease;\n}\n\n.lulla-scene-caption-heart{\n  color:#1D1D1B!important;\n  font-style:normal;\n  margin-left:3px;\n}\n\n\n\/* =========================================================\n   CAPTION TYPEWRITER\n========================================================= *\/\n\n.lulla-scene-caption.is-typing{\n  opacity:1;\n}\n\n.lulla-scene-caption-text,\n.lulla-scene-caption-heart{\n  display:inline;\n}\n\n\n\/* =========================================================\n   ACTIVE SCENE\n========================================================= *\/\n\n.outfit-panel.lulla-scene-active\n.lulla-scene-bg{\n  opacity:1;\n}\n\n.outfit-panel.lulla-scene-active\n.lulla-scene-light{\n  opacity:.10;\n  animation:none!important;\n  transform:none!important;\n}\n\n.outfit-panel.lulla-scene-active\n.lulla-scene-shadow{\n  opacity:.34;\n}\n\n\n\/* =========================================================\n   UI ABOVE EVERYTHING\n========================================================= *\/\n\n.outfit-panel .outfit-header,\n.outfit-panel .outfit-footer{\n  position:relative!important;\n  z-index:210!important;\n}\n\n\n\/* =========================================================\n   REDUCED MOTION\n========================================================= *\/\n\n@media(prefers-reduced-motion:reduce){\n\n  .lulla-scene-shadow,\n  .lulla-scene-light{\n    animation:none!important;\n  }\n\n  .lulla-scene-bg,\n  .lulla-scene-light,\n  .lulla-scene-shadow,\n  .lulla-canvas-layer{\n    transition:none!important;\n  }\n\n  .lulla-scene-caption{\n    transition:none!important;\n  }\n}\n\n\n\/* =========================================================\n   MOBILE\n========================================================= *\/\n\n@media(max-width:767px){\n\n  .lulla-scene-light{\n    mix-blend-mode:normal!important;\n\n    \/* Mobile: static, subtle light stays behind the garment. *\/\n    animation:none!important;\n    transform:none!important;\n    opacity:0!important;\n    z-index:-1!important;\n\n    background:\n      radial-gradient(\n        ellipse 60% 46% at 76% 6%,\n        rgba(255,244,222,.12),\n        rgba(255,244,222,0) 72%\n      );\n  }\n\n  .outfit-panel.lulla-scene-active\n  .lulla-scene-light{\n    opacity:.08!important;\n  }\n\n\n  .lulla-scene-shadow{\n    left:-5%!important;\n    top:0!important;\n\n    width:105%!important;\n    height:100%!important;\n\n    background:\n      left center\/cover no-repeat;\n\n    mix-blend-mode:normal!important;\n\n    filter:none!important;\n\n    z-index:199!important;\n  }\n\n\n  .outfit-panel.lulla-scene-active\n  .lulla-scene-shadow{\n\n    opacity:.24;\n\n    animation:\n      lulla-scene-sway-mobile\n      12s ease-in-out\n      infinite alternate;\n  }\n\n\n  @keyframes lulla-scene-sway-mobile{\n\n    0%{\n      transform:translate3d(0,0,0);\n    }\n\n    25%{\n      transform:translate3d(5px,0,0);\n    }\n\n    50%{\n      transform:translate3d(-3px,1px,0);\n    }\n\n    75%{\n      transform:translate3d(6px,0,0);\n    }\n\n    100%{\n      transform:translate3d(-4px,0,0);\n    }\n\n  }\n\n\n  .outfit-panel.lulla-scene-graded\n  .lulla-canvas-layer{\n\n    \/* Mobile: keep the main garment shadow, remove the second shadow. *\/\n    filter:\n      drop-shadow(\n        20px 11px 13px\n        rgba(28,20,12,.34)\n      )!important;\n  }\n\n\n  .lulla-scene-caption{\n\n    bottom:7%!important;\n\n    font-size:\n      clamp(17px,5vw,21px);\n  }\n\n  .lulla-scene-caption-heart{\n    font-size:.68em!important;\n    display:inline-block!important;\n    transform:translateY(-.02em) scale(.9);\n    transform-origin:center center;\n  }\n}\n\n\n\/* =========================================================\n   CONFIG\n========================================================= *\/\n\n.lulla-final-scene-root{\n  --scene-ready:0;\n}\n<\/style>\n\n\n<script>\n(function(){\n\n  \"use strict\";\n\n\n  \/* =======================================================\n     CONFIG\n  ======================================================= *\/\n\n  var C={\n\n    bg:\n      \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/sunnybg.webp\",\n\n    shadow:\n      \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/shadowsbg.webp\",\n\n    text:\n      \"Made by you\",\n\n    heart:\n      \"\u2661\",\n\n    captionDelay:\n      1100,\n\n    typingSpeed:\n      85\n  };\n\n\n  \/* =======================================================\n     ROOT\n  ======================================================= *\/\n\n  var root=\n    document.querySelector(\n      \".lulla-final-scene-root\"\n    );\n\n  var panel=\n    document.querySelector(\n      \".outfit-panel\"\n    );\n\n  if(!root||!panel){\n    return;\n  }\n\n\n  var built=false;\n\n  var bg;\n  var light;\n  var shadow;\n  var caption;\n\n  var typingTimer=null;\n  var sceneVersion=0;\n\n\n  \/* =======================================================\n     IMAGE PRELOAD\n  ======================================================= *\/\n\n  var imageCache={};\n\n\n  function preloadImage(src){\n\n    if(imageCache[src]){\n      return imageCache[src];\n    }\n\n    imageCache[src]=new Promise(function(resolve,reject){\n\n      var image=\n        new Image();\n\n      image.decoding=\"async\";\n\n      try{\n        image.fetchPriority=\"high\";\n      }catch(error){}\n\n      function finish(){\n        if(typeof image.decode === \"function\"){\n          image.decode()\n            .then(function(){\n              resolve(image);\n            })\n            .catch(function(){\n              resolve(image);\n            });\n        }else{\n          resolve(image);\n        }\n      }\n\n      image.onload=finish;\n\n      image.onerror=function(){\n        delete imageCache[src];\n        reject(\n          new Error(\n            \"Failed to load scene image: \"+src\n          )\n        );\n      };\n\n      image.src=src;\n\n      if(image.complete && image.naturalWidth){\n        finish();\n      }\n\n    });\n\n    return imageCache[src];\n\n  }\n\n\n  \/* =======================================================\n     STOP TYPEWRITER\n  ======================================================= *\/\n\n  function stopTypewriter(){\n\n    if(typingTimer){\n\n      clearTimeout(\n        typingTimer\n      );\n\n      typingTimer=null;\n    }\n\n  }\n\n\n  \/* =======================================================\n     TYPE CAPTION\n  ======================================================= *\/\n\n  function typeCaption(){\n\n    stopTypewriter();\n\n    if(!caption){\n      return;\n    }\n\n\n    caption.innerHTML=\"\";\n\n    caption.classList.add(\n      \"is-typing\"\n    );\n\n\n    var text=C.text;\n\n    var index=0;\n\n\n    function next(){\n\n      if(index<text.length){\n\n        caption.appendChild(\n          document.createTextNode(\n            text.charAt(index)\n          )\n        );\n\n        index++;\n\n        typingTimer=\n          setTimeout(\n            next,\n            C.typingSpeed\n          );\n\n        return;\n      }\n\n\n      \/*\n       * Heart appears after the text finishes.\n       *\/\n\n      var heart=\n        document.createElement(\n          \"span\"\n        );\n\n      heart.className=\n        \"lulla-scene-caption-heart\";\n\n      heart.textContent=\n        \" \"+C.heart;\n\n      caption.appendChild(\n        heart\n      );\n\n\n      typingTimer=null;\n\n    }\n\n\n    next();\n\n  }\n\n\n  \/* =======================================================\n     BUILD\n  ======================================================= *\/\n\n  function build(){\n\n    if(built){\n      return;\n    }\n\n    built=true;\n\n\n    bg=\n      document.createElement(\n        \"div\"\n      );\n\n    bg.className=\n      \"lulla-scene-bg\";\n\n    bg.style.backgroundImage=\n      'url(\"'+C.bg+'\")';\n\n\n    light=\n      document.createElement(\n        \"div\"\n      );\n\n    light.className=\n      \"lulla-scene-light\";\n\n\n    shadow=\n      document.createElement(\n        \"div\"\n      );\n\n    shadow.className=\n      \"lulla-scene-shadow\";\n\n    shadow.style.backgroundImage=\n      'url(\"'+C.shadow+'\")';\n\n\n    caption=\n      document.createElement(\n        \"div\"\n      );\n\n    caption.className=\n      \"lulla-scene-caption\";\n\n\n    \/*\n     * Background behind panel content.\n     *\/\n\n    panel.insertBefore(\n      bg,\n      panel.firstChild\n    );\n\n\n    \/*\n     * Scene effects around outfit:\n     * light sits behind the garment; shadow sits above it.\n     *\/\n\n    panel.appendChild(\n      light\n    );\n\n    panel.appendChild(\n      shadow\n    );\n\n    panel.appendChild(\n      caption\n    );\n\n  }\n\n\n  \/* =======================================================\n     RESET SCENE\n  ======================================================= *\/\n\n  function resetScene(){\n\n    sceneVersion += 1;\n    stopTypewriter();\n\n    panel.classList.remove(\n      \"lulla-scene-active\",\n      \"lulla-scene-graded\"\n    );\n\n    if(caption){\n\n      caption.classList.remove(\n        \"is-typing\"\n      );\n\n      caption.innerHTML=\"\";\n    }\n\n    root.classList.remove(\n      \"is-active\"\n    );\n\n    root.setAttribute(\n      \"aria-hidden\",\n      \"true\"\n    );\n\n  }\n\n\n  \/* =======================================================\n     ACTIVATE\n  ======================================================= *\/\n\n  function activate(){\n\n    build();\n\n\n    if(\n      panel.classList.contains(\n        \"lulla-scene-active\"\n      )\n    ){\n      return;\n    }\n\n\n    var activationVersion=++sceneVersion;\n\n    stopTypewriter();\n\n\n    panel.classList.remove(\n      \"lulla-scene-active\",\n      \"lulla-scene-graded\"\n    );\n\n\n    caption.classList.remove(\n      \"is-typing\"\n    );\n\n    caption.innerHTML=\"\";\n\n\n    root.classList.add(\n      \"is-active\"\n    );\n\n    root.setAttribute(\n      \"aria-hidden\",\n      \"false\"\n    );\n\n\n    \/*\n     * Both scene images load in parallel.\n     *\/\n\n    Promise.all([\n      preloadImage(C.bg),\n      preloadImage(C.shadow)\n    ])\n    .then(function(){\n\n      if(activationVersion !== sceneVersion){\n        return;\n      }\n\n      requestAnimationFrame(function(){\n\n        if(activationVersion !== sceneVersion){\n          return;\n        }\n\n        requestAnimationFrame(function(){\n\n          if(activationVersion !== sceneVersion){\n            return;\n          }\n\n          \/*\n           * The garment is already rendered by the Canvas Engine.\n           * Only the final scene layers fade in now: background, soft light\n           * and botanical shadow. This keeps the outfit stable and prevents\n           * progressive image\/decode rendering from becoming visible.\n           *\/\n          panel.classList.add(\n            \"lulla-scene-graded\"\n          );\n\n          panel.classList.add(\n            \"lulla-scene-active\"\n          );\n\n\n          \/*\n           * Wait until the scene has settled,\n           * then start the typewriter.\n           *\/\n\n          typingTimer=\n            setTimeout(\n              function(){\n                if(activationVersion === sceneVersion){\n                  typeCaption();\n                }\n              },\n              C.captionDelay\n            );\n\n        });\n\n      });\n\n    })\n    .catch(function(){\n\n      if(activationVersion !== sceneVersion){\n        return;\n      }\n\n      panel.classList.remove(\n        \"lulla-scene-active\",\n        \"lulla-scene-graded\"\n      );\n\n      root.classList.remove(\n        \"is-active\"\n      );\n\n      root.setAttribute(\n        \"aria-hidden\",\n        \"true\"\n      );\n\n    });\n\n  }\n\n\n  \/* =======================================================\n     DEACTIVATE\n  ======================================================= *\/\n\n  function deactivate(){\n\n    resetScene();\n\n  }\n\n\n  \/* =======================================================\n     EVENTS\n  ======================================================= *\/\n\n  document.addEventListener(\n    \"lulla:outfit-added\",\n    activate\n  );\n\n  document.addEventListener(\n    \"lulla:added-to-cart\",\n    activate\n  );\n\n  document.addEventListener(\n    \"lulla:outfit-reset\",\n    deactivate\n  );\n\n  document.addEventListener(\n    \"lulla:size-screen-close\",\n    deactivate\n  );\n\n  document.addEventListener(\n    \"lulla:product-change\",\n    deactivate\n  );\n\n\n  if(window.jQuery){\n\n    window.jQuery(document.body).on(\n      \"added_to_cart.lullaFinalScene\",\n      activate\n    );\n\n  }\n\n\n  \/* =======================================================\n     INITIAL STATE\n  ======================================================= *\/\n\n  root.setAttribute(\n    \"aria-hidden\",\n    \"true\"\n  );\n\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b32c0ec e-con-full outfit-header e-flex e-con e-child\" data-id=\"b32c0ec\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-607fba6 elementor-widget elementor-widget-html\" data-id=\"607fba6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"lulla-mm-header\">\r\n  <button type=\"button\" class=\"lulla-mm-back is-header-hidden\" aria-label=\"Back\">\r\n    <svg class=\"lulla-mm-back-arrow\" viewBox=\"0 0 10 16\" aria-hidden=\"true\">\r\n      <path d=\"M8 2L2 8L8 14\"><\/path>\r\n    <\/svg>\r\n    <span class=\"lulla-mm-back-text\">BACK<\/span>\r\n  <\/button>\r\n  <div class=\"lulla-mm-logo-wrap\">\r\n    <span class=\"lulla-mm-logo\" role=\"img\" aria-label=\"LULLA\"><\/span>\r\n  <\/div>\r\n  <span class=\"lulla-mm-spacer\" aria-hidden=\"true\"><\/span>\r\n<\/div>\r\n\r\n<style>\r\n.lulla-mm-header{\r\n  --lulla-header-side:150px;\r\n  --lulla-header-height:44px;\r\n  --lulla-header-logo-w:clamp(56px,13vw,90px);\r\n  position:relative !important;\r\n  top:auto !important;\r\n  right:auto !important;\r\n  left:auto !important;\r\n  width:100% !important;\r\n  height:var(--lulla-header-height) !important;\r\n  min-width:100% !important;\r\n  min-height:var(--lulla-header-height) !important;\r\n  max-height:var(--lulla-header-height) !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  box-sizing:border-box !important;\r\n  display:grid !important;\r\n  grid-template-columns:var(--lulla-header-side) minmax(0,1fr) var(--lulla-header-side) !important;\r\n  align-items:end !important;\r\n  flex:0 0 var(--lulla-header-height) !important;\r\n  align-self:stretch !important;\r\n  background:transparent !important;\r\n  overflow:visible !important;\r\n  z-index:99999999 !important;\r\n  pointer-events:auto !important;\r\n  transition:height .22s ease,flex-basis .22s ease,grid-template-columns .22s ease !important;\r\n}\r\n.lulla-mm-back{\r\n  position:relative !important;\r\n  grid-column:1 !important;\r\n  justify-self:start !important;\r\n  align-self:end !important;\r\n  display:flex !important;\r\n  visibility:hidden !important;\r\n  opacity:0 !important;\r\n  pointer-events:none !important;\r\n  transition:opacity .22s ease, visibility 0s linear .22s !important;\r\n  appearance:none !important;\r\n  -webkit-appearance:none !important;\r\n  width:auto !important;\r\n  height:auto !important;\r\n  min-width:0 !important;\r\n  min-height:0 !important;\r\n  max-width:none !important;\r\n  max-height:none !important;\r\n  margin:0 0 6px 20px !important;\r\n  padding:0 !important;\r\n  box-sizing:border-box !important;\r\n  align-items:center !important;\r\n  justify-content:flex-start !important;\r\n  gap:6px !important;\r\n  border:0 !important;\r\n  border-radius:0 !important;\r\n  outline:none !important;\r\n  box-shadow:none !important;\r\n  background:transparent !important;\r\n  background-color:transparent !important;\r\n  background-image:none !important;\r\n  color:#1D1D1B !important;\r\n  font-family:\"Inter Tight\",Arial,sans-serif !important;\r\n  font-size:12px !important;\r\n  font-weight:400 !important;\r\n  line-height:1 !important;\r\n  letter-spacing:0 !important;\r\n  text-align:left !important;\r\n  text-decoration:none !important;\r\n  cursor:pointer !important;\r\n  user-select:none !important;\r\n  -webkit-user-select:none !important;\r\n  -webkit-tap-highlight-color:transparent !important;\r\n  touch-action:manipulation !important;\r\n  z-index:100000000 !important;\r\n}\r\n.lulla-mm-back.is-header-visible{\r\n  display:flex !important;\r\n  visibility:visible !important;\r\n  opacity:1 !important;\r\n  pointer-events:auto !important;\r\n  transition:opacity .22s ease, visibility 0s !important;\r\n}\r\n.lulla-mm-back.is-header-hidden{\r\n  display:flex !important;\r\n  visibility:hidden !important;\r\n  opacity:0 !important;\r\n  pointer-events:none !important;\r\n  transition:opacity .22s ease, visibility 0s linear .22s !important;\r\n}\r\n.lulla-mm-back-text{\r\n  display:block !important;\r\n  width:auto !important;\r\n  height:auto !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  font-family:\"Inter Tight\",Arial,sans-serif !important;\r\n  font-size:12px !important;\r\n  font-weight:400 !important;\r\n  line-height:1 !important;\r\n  letter-spacing:0 !important;\r\n  color:#1D1D1B !important;\r\n  white-space:nowrap !important;\r\n  pointer-events:none !important;\r\n}\r\n.lulla-mm-back-arrow{\r\n  display:block !important;\r\n  width:9px !important;\r\n  height:12px !important;\r\n  min-width:9px !important;\r\n  max-width:9px !important;\r\n  flex:0 0 9px !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  pointer-events:none !important;\r\n  transition:transform .28s cubic-bezier(.22,.61,.36,1) !important;\r\n}\r\n.lulla-mm-back-arrow path{\r\n  fill:none !important;\r\n  stroke:#1D1D1B !important;\r\n  stroke-width:1.35 !important;\r\n  stroke-linecap:round !important;\r\n  stroke-linejoin:round !important;\r\n}\r\n.lulla-mm-back:hover{opacity:.72 !important;}\r\n.lulla-mm-back:hover .lulla-mm-back-arrow{transform:translateX(-4px) !important;}\r\n.lulla-mm-back:focus,\r\n.lulla-mm-back:focus-visible,\r\n.lulla-mm-back:active{\r\n  border:0 !important;\r\n  outline:none !important;\r\n  box-shadow:none !important;\r\n  background:transparent !important;\r\n  background-color:transparent !important;\r\n  background-image:none !important;\r\n}\r\n.lulla-mm-back:active{opacity:.72 !important;}\r\n.lulla-mm-back::-moz-focus-inner{border:0 !important;padding:0 !important;}\r\n.lulla-mm-logo-wrap{\r\n  grid-column:2 !important;\r\n  justify-self:center !important;\r\n  align-self:end !important;\r\n  width:100% !important;\r\n  min-width:0 !important;\r\n  display:flex !important;\r\n  align-items:flex-end !important;\r\n  justify-content:center !important;\r\n  pointer-events:none !important;\r\n}\r\n.lulla-mm-logo{\r\n  display:block !important;\r\n  width:var(--lulla-header-logo-w) !important;\r\n  min-width:0 !important;\r\n  max-width:var(--lulla-header-logo-w) !important;\r\n  height:22px !important;\r\n  min-height:22px !important;\r\n  flex:0 0 auto !important;\r\n  margin:0 0 2px !important;\r\n  padding:0 !important;\r\n  pointer-events:none !important;\r\n\r\n  background-image:url(\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/03\/LULLA_hor.svg\") !important;\r\n  background-repeat:no-repeat !important;\r\n  background-position:center bottom !important;\r\n  background-size:contain !important;\r\n\r\n  opacity:0 !important;\r\n  visibility:hidden !important;\r\n\r\n  transition:\r\n    opacity .4s cubic-bezier(.22,.61,.36,1),\r\n    visibility 0s linear .4s,\r\n    width .22s ease,\r\n    max-width .22s ease !important;\r\n}\r\n\r\n.lulla-mm-logo.is-ready{\r\n  opacity:1 !important;\r\n  visibility:visible !important;\r\n\r\n  transition:\r\n    opacity .4s cubic-bezier(.22,.61,.36,1),\r\n    visibility 0s linear 0s,\r\n    width .22s ease,\r\n    max-width .22s ease !important;\r\n}\r\n.lulla-mm-spacer{\r\n  grid-column:3 !important;\r\n  display:block !important;\r\n  width:var(--lulla-header-side) !important;\r\n  pointer-events:none !important;\r\n}\r\n@media(max-width:850px) and (max-aspect-ratio:.95){\r\n  .lulla-mm-header{\r\n    --lulla-header-side:105px;\r\n    --lulla-header-height:40px;\r\n    --lulla-header-logo-w:clamp(52px,20vw,78px);\r\n  }\r\n  .lulla-mm-back{margin:0 0 5px 16px !important;font-size:12px !important;}\r\n  .lulla-mm-back-text{font-size:12px !important;}\r\n}\r\n@media(orientation:landscape) and (max-height:500px){\r\n  .lulla-mm-header{\r\n    --lulla-header-side:92px;\r\n    --lulla-header-height:36px;\r\n    --lulla-header-logo-w:clamp(46px,11vw,66px);\r\n  }\r\n  .lulla-mm-back{margin:0 0 5px 14px !important;font-size:11px !important;}\r\n  .lulla-mm-back-text{font-size:11px !important;}\r\n}\r\n@media(orientation:landscape) and (max-height:400px),(orientation:landscape) and (max-width:700px) and (max-height:500px){\r\n  .lulla-mm-header{\r\n    --lulla-header-side:72px;\r\n    --lulla-header-logo-w:clamp(40px,13vw,56px);\r\n  }\r\n  .lulla-mm-back{margin:0 0 5px 12px !important;gap:4px !important;}\r\n}\r\n.lulla-mm-header button{\r\n  -webkit-tap-highlight-color:transparent !important;\r\n  -webkit-touch-callout:none !important;\r\n}\r\n@media(prefers-reduced-motion:reduce){\r\n  .lulla-mm-back,.lulla-mm-back,.lulla-mm-back-arrow,.lulla-mm-header,.lulla-mm-logo{transition:none !important;}\r\n}\r\n<\/style>\r\n\r\n<script>\r\n(function(){\r\n  \"use strict\";\r\n  function initLullaHeader(){\r\n    document.querySelectorAll(\".lulla-mm-header\").forEach(function(header){\r\n      if(header.dataset.lullaHeaderReady===\"true\"){return;}\r\n      header.dataset.lullaHeaderReady=\"true\";\r\n      var backButton=header.querySelector(\".lulla-mm-back\");\r\n      var backText=header.querySelector(\".lulla-mm-back-text\");\r\n      var logo=header.querySelector(\".lulla-mm-logo\");\r\n      if(!backButton||!backText||!logo){return;}\r\n\r\n      \/*\r\n       * The logo is a CSS background, not an Elementor image.\r\n       * Preload the SVG separately, then reveal the already-loaded\r\n       * background with a simple opacity fade.\r\n       *\/\r\n      var logoSrc=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/03\/LULLA_hor.svg\";\r\n\r\n      function revealLogo(){\r\n        logo.classList.add(\"is-ready\");\r\n      }\r\n\r\n      var logoPreloader=new Image();\r\n\r\n      logoPreloader.onload=function(){\r\n        revealLogo();\r\n      };\r\n\r\n      logoPreloader.onerror=function(){\r\n        \/* Keep it hidden if the SVG genuinely fails to load. *\/\r\n        logo.classList.remove(\"is-ready\");\r\n      };\r\n\r\n      logoPreloader.src=logoSrc;\r\n\r\n      var htmlWidget=header.closest(\".elementor-widget-html\");\r\n      var element=header.closest(\".elementor-element\");\r\n      var widgetContainer=header.closest(\".elementor-widget-container\");\r\n      function syncWrapperHeight(){\r\n        var height=window.getComputedStyle(header).height;\r\n        if(!height||height===\"0px\"){return;}\r\n        [htmlWidget,element,widgetContainer].forEach(function(node){\r\n          if(!node){return;}\r\n          node.style.position=\"relative\";\r\n          node.style.top=\"auto\";\r\n          node.style.left=\"auto\";\r\n          node.style.right=\"auto\";\r\n          node.style.width=\"100%\";\r\n          node.style.maxWidth=\"100%\";\r\n          node.style.minWidth=\"100%\";\r\n          node.style.height=height;\r\n          node.style.minHeight=height;\r\n          node.style.boxSizing=\"border-box\";\r\n          node.style.zIndex=\"99999999\";\r\n          node.style.pointerEvents=\"auto\";\r\n          if(node!==widgetContainer){\r\n            node.style.maxHeight=height;\r\n            node.style.flex=\"0 0 \"+height;\r\n            node.style.alignSelf=\"stretch\";\r\n            node.style.paddingTop=\"0\";\r\n            node.style.paddingRight=\"0\";\r\n            node.style.paddingBottom=\"0\";\r\n            node.style.paddingLeft=\"0\";\r\n            node.style.marginTop=\"0\";\r\n            node.style.marginRight=\"0\";\r\n            node.style.marginBottom=\"0\";\r\n            node.style.marginLeft=\"0\";\r\n          }else{\r\n            node.style.overflow=\"visible\";\r\n          }\r\n        });\r\n      }\r\n      var headerButtonVisible=false;\r\n      var headerMode=\"back\";\r\n      var requestedHeaderMode=\"back\";\r\n      var headerTransitionTimer=null;\r\n      var headerTransitioning=false;\r\n      var headerTransitionToken=0;\r\n\r\n      function clearHeaderTransition(){\r\n        if(headerTransitionTimer){\r\n          window.clearTimeout(headerTransitionTimer);\r\n          headerTransitionTimer=null;\r\n        }\r\n        headerTransitioning=false;\r\n        headerTransitionToken++;\r\n      }\r\n\r\n      function hideBackButton(immediate){\r\n        clearHeaderTransition();\r\n        backButton.classList.remove(\"is-header-visible\");\r\n        backButton.classList.add(\"is-header-hidden\");\r\n        backButton.style.display=\"flex\";\r\n        backButton.style.pointerEvents=\"none\";\r\n        backButton.style.visibility=immediate ? \"hidden\" : \"visible\";\r\n        backButton.style.opacity=\"0\";\r\n        headerButtonVisible=false;\r\n      }\r\n\r\n      function showBackButton(){\r\n        backButton.style.display=\"flex\";\r\n        backButton.classList.remove(\"is-header-hidden\");\r\n        backButton.classList.add(\"is-header-visible\");\r\n        backButton.style.visibility=\"visible\";\r\n        backButton.style.opacity=\"1\";\r\n        backButton.style.pointerEvents=\"auto\";\r\n        headerButtonVisible=true;\r\n      }\r\n\r\n      function applyHeaderMode(mode){\r\n        headerMode=mode===\"studio\" ? \"studio\" : \"back\";\r\n        requestedHeaderMode=headerMode;\r\n        if(headerMode===\"studio\"){\r\n          backText.textContent=\"TO STUDIO\";\r\n          backButton.setAttribute(\"aria-label\",\"To Studio\");\r\n        }else{\r\n          backText.textContent=originalText;\r\n          backButton.setAttribute(\"aria-label\",originalLabel);\r\n        }\r\n      }\r\n\r\n      function setHeaderMode(mode,animate){\r\n        var nextMode=mode===\"studio\" ? \"studio\" : \"back\";\r\n        requestedHeaderMode=nextMode;\r\n\r\n        \/*\r\n         * Ignore duplicate state reports while a cross-fade is already\r\n         * running. This is important because State 3 changes several\r\n         * classes in quick succession and the MutationObserver can fire\r\n         * multiple times.\r\n         *\/\r\n        if(headerTransitioning){\r\n          return;\r\n        }\r\n\r\n        if(nextMode===headerMode && headerButtonVisible){\r\n          return;\r\n        }\r\n\r\n        if(!animate){\r\n          clearHeaderTransition();\r\n          applyHeaderMode(nextMode);\r\n          showBackButton();\r\n          return;\r\n        }\r\n\r\n        \/*\r\n         * Current button is visible:\r\n         * 1. fade the existing label out\r\n         * 2. change the label while invisible\r\n         * 3. fade the new label in\r\n         *\/\r\n        if(headerButtonVisible){\r\n          var token=++headerTransitionToken;\r\n          headerTransitioning=true;\r\n\r\n          backButton.classList.remove(\"is-header-visible\");\r\n          backButton.classList.add(\"is-header-hidden\");\r\n          backButton.style.display=\"flex\";\r\n          backButton.style.visibility=\"visible\";\r\n          backButton.style.opacity=\"0\";\r\n          backButton.style.pointerEvents=\"none\";\r\n\r\n          headerTransitionTimer=window.setTimeout(function(){\r\n            if(token!==headerTransitionToken){\r\n              return;\r\n            }\r\n\r\n            headerTransitionTimer=null;\r\n            applyHeaderMode(requestedHeaderMode);\r\n            headerTransitioning=false;\r\n\r\n            backButton.classList.remove(\"is-header-hidden\");\r\n            backButton.classList.add(\"is-header-visible\");\r\n            backButton.style.display=\"flex\";\r\n            backButton.style.visibility=\"visible\";\r\n            backButton.style.opacity=\"1\";\r\n            backButton.style.pointerEvents=\"auto\";\r\n            headerButtonVisible=true;\r\n          },240);\r\n\r\n          return;\r\n        }\r\n\r\n        \/*\r\n         * Already hidden: simply prepare the correct label and fade in.\r\n         *\/\r\n        applyHeaderMode(nextMode);\r\n        showBackButton();\r\n      }\r\n\r\n      var state3Active=false;\r\n      var outfitCompleted=false;\r\n      var originalText=\"BACK\";\r\n      var originalLabel=\"Back\";\r\n\r\n      function isOutfitCompleted(){\r\n        var sizeScreen=document.querySelector(\".lulla-size-screen\");\r\n        return !!(outfitCompleted||(sizeScreen&&sizeScreen.classList.contains(\"is-success\")));\r\n      }\r\n\r\n      function detectState3(){\r\n        var sizeScreen=document.querySelector(\".lulla-size-screen\");\r\n        if(!sizeScreen||isOutfitCompleted()){return false;}\r\n        return sizeScreen.classList.contains(\"is-entering\")||sizeScreen.classList.contains(\"is-visible\");\r\n      }\r\n\r\n      function setState3Header(active,animate){\r\n        state3Active=!!active;\r\n        setHeaderMode(state3Active ? \"studio\" : \"back\",animate!==false);\r\n      }\r\n\r\n      function syncHeader(animate){\r\n        var state1=document.querySelector(\".lulla-state1\");\r\n        var introVisible=!!(state1&&(!state1.classList.contains(\"is-hidden\")||state1.getAttribute(\"aria-hidden\")!==\"true\"));\r\n\r\n        if(isOutfitCompleted()){\r\n          state3Active=false;\r\n          hideBackButton(false);\r\n          return;\r\n        }\r\n\r\n        if(introVisible){\r\n          state3Active=false;\r\n          hideBackButton(false);\r\n          return;\r\n        }\r\n\r\n        if(state3Active||detectState3()){\r\n          state3Active=true;\r\n          setHeaderMode(\"studio\",animate!==false);\r\n          return;\r\n        }\r\n\r\n        state3Active=false;\r\n        setHeaderMode(\"back\",animate!==false);\r\n      }\r\n\r\n      window.addEventListener(\"resize\",function(){\r\n        if(!window.__lullaHeaderResizeFrame){\r\n          window.__lullaHeaderResizeFrame=requestAnimationFrame(function(){\r\n            window.__lullaHeaderResizeFrame=null;\r\n            syncWrapperHeight();\r\n            syncHeader();\r\n          });\r\n        }\r\n      },{passive:true});\r\n      window.addEventListener(\"orientationchange\",function(){\r\n        hideBackButton(false);\r\n        window.setTimeout(function(){syncWrapperHeight();syncHeader(true);},60);\r\n        window.setTimeout(function(){syncWrapperHeight();syncHeader(true);},250);\r\n      },{passive:true});\r\n      backButton.addEventListener(\"click\",function(event){\r\n        event.preventDefault();\r\n        event.stopPropagation();\r\n        if(isOutfitCompleted()){\r\n          hideBackButton(false);\r\n          return;\r\n        }\r\n        if(state3Active){\r\n          state3Active=false;\r\n          hideBackButton(false);\r\n          document.dispatchEvent(new CustomEvent(\"lulla:size-screen-close\",{bubbles:true}));\r\n          return;\r\n        }\r\n        var changeButton=document.querySelector(\".lulla-change-button\");\r\n        if(changeButton){\r\n          changeButton.click();\r\n        }else{\r\n          document.dispatchEvent(new CustomEvent(\"lulla:setup-change\",{bubbles:true,detail:{clearProducts:true}}));\r\n        }\r\n        hideBackButton(false);\r\n      });\r\n      document.addEventListener(\"lulla:state3-mode-change\",function(event){\r\n        var active=!!(event&&event.detail&&event.detail.active);\r\n        if(active){\r\n          setState3Header(true,true);\r\n        }else{\r\n          state3Active=false;\r\n          syncHeader(true);\r\n        }\r\n      });\r\n      document.addEventListener(\"lulla:size-screen-close\",function(){\r\n        state3Active=false;\r\n        syncHeader(true);\r\n      });\r\n      document.addEventListener(\"lulla:outfit-added\",function(){\r\n        outfitCompleted=true;\r\n        state3Active=false;\r\n        hideBackButton(false);\r\n      });\r\n      document.addEventListener(\"lulla:outfit-reset\",function(){\r\n        outfitCompleted=false;\r\n        syncHeader();\r\n      });\r\n      document.addEventListener(\"lulla:setup-change\",function(){\r\n        state3Active=false;\r\n        hideBackButton(false);\r\n      });\r\n      document.addEventListener(\"lulla:setup-back\",function(){\r\n        state3Active=false;\r\n        hideBackButton(false);\r\n      });\r\n      document.addEventListener(\"lulla:gender-change\",function(){\r\n        state3Active=false;\r\n        hideBackButton(false);\r\n        window.setTimeout(function(){syncHeader(true);},20);\r\n        window.setTimeout(function(){syncHeader(true);},150);\r\n        window.setTimeout(function(){syncHeader(true);},350);\r\n      });\r\n      var state1=document.querySelector(\".lulla-state1\");\r\n      if(state1){\r\n        var state1Observer=new MutationObserver(function(){syncHeader();});\r\n        state1Observer.observe(state1,{attributes:true,attributeFilter:[\"class\",\"aria-hidden\"]});\r\n      }\r\n      var sizeScreen=document.querySelector(\".lulla-size-screen\");\r\n      if(sizeScreen){\r\n        var state3Observer=new MutationObserver(function(){\r\n          if(isOutfitCompleted()){\r\n            state3Active=false;\r\n            hideBackButton(false);\r\n            return;\r\n          }\r\n          if(sizeScreen.classList.contains(\"is-visible\")||sizeScreen.classList.contains(\"is-entering\")){\r\n            setState3Header(true);\r\n          }else{\r\n            state3Active=false;\r\n            syncHeader();\r\n          }\r\n        });\r\n        state3Observer.observe(sizeScreen,{attributes:true,attributeFilter:[\"class\",\"aria-hidden\"]});\r\n      }\r\n      hideBackButton(true);\r\n      syncHeader(false);\r\n      syncWrapperHeight();\r\n    });\r\n  }\r\n  if(document.readyState===\"loading\"){\r\n    document.addEventListener(\"DOMContentLoaded\",initLullaHeader,{once:true});\r\n  }else{\r\n    initLullaHeader();\r\n  }\r\n  if(typeof jQuery!==\"undefined\"){\r\n    jQuery(window).on(\"elementor\/frontend\/init\",initLullaHeader);\r\n  }\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-db46a7d e-con-full canvas-area e-flex e-con e-child\" data-id=\"db46a7d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-2fb5db8 e-con-full outfit-canvas e-flex e-con e-child\" data-id=\"2fb5db8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5898262 elementor-widget elementor-widget-html\" data-id=\"5898262\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\n\n\/* =========================================================\n   LULLA \u2014 CANVAS COMPOSITION ENGINE\n   REFERENCE STAGE: 575 \u00d7 745\n   RESPONSIVE WIDTH: 575 \u2192 645 (height always 745)\n   ========================================================= *\/\n\n\n\/* =========================================================\n   RESPONSIVE WRAPPER\n   ========================================================= *\/\n\n.lulla-canvas-wrapper{\n\n    position:relative;\n\n    width:100%;\n    height:100%;\n\n    min-width:0;\n    min-height:0;\n\n    margin:0;\n    padding:0;\n\n    box-sizing:border-box;\n\n    display:flex;\n\n    align-items:center;\n    justify-content:center;\n\n    align-self:stretch;\n\n    flex:1 1 auto;\n\n    overflow:visible;\n\n}\n\n\n\/* =========================================================\n   CANVAS\n   Width is driven by --lulla-canvas-w (set by the Engine,\n   range 575px \u2013 645px). Height is always 745px.\n   ========================================================= *\/\n\n.lulla-canvas-wrapper > .outfit-canvas,\n.outfit-canvas{\n\n    width:var(--lulla-canvas-w, 575px) !important;\n    height:745px !important;\n\n    min-width:var(--lulla-canvas-w, 575px) !important;\n    min-height:745px !important;\n\n    max-width:none !important;\n    max-height:none !important;\n\n    flex:0 0 auto !important;\n\n    position:absolute !important;\n\n    left:50% !important;\n    top:50% !important;\n\n    margin:0 !important;\n\n    box-sizing:border-box !important;\n\n    \/* Default (before the Engine sets the inline transform) *\/\n    transform:translate(-50%, -50%);\n\n    transform-origin:center center !important;\n\n    will-change:transform;\n\n    overflow:visible !important;\n\n}\n\n\n\/* =========================================================\n   VISUAL LAYERS\n   ========================================================= *\/\n\n.outfit-canvas .lulla-canvas-layer{\n\n    position:absolute;\n\n    left:50%;\n    top:50%;\n\n    width:260px;\n    height:260px;\n\n    margin:0;\n    padding:0;\n\n    box-sizing:border-box;\n\n    background-repeat:no-repeat;\n    background-position:center center;\n    background-size:contain;\n\n    background-color:transparent;\n\n    pointer-events:none;\n\n    transform:\n        translate(-50%,-50%);\n\n    transform-origin:center center;\n\n    opacity:0;\n\n    will-change:\n        transform,\n        opacity;\n\n}\n\n\n\/* =========================================================\n   Z-INDEX\n   ========================================================= *\/\n\n.outfit-canvas .lulla-layer-bottom{\n    z-index:10;\n}\n\n.outfit-canvas .lulla-layer-base{\n    z-index:20;\n}\n\n.outfit-canvas .lulla-layer-onepiece{\n    z-index:30;\n}\n\n.outfit-canvas .lulla-layer-jacket{\n    z-index:40;\n}\n\n.outfit-canvas .lulla-layer-accessory{\n    z-index:50;\n}\n\n.outfit-canvas .lulla-layer-hat{\n    z-index:60;\n}\n\n<\/style>\n\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.12.2\/gsap.min.js\"><\/script>\n\n\n<script>\n\n(function(){\n\n    \"use strict\";\n\n\n    \/* =====================================================\n       CONFIG\n       ===================================================== *\/\n\n    const CONFIG = {\n\n        canvas:{\n            width:575,\n            height:745,\n\n            centerX:288,\n            centerY:373\n        },\n\n\n        \/* =================================================\n           RESPONSIVE LAYER (new)\n\n           The reference layouts below are NEVER modified.\n           The canvas may grow from minWidth to maxWidth when\n           its parent has free space. Only the horizontal\n           distance from the centre is multiplied:\n\n             offsetX = (layout.x - centerX) * spreadFactor\n\n           spreadFactor = 1 at minWidth (575px)\n                        = maxXSpread (or slotXSpread[slot])\n                          at maxWidth (645px)\n                        (linear in between)\n\n           Y and scale are never touched.\n\n           maxXSpread: 1.08 \/ 1.10 \/ 1.12 \/ 1.15\n           safeSpace : fallback per-side margin in px; the\n                       CSS variable --lulla-canvas-safe-space\n                       on the Canvas Area overrides it.\n           ================================================= *\/\n\n        responsive:{\n            minWidth:575,\n            maxWidth:645,\n\n            \/*\n             * SMALL SCREENS (height-limited, e.g. phones):\n             * when the Canvas Area is too short for 745px the\n             * canvas is scaled down and free space appears on\n             * the left\/right. In that case the canvas gets\n             * WIDER (in reference px) so it fills that space,\n             * up to constrainedMaxWidth. Clothing size and Y\n             * are still unchanged, only the X spread grows.\n             *\n             * constrainedRampScale: visual scale at (or below)\n             * which the full constrainedMaxWidth is allowed.\n             * Between scale 1 and this value the cap grows\n             * smoothly from maxWidth to constrainedMaxWidth.\n             *\/\n            constrainedMaxWidth:760,\n            constrainedRampScale:0.75,\n\n            safeSpace:24,\n            maxXSpread:1.12,\n\n            \/*\n             * Optional per-slot override of maxXSpread.\n             * Slots that are not listed use maxXSpread.\n             * Items standing exactly on the centre (x = 288)\n             * always stay at offset 0, whatever the value.\n             *\n             * slots: bottom, base (top), onepiece, jacket,\n             *        hat, accessory\n             *\/\n            slotXSpread:{\n                base:1.30,\n                onepiece:1.30,\n                jacket:1.30\n            }\n        },\n\n\n        \/*\n         * Existing reference image box.\n         *\/\n\n        assetBoxSize:1170,\n\n\n        \/*\n         * Upper visual stack:\n         *\n         * TOPS\n         * ONEPIECE \/ DRESSES\n         * OUTWEAR\n         *\/\n\n        upperPriority:[\n            \"base\",\n            \"onepiece\",\n            \"jacket\"\n        ],\n\n\n        \/* =================================================\n           MAIN LAYOUTS\n           ================================================= *\/\n\n        mainLayouts:{\n\n            \"no-bottom:u0\":{\n\n                scale:0,\n\n                bottom:null,\n\n                uppers:[]\n\n            },\n\n\n            \/*\n             * WAS: 1\n             * NOW: 0.5525 (15% smaller)\n             *\/\n\n            \"no-bottom:u1\":{\n\n                scale:0.5525,\n\n                bottom:null,\n\n                uppers:[\n\n                    {\n                        x:288,\n                        y:373\n                    }\n\n                ]\n\n            },\n\n\n            \/*\n             * WAS: 0.80\n             * NOW: 0.52\n             *\/\n\n            \"no-bottom:u2\":{\n\n                scale:0.468,\n\n                bottom:null,\n\n                uppers:[\n\n                    {\n                        x:245,\n                        y:290\n                    },\n\n                    {\n                        x:330,\n                        y:455\n                    }\n\n                ]\n\n            },\n\n\n            \/*\n             * top + jacket + onepiece (the only possible\n             * u3 combo, since there are just 3 upper\n             * slots total).\n             *\n             * Chain from the onepiece overrides below:\n             * onepiece+jacket (0.5718375) -> another\n             * -10% -> 0.51465375. Positions made exactly\n             * symmetric about the canvas center (x:288).\n             *\/\n\n            \"no-bottom:u3\":{\n\n                \/* SET + TOP + OUTWEAR matches the calibrated pants + TOP + OUTWEAR composition scale. *\/\n                scale:0.4184540032,\n\n                bottom:null,\n\n                uppers:[\n\n                    {\n                        x:198,\n                        y:300\n                    },\n\n                    {\n                        x:288,\n                        y:300\n                    },\n\n                    {\n                        x:378,\n                        y:432\n                    }\n\n                ]\n\n            },\n\n\n            \/*\n             * WAS: 1\n             * NOW: 0.49863125 (5% smaller than 0.524875)\n             *\/\n\n            \"bottom:u0\":{\n\n                scale:0.49863125,\n\n                bottom:{\n\n                    x:288,\n                    y:373\n\n                },\n\n                uppers:[]\n\n            },\n\n\n            \/*\n             * WAS: 0.80\n             * NOW: 0.468 (10% smaller than 0.52)\n             *\/\n\n            \"bottom:u1\":{\n\n                scale:0.468,\n\n                bottom:{\n\n                    x:288,\n                    y:510\n\n                },\n\n                uppers:[\n\n                    {\n                        x:288,\n                        y:215\n                    }\n\n                ]\n\n            },\n\n\n            \/*\n             * pants + top + jacket (bottom:u2):\n             * top shifted right\/down, jacket shifted left\/down,\n             * whole composition reduced by 3%\n             * (0.435708 -> 0.42263676)\n             *\/\n\n            \"bottom:u2\":{\n\n                scale:0.42263676,\n\n                bottom:{\n\n                    x:288,\n                    y:510\n\n                },\n\n                uppers:[\n\n                    {\n                        x:236,\n                        y:225\n                    },\n\n                    {\n                        x:340,\n                        y:315\n                    }\n\n                ]\n\n            },\n\n\n            \/*\n             * WAS: 0.64\n             * NOW: 0.416\n             *\/\n\n            \"bottom:u3\":{\n\n                scale:0.4184540032,\n\n                bottom:{\n\n                    x:288,\n                    y:565\n\n                },\n\n                uppers:[\n\n                    {\n                        x:260,\n                        y:310\n                    },\n\n                    {\n                        x:320,\n                        y:360\n                    },\n\n                    {\n                        x:288,\n                        y:265\n                    }\n\n                ]\n\n            }\n\n        },\n\n\n        \/* =================================================\n           ONEPIECE \/ SETS \u2014 COMBO OVERRIDES\n           These only fire when \"onepiece\" is one of the\n           active upper slots, taking priority over the\n           generic u-count layouts above so a plain\n           top+jacket composition is left untouched.\n\n           Chain:\n           onepiece alone:            u1 scale (0.5525) *1.15 = 0.635375\n           onepiece + top OR jacket:  0.635375 *0.90         = 0.5718375\n           top + jacket + onepiece:   handled directly on\n                                       \"no-bottom:u3\" above\n                                       (0.5718375 *0.90 = 0.51465375)\n           ================================================= *\/\n\n        mainLayoutOverrides:{\n\n            \/* SET solo: +10% from the current calibrated solo size. *\/\n            \"no-bottom:onepiece\":{\n\n                scale:0.65819325,\n\n                bottom:null,\n\n                uppers:[\n                    {\n                        x:288,\n                        y:373\n                    }\n                ]\n\n            },\n\n            \/* SET + TOP:\n             * SET follows the same proportional reduction as pants when\n             * pants gain TOP: 0.49863125 -> 0.468.\n             * TOP keeps the established pants+TOP scale: 0.468.\n             * SET moves right\/down; TOP moves left\/up.\n             *\/\n            \"no-bottom:base+onepiece\":{\n\n                scale:0.468,\n\n                bottom:null,\n\n                uppers:[\n                    {\n                        x:220,\n                        y:290,\n                        scale:0.468\n                    },\n                    {\n                        x:315,\n                        y:400,\n                        scale:0.61776\n                    }\n                ]\n\n            },\n\n            \/* SET + OUTWEAR:\n             * Same proportional reduction for SET.\n             * OUTWEAR keeps the established pants+OUTWEAR scale: 0.468.\n             * SET moves left\/up; OUTWEAR moves right\/down.\n             *\/\n            \"no-bottom:onepiece+jacket\":{\n\n                scale:0.468,\n\n                bottom:null,\n\n                uppers:[\n                    {\n                        x:250,\n                        y:345,\n                        scale:0.61776\n                    },\n                    {\n                        x:350,\n                        y:410,\n                        scale:0.468\n                    }\n                ]\n\n            },\n\n            \/* SET + TOP + OUTWEAR:\n             * WHITE TOP stays upper-left and moves upward for visibility.\n             * GREEN SET stays centered, becomes 5% larger, and moves lower.\n             * BEIGE OUTWEAR moves lower to create more vertical separation.\n             * X positions remain unchanged.\n             *\/\n            \"no-bottom:base+onepiece+jacket\":{\n\n                scale:0.4184540032,\n\n                bottom:null,\n\n                uppers:[\n                    {\n                        x:220,\n                        y:190,\n                        scale:0.4184540032\n                    },\n                    {\n                        x:288,\n                        y:400,\n                        scale:0.58577454936\n                    },\n                    {\n                        x:350,\n                        y:430,\n                        scale:0.4184540032\n                    }\n                ]\n\n            }\n\n        },\n\n\n        \/* =================================================\n           HAT \/ ACCESSORY\n           ================================================= *\/\n\n        headLayouts:{\n\n            \/* HEADWEAR ONLY \u2014 no canvas or clothing layout changes. *\/\n\n            \"no-bottom:u0\":{\n                hat:{ x:288, y:373, scale:0.3740625, rotation:0 },\n                accessory:{ x:288, y:373, scale:0.39375, rotation:0 }\n            },\n\n            \"no-bottom:u0:pair\":{\n                hat:{ x:330, y:300, scale:0.354375, rotation:25 },\n                accessory:{ x:235, y:450, scale:0.354375, rotation:-18 }\n            },\n\n            \/* 1 clothing item: hat reduced by 5% and lowered. *\/\n            \"no-bottom:u1\":{\n                hat:{ x:445, y:155, scale:0.2726915625, rotation:25 },\n                accessory:{ x:145, y:590, scale:0.28704375, rotation:-18 }\n            },\n\n            \/* 2 clothing items: hat reduced by another 5% and lowered. *\/\n            \"no-bottom:u2\":{\n                hat:{ x:430, y:150, scale:0.259057984375, rotation:25 },\n                accessory:{ x:145, y:590, scale:0.2726915625, rotation:-18 }\n            },\n\n            \/* 3 clothing items: hat reduced further; accessory stays balanced. *\/\n            \"no-bottom:u3\":{\n                hat:{ x:435, y:125, scale:0.2331512859375, rotation:25 },\n                accessory:{ x:135, y:600, scale:0.259057984375, rotation:-18 }\n            },\n\n            \/* Pants + headwear = 1 clothing item: same calibrated hat size\/height as a solo clothing item. *\/\n            \"bottom:u0\":{\n                hat:{ x:445, y:155, scale:0.2726915625, rotation:25 },\n                accessory:{ x:145, y:590, scale:0.28704375, rotation:-18 }\n            },\n\n            \/* Pants + one more clothing item = 2 clothing items: slightly smaller and lower. *\/\n            \"bottom:u1\":{\n                hat:{ x:430, y:145, scale:0.259057984375, rotation:25 },\n                accessory:{ x:145, y:590, scale:0.2726915625, rotation:-18 }\n            },\n\n            \/* Pants + two more clothing items = 3 clothing items: slightly smaller and lower. *\/\n            \"bottom:u2\":{\n                hat:{ x:435, y:145, scale:0.221493721640625, rotation:25 },\n                accessory:{ x:135, y:600, scale:0.259057984375, rotation:-18 }\n            },\n\n            \/* Pants + three more clothing items = 4 clothing items. *\/\n            \"bottom:u3\":{\n                hat:{ x:440, y:120, scale:0.221493721640625, rotation:25 },\n                accessory:{ x:130, y:600, scale:0.24610508515625, rotation:-18 }\n            }\n        },\n\n\n        \/* =================================================\n           BACKEND \u2192 CANVAS CATEGORY MAP\n           ================================================= *\/\n\n        categoryMap:{\n\n            \"tops\":\n                \"base\",\n\n            \"bottoms\":\n                \"bottom\",\n\n            \"onepiece-sets\":\n                \"onepiece\",\n\n            \"dresses\":\n                \"onepiece\",\n\n            \"outwear\":\n                \"jacket\",\n\n            \"hats\":\n                \"hat\",\n\n            \"accessories\":\n                \"accessory\"\n\n        },\n\n\n        \/* =================================================\n           LEGACY ALIASES\n           ================================================= *\/\n\n        legacyCategoryMap:{\n\n            \"base\":\n                \"base\",\n\n            \"base-top\":\n                \"base\",\n\n            \"base-tops\":\n                \"base\",\n\n            \"bottom\":\n                \"bottom\",\n\n            \"hat\":\n                \"hat\",\n\n            \"hats\":\n                \"hat\",\n\n            \"jacket\":\n                \"jacket\",\n\n            \"jackets\":\n                \"jacket\",\n\n            \"accessory\":\n                \"accessory\",\n\n            \"accessories\":\n                \"accessory\"\n\n        },\n\n\n        \/* =================================================\n           EXISTING APPROVED ANIMATION SYSTEM\n           ================================================= *\/\n\n        animation:{\n\n            moveDuration:0.85,\n\n            moveEase:\"back.out(1.15)\",\n\n\n            \/* ENTER *\/\n\n            enterStartScale:0.72,\n\n            enterOvershoot:1.025,\n\n            enterDuration:0.55,\n\n            settleDuration:0.28,\n\n            enterRotationOffset:-4,\n\n            enterEase:\"power2.out\",\n\n            settleEase:\"power2.out\",\n\n\n            \/* EXIT *\/\n\n            exitImpulse:0.02,\n\n            exitScale:0.25,\n\n            exitImpulseDuration:0.10,\n\n            exitDuration:0.30,\n\n            exitEase:\"power3.in\"\n\n        }\n\n    };\n\n\n    \/* =========================================================\n       SHARED FULL IMAGE PRELOADER\n       State 2 normally creates this first. Canvas initializes the\n       same shared instance if it loads earlier.\n       ========================================================= *\/\n    function ensureLullaImagePreloader(){\n        if(\n            window.LullaImagePreloader &&\n            typeof window.LullaImagePreloader.preload === \"function\"\n        ){\n            return window.LullaImagePreloader;\n        }\n\n        const records =\n            new Map();\n\n        const queue =\n            [];\n\n        let active =\n            0;\n\n        const MAX_ENTRIES =\n            64;\n\n        const MAX_CONCURRENT =\n            3;\n\n        function trim(){\n            if(\n                records.size <=\n                MAX_ENTRIES\n            ){\n                return;\n            }\n\n            for(\n                const entry of\n                records\n            ){\n                if(\n                    records.size <=\n                    MAX_ENTRIES\n                ){\n                    break;\n                }\n\n                if(\n                    entry[1].status ===\n                    \"ready\"\n                ){\n                    records.delete(\n                        entry[0]\n                    );\n                }\n            }\n        }\n\n        function preload(\n            url,\n            priority\n        ){\n            const src =\n                String(\n                    url ||\n                    \"\"\n                ).trim();\n\n            if(\n                !src\n            ){\n                return Promise.resolve(\n                    false\n                );\n            }\n\n            const requestedPriority =\n                priority ===\n                    \"high\"\n                    ? \"high\"\n                    : \"low\";\n\n            const existing =\n                records.get(\n                    src\n                );\n\n            if(\n                existing\n            ){\n                if(\n                    existing.status ===\n                    \"loading\" &&\n                    requestedPriority ===\n                    \"high\"\n                ){\n                    try{\n                        existing.image.fetchPriority =\n                            \"high\";\n                    }catch(\n                        error\n                    ){}\n                }\n\n                if(\n                    existing.status ===\n                    \"ready\"\n                ){\n                    records.delete(\n                        src\n                    );\n                    records.set(\n                        src,\n                        existing\n                    );\n                }\n\n                return existing.promise;\n            }\n\n            let resolvePromise;\n\n            const promise =\n                new Promise(\n                    function(resolve){\n                        resolvePromise =\n                            resolve;\n                    }\n                );\n\n            const image =\n                new Image();\n\n            const record = {\n                status:\n                    \"loading\",\n                image:\n                    image,\n                promise:\n                    promise\n            };\n\n            records.set(\n                src,\n                record\n            );\n\n            image.decoding =\n                \"async\";\n\n            try{\n                image.fetchPriority =\n                    requestedPriority;\n            }catch(\n                error\n            ){}\n\n            function finish(\n                ok\n            ){\n                if(\n                    record.status !==\n                    \"loading\"\n                ){\n                    return;\n                }\n\n                record.status =\n                    ok\n                        ? \"ready\"\n                        : \"error\";\n\n                if(\n                    ok\n                ){\n                    trim();\n                }else{\n                    records.delete(\n                        src\n                    );\n                }\n\n                resolvePromise(\n                    !!ok\n                );\n            }\n\n            image.onload =\n                function(){\n                    finish(\n                        true\n                    );\n                };\n\n            image.onerror =\n                function(){\n                    finish(\n                        false\n                    );\n                };\n\n            image.src =\n                src;\n\n            if(\n                image.complete\n            ){\n                setTimeout(\n                    function(){\n                        finish(\n                            image.naturalWidth >\n                            0\n                        );\n                    },\n                    0\n                );\n            }\n\n            return promise;\n        }\n\n        function enqueue(\n            urls\n        ){\n            if(\n                !Array.isArray(\n                    urls\n                )\n            ){\n                return;\n            }\n\n            urls.forEach(\n                function(url){\n                    const src =\n                        String(\n                            url ||\n                            \"\"\n                        ).trim();\n\n                    if(\n                        !src ||\n                        records.has(\n                            src\n                        ) ||\n                        queue.includes(\n                            src\n                        )\n                    ){\n                        return;\n                    }\n\n                    queue.push(\n                        src\n                    );\n                }\n            );\n\n            pump();\n        }\n\n        function pump(){\n            while(\n                active <\n                MAX_CONCURRENT &&\n                queue.length\n            ){\n                const src =\n                    queue.shift();\n\n                if(\n                    records.has(\n                        src\n                    )\n                ){\n                    continue;\n                }\n\n                active +=\n                    1;\n\n                preload(\n                    src,\n                    \"low\"\n                ).then(\n                    function(){\n                        active -=\n                            1;\n                        pump();\n                    }\n                );\n            }\n        }\n\n        function clearQueue(){\n            queue.length =\n                0;\n        }\n\n        window.LullaImagePreloader = {\n            preload:\n                preload,\n            ready:\n                function(url){\n                    return preload(\n                        url,\n                        \"high\"\n                    );\n                },\n            enqueue:\n                enqueue,\n            clearQueue:\n                clearQueue\n        };\n\n        return window.LullaImagePreloader;\n    }\n\n    ensureLullaImagePreloader();\n\n    const imagePreloader =\n        ensureLullaImagePreloader();\n\n\n    \/* =====================================================\n       STATE\n       ===================================================== *\/\n\n    const state = {\n\n        bottom:null,\n\n        base:null,\n\n        onepiece:null,\n\n        hat:null,\n\n        jacket:null,\n\n        accessory:null,\n\n        previousLayout:null,\n\n        previousItems:{\n\n            bottom:null,\n\n            base:null,\n\n            onepiece:null,\n\n            jacket:null,\n\n            hat:null,\n\n            accessory:null\n\n        }\n\n    };\n\n\n    \/*\n     * RESPONSIVE VIEW (new)\n     *\n     * width  \u2014 current canvas width in px (575 \u2026 645)\n     * progress \u2014 0 \u2026 1, how far the canvas is between\n     *            minWidth and maxWidth (drives the X spread)\n     * scale  \u2014 current visual scale (only < 1 when the\n     *          Canvas Area is too small for 575 \u00d7 745)\n     *\/\n\n    const view = {\n\n        width:CONFIG.responsive.minWidth,\n\n        progress:0,\n\n        scale:1\n\n    };\n\n\n    let layers = null;\n\n    const transitionVersions = {\n        bottom:0,\n        base:0,\n        onepiece:0,\n        jacket:0,\n        hat:0,\n        accessory:0\n    };\n\n    function beginTransition(\n        slot\n    ){\n        transitionVersions[slot] =\n            (transitionVersions[slot] || 0) +\n            1;\n\n        return transitionVersions[slot];\n    }\n\n    function isCurrentTransition(\n        slot,\n        version\n    ){\n        return (\n            transitionVersions[slot] ===\n            version\n        );\n    }\n\n\n    \/* =====================================================\n       CANVAS\n       ===================================================== *\/\n\n    function getCanvas(){\n\n        return document.querySelector(\n            \".outfit-canvas\"\n        );\n\n    }\n\n\n    function getWrapper(){\n\n        const canvas =\n            getCanvas();\n\n\n        if(!canvas){\n\n            return null;\n\n        }\n\n\n        return canvas.closest(\n            \".lulla-canvas-wrapper\"\n        );\n\n    }\n\n\n    function ensureResponsiveWrapper(){\n\n        const canvas =\n            getCanvas();\n\n\n        if(!canvas){\n\n            return null;\n\n        }\n\n\n        let wrapper =\n            getWrapper();\n\n\n        if(wrapper){\n\n            return wrapper;\n\n        }\n\n\n        wrapper =\n            document.createElement(\n                \"div\"\n            );\n\n\n        wrapper.className =\n            \"lulla-canvas-wrapper\";\n\n\n        canvas.parentNode.insertBefore(\n            wrapper,\n            canvas\n        );\n\n\n        wrapper.appendChild(\n            canvas\n        );\n\n\n        return wrapper;\n\n    }\n\n\n    \/* =====================================================\n       RESPONSIVE LAYER (new)\n       ===================================================== *\/\n\n    \/*\n     * Per-side safe space in px.\n     * Source of truth: CSS variable --lulla-canvas-safe-space\n     * on the Canvas Area (inherited by the wrapper).\n     * Fallback: CONFIG.responsive.safeSpace.\n     *\/\n\n    function getSafeSpace(){\n\n        const wrapper =\n            getWrapper();\n\n\n        let value =\n            NaN;\n\n\n        if(wrapper){\n\n            value =\n                parseFloat(\n\n                    window\n                        .getComputedStyle(\n                            wrapper\n                        )\n                        .getPropertyValue(\n                            \"--lulla-canvas-safe-space\"\n                        )\n\n                );\n\n        }\n\n\n        if(\n            !isFinite(\n                value\n            )\n        ){\n\n            value =\n                CONFIG.responsive.safeSpace;\n\n        }\n\n\n        return Math.max(\n            0,\n            value\n        );\n\n    }\n\n\n    \/*\n     * progress = (W - min) \/ (maxWidth - min)\n     *   0 at 575px, 1 at 645px, > 1 only on height-limited\n     *   screens where the canvas may be wider than 645.\n     *\/\n\n    function computeProgress(\n        canvasWidth\n    ){\n\n        const R =\n            CONFIG.responsive;\n\n\n        const range =\n            R.maxWidth -\n            R.minWidth;\n\n\n        return (\n\n            range > 0\n\n                ? Math.max(\n                    0,\n                    (\n                        canvasWidth -\n                        R.minWidth\n                    ) \/\n                    range\n                )\n\n                : 0\n\n        );\n\n    }\n\n\n    \/*\n     * spread(slot) = 1 + (maxSpread(slot) - 1) * progress\n     *\/\n\n    function getSpread(\n        slot\n    ){\n\n        const R =\n            CONFIG.responsive;\n\n\n        const max =\n            (\n                R.slotXSpread &&\n                R.slotXSpread[\n                    slot\n                ]\n            )\n            ||\n            R.maxXSpread;\n\n\n        return (\n            1 +\n            (\n                max -\n                1\n            ) *\n            view.progress\n        );\n\n    }\n\n\n    \/*\n     * Re-applies ONLY the X offset of layers that are\n     * currently part of the composition. No enter\/exit,\n     * no scale, no Y, no opacity.\n     *\n     * state.previousLayout holds the current composition\n     * in REFERENCE coordinates (the layout objects are\n     * never modified).\n     *\/\n\n    function repositionLayers(){\n\n        if(\n            !layers ||\n            !state.previousLayout\n        ){\n\n            return;\n\n        }\n\n\n        Object.keys(\n            state.previousLayout\n        )\n        .forEach(\n            function(slot){\n\n                const element =\n                    layers[slot];\n\n\n                const target =\n                    state.previousLayout[\n                        slot\n                    ];\n\n\n                if(\n                    !element ||\n                    !target\n                ){\n\n                    return;\n\n                }\n\n\n                gsap.to(\n                    element,\n                    {\n\n                        x:\n                            toCanvasOffset(target.x, target.y, element.dataset.slot).x,\n\n                        duration:0,\n\n                        overwrite:\n                            \"auto\"\n\n                    }\n                );\n\n            }\n        );\n\n    }\n\n\n    function updateCanvasScale(\n        width,\n        height\n    ){\n\n        const canvas =\n            getCanvas();\n\n\n        if(\n            !canvas ||\n            !width ||\n            !height\n        ){\n\n            return;\n\n        }\n\n\n        const R =\n            CONFIG.responsive;\n\n\n        const safeSpace =\n            getSafeSpace();\n\n\n        const availableWidth =\n            Math.max(\n                width -\n                safeSpace *\n                2,\n                1\n            );\n\n\n        \/*\n         * 1. Height-limited scale (1 when there is enough height).\n         *\/\n\n        const heightScale =\n            Math.min(\n                height \/\n                CONFIG.canvas.height,\n                1\n            );\n\n\n        \/*\n         * 2. Canvas WIDTH (reference px).\n         *\n         *    fillWidth = the width that exactly fills the\n         *    available space at the current height scale.\n         *    On normal screens heightScale = 1, so this is just\n         *    the available width, capped at maxWidth (645).\n         *    On height-limited screens (phones) the cap grows\n         *    smoothly up to constrainedMaxWidth, so the free\n         *    left\/right space is used by the X spread.\n         *\/\n\n        const fillWidth =\n            availableWidth \/\n            heightScale;\n\n\n        const ramp =\n            Math.min(\n                1,\n                Math.max(\n                    0,\n                    (\n                        1 -\n                        heightScale\n                    ) \/\n                    (\n                        1 -\n                        R.constrainedRampScale\n                    )\n                )\n            );\n\n\n        const widthCap =\n            R.maxWidth +\n            (\n                R.constrainedMaxWidth -\n                R.maxWidth\n            ) *\n            ramp;\n\n\n        const canvasWidth =\n            Math.round(\n\n                Math.min(\n                    widthCap,\n                    Math.max(\n                        R.minWidth,\n                        fillWidth\n                    )\n                )\n\n            );\n\n\n        \/*\n         * 3. Visual SCALE (existing behaviour)\n         *    Shrinks only when the Canvas Area cannot fit the\n         *    canvas by width or by height.\n         *\/\n\n        const scale =\n            Math.min(\n\n                width \/\n                canvasWidth,\n\n                heightScale,\n\n                1\n\n            );\n\n\n        const widthChanged =\n            canvasWidth !==\n            view.width;\n\n\n        view.width =\n            canvasWidth;\n\n\n        view.scale =\n            scale;\n\n\n        canvas.style.setProperty(\n            \"--lulla-canvas-w\",\n            canvasWidth +\n            \"px\"\n        );\n\n\n        canvas.style.transform =\n            \"translate(-50%, -50%) scale(\" +\n            scale +\n            \")\";\n\n\n        \/*\n         * 4. X SPREAD \u2014 reflow the current outfit\n         *    (no enter\/exit animation).\n         *\/\n\n        if(\n            widthChanged\n        ){\n\n            view.progress =\n                computeProgress(\n                    canvasWidth\n                );\n\n            repositionLayers();\n\n        }\n\n    }\n\n\n    function setupCanvasObserver(){\n\n        const wrapper =\n            ensureResponsiveWrapper();\n\n\n        if(!wrapper){\n\n            return null;\n\n        }\n\n\n        if(\n            window.__LULLA_CANVAS_RESIZE_OBSERVER\n        ){\n\n            window\n                .__LULLA_CANVAS_RESIZE_OBSERVER\n                .disconnect();\n\n        }\n\n\n        const observer =\n            new ResizeObserver(\n                function(entries){\n\n                    entries.forEach(\n                        function(entry){\n\n                            requestAnimationFrame(\n                                function(){\n\n                                    updateCanvasScale(\n                                        entry.contentRect.width,\n                                        entry.contentRect.height\n                                    );\n\n                                }\n                            );\n\n                        }\n                    );\n\n                }\n            );\n\n\n        observer.observe(\n            wrapper\n        );\n\n\n        window.__LULLA_CANVAS_RESIZE_OBSERVER =\n            observer;\n\n\n        requestAnimationFrame(\n            function(){\n\n                const rect =\n                    wrapper.getBoundingClientRect();\n\n\n                updateCanvasScale(\n                    rect.width,\n                    rect.height\n                );\n\n            }\n        );\n\n\n        return wrapper;\n\n    }\n\n\n    \/* =====================================================\n       LAYERS\n       ===================================================== *\/\n\n    function ensureLayers(){\n\n        const canvas =\n            getCanvas();\n\n\n        if(!canvas){\n\n            return null;\n\n        }\n\n\n        const definitions = [\n\n            [\n                \"bottom\",\n                \"lulla-layer-bottom\"\n            ],\n\n            [\n                \"base\",\n                \"lulla-layer-base\"\n            ],\n\n            [\n                \"onepiece\",\n                \"lulla-layer-onepiece\"\n            ],\n\n            [\n                \"hat\",\n                \"lulla-layer-hat\"\n            ],\n\n            [\n                \"jacket\",\n                \"lulla-layer-jacket\"\n            ],\n\n            [\n                \"accessory\",\n                \"lulla-layer-accessory\"\n            ]\n\n        ];\n\n\n        const result =\n            {};\n\n\n        definitions.forEach(\n            function(def){\n\n                const slot =\n                    def[0];\n\n\n                const className =\n                    def[1];\n\n\n                let element =\n                    canvas.querySelector(\n                        \".\" +\n                        className\n                    );\n\n\n                if(!element){\n\n                    element =\n                        document.createElement(\n                            \"div\"\n                        );\n\n\n                    element.className =\n                        \"lulla-canvas-layer \" +\n                        className;\n\n\n                    element.dataset.slot =\n                        slot;\n\n\n                    element.setAttribute(\n                        \"aria-hidden\",\n                        \"true\"\n                    );\n\n\n                    canvas.appendChild(\n                        element\n                    );\n\n                }\n\n\n                result[slot] =\n                    element;\n\n            }\n        );\n\n\n        const oldLayer =\n            canvas.querySelector(\n                \".lulla-layer-layer\"\n            );\n\n\n        if(oldLayer){\n\n            gsap.killTweensOf(\n                oldLayer\n            );\n\n\n            oldLayer.remove();\n\n        }\n\n\n        layers =\n            result;\n\n\n        return result;\n\n    }\n\n\n    \/* =====================================================\n       STATE \/ LAYOUT\n       ===================================================== *\/\n\n    function getUpperSlots(){\n\n        return CONFIG.upperPriority.filter(\n            function(slot){\n\n                return !!state[slot];\n\n            }\n        );\n\n    }\n\n\n    function getUpperCount(){\n\n        return getUpperSlots().length;\n\n    }\n\n\n    function getMainStateKey(){\n\n        return (\n\n            state.bottom\n                ? \"bottom\"\n                : \"no-bottom\"\n\n        )\n        +\n        \":u\"\n        +\n        getUpperCount();\n\n    }\n\n\n    function resolveMainLayout(){\n\n        const uppers =\n            getUpperSlots();\n\n\n        \/*\n         * Combo-specific override key, e.g.\n         * \"no-bottom:onepiece\", \"no-bottom:base+onepiece\",\n         * \"no-bottom:onepiece+jacket\". Only combos that\n         * include \"onepiece\" have entries in\n         * mainLayoutOverrides, so a plain top+jacket (or\n         * top-alone \/ jacket-alone) composition always\n         * falls through to the existing numeric u-count\n         * config untouched.\n         *\/\n\n        const comboKey =\n            (\n\n                state.bottom\n                    ? \"bottom\"\n                    : \"no-bottom\"\n\n            )\n            +\n            \":\"\n            +\n            uppers.join(\n                \"+\"\n            );\n\n\n        const config =\n            CONFIG.mainLayoutOverrides[\n                comboKey\n            ]\n            ||\n            CONFIG.mainLayouts[\n                getMainStateKey()\n            ]\n            ||\n            CONFIG.mainLayouts[\n                \"no-bottom:u0\"\n            ];\n\n\n        const result =\n            {};\n\n\n        if(\n            config.bottom\n        ){\n\n            result.bottom = {\n\n                x:\n                    config.bottom.x,\n\n                y:\n                    config.bottom.y,\n\n                scale:\n                    config.scale,\n\n                rotation:0,\n\n                opacity:1\n\n            };\n\n        }\n\n\n        uppers.forEach(\n            function(\n                slot,\n                index\n            ){\n\n                const position =\n                    config.uppers[\n                        index\n                    ];\n\n\n                if(!position){\n\n                    return;\n\n                }\n\n\n                result[slot] = {\n\n                    x:\n                        position.x,\n\n                    y:\n                        position.y,\n\n                    scale:\n                        position.scale ?? config.scale,\n\n                    rotation:0,\n\n                    opacity:1\n\n                };\n\n            }\n        );\n\n\n        return result;\n\n    }\n\n\n    function resolveHeadLayout(){\n\n        const mainKey =\n            getMainStateKey();\n\n\n        const key =\n            (\n                mainKey ===\n                    \"no-bottom:u0\"\n\n                &&\n                state.hat\n\n                &&\n                state.accessory\n\n            )\n            ?\n                \"no-bottom:u0:pair\"\n            :\n                mainKey;\n\n\n        const config =\n            CONFIG.headLayouts[\n                key\n            ]\n            ||\n            {};\n\n\n        const result =\n            {};\n\n\n        if(\n            state.hat &&\n            config.hat\n        ){\n\n            result.hat = {\n\n                x:\n                    config.hat.x,\n\n                y:\n                    config.hat.y,\n\n                scale:\n                    config.hat.scale,\n\n                rotation:\n                    config.hat.rotation,\n\n                opacity:1\n\n            };\n\n        }\n\n\n        if(\n            state.accessory &&\n            config.accessory\n        ){\n\n            result.accessory = {\n\n                x:\n                    config.accessory.x,\n\n                y:\n                    config.accessory.y,\n\n                scale:\n                    config.accessory.scale,\n\n                rotation:\n                    config.accessory.rotation,\n\n                opacity:1\n\n            };\n\n        }\n\n\n        return result;\n\n    }\n\n\n    function resolveLayout(){\n\n        return {\n\n            ...resolveMainLayout(),\n\n            ...resolveHeadLayout()\n\n        };\n\n    }\n\n\n    \/* =====================================================\n       CATEGORY \u2192 SLOT\n       ===================================================== *\/\n\n    function categoryToSlot(\n        category\n    ){\n\n        if(!category){\n\n            return null;\n\n        }\n\n\n        const value =\n            String(\n                category\n            )\n            .toLowerCase()\n            .trim();\n\n\n        return (\n\n            CONFIG.categoryMap[\n                value\n            ]\n\n            ||\n\n            CONFIG.legacyCategoryMap[\n                value\n            ]\n\n            ||\n\n            null\n\n        );\n\n    }\n\n\n    \/* =====================================================\n       COORDINATES\n\n       Reference layout coordinate \u2192 offset from the canvas\n       centre.\n\n       X: distance from centre \u00d7 current spread factor of\n          the item's slot (1 at 575px \u2026 max at 645px).\n          x = centerX always stays exactly 0.\n       Y: unchanged.\n       ===================================================== *\/\n\n    function toCanvasOffset(\n        x,\n        y,\n        slot\n    ){\n\n        return {\n\n            x:\n                (\n                    x -\n                    CONFIG.canvas.centerX\n                ) *\n                getSpread(\n                    slot\n                ),\n\n            y:\n                y -\n                CONFIG.canvas.centerY\n\n        };\n\n    }\n\n\n    \/* =====================================================\n       PREPARE ELEMENT\n       ===================================================== *\/\n\n    function prepareElement(\n        element,\n        item\n    ){\n\n        if(\n            !element ||\n            !item\n        ){\n\n            return;\n\n        }\n\n\n        const image =\n            String(\n                item.image ||\n                \"\"\n            )\n            .replace(\n                \/\"\/g,\n                '\\\\\"'\n            );\n\n\n        element.style.backgroundImage =\n            'url(\"' +\n            image +\n            '\")';\n\n\n        element.style.width =\n            CONFIG.assetBoxSize +\n            \"px\";\n\n\n        element.style.height =\n            CONFIG.assetBoxSize +\n            \"px\";\n\n    }\n\n\n    \/* =====================================================\n       ENTER\n       ===================================================== *\/\n\n    function enterSoftPop(\n        element,\n        target,\n        delay\n    ){\n\n        if(\n            !element ||\n            !target\n        ){\n\n            return;\n\n        }\n\n\n        const offset =\n            toCanvasOffset(target.x, target.y, element.dataset.slot);\n\n\n        gsap.killTweensOf(\n            element\n        );\n\n\n        gsap.set(\n            element,\n            {\n\n                opacity:0,\n\n                scale:\n                    target.scale *\n                    CONFIG.animation.enterStartScale,\n\n                x:\n                    offset.x,\n\n                y:\n                    offset.y,\n\n                rotation:\n                    target.rotation +\n                    CONFIG.animation.enterRotationOffset\n\n            }\n        );\n\n\n        const timeline =\n            gsap.timeline({\n\n                overwrite:\"auto\",\n\n                delay:\n                    delay || 0\n\n            });\n\n\n        timeline.to(\n            element,\n            {\n\n                opacity:1,\n\n                scale:\n                    target.scale *\n                    CONFIG.animation.enterOvershoot,\n\n                rotation:\n                    target.rotation,\n\n                duration:\n                    CONFIG.animation.enterDuration,\n\n                ease:\n                    CONFIG.animation.enterEase\n\n            }\n        );\n\n\n        timeline.to(\n            element,\n            {\n\n                scale:\n                    target.scale,\n\n                duration:\n                    CONFIG.animation.settleDuration,\n\n                ease:\n                    CONFIG.animation.settleEase\n\n            },\n\n            \"-=0.08\"\n\n        );\n\n\n        return timeline;\n\n    }\n\n\n    \/* =====================================================\n       EXIT\n       ===================================================== *\/\n\n    function exitPopVanish(\n        element,\n        onComplete\n    ){\n\n        if(!element){\n\n            if(\n                typeof onComplete ===\n                \"function\"\n            ){\n\n                onComplete();\n\n            }\n\n            return;\n\n        }\n\n\n        gsap.killTweensOf(\n            element\n        );\n\n\n        const timeline =\n            gsap.timeline({\n\n                overwrite:\"auto\",\n\n                onComplete:\n                    onComplete ||\n                    null\n\n            });\n\n\n        timeline.to(\n            element,\n            {\n\n                scale:\n                    \"+=\" +\n                    CONFIG.animation.exitImpulse,\n\n                duration:\n                    CONFIG.animation.exitImpulseDuration,\n\n                ease:\"power1.out\"\n\n            }\n        );\n\n\n        timeline.to(\n            element,\n            {\n\n                scale:\n                    CONFIG.animation.exitScale,\n\n                opacity:0,\n\n                duration:\n                    CONFIG.animation.exitDuration,\n\n                ease:\n                    CONFIG.animation.exitEase\n\n            }\n        );\n\n\n        return timeline;\n\n    }\n\n\n    \/* =====================================================\n       MOVE\n       ===================================================== *\/\n\n    function moveToLayout(\n        element,\n        target\n    ){\n\n        if(\n            !element ||\n            !target\n        ){\n\n            return;\n\n        }\n\n\n        const offset =\n            toCanvasOffset(target.x, target.y, element.dataset.slot);\n\n\n        gsap.killTweensOf(\n            element\n        );\n\n\n        gsap.to(\n            element,\n            {\n\n                opacity:\n                    target.opacity ??\n                    1,\n\n                x:\n                    offset.x,\n\n                y:\n                    offset.y,\n\n                scale:\n                    target.scale,\n\n                rotation:\n                    target.rotation ??\n                    0,\n\n                duration:\n                    CONFIG.animation.moveDuration,\n\n                ease:\n                    CONFIG.animation.moveEase,\n\n                overwrite:\n                    \"auto\"\n\n            }\n        );\n\n    }\n\n\n    \/* =====================================================\n       HIDE\n       ===================================================== *\/\n\n    function hideLayer(\n        element\n    ){\n\n        if(!element){\n\n            return;\n\n        }\n\n\n        gsap.killTweensOf(\n            element\n        );\n\n\n        gsap.to(\n            element,\n            {\n\n                opacity:0,\n\n                scale:0.94,\n\n                duration:0.25,\n\n                ease:\"power2.inOut\",\n\n                overwrite:\"auto\"\n\n            }\n        );\n\n    }\n\n\n    \/* =====================================================\n       SAME-SLOT PRODUCT REPLACEMENT\n       ===================================================== *\/\n\n    function replaceSameSlotProduct(\n        element,\n        nextItem,\n        nextTarget,\n        slot,\n        version\n    ){\n\n        if(\n            !element ||\n            !nextItem ||\n            !nextTarget\n        ){\n\n            return;\n\n        }\n\n\n        const nextImage =\n            String(\n                nextItem.image ||\n                \"\"\n            ).trim();\n\n\n        \/*\n         * Start loading the next full image immediately.\n         * The existing visual sequence remains unchanged:\n         * old item exits completely, then the new item enters.\n         *\/\n        const imageReady =\n            imagePreloader.ready(\n                nextImage\n            );\n\n\n        gsap.killTweensOf(\n            element\n        );\n\n\n        exitPopVanish(\n            element,\n            function(){\n\n                imageReady.then(\n                    function(){\n\n                        if(\n                            !isCurrentTransition(\n                                slot,\n                                version\n                            )\n                        ){\n                            return;\n                        }\n\n                        element.style.backgroundImage =\n                            'url(\"' +\n                            nextImage.replace(\n                                \/\"\/g,\n                                '\\\\\"'\n                            ) +\n                            '\")';\n\n\n                        element.style.width =\n                            CONFIG.assetBoxSize +\n                            \"px\";\n\n\n                        element.style.height =\n                            CONFIG.assetBoxSize +\n                            \"px\";\n\n\n                        enterSoftPop(\n                            element,\n                            nextTarget\n                        );\n\n                    }\n                );\n\n            }\n        );\n\n    }\n\n\n    \/* =====================================================\n       TRANSITION LAYER\n       ===================================================== *\/\n\n    function transitionLayer(\n        slot,\n        previousItem,\n        nextItem,\n        previousLayout,\n        nextLayout\n    ){\n\n        const version =\n            beginTransition(\n                slot\n            );\n\n        const element =\n            layers &&\n            layers[slot];\n\n\n        const previous =\n            previousLayout &&\n            previousLayout[slot];\n\n\n        const next =\n            nextLayout &&\n            nextLayout[slot];\n\n\n        \/* =================================================\n           NOTHING \u2192 NEW ITEM\n           ================================================= *\/\n\n        if(\n            !previousItem &&\n            nextItem &&\n            next\n        ){\n\n            const nextImage =\n                String(\n                    nextItem.image ||\n                    \"\"\n                ).trim();\n\n            imagePreloader\n                .ready(\n                    nextImage\n                )\n                .then(\n                    function(){\n\n                        if(\n                            !isCurrentTransition(\n                                slot,\n                                version\n                            )\n                        ){\n                            return;\n                        }\n\n                        prepareElement(\n                            element,\n                            nextItem\n                        );\n\n\n                        enterSoftPop(\n                            element,\n                            next\n                        );\n\n                    }\n                );\n\n\n            return;\n\n        }\n\n\n        \/* =================================================\n           EXISTING \u2192 NOTHING\n           ================================================= *\/\n\n        if(\n            previousItem &&\n            !nextItem\n        ){\n\n            exitPopVanish(\n                element\n            );\n\n\n            return;\n\n        }\n\n\n        \/* =================================================\n           EXISTING \u2192 EXISTING\n           ================================================= *\/\n\n        if(\n            previousItem &&\n            nextItem &&\n            previous &&\n            next\n        ){\n\n            const previousId =\n                previousItem.id ||\n                previousItem.productId ||\n                \"\";\n\n\n            const nextId =\n                nextItem.id ||\n                nextItem.productId ||\n                \"\";\n\n\n            const previousImage =\n                String(\n                    previousItem.image ||\n                    \"\"\n                );\n\n\n            const nextImage =\n                String(\n                    nextItem.image ||\n                    \"\"\n                );\n\n\n            const sameProduct =\n                (\n                    previousId ===\n                    nextId\n                )\n                &&\n                (\n                    previousImage ===\n                    nextImage\n                );\n\n\n            \/* ---------------------------------------------\n               SAME PRODUCT:\n               only composition\/layout changed\n               --------------------------------------------- *\/\n\n            if(\n                sameProduct\n            ){\n\n                prepareElement(\n                    element,\n                    nextItem\n                );\n\n\n                moveToLayout(\n                    element,\n                    next\n                );\n\n\n                return;\n\n            }\n\n\n            \/* ---------------------------------------------\n               DIFFERENT PRODUCT:\n               same slot\/category\n               --------------------------------------------- *\/\n\n            replaceSameSlotProduct(\n                element,\n                nextItem,\n                next,\n                slot,\n                version\n            );\n\n\n            return;\n\n        }\n\n\n        \/* =================================================\n           FALLBACK\n           ================================================= *\/\n\n        if(\n            nextItem &&\n            next\n        ){\n\n            const nextImage =\n                String(\n                    nextItem.image ||\n                    \"\"\n                ).trim();\n\n            imagePreloader\n                .ready(\n                    nextImage\n                )\n                .then(\n                    function(){\n\n                        if(\n                            !isCurrentTransition(\n                                slot,\n                                version\n                            )\n                        ){\n                            return;\n                        }\n\n                        prepareElement(\n                            element,\n                            nextItem\n                        );\n\n\n                        enterSoftPop(\n                            element,\n                            next\n                        );\n\n                    }\n                );\n\n\n            return;\n\n        }\n\n\n        hideLayer(\n            element\n        );\n\n    }\n\n\n    \/* =====================================================\n       RENDER LAYOUT\n       ===================================================== *\/\n\n    function renderLayout(\n        nextLayout\n    ){\n\n        if(!layers){\n\n            return;\n\n        }\n\n\n        const previousLayout =\n            state.previousLayout ||\n            {};\n\n\n        \/*\n         * CRITICAL:\n         *\n         * previousItems contains the state\n         * BEFORE this event.\n         *\n         * state.* already contains the NEW state.\n         *\/\n\n        const previousItems = {\n\n            bottom:\n                state.previousItems.bottom,\n\n            base:\n                state.previousItems.base,\n\n            onepiece:\n                state.previousItems.onepiece,\n\n            jacket:\n                state.previousItems.jacket,\n\n            hat:\n                state.previousItems.hat,\n\n            accessory:\n                state.previousItems.accessory\n\n        };\n\n\n        const nextItems = {\n\n            bottom:\n                state.bottom,\n\n            base:\n                state.base,\n\n            onepiece:\n                state.onepiece,\n\n            jacket:\n                state.jacket,\n\n            hat:\n                state.hat,\n\n            accessory:\n                state.accessory\n\n        };\n\n\n        [\n\n            \"bottom\",\n            \"base\",\n            \"onepiece\",\n            \"jacket\",\n            \"hat\",\n            \"accessory\"\n\n        ].forEach(\n            function(slot){\n\n                transitionLayer(\n\n                    slot,\n\n                    previousItems[slot],\n\n                    nextItems[slot],\n\n                    previousLayout,\n\n                    nextLayout\n\n                );\n\n            }\n        );\n\n\n        \/*\n         * Save the NEW layout\n         * (reference coordinates \u2014 used by repositionLayers()).\n         *\/\n\n        state.previousLayout =\n            JSON.parse(\n                JSON.stringify(\n                    nextLayout\n                )\n            );\n\n\n        \/*\n         * Save the NEW item state only AFTER\n         * all transitions have been decided.\n         *\/\n\n        state.previousItems = {\n\n            bottom:\n                nextItems.bottom,\n\n            base:\n                nextItems.base,\n\n            onepiece:\n                nextItems.onepiece,\n\n            jacket:\n                nextItems.jacket,\n\n            hat:\n                nextItems.hat,\n\n            accessory:\n                nextItems.accessory\n\n        };\n\n    }\n\n\n    \/* =====================================================\n       SYNC STATE FROM PRODUCTS SCROLL\n       ===================================================== *\/\n\n    function syncStateFromActiveProducts(\n        activeProducts\n    ){\n\n        const nextState = {\n\n            bottom:null,\n\n            base:null,\n\n            onepiece:null,\n\n            jacket:null,\n\n            hat:null,\n\n            accessory:null\n\n        };\n\n\n        if(\n            activeProducts &&\n            typeof activeProducts ===\n                \"object\"\n        ){\n\n            Object.keys(\n                activeProducts\n            )\n            .forEach(\n                function(category){\n\n                    const entry =\n                        activeProducts[\n                            category\n                        ];\n\n\n                    if(\n                        !entry ||\n                        !entry.product\n                    ){\n\n                        return;\n\n                    }\n\n\n                    const slot =\n                        categoryToSlot(\n                            category\n                        );\n\n\n                    if(!slot){\n\n                        return;\n\n                    }\n\n\n                    nextState[slot] =\n                        entry.product;\n\n                }\n            );\n\n        }\n\n\n        state.bottom =\n            nextState.bottom;\n\n        state.base =\n            nextState.base;\n\n        state.onepiece =\n            nextState.onepiece;\n\n        state.jacket =\n            nextState.jacket;\n\n        state.hat =\n            nextState.hat;\n\n        state.accessory =\n            nextState.accessory;\n\n    }\n\n\n    \/* =====================================================\n       PRODUCT CHANGE\n       ===================================================== *\/\n\n    function handleProductChange(\n        event\n    ){\n\n        const detail =\n            event &&\n            event.detail;\n\n\n        if(!detail){\n\n            return;\n\n        }\n\n\n        \/*\n         * Products Scroll has already resolved\n         * all category conflicts.\n         *\/\n\n        syncStateFromActiveProducts(\n            detail.activeProducts || {}\n        );\n\n\n        \/*\n         * ONE SINGLE render pass.\n         *\/\n\n        renderLayout(\n            resolveLayout()\n        );\n\n    }\n\n\n    \/* =====================================================\n       RESIZE\n       ===================================================== *\/\n\n    function handleResize(){\n\n        const wrapper =\n            getWrapper();\n\n\n        if(!wrapper){\n\n            return;\n\n        }\n\n\n        const rect =\n            wrapper.getBoundingClientRect();\n\n\n        updateCanvasScale(\n            rect.width,\n            rect.height\n        );\n\n    }\n\n\n    \/* =====================================================\n       CLEANUP\n       ===================================================== *\/\n\n    function removePreviousHandlers(){\n\n        if(\n            window.__LULLA_CANVAS_PRODUCT_HANDLER\n        ){\n\n            document.removeEventListener(\n                \"lulla:product-change\",\n                window.__LULLA_CANVAS_PRODUCT_HANDLER\n            );\n\n\n            window.__LULLA_CANVAS_PRODUCT_HANDLER =\n                null;\n\n        }\n\n\n        if(\n            window.__LULLA_CANVAS_RESIZE_HANDLER\n        ){\n\n            window.removeEventListener(\n                \"resize\",\n                window.__LULLA_CANVAS_RESIZE_HANDLER\n            );\n\n\n            window.__LULLA_CANVAS_RESIZE_HANDLER =\n                null;\n\n        }\n\n\n        if(\n            window.__LULLA_CANVAS_RESIZE_OBSERVER\n        ){\n\n            window\n                .__LULLA_CANVAS_RESIZE_OBSERVER\n                .disconnect();\n\n\n            window.__LULLA_CANVAS_RESIZE_OBSERVER =\n                null;\n\n        }\n\n    }\n\n\n    \/* =====================================================\n       INIT\n       ===================================================== *\/\n\n    function init(){\n\n        const canvas =\n            getCanvas();\n\n\n        if(!canvas){\n\n            return;\n\n        }\n\n\n        removePreviousHandlers();\n\n\n        const wrapper =\n            ensureResponsiveWrapper();\n\n\n        if(!wrapper){\n\n            return;\n\n        }\n\n\n        ensureLayers();\n\n\n        if(!layers){\n\n            return;\n\n        }\n\n\n        \/*\n         * Reset state.\n         *\/\n\n        state.bottom =\n            null;\n\n        state.base =\n            null;\n\n        state.onepiece =\n            null;\n\n        state.hat =\n            null;\n\n        state.jacket =\n            null;\n\n        state.accessory =\n            null;\n\n        state.previousLayout =\n            null;\n\n        state.previousItems = {\n\n            bottom:null,\n\n            base:null,\n\n            onepiece:null,\n\n            jacket:null,\n\n            hat:null,\n\n            accessory:null\n\n        };\n\n\n        \/*\n         * Reset visual layers.\n         *\/\n\n        Object.values(\n            layers\n        )\n        .forEach(\n            function(element){\n\n                gsap.killTweensOf(\n                    element\n                );\n\n\n                gsap.set(\n                    element,\n                    {\n\n                        opacity:0,\n\n                        x:0,\n\n                        y:0,\n\n                        scale:1,\n\n                        rotation:0\n\n                    }\n                );\n\n            }\n        );\n\n\n        \/*\n         * Reset responsive view to the reference size;\n         * the ResizeObserver below applies the real one.\n         *\/\n\n        view.width =\n            CONFIG.responsive.minWidth;\n\n        view.progress =\n            0;\n\n        view.scale =\n            1;\n\n\n        canvas.style.setProperty(\n            \"--lulla-canvas-w\",\n            CONFIG.responsive.minWidth +\n            \"px\"\n        );\n\n\n        canvas.style.transform =\n            \"translate(-50%, -50%) scale(1)\";\n\n\n        \/*\n         * Product change listener.\n         *\/\n\n        window.__LULLA_CANVAS_PRODUCT_HANDLER =\n            handleProductChange;\n\n\n        document.addEventListener(\n            \"lulla:product-change\",\n            window.__LULLA_CANVAS_PRODUCT_HANDLER\n        );\n\n\n        \/*\n         * Resize listener.\n         *\/\n\n        window.__LULLA_CANVAS_RESIZE_HANDLER =\n            handleResize;\n\n\n        window.addEventListener(\n            \"resize\",\n            window.__LULLA_CANVAS_RESIZE_HANDLER,\n            {\n                passive:true\n            }\n        );\n\n\n        setupCanvasObserver();\n\n    }\n\n\n    \/* =====================================================\n       START\n       ===================================================== *\/\n\n    function start(){\n\n        init();\n\n    }\n\n\n    if(\n        document.readyState ===\n        \"loading\"\n    ){\n\n        document.addEventListener(\n            \"DOMContentLoaded\",\n            start,\n            {\n                once:true\n            }\n        );\n\n    }else{\n\n        start();\n\n    }\n\n\n    if(\n        typeof jQuery !==\n        \"undefined\"\n    ){\n\n        jQuery(window).on(\n            \"elementor\/frontend\/init\",\n            start\n        );\n\n    }\n\n})();\n\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-856a684 elementor-widget elementor-widget-html\" data-id=\"856a684\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"lulla-canvas-instructions\" aria-hidden=\"true\">\r\n  <div class=\"lulla-instructions-full\">\r\n\r\n    <div class=\"lulla-instruction-step\">\r\n      <div class=\"lulla-instruction-icon lulla-icon-outfit\">\r\n        <img decoding=\"async\" src=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/outfit-icon.svg\" alt=\"\">\r\n      <\/div>\r\n\r\n      <div class=\"lulla-instruction-title\">Build your look<\/div>\r\n      <div class=\"lulla-instruction-copy\">Start with one item.<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"lulla-instruction-arrow\">\u2193<\/div>\r\n\r\n    <div class=\"lulla-instruction-step\">\r\n      <div class=\"lulla-instruction-icon lulla-icon-tape\">\r\n        <img decoding=\"async\" src=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/measuring-tape-icon.svg\" alt=\"\">\r\n      <\/div>\r\n\r\n      <div class=\"lulla-instruction-title\">Choose your sizes<\/div>\r\n      <div class=\"lulla-instruction-copy\">Find the right fit.<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"lulla-instruction-arrow\">\u2193<\/div>\r\n\r\n    <div class=\"lulla-instruction-step\">\r\n      <div class=\"lulla-instruction-icon lulla-icon-bag\">\r\n        <img decoding=\"async\" src=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/shopping-bag-icon.svg\" alt=\"\">\r\n      <\/div>\r\n\r\n      <div class=\"lulla-instruction-title\">Add to bag<\/div>\r\n      <div class=\"lulla-instruction-copy\">Complete your outfit.<\/div>\r\n    <\/div>\r\n\r\n  <\/div>\r\n<\/div>\r\n\r\n<style>\r\n\/*\r\n * The intro layer fills the CURRENT canvas (width follows the\r\n * Engine's --lulla-canvas-w, height is 745px), so its content is\r\n * always centered \u2014 no matter how wide the responsive canvas is.\r\n * (It used to be a fixed 575px box pinned to the left edge.)\r\n *\/\r\n.lulla-canvas-instructions{\r\n    position:absolute!important;\r\n    left:0!important;\r\n    top:0!important;\r\n    width:100%!important;\r\n    height:100%!important;\r\n    min-width:0!important;\r\n    min-height:0!important;\r\n    box-sizing:border-box!important;\r\n    margin:0!important;\r\n    padding:0!important;\r\n    display:flex!important;\r\n    align-items:center!important;\r\n    justify-content:center!important;\r\n    pointer-events:none!important;\r\n    z-index:900!important;\r\n\r\n    opacity:0;\r\n    visibility:hidden;\r\n\r\n    \/*\r\n     * SAME REVEAL ANIMATION:\r\n     * blur + scale up into place\r\n     *\/\r\n    transform:scale(.95);\r\n    filter:blur(10px);\r\n\r\n    transition:\r\n        opacity .95s cubic-bezier(.22,.61,.36,1),\r\n        transform 1.05s cubic-bezier(.22,.61,.36,1),\r\n        filter 1.05s cubic-bezier(.22,.61,.36,1),\r\n        visibility 0s linear 1.05s;\r\n}\r\n\r\n.lulla-canvas-instructions.is-visible{\r\n    opacity:1;\r\n    visibility:visible;\r\n    transform:scale(1);\r\n    filter:blur(0);\r\n\r\n    transition:\r\n        opacity .95s cubic-bezier(.22,.61,.36,1),\r\n        transform 1.05s cubic-bezier(.22,.61,.36,1),\r\n        filter 1.05s cubic-bezier(.22,.61,.36,1),\r\n        visibility 0s;\r\n}\r\n\r\n.lulla-canvas-instructions.is-hidden{\r\n    opacity:0!important;\r\n    visibility:hidden!important;\r\n\r\n    \/*\r\n     * REVERSE OF THE SAME ANIMATION\r\n     *\/\r\n    transform:scale(.95)!important;\r\n    filter:blur(10px)!important;\r\n\r\n    transition:\r\n        opacity .95s cubic-bezier(.22,.61,.36,1),\r\n        transform 1.05s cubic-bezier(.22,.61,.36,1),\r\n        filter 1.05s cubic-bezier(.22,.61,.36,1),\r\n        visibility 0s linear 1.05s;\r\n}\r\n\r\n.lulla-instructions-full{\r\n    width:390px;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    justify-content:flex-start;\r\n    text-align:center;\r\n    box-sizing:border-box;\r\n    padding-top:42px;\r\n}\r\n\r\n.lulla-instruction-step{\r\n    width:100%;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    justify-content:flex-start;\r\n    text-align:center;\r\n}\r\n\r\n.lulla-instruction-icon{\r\n    width:84px;\r\n    height:84px;\r\n    flex:0 0 84px;\r\n    margin-top:7px;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    overflow:visible;\r\n}\r\n\r\n.lulla-instruction-icon img{\r\n    display:block;\r\n    width:100%;\r\n    height:100%;\r\n    object-fit:contain;\r\n}\r\n\r\n.lulla-icon-outfit img{\r\n    width:100%;\r\n    height:100%;\r\n}\r\n\r\n.lulla-icon-tape{\r\n    width:84px;\r\n    height:60px;\r\n    flex-basis:60px;\r\n    margin-top:5px;\r\n}\r\n\r\n.lulla-icon-tape img{\r\n    width:90px;\r\n    height:90px;\r\n    max-width:none;\r\n    max-height:none;\r\n    object-fit:contain;\r\n    transform:translateY(-4px);\r\n}\r\n\r\n.lulla-icon-bag img{\r\n    width:82%;\r\n    height:82%;\r\n}\r\n\r\n.lulla-instruction-title{\r\n    margin-top:8px;\r\n    font:italic 27px\/1.05 \"Playfair Display\",Georgia,serif!important;\r\n    font-weight:400!important;\r\n    letter-spacing:-.2px!important;\r\n    color:#1D1D1B!important;\r\n}\r\n\r\n.lulla-instruction-copy{\r\n    margin-top:6px;\r\n    font:400 14px\/1.15 \"Inter Tight\",sans-serif!important;\r\n    color:#1D1D1B!important;\r\n}\r\n\r\n.lulla-instruction-arrow{\r\n    height:30px;\r\n    margin:12px 0;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    font:300 20px\/1 \"Inter Tight\",sans-serif!important;\r\n    color:rgba(29,29,27,.42)!important;\r\n}\r\n\r\n@media(max-width:850px){\r\n    .lulla-instructions-full{\r\n        width:390px;\r\n        padding-top:38px;\r\n        transform:scale(1.12);\r\n    }\r\n\r\n    .lulla-instruction-icon{\r\n        width:92px;\r\n        height:92px;\r\n        flex-basis:92px;\r\n    }\r\n\r\n    .lulla-icon-tape{\r\n        height:62px;\r\n        flex-basis:62px;\r\n    }\r\n\r\n    .lulla-icon-tape img{\r\n        width:92px;\r\n        height:92px;\r\n    }\r\n\r\n    .lulla-icon-bag img{\r\n        width:82%;\r\n        height:82%;\r\n    }\r\n\r\n    .lulla-instruction-title{\r\n        font-size:27px!important;\r\n    }\r\n\r\n    .lulla-instruction-copy{\r\n        font-size:14px!important;\r\n    }\r\n\r\n    .lulla-instruction-arrow{\r\n        height:27px;\r\n        margin:10px 0;\r\n    }\r\n}\r\n\r\n@media(max-width:600px){\r\n    .lulla-instructions-full{\r\n        width:390px;\r\n        padding-top:24px;\r\n        transform:scale(1.22);\r\n    }\r\n\r\n    .lulla-instruction-icon{\r\n        width:96px;\r\n        height:96px;\r\n        flex-basis:96px;\r\n        margin-top:4px;\r\n    }\r\n\r\n    .lulla-icon-tape{\r\n        width:96px;\r\n        height:58px;\r\n        flex-basis:58px;\r\n        margin-top:1px;\r\n    }\r\n\r\n    .lulla-icon-tape img{\r\n        width:86px;\r\n        height:86px;\r\n        transform:translateY(-3px);\r\n    }\r\n\r\n    .lulla-icon-bag img{\r\n        width:84%;\r\n        height:84%;\r\n    }\r\n\r\n    .lulla-instruction-title{\r\n        margin-top:5px;\r\n        font-size:34px!important;\r\n        line-height:1.02!important;\r\n    }\r\n\r\n    .lulla-instruction-copy{\r\n        margin-top:6px;\r\n        font-size:19px!important;\r\n        line-height:1.15!important;\r\n    }\r\n\r\n    .lulla-instruction-arrow{\r\n        height:21px;\r\n        margin:7px 0;\r\n        font-size:22px!important;\r\n    }\r\n}\r\n\r\n@media(max-width:390px){\r\n    .lulla-instructions-full{\r\n        padding-top:21px;\r\n        transform:scale(1.28);\r\n    }\r\n\r\n    .lulla-instruction-icon{\r\n        width:92px;\r\n        height:92px;\r\n        flex-basis:92px;\r\n    }\r\n\r\n    .lulla-icon-tape{\r\n        height:56px;\r\n        flex-basis:56px;\r\n    }\r\n\r\n    .lulla-icon-tape img{\r\n        width:84px;\r\n        height:84px;\r\n    }\r\n\r\n    .lulla-instruction-title{\r\n        font-size:32px!important;\r\n    }\r\n\r\n    .lulla-instruction-copy{\r\n        font-size:18px!important;\r\n    }\r\n\r\n    .lulla-instruction-arrow{\r\n        height:19px;\r\n        margin:6px 0;\r\n    }\r\n}\r\n\r\n@media(max-width:850px) and (orientation:landscape) and (max-height:520px){\r\n    .lulla-instructions-full{\r\n        position:absolute;\r\n        left:50%;\r\n        top:50%;\r\n        width:390px;\r\n        padding-top:0;\r\n        transform:translate(-50%,-50%) scale(.95);\r\n        transform-origin:center center;\r\n    }\r\n\r\n    .lulla-instruction-icon{\r\n        width:90px;\r\n        height:90px;\r\n        flex-basis:90px;\r\n    }\r\n\r\n    .lulla-icon-tape{\r\n        height:58px;\r\n        flex-basis:58px;\r\n    }\r\n\r\n    .lulla-icon-tape img{\r\n        width:84px;\r\n        height:84px;\r\n    }\r\n\r\n    .lulla-instruction-title{\r\n        font-size:28px!important;\r\n    }\r\n\r\n    .lulla-instruction-copy{\r\n        font-size:16px!important;\r\n    }\r\n\r\n    .lulla-instruction-arrow{\r\n        height:13px;\r\n        margin:4px 0;\r\n    }\r\n}\r\n\r\n@media(max-width:850px) and (orientation:landscape) and (max-height:400px){\r\n    .lulla-instructions-full{\r\n        transform:translate(-50%,-50%) scale(.86);\r\n    }\r\n}\r\n\r\n@media(prefers-reduced-motion:reduce){\r\n    .lulla-canvas-instructions{\r\n        transition:none!important;\r\n    }\r\n}\r\n<\/style>\r\n\r\n<script>\r\n(function(){\r\n    \"use strict\";\r\n\r\n    var started=false;\r\n    var root=null;\r\n\r\n    function getActiveCount(){\r\n        try{\r\n            if(\r\n                window.LullaProductScroll &&\r\n                typeof window.LullaProductScroll.getState===\"function\"\r\n            ){\r\n                var state=window.LullaProductScroll.getState();\r\n                var active=state&&state.activeProducts\r\n                    ?state.activeProducts\r\n                    :{};\r\n\r\n                return Object.keys(active).filter(function(key){\r\n                    return Boolean(active[key]);\r\n                }).length;\r\n            }\r\n        }catch(error){}\r\n\r\n        return null;\r\n    }\r\n\r\n    function show(){\r\n        if(!root)return;\r\n\r\n        root.classList.remove(\"is-hidden\");\r\n        root.classList.add(\"is-visible\");\r\n        root.setAttribute(\"aria-hidden\",\"false\");\r\n    }\r\n\r\n    function hide(){\r\n        if(!root)return;\r\n\r\n        root.classList.remove(\"is-visible\");\r\n        root.classList.add(\"is-hidden\");\r\n        root.setAttribute(\"aria-hidden\",\"true\");\r\n    }\r\n\r\n    function syncFromState(){\r\n        var count=getActiveCount();\r\n\r\n        if(count===null){\r\n            return false;\r\n        }\r\n\r\n        if(count>0){\r\n            started=true;\r\n            hide();\r\n        }else if(!started){\r\n            show();\r\n        }else{\r\n            hide();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function init(){\r\n        root=document.querySelector(\".lulla-canvas-instructions\");\r\n\r\n        if(!root||root.dataset.lullaReady===\"true\"){\r\n            return;\r\n        }\r\n\r\n        var canvas=document.querySelector(\".outfit-canvas\");\r\n\r\n        if(!canvas){\r\n            setTimeout(init,100);\r\n            return;\r\n        }\r\n\r\n        if(root.parentElement!==canvas){\r\n            canvas.appendChild(root);\r\n        }\r\n\r\n        root.dataset.lullaReady=\"true\";\r\n\r\n        document.addEventListener(\"lulla:outfit-reset\",function(){\r\n            started=false;\r\n            show();\r\n        });\r\n\r\n        document.addEventListener(\"lulla:gender-change\",function(){\r\n            window.setTimeout(function(){\r\n                var count=getActiveCount();\r\n\r\n                if(count===0){\r\n                    started=false;\r\n                    show();\r\n                }else{\r\n                    started=true;\r\n                    hide();\r\n                }\r\n            },0);\r\n        });\r\n\r\n        document.addEventListener(\"lulla:catalog-filter-change\",function(){\r\n            window.setTimeout(function(){\r\n                var count=getActiveCount();\r\n\r\n                if(count===0){\r\n                    started=false;\r\n                    show();\r\n                }else{\r\n                    started=true;\r\n                    hide();\r\n                }\r\n            },0);\r\n        });\r\n\r\n        document.addEventListener(\"lulla:product-change\",function(event){\r\n            var active=\r\n                event.detail &&\r\n                event.detail.activeProducts\r\n                    ?event.detail.activeProducts\r\n                    :{};\r\n\r\n            var count=Object.keys(active).filter(function(key){\r\n                return Boolean(active[key]);\r\n            }).length;\r\n\r\n            if(count>0){\r\n                started=true;\r\n                hide();\r\n            }else if(!started){\r\n                show();\r\n            }else{\r\n                hide();\r\n            }\r\n        });\r\n\r\n        root.classList.remove(\"is-visible\",\"is-hidden\");\r\n        root.setAttribute(\"aria-hidden\",\"true\");\r\n\r\n        if(!syncFromState()){\r\n            window.setTimeout(syncFromState,100);\r\n            window.setTimeout(syncFromState,300);\r\n        }\r\n    }\r\n\r\n    if(document.readyState===\"loading\"){\r\n        document.addEventListener(\"DOMContentLoaded\",init,{once:true});\r\n    }else{\r\n        init();\r\n    }\r\n\r\n    if(typeof jQuery!==\"undefined\"){\r\n        jQuery(window).on(\"elementor\/frontend\/init\",init);\r\n    }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-c4861a4 e-con-full outfit-footer e-flex e-con e-child\" data-id=\"c4861a4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-fd8413b elementor-widget__width-inherit elementor-widget elementor-widget-html\" data-id=\"fd8413b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"outfit-footer-controls\">\n  <div class=\"outfit-footer-inner\">\n\n    <div class=\"outfit-total\">\n      <span class=\"outfit-total-label\">TOTAL<\/span>\n      <span class=\"outfit-total-price\" data-total-price>&euro;0,00<\/span>\n    <\/div>\n\n    <button\n      class=\"outfit-size-button\"\n      type=\"button\"\n      aria-hidden=\"true\"\n      hidden\n    >\n      <span class=\"outfit-size-button-text\">CHOOSE SIZES<\/span>\n\n      <svg class=\"outfit-size-arrow\" viewBox=\"0 0 10 16\" aria-hidden=\"true\">\n        <path d=\"M2 2L8 8L2 14\"><\/path>\n      <\/svg>\n    <\/button>\n\n  <\/div>\n<\/div>\n\n<style>\n\/* =========================================================\n   FOOTER\n========================================================= *\/\n\n.outfit-footer{\n    width:100% !important;\n    height:auto !important;\n    min-height:0 !important;\n    margin:0 !important;\n    padding:0 !important;\n    box-sizing:border-box !important;\n    overflow:visible !important;\n}\n\n.outfit-footer-controls{\n    width:100%;\n    height:58px;\n    min-height:58px;\n    margin:0 !important;\n    padding:0 20px 14px 20px;\n    box-sizing:border-box;\n    overflow:hidden;\n    background:transparent;\n    transition:\n        opacity .28s cubic-bezier(.22,.61,.36,1),\n        visibility 0s linear 0s;\n}\n\n\/* State 1 *\/\n.outfit-panel:has(.lulla-state1:not(.is-hidden)) .outfit-footer-controls{\n    opacity:0 !important;\n    visibility:hidden !important;\n    pointer-events:none !important;\n    transition:\n        opacity .28s cubic-bezier(.22,.61,.36,1),\n        visibility 0s linear .28s !important;\n}\n\n\/* State 3 hidden *\/\n.outfit-footer-controls.is-state3-hidden{\n    height:58px !important;\n    min-height:58px !important;\n    padding:0 20px 14px 20px !important;\n    overflow:hidden !important;\n    pointer-events:none !important;\n}\n\n\/* Inner *\/\n.outfit-footer-inner{\n    width:100%;\n    height:100%;\n    display:flex;\n    align-items:center;\n    justify-content:space-between;\n    font-family:\"Inter Tight\",sans-serif !important;\n    opacity:0;\n    visibility:hidden;\n    pointer-events:none;\n    transform:translateY(16px);\n    transition:\n        opacity .22s ease,\n        transform .26s cubic-bezier(.4,0,1,1),\n        visibility 0s linear .26s;\n}\n\n.outfit-footer-inner.is-visible{\n    opacity:1;\n    visibility:visible;\n    pointer-events:auto;\n    transform:translateY(0);\n    transition:\n        opacity .32s cubic-bezier(.22,.61,.36,1),\n        transform .38s cubic-bezier(.22,.61,.36,1),\n        visibility 0s;\n}\n\n\/* Total *\/\n.outfit-total{\n    flex:0 0 auto;\n    display:flex;\n    flex-direction:column;\n    align-items:flex-start;\n    justify-content:flex-end;\n    gap:2px;\n    height:auto;\n    margin:0 !important;\n    padding:0 !important;\n    white-space:nowrap;\n}\n\n.outfit-total-label{\n    display:block;\n    margin:0 !important;\n    padding:0 !important;\n    font-family:\"Inter Tight\",sans-serif !important;\n    font-size:8px !important;\n    font-weight:400 !important;\n    line-height:1 !important;\n    letter-spacing:.06em !important;\n    text-transform:uppercase;\n    color:rgba(29,29,27,.48) !important;\n}\n\n.outfit-total-price{\n    display:block;\n    margin:0 !important;\n    padding:0 !important;\n    font-family:\"Inter Tight\",sans-serif !important;\n    font-size:12px !important;\n    font-weight:600 !important;\n    line-height:1 !important;\n    letter-spacing:0 !important;\n    color:#1d1d1b !important;\n}\n\n\/* Choose Sizes *\/\n.outfit-size-button{\n    appearance:none !important;\n    -webkit-appearance:none !important;\n\n    width:auto !important;\n    height:auto !important;\n    min-height:0 !important;\n\n    margin:0 !important;\n    padding:7px 14px 7px 16px !important;\n\n    box-sizing:border-box !important;\n\n    border:1px solid #6B7557 !important;\n    border-radius:999px !important;\n\n    outline:none !important;\n    box-shadow:none !important;\n\n    background:#6B7557 !important;\n    background-color:#6B7557 !important;\n\n    display:flex !important;\n    align-items:center !important;\n    gap:9px !important;\n\n    align-self:center !important;\n\n    font-family:\"Inter Tight\",sans-serif !important;\n    color:#fff !important;\n\n    cursor:pointer !important;\n\n    user-select:none !important;\n    -webkit-user-select:none !important;\n\n    -webkit-tap-highlight-color:transparent !important;\n    -webkit-touch-callout:none !important;\n    touch-action:manipulation !important;\n\n    transition:opacity .20s ease, transform .20s ease;\n}\n\n.outfit-size-button-text{\n    display:block !important;\n    margin:0 !important;\n    padding:0 !important;\n\n    font-family:\"Inter Tight\",sans-serif !important;\n    font-size:12px !important;\n    font-weight:400 !important;\n    line-height:1 !important;\n    letter-spacing:.005em !important;\n\n    color:#fff !important;\n    white-space:nowrap !important;\n    pointer-events:none !important;\n}\n\n.outfit-size-arrow{\n    display:block !important;\n    width:8px !important;\n    height:12px !important;\n    min-width:8px !important;\n    flex:0 0 8px !important;\n\n    pointer-events:none !important;\n\n    transition:transform .28s cubic-bezier(.22,.61,.36,1) !important;\n}\n\n.outfit-size-arrow path{\n    fill:none;\n    stroke:#fff;\n    stroke-width:1.15;\n    stroke-linecap:round;\n    stroke-linejoin:round;\n}\n\n.outfit-size-button:hover{\n    opacity:.92 !important;\n}\n\n.outfit-size-button:hover .outfit-size-arrow{\n    transform:translateX(4px) !important;\n}\n\n.outfit-size-button:focus,\n.outfit-size-button:focus-visible{\n    outline:none !important;\n    box-shadow:none !important;\n}\n\n.outfit-size-button:active{\n    opacity:.80 !important;\n    transform:scale(.985) !important;\n}\n\n.outfit-size-button[hidden]{\n    display:none !important;\n}\n\n\/* Mobile *\/\n@media(max-width:850px){\n    .outfit-footer-controls{\n        height:50px;\n        min-height:50px;\n        padding:0 16px 10px 16px;\n    }\n\n    .outfit-footer-controls.is-state3-hidden{\n        height:50px !important;\n        min-height:50px !important;\n        padding:0 16px 10px 16px !important;\n    }\n\n    .outfit-size-button{\n        padding:6px 12px 6px 14px !important;\n        gap:8px !important;\n    }\n\n    .outfit-size-button-text{\n        font-size:12px !important;\n    }\n}\n\n@media(max-width:420px){\n    .outfit-footer-controls{\n        height:48px;\n        min-height:48px;\n        padding:0 14px 9px 14px;\n    }\n\n    .outfit-footer-controls.is-state3-hidden{\n        height:48px !important;\n        min-height:48px !important;\n        padding:0 14px 9px 14px !important;\n    }\n\n    .outfit-size-button{\n        padding:6px 11px 6px 13px !important;\n        gap:7px !important;\n    }\n\n    .outfit-size-button-text{\n        font-size:11px !important;\n    }\n}\n\n\/* Reduced motion *\/\n@media(prefers-reduced-motion:reduce){\n    .outfit-footer-controls,\n    .outfit-footer-inner,\n    .outfit-size-button,\n    .outfit-size-arrow{\n        transition:none !important;\n    }\n}\n<\/style>\n\n<script>\n(function(){\n    \"use strict\";\n\n    var footer = document.querySelector(\".outfit-footer-controls\");\n    if(!footer) return;\n\n    var inner = footer.querySelector(\".outfit-footer-inner\");\n    var totalPrice = footer.querySelector(\"[data-total-price]\");\n    var sizeButton = footer.querySelector(\".outfit-size-button\");\n\n    if(!inner || !totalPrice || !sizeButton) return;\n\n    var INNER_EXIT_MS = 260;\n    var collapseTimer = null;\n    var lastActiveProducts = {};\n\n    function formatPrice(value){\n        var number = Number(value) || 0;\n        return \"\\u20AC\" + number.toFixed(2).replace(\".\", \",\");\n    }\n\n    function calculateTotal(activeProducts){\n        var total = 0;\n\n        Object.keys(activeProducts).forEach(function(category){\n            var selection = activeProducts[category];\n            if(!selection) return;\n\n            var product = selection.product || selection;\n            if(!product) return;\n\n            var price = Number(product.price);\n            if(Number.isFinite(price)) total += price;\n        });\n\n        return total;\n    }\n\n    function clearCollapseTimer(){\n        if(collapseTimer){\n            window.clearTimeout(collapseTimer);\n            collapseTimer = null;\n        }\n    }\n\n    function revealFooter(){\n        clearCollapseTimer();\n\n        footer.classList.remove(\"is-state3-hidden\");\n\n        requestAnimationFrame(function(){\n            inner.classList.add(\"is-visible\");\n        });\n    }\n\n    function hideFooterContentOnly(){\n        clearCollapseTimer();\n        inner.classList.remove(\"is-visible\");\n    }\n\n    function retreatFooterForState3(){\n        clearCollapseTimer();\n\n        inner.classList.remove(\"is-visible\");\n\n        collapseTimer = window.setTimeout(function(){\n            footer.classList.add(\"is-state3-hidden\");\n            collapseTimer = null;\n        }, INNER_EXIT_MS);\n    }\n\n    function updateFooter(activeProducts){\n        lastActiveProducts = activeProducts || {};\n\n        var categories = Object.keys(lastActiveProducts);\n        var total = calculateTotal(lastActiveProducts);\n\n        totalPrice.textContent = formatPrice(total);\n\n        if(!categories.length){\n            hideFooterContentOnly();\n            return;\n        }\n\n        sizeButton.hidden = false;\n        sizeButton.setAttribute(\"aria-hidden\", \"false\");\n\n        if(!footer.classList.contains(\"is-state3-hidden\")){\n            revealFooter();\n        }\n    }\n\n    document.addEventListener(\n        \"lulla:product-change\",\n        function(event){\n            if(!event || !event.detail) return;\n\n            updateFooter(\n                event.detail.activeProducts || {}\n            );\n        }\n    );\n\n    document.addEventListener(\n        \"lulla:state3-mode-change\",\n        function(event){\n            var active = !!(\n                event &&\n                event.detail &&\n                event.detail.active\n            );\n\n            if(active){\n                retreatFooterForState3();\n                return;\n            }\n\n            clearCollapseTimer();\n\n            footer.classList.remove(\"is-state3-hidden\");\n\n            updateFooter(lastActiveProducts);\n        }\n    );\n\n    sizeButton.addEventListener(\n        \"click\",\n        function(){\n            document.dispatchEvent(\n                new CustomEvent(\n                    \"lulla:choose-size\",\n                    { bubbles:true }\n                )\n            );\n        }\n    );\n\n    footer.classList.remove(\"is-state3-hidden\");\n    inner.classList.remove(\"is-visible\");\n\n    sizeButton.hidden = true;\n    sizeButton.setAttribute(\"aria-hidden\", \"true\");\n\n    totalPrice.textContent = formatPrice(0);\n\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-49278cd e-con-full outfit-footer e-flex e-con e-child\" data-id=\"49278cd\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0cf2b68 elementor-widget elementor-widget-html\" data-id=\"0cf2b68\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\n=========================================================\nLULLA \u2014 STATE 3 \/ LEFT\nREAL STATE 2 CANVAS\nLIQUID GLASS SIZE MARKERS\nSETTLE-THEN-REVEAL POSITIONING ENGINE\nSMOOTH PRELOADED GALLERY\nPILL COLLAPSE ON RETURN TO STAGE 2\n=========================================================\n-->\n\n<div class=\"lulla-item-info\" aria-hidden=\"true\">\n\n  <div class=\"lulla-item-stage\">\n\n    <div class=\"lulla-s3-marker-layer\" aria-hidden=\"false\"><\/div>\n\n    <div class=\"lulla-item-gallery\" aria-hidden=\"true\">\n      <div class=\"lulla-item-gallery-main\">\n        <div class=\"lulla-item-gallery-viewport\">\n          <div class=\"lulla-item-gallery-track\"><\/div>\n        <\/div>\n\n        <button type=\"button\" class=\"lulla-item-gallery-nav lulla-item-gallery-prev\" aria-label=\"Previous image\" hidden>\n          <span aria-hidden=\"true\">&lsaquo;<\/span>\n        <\/button>\n\n        <button type=\"button\" class=\"lulla-item-gallery-nav lulla-item-gallery-next\" aria-label=\"Next image\" hidden>\n          <span aria-hidden=\"true\">&rsaquo;<\/span>\n        <\/button>\n\n        <button type=\"button\" class=\"lulla-item-gallery-close\" aria-label=\"Close\">\n          <span aria-hidden=\"true\"><\/span>\n        <\/button>\n\n        <div class=\"lulla-item-gallery-dots\"><\/div>\n      <\/div>\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n<div class=\"lulla-size-guide-modal\" hidden>\n  <div class=\"lulla-size-guide-backdrop\"><\/div>\n  <div class=\"lulla-size-guide-box\">\n    <button type=\"button\" class=\"lulla-size-guide-close\" aria-label=\"Close\">&times;<\/button>\n    <img decoding=\"async\" class=\"lulla-size-guide-img\" src=\"\" alt=\"Size guide\">\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n\n  \"use strict\";\n\n  \/* =======================================================\n     ROOT \/ ELEMENTS\n  ======================================================= *\/\n\n  var root = document.querySelector(\".lulla-item-info\");\n  if(!root){ return; }\n\n  var stage        = root.querySelector(\".lulla-item-stage\");\n  var markerLayer  = root.querySelector(\".lulla-s3-marker-layer\");\n  var gallery      = root.querySelector(\".lulla-item-gallery\");\n  var galleryMain  = root.querySelector(\".lulla-item-gallery-main\");\n  var track        = root.querySelector(\".lulla-item-gallery-track\");\n  var dots         = root.querySelector(\".lulla-item-gallery-dots\");\n  var prevButton   = root.querySelector(\".lulla-item-gallery-prev\");\n  var nextButton   = root.querySelector(\".lulla-item-gallery-next\");\n  var closeButton   = root.querySelector(\".lulla-item-gallery-close\");\n\n  var sizeGuideModal    = document.querySelector(\".lulla-size-guide-modal\");\n  var sizeGuideImg      = sizeGuideModal ? sizeGuideModal.querySelector(\".lulla-size-guide-img\") : null;\n  var sizeGuideClose    = sizeGuideModal ? sizeGuideModal.querySelector(\".lulla-size-guide-close\") : null;\n  var sizeGuideBackdrop = sizeGuideModal ? sizeGuideModal.querySelector(\".lulla-size-guide-backdrop\") : null;\n\n  \/* =======================================================\n     PANEL VISIBILITY STATE\n  ======================================================= *\/\n\n  var visibilityState = \"hidden\"; \/\/ hidden | entering | visible | leaving\n\n  var currentProduct = null;\n  var currentPhotos  = [];\n  var currentIndex   = 0;\n\n  var requestToken = 0;\n\n  var galleryClearTimer = null;\n  var panelHideTimer    = null;\n\n  var detailsCache   = {};\n  var detailsPending = {};\n\n  var photosCache   = {};\n  var photosPending = {};\n\n  \/* =======================================================\n     GALLERY TIMING\n  ======================================================= *\/\n\n  var GALLERY_FADE_OUT   = 180;\n  var GALLERY_FADE_IN    = 380;\n  var GALLERY_CLOSE_FADE = 220;\n\n  \/*\n   * Important:\n   * The gallery CSS no longer controls this transition.\n   * JS owns the reveal so we never get CSS\/JS fighting each other.\n   *\/\n\n  \/* =======================================================\n     MARKER GEOMETRY CONSTANTS\n  ======================================================= *\/\n\n  var MARKER_PILL_HEIGHT = 32;\n  var MARKER_LINE_LENGTH = 10;\n  var MARKER_DOT_SIZE    = 7;\n\n  var MARKER_OUT_DURATION = 220;\n  var MARKER_IN_DURATION  = 380;\n  var MARKER_IN_STAGGER   = 45;\n  var MARKER_REVEAL_DELAY = 150;\n\n  \/*\n   * Return-to-Stage-2 animation.\n   * The same visual language as marker entrance:\n   * pill collapses inward first, then the stage fades away.\n   *\/\n\n  var MARKER_RETURN_DURATION = 180;\n\n  var SETTLE_STABLE_FRAMES = 3;\n  var SETTLE_MAX_MS        = 900;\n\n  \/* =======================================================\n     CATEGORY -> SLOT\n  ======================================================= *\/\n\n  var CATEGORY_TO_SLOT = {\n    bottoms: \"bottom\",\n    tops: \"base\",\n    \"onepiece-sets\": \"onepiece\",\n    outwear: \"jacket\",\n    accessories: \"accessory\",\n    hats: \"hat\"\n  };\n\n  function categoryToSlot(category){\n    return CATEGORY_TO_SLOT[category] || null;\n  }\n\n  function getRealCanvas(){\n    return document.querySelector(\".outfit-canvas\") || document.querySelector(\"#lullaCanvas\") || null;\n  }\n\n  function now(){\n    return (window.performance && performance.now) ? performance.now() : Date.now();\n  }\n\n  \/* =======================================================\n     STATE-3 MODE EVENT\n  ======================================================= *\/\n\n  function dispatchState3Mode(active){\n    document.dispatchEvent(new CustomEvent(\"lulla:state3-mode-change\", {\n      bubbles: true,\n      detail: { active: !!active }\n    }));\n  }\n\n  \/* =======================================================\n     MARKER STATE\n  ======================================================= *\/\n\n  var markerState = {\n    activeProducts: {},\n    confirmedSizes: {}\n  };\n\n  var cartCollapseStarted = false;\n\n  function hydrateMarkerState(){\n    try{\n      if(typeof window.LullaState3GetSizeState === \"function\"){\n        var state = window.LullaState3GetSizeState();\n\n        if(state){\n          markerState.activeProducts = state.activeProducts || {};\n          markerState.confirmedSizes = state.confirmedSizes || {};\n        }\n      }\n    }catch(error){\n      \/* no-op *\/\n    }\n  }\n\n  \/* =======================================================\n     MARKER LIFECYCLE\n  ======================================================= *\/\n\n  var sessionPhase = \"idle\";\n\n  var settleFrame       = null;\n  var settleStableCount = 0;\n  var settleSnapshotKey = null;\n  var settleStartedAt   = 0;\n\n  var trackingFrame = null;\n\n  \/* =======================================================\n     GEOMETRY HELPERS\n  ======================================================= *\/\n\n  function clamp(value, min, max){\n    return Math.max(min, Math.min(max, value));\n  }\n\n  function boxesOverlap(a, b, gap){\n    return !(\n      a.right + gap <= b.left ||\n      a.left >= b.right + gap ||\n      a.bottom + gap <= b.top ||\n      a.top >= b.bottom + gap\n    );\n  }\n\n  function getVisualRect(layer){\n    if(!layer){ return null; }\n\n    var candidates = Array.prototype.slice.call(layer.querySelectorAll(\"img,svg\"));\n    var best = null;\n\n    candidates.forEach(function(node){\n\n      var computed = window.getComputedStyle(node);\n\n      if(\n        computed.display === \"none\" ||\n        computed.visibility === \"hidden\" ||\n        Number(computed.opacity) === 0\n      ){\n        return;\n      }\n\n      var rect = node.getBoundingClientRect();\n\n      if(rect.width <= 0 || rect.height <= 0){\n        return;\n      }\n\n      if(!best){\n        best = rect;\n        return;\n      }\n\n      var area     = rect.width * rect.height;\n      var bestArea = best.width * best.height;\n\n      if(area > bestArea){\n        best = rect;\n      }\n    });\n\n    if(!best){\n\n      var fallback = layer.getBoundingClientRect();\n\n      if(fallback.width <= 0 || fallback.height <= 0){\n        return null;\n      }\n\n      best = fallback;\n    }\n\n    return best;\n  }\n\n  function chooseMarkerPosition(rect, markerWidth, occupied, bounds, preferredSide){\n\n    if(!rect || !bounds){\n      return null;\n    }\n\n    var centerX = rect.left + rect.width * .5;\n    var centerY = rect.top  + rect.height * .5;\n\n    var horizontalOffset = clamp(rect.width * .10, 8, 22);\n    var verticalOffset   = clamp(rect.height * .055, 3, 12);\n\n    var anchors = [\n      { x:centerX - horizontalOffset, y:centerY },\n      { x:centerX + horizontalOffset, y:centerY },\n      { x:centerX - horizontalOffset, y:centerY - verticalOffset },\n      { x:centerX + horizontalOffset, y:centerY - verticalOffset },\n      { x:centerX - horizontalOffset, y:centerY + verticalOffset },\n      { x:centerX + horizontalOffset, y:centerY + verticalOffset }\n    ];\n\n    anchors.forEach(function(anchor){\n\n      anchor.x = clamp(\n        anchor.x,\n        rect.left + rect.width * .18,\n        rect.right - rect.width * .18\n      );\n\n      anchor.y = clamp(\n        anchor.y,\n        rect.top + rect.height * .20,\n        rect.bottom - rect.height * .20\n      );\n    });\n\n    var best      = null;\n    var bestScore = Infinity;\n\n    anchors.forEach(function(anchor){\n\n      [\"left\",\"right\"].forEach(function(side){\n\n        var markerLeft = (side === \"left\")\n          ? anchor.x - markerWidth\n          : anchor.x - (MARKER_DOT_SIZE \/ 2);\n\n        var markerTop    = anchor.y - MARKER_PILL_HEIGHT \/ 2;\n        var markerRight  = markerLeft + markerWidth;\n        var markerBottom = markerTop + MARKER_PILL_HEIGHT;\n\n        var box = {\n          left:markerLeft,\n          top:markerTop,\n          right:markerRight,\n          bottom:markerBottom\n        };\n\n        var overflow = 0;\n\n        if(box.left < bounds.left){\n          overflow += bounds.left - box.left;\n        }\n\n        if(box.right > bounds.right){\n          overflow += box.right - bounds.right;\n        }\n\n        if(box.top < bounds.top){\n          overflow += bounds.top - box.top;\n        }\n\n        if(box.bottom > bounds.bottom){\n          overflow += box.bottom - bounds.bottom;\n        }\n\n        var score = overflow * 10000;\n\n        if(preferredSide && side !== preferredSide){\n          score += 1800;\n        }\n\n        occupied.forEach(function(other){\n\n          if(boxesOverlap(box, other, 8)){\n            score += 8000;\n          }\n\n        });\n\n        var freeSpace = (side === \"left\")\n          ? anchor.x - bounds.left\n          : bounds.right - anchor.x;\n\n        score -= Math.min(freeSpace, 160);\n        score += Math.abs(anchor.y - centerY) * 1.5;\n\n        if(score < bestScore){\n\n          bestScore = score;\n\n          best = {\n            left:markerLeft,\n            top:markerTop,\n            right:markerRight,\n            bottom:markerBottom,\n            anchorX:anchor.x,\n            anchorY:anchor.y,\n            side:side\n          };\n        }\n      });\n    });\n\n    if(!best){\n      return null;\n    }\n\n    var shiftX = 0;\n    var shiftY = 0;\n\n    if(best.left < bounds.left){\n      shiftX = bounds.left - best.left;\n    }\n\n    if(best.right > bounds.right){\n      shiftX = bounds.right - best.right;\n    }\n\n    if(best.top < bounds.top){\n      shiftY = bounds.top - best.top;\n    }\n\n    if(best.bottom > bounds.bottom){\n      shiftY = bounds.bottom - best.bottom;\n    }\n\n    best.left += shiftX;\n    best.right += shiftX;\n    best.top += shiftY;\n    best.bottom += shiftY;\n    best.anchorX += shiftX;\n    best.anchorY += shiftY;\n\n    return best;\n  }\n\n  \/* =======================================================\n     MARKER DOM\n  ======================================================= *\/\n\n  function createMarker(category, slot, confirmed){\n\n    var marker = document.createElement(\"button\");\n\n    marker.type = \"button\";\n    marker.className = \"lulla-s3-marker\";\n    marker.dataset.category = category;\n    marker.dataset.slot = slot;\n    marker.setAttribute(\"aria-label\", \"Add size\");\n\n    var pill = document.createElement(\"span\");\n    pill.className = \"lulla-s3-marker-pill\";\n\n    var label = document.createElement(\"span\");\n    label.className = \"lulla-s3-marker-label\";\n\n    var plus = document.createElement(\"span\");\n    plus.className = \"lulla-s3-marker-plus\";\n    plus.setAttribute(\"aria-hidden\", \"true\");\n\n    var connector = document.createElement(\"span\");\n    connector.className = \"lulla-s3-marker-connector\";\n    connector.setAttribute(\"aria-hidden\", \"true\");\n\n    var dot = document.createElement(\"span\");\n    dot.className = \"lulla-s3-marker-dot\";\n    dot.setAttribute(\"aria-hidden\", \"true\");\n\n    pill.appendChild(label);\n    pill.appendChild(plus);\n\n    marker.appendChild(pill);\n    marker.appendChild(connector);\n    marker.appendChild(dot);\n\n    marker.addEventListener(\"click\", function(event){\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if(sessionPhase === \"removing\"){\n        return;\n      }\n\n      document.dispatchEvent(new CustomEvent(\"lulla:state3-open-item\", {\n        bubbles:true,\n        detail:{\n          category:category,\n          slot:slot\n        }\n      }));\n    });\n\n    \/* =====================================================\n       PRESS FEEDBACK\n    ===================================================== *\/\n\n    function setPressed(pressed){\n\n      if(marker.classList.contains(\"is-removing\")){\n        return;\n      }\n\n      var targetPill = marker.querySelector(\".lulla-s3-marker-pill\");\n\n      if(!targetPill){\n        return;\n      }\n\n      \/*\n       * Immediate centered jelly press.\n       * This runs on pointerdown, so the feedback does not\n       * wait for the click \/ pointerup event.\n       *\/\n      targetPill.style.transformOrigin = \"50% 50%\";\n\n      if(window.gsap){\n\n        window.gsap.killTweensOf(targetPill);\n\n        if(pressed){\n\n          window.gsap.to(targetPill, {\n            scale:0.89,\n            duration:0.075,\n            ease:\"power2.out\",\n            overwrite:\"auto\"\n          });\n\n        }else{\n\n          window.gsap.to(targetPill, {\n            scale:1,\n            duration:0.42,\n            ease:\"elastic.out(1, 0.60)\",\n            overwrite:\"auto\"\n          });\n\n        }\n\n      }else{\n\n        targetPill.style.transition = pressed\n          ? \"transform 75ms ease-out\"\n          : \"transform 420ms cubic-bezier(.22,.61,.36,1)\";\n\n        targetPill.style.transform = pressed\n          ? \"scale(0.89)\"\n          : \"scale(1)\";\n      }\n    }\n\n    function releasePressed(){\n      setPressed(false);\n    }\n\n    marker.addEventListener(\"pointerdown\", function(){\n      setPressed(true);\n    }, {passive:true});\n\n    marker.addEventListener(\"pointerup\", releasePressed);\n    marker.addEventListener(\"pointercancel\", releasePressed);\n    marker.addEventListener(\"pointerleave\", releasePressed);\n    marker.addEventListener(\"lostpointercapture\", releasePressed);\n\n    updateMarkerContent(\n      marker,\n      category,\n      slot,\n      confirmed\n    );\n\n    return marker;\n  }\n\n  function updateMarkerContent(marker, category, slot, confirmed){\n\n    var label = marker.querySelector(\".lulla-s3-marker-label\");\n    var plus  = marker.querySelector(\".lulla-s3-marker-plus\");\n\n    if(confirmed && confirmed.sizeLabel){\n\n      label.textContent = confirmed.sizeLabel;\n      plus.innerHTML =\n        '<img decoding=\"async\" src=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/action-check-checkmark-ok-icon-svgrepo-com.svg\" alt=\"\" aria-hidden=\"true\">';\n\n      marker.classList.add(\"is-confirmed\");\n      marker.setAttribute(\n        \"aria-label\",\n        \"Size \" + confirmed.sizeLabel\n      );\n\n    }else{\n\n      label.textContent = \"ADD SIZE\";\n      plus.textContent = \"+\";\n\n      marker.classList.remove(\"is-confirmed\");\n      marker.setAttribute(\n        \"aria-label\",\n        \"Add size\"\n      );\n    }\n  }\n\n  \/* =======================================================\n     APPLY MARKER GEOMETRY\n  ======================================================= *\/\n\n  function applyMarkerGeometry(marker, position, markerWidth){\n\n    marker.classList.remove(\n      \"side-left\",\n      \"side-right\"\n    );\n\n    marker.classList.add(\n      \"side-\" + position.side\n    );\n\n    marker.style.left   = position.left + \"px\";\n    marker.style.top    = (position.top - 15) + \"px\";\n    marker.style.width  = markerWidth + \"px\";\n    marker.style.height = MARKER_PILL_HEIGHT + \"px\";\n\n    var pill      = marker.querySelector(\".lulla-s3-marker-pill\");\n    var connector = marker.querySelector(\".lulla-s3-marker-connector\");\n    var dot       = marker.querySelector(\".lulla-s3-marker-dot\");\n\n    var anchorLocalX = position.anchorX - position.left;\n    var anchorLocalY = position.anchorY - position.top;\n\n    if(dot){\n\n      dot.style.left = anchorLocalX + \"px\";\n      dot.style.top  = anchorLocalY + \"px\";\n    }\n\n    if(position.side === \"left\"){\n\n      if(pill){\n        pill.style.left = \"0px\";\n      }\n\n      if(connector){\n\n        var leftStart = pill\n          ? pill.getBoundingClientRect().width\n          : (markerWidth - MARKER_LINE_LENGTH - MARKER_DOT_SIZE);\n\n        connector.style.left = leftStart + \"px\";\n        connector.style.width = Math.max(\n          1,\n          anchorLocalX - leftStart\n        ) + \"px\";\n        connector.style.top = anchorLocalY + \"px\";\n      }\n\n    }else{\n\n      if(pill){\n\n        var pillWidth = pill.getBoundingClientRect().width;\n\n        pill.style.left =\n          (markerWidth - pillWidth) + \"px\";\n      }\n\n      if(connector){\n\n        var pillWidth2 = pill\n          ? pill.getBoundingClientRect().width\n          : markerWidth;\n\n        var pillLeft =\n          markerWidth - pillWidth2;\n\n        connector.style.left = anchorLocalX + \"px\";\n        connector.style.width = Math.max(\n          1,\n          pillLeft - anchorLocalX\n        ) + \"px\";\n        connector.style.top = anchorLocalY + \"px\";\n      }\n    }\n  }\n\n  \/* =======================================================\n     MARKER ENTER\n  ======================================================= *\/\n\n  function animateMarkerIn(marker, index){\n\n    var pill = marker.querySelector(\".lulla-s3-marker-pill\");\n    var delay = MARKER_REVEAL_DELAY + index * MARKER_IN_STAGGER;\n\n    marker.style.pointerEvents = \"auto\";\n\n    if(window.gsap){\n\n      window.gsap.killTweensOf(marker);\n\n      if(pill){\n        window.gsap.killTweensOf(pill);\n      }\n\n      window.gsap.set(marker, {\n        autoAlpha:0\n      });\n\n      if(pill){\n\n        window.gsap.set(pill, {\n          scale:0\n        });\n      }\n\n      window.gsap.to(marker, {\n        autoAlpha:1,\n        duration:.13,\n        delay:delay \/ 1000,\n        ease:\"power2.out\",\n        overwrite:\"auto\"\n      });\n\n      if(pill){\n\n        window.gsap.to(pill, {\n          scale:1,\n          duration:MARKER_IN_DURATION \/ 1000,\n          delay:delay \/ 1000,\n          ease:\"back.out(1.65)\",\n          overwrite:\"auto\"\n        });\n      }\n\n    }else{\n\n      marker.style.opacity = \"0\";\n\n      if(pill){\n        pill.style.transform = \"scale(0)\";\n      }\n\n      window.setTimeout(function(){\n\n        marker.style.opacity = \"1\";\n\n        if(pill){\n\n          pill.style.transition =\n            \"transform \" +\n            MARKER_IN_DURATION +\n            \"ms cubic-bezier(.22,.61,.36,1)\";\n\n          pill.style.transform = \"scale(1)\";\n        }\n\n      }, delay);\n    }\n  }\n\n  \/* =======================================================\n     MARKER RETURN TO STAGE 2\n     PILL COLLAPSES FIRST\n  ======================================================= *\/\n\n  function animateMarkersReturn(){\n\n    var markers = Array.prototype.slice.call(\n      markerLayer.querySelectorAll(\".lulla-s3-marker\")\n    );\n\n    if(!markers.length){\n      return Promise.resolve();\n    }\n\n    sessionPhase = \"removing\";\n\n    markers.forEach(function(marker){\n\n      marker.style.pointerEvents = \"none\";\n      marker.classList.add(\"is-removing\");\n\n      var pill = marker.querySelector(\".lulla-s3-marker-pill\");\n\n      if(window.gsap){\n\n        window.gsap.killTweensOf(marker);\n\n        if(pill){\n          window.gsap.killTweensOf(pill);\n        }\n\n        \/*\n         * The marker itself also fades slightly, but the main\n         * visual movement is the pill collapsing inward.\n         *\/\n\n        window.gsap.to(marker, {\n          autoAlpha:0,\n          duration:MARKER_RETURN_DURATION \/ 1000,\n          ease:\"power2.in\",\n          overwrite:\"auto\"\n        });\n\n        if(pill){\n\n          window.gsap.to(pill, {\n            scale:0,\n            duration:MARKER_RETURN_DURATION \/ 1000,\n            ease:\"back.in(1.25)\",\n            overwrite:\"auto\"\n          });\n        }\n\n      }else{\n\n        marker.style.transition =\n          \"opacity \" +\n          MARKER_RETURN_DURATION +\n          \"ms ease\";\n\n        marker.style.opacity = \"0\";\n\n        if(pill){\n\n          pill.style.transition =\n            \"transform \" +\n            MARKER_RETURN_DURATION +\n            \"ms cubic-bezier(.55,0,.85,.18)\";\n\n          pill.style.transform = \"scale(0)\";\n        }\n      }\n    });\n\n    return new Promise(function(resolve){\n\n      window.setTimeout(\n        resolve,\n        MARKER_RETURN_DURATION\n      );\n    });\n  }\n\n  \/* =======================================================\n     VISUAL SNAPSHOT\n  ======================================================= *\/\n\n  function collectVisualState(){\n\n    var canvas = getRealCanvas();\n\n    if(!canvas){\n      return null;\n    }\n\n    var layerRect =\n      markerLayer.getBoundingClientRect();\n\n    if(!layerRect.width || !layerRect.height){\n      return null;\n    }\n\n    var active =\n      markerState.activeProducts || {};\n\n    var categories =\n      Object.keys(active)\n        .filter(function(c){\n          return active[c] && active[c].product;\n        })\n        .sort();\n\n    var rects = {};\n\n    categories.forEach(function(category){\n\n      var slot =\n        categoryToSlot(category);\n\n      if(!slot){\n        return;\n      }\n\n      var layer =\n        canvas.querySelector(\n          '.lulla-canvas-layer[data-slot=\"' +\n          slot +\n          '\"]'\n        );\n\n      if(!layer){\n        return;\n      }\n\n      var computed =\n        window.getComputedStyle(layer);\n\n      if(\n        computed.display === \"none\" ||\n        computed.visibility === \"hidden\" ||\n        Number(computed.opacity) === 0\n      ){\n        return;\n      }\n\n      var visualRect =\n        getVisualRect(layer);\n\n      if(!visualRect){\n        return;\n      }\n\n      rects[category] = {\n\n        left:\n          visualRect.left - layerRect.left,\n\n        top:\n          visualRect.top - layerRect.top,\n\n        right:\n          visualRect.right - layerRect.left,\n\n        bottom:\n          visualRect.bottom - layerRect.top,\n\n        width:\n          visualRect.width,\n\n        height:\n          visualRect.height\n      };\n    });\n\n    return {\n      layerRect:layerRect,\n      categories:categories,\n      rects:rects\n    };\n  }\n\n  function allRectsReady(snap){\n\n    return snap.categories.every(function(c){\n      return !!snap.rects[c];\n    });\n  }\n\n  function snapshotKey(snap){\n\n    var parts = [];\n\n    snap.categories.forEach(function(category){\n\n      var r = snap.rects[category];\n\n      parts.push(\n        r\n          ? category +\n            \":\" +\n            Math.round(r.left) +\n            \",\" +\n            Math.round(r.top) +\n            \",\" +\n            Math.round(r.width) +\n            \",\" +\n            Math.round(r.height)\n          : category + \":pending\"\n      );\n    });\n\n    return parts.join(\"|\");\n  }\n\n  \/* =======================================================\n     SETTLE -> COMMIT -> TRACK\n  ======================================================= *\/\n\n  function cancelSettle(){\n\n    if(settleFrame !== null){\n\n      window.cancelAnimationFrame(\n        settleFrame\n      );\n\n      settleFrame = null;\n    }\n  }\n\n  function cancelTracking(){\n\n    if(trackingFrame !== null){\n\n      window.cancelAnimationFrame(\n        trackingFrame\n      );\n\n      trackingFrame = null;\n    }\n  }\n\n  function requestResettle(){\n\n    cancelTracking();\n    cancelSettle();\n\n    sessionPhase = \"settling\";\n\n    settleStableCount = 0;\n    settleSnapshotKey = null;\n    settleStartedAt   = now();\n\n    settleStep();\n  }\n\n  function settleStep(){\n\n    settleFrame =\n      requestAnimationFrame(settleStep);\n\n    if(\n      visibilityState === \"hidden\" ||\n      visibilityState === \"leaving\"\n    ){\n\n      cancelSettle();\n      return;\n    }\n\n    var snap = collectVisualState();\n\n    var elapsed =\n      now() - settleStartedAt;\n\n    if(!snap){\n\n      if(elapsed > SETTLE_MAX_MS){\n\n        cancelSettle();\n\n        commitMarkers({\n          layerRect:null,\n          categories:[],\n          rects:{}\n        });\n\n        startTracking();\n      }\n\n      return;\n    }\n\n    var ready = allRectsReady(snap);\n    var key   = snapshotKey(snap);\n\n    if(\n      ready &&\n      key === settleSnapshotKey\n    ){\n\n      settleStableCount++;\n\n    }else{\n\n      settleStableCount = 0;\n    }\n\n    settleSnapshotKey = key;\n\n    if(\n      (\n        ready &&\n        settleStableCount >=\n        SETTLE_STABLE_FRAMES\n      ) ||\n      elapsed > SETTLE_MAX_MS\n    ){\n\n      cancelSettle();\n\n      commitMarkers(snap);\n      startTracking();\n    }\n  }\n\n  \/* =======================================================\n     MARKER COMMIT\n  ======================================================= *\/\n\n  function commitMarkers(snap){\n\n    sessionPhase = \"active\";\n\n    markerLayer.innerHTML = \"\";\n\n    if(!snap || !snap.layerRect){\n      return;\n    }\n\n    var confirmed =\n      markerState.confirmedSizes || {};\n\n    var occupied = [];\n    var created  = [];\n\n    var bounds = {\n      left:6,\n      top:6,\n      right:snap.layerRect.width - 6,\n      bottom:snap.layerRect.height - 6\n    };\n\n    snap.categories.forEach(function(category){\n\n      var rect =\n        snap.rects[category];\n\n      if(!rect){\n        return;\n      }\n\n      var slot =\n        categoryToSlot(category);\n\n      if(!slot){\n        return;\n      }\n\n      var marker =\n        createMarker(\n          category,\n          slot,\n          confirmed[category] || null\n        );\n\n      marker.style.visibility = \"hidden\";\n\n      markerLayer.appendChild(marker);\n\n      var pill =\n        marker.querySelector(\n          \".lulla-s3-marker-pill\"\n        );\n\n      var pillWidth =\n        pill\n          ? pill.getBoundingClientRect().width\n          : 88;\n\n      var markerWidth =\n        pillWidth +\n        MARKER_LINE_LENGTH +\n        MARKER_DOT_SIZE;\n\n      var position =\n        chooseMarkerPosition(\n          rect,\n          markerWidth,\n          occupied,\n          bounds,\n          marker.classList.contains(\"side-right\")\n            ? \"right\"\n            : (marker.classList.contains(\"side-left\") ? \"left\" : null)\n        );\n\n      if(!position){\n\n        marker.remove();\n        return;\n      }\n\n      applyMarkerGeometry(\n        marker,\n        position,\n        markerWidth\n      );\n\n      occupied.push({\n        left:position.left,\n        top:position.top,\n        right:position.right,\n        bottom:position.bottom\n      });\n\n      marker.style.visibility = \"visible\";\n\n      created.push(marker);\n    });\n\n    created.forEach(function(marker, index){\n\n      animateMarkerIn(\n        marker,\n        index\n      );\n    });\n  }\n\n  \/* =======================================================\n     TRACKING\n  ======================================================= *\/\n\n  function startTracking(){\n\n    cancelTracking();\n\n    function tick(){\n\n      trackingFrame =\n        requestAnimationFrame(tick);\n\n      if(sessionPhase !== \"active\"){\n        return;\n      }\n\n      if(\n        visibilityState !== \"visible\" &&\n        visibilityState !== \"entering\"\n      ){\n        return;\n      }\n\n      updateActiveMarkers();\n    }\n\n    trackingFrame =\n      requestAnimationFrame(tick);\n  }\n\n  function updateActiveMarkers(){\n\n    var snap =\n      collectVisualState();\n\n    if(!snap){\n      return;\n    }\n\n    var existingMarkers = {};\n\n    Array.prototype.forEach.call(\n      markerLayer.querySelectorAll(\n        \".lulla-s3-marker\"\n      ),\n      function(marker){\n\n        existingMarkers[\n          marker.dataset.category || \"\"\n        ] = marker;\n      }\n    );\n\n    var existingCategories =\n      Object.keys(existingMarkers)\n        .sort();\n\n    var activeCategories =\n      snap.categories\n        .slice()\n        .sort();\n\n    var sameSet =\n      existingCategories.length ===\n      activeCategories.length &&\n      existingCategories.every(function(c, i){\n        return c === activeCategories[i];\n      });\n\n    if(!sameSet){\n\n      beginRemovalTransition();\n      return;\n    }\n\n    var bounds = {\n      left:6,\n      top:6,\n      right:snap.layerRect.width - 6,\n      bottom:snap.layerRect.height - 6\n    };\n\n    var occupied = [];\n\n    activeCategories.forEach(function(category){\n\n      var rect =\n        snap.rects[category];\n\n      var marker =\n        existingMarkers[category];\n\n      if(!rect || !marker){\n        return;\n      }\n\n      var pill =\n        marker.querySelector(\n          \".lulla-s3-marker-pill\"\n        );\n\n      var pillWidth =\n        pill\n          ? pill.getBoundingClientRect().width\n          : 88;\n\n      var markerWidth =\n        pillWidth +\n        MARKER_LINE_LENGTH +\n        MARKER_DOT_SIZE;\n\n      var position =\n        chooseMarkerPosition(\n          rect,\n          markerWidth,\n          occupied,\n          bounds,\n          marker.classList.contains(\"side-right\")\n            ? \"right\"\n            : (marker.classList.contains(\"side-left\") ? \"left\" : null)\n        );\n\n      if(!position){\n        return;\n      }\n\n      applyMarkerGeometry(\n        marker,\n        position,\n        markerWidth\n      );\n\n      occupied.push({\n        left:position.left,\n        top:position.top,\n        right:position.right,\n        bottom:position.bottom\n      });\n    });\n  }\n\n  \/* =======================================================\n     PRODUCT CHANGED\n  ======================================================= *\/\n\n  function beginRemovalTransition(){\n\n    if(sessionPhase === \"removing\"){\n      return;\n    }\n\n    sessionPhase = \"removing\";\n\n    cancelTracking();\n\n    var markers =\n      Array.prototype.slice.call(\n        markerLayer.querySelectorAll(\n          \".lulla-s3-marker\"\n        )\n      );\n\n    if(!markers.length){\n\n      markerLayer.innerHTML = \"\";\n\n      requestResettle();\n      return;\n    }\n\n    var remaining =\n      markers.length;\n\n    function done(){\n\n      remaining--;\n\n      if(remaining <= 0){\n\n        markerLayer.innerHTML = \"\";\n\n        requestResettle();\n      }\n    }\n\n    markers.forEach(function(marker){\n\n      marker.style.pointerEvents = \"none\";\n\n      marker.classList.add(\"is-removing\");\n\n      var pill =\n        marker.querySelector(\n          \".lulla-s3-marker-pill\"\n        );\n\n      if(window.gsap){\n\n        window.gsap.killTweensOf(marker);\n\n        if(pill){\n          window.gsap.killTweensOf(pill);\n        }\n\n        window.gsap.to(marker, {\n          autoAlpha:0,\n          duration:MARKER_OUT_DURATION \/ 1000,\n          ease:\"power3.in\",\n          overwrite:\"auto\",\n          onComplete:done\n        });\n\n        if(pill){\n\n          window.gsap.to(pill, {\n            scale:0,\n            duration:MARKER_OUT_DURATION \/ 1000,\n            ease:\"power3.in\",\n            overwrite:\"auto\"\n          });\n        }\n\n      }else{\n\n        marker.style.transition =\n          \"opacity \" +\n          MARKER_OUT_DURATION +\n          \"ms ease\";\n\n        marker.style.opacity = \"0\";\n\n        if(pill){\n\n          pill.style.transition =\n            \"transform \" +\n            MARKER_OUT_DURATION +\n            \"ms ease\";\n\n          pill.style.transform = \"scale(0)\";\n        }\n\n        window.setTimeout(\n          done,\n          MARKER_OUT_DURATION\n        );\n      }\n    });\n  }\n\n  \/* =======================================================\n     SIZE STATE SYNC\n  ======================================================= *\/\n\n  function syncMarkerSizeState(state){\n\n    state = state || {};\n\n    var nextActive =\n      state.activeProducts || {};\n\n    var nextConfirmed =\n      state.confirmedSizes || {};\n\n    var previousActive =\n      markerState.activeProducts || {};\n\n    var categoriesChanged = false;\n\n    var allCats = {};\n\n    Object.keys(previousActive)\n      .forEach(function(c){\n        allCats[c] = true;\n      });\n\n    Object.keys(nextActive)\n      .forEach(function(c){\n        allCats[c] = true;\n      });\n\n    Object.keys(allCats)\n      .forEach(function(category){\n\n        var was =\n          previousActive[category] &&\n          previousActive[category].product;\n\n        var is =\n          nextActive[category] &&\n          nextActive[category].product;\n\n        if(!!was !== !!is){\n\n          categoriesChanged = true;\n        }\n      });\n\n    markerState.activeProducts =\n      nextActive;\n\n    markerState.confirmedSizes =\n      nextConfirmed;\n\n    preloadActiveProductGalleries(\n      markerState.activeProducts\n    );\n\n    if(\n      visibilityState === \"hidden\"\n    ){\n      return;\n    }\n\n    if(categoriesChanged){\n\n      if(sessionPhase === \"active\"){\n\n        beginRemovalTransition();\n\n      }else{\n\n        requestResettle();\n      }\n\n      return;\n    }\n\n    var confirmed =\n      markerState.confirmedSizes || {};\n\n    Array.prototype.forEach.call(\n      markerLayer.querySelectorAll(\n        \".lulla-s3-marker\"\n      ),\n      function(marker){\n\n        updateMarkerContent(\n          marker,\n          marker.dataset.category,\n          marker.dataset.slot,\n          confirmed[\n            marker.dataset.category\n          ] || null\n        );\n      }\n    );\n  }\n\n  document.addEventListener(\n    \"lulla:size-state-change\",\n    function(event){\n\n      syncMarkerSizeState(\n        event ? event.detail : null\n      );\n    }\n  );\n\n  window.LullaState3SetSizeState =\n    function(\n      activeProducts,\n      confirmedSizes\n    ){\n\n      syncMarkerSizeState({\n        activeProducts:\n          activeProducts || {},\n\n        confirmedSizes:\n          confirmedSizes || {}\n      });\n    };\n\n  window.LullaState3GetSizeState =\n    function(){\n\n      return {\n        activeProducts:\n          markerState.activeProducts || {},\n\n        confirmedSizes:\n          markerState.confirmedSizes || {}\n      };\n    };\n\n  \/* =======================================================\n     SHOW PANEL\n  ======================================================= *\/\n\n  function showPanel(){\n\n    cartCollapseStarted = false;\n\n    if(panelHideTimer){\n      window.clearTimeout(panelHideTimer);\n      panelHideTimer = null;\n    }\n\n    root.classList.remove(\n      \"is-leaving\",\n      \"is-returning\"\n    );\n\n    if(\n      visibilityState === \"visible\" ||\n      visibilityState === \"entering\"\n    ){\n\n      hydrateMarkerState();\n\n      dispatchState3Mode(true);\n\n      requestResettle();\n\n      return;\n    }\n\n    root.classList.add(\n      \"is-entering\"\n    );\n\n    root.setAttribute(\n      \"aria-hidden\",\n      \"false\"\n    );\n\n    visibilityState =\n      \"entering\";\n\n    dispatchState3Mode(true);\n\n    hydrateMarkerState();\n\n    requestResettle();\n\n    requestAnimationFrame(function(){\n\n      requestAnimationFrame(function(){\n\n        if(\n          visibilityState !==\n          \"entering\"\n        ){\n          return;\n        }\n\n        root.classList.remove(\n          \"is-entering\"\n        );\n\n        root.classList.add(\n          \"is-visible\"\n        );\n\n        visibilityState =\n          \"visible\";\n      });\n    });\n  }\n\n  \/* =======================================================\n     HIDE PANEL\n     MARKERS SHRINK BEFORE PANEL FADES\n  ======================================================= *\/\n\n  async function hidePanel(){\n\n    if(panelHideTimer){\n      window.clearTimeout(panelHideTimer);\n      panelHideTimer = null;\n    }\n\n    cancelSettle();\n    cancelTracking();\n\n    sessionPhase = \"removing\";\n\n    if(\n      root.contains(document.activeElement) &&\n      document.activeElement &&\n      typeof document.activeElement.blur === \"function\"\n    ){\n\n      document.activeElement.blur();\n    }\n\n    if(\n      visibilityState === \"hidden\"\n    ){\n\n      dispatchState3Mode(false);\n\n      clearGalleryImmediate();\n\n      markerLayer.innerHTML = \"\";\n\n      return;\n    }\n\n    \/*\n     * Keep Stage 3 visible for the marker collapse.\n     * We do NOT fade the whole root yet.\n     *\/\n\n    root.classList.remove(\n      \"is-entering\",\n      \"is-visible\",\n      \"is-leaving\"\n    );\n\n    root.classList.add(\n      \"is-returning\"\n    );\n\n    root.setAttribute(\n      \"aria-hidden\",\n      \"true\"\n    );\n\n    visibilityState =\n      \"leaving\";\n\n    dispatchState3Mode(false);\n\n    \/*\n     * Gallery closes independently while the markers\n     * perform their shrink-to-zero animation.\n     *\/\n\n    clearGallery();\n\n    await animateMarkersReturn();\n\n    \/*\n     * Now fade the entire Stage 3 away.\n     *\/\n\n    if(\n      visibilityState !== \"leaving\"\n    ){\n      return;\n    }\n\n    root.classList.remove(\n      \"is-returning\"\n    );\n\n    root.classList.add(\n      \"is-leaving\"\n    );\n\n    panelHideTimer =\n      window.setTimeout(function(){\n\n        panelHideTimer = null;\n\n        root.classList.remove(\n          \"is-leaving\"\n        );\n\n        visibilityState =\n          \"hidden\";\n\n        markerLayer.innerHTML = \"\";\n\n        sessionPhase =\n          \"idle\";\n\n      }, 320);\n  }\n\n  window.LullaShowItemInfoPanel =\n    showPanel;\n\n  window.LullaHideItemInfoPanel =\n    hidePanel;\n\n  \/* =======================================================\n     PRODUCT DETAILS\n  ======================================================= *\/\n\n  function fetchItemDetails(productId){\n\n    if(!productId){\n      return Promise.resolve({});\n    }\n\n    if(detailsCache[productId]){\n      return Promise.resolve(\n        detailsCache[productId]\n      );\n    }\n\n    if(detailsPending[productId]){\n      return detailsPending[productId];\n    }\n\n    detailsPending[productId] =\n      fetch(\n        \"\/wp-json\/lulla\/v1\/mixmatch-item\/\" +\n        productId,\n        {\n          credentials:\"same-origin\"\n        }\n      )\n      .then(function(response){\n\n        if(!response.ok){\n          throw new Error(\n            \"Product details unavailable.\"\n          );\n        }\n\n        return response.json();\n      })\n      .then(function(data){\n\n        data = data || {};\n\n        detailsCache[productId] =\n          data;\n\n        return data;\n      })\n      .catch(function(){\n\n        return {};\n      })\n      .finally(function(){\n\n        delete detailsPending[productId];\n      });\n\n    return detailsPending[productId];\n  }\n\n  \/* =======================================================\n     PHOTOS\n  ======================================================= *\/\n\n  function uniquePhotos(list){\n\n    var result = [];\n\n    if(!Array.isArray(list)){\n      return result;\n    }\n\n    list.forEach(function(url){\n\n      if(!url){\n        return;\n      }\n\n      var clean =\n        String(url).trim();\n\n      if(\n        clean &&\n        result.indexOf(clean) === -1\n      ){\n\n        result.push(clean);\n      }\n    });\n\n    return result;\n  }\n\n  \/*\n   * IMPORTANT:\n   * Wait for BOTH:\n   * 1. network\/browser image load\n   * 2. image decode\n   *\n   * This prevents the exact \"blink \/ flash \/ sudden pop\"\n   * that was happening when the DOM appeared before the\n   * browser had decoded the first frame.\n   *\/\n\n  function preloadImage(url){\n\n    if(!url){\n      return Promise.resolve();\n    }\n\n    return new Promise(function(resolve){\n\n      var image = new Image();\n\n      var finished = false;\n\n      function done(){\n\n        if(finished){\n          return;\n        }\n\n        finished = true;\n\n        if(\n          typeof image.decode === \"function\"\n        ){\n\n          image.decode()\n            .catch(function(){})\n            .finally(function(){\n\n              resolve();\n            });\n\n        }else{\n\n          resolve();\n        }\n      }\n\n      image.onload = done;\n      image.onerror = done;\n\n      image.src = url;\n\n      \/*\n       * Cached images can sometimes already be complete\n       * before onload is attached.\n       *\/\n\n      if(image.complete){\n        done();\n      }\n    });\n  }\n\n  \/*\n   * Only place the product into photosCache AFTER the\n   * first photo has finished loading + decoding.\n   *\n   * That means:\n   * cached === guaranteed-ready-first-image.\n   *\/\n\n  function preloadProductGallery(product){\n\n    if(!product){\n      return Promise.resolve([]);\n    }\n\n    var productId =\n      product.productId ||\n      product.id;\n\n    if(!productId){\n      return Promise.resolve([]);\n    }\n\n    if(photosCache[productId]){\n\n      return Promise.resolve(\n        photosCache[productId]\n      );\n    }\n\n    if(photosPending[productId]){\n\n      return photosPending[productId];\n    }\n\n    photosPending[productId] =\n      fetchItemDetails(productId)\n      .then(function(details){\n\n        var photos =\n          uniquePhotos(\n            details.photos || []\n          );\n\n        if(!photos.length){\n\n          photosCache[productId] = [];\n\n          return [];\n        }\n\n        \/*\n         * FIRST IMAGE IS THE GATE.\n         * The gallery is not revealed before this resolves.\n         *\/\n\n        return preloadImage(\n          photos[0]\n        )\n        .then(function(){\n\n          photosCache[productId] =\n            photos;\n\n          \/*\n           * Warm up a couple of additional slides in the\n           * background. They do NOT block the first reveal.\n           *\/\n\n          photos.slice(1, 3)\n            .forEach(function(url){\n\n              preloadImage(url);\n            });\n\n          return photos;\n        });\n      })\n      .catch(function(){\n\n        photosCache[productId] = [];\n\n        return [];\n      })\n      .finally(function(){\n\n        delete photosPending[productId];\n      });\n\n    return photosPending[productId];\n  }\n\n  function preloadActiveProductGalleries(products){\n\n    if(!products){\n      return;\n    }\n\n    Object.keys(products)\n      .forEach(function(category){\n\n        var entry =\n          products[category];\n\n        if(\n          !entry ||\n          !entry.product\n        ){\n          return;\n        }\n\n        preloadProductGallery(\n          entry.product\n        );\n      });\n  }\n\n  \/* =======================================================\n     GALLERY RENDER\n  ======================================================= *\/\n\n  function applyGalleryContent(photos){\n\n    currentPhotos =\n      uniquePhotos(photos);\n\n    currentIndex = 0;\n\n    track.innerHTML = \"\";\n    dots.innerHTML = \"\";\n\n    currentPhotos.forEach(function(url, index){\n\n      var slide =\n        document.createElement(\"div\");\n\n      slide.className =\n        \"lulla-item-gallery-slide\";\n\n      var image =\n        document.createElement(\"img\");\n\n      image.src = url;\n      image.alt = \"\";\n      image.draggable = false;\n\n      \/*\n       * Decoding hint to browser.\n       *\/\n\n      image.decoding = \"async\";\n\n      if(index === 0){\n        image.setAttribute(\n          \"fetchpriority\",\n          \"high\"\n        );\n      }\n\n      slide.appendChild(image);\n      track.appendChild(slide);\n\n      var dot =\n        document.createElement(\"button\");\n\n      dot.type = \"button\";\n\n      dot.className =\n        \"lulla-item-gallery-dot\";\n\n      dot.setAttribute(\n        \"aria-label\",\n        \"Image \" + (index + 1)\n      );\n\n      if(index === 0){\n        dot.classList.add(\n          \"is-active\"\n        );\n      }\n\n      dot.addEventListener(\n        \"click\",\n        function(event){\n\n          event.preventDefault();\n          event.stopPropagation();\n\n          goToSlide(index);\n        }\n      );\n\n      dots.appendChild(dot);\n    });\n\n    track.style.transition =\n      \"none\";\n\n    track.style.transform =\n      \"translate3d(0,0,0)\";\n\n    \/*\n     * Do not reveal yet.\n     * The caller decides when this gallery is ready.\n     *\/\n\n    galleryMain.classList.remove(\n      \"is-ready\"\n    );\n\n    galleryMain.style.visibility =\n      \"hidden\";\n\n    galleryMain.style.opacity =\n      \"0\";\n\n    updateSlider();\n  }\n\n  function revealGallery(token){\n\n    if(token !== requestToken){\n      return;\n    }\n\n    if(!currentPhotos.length){\n      return;\n    }\n\n    galleryMain.classList.add(\n      \"is-ready\"\n    );\n\n    galleryMain.style.visibility =\n      \"visible\";\n\n    galleryMain.style.pointerEvents =\n      \"auto\";\n\n    galleryMain.style.setProperty(\n      \"transition\",\n      \"opacity \" +\n      GALLERY_FADE_IN +\n      \"ms cubic-bezier(.22,.61,.36,1)\",\n      \"important\"\n    );\n\n    \/*\n     * Two RAFs guarantee that the browser paints the\n     * prepared hidden frame before the fade begins.\n     *\/\n\n    requestAnimationFrame(function(){\n\n      requestAnimationFrame(function(){\n\n        if(token !== requestToken){\n          return;\n        }\n\n        galleryMain.style.opacity =\n          \"1\";\n      });\n    });\n  }\n\n  \/* =======================================================\n     OPEN GALLERY\n  ======================================================= *\/\n\n  window.LullaRenderItemInfo =\n    function(product){\n\n      if(!product){\n        return;\n      }\n\n      if(galleryClearTimer){\n\n        window.clearTimeout(\n          galleryClearTimer\n        );\n\n        galleryClearTimer = null;\n      }\n\n      var token =\n        ++requestToken;\n\n      currentProduct =\n        product;\n\n      root.classList.add(\n        \"is-gallery-open\"\n      );\n\n      gallery.setAttribute(\n        \"aria-hidden\",\n        \"false\"\n      );\n\n      \/*\n       * IMPORTANT:\n       * Do not instantly render cached content by itself.\n       *\n       * preloadProductGallery() now guarantees that the first\n       * image is already loaded + decoded before this point.\n       *\/\n\n      preloadProductGallery(product)\n        .then(function(photos){\n\n          if(token !== requestToken){\n            return;\n          }\n\n          if(currentProduct !== product){\n            return;\n          }\n\n          photos =\n            uniquePhotos(photos);\n\n          if(!photos.length){\n\n            root.classList.remove(\n              \"is-gallery-open\"\n            );\n\n            gallery.setAttribute(\n              \"aria-hidden\",\n              \"true\"\n            );\n\n            galleryMain.classList.remove(\n              \"is-ready\"\n            );\n\n            galleryMain.style.opacity =\n              \"0\";\n\n            galleryMain.style.visibility =\n              \"hidden\";\n\n            prevButton.hidden = true;\n            nextButton.hidden = true;\n\n            return;\n          }\n\n          var wasReady =\n            galleryMain.classList.contains(\n              \"is-ready\"\n            );\n\n          var samePhotos =\n            currentPhotos.join(\"|\") ===\n            photos.join(\"|\");\n\n          \/*\n           * Same gallery already visible.\n           * Absolutely nothing should blink.\n           *\/\n\n          if(\n            wasReady &&\n            samePhotos\n          ){\n\n            galleryMain.style.opacity =\n              \"1\";\n\n            galleryMain.style.visibility =\n              \"visible\";\n\n            return;\n          }\n\n          \/*\n           * Switching from one product\/gallery to another.\n           * Old gallery fades away first.\n           *\/\n\n          if(wasReady){\n\n            galleryMain.style.setProperty(\n              \"transition\",\n              \"opacity \" +\n              GALLERY_FADE_OUT +\n              \"ms cubic-bezier(.22,.61,.36,1)\",\n              \"important\"\n            );\n\n            galleryMain.style.opacity =\n              \"0\";\n\n            window.setTimeout(function(){\n\n              if(token !== requestToken){\n                return;\n              }\n\n              applyGalleryContent(\n                photos\n              );\n\n              revealGallery(\n                token\n              );\n\n            }, GALLERY_FADE_OUT);\n\n            return;\n          }\n\n          \/*\n           * First open.\n           * Content is already decoded by this point.\n           *\/\n\n          applyGalleryContent(\n            photos\n          );\n\n          revealGallery(\n            token\n          );\n\n        });\n    };\n\n  \/* =======================================================\n     CLEAR GALLERY\n  ======================================================= *\/\n\n  function clearGallery(){\n\n    if(galleryClearTimer){\n\n      window.clearTimeout(\n        galleryClearTimer\n      );\n\n      galleryClearTimer = null;\n    }\n\n    var token =\n      ++requestToken;\n\n    currentProduct = null;\n\n    root.classList.remove(\n      \"is-gallery-open\"\n    );\n\n    gallery.setAttribute(\n      \"aria-hidden\",\n      \"true\"\n    );\n\n    if(!currentPhotos.length){\n\n      clearGalleryImmediate();\n\n      return;\n    }\n\n    galleryMain.style.setProperty(\n      \"transition\",\n      \"opacity \" +\n      GALLERY_CLOSE_FADE +\n      \"ms cubic-bezier(.22,.61,.36,1)\",\n      \"important\"\n    );\n\n    galleryMain.style.opacity =\n      \"0\";\n\n    galleryClearTimer =\n      window.setTimeout(function(){\n\n        galleryClearTimer = null;\n\n        if(token !== requestToken){\n          return;\n        }\n\n        currentPhotos = [];\n        currentIndex  = 0;\n\n        track.innerHTML = \"\";\n        dots.innerHTML  = \"\";\n\n        galleryMain.classList.remove(\n          \"is-ready\"\n        );\n\n        galleryMain.style.setProperty(\n          \"transition\",\n          \"none\",\n          \"important\"\n        );\n\n        galleryMain.style.opacity =\n          \"0\";\n\n        galleryMain.style.visibility =\n          \"hidden\";\n\n        galleryMain.style.pointerEvents =\n          \"none\";\n\n        prevButton.hidden = true;\n        nextButton.hidden = true;\n\n      }, GALLERY_CLOSE_FADE);\n  }\n\n  function clearGalleryImmediate(){\n\n    if(galleryClearTimer){\n\n      window.clearTimeout(\n        galleryClearTimer\n      );\n\n      galleryClearTimer = null;\n    }\n\n    requestToken++;\n\n    currentProduct = null;\n    currentPhotos  = [];\n    currentIndex   = 0;\n\n    if(track){\n      track.innerHTML = \"\";\n    }\n\n    if(dots){\n      dots.innerHTML = \"\";\n    }\n\n    if(galleryMain){\n\n      galleryMain.classList.remove(\n        \"is-ready\"\n      );\n\n      galleryMain.style.setProperty(\n        \"transition\",\n        \"none\",\n        \"important\"\n      );\n\n      galleryMain.style.opacity =\n        \"0\";\n\n      galleryMain.style.visibility =\n        \"hidden\";\n\n      galleryMain.style.pointerEvents =\n        \"none\";\n    }\n\n    if(prevButton){\n      prevButton.hidden = true;\n    }\n\n    if(nextButton){\n      nextButton.hidden = true;\n    }\n\n    root.classList.remove(\n      \"is-gallery-open\"\n    );\n\n    gallery.setAttribute(\n      \"aria-hidden\",\n      \"true\"\n    );\n  }\n\n  window.LullaClearItemInfo =\n    clearGallery;\n\n  \/* =======================================================\n     SLIDER\n  ======================================================= *\/\n\n  function updateSlider(){\n\n    if(!currentPhotos.length){\n\n      prevButton.hidden = true;\n      nextButton.hidden = true;\n\n      return;\n    }\n\n    track.style.transform =\n      \"translate3d(-\" +\n      (currentIndex * 100) +\n      \"%,0,0)\";\n\n    dots.querySelectorAll(\n      \".lulla-item-gallery-dot\"\n    ).forEach(function(dot, index){\n\n      dot.classList.toggle(\n        \"is-active\",\n        index === currentIndex\n      );\n    });\n\n    var multiple =\n      currentPhotos.length > 1;\n\n    prevButton.hidden =\n      !multiple;\n\n    nextButton.hidden =\n      !multiple;\n  }\n\n  function goToSlide(index){\n\n    if(currentPhotos.length < 2){\n      return;\n    }\n\n    if(index < 0){\n      index =\n        currentPhotos.length - 1;\n    }\n\n    if(index >= currentPhotos.length){\n      index = 0;\n    }\n\n    currentIndex = index;\n\n    track.style.transition =\n      \"transform .50s cubic-bezier(.22,.61,.36,1)\";\n\n    updateSlider();\n  }\n\n  function nextSlide(){\n    goToSlide(\n      currentIndex + 1\n    );\n  }\n\n  function previousSlide(){\n    goToSlide(\n      currentIndex - 1\n    );\n  }\n\n  \/* =======================================================\n     SIZE GUIDE\n  ======================================================= *\/\n\n  window.LullaOpenSizeGuide =\n    function(url){\n\n      if(\n        !url ||\n        !sizeGuideModal ||\n        !sizeGuideImg\n      ){\n        return;\n      }\n\n      sizeGuideImg.src =\n        url;\n\n      sizeGuideModal.hidden =\n        false;\n\n      requestAnimationFrame(function(){\n\n        sizeGuideModal.classList.add(\n          \"is-visible\"\n        );\n      });\n    };\n\n  function closeSizeGuide(){\n\n    if(!sizeGuideModal){\n      return;\n    }\n\n    sizeGuideModal.classList.remove(\n      \"is-visible\"\n    );\n\n    window.setTimeout(function(){\n\n      sizeGuideModal.hidden =\n        true;\n\n      if(sizeGuideImg){\n        sizeGuideImg.src = \"\";\n      }\n\n    }, 220);\n  }\n\n  if(sizeGuideClose){\n\n    sizeGuideClose.addEventListener(\n      \"click\",\n      function(event){\n\n        event.preventDefault();\n        event.stopPropagation();\n\n        closeSizeGuide();\n      }\n    );\n  }\n\n  if(sizeGuideBackdrop){\n\n    sizeGuideBackdrop.addEventListener(\n      \"click\",\n      function(){\n\n        closeSizeGuide();\n      }\n    );\n  }\n\n  \/* =======================================================\n     GALLERY SWIPE\n  ======================================================= *\/\n\n  var galleryPointerId = null;\n  var galleryStartX = 0;\n  var galleryStartY = 0;\n  var galleryStartTime = 0;\n\n  if(galleryMain){\n\n    galleryMain.addEventListener(\n      \"pointerdown\",\n      function(event){\n\n        if(\n          event.pointerType === \"mouse\" ||\n          currentPhotos.length < 2\n        ){\n          return;\n        }\n\n        galleryPointerId =\n          event.pointerId;\n\n        galleryStartX =\n          event.clientX;\n\n        galleryStartY =\n          event.clientY;\n\n        galleryStartTime =\n          Date.now();\n\n        if(\n          typeof galleryMain.setPointerCapture ===\n          \"function\"\n        ){\n          try{\n            galleryMain.setPointerCapture(\n              galleryPointerId\n            );\n          }catch(error){}\n        }\n      },\n      {passive:true}\n    );\n\n    galleryMain.addEventListener(\n      \"pointerup\",\n      function(event){\n\n        if(\n          galleryPointerId === null ||\n          event.pointerId !== galleryPointerId\n        ){\n          return;\n        }\n\n        var dx =\n          event.clientX -\n          galleryStartX;\n\n        var dy =\n          event.clientY -\n          galleryStartY;\n\n        var elapsed =\n          Math.max(\n            1,\n            Date.now() -\n            galleryStartTime\n          );\n\n        galleryPointerId = null;\n\n        if(\n          Math.abs(dx) >= 36 &&\n          Math.abs(dx) > Math.abs(dy) * 1.15 &&\n          elapsed <= 700 &&\n          currentPhotos.length > 1\n        ){\n          if(dx < 0){\n            nextSlide();\n          }else{\n            previousSlide();\n          }\n\n          event.preventDefault();\n          event.stopPropagation();\n        }\n      },\n      {passive:false}\n    );\n\n    galleryMain.addEventListener(\n      \"pointercancel\",\n      function(event){\n\n        if(\n          galleryPointerId ===\n          event.pointerId\n        ){\n          galleryPointerId = null;\n        }\n      },\n      {passive:true}\n    );\n  }\n\n  \/* =======================================================\n     GALLERY CLOSE\n  ======================================================= *\/\n\n  function closeGalleryAndCard(){\n\n    \/*\n     * Clear the gallery immediately so the left-side visual\n     * disappears with the existing gallery fade.\n     *\/\n    clearGallery();\n\n    \/*\n     * Let State 3 use its existing card-close logic.\n     * We deliberately click the active size-card toggle instead\n     * of inventing a second close-card event.\n     *\/\n    var activeCard =\n      document.querySelector(\n        \".lulla-size-card.is-active\"\n      );\n\n    var activeToggle =\n      activeCard\n        ? activeCard.querySelector(\n            \".lulla-size-card-toggle\"\n          )\n        : null;\n\n    if(activeToggle){\n      activeToggle.click();\n    }\n  }\n\n  if(closeButton){\n\n    closeButton.addEventListener(\n      \"click\",\n      function(event){\n\n        event.preventDefault();\n        event.stopPropagation();\n\n        closeGalleryAndCard();\n      }\n    );\n  }\n\n  \/* =======================================================\n     GALLERY NAV\n  ======================================================= *\/\n\n  if(prevButton){\n\n    prevButton.addEventListener(\n      \"click\",\n      function(event){\n\n        event.preventDefault();\n        event.stopPropagation();\n\n        previousSlide();\n      }\n    );\n  }\n\n  if(nextButton){\n\n    nextButton.addEventListener(\n      \"click\",\n      function(event){\n\n        event.preventDefault();\n        event.stopPropagation();\n\n        nextSlide();\n      }\n    );\n  }\n\n  \/* =======================================================\n     PANEL EVENTS\n  ======================================================= *\/\n\n  document.addEventListener(\n    \"lulla:choose-size\",\n    function(){\n\n      showPanel();\n    }\n  );\n\n  document.addEventListener(\n    \"lulla:size-screen-close\",\n    function(){\n\n      hidePanel();\n    }\n  );\n\n  \/* =======================================================\n     ADD TO CART \u2014 COLLAPSE CONFIRMED SIZE BUBBLES\n  ======================================================= *\/\n\n  function hideMarkersAfterCart(){\n\n    if(\n      cartCollapseStarted ||\n      !markerLayer ||\n      visibilityState === \"hidden\" ||\n      visibilityState === \"leaving\"\n    ){\n      return;\n    }\n\n    var markers =\n      Array.prototype.slice.call(\n        markerLayer.querySelectorAll(\n          \".lulla-s3-marker\"\n        )\n      );\n\n    if(!markers.length){\n      return;\n    }\n\n    cartCollapseStarted = true;\n    cancelSettle();\n    cancelTracking();\n\n    sessionPhase = \"removing\";\n\n    markers.forEach(function(marker){\n\n      marker.style.pointerEvents = \"none\";\n      marker.classList.add(\"is-removing\");\n\n      var pill =\n        marker.querySelector(\n          \".lulla-s3-marker-pill\"\n        );\n\n      if(window.gsap){\n\n        window.gsap.killTweensOf(marker);\n\n        if(pill){\n          window.gsap.killTweensOf(pill);\n          window.gsap.set(pill,{\n            transformOrigin:\"50% 50%\"\n          });\n        }\n\n        window.gsap.to(marker,{\n          autoAlpha:0,\n          duration:MARKER_RETURN_DURATION \/ 1000,\n          ease:\"power2.in\",\n          overwrite:\"auto\"\n        });\n\n        if(pill){\n\n          window.gsap.to(pill,{\n            scale:0,\n            duration:MARKER_RETURN_DURATION \/ 1000,\n            ease:\"back.in(1.25)\",\n            overwrite:\"auto\"\n          });\n\n        }\n\n      }else{\n\n        marker.style.transition =\n          \"opacity \" +\n          MARKER_RETURN_DURATION +\n          \"ms ease\";\n\n        marker.style.opacity = \"0\";\n\n        if(pill){\n\n          pill.style.transition =\n            \"transform \" +\n            MARKER_RETURN_DURATION +\n            \"ms cubic-bezier(.55,0,.85,.18)\";\n\n          pill.style.transformOrigin = \"50% 50%\";\n          pill.style.transform = \"scale(0)\";\n        }\n\n      }\n\n    });\n\n    window.setTimeout(function(){\n\n      markerLayer.innerHTML = \"\";\n\n      sessionPhase = \"idle\";\n      cartCollapseStarted = false;\n\n    }, MARKER_RETURN_DURATION + 30);\n  }\n\n\n  \/*\n   * Event delegation means this also works when the\n   * ADD TO CART button is rendered dynamically.\n   *\/\n  document.addEventListener(\n    \"click\",\n    function(event){\n\n      var button =\n        event.target &&\n        event.target.closest\n          ? event.target.closest(\"button,a\")\n          : null;\n\n      if(!button){\n        return;\n      }\n\n      var text =\n        (button.textContent || \"\")\n          .replace(\/\\s+\/g,\" \")\n          .trim()\n          .toUpperCase();\n\n      if(\n        text === \"ADD TO CART\" ||\n        text.indexOf(\"ADD TO CART\") !== -1\n      ){\n\n        hideMarkersAfterCart();\n\n      }\n\n    },\n    true\n  );\n\n\n  \/*\n   * WooCommerce AJAX success backup.\n   *\/\n  if(typeof jQuery !== \"undefined\"){\n\n    jQuery(document.body).on(\n      \"added_to_cart\",\n      function(){\n\n        hideMarkersAfterCart();\n\n      }\n    );\n\n  }\n\n  \/* =======================================================\n     INITIAL STATE\n  ======================================================= *\/\n\n  root.setAttribute(\n    \"aria-hidden\",\n    \"true\"\n  );\n\n  root.classList.remove(\n    \"is-gallery-open\",\n    \"is-entering\",\n    \"is-visible\",\n    \"is-leaving\",\n    \"is-returning\"\n  );\n\n  gallery.setAttribute(\n    \"aria-hidden\",\n    \"true\"\n  );\n\n  galleryMain.classList.remove(\n    \"is-ready\"\n  );\n\n  galleryMain.style.setProperty(\n    \"transition\",\n    \"none\",\n    \"important\"\n  );\n\n  galleryMain.style.opacity =\n    \"0\";\n\n  galleryMain.style.visibility =\n    \"hidden\";\n\n  galleryMain.style.pointerEvents =\n    \"none\";\n\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30b0809 lulla-state1-host elementor-widget elementor-widget-html\" data-id=\"30b0809\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\n=========================================================\nLULLA \u2014 STATE 1 \/ INTRO OVERLAY\n=========================================================\n\nELEMENTOR LOCATION:\n\nOUTFIT PANEL\n\u251c\u2500\u2500 OUTFIT HEADER\n\u251c\u2500\u2500 CANVAS AREA\n\u251c\u2500\u2500 OUTFIT FOOTER\n\u251c\u2500\u2500 OUTFIT INFO PANEL\n\u2514\u2500\u2500 THIS HTML  \u2190 STATE 1\n\nSTATE 1 reacts only to:\n\nlulla:gender-change  \u2192 hide\nlulla:setup-change   \u2192 show\nlulla:setup-back     \u2192 show\n=========================================================\n-->\n\n<div\n  class=\"lulla-state1\"\n  aria-hidden=\"false\"\n>\n\n  <!-- =====================================================\n       CENTRAL LOOK\n       ===================================================== -->\n\n  <div\n    class=\"lulla-state1-look\"\n    aria-hidden=\"true\"\n  ><\/div>\n\n\n  <!-- =====================================================\n       FLOATING CLOTHES\n       ===================================================== -->\n\n  <div\n    class=\"lulla-state1-clothes\"\n    aria-hidden=\"true\"\n  ><\/div>\n\n\n  <!-- =====================================================\n       FULL-WIDTH BOTTOM GRADIENT\n       =====================================================\n\n       IMPORTANT:\n       This is attached directly to STATE 1,\n       NOT to the text block.\n\n       Therefore it always spans 100% of\n       the entire State 1 \/ Outfit Panel width.\n       ===================================================== -->\n\n  <div\n    class=\"lulla-state1-gradient\"\n    aria-hidden=\"true\"\n  ><\/div>\n\n\n  <!-- =====================================================\n       TEXT\n       ===================================================== -->\n\n  <div class=\"lulla-state1-copy\">\n\n    <div class=\"lulla-state1-title\">\n      Outfit Studio\n    <\/div>\n\n    <div class=\"lulla-state1-subtitle\">\n      MIX IT, MATCH IT, MAKE IT YOURS\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n\n<style>\n\n\/* =========================================================\n   OUTFIT PANEL\n   ========================================================= *\/\n\n.outfit-panel{\n\n  position:relative !important;\n\n}\n\n\n\/* =========================================================\n   WIDGET HOST\n   ========================================================= *\/\n\n.outfit-panel\n.elementor-widget:has(\n  .lulla-state1\n){\n\n  position:static !important;\n\n  width:0 !important;\n\n  min-width:0 !important;\n\n  max-width:0 !important;\n\n  height:0 !important;\n\n  min-height:0 !important;\n\n  max-height:0 !important;\n\n  margin:0 !important;\n\n  padding:0 !important;\n\n  overflow:visible !important;\n\n  flex:\n    0 0 0 !important;\n\n}\n\n\n\/* =========================================================\n   STATE 1\n   ========================================================= *\/\n\n.lulla-state1{\n\n  position:absolute !important;\n\n  inset:0 !important;\n\n  width:100% !important;\n\n  height:100% !important;\n\n  min-width:0 !important;\n\n  min-height:0 !important;\n\n  margin:0 !important;\n\n  padding:0 !important;\n\n  box-sizing:border-box !important;\n\n  background:#FCF7F1;\n\n  overflow:visible !important;\n\n  z-index:100;\n\n  opacity:1;\n\n  visibility:visible;\n\n  pointer-events:none;\n\n  transition:\n    opacity .45s\n      cubic-bezier(.22,.61,.36,1),\n\n    visibility\n      0s linear 0s;\n\n  font-synthesis:none !important;\n\n}\n\n\n\/* =========================================================\n   HIDDEN\n   ========================================================= *\/\n\n.lulla-state1.is-hidden{\n\n  opacity:0 !important;\n\n  visibility:hidden !important;\n\n  transition:\n    opacity .45s\n      cubic-bezier(.22,.61,.36,1),\n\n    visibility\n      0s linear .45s;\n\n}\n\n\n\/* =========================================================\n   IMAGES\n   ========================================================= *\/\n\n.lulla-state1-look,\n.lulla-state1-clothes{\n\n  position:absolute !important;\n\n  inset:0 !important;\n\n  width:100% !important;\n\n  height:100% !important;\n\n  min-width:100% !important;\n\n  min-height:100% !important;\n\n  max-width:none !important;\n\n  max-height:none !important;\n\n  margin:0 !important;\n\n  padding:0 !important;\n\n  display:block !important;\n\n  background-color:transparent !important;\n\n  background-repeat:no-repeat !important;\n\n  background-size:cover !important;\n\n  background-position:center center !important;\n\n  user-select:none;\n\n  pointer-events:none;\n  opacity:0 !important;\n\n  visibility:hidden !important;\n\n  transition:opacity .5s cubic-bezier(.22,.61,.36,1);\n\n  will-change:opacity;\n\n}\n\n\n\/* =========================================================\n   IMAGE READY\n   ========================================================= *\/\n\n.lulla-state1-look.lulla-image-ready,\n.lulla-state1-clothes.lulla-image-ready{\n\n  opacity:1 !important;\n\n  visibility:visible !important;\n\n}\n\n\n\/* =========================================================\n   CENTRAL LOOK\n   ========================================================= *\/\n\n.lulla-state1-look{\n\n  z-index:1;\n\n  animation:\n    lullaState1LookFloat\n    8s\n    ease-in-out\n    infinite;\n\n}\n\n\n\/* =========================================================\n   FLOATING CLOTHES\n   ========================================================= *\/\n\n.lulla-state1-clothes{\n\n  z-index:2;\n\n  overflow:visible !important;\n\n  transform-origin:center center;\n\n  animation:\n    lullaState1ClothesSway\n    16s\n    ease-in-out\n    infinite;\n\n}\n\n\n\/* =========================================================\n   FULL-WIDTH GRADIENT\n   =========================================================\n\n   100% WIDTH OF STATE 1\n\n   NOT LIMITED BY TEXT WIDTH.\n   ========================================================= *\/\n\n.lulla-state1-gradient{\n\n  position:absolute !important;\n\n  left:0 !important;\n\n  right:0 !important;\n\n  bottom:0 !important;\n\n  width:100% !important;\n\n  height:\n    clamp(\n      150px,\n      22vh,\n      240px\n    ) !important;\n\n  z-index:5;\n\n  pointer-events:none;\n\n  background:\n    linear-gradient(\n      to bottom,\n\n      rgba(252,247,241,0) 0%,\n\n      rgba(252,247,241,.04) 18%,\n\n      rgba(252,247,241,.12) 32%,\n\n      rgba(252,247,241,.28) 50%,\n\n      rgba(252,247,241,.52) 68%,\n\n      rgba(252,247,241,.78) 82%,\n\n      rgba(252,247,241,.94) 93%,\n\n      rgba(252,247,241,1) 100%\n    );\n\n}\n\n\n\/* =========================================================\n   TEXT CONTAINER\n   ========================================================= *\/\n\n.lulla-state1-copy{\n\n  position:absolute;\n\n  left:\n    clamp(\n      30px,\n      4.5%,\n      70px\n    );\n\n  bottom:\n    clamp(\n      28px,\n      4.5%,\n      60px\n    );\n\n  width:\n    min(\n      560px,\n      72%\n    );\n\n  z-index:10;\n\n  pointer-events:none;\n\n  text-align:left;\n\n}\n\n\n\/* =========================================================\n   OUTFIT STUDIO\n\n   EXACT TYPOGRAPHY FROM GENDER TABS\n   ========================================================= *\/\n\n.lulla-state1-title{\n\n  width:100% !important;\n\n  margin:0 !important;\n\n  padding:0 !important;\n\n  font-family:\n    \"Playfair Display\",\n    serif !important;\n\n  font-size:\n    clamp(\n      34px,\n      4.2vw,\n      58px\n    ) !important;\n\n  font-weight:\n    400 !important;\n\n  font-style:\n    italic !important;\n\n  line-height:\n    .90 !important;\n\n  letter-spacing:\n    -.8px !important;\n\n  font-synthesis:\n    none !important;\n\n  font-variant:\n    normal !important;\n\n  font-variation-settings:\n    normal !important;\n\n  -webkit-text-stroke:\n    0 !important;\n\n  text-shadow:\n    none !important;\n\n  color:\n    #1D1D1B !important;\n\n}\n\n\n\/* =========================================================\n   SUBTITLE\n   ========================================================= *\/\n\n.lulla-state1-subtitle{\n\n  width:100% !important;\n\n  margin:\n    12px 0 0 !important;\n\n  padding:0 !important;\n\n  font-family:\n    \"Inter Tight\",\n    sans-serif !important;\n\n  font-style:\n    normal !important;\n\n  font-weight:\n    300 !important;\n\n  font-size:\n    12px !important;\n\n  line-height:\n    1.1 !important;\n\n  letter-spacing:\n    .065em !important;\n\n  color:\n    rgba(\n      29,\n      29,\n      27,\n      .56\n    ) !important;\n\n}\n\n\n\/* =========================================================\n   MAIN FLOAT\n   ========================================================= *\/\n\n@keyframes lullaState1LookFloat{\n\n  0%,\n  100%{\n\n    transform:\n      translate3d(\n        0,\n        0,\n        0\n      );\n\n  }\n\n  50%{\n\n    transform:\n      translate3d(\n        0,\n        -10px,\n        0\n      );\n\n  }\n\n}\n\n\n\/* =========================================================\n   CLOTHES SWAY\n   ========================================================= *\/\n\n@keyframes lullaState1ClothesSway{\n\n  0%,\n  100%{\n\n    transform:\n      rotate(-1.5deg);\n\n  }\n\n  50%{\n\n    transform:\n      rotate(1.5deg);\n\n  }\n\n}\n\n\n\/* =========================================================\n   HEADER ABOVE STATE 1\n   ========================================================= *\/\n\n.outfit-panel\n.outfit-header{\n\n  position:relative !important;\n\n  z-index:200 !important;\n\n}\n\n\n\/* =========================================================\n   MOBILE\n   =========================================================\n\n   SAME COMPOSITION:\n\n   left side\n   Outfit Studio\n   subtitle visible\n   same Playfair typography\n   ========================================================= *\/\n\n@media(max-width:850px){\n\n  .lulla-state1-look,\n  .lulla-state1-clothes{\n\n    background-position:\n      center center !important;\n\n  }\n\n\n  .lulla-state1-gradient{\n\n    left:0 !important;\n\n    right:0 !important;\n\n    width:100% !important;\n\n    bottom:0 !important;\n\n    height:\n      clamp(\n        120px,\n        22vh,\n        180px\n      ) !important;\n\n    background:\n      linear-gradient(\n        to bottom,\n\n        rgba(252,247,241,0) 0%,\n\n        rgba(252,247,241,.05) 20%,\n\n        rgba(252,247,241,.14) 38%,\n\n        rgba(252,247,241,.32) 56%,\n\n        rgba(252,247,241,.56) 72%,\n\n        rgba(252,247,241,.80) 86%,\n\n        rgba(252,247,241,.96) 96%,\n\n        rgba(252,247,241,1) 100%\n      );\n\n  }\n\n\n  .lulla-state1-copy{\n\n    left:\n      clamp(\n        18px,\n        5vw,\n        32px\n      );\n\n    right:auto;\n\n    bottom:\n      clamp(\n        10px,\n        3vw,\n        20px\n      );\n\n    width:\n      min(\n        76%,\n        430px\n      );\n\n    max-width:\n      76%;\n\n    text-align:left;\n\n  }\n\n\n  .lulla-state1-title{\n\n    font-family:\n      \"Playfair Display\",\n      serif !important;\n\n    font-size:\n      clamp(\n        36px,\n        9vw,\n        44px\n      ) !important;\n\n    font-weight:\n      400 !important;\n\n    font-style:\n      italic !important;\n\n    line-height:\n      .90 !important;\n\n    letter-spacing:\n      -.7px !important;\n\n    font-synthesis:\n      none !important;\n\n    font-variation-settings:\n      normal !important;\n\n  }\n\n\n  .lulla-state1-subtitle{\n\n    display:block !important;\n\n    width:100% !important;\n\n    margin-top:\n      9px !important;\n\n    font-family:\n      \"Inter Tight\",\n      sans-serif !important;\n\n    font-style:\n      normal !important;\n\n    font-weight:\n      300 !important;\n\n    font-size:\n      clamp(\n        9px,\n        2.5vw,\n        12px\n      ) !important;\n\n    line-height:\n      1.1 !important;\n\n    letter-spacing:\n      .055em !important;\n\n  }\n\n}\n\n\n\/* =========================================================\n   TABLET PORTRAIT\n   ========================================================= *\/\n\n@media(min-width:600px) and (max-width:850px) and (orientation:portrait){\n\n  .lulla-state1-copy{\n    bottom:14px;\n    width:88%;\n    max-width:88%;\n  }\n\n  .lulla-state1-title{\n    font-size:50px !important;\n    line-height:.90 !important;\n    letter-spacing:-1px !important;\n  }\n\n}\n\n\/* =========================================================\n   PHONE LANDSCAPE\n   ========================================================= *\/\n\n@media(max-width:850px) and (orientation:landscape){\n\n  .lulla-state1-copy{\n    width:90%;\n    max-width:90%;\n    bottom:12px;\n  }\n\n  .lulla-state1-title{\n    font-size:24px !important;\n    line-height:1 !important;\n    letter-spacing:-.45px !important;\n    white-space:nowrap !important;\n  }\n\n  .lulla-state1-subtitle{\n    margin-top:6px !important;\n    font-size:8px !important;\n  }\n\n}\n\n\/* =========================================================\n   SMALL PHONE\n   ========================================================= *\/\n\n@media(max-width:420px){\n\n  .lulla-state1-gradient{\n\n    width:100% !important;\n\n    left:0 !important;\n\n    right:0 !important;\n\n    height:\n      125px !important;\n\n  }\n\n\n  .lulla-state1-copy{\n\n    left:18px;\n\n    right:auto;\n\n    bottom:12px;\n\n    width:88%;\n\n    max-width:88%;\n\n    text-align:left;\n\n  }\n\n\n  .lulla-state1-title{\n\n    font-family:\n      \"Playfair Display\",\n      serif !important;\n\n    font-size:\n      38px !important;\n\n    font-weight:\n      400 !important;\n\n    font-style:\n      italic !important;\n\n    line-height:\n      .90 !important;\n\n    letter-spacing:\n      -.7px !important;\n\n    font-synthesis:\n      none !important;\n\n  }\n\n\n  .lulla-state1-subtitle{\n\n    margin-top:\n      8px !important;\n\n    font-size:\n      10px !important;\n\n    font-weight:\n      300 !important;\n\n    letter-spacing:\n      .045em !important;\n\n  }\n\n}\n\n\n\/* =========================================================\n   REDUCED MOTION\n   ========================================================= *\/\n\n@media(prefers-reduced-motion:reduce){\n\n  .lulla-state1-look,\n  .lulla-state1-clothes{\n\n    animation:none !important;\n\n  }\n\n}\n\n<\/style>\n\n\n<script>\n(function(){\n\n  \"use strict\";\n\n\n  \/* =====================================================\n     IMAGE PRELOAD \/ FADE-IN\n     ===================================================== *\/\n\n  function initLullaState1Images(){\n\n    var sources = [\n\n      {\n        selector:\n          \".lulla-state1-look\",\n        url:\n          \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/08\/Group-78-scaled.png\"\n      },\n\n      {\n        selector:\n          \".lulla-state1-clothes\",\n        url:\n          \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/08\/mixmatchbg-1-scaled.webp\"\n      }\n\n    ];\n\n    sources.forEach(\n      function(item){\n\n        var element =\n          document.querySelector(\n            item.selector\n          );\n\n        if(!element){\n          return;\n        }\n\n        if(\n          element.dataset.lullaImageLoading ===\n          \"true\"\n        ){\n          return;\n        }\n\n        element.dataset.lullaImageLoading =\n          \"true\";\n\n        var image =\n          new Image();\n\n        image.onload =\n          function(){\n\n            element.style.backgroundImage =\n              'url(\"' + item.url + '\")';\n\n            element.classList.add(\n              \"lulla-image-ready\"\n            );\n\n          };\n\n        image.onerror =\n          function(){\n\n            element.style.backgroundImage =\n              \"none\";\n\n          };\n\n        image.src =\n          item.url;\n\n      }\n    );\n\n  }\n\n\n  function initLullaState1(){\n\n    initLullaState1Images();\n\n    var root =\n      document.querySelector(\n        \".lulla-state1\"\n      );\n\n\n    if(!root){\n      return;\n    }\n\n\n    if(\n      root.dataset.lullaStateReady ===\n      \"true\"\n    ){\n\n      return;\n\n    }\n\n\n    root.dataset.lullaStateReady =\n      \"true\";\n\n\n    \/* =====================================================\n       NORMALIZE ELEMENTOR WIDGET\n       ===================================================== *\/\n\n    var widget =\n      root.closest(\n        \".elementor-widget\"\n      );\n\n\n    if(widget){\n\n      widget.style.position =\n        \"static\";\n\n      widget.style.width =\n        \"0\";\n\n      widget.style.minWidth =\n        \"0\";\n\n      widget.style.maxWidth =\n        \"0\";\n\n      widget.style.height =\n        \"0\";\n\n      widget.style.minHeight =\n        \"0\";\n\n      widget.style.maxHeight =\n        \"0\";\n\n      widget.style.margin =\n        \"0\";\n\n      widget.style.padding =\n        \"0\";\n\n      widget.style.overflow =\n        \"visible\";\n\n      widget.style.flex =\n        \"0 0 0\";\n\n    }\n\n\n    \/* =====================================================\n       OUTFIT PANEL\n       ===================================================== *\/\n\n    var outfitPanel =\n      root.closest(\n        \".outfit-panel\"\n      );\n\n\n    if(outfitPanel){\n\n      outfitPanel.style.position =\n        \"relative\";\n\n    }\n\n\n    \/* =====================================================\n       START BUILDING\n       ===================================================== *\/\n\n    document.addEventListener(\n      \"lulla:gender-change\",\n      function(){\n\n        root.classList.add(\n          \"is-hidden\"\n        );\n\n        root.setAttribute(\n          \"aria-hidden\",\n          \"true\"\n        );\n\n      }\n    );\n\n\n    \/* =====================================================\n       CHANGE\n       ===================================================== *\/\n\n    document.addEventListener(\n      \"lulla:setup-change\",\n      function(){\n\n        root.classList.remove(\n          \"is-hidden\"\n        );\n\n        root.setAttribute(\n          \"aria-hidden\",\n          \"false\"\n        );\n\n      }\n    );\n\n\n    \/* =====================================================\n       BACK\n       ===================================================== *\/\n\n    document.addEventListener(\n      \"lulla:setup-back\",\n      function(){\n\n        root.classList.remove(\n          \"is-hidden\"\n        );\n\n        root.setAttribute(\n          \"aria-hidden\",\n          \"false\"\n        );\n\n      }\n    );\n\n  }\n\n\n  \/* =======================================================\n     DOM READY\n     ======================================================= *\/\n\n  if(\n    document.readyState ===\n    \"loading\"\n  ){\n\n    document.addEventListener(\n      \"DOMContentLoaded\",\n      initLullaState1,\n      {\n        once:true\n      }\n    );\n\n  }else{\n\n    initLullaState1();\n\n  }\n\n\n  \/* =======================================================\n     ELEMENTOR\n     ======================================================= *\/\n\n  if(\n    typeof jQuery !==\n    \"undefined\"\n  ){\n\n    jQuery(window).on(\n      \"elementor\/frontend\/init\",\n      initLullaState1\n    );\n\n  }\n\n})();\n<\/script>\n\n<!-- =========================================================\n     STATE 1 \u2014 FOOTER VISIBILITY OVERRIDE\n\n     State 1 is the full left-panel layer. When State 1 is visible,\n     the State 2 footer must not be visible underneath\/through it.\n\n     IMPORTANT:\n     This does not change the footer's State 2 \/ State 3 logic.\n     It only gives State 1 priority while State 1 is on screen.\n     ========================================================= -->\n<style>\n  .outfit-footer-controls.is-state1-hidden{\n    height:0 !important;\n    min-height:0 !important;\n    margin:0 !important;\n    padding:0 !important;\n    overflow:hidden !important;\n    opacity:0 !important;\n    visibility:hidden !important;\n    pointer-events:none !important;\n  }\n\n  .outfit-footer-controls.is-state1-hidden .outfit-footer-inner{\n    opacity:0 !important;\n    visibility:hidden !important;\n    pointer-events:none !important;\n    transform:translateY(16px) !important;\n  }\n<\/style>\n\n<script>\n(function(){\n  \"use strict\";\n\n  function getState1(){\n    return document.querySelector(\".lulla-state1\");\n  }\n\n  function getFooter(){\n    return document.querySelector(\".outfit-footer-controls\");\n  }\n\n  function isState1Visible(state1){\n    if(!state1){\n      return false;\n    }\n\n    var ariaHidden = state1.getAttribute(\"aria-hidden\");\n    var hiddenClass = state1.classList.contains(\"is-hidden\");\n    var computed = window.getComputedStyle(state1);\n\n    return (\n      ariaHidden !== \"true\" &&\n      !hiddenClass &&\n      computed.visibility !== \"hidden\" &&\n      Number(computed.opacity) > 0.01\n    );\n  }\n\n  function syncFooter(){\n    var state1 = getState1();\n    var footer = getFooter();\n\n    if(!state1 || !footer){\n      return;\n    }\n\n    if(isState1Visible(state1)){\n      footer.classList.add(\"is-state1-hidden\");\n      return;\n    }\n\n    footer.classList.remove(\"is-state1-hidden\");\n  }\n\n  function initState1FooterControl(){\n    var state1 = getState1();\n\n    if(!state1){\n      window.setTimeout(initState1FooterControl, 50);\n      return;\n    }\n\n    syncFooter();\n\n    if(typeof MutationObserver !== \"undefined\"){\n      var observer = new MutationObserver(function(){\n        syncFooter();\n      });\n\n      observer.observe(state1, {\n        attributes:true,\n        attributeFilter:[\"class\",\"aria-hidden\",\"style\"]\n      });\n    }\n  }\n\n  if(document.readyState === \"loading\"){\n    document.addEventListener(\n      \"DOMContentLoaded\",\n      initState1FooterControl,\n      {once:true}\n    );\n  }else{\n    initState1FooterControl();\n  }\n\n  if(typeof jQuery !== \"undefined\"){\n    jQuery(window).on(\n      \"elementor\/frontend\/init\",\n      initState1FooterControl\n    );\n  }\n})();\n<\/script>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-da81ae4 e-con-full products-panel e-flex e-con e-child\" data-id=\"da81ae4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-7d52120 e-con-full gender-tabs e-flex e-con e-child\" data-id=\"7d52120\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ac91a66 elementor-widget__width-inherit elementor-widget elementor-widget-html\" data-id=\"ac91a66\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<nav class=\"gender-tabs\" aria-label=\"Outfit setup\">\r\n\r\n  <div class=\"lulla-setup-overlay\">\r\n    <div class=\"lulla-floating-stage\" aria-hidden=\"true\"><\/div>\r\n\r\n    <div class=\"lulla-setup-card\">\r\n\r\n      <h1 class=\"lulla-setup-title\">\r\n        Who are we dressing?\r\n      <\/h1>\r\n\r\n      <div class=\"lulla-setup-section lulla-gender-section\">\r\n\r\n        <div class=\"lulla-setup-label\">\r\n          Who are we dressing?\r\n        <\/div>\r\n\r\n        <div\r\n          class=\"lulla-gender-row\"\r\n          role=\"radiogroup\"\r\n          aria-label=\"Gender\"\r\n        >\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-gender-choice\"\r\n            data-gender=\"boys\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            Boy\r\n          <\/button>\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-gender-choice\"\r\n            data-gender=\"girls\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            Girl\r\n          <\/button>\r\n\r\n        <\/div>\r\n\r\n      <\/div>\r\n\r\n      <div class=\"lulla-setup-section lulla-size-section\">\r\n\r\n        <div class=\"lulla-setup-label\">\r\n          What age?\r\n        <\/div>\r\n\r\n        <div\r\n          class=\"lulla-size-grid\"\r\n          role=\"radiogroup\"\r\n          aria-label=\"Size\"\r\n        >\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-size-choice\"\r\n            data-age-range=\"9-12m\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            9\u201312M\r\n          <\/button>\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-size-choice\"\r\n            data-age-range=\"12-18m\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            12\u201318M\r\n          <\/button>\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-size-choice\"\r\n            data-age-range=\"2-3y\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            2\u20133Y\r\n          <\/button>\r\n\r\n          <button\r\n            type=\"button\"\r\n            class=\"lulla-choice lulla-size-choice\"\r\n            data-age-range=\"3-4y\"\r\n            role=\"radio\"\r\n            aria-checked=\"false\"\r\n          >\r\n            3\u20134Y\r\n          <\/button>\r\n\r\n        <\/div>\r\n\r\n      <\/div>\r\n\r\n      <div class=\"lulla-action-row\">\r\n\r\n        <button\r\n          type=\"button\"\r\n          class=\"lulla-mobile-back\"\r\n          aria-label=\"Back\"\r\n        >\r\n          <svg class=\"lulla-mobile-back-arrow\" viewBox=\"0 0 10 16\" aria-hidden=\"true\">\r\n            <path d=\"M8 2L2 8L8 14\"><\/path>\r\n          <\/svg>\r\n          <span class=\"lulla-mobile-back-text\">BACK<\/span>\r\n        <\/button>\r\n\r\n        <button\r\n          type=\"button\"\r\n          class=\"lulla-start-button\"\r\n        >\r\n          <span class=\"lulla-start-label\">\r\n            Start building\r\n          <\/span>\r\n        <\/button>\r\n\r\n      <\/div>\r\n\r\n    <\/div>\r\n\r\n  <\/div>\r\n\r\n  <div class=\"lulla-selected-bar\">\r\n\r\n    <div class=\"lulla-selected-group\">\r\n\r\n      <div class=\"lulla-selected-context\">\r\n\r\n        <span class=\"lulla-selected-gender\">\r\n          BOY\r\n        <\/span>\r\n\r\n        <span class=\"lulla-selected-dot\">\r\n          \u00b7\r\n        <\/span>\r\n\r\n        <span class=\"lulla-selected-size\">\r\n          12\u201318M\r\n        <\/span>\r\n\r\n      <\/div>\r\n\r\n      <button\r\n        type=\"button\"\r\n        class=\"lulla-change-button\"\r\n      >\r\n        CHANGE\r\n      <\/button>\r\n\r\n    <\/div>\r\n\r\n  <\/div>\r\n\r\n<\/nav>\r\n\r\n<style>\r\n\r\n\/* =========================================================\r\n   HOST\r\n   ========================================================= *\/\r\n\r\n.gender-tabs{\r\n\r\n  --ink:#1D1D1B;\r\n  --cream:#FCF7F1;\r\n  --panel:#FFFCF8;\r\n  --sage:#6B7557;\r\n  --border:rgba(29,29,27,.14);\r\n  --border-hover:rgba(29,29,27,.24);\r\n\r\n  --shadow-btn:\r\n    0 2px 7px\r\n    rgba(29,29,27,.025);\r\n\r\n  position:relative;\r\n\r\n  width:100%;\r\n  height:60px;\r\n\r\n  margin:0;\r\n  padding:0;\r\n\r\n  box-sizing:border-box;\r\n\r\n  background:\r\n    var(--cream) !important;\r\n\r\n  border:0 !important;\r\n\r\n  font-family:\r\n    \"Inter Tight\",\r\n    sans-serif !important;\r\n\r\n  overflow:visible;\r\n\r\n}\r\n\r\n.gender-tabs *{\r\n  box-sizing:border-box;\r\n}\r\n\r\n\/* =========================================================\r\n   BUTTON RESET\r\n   ========================================================= *\/\r\n\r\n.gender-tabs button,\r\n.gender-tabs button:hover,\r\n.gender-tabs button:focus,\r\n.gender-tabs button:active,\r\n.gender-tabs button:focus-visible{\r\n\r\n  appearance:none !important;\r\n\r\n  -webkit-appearance:none !important;\r\n\r\n  border-radius:4px !important;\r\n\r\n  outline:none !important;\r\n\r\n  -webkit-tap-highlight-color:\r\n    transparent !important;\r\n\r\n}\r\n\r\n.gender-tabs button::-moz-focus-inner{\r\n\r\n  border:0 !important;\r\n\r\n  padding:0 !important;\r\n\r\n}\r\n\r\n.gender-tabs button:focus,\r\n.gender-tabs button:active{\r\n\r\n  outline:none !important;\r\n\r\n  box-shadow:none !important;\r\n\r\n}\r\n\r\n.gender-tabs button:focus-visible{\r\n\r\n  outline:none !important;\r\n\r\n  box-shadow:\r\n    inset 0 0 0 1px\r\n    rgba(29,29,27,.22)\r\n    !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SETUP OVERLAY\r\n   ========================================================= *\/\r\n\r\n\/* =========================================================\r\n   INITIAL SETUP GEOMETRY\r\n   Apply state-1 geometry in CSS immediately so the browser never\r\n   paints the default 60px gender-tabs bar before JavaScript runs.\r\n   ========================================================= *\/\r\n\r\n.gender-tabs:has(> .lulla-setup-overlay):not(.is-leaving):not(.is-selected){\r\n  position:absolute !important;\r\n  inset:0 !important;\r\n  width:100% !important;\r\n  height:100% !important;\r\n  min-width:0 !important;\r\n  min-height:0 !important;\r\n  max-width:none !important;\r\n  max-height:none !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  z-index:1000 !important;\r\n  overflow:hidden !important;\r\n}\r\n\r\n.gender-tabs:has(> .lulla-setup-overlay):not(.is-leaving):not(.is-selected)\r\n.lulla-setup-overlay{\r\n  position:absolute !important;\r\n  inset:0 !important;\r\n  width:100% !important;\r\n  height:100% !important;\r\n}\r\n\r\n.lulla-setup-overlay{\r\n\r\n  position:absolute;\r\n\r\n  inset:0;\r\n\r\n  width:100%;\r\n  height:100%;\r\n\r\n  z-index:99990;\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n  justify-content:center;\r\n\r\n  box-sizing:border-box;\r\n\r\n  background:\r\n    var(--cream);\r\n\r\n  opacity:1;\r\n\r\n  visibility:visible;\r\n\r\n  transform:none;\r\n\r\n  overflow:hidden;\r\n\r\n  transition:\r\n    opacity .38s\r\n      cubic-bezier(.22,.61,.36,1),\r\n\r\n    visibility\r\n      0s linear 0s;\r\n\r\n}\r\n\r\n.gender-tabs.is-leaving\r\n.lulla-setup-overlay{\r\n\r\n  opacity:0;\r\n\r\n  visibility:hidden;\r\n\r\n  transition:\r\n    opacity .38s\r\n      cubic-bezier(.22,.61,.36,1),\r\n\r\n    visibility\r\n      0s linear .38s;\r\n\r\n}\r\n\r\n.lulla-floating-stage{\r\n\r\n  position:absolute;\r\n\r\n  inset:0;\r\n\r\n  z-index:1;\r\n\r\n  pointer-events:none;\r\n\r\n  overflow:hidden;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SETUP CARD\r\n   ========================================================= *\/\r\n\r\n.lulla-setup-card{\r\n\r\n  position:relative;\r\n\r\n  z-index:3;\r\n\r\n  width:\r\n    min(\r\n      400px,\r\n      calc(100% - 40px)\r\n    );\r\n\r\n  max-width:400px;\r\n\r\n  max-height:\r\n    calc(100% - 40px);\r\n\r\n  margin:0;\r\n\r\n  padding:\r\n    clamp(\r\n      24px,\r\n      4.8vh,\r\n      48px\r\n    )\r\n    0;\r\n\r\n  display:flex;\r\n\r\n  flex-direction:column;\r\n\r\n  align-items:flex-start;\r\n\r\n  box-sizing:border-box;\r\n\r\n  overflow-y:auto;\r\n\r\n  overflow-x:hidden;\r\n\r\n  scrollbar-width:none;\r\n\r\n}\r\n\r\n.lulla-setup-card::-webkit-scrollbar{\r\n  display:none;\r\n}\r\n\r\n\/* =========================================================\r\n   TITLE \u2014 DESKTOP \/ LANDSCAPE\r\n   ========================================================= *\/\r\n\r\n.lulla-setup-title{\r\n\r\n  width:100%;\r\n\r\n  margin:0;\r\n  padding:0;\r\n\r\n  font-family:\r\n    \"Playfair Display\",\r\n    serif !important;\r\n\r\n  font-size:\r\n    clamp(\r\n      34px,\r\n      4.2vw,\r\n      58px\r\n    ) !important;\r\n\r\n  font-weight:400 !important;\r\n\r\n  font-style:italic !important;\r\n\r\n  line-height:.90 !important;\r\n\r\n  letter-spacing:-.8px !important;\r\n\r\n  color:\r\n    var(--ink) !important;\r\n\r\n  font-synthesis:none !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SECTIONS\r\n   ========================================================= *\/\r\n\r\n.lulla-setup-section{\r\n\r\n  width:100%;\r\n\r\n  margin-top:\r\n    clamp(\r\n      28px,\r\n      4.8vh,\r\n      40px\r\n    );\r\n\r\n}\r\n\r\n.lulla-gender-section{\r\n  margin-top:30px;\r\n}\r\n\r\n.lulla-size-section{\r\n  margin-top:42px;\r\n}\r\n\r\n\/* =========================================================\r\n   SMALL INTER QUESTION LABEL\r\n   ========================================================= *\/\r\n\r\n.lulla-setup-label{\r\n\r\n  margin:\r\n    0 0 11px;\r\n\r\n  font-family:\r\n    \"Inter Tight\",\r\n    sans-serif !important;\r\n\r\n  font-size:9px !important;\r\n\r\n  font-weight:300 !important;\r\n\r\n  line-height:1 !important;\r\n\r\n  letter-spacing:.06em !important;\r\n\r\n  text-transform:uppercase;\r\n\r\n  color:\r\n    rgba(29,29,27,.45)\r\n    !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   TYPOGRAPHY\r\n   ========================================================= *\/\r\n\r\n.lulla-choice,\r\n.lulla-start-button,\r\n.lulla-change-button,\r\n.lulla-selected-context,\r\n.lulla-mobile-back{\r\n\r\n  font-family:\r\n    \"Inter Tight\",\r\n    sans-serif !important;\r\n\r\n  font-style:normal !important;\r\n\r\n  font-weight:400 !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   CHOICES\r\n   ========================================================= *\/\r\n\r\n.lulla-choice{\r\n\r\n  width:100%;\r\n\r\n  min-width:0;\r\n\r\n  margin:0;\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  justify-content:center;\r\n\r\n  text-align:center;\r\n\r\n  border:\r\n    1px solid\r\n    var(--border)\r\n    !important;\r\n\r\n  border-radius:4px !important;\r\n\r\n  background:\r\n    var(--panel)\r\n    !important;\r\n\r\n  color:\r\n    var(--ink)\r\n    !important;\r\n\r\n  line-height:1 !important;\r\n\r\n  text-transform:uppercase !important;\r\n\r\n  cursor:pointer;\r\n\r\n  box-shadow:\r\n    var(--shadow-btn)\r\n    !important;\r\n\r\n  transition:\r\n    background-color .20s ease,\r\n    border-color .20s ease,\r\n    color .20s ease,\r\n    opacity .20s ease,\r\n    font-weight .20s ease;\r\n\r\n}\r\n\r\n.lulla-choice:hover{\r\n\r\n  border-color:\r\n    var(--border-hover)\r\n    !important;\r\n\r\n}\r\n\r\n.lulla-choice:active{\r\n\r\n  opacity:.82;\r\n\r\n}\r\n\r\n.lulla-choice.is-active{\r\n\r\n  background:\r\n    var(--sage)\r\n    !important;\r\n\r\n  border-color:\r\n    var(--sage)\r\n    !important;\r\n\r\n  color:\r\n    var(--cream)\r\n    !important;\r\n\r\n  font-weight:500 !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   GENDER\r\n   ========================================================= *\/\r\n\r\n.lulla-gender-row{\r\n\r\n  width:100%;\r\n  container-type:inline-size;\r\n\r\n  display:grid;\r\n\r\n  grid-template-columns:\r\n    repeat(\r\n      2,\r\n      minmax(0,1fr)\r\n    );\r\n\r\n  gap:8px;\r\n\r\n}\r\n\r\n.lulla-gender-choice{\r\n\r\n  height:42px;\r\n\r\n  padding:\r\n    0 12px;\r\n\r\n  font-size:\r\n    clamp(10px,3.0cqw,12px) !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SIZE\r\n   ========================================================= *\/\r\n\r\n.lulla-size-grid{\r\n\r\n  width:100%;\r\n  container-type:inline-size;\r\n\r\n  display:grid;\r\n\r\n  grid-template-columns:\r\n    repeat(\r\n      4,\r\n      minmax(0,1fr)\r\n    );\r\n\r\n  gap:4px;\r\n\r\n}\r\n\r\n.lulla-size-choice{\r\n\r\n  height:40px;\r\n\r\n  padding:\r\n    0 4px;\r\n\r\n  font-size:\r\n    11px !important;\r\n\r\n  white-space:nowrap;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   ACTIONS\r\n   ========================================================= *\/\r\n\r\n.lulla-action-row{\r\n\r\n  width:100%;\r\n  container-type:inline-size;\r\n\r\n  max-width:100%;\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  justify-content:stretch;\r\n\r\n  gap:10px;\r\n\r\n  margin-top:58px;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   BACK\r\n   ========================================================= *\/\r\n\r\n.lulla-mobile-back{\r\n  position:relative;\r\n  display:flex;\r\n  align-items:center;\r\n  justify-content:flex-start;\r\n  width:auto;\r\n  height:42px;\r\n  flex:0 0 auto;\r\n  min-width:64px;\r\n  margin:0;\r\n  padding:0 6px 0 2px;\r\n  box-sizing:border-box;\r\n  appearance:none !important;\r\n  -webkit-appearance:none !important;\r\n  border:0 !important;\r\n  border-radius:0 !important;\r\n  outline:none !important;\r\n  box-shadow:none !important;\r\n  background:transparent !important;\r\n  background-color:transparent !important;\r\n  color:#1D1D1B !important;\r\n  font-family:\"Inter Tight\", Arial, sans-serif !important;\r\n  font-size:12px !important;\r\n  font-weight:400 !important;\r\n  line-height:1 !important;\r\n  letter-spacing:0 !important;\r\n  text-align:left !important;\r\n  text-decoration:none !important;\r\n  cursor:pointer;\r\n  user-select:none;\r\n  -webkit-user-select:none;\r\n  -webkit-tap-highlight-color:transparent !important;\r\n  touch-action:manipulation !important;\r\n  opacity:1;\r\n  transition:opacity .20s ease !important;\r\n}\r\n\r\n.lulla-mobile-back-text{\r\n  display:block;\r\n  width:auto;\r\n  height:auto;\r\n  margin:0;\r\n  padding:0;\r\n  font-family:\"Inter Tight\", Arial, sans-serif !important;\r\n  font-size:clamp(9px,3cqw,12px) !important;\r\n  font-weight:400 !important;\r\n  line-height:1 !important;\r\n  letter-spacing:0 !important;\r\n  color:#1D1D1B !important;\r\n  text-decoration:none !important;\r\n  white-space:nowrap;\r\n  pointer-events:none;\r\n}\r\n\r\n.lulla-mobile-back-arrow{\r\n  display:block;\r\n  width:9px !important;\r\n  height:12px !important;\r\n  min-width:9px !important;\r\n  max-width:9px !important;\r\n  flex:0 0 9px !important;\r\n  margin:0 6px 0 0 !important;\r\n  padding:0;\r\n  pointer-events:none;\r\n  transition:transform .28s cubic-bezier(.22,.61,.36,1) !important;\r\n}\r\n\r\n.lulla-mobile-back-arrow path{\r\n  fill:none !important;\r\n  stroke:#1D1D1B !important;\r\n  stroke-width:1.35 !important;\r\n  stroke-linecap:round !important;\r\n  stroke-linejoin:round !important;\r\n}\r\n\r\n.lulla-mobile-back:hover{\r\n  opacity:.72 !important;\r\n}\r\n\r\n.lulla-mobile-back:hover .lulla-mobile-back-arrow{\r\n  transform:translateX(-4px) !important;\r\n}\r\n\r\n.lulla-mobile-back:focus,\r\n.lulla-mobile-back:focus-visible,\r\n.lulla-mobile-back:active{\r\n  border:0 !important;\r\n  outline:none !important;\r\n  box-shadow:none !important;\r\n  background:transparent !important;\r\n  background-color:transparent !important;\r\n}\r\n\r\n.lulla-mobile-back:active{\r\n  opacity:.72 !important;\r\n}\r\n\r\n.lulla-mobile-back::-moz-focus-inner{\r\n  border:0 !important;\r\n  padding:0 !important;\r\n}\r\n\r\n\/* =========================================================\r\n   START BUILDING\r\n   ========================================================= *\/\r\n\r\n.lulla-start-button{\r\n\r\n  position:relative;\r\n\r\n  width:100%;\r\n\r\n  height:42px;\r\n\r\n  flex:\r\n    1 1 auto;\r\n\r\n  min-width:0;\r\n\r\n  margin:0;\r\n\r\n  padding:\r\n    0 16px;\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  justify-content:center;\r\n\r\n  text-align:center;\r\n\r\n  border:0 !important;\r\n\r\n  background:\r\n    var(--ink)\r\n    !important;\r\n\r\n  color:\r\n    var(--cream)\r\n    !important;\r\n\r\n  font-size:\r\n    clamp(9px,3cqw,12px) !important;\r\n\r\n  font-weight:400 !important;\r\n\r\n  line-height:1 !important;\r\n\r\n  text-transform:uppercase !important;\r\n\r\n  cursor:pointer;\r\n\r\n  box-shadow:\r\n    0 3px 9px\r\n    rgba(29,29,27,.09)\r\n    !important;\r\n\r\n  border-radius:4px !important;\r\n\r\n  container-type:inline-size;\r\n\r\n  transition:\r\n    opacity .20s ease,\r\n    font-weight .20s ease;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   START BUILDING \u2014 DISABLED \/ ENABLED\r\n   ========================================================= *\/\r\n\r\n.lulla-start-button:disabled,\r\n.lulla-start-button[disabled]{\r\n  opacity:.42 !important;\r\n  cursor:default !important;\r\n  pointer-events:none !important;\r\n}\r\n\r\n.lulla-start-button:hover{\r\n\r\n  opacity:.92;\r\n\r\n}\r\n\r\n.lulla-start-button:active{\r\n\r\n  opacity:.78;\r\n\r\n}\r\n\r\n.lulla-start-label{\r\n\r\n  display:block;\r\n\r\n  white-space:nowrap;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   START ARROW \u2014 DISABLED\r\n   ========================================================= *\/\r\n\r\n.lulla-start-arrow{\r\n\r\n  display:none !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SELECTED BAR\r\n   ========================================================= *\/\r\n\r\n.lulla-selected-bar{\r\n\r\n  position:absolute;\r\n\r\n  z-index:100000;\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  justify-content:flex-start;\r\n\r\n  width:auto;\r\n\r\n  min-width:0;\r\n\r\n  height:60px;\r\n\r\n  margin:0;\r\n\r\n  padding:\r\n    0 20px;\r\n\r\n  box-sizing:border-box;\r\n\r\n  background:\r\n    rgba(252,247,241,.96);\r\n\r\n  border-top:\r\n    1px solid\r\n    rgba(29,29,27,.08);\r\n\r\n  border-bottom:\r\n    1px solid\r\n    rgba(29,29,27,.08);\r\n\r\n  backdrop-filter:\r\n    blur(10px);\r\n\r\n  -webkit-backdrop-filter:\r\n    blur(10px);\r\n\r\n  opacity:0;\r\n\r\n  visibility:hidden;\r\n\r\n  pointer-events:none;\r\n\r\n  transition:\r\n    opacity .42s\r\n      cubic-bezier(.22,.61,.36,1),\r\n\r\n    visibility\r\n      0s linear .42s;\r\n\r\n}\r\n\r\n.lulla-selected-bar.is-visible{\r\n\r\n  opacity:1;\r\n\r\n  visibility:visible;\r\n\r\n  pointer-events:auto;\r\n\r\n  transition:\r\n    opacity .42s\r\n      cubic-bezier(.22,.61,.36,1),\r\n\r\n    visibility\r\n      0s linear 0s;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   THIRD SCREEN \u2014 HIDDEN\r\n   ========================================================= *\/\r\n\r\n.lulla-selected-bar.is-size-selection{\r\n\r\n  opacity:0 !important;\r\n\r\n  visibility:hidden !important;\r\n\r\n  pointer-events:none !important;\r\n\r\n  height:0 !important;\r\n\r\n  min-height:0 !important;\r\n\r\n  max-height:0 !important;\r\n\r\n  padding:0 !important;\r\n\r\n  border:0 !important;\r\n\r\n  overflow:hidden !important;\r\n\r\n  transform:\r\n    translateY(-6px) !important;\r\n\r\n}\r\n\r\n.lulla-selected-group{\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  gap:10px;\r\n\r\n  width:max-content;\r\n\r\n  max-width:100%;\r\n\r\n}\r\n\r\n.lulla-selected-context{\r\n\r\n  display:flex;\r\n\r\n  align-items:center;\r\n\r\n  gap:8px;\r\n\r\n  font-size:\r\n    12px !important;\r\n\r\n  line-height:1;\r\n\r\n  text-transform:uppercase;\r\n\r\n  white-space:nowrap;\r\n\r\n}\r\n\r\n.lulla-selected-gender{\r\n\r\n  color:\r\n    var(--ink) !important;\r\n\r\n  font-weight:500 !important;\r\n\r\n}\r\n\r\n.lulla-selected-dot{\r\n\r\n  color:\r\n    rgba(29,29,27,.50);\r\n\r\n  font-size:14px;\r\n\r\n}\r\n\r\n.lulla-selected-size{\r\n\r\n  color:\r\n    rgba(29,29,27,.80)\r\n    !important;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   CHANGE \u2014 MOBILE TAP \/ FOCUS RESET\r\n   The selected bar is moved to <body> by the existing JS,\r\n   so the general .gender-tabs button reset does not reach it.\r\n   ========================================================= *\/\r\n\r\n.lulla-change-button,\r\n.lulla-change-button:hover,\r\n.lulla-change-button:focus,\r\n.lulla-change-button:focus-visible,\r\n.lulla-change-button:active{\r\n  appearance:none !important;\r\n  -webkit-appearance:none !important;\r\n\r\n  background:transparent !important;\r\n  background-color:transparent !important;\r\n\r\n  border:0 !important;\r\n  outline:none !important;\r\n  box-shadow:none !important;\r\n\r\n  -webkit-tap-highlight-color:transparent !important;\r\n  -webkit-touch-callout:none !important;\r\n  -webkit-focus-ring-color:transparent !important;\r\n\r\n  text-shadow:none !important;\r\n  -webkit-user-select:none !important;\r\n  user-select:none !important;\r\n}\r\n\r\n@media(max-width:850px){\r\n\r\n  .lulla-change-button,\r\n  .lulla-change-button:hover,\r\n  .lulla-change-button:focus,\r\n  .lulla-change-button:focus-visible,\r\n  .lulla-change-button:active{\r\n    background:transparent !important;\r\n    background-color:transparent !important;\r\n    border:0 !important;\r\n    outline:none !important;\r\n    box-shadow:none !important;\r\n    -webkit-tap-highlight-color:transparent !important;\r\n    -webkit-focus-ring-color:transparent !important;\r\n  }\r\n\r\n  .lulla-change-button{\r\n    touch-action:manipulation !important;\r\n  }\r\n\r\n}\r\n\r\n.lulla-change-button{\r\n\r\n  width:auto;\r\n\r\n  flex:0 0 auto;\r\n\r\n  margin:0;\r\n  padding:0;\r\n\r\n  border:0 !important;\r\n\r\n  background:\r\n    transparent !important;\r\n\r\n  color:\r\n    rgba(29,29,27,.60)\r\n    !important;\r\n\r\n  font-size:\r\n    10px !important;\r\n\r\n  line-height:1 !important;\r\n\r\n  text-transform:uppercase !important;\r\n\r\n  text-decoration:underline !important;\r\n\r\n  text-decoration-thickness:\r\n    1px !important;\r\n\r\n  text-underline-offset:\r\n    2px !important;\r\n\r\n  cursor:pointer;\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SELECTED BAR \u2014 HARD CONTENT ALIGNMENT\r\n   ========================================================= *\/\r\n.gender-tabs .lulla-selected-bar,\r\n.lulla-selected-bar{\r\n  display:flex !important;\r\n  flex-direction:row !important;\r\n  align-items:center !important;\r\n  justify-content:flex-start !important;\r\n}\r\n\r\n.gender-tabs .lulla-selected-group,\r\n.lulla-selected-bar .lulla-selected-group{\r\n  display:flex !important;\r\n  flex-direction:row !important;\r\n  align-items:center !important;\r\n  justify-content:flex-start !important;\r\n  width:max-content !important;\r\n  min-width:0 !important;\r\n  max-width:none !important;\r\n  flex:0 0 auto !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n}\r\n\r\n.gender-tabs .lulla-selected-context,\r\n.lulla-selected-bar .lulla-selected-context{\r\n  display:flex !important;\r\n  flex-direction:row !important;\r\n  align-items:center !important;\r\n  justify-content:flex-start !important;\r\n  width:max-content !important;\r\n  min-width:0 !important;\r\n  max-width:none !important;\r\n  flex:0 0 auto !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n}\r\n\r\n.lulla-selected-bar .lulla-selected-gender,\r\n.lulla-selected-bar .lulla-selected-dot,\r\n.lulla-selected-bar .lulla-selected-size,\r\n.lulla-selected-bar .lulla-change-button{\r\n  flex:0 0 auto !important;\r\n  margin:0 !important;\r\n}\r\n\r\n.lulla-selected-bar .lulla-selected-size{\r\n  font-weight:500 !important;\r\n}\r\n\r\n.lulla-selected-bar .lulla-change-button{\r\n  width:auto !important;\r\n  min-width:0 !important;\r\n  max-width:none !important;\r\n  padding:0 !important;\r\n  border:0 !important;\r\n}\r\n\r\n\/* =========================================================\r\n   TALL IPAD PORTRAIT\r\n   ========================================================= *\/\r\n\r\n@media(min-width:700px) and (max-width:850px) and (min-height:700px) and (orientation:portrait){\r\n\r\n  .lulla-setup-card{\r\n    width:430px !important;\r\n    max-width:430px !important;\r\n    max-height:calc(100dvh - 24px) !important;\r\n    padding:16px 0 !important;\r\n  }\r\n\r\n  .lulla-setup-title{\r\n    display:block !important;\r\n    white-space:nowrap !important;\r\n    font-size:42px !important;\r\n    line-height:.90 !important;\r\n    letter-spacing:-1px !important;\r\n  }\r\n\r\n  .lulla-gender-section .lulla-setup-label{\r\n    display:none !important;\r\n  }\r\n\r\n  .lulla-gender-section{\r\n    margin-top:22px !important;\r\n  }\r\n\r\n  .lulla-size-section{\r\n    margin-top:16px !important;\r\n  }\r\n\r\n  .lulla-action-row{\r\n    margin-top:46px !important;\r\n  }\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   DESKTOP \/ LANDSCAPE\r\n   ========================================================= *\/\r\n\r\n@media(min-width:851px){\r\n\r\n  .lulla-gender-section\r\n  .lulla-setup-label{\r\n\r\n    display:none !important;\r\n\r\n  }\r\n\r\n  .lulla-action-row{\r\n\r\n    flex-direction:row !important;\r\n\r\n    align-items:center !important;\r\n\r\n    justify-content:stretch !important;\r\n\r\n  }\r\n\r\n  .lulla-mobile-back{\r\n\r\n    display:flex !important;\r\n\r\n  }\r\n\r\n  .lulla-start-button{\r\n\r\n    flex:\r\n      1 1 auto !important;\r\n\r\n  }\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   MOBILE PORTRAIT\r\n   ========================================================= *\/\r\n\r\n@media(max-width:850px){\r\n\r\n  .gender-tabs{\r\n\r\n    height:34px;\r\n\r\n  }\r\n\r\n  .lulla-setup-overlay{\r\n\r\n    overflow:hidden !important;\r\n\r\n    display:flex !important;\r\n\r\n    align-items:center !important;\r\n\r\n    justify-content:center !important;\r\n\r\n  }\r\n\r\n  .lulla-setup-card{\r\n\r\n    width:\r\n      min(\r\n        430px,\r\n        calc(100% - 40px)\r\n      );\r\n\r\n    max-width:430px;\r\n\r\n    height:auto !important;\r\n\r\n    max-height:\r\n      calc(100% - 32px) !important;\r\n\r\n    margin:\r\n      0 auto !important;\r\n\r\n    padding:\r\n      24px 0 !important;\r\n\r\n    \/*\r\n     * IMPORTANT:\r\n     * Keep the questionnaire vertically centered.\r\n     * Do not push it down with flex-end.\r\n     *\/\r\n\r\n    justify-content:center !important;\r\n\r\n    align-items:flex-start !important;\r\n\r\n    overflow:hidden !important;\r\n\r\n  }\r\n\r\n  \/*\r\n   * Portrait mobile uses compact Inter question.\r\n   *\/\r\n\r\n  .lulla-setup-title{\r\n\r\n    display:none !important;\r\n\r\n  }\r\n\r\n  .lulla-gender-section{\r\n\r\n    margin-top:0 !important;\r\n\r\n  }\r\n\r\n  .lulla-setup-label{\r\n\r\n    margin-bottom:8px;\r\n\r\n    font-size:\r\n      9px !important;\r\n\r\n    color:\r\n      rgba(29,29,27,.82)\r\n      !important;\r\n\r\n  }\r\n\r\n  .lulla-gender-row{\r\n\r\n    gap:7px;\r\n\r\n  }\r\n\r\n  .lulla-gender-choice{\r\n\r\n    height:40px;\r\n\r\n    padding:\r\n      0 8px;\r\n\r\n    font-size:\r\n      clamp(10px,3.0cqw,12px) !important;\r\n\r\n  }\r\n\r\n  .lulla-size-section{\r\n\r\n    margin-top:16px;\r\n\r\n  }\r\n\r\n  .lulla-size-grid{\r\n\r\n    gap:5px;\r\n\r\n  }\r\n\r\n  .lulla-size-choice{\r\n\r\n    height:38px;\r\n\r\n    padding:\r\n      0 3px;\r\n\r\n    font-size:\r\n      clamp(9px,2.8cqw,11px) !important;\r\n\r\n  }\r\n\r\n  \/*\r\n   * BACK + START BUILDING ALWAYS ON ONE LINE.\r\n   *\/\r\n\r\n  .lulla-action-row{\r\n\r\n    flex-direction:row !important;\r\n\r\n    align-items:center !important;\r\n\r\n    justify-content:stretch !important;\r\n\r\n    gap:10px;\r\n\r\n    margin-top:30px;\r\n\r\n  }\r\n  .lulla-mobile-back{\r\n    display:flex !important;\r\n    order:1;\r\n    height:42px;\r\n    flex:0 0 auto;\r\n    min-width:64px;\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-mobile-back-text{\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-start-button{\r\n\r\n    order:2;\r\n\r\n    flex:\r\n      1 1 auto;\r\n\r\n    width:auto;\r\n\r\n    min-width:0;\r\n\r\n    height:42px;\r\n\r\n    font-size:\r\n      clamp(9px,3cqw,12px) !important;\r\n\r\n  }\r\n\r\n  .lulla-selected-bar{\r\n\r\n    height:34px;\r\n\r\n    min-height:34px;\r\n\r\n    max-height:34px;\r\n\r\n    padding:\r\n      0 20px;\r\n\r\n  }\r\n\r\n  .lulla-selected-bar.is-size-selection{\r\n\r\n    height:0 !important;\r\n\r\n    min-height:0 !important;\r\n\r\n    max-height:0 !important;\r\n\r\n    padding:0 !important;\r\n\r\n  }\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SHORT PORTRAIT PHONES\r\n   ========================================================= *\/\r\n\r\n@media(max-width:850px) and (orientation:portrait) and (max-height:700px){\r\n\r\n  .lulla-setup-card{\r\n    max-height:calc(100dvh - 8px) !important;\r\n    padding:clamp(6px, 1.6vh, 14px) 0 !important;\r\n  }\r\n\r\n  .lulla-size-section{\r\n    margin-top:12px !important;\r\n  }\r\n\r\n  .lulla-action-row{\r\n    margin-top:24px !important;\r\n  }\r\n\r\n}\r\n\r\n@media(max-width:850px) and (orientation:portrait) and (max-height:600px){\r\n\r\n  .lulla-setup-card{\r\n    padding:4px 0 !important;\r\n  }\r\n\r\n  .lulla-setup-label{\r\n    margin-bottom:6px !important;\r\n  }\r\n\r\n  .lulla-gender-choice{\r\n    height:38px;\r\n  }\r\n\r\n  .lulla-size-section{\r\n    margin-top:9px !important;\r\n  }\r\n\r\n  .lulla-size-choice{\r\n    height:36px;\r\n    min-height:36px;\r\n  }\r\n\r\n  .lulla-action-row{\r\n    margin-top:18px !important;\r\n  }\r\n\r\n}\r\n\r\n@media(max-width:850px) and (orientation:portrait) and (max-height:500px){\r\n\r\n  .lulla-setup-card{\r\n    padding:2px 0 !important;\r\n  }\r\n\r\n  .lulla-setup-label{\r\n    margin-bottom:5px !important;\r\n  }\r\n\r\n  .lulla-gender-row{\r\n    gap:5px;\r\n  }\r\n\r\n  .lulla-gender-choice{\r\n    height:35px;\r\n  }\r\n\r\n  .lulla-size-section{\r\n    margin-top:7px !important;\r\n  }\r\n\r\n  .lulla-size-grid{\r\n    gap:4px;\r\n  }\r\n\r\n  .lulla-size-choice{\r\n    height:33px;\r\n    min-height:33px;\r\n  }\r\n\r\n  .lulla-action-row{\r\n    margin-top:14px !important;\r\n  }\r\n\r\n  .lulla-mobile-back,\r\n  .lulla-start-button{\r\n    height:37px;\r\n  }\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   MOBILE LANDSCAPE\r\n   ========================================================= *\/\r\n\r\n@media(\r\n  max-width:850px\r\n)\r\nand\r\n(orientation:landscape){\r\n\r\n  \/*\r\n   * Landscape uses the large Playfair question.\r\n   *\/\r\n\r\n  .lulla-setup-overlay{\r\n\r\n    display:flex !important;\r\n\r\n    align-items:center !important;\r\n\r\n    justify-content:center !important;\r\n\r\n  }\r\n\r\n  .lulla-setup-card{\r\n\r\n    width:\r\n      min(\r\n        430px,\r\n        calc(100% - 36px)\r\n      );\r\n\r\n    max-width:430px;\r\n\r\n    height:auto !important;\r\n\r\n    max-height:\r\n      calc(100% - 24px) !important;\r\n\r\n    margin:0 auto !important;\r\n\r\n    padding:\r\n      20px 0 !important;\r\n\r\n    justify-content:center !important;\r\n\r\n    overflow:hidden !important;\r\n\r\n  }\r\n\r\n  .lulla-setup-title{\r\n\r\n    display:block !important;\r\n\r\n    font-size:\r\n      clamp(\r\n        30px,\r\n        4vw,\r\n        46px\r\n      ) !important;\r\n\r\n    line-height:.90 !important;\r\n\r\n  }\r\n\r\n  .lulla-gender-section\r\n  .lulla-setup-label{\r\n\r\n    display:none !important;\r\n\r\n  }\r\n\r\n  .lulla-gender-section{\r\n\r\n    margin-top:\r\n      clamp(\r\n        22px,\r\n        4vh,\r\n        34px\r\n      ) !important;\r\n\r\n  }\r\n\r\n  .lulla-size-section{\r\n\r\n    margin-top:\r\n      clamp(\r\n        18px,\r\n        3vh,\r\n        30px\r\n      ) !important;\r\n\r\n  }\r\n\r\n  .lulla-action-row{\r\n\r\n    flex-direction:row !important;\r\n\r\n    align-items:center !important;\r\n\r\n    gap:10px;\r\n\r\n    margin-top:\r\n      clamp(\r\n        20px,\r\n        4vh,\r\n        34px\r\n      ) !important;\r\n\r\n  }\r\n\r\n  .lulla-mobile-back{\r\n    display:flex !important;\r\n    flex:0 0 auto;\r\n    min-width:64px;\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-mobile-back-text{\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-start-button{\r\n\r\n    flex:\r\n      1 1 auto;\r\n\r\n    width:auto;\r\n\r\n  }\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   SMALL PHONE\r\n   ========================================================= *\/\r\n\r\n@media(max-width:420px){\r\n\r\n  .lulla-setup-card{\r\n\r\n    width:\r\n      calc(100% - 40px);\r\n\r\n    margin:\r\n      0 20px;\r\n\r\n    padding:\r\n      24px 0 !important;\r\n\r\n  }\r\n\r\n  .lulla-size-choice{\r\n\r\n    height:38px;\r\n\r\n    min-height:38px;\r\n\r\n  }\r\n\r\n  .lulla-mobile-back{\r\n    min-width:64px;\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-mobile-back-text{\r\n    font-size:clamp(9px,3cqw,12px) !important;\r\n  }\r\n\r\n  .lulla-start-button{\r\n\r\n    font-size:\r\n      clamp(9px,3cqw,12px) !important;\r\n\r\n  }\r\n\r\n  .lulla-selected-bar{\r\n\r\n    height:34px;\r\n\r\n  }\r\n\r\n}\r\n\r\n.gender-tabs.lulla-state1-host{\r\n  position:absolute !important;\r\n  inset:0 !important;\r\n  width:100% !important;\r\n  height:100% !important;\r\n  min-width:0 !important;\r\n  min-height:0 !important;\r\n  max-width:none !important;\r\n  max-height:none !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  z-index:1000 !important;\r\n  overflow:hidden !important;\r\n  pointer-events:auto !important;\r\n}\r\n.gender-tabs.lulla-state1-host > .elementor-element,\r\n.gender-tabs.lulla-state1-host > .elementor-container,\r\n.gender-tabs.lulla-state1-host > .elementor-widget-wrap,\r\n.gender-tabs.lulla-state1-host > .elementor-widget-container,\r\n.gender-tabs.lulla-state1-host > .elementor-widget-html,\r\n.gender-tabs.lulla-state1-host > .elementor-widget-html > .elementor-widget-container{\r\n  width:100% !important;\r\n  height:100% !important;\r\n  min-width:0 !important;\r\n  min-height:0 !important;\r\n  max-width:none !important;\r\n  max-height:none !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  box-sizing:border-box !important;\r\n}\r\n.gender-tabs.lulla-state1-host > nav.gender-tabs{\r\n  position:absolute !important;\r\n  inset:0 !important;\r\n  width:100% !important;\r\n  height:100% !important;\r\n  min-width:0 !important;\r\n  min-height:0 !important;\r\n  max-width:none !important;\r\n  max-height:none !important;\r\n  margin:0 !important;\r\n  padding:0 !important;\r\n  overflow:hidden !important;\r\n  pointer-events:auto !important;\r\n}\r\nhtml.lulla-setup-lock,body.lulla-setup-lock{\r\n  overflow:hidden !important;\r\n}\r\n\r\n\/* =========================================================\r\n   NO OVERFLOW\r\n   ========================================================= *\/\r\n\r\n.lulla-setup-overlay,\r\n.lulla-setup-card,\r\n.lulla-setup-section,\r\n.lulla-gender-row,\r\n.lulla-size-grid,\r\n.lulla-action-row,\r\n.lulla-start-button{\r\n\r\n  max-width:100%;\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n<script>\r\n\r\n(function(){\r\n\r\n  \"use strict\";\r\n\r\n  function initLullaSetup(){\r\n\r\n    document\r\n      .querySelectorAll(\r\n        \".gender-tabs\"\r\n      )\r\n      .forEach(\r\n        function(root){\r\n\r\n          if(\r\n            root.dataset.lullaSetupReady ===\r\n            \"true\"\r\n          ){\r\n\r\n            return;\r\n\r\n          }\r\n\r\n          var host = null;\r\n          var hostWalker = root.parentElement;\r\n          while(hostWalker){\r\n            if(hostWalker.classList && hostWalker.classList.contains(\"gender-tabs\")){\r\n              host = hostWalker;\r\n              break;\r\n            }\r\n            hostWalker = hostWalker.parentElement;\r\n          }\r\n          var panel = root.closest(\".products-panel\") || null;\r\n          if(!host && panel){\r\n            var candidates = panel.querySelectorAll(\".gender-tabs\");\r\n            for(var ci=0;ci<candidates.length;ci++){\r\n              if(candidates[ci] !== root && candidates[ci].contains(root)){\r\n                host = candidates[ci];\r\n                break;\r\n              }\r\n            }\r\n          }\r\n\r\n          var overlay =\r\n            root.querySelector(\r\n              \".lulla-setup-overlay\"\r\n            );\r\n\r\n          var selectedBar =\r\n            root.querySelector(\r\n              \".lulla-selected-bar\"\r\n            );\r\n\r\n          var startButton =\r\n            root.querySelector(\r\n              \".lulla-start-button\"\r\n            );\r\n\r\n          var changeButton =\r\n            root.querySelector(\r\n              \".lulla-change-button\"\r\n            );\r\n\r\n          var backButton =\r\n            root.querySelector(\r\n              \".lulla-mobile-back\"\r\n            );\r\n\r\n          var genderButtons =\r\n            root.querySelectorAll(\r\n              \".lulla-gender-choice\"\r\n            );\r\n\r\n          var sizeButtons =\r\n            root.querySelectorAll(\r\n              \".lulla-size-choice\"\r\n            );\r\n\r\n          if(\r\n            !host ||\r\n            !overlay ||\r\n            !selectedBar ||\r\n            !startButton ||\r\n            !changeButton ||\r\n            !genderButtons.length ||\r\n            !sizeButtons.length\r\n          ){\r\n\r\n            return;\r\n\r\n          }\r\n\r\n          root.dataset.lullaSetupReady =\r\n            \"true\";\r\n\r\n          var selectedGender =\r\n            null;\r\n\r\n          var selectedSize =\r\n            null;\r\n\r\n          var hostStyleSnapshot =\r\n            host.getAttribute(\"style\") || \"\";\r\n          var rootStyleSnapshot =\r\n            root.getAttribute(\"style\") || \"\";\r\n          var overlayStyleSnapshot =\r\n            overlay.getAttribute(\"style\") || \"\";\r\n\r\n          function setSetupState(active){\r\n            var next = !!active;\r\n            if(panel && getComputedStyle(panel).position === \"static\"){\r\n              panel.style.position = \"relative\";\r\n            }\r\n            if(next){\r\n              host.classList.add(\"lulla-state1-host\");\r\n              host.style.position = \"absolute\";\r\n              host.style.inset = \"0\";\r\n              host.style.width = \"100%\";\r\n              host.style.height = \"100%\";\r\n              host.style.minWidth = \"0\";\r\n              host.style.minHeight = \"0\";\r\n              host.style.maxWidth = \"none\";\r\n              host.style.maxHeight = \"none\";\r\n              host.style.margin = \"0\";\r\n              host.style.padding = \"0\";\r\n              host.style.zIndex = \"1000\";\r\n              host.style.overflow = \"hidden\";\r\n              host.style.pointerEvents = \"auto\";\r\n              root.style.position = \"absolute\";\r\n              root.style.inset = \"0\";\r\n              root.style.width = \"100%\";\r\n              root.style.height = \"100%\";\r\n              root.style.minWidth = \"0\";\r\n              root.style.minHeight = \"0\";\r\n              root.style.maxWidth = \"none\";\r\n              root.style.maxHeight = \"none\";\r\n              root.style.margin = \"0\";\r\n              root.style.padding = \"0\";\r\n              root.style.overflow = \"hidden\";\r\n              root.style.pointerEvents = \"auto\";\r\n              overlay.style.position = \"absolute\";\r\n              overlay.style.inset = \"0\";\r\n              overlay.style.width = \"100%\";\r\n              overlay.style.height = \"100%\";\r\n              overlay.style.pointerEvents = \"auto\";\r\n              document.documentElement.classList.add(\"lulla-setup-lock\");\r\n              document.body.classList.add(\"lulla-setup-lock\");\r\n            }else{\r\n              host.classList.remove(\"lulla-state1-host\");\r\n              host.setAttribute(\"style\",hostStyleSnapshot);\r\n              root.setAttribute(\"style\",rootStyleSnapshot);\r\n              overlay.setAttribute(\"style\",overlayStyleSnapshot);\r\n              document.documentElement.classList.remove(\"lulla-setup-lock\");\r\n              document.body.classList.remove(\"lulla-setup-lock\");\r\n            }\r\n          }\r\n\r\n          var sizeLabels = {\r\n\r\n            \"9-12m\":\r\n              \"9\u201312M\",\r\n\r\n            \"12-18m\":\r\n              \"12\u201318M\",\r\n\r\n            \"2-3y\":\r\n              \"2\u20133Y\",\r\n\r\n            \"3-4y\":\r\n              \"3\u20134Y\"\r\n\r\n          };\r\n\r\n          \/* =================================================\r\n             MOVE BAR TO BODY\r\n             ================================================= *\/\r\n\r\n          if(\r\n            selectedBar.parentNode !==\r\n            document.body\r\n          ){\r\n\r\n            document.body.appendChild(\r\n              selectedBar\r\n            );\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             HELPERS\r\n             ================================================= *\/\r\n\r\n          function findBuilder(){\r\n\r\n            return (\r\n              root.closest(\r\n                \".build-outfit\"\r\n              )\r\n              ||\r\n              document.querySelector(\r\n                \".build-outfit\"\r\n              )\r\n            );\r\n\r\n          }\r\n\r\n          function findProductsPanel(){\r\n\r\n            var panel =\r\n              root.closest(\r\n                \".products-panel\"\r\n              );\r\n\r\n            if(!panel){\r\n\r\n              var build =\r\n                root.closest(\r\n                  \".build-outfit\"\r\n                );\r\n\r\n              if(build){\r\n\r\n                panel =\r\n                  build.querySelector(\r\n                    \".products-panel\"\r\n                  );\r\n\r\n              }\r\n\r\n            }\r\n\r\n            return panel;\r\n\r\n          }\r\n\r\n          function getValidRect(el){\r\n\r\n            if(!el){\r\n\r\n              return null;\r\n\r\n            }\r\n\r\n            var rect =\r\n              el.getBoundingClientRect();\r\n\r\n            if(\r\n              rect.width < 10 ||\r\n              rect.height < 10\r\n            ){\r\n\r\n              return null;\r\n\r\n            }\r\n\r\n            return rect;\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             STATE \/ LAYOUT\r\n             ================================================= *\/\r\n\r\n          function positionOverlay(){}\r\n\r\n          \/* =================================================\r\n             POSITION SELECTED BAR\r\n             ================================================= *\/\r\n\r\n          function positionSelectedBar(){\r\n\r\n            if(\r\n              selectedBar.classList.contains(\r\n                \"is-size-selection\"\r\n              )\r\n            ){\r\n\r\n              return;\r\n\r\n            }\r\n\r\n            var rect =\r\n              getValidRect(\r\n                findProductsPanel()\r\n              );\r\n\r\n            if(!rect){\r\n\r\n              return;\r\n\r\n            }\r\n\r\n            var scrollX =\r\n              window.pageXOffset ||\r\n              document.documentElement\r\n                .scrollLeft ||\r\n              0;\r\n\r\n            var scrollY =\r\n              window.pageYOffset ||\r\n              document.documentElement\r\n                .scrollTop ||\r\n              0;\r\n\r\n            var barHeight =\r\n              window.innerWidth <= 850\r\n                ? 34\r\n                : 60;\r\n\r\n            selectedBar.style.position =\r\n              \"absolute\";\r\n\r\n            selectedBar.style.left =\r\n              (\r\n                rect.left +\r\n                scrollX\r\n              ) + \"px\";\r\n\r\n            selectedBar.style.top =\r\n              (\r\n                rect.top +\r\n                scrollY\r\n              ) + \"px\";\r\n\r\n            selectedBar.style.width =\r\n              rect.width + \"px\";\r\n\r\n            selectedBar.style.height =\r\n              barHeight + \"px\";\r\n\r\n          }\r\n\r\n          function positionElements(){\r\n            positionSelectedBar();\r\n          }\r\n\r\n          function schedulePositioning(){\r\n\r\n            positionElements();\r\n\r\n            window.requestAnimationFrame(\r\n              positionElements\r\n            );\r\n\r\n            [100,300,700]\r\n              .forEach(\r\n                function(delay){\r\n\r\n                  window.setTimeout(\r\n                    positionElements,\r\n                    delay\r\n                  );\r\n\r\n                }\r\n              );\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             SELECTED BAR\r\n             ================================================= *\/\r\n\r\n          function updateSelectedBar(){\r\n\r\n            var gender =\r\n              selectedBar.querySelector(\r\n                \".lulla-selected-gender\"\r\n              );\r\n\r\n            var size =\r\n              selectedBar.querySelector(\r\n                \".lulla-selected-size\"\r\n              );\r\n\r\n            if(gender){\r\n\r\n              gender.textContent =\r\n                selectedGender === \"boys\"\r\n                  ? \"BOY\"\r\n                  : selectedGender === \"girls\"\r\n                    ? \"GIRL\"\r\n                    : \"\";\r\n\r\n            }\r\n\r\n            if(size){\r\n\r\n              size.textContent =\r\n                sizeLabels[\r\n                  selectedSize\r\n                ] ||\r\n                selectedSize;\r\n\r\n            }\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             SELECT\r\n             ================================================= *\/\r\n\r\n          function selectFrom(\r\n            list,\r\n            button\r\n          ){\r\n\r\n            list.forEach(\r\n              function(item){\r\n\r\n                var active =\r\n                  !!button && item === button;\r\n\r\n                item.classList.toggle(\r\n                  \"is-active\",\r\n                  active\r\n                );\r\n\r\n                item.setAttribute(\r\n                  \"aria-checked\",\r\n                  active\r\n                    ? \"true\"\r\n                    : \"false\"\r\n                );\r\n\r\n              }\r\n            );\r\n\r\n          }\r\n\r\n          function updateStartButton(){\r\n\r\n            var ready =\r\n              !!selectedGender &&\r\n              !!selectedSize;\r\n\r\n            startButton.disabled =\r\n              !ready;\r\n\r\n            startButton.setAttribute(\r\n              \"aria-disabled\",\r\n              ready ? \"false\" : \"true\"\r\n            );\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             GENDER\r\n             ================================================= *\/\r\n\r\n          genderButtons.forEach(\r\n            function(button){\r\n\r\n              button.addEventListener(\r\n                \"click\",\r\n                function(){\r\n\r\n                  selectFrom(\r\n                    genderButtons,\r\n                    button\r\n                  );\r\n\r\n                  selectedGender =\r\n                    button.dataset.gender;\r\n\r\n                  updateStartButton();\r\n\r\n                }\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             SIZE\r\n             ================================================= *\/\r\n\r\n          sizeButtons.forEach(\r\n            function(button){\r\n\r\n              button.addEventListener(\r\n                \"click\",\r\n                function(){\r\n\r\n                  selectFrom(\r\n                    sizeButtons,\r\n                    button\r\n                  );\r\n\r\n                  selectedSize =\r\n                    button.dataset.ageRange;\r\n\r\n                  updateStartButton();\r\n\r\n                }\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             BACK\r\n             ================================================= *\/\r\n\r\n          if(backButton){\r\n\r\n            backButton.addEventListener(\r\n              \"click\",\r\n              function(event){\r\n\r\n                if(event){\r\n                  event.preventDefault();\r\n                  event.stopPropagation();\r\n                }\r\n\r\n                window.location.href =\r\n                  \"https:\/\/lullastudio.com\/\";\r\n\r\n              }\r\n            );\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             START BUILDING\r\n             ================================================= *\/\r\n\r\n          startButton.addEventListener(\r\n            \"click\",\r\n            function(){\r\n\r\n              if(!selectedGender || !selectedSize){\r\n                return;\r\n              }\r\n\r\n              updateSelectedBar();\r\n\r\n              var detail = {\r\n\r\n                gender:\r\n                  selectedGender,\r\n\r\n                ageRange:\r\n                  selectedSize\r\n\r\n              };\r\n\r\n              document.dispatchEvent(\r\n                new CustomEvent(\r\n                  \"lulla:gender-change\",\r\n                  {\r\n                    bubbles:true,\r\n                    detail:detail\r\n                  }\r\n                )\r\n              );\r\n\r\n              root.dispatchEvent(\r\n                new CustomEvent(\r\n                  \"lulla:catalog-filter-change\",\r\n                  {\r\n                    bubbles:true,\r\n                    detail:detail\r\n                  }\r\n                )\r\n              );\r\n\r\n              positionSelectedBar();\r\n\r\n              void selectedBar.offsetWidth;\r\n\r\n              window.requestAnimationFrame(\r\n                function(){\r\n\r\n                  selectedBar.classList.add(\r\n                    \"is-visible\"\r\n                  );\r\n\r\n                }\r\n              );\r\n\r\n              root.classList.add(\r\n                \"is-leaving\"\r\n              );\r\n\r\n              window.setTimeout(\r\n                function(){\r\n                  setSetupState(false);\r\n                  root.classList.add(\"is-selected\");\r\n                },\r\n                300\r\n              );\r\n\r\n              window.setTimeout(\r\n                positionElements,\r\n                500\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             CHANGE\r\n             ================================================= *\/\r\n\r\n          changeButton.addEventListener(\r\n            \"click\",\r\n            function(){\r\n\r\n              setSetupState(true);\r\n              root.classList.remove(\"is-selected\");\r\n              root.classList.remove(\"is-leaving\");\r\n              selectedBar.classList.remove(\r\n                \"is-size-selection\"\r\n              );\r\n\r\n              selectedBar.setAttribute(\r\n                \"aria-hidden\",\r\n                \"false\"\r\n              );\r\n\r\n              selectedBar.classList.remove(\r\n                \"is-visible\"\r\n              );\r\n\r\n              root.classList.remove(\r\n                \"is-selected\"\r\n              );\r\n\r\n              root.classList.remove(\r\n                \"is-leaving\"\r\n              );\r\n\r\n              var detail = {\r\n\r\n                gender:\r\n                  selectedGender,\r\n\r\n                ageRange:\r\n                  selectedSize,\r\n\r\n                clearProducts:true\r\n\r\n              };\r\n\r\n              document.dispatchEvent(\r\n                new CustomEvent(\r\n                  \"lulla:setup-change\",\r\n                  {\r\n                    bubbles:true,\r\n                    detail:detail\r\n                  }\r\n                )\r\n              );\r\n\r\n              root.dispatchEvent(\r\n                new CustomEvent(\r\n                  \"lulla:catalog-reset\",\r\n                  {\r\n                    bubbles:true,\r\n                    detail:detail\r\n                  }\r\n                )\r\n              );\r\n\r\n              schedulePositioning();\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             THIRD SCREEN OPEN\r\n             ================================================= *\/\r\n\r\n          document.addEventListener(\r\n            \"lulla:choose-size\",\r\n            function(){\r\n\r\n              selectedBar.classList.add(\r\n                \"is-size-selection\"\r\n              );\r\n\r\n              selectedBar.classList.remove(\r\n                \"is-visible\"\r\n              );\r\n\r\n              selectedBar.setAttribute(\r\n                \"aria-hidden\",\r\n                \"true\"\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             THIRD SCREEN CLOSE\r\n             ================================================= *\/\r\n\r\n          document.addEventListener(\r\n            \"lulla:size-screen-close\",\r\n            function(){\r\n\r\n              selectedBar.classList.remove(\r\n                \"is-size-selection\"\r\n              );\r\n\r\n              selectedBar.setAttribute(\r\n                \"aria-hidden\",\r\n                \"false\"\r\n              );\r\n\r\n              updateSelectedBar();\r\n\r\n              selectedBar.classList.add(\r\n                \"is-visible\"\r\n              );\r\n\r\n              window.requestAnimationFrame(\r\n                positionElements\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             FINAL OUTFIT\r\n             ================================================= *\/\r\n\r\n          document.addEventListener(\r\n            \"lulla:outfit-final\",\r\n            function(){\r\n\r\n              selectedBar.classList.add(\r\n                \"is-size-selection\"\r\n              );\r\n\r\n              selectedBar.classList.remove(\r\n                \"is-visible\"\r\n              );\r\n\r\n              selectedBar.setAttribute(\r\n                \"aria-hidden\",\r\n                \"true\"\r\n              );\r\n\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             INITIAL STATE\r\n             ================================================= *\/\r\n\r\n          selectFrom(\r\n            genderButtons,\r\n            null\r\n          );\r\n\r\n          selectFrom(\r\n            sizeButtons,\r\n            null\r\n          );\r\n\r\n          updateStartButton();\r\n\r\n          setSetupState(true);\r\n          schedulePositioning();\r\n\r\n          \/* =================================================\r\n             RESIZE OBSERVER\r\n             ================================================= *\/\r\n\r\n          var resizeFrame =\r\n            null;\r\n\r\n          if(\r\n            typeof ResizeObserver !==\r\n            \"undefined\"\r\n          ){\r\n\r\n            var observer =\r\n              new ResizeObserver(\r\n                function(){\r\n\r\n                  if(resizeFrame){\r\n\r\n                    cancelAnimationFrame(\r\n                      resizeFrame\r\n                    );\r\n\r\n                  }\r\n\r\n                  resizeFrame =\r\n                    requestAnimationFrame(\r\n                      function(){\r\n\r\n                        positionElements();\r\n\r\n                        resizeFrame =\r\n                          null;\r\n\r\n                      }\r\n                    );\r\n\r\n                }\r\n              );\r\n\r\n            var builder =\r\n              findBuilder();\r\n\r\n            var panel =\r\n              findProductsPanel();\r\n\r\n            if(builder){\r\n\r\n              observer.observe(\r\n                builder\r\n              );\r\n\r\n            }\r\n\r\n            if(panel){\r\n\r\n              observer.observe(\r\n                panel\r\n              );\r\n\r\n            }\r\n\r\n          }\r\n\r\n          \/* =================================================\r\n             WINDOW RESIZE\r\n             ================================================= *\/\r\n\r\n          window.addEventListener(\r\n            \"resize\",\r\n            positionElements,\r\n            {\r\n              passive:true\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             SCROLL\r\n             ================================================= *\/\r\n\r\n          var scrollFrame =\r\n            null;\r\n\r\n          window.addEventListener(\r\n            \"scroll\",\r\n            function(){\r\n\r\n              if(scrollFrame){\r\n\r\n                return;\r\n\r\n              }\r\n\r\n              scrollFrame =\r\n                requestAnimationFrame(\r\n                  function(){\r\n\r\n                    positionSelectedBar();\r\n\r\n                    scrollFrame =\r\n                      null;\r\n\r\n                  }\r\n                );\r\n\r\n            },\r\n            {\r\n              passive:true\r\n            }\r\n          );\r\n\r\n          \/* =================================================\r\n             ORIENTATION\r\n             ================================================= *\/\r\n\r\n          window.addEventListener(\r\n            \"orientationchange\",\r\n            function(){\r\n\r\n              window.setTimeout(\r\n                schedulePositioning,\r\n                120\r\n              );\r\n\r\n            },\r\n            {\r\n              passive:true\r\n            }\r\n          );\r\n\r\n        }\r\n      );\r\n\r\n  }\r\n\r\n  \/* =========================================================\r\n     INIT\r\n     ========================================================= *\/\r\n\r\n  if(\r\n    document.readyState ===\r\n    \"loading\"\r\n  ){\r\n\r\n    document.addEventListener(\r\n      \"DOMContentLoaded\",\r\n      initLullaSetup,\r\n      {\r\n        once:true\r\n      }\r\n    );\r\n\r\n  }else{\r\n\r\n    initLullaSetup();\r\n\r\n  }\r\n\r\n  if(\r\n    typeof jQuery !==\r\n    \"undefined\"\r\n  ){\r\n\r\n    jQuery(window).on(\r\n      \"elementor\/frontend\/init\",\r\n      initLullaSetup\r\n    );\r\n\r\n  }\r\n\r\n})();\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-873df86 e-con-full products-scroll e-flex e-con e-child\" data-id=\"873df86\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9bef2ba elementor-widget elementor-widget-html\" data-id=\"9bef2ba\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div id=\"builder-products-root\"><\/div>\n<style>\n\/* =========================================================\n   LULLA PRODUCT SCROLL\n   PRODUCTION \/ API VERSION\n   ========================================================= *\/\n#builder-products-root{\n    width:100%;\n    height:100%;\n    min-width:0;\n    min-height:0;\n    margin:0;\n    padding:\n        14px 20px 18px;\n    box-sizing:border-box;\n    font-family:\n        \"Inter Tight\",\n        sans-serif !important;\n    overflow-x:hidden;\n    overflow-y:auto;\n    scrollbar-width:none;\n    -webkit-overflow-scrolling:touch;\n    display:flex;\n    flex-direction:column;\n    gap:12px;\n    background:#FCF7F1;\n    position:relative;\n    container-type:size;\n}\n\n#builder-products-root.is-catalog-swapping{\n    opacity:.18;\n    transition:\n        opacity .16s cubic-bezier(.22,.61,.36,1);\n}\n#builder-products-root::-webkit-scrollbar{\n    display:none;\n}\n\/* =========================================================\n   LOADING\n   ========================================================= *\/\n.lulla-products-loading{\n    position:absolute;\n    inset:0;\n    width:100%;\n    height:100%;\n    min-height:0;\n    margin:0;\n    padding:0;\n    box-sizing:border-box;\n    display:flex;\n    align-items:center;\n    justify-content:center;\n    background:#FCF7F1;\n    overflow:hidden;\n    opacity:1;\n    visibility:visible;\n    z-index:20;\n    transition:\n        opacity .8s cubic-bezier(.22,.61,.36,1),\n        visibility 0s linear 0s;\n}\n\n.lulla-products-loading.is-exiting{\n    opacity:0;\n    visibility:hidden;\n    transition:\n        opacity .8s cubic-bezier(.22,.61,.36,1),\n        visibility 0s linear .8s;\n}\n\n.lulla-loader-visual{\n    display:flex;\n    flex-direction:column;\n    align-items:center;\n    justify-content:center;\n    width:min(360px,82%);\n    min-height:220px;\n    margin-top:-2%;\n}\n\n.lulla-loader-text{\n    margin:0 0 28px;\n    font-family:\"Playfair Display\",Georgia,serif !important;\n    font-style:italic !important;\n    font-weight:400;\n    font-size:18px;\n    line-height:1.2;\n    letter-spacing:0;\n    text-align:center;\n    text-transform:none;\n    color:#2D2C2A;\n    opacity:0;\n    transform:translateY(10px);\n    animation:lullaLoaderTextIn .85s cubic-bezier(.22,.61,.36,1) .08s forwards;\n}\n\n.lulla-carousel-scene{\n    width:72px;\n    height:72px;\n    perspective:900px;\n    perspective-origin:50% 50%;\n    position:relative;\n    overflow:visible;\n    opacity:0;\n    transform:translateY(10px);\n    animation:lullaLoaderCarouselIn .95s cubic-bezier(.22,.61,.36,1) .18s forwards;\n}\n\n.lulla-carousel{\n    width:100%;\n    height:100%;\n    position:absolute;\n    transform-style:preserve-3d;\n    animation:\n        lullaSpin\n        7s\n        infinite;\n    animation-timing-function:\n        cubic-bezier(.2,.88,.22,1);\n    will-change:transform;\n}\n\n.lulla-card-wrapper{\n    position:absolute;\n    width:72px;\n    height:72px;\n    left:0;\n    top:0;\n    transform-style:preserve-3d;\n}\n\n.lulla-card-wrapper:nth-child(1){transform:rotateY(0deg) translateZ(112px);}\n.lulla-card-wrapper:nth-child(2){transform:rotateY(60deg) translateZ(112px);}\n.lulla-card-wrapper:nth-child(3){transform:rotateY(120deg) translateZ(112px);}\n.lulla-card-wrapper:nth-child(4){transform:rotateY(180deg) translateZ(112px);}\n.lulla-card-wrapper:nth-child(5){transform:rotateY(240deg) translateZ(112px);}\n.lulla-card-wrapper:nth-child(6){transform:rotateY(300deg) translateZ(112px);}\n\n.lulla-card-face{\n    position:absolute;\n    width:100%;\n    height:100%;\n    border-radius:13px;\n    backface-visibility:hidden;\n    display:flex;\n    align-items:center;\n    justify-content:center;\n    box-sizing:border-box;\n}\n\n.lulla-card-front{\n    background:#FFFFFF;\n    box-shadow:0 8px 22px rgba(45,44,42,.035);\n    border:1px solid rgba(45,44,42,.055);\n}\n\n.lulla-card-back{\n    background:#ECEBE6;\n    transform:rotateY(180deg);\n    border:1px solid rgba(45,44,42,.035);\n}\n\n.lulla-svg-icon{\n    width:41px;\n    height:41px;\n    display:block;\n    overflow:visible;\n    stroke:#2D2C2A;\n    stroke-width:1.45;\n    stroke-linecap:round;\n    stroke-linejoin:round;\n    fill:none;\n}\n\n@keyframes lullaSpin{\n    \/*\n     * Soft stop-and-go carousel motion:\n     * hold \u2192 accelerate \u2192 decelerate into the next card \u2192 hold.\n     * No overshoot and no secondary click\/bounce.\n     * One full loop = 7s \/ six positions.\n     *\/\n    0%{\n        transform:rotateY(0deg);\n    }\n    4.5%{\n        transform:rotateY(0deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    12.5%{\n        transform:rotateY(-60deg);\n    }\n    16.666%{\n        transform:rotateY(-60deg);\n    }\n\n    21.166%{\n        transform:rotateY(-60deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    29.166%{\n        transform:rotateY(-120deg);\n    }\n    33.333%{\n        transform:rotateY(-120deg);\n    }\n\n    37.833%{\n        transform:rotateY(-120deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    45.833%{\n        transform:rotateY(-180deg);\n    }\n    50%{\n        transform:rotateY(-180deg);\n    }\n\n    54.5%{\n        transform:rotateY(-180deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    62.5%{\n        transform:rotateY(-240deg);\n    }\n    66.666%{\n        transform:rotateY(-240deg);\n    }\n\n    71.166%{\n        transform:rotateY(-240deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    79.166%{\n        transform:rotateY(-300deg);\n    }\n    83.333%{\n        transform:rotateY(-300deg);\n    }\n\n    87.833%{\n        transform:rotateY(-300deg);\n        animation-timing-function:cubic-bezier(.48,0,.18,1);\n    }\n    95.833%{\n        transform:rotateY(-360deg);\n    }\n    100%{\n        transform:rotateY(-360deg);\n    }\n}\n\n@keyframes lullaLoaderTextIn{\n    from{opacity:0;transform:translateY(10px);}\n    to{opacity:1;transform:translateY(0);}\n}\n\n@keyframes lullaLoaderCarouselIn{\n    from{opacity:0;transform:translateY(10px) scale(.97);}\n    to{opacity:1;transform:translateY(0) scale(1);}\n}\n\/* =========================================================\n   ERROR\n   ========================================================= *\/\n.lulla-products-error{\n    width:100%;\n    margin:0;\n    padding:\n        14px 0;\n    box-sizing:border-box;\n    font-family:\n        \"Inter Tight\",\n        sans-serif !important;\n    font-size:9px;\n    font-weight:300;\n    line-height:1.35;\n    letter-spacing:.03em;\n    color:\n        rgba(29,29,27,.48);\n}\n\/* =========================================================\n   CATEGORY\n   ========================================================= *\/\n.builder-category{\n    width:100%;\n    min-width:0;\n    min-height:0;\n    margin:0;\n    padding:0;\n    box-sizing:border-box;\n    display:flex;\n    flex-direction:column;\n    animation:\n        builderCategoryFade\n        .38s\n        cubic-bezier(.22,.61,.36,1)\n        both;\n    animation-delay:\n        calc(\n            var(--category-index,0)\n            * 90ms\n        );\n}\n.builder-category-title{\n    flex:0 0 auto;\n    margin:\n        0 0 7px;\n    padding:0;\n    font-family:\n        \"Inter Tight\",\n        sans-serif !important;\n    font-size:\n        clamp(\n            8px,\n            1.55cqh,\n            11px\n        );\n    font-weight:400;\n    line-height:1.1;\n    letter-spacing:.08em;\n    text-transform:uppercase;\n    color:\n        rgba(29,29,27,.55);\n    animation:\n        builderTitleFade\n        .32s\n        cubic-bezier(.22,.61,.36,1)\n        both;\n    animation-delay:\n        calc(\n            var(--category-index,0)\n            * 90ms\n            + 45ms\n        );\n}\n.builder-product-wrap{\n    position:relative;\n    width:100%;\n    min-width:0;\n    min-height:0;\n    box-sizing:border-box;\n    flex:1 1 auto;\n}\n\/* =========================================================\n   RAIL\n   ========================================================= *\/\n.builder-product-rail{\n    display:flex;\n    align-items:flex-start;\n    gap:\n        clamp(\n            8px,\n            1.35cqh,\n            12px\n        );\n    width:100%;\n    height:100%;\n    margin:0;\n    padding:0 4px;\n    box-sizing:border-box;\n    overflow-x:auto;\n    overflow-y:hidden;\n    scrollbar-width:none;\n    -webkit-overflow-scrolling:touch;\n    overscroll-behavior-x:contain;\n    scroll-behavior:auto;\n    cursor:grab;\n    user-select:none;\n    touch-action:\n        pan-x pan-y;\n}\n.builder-product-rail::-webkit-scrollbar{\n    display:none;\n}\n.builder-product-rail.is-mouse-dragging{\n    cursor:grabbing;\n}\n\/* =========================================================\n   CARD\n   ========================================================= *\/\n.builder-product-card{\n    position:relative;\n    flex:\n        0 0\n        var(--fit-card-size,88px)\n        !important;\n    width:\n        var(--fit-card-size,88px)\n        !important;\n    height:\n        var(--fit-card-size,88px)\n        !important;\n    min-width:0;\n    min-height:0;\n    display:flex;\n    align-items:center;\n    justify-content:center;\n    margin:0 !important;\n    padding:0 !important;\n    box-sizing:border-box;\n    appearance:none !important;\n    -webkit-appearance:none !important;\n    border:\n        1px solid\n        rgba(0,0,0,.08)\n        !important;\n    border-radius:\n        11px\n        !important;\n    outline:none !important;\n    box-shadow:none !important;\n    background:#fff !important;\n    background-color:#fff !important;\n    background-image:none !important;\n    cursor:pointer;\n    overflow:hidden;\n    transform:none !important;\n    -webkit-tap-highlight-color:\n        transparent;\n    touch-action:\n        pan-x pan-y;\n    opacity:0;\n    animation:\n        builderCardFade\n        .38s\n        cubic-bezier(.22,.61,.36,1)\n        forwards;\n    animation-delay:\n        calc(\n            var(--category-index,0)\n            * 90ms\n            + var(--card-index,0)\n            * 20ms\n            + 55ms\n        );\n    transition:\n        border-color .2s ease,\n        box-shadow .2s ease;\n}\n.builder-product-card:hover{\n    border-color:\n        rgba(107,117,87,.35)\n        !important;\n    box-shadow:\n        0\n        0\n        0\n        1px\n        rgba(107,117,87,.06);\n    background:#fff !important;\n    background-color:#fff !important;\n    transform:none !important;\n}\n.builder-product-card:focus,\n.builder-product-card:focus-visible,\n.builder-product-card:active{\n    background:#fff !important;\n    background-color:#fff !important;\n    background-image:none !important;\n    outline:none !important;\n    box-shadow:none !important;\n    transform:none !important;\n}\n.builder-product-card.is-selected,\n.builder-product-card.is-selected:hover,\n.builder-product-card.is-selected:focus,\n.builder-product-card.is-selected:focus-visible,\n.builder-product-card.is-selected:active{\n    border:\n        2px solid\n        #6B7557\n        !important;\n    background:#fff !important;\n    background-color:#fff !important;\n    background-image:none !important;\n    box-shadow:none !important;\n    transform:none !important;\n}\n\/* =========================================================\n   IMAGE\n   ========================================================= *\/\n.builder-product-card img{\n    display:block !important;\n    width:100% !important;\n    height:100% !important;\n    min-width:100% !important;\n    min-height:100% !important;\n    max-width:none !important;\n    max-height:none !important;\n    margin:0 !important;\n    padding:0 !important;\n    object-fit:contain !important;\n    transform:\n        translateZ(0)\n        scale(1.08)\n        !important;\n    transform-origin:center center !important;\n    opacity:1 !important;\n    visibility:visible !important;\n    pointer-events:none;\n    user-select:none;\n    -webkit-user-drag:none;\n    transition:\n        transform .2s ease;\n}\n.builder-product-card:hover img{\n    transform:\n        translateZ(0)\n        scale(1.10)\n        !important;\n}\n.builder-product-card.is-selected img{\n    transform:\n        translateZ(0)\n        scale(1.10)\n        !important;\n}\n\n\/* =========================================================\n   LULLA CARD EDGE SAFETY\n   Keep transparent product images fully inside their card.\n   The PNG keeps its own alpha; the card remains the clipping\n   surface, but the image no longer scales aggressively into\n   the rounded corners.\n   ========================================================= *\/\n.builder-product-card img{\n    box-sizing:border-box;\n    object-position:center center !important;\n}\n\/* =========================================================\n   ONEPIECE\n   ========================================================= *\/\n.builder-product-card.is-onepiece{\n    flex:\n        0 0\n        var(--fit-card-size,88px)\n        !important;\n    width:\n        var(--fit-card-size,88px)\n        !important;\n    height:\n        calc(\n            var(--fit-card-size,88px)\n            * 1.333333\n        )\n        !important;\n    min-width:\n        var(--fit-card-size,88px);\n    min-height:\n        calc(\n            var(--fit-card-size,88px)\n            * 1.333333\n        );\n    max-width:none !important;\n    max-height:none !important;\n    border-radius:\n        11px\n        !important;\n}\n.builder-product-card.is-onepiece img{\n    transform:\n        translateZ(0)\n        scale(1.06)\n        !important;\n}\n.builder-product-card.is-onepiece:hover img,\n.builder-product-card.is-onepiece.is-selected img{\n    transform:\n        translateZ(0)\n        scale(1.08)\n        !important;\n}\n\/* =========================================================\n   NO IMAGE\n   ========================================================= *\/\n.builder-product-card.is-no-image{\n    background:\n        rgba(29,29,27,.025)\n        !important;\n}\n.builder-product-card.is-no-image::after{\n    content:\n        \"NO IMAGE\";\n    font-family:\n        \"Inter Tight\",\n        sans-serif;\n    font-size:7px;\n    font-weight:300;\n    letter-spacing:.05em;\n    color:\n        rgba(29,29,27,.35);\n}\n\/* =========================================================\n   ANIMATIONS\n   ========================================================= *\/\n@keyframes builderCardFade{\n    from{\n        opacity:0;\n        transform:\n            translateY(5px);\n    }\n    to{\n        opacity:1;\n        transform:\n            translateY(0);\n    }\n}\n@keyframes builderCategoryFade{\n    from{\n        opacity:0;\n        transform:\n            translateY(4px);\n    }\n    to{\n        opacity:1;\n        transform:\n            translateY(0);\n    }\n}\n@keyframes builderTitleFade{\n    from{\n        opacity:0;\n    }\n    to{\n        opacity:1;\n    }\n}\n\/* =========================================================\n   GRADIENT\n   ========================================================= *\/\n.builder-product-edge{\n    position:absolute;\n    top:0;\n    bottom:0;\n    width:30px;\n    pointer-events:none;\n    z-index:5;\n    opacity:0;\n    visibility:hidden;\n    transition:\n        opacity .35s ease,\n        visibility .35s ease;\n}\n.builder-product-edge-right{\n    right:-1px;\n    background:\n        linear-gradient(\n            to left,\n            #FCF7F1 0%,\n            #FCF7F1 14%,\n            rgba(252,247,241,.92) 30%,\n            rgba(252,247,241,.68) 48%,\n            rgba(252,247,241,.38) 68%,\n            rgba(252,247,241,.14) 84%,\n            rgba(252,247,241,0) 100%\n        );\n}\n.builder-product-edge-left{\n    left:-1px;\n    background:\n        linear-gradient(\n            to right,\n            #FCF7F1 0%,\n            #FCF7F1 14%,\n            rgba(252,247,241,.92) 30%,\n            rgba(252,247,241,.68) 48%,\n            rgba(252,247,241,.38) 68%,\n            rgba(252,247,241,.14) 84%,\n            rgba(252,247,241,0) 100%\n        );\n}\n\/* =========================================================\n   ARROWS\n   ========================================================= *\/\n.builder-product-arrow{\n    position:absolute;\n    top:0;\n    bottom:0;\n    width:28px;\n    height:auto;\n    padding:0 !important;\n    margin:0 !important;\n    border:0 !important;\n    border-radius:0 !important;\n    outline:none !important;\n    box-shadow:none !important;\n    background:transparent !important;\n    background-color:transparent !important;\n    background-image:none !important;\n    display:flex;\n    align-items:center;\n    cursor:pointer;\n    opacity:0;\n    visibility:hidden;\n    pointer-events:none;\n    z-index:10;\n    -webkit-tap-highlight-color:\n        transparent;\n    touch-action:manipulation;\n    transition:\n        opacity .35s ease,\n        visibility .35s ease;\n}\n.builder-product-arrow-right{\n    right:-1px;\n    justify-content:flex-end;\n    padding-right:1px !important;\n}\n.builder-product-arrow-left{\n    left:-1px;\n    justify-content:flex-start;\n    padding-left:1px !important;\n}\n.builder-product-arrow svg{\n    width:11px;\n    height:17px;\n    display:block;\n    pointer-events:none;\n}\n.builder-product-arrow svg path{\n    fill:none;\n    stroke:\n        rgba(29,29,27,.56);\n    stroke-width:1.3;\n    stroke-linecap:round;\n    stroke-linejoin:round;\n}\n.builder-product-arrow:hover svg path{\n    stroke:\n        rgba(29,29,27,.74);\n}\n\/* =========================================================\n   ARROW STATES\n   ========================================================= *\/\n.builder-product-wrap.has-more\n.builder-product-edge-right{\n    opacity:1;\n    visibility:visible;\n}\n.builder-product-wrap.has-more\n.builder-product-arrow-right{\n    opacity:1;\n    visibility:visible;\n    pointer-events:auto;\n}\n.builder-product-wrap.has-left\n.builder-product-edge-left{\n    opacity:1;\n    visibility:visible;\n}\n.builder-product-wrap.has-left\n.builder-product-arrow-left{\n    opacity:1;\n    visibility:visible;\n    pointer-events:auto;\n}\n.builder-product-wrap.at-end\n.builder-product-edge-right{\n    opacity:0;\n    visibility:hidden;\n}\n.builder-product-wrap.at-end\n.builder-product-arrow-right{\n    opacity:0;\n    visibility:hidden;\n    pointer-events:none;\n}\n.builder-product-wrap.at-start\n.builder-product-edge-left{\n    opacity:0;\n    visibility:hidden;\n}\n.builder-product-wrap.at-start\n.builder-product-arrow-left{\n    opacity:0;\n    visibility:hidden;\n    pointer-events:none;\n}\n\/* =========================================================\n   LANDSCAPE\n   ========================================================= *\/\n@media(\n    min-width:601px\n)\nand (\n    orientation:landscape\n){\n    #builder-products-root{\n        overflow-y:hidden;\n        gap:12px;\n    }\n    .builder-category{\n        flex:0 0 auto;\n        min-height:0;\n    }\n    .builder-product-wrap{\n        flex:0 0 auto;\n        min-height:0;\n        height:auto;\n    }\n    .builder-product-rail{\n        height:auto;\n        align-items:flex-start;\n    }\n}\n\/* =========================================================\n   LANDSCAPE \u2014 ADAPTIVE FIT\n   Categories keep natural row heights instead of stretching\n   to arbitrary equal-height bands; the shared card size is\n   fitted to the real available height so every row stays\n   fully visible while still leaving deliberate breathing room.\n   - is-compact-fit: max card size was reached with room to\n     spare (few active categories) \u2014 stop stretching rows,\n     stack them top to bottom at their natural height instead\n     of spreading them out with big gaps.\n   - is-scroll-fallback: even the minimum card size wouldn't\n     fit every active category on screen (many categories \/\n     short viewport, e.g. a phone in landscape) \u2014 stop trying\n     to cram everything in (which was causing rows to get\n     compressed thinner than their cards and overlap\/clip) and\n     fall back to a normal scrollable list instead.\n   ========================================================= *\/\n@media(min-width:601px) and (orientation:landscape){\n    #builder-products-root.is-scroll-fallback{\n        overflow-y:auto;\n    }\n    #builder-products-root.is-scroll-fallback .builder-category{\n        flex:0 0 auto;\n        min-height:0;\n    }\n    #builder-products-root.is-scroll-fallback .builder-product-wrap{\n        flex:0 0 auto;\n        min-height:0;\n        height:auto;\n    }\n    #builder-products-root.is-scroll-fallback .builder-product-rail{\n        height:auto;\n    }\n    #builder-products-root.is-compact-fit .builder-category{\n        flex:0 0 auto;\n    }\n    #builder-products-root.is-compact-fit .builder-product-wrap{\n        flex:0 0 auto;\n        height:auto;\n    }\n}\n\/* =========================================================\n   TABLET LANDSCAPE\n   ========================================================= *\/\n@media(\n    min-width:601px\n)\nand (\n    max-width:850px\n)\nand (\n    orientation:landscape\n){\n    .builder-product-rail{\n        gap:10px;\n    }\n    .builder-product-card{\n        border-radius:\n            11px\n            !important;\n    }\n}\n\/* =========================================================\n   PORTRAIT TABLET\n   ========================================================= *\/\n@media(\n    min-width:601px\n)\nand (\n    max-width:850px\n)\nand (\n    orientation:portrait\n){\n    #builder-products-root{\n        overflow-y:auto;\n        overflow-x:hidden;\n        gap:12px;\n    }\n    .builder-category{\n        flex:0 0 auto;\n    }\n    .builder-product-rail{\n        height:auto;\n        gap:10px;\n    }\n    .builder-product-card{\n        flex:\n            0 0\n            88px\n            !important;\n        width:\n            88px\n            !important;\n        height:\n            88px\n            !important;\n        min-width:\n            88px\n            !important;\n        min-height:\n            88px\n            !important;\n        max-width:\n            88px\n            !important;\n        max-height:\n            88px\n            !important;\n        border-radius:\n            11px\n            !important;\n    }\n    .builder-product-card.is-onepiece{\n        flex:\n            0 0\n            88px\n            !important;\n        width:\n            88px\n            !important;\n        height:\n            117.333px\n            !important;\n        min-width:\n            88px\n            !important;\n        min-height:\n            117.333px\n            !important;\n        max-width:\n            88px\n            !important;\n        max-height:\n            117.333px\n            !important;\n    }\n}\n\/* =========================================================\n   SMALLER PORTRAIT TABLET\n   ========================================================= *\/\n@media(\n    min-width:601px\n)\nand (\n    max-width:699px\n)\nand (\n    orientation:portrait\n){\n    .builder-product-card{\n        flex:\n            0 0\n            80px\n            !important;\n        width:\n            80px\n            !important;\n        height:\n            80px\n            !important;\n        min-width:\n            80px\n            !important;\n        min-height:\n            80px\n            !important;\n        max-width:\n            80px\n            !important;\n        max-height:\n            80px\n            !important;\n    }\n    .builder-product-card.is-onepiece{\n        flex:\n            0 0\n            80px\n            !important;\n        width:\n            80px\n            !important;\n        height:\n            106.666px\n            !important;\n        min-width:\n            80px\n            !important;\n        min-height:\n            106.666px\n            !important;\n        max-width:\n            80px\n            !important;\n        max-height:\n            106.666px\n            !important;\n    }\n}\n\/* =========================================================\n   PHONE\n   ========================================================= *\/\n@media(max-width:600px){\n    #builder-products-root{\n        padding-top:12px;\n        padding-left:20px;\n        padding-right:20px;\n        padding-bottom:18px;\n        gap:12px;\n        overflow-y:auto;\n        overflow-x:hidden;\n    }\n    .builder-category{\n        flex:0 0 auto;\n    }\n    .builder-category-title{\n        font-size:9px;\n        margin-bottom:7px;\n    }\n    .builder-product-rail{\n        height:auto;\n        gap:9px;\n    }\n    .builder-product-card{\n        flex:\n            0 0\n            68px\n            !important;\n        width:\n            68px\n            !important;\n        height:\n            68px\n            !important;\n        min-width:\n            68px\n            !important;\n        min-height:\n            68px\n            !important;\n        max-width:\n            68px\n            !important;\n        max-height:\n            68px\n            !important;\n        border-radius:\n            10px\n            !important;\n    }\n    .builder-product-card.is-onepiece{\n        flex:\n            0 0\n            68px\n            !important;\n        width:\n            68px\n            !important;\n        height:\n            90.666px\n            !important;\n        min-width:\n            68px\n            !important;\n        min-height:\n            90.666px\n            !important;\n        max-width:\n            68px\n            !important;\n        max-height:\n            90.666px\n            !important;\n    }\n}\n\/* =========================================================\n   SMALL PHONE\n   ========================================================= *\/\n@media(max-width:420px){\n    #builder-products-root{\n        padding-top:12px;\n        padding-bottom:16px;\n        gap:6px;\n    }\n    .builder-product-rail{\n        gap:8px;\n    }\n    .builder-product-card{\n        flex:\n            0 0\n            64px\n            !important;\n        width:\n            64px\n            !important;\n        height:\n            64px\n            !important;\n        min-width:\n            64px\n            !important;\n        min-height:\n            64px\n            !important;\n        max-width:\n            64px\n            !important;\n        max-height:\n            64px\n            !important;\n        border-radius:\n            9px\n            !important;\n    }\n    .builder-product-card.is-onepiece{\n        flex:\n            0 0\n            64px\n            !important;\n        width:\n            64px\n            !important;\n        height:\n            85.333px\n            !important;\n        min-width:\n            64px\n            !important;\n        min-height:\n            85.333px\n            !important;\n        max-width:\n            64px\n            !important;\n        max-height:\n            85.333px\n            !important;\n    }\n}\n@media(max-width:600px){\n    .lulla-loader-text{\n        font-size:17px;\n        margin-bottom:24px;\n    }\n\n    \/* PHONE LOADER \u2014 cards 30% smaller *\/\n    .lulla-carousel-scene{\n        width:46px;\n        height:46px;\n        perspective:574px;\n    }\n\n    .lulla-card-wrapper{\n        width:46px;\n        height:46px;\n    }\n\n    .lulla-card-wrapper:nth-child(1){transform:rotateY(0deg) translateZ(71px);}\n    .lulla-card-wrapper:nth-child(2){transform:rotateY(60deg) translateZ(71px);}\n    .lulla-card-wrapper:nth-child(3){transform:rotateY(120deg) translateZ(71px);}\n    .lulla-card-wrapper:nth-child(4){transform:rotateY(180deg) translateZ(71px);}\n    .lulla-card-wrapper:nth-child(5){transform:rotateY(240deg) translateZ(71px);}\n    .lulla-card-wrapper:nth-child(6){transform:rotateY(300deg) translateZ(71px);}\n\n    .lulla-svg-icon{\n        width:26px;\n        height:26px;\n    }\n}\n\n\/* =========================================================\n   LANDSCAPE, SHORT VIEWPORT \u2014 FIT LOADER TO AVAILABLE PANEL SPACE\n   Keyed off available HEIGHT (not viewport width) so it\n   reliably catches real phones in landscape \u2014 a landscape\n   phone is usually well over 600px WIDE, so a width-only\n   query never matched real devices. Tablets in landscape\n   keep the full-size loader since their height stays above\n   this threshold.\n   ========================================================= *\/\n@media(orientation:landscape) and (max-height:520px){\n    .lulla-loader-visual{\n        width:min(92%, 340px);\n        min-height:0;\n        margin-top:0;\n    }\n\n    .lulla-loader-text{\n        font-size:clamp(14px, 4.1cqh, 17px);\n        margin-bottom:clamp(13px, 4.5cqh, 20px);\n    }\n\n    .lulla-carousel-scene{\n        width:clamp(46px, 17cqh, 58px);\n        height:clamp(46px, 17cqh, 58px);\n        perspective:clamp(560px, 210cqh, 760px);\n    }\n\n    .lulla-card-wrapper{\n        width:clamp(46px, 17cqh, 58px);\n        height:clamp(46px, 17cqh, 58px);\n    }\n\n    .lulla-card-wrapper:nth-child(1),\n    .lulla-card-wrapper:nth-child(2),\n    .lulla-card-wrapper:nth-child(3),\n    .lulla-card-wrapper:nth-child(4),\n    .lulla-card-wrapper:nth-child(5),\n    .lulla-card-wrapper:nth-child(6){\n        --loader-radius:clamp(68px, 25cqh, 82px);\n    }\n\n    .lulla-card-wrapper:nth-child(1){transform:rotateY(0deg) translateZ(var(--loader-radius));}\n    .lulla-card-wrapper:nth-child(2){transform:rotateY(60deg) translateZ(var(--loader-radius));}\n    .lulla-card-wrapper:nth-child(3){transform:rotateY(120deg) translateZ(var(--loader-radius));}\n    .lulla-card-wrapper:nth-child(4){transform:rotateY(180deg) translateZ(var(--loader-radius));}\n    .lulla-card-wrapper:nth-child(5){transform:rotateY(240deg) translateZ(var(--loader-radius));}\n    .lulla-card-wrapper:nth-child(6){transform:rotateY(300deg) translateZ(var(--loader-radius));}\n\n    .lulla-svg-icon{\n        width:clamp(27px, 10cqh, 33px);\n        height:clamp(27px, 10cqh, 33px);\n    }\n}\n\n\/* =========================================================\n   TOUCH\n   ========================================================= *\/\n@media(pointer:coarse){\n    .builder-product-arrow{\n        z-index:30;\n    }\n    .builder-product-wrap.has-more\n    .builder-product-arrow-right{\n        opacity:1 !important;\n        visibility:visible !important;\n        pointer-events:auto !important;\n    }\n    .builder-product-wrap.has-left\n    .builder-product-arrow-left{\n        opacity:1 !important;\n        visibility:visible !important;\n        pointer-events:auto !important;\n    }\n}\n<\/style>\n<script>\n(function(){\n    \"use strict\";\n    \/* =========================================================\n       CONFIG\n       ========================================================= *\/\n    const CONFIG = {\n        apiUrl:\n            \"\/wp-json\/lulla\/v1\/mixmatch-catalog\",\n        categories:[\n            {\n                slug:\"tops\",\n                label:\"TOPS\"\n            },\n            {\n                slug:\"bottoms\",\n                label:\"BOTTOMS\"\n            },\n            {\n                slug:\"onepiece-sets\",\n                label:\"ONEPIECE + SETS\"\n            },\n            {\n                slug:\"dresses\",\n                label:\"DRESSES\"\n            },\n            {\n                slug:\"outwear\",\n                label:\"OUTWEAR\"\n            },\n            {\n                slug:\"hats\",\n                label:\"HATS\"\n            },\n            {\n                slug:\"accessories\",\n                label:\"ACCESSORIES\"\n            }\n        ],\n        \/*\n         * How many cards, counted from the start of each\n         * category rail, are treated as \"immediately visible\"\n         * and therefore worth loading eagerly \/ waiting on\n         * before revealing the catalog. Everything after this\n         * loads lazily in the background instead of competing\n         * with the first screenful for bandwidth.\n         *\/\n        priorityCardsPerRail:4,\n        \/*\n         * Per-image cap (ms) when waiting for a priority photo\n         * before reveal \u2014 keeps one slow photo on a bad\n         * connection from holding up the whole catalog.\n         *\/\n        priorityImageTimeout:900,\n        \/* Matches the loader's own fade-out transition length. *\/\n        loaderFadeDelay:780\n    };\n\n    \/* =========================================================\n       FULL CANVAS IMAGE PRELOADER\n       Shared between State 2 and the Canvas engine.\n       ========================================================= *\/\n    function ensureLullaImagePreloader(){\n        if(\n            window.LullaImagePreloader &&\n            typeof window.LullaImagePreloader.preload === \"function\"\n        ){\n            return window.LullaImagePreloader;\n        }\n\n        const records = new Map();\n        const queue = [];\n        let active = 0;\n\n        const MAX_ENTRIES = 64;\n        const MAX_CONCURRENT = 3;\n\n        function trim(){\n            if(records.size <= MAX_ENTRIES){\n                return;\n            }\n\n            for(const entry of records){\n                if(records.size <= MAX_ENTRIES){\n                    break;\n                }\n\n                if(entry[1].status === \"ready\"){\n                    records.delete(entry[0]);\n                }\n            }\n        }\n\n        function preload(url, priority){\n            const src = String(url || \"\").trim();\n\n            if(!src){\n                return Promise.resolve(false);\n            }\n\n            const requestedPriority =\n                priority === \"high\" ? \"high\" : \"low\";\n\n            const existing = records.get(src);\n\n            if(existing){\n                if(\n                    existing.status === \"loading\" &&\n                    requestedPriority === \"high\"\n                ){\n                    try{\n                        existing.image.fetchPriority = \"high\";\n                    }catch(error){}\n                }\n\n                if(existing.status === \"ready\"){\n                    records.delete(src);\n                    records.set(src, existing);\n                }\n\n                return existing.promise;\n            }\n\n            let resolvePromise;\n\n            const promise = new Promise(function(resolve){\n                resolvePromise = resolve;\n            });\n\n            const image = new Image();\n\n            const record = {\n                status:\"loading\",\n                image:image,\n                promise:promise\n            };\n\n            records.set(src, record);\n\n            image.decoding = \"async\";\n\n            try{\n                image.fetchPriority = requestedPriority;\n            }catch(error){}\n\n            function finish(ok){\n                if(record.status !== \"loading\"){\n                    return;\n                }\n\n                record.status = ok ? \"ready\" : \"error\";\n\n                if(ok){\n                    trim();\n                }else{\n                    records.delete(src);\n                }\n\n                resolvePromise(!!ok);\n            }\n\n            image.onload = function(){\n                finish(true);\n            };\n\n            image.onerror = function(){\n                finish(false);\n            };\n\n            image.src = src;\n\n            if(image.complete){\n                setTimeout(function(){\n                    finish(image.naturalWidth > 0);\n                }, 0);\n            }\n\n            return promise;\n        }\n\n        function enqueue(urls){\n            if(!Array.isArray(urls)){\n                return;\n            }\n\n            urls.forEach(function(url){\n                const src = String(url || \"\").trim();\n\n                if(\n                    !src ||\n                    records.has(src) ||\n                    queue.includes(src)\n                ){\n                    return;\n                }\n\n                queue.push(src);\n            });\n\n            pump();\n        }\n\n        function pump(){\n            while(\n                active < MAX_CONCURRENT &&\n                queue.length\n            ){\n                const src = queue.shift();\n\n                if(records.has(src)){\n                    continue;\n                }\n\n                active += 1;\n\n                preload(src, \"low\").then(function(){\n                    active -= 1;\n                    pump();\n                });\n            }\n        }\n\n        function clearQueue(){\n            queue.length = 0;\n        }\n\n        window.LullaImagePreloader = {\n            preload:preload,\n            ready:function(url){\n                return preload(url, \"high\");\n            },\n            enqueue:enqueue,\n            clearQueue:clearQueue\n        };\n\n        return window.LullaImagePreloader;\n    }\n\n    ensureLullaImagePreloader();\n    \/* =========================================================\n       ROOT\n       ========================================================= *\/\n    const root =\n        document.getElementById(\n            \"builder-products-root\"\n        );\n    if(!root){\n        return;\n    }\n    \/* =========================================================\n       STATE\n       ========================================================= *\/\n    const state = {\n        catalog:[],\n        catalogLoaded:false,\n        catalogLoading:false,\n        catalogError:null,\n        gender:\"boys\",\n        ageRange:\"12-18m\",\n        activeProducts:{},\n        initialized:false\n    };\n    let fetchPromise =\n        null;\n    let lastFilterSignature =\n        \"\";\n    \/* =========================================================\n       LOADING\n       ========================================================= *\/\n    function renderLoading(){\n        root.innerHTML =\n            `\n            <div class=\"lulla-products-loading\" aria-live=\"polite\">\n                <div class=\"lulla-loader-visual\">\n                    <div class=\"lulla-loader-text\">\n                        Preparing your wardrobe\n                    <\/div>\n\n                    <div class=\"lulla-carousel-scene\" aria-hidden=\"true\">\n                        <div class=\"lulla-carousel\">\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 38 42\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M31.3207 7V5C31.3207 3.11438 31.3207 2.17157 30.7193 1.58579C30.1178 1 29.1498 1 27.2138 1H10.7862C8.85018 1 7.88218 1 7.28074 1.58579C6.67929 2.17157 6.67929 3.11438 6.67929 5V7M31.3207 7L36.6304 36.3049C37.0249 38.4822 37.2221 39.5709 36.6066 40.2855C35.9911 41 34.8561 41 32.5859 41H30.2471C28.7852 41 28.0543 41 27.5105 40.6088C26.9666 40.2176 26.7517 39.5372 26.3218 38.1763L22.9253 27.4251C21.3195 22.3422 20.5166 19.8007 19 19.8007C17.4834 19.8007 16.6805 22.3422 15.0747 27.4251L11.6782 38.1763C11.2483 39.5372 11.0334 40.2176 10.4895 40.6088C9.94568 41 9.21476 41 7.75294 41H5.41405C3.14393 41 2.00887 41 1.39337 40.2855C0.777867 39.5709 0.975125 38.4822 1.36964 36.3049L6.67929 7M31.3207 7H6.67929\"\/>\n<path d=\"M15 12.5556L19 7L25 17\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 42 43\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M2.00012 31.5L1.11614 26.5523C-0.150276 14.773 9.11257 4.5 21.0001 4.5C32.8877 4.5 42.1505 14.773 40.8841 26.5524L40.0001 31.5\"\/>\n<path d=\"M13.0315 18.5C12.626 12.0901 16.1964 4.5 21.0001 4.5\"\/>\n<path d=\"M29.0002 18.5C29.4058 12.0901 25.8354 4.5 21.0316 4.5\"\/>\n<path d=\"M21.0001 3.5V1.5\"\/>\n<path d=\"M2.00012 31.5188C18.0001 25.7856 24.0001 26.5488 40.0001 31.5188C39.4473 33.7617 39.1464 40.0992 36.702 41.2934C35.5301 41.8659 33.8494 41.0978 32.642 40.8094C26.8505 39.4259 23.9547 38.7342 21.0001 38.7342C18.0455 38.7342 15.1498 39.4259 9.35821 40.8094C8.15082 41.0978 6.47016 41.8659 5.2982 41.2934C2.85381 40.0992 2.55296 33.7617 2.00012 31.5188Z\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 38 42\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M10.2222 1.29581L10.603 1.21771C11.5784 1.01769 12.066 0.917685 12.3812 1.08404C12.6964 1.25039 12.9617 1.87497 13.4924 3.12414C14.443 5.36172 16.6512 6.93345 19.0022 6.93345C21.3532 6.93345 23.5614 5.36172 24.512 3.12414C25.0427 1.87497 25.308 1.25039 25.6232 1.08404C25.9384 0.917685 26.426 1.01769 27.4014 1.21771L27.7822 1.29581C30.3003 1.75605 30.3398 1.77899 32.0674 3.78569C33.5271 5.4812 35.6191 7.21378 36.6619 9.25441C37.4299 10.7573 36.7753 12.0458 35.9133 13.2398C34.8367 14.7311 33.4389 16.1634 31.5463 15.003C30.3377 14.2621 29.374 12.6983 28.4368 11.6165C28.4368 11.6165 29.0022 18.8492 27.0022 20.8629C28.8176 22.1727 31.6871 24.7159 33.9632 29.9285C34.7746 31.7866 35.8657 33.9039 34.7897 35.8874C31.1315 42.6308 6.95248 42.7775 3.21471 35.8874C2.13869 33.9039 3.22977 31.7866 4.04115 29.9285C6.31732 24.7159 9.18681 22.1727 11.0022 20.8629C9.0022 18.8492 9.5676 11.6165 9.5676 11.6165C8.63043 12.6983 7.66666 14.2621 6.45811 15.003C4.56545 16.1634 3.16768 14.7311 2.09107 13.2398C1.22912 12.0458 0.574505 10.7573 1.34251 9.25441C2.38532 7.21378 4.47735 5.4812 5.93703 3.78569C7.66465 1.77895 7.70406 1.75605 10.2222 1.29581Z\"\/>\n<path d=\"M11.0022 21H27.0022\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 42 42\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M10.9236 23.1181L6.13682 37.4393C5.85809 38.2732 5.71872 38.6902 5.37424 38.8799C4.64823 39.2796 1.65893 38.6168 1.14265 37.8501C0.925002 37.5269 0.989281 37.0965 1.11784 36.2357L4.23185 15.3843C4.76212 11.8336 5.59767 10.733 8.86931 9.24998L15 6.03482V3.02013C15 1.35536 15.35 1.01034 17.0153 1.01034L24.9847 1C26.65 1 27 1.34502 27 3.00979V6.02448L33.1307 9.24998C36.4023 10.733 37.2379 11.8336 37.7682 15.3843L40.8822 36.2357C41.0107 37.0965 41.075 37.5269 40.8574 37.8501C40.3411 38.6168 37.3518 39.2796 36.6258 38.8799C36.2813 38.6902 36.1419 38.2732 35.8632 37.4393L31.0764 23.1181\"\/>\n<path d=\"M10 17C10.3323 18.9935 10.7514 20.9916 10.9182 23.0068C11.3009 27.6307 11 32.366 11 37C11 40.3093 11.6907 41 15 41H27C30.3093 41 31 40.3093 31 37C31 32.366 30.6991 27.6307 31.0818 23.0068C31.2486 20.9916 31.6677 18.9935 32 17\"\/>\n<path d=\"M15 7C18.6 9.66667 23.4 9.66667 27 7\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 42 38\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M9 13V28.3682C9 31.9905 9 33.8016 10.1716 34.9269C12.7998 37.4513 28.7115 37.9208 31.8284 34.9269C33 33.8016 33 31.9905 33 28.3682V13\"\/>\n<path d=\"M8.48147 19L3.08642 13.7783C1.69547 12.432 1 11.7589 1 10.9225C1 10.086 1.69547 9.41288 3.08642 8.06662L7.08836 4.19327C7.78176 3.52215 8.12847 3.18658 8.54176 2.93936C8.95506 2.69213 9.42021 2.54206 10.3505 2.24193L13.6422 1.17994C14.1235 1.02466 14.3642 0.947024 14.5278 1.04037C14.6915 1.13371 14.7431 1.4026 14.8465 1.94036C15.3872 4.75368 17.9366 6.88369 21 6.88369C24.0634 6.88369 26.6128 4.75368 27.1535 1.94036C27.2569 1.4026 27.3085 1.13371 27.4722 1.04037C27.6358 0.947024 27.8765 1.02466 28.3578 1.17994L31.6495 2.24193C32.5798 2.54206 33.0449 2.69213 33.4582 2.93936C33.8715 3.18658 34.2182 3.52215 34.9116 4.19327L38.9136 8.06662C40.3045 9.41288 41 10.086 41 10.9225C41 11.7589 40.3045 12.432 38.9136 13.7783L33.5185 19\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                            <div class=\"lulla-card-wrapper\">\n                                <div class=\"lulla-card-face lulla-card-front\">\n                                    <svg class=\"lulla-svg-icon\" viewBox=\"0 0 42 42\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M18.9762 27.2461L17.5142 37.4509C17.0476 40.7077 16.2676 41.2934 13.0032 40.8865L4.58504 39.8373C1.41328 39.442 0.803912 38.7079 1.04977 35.5209L2.52171 16.4405C2.63552 14.9653 2.69242 14.2276 2.83791 13.5054C3.20624 11.6771 4.22582 10.0713 4.64544 8.27083C4.88967 7.22289 4.8031 6.11181 4.8031 5.03787C4.8031 1.69222 5.5073 1 8.85257 1H33.1494C36.4946 1 37.1989 1.69222 37.1989 5.03787C37.1989 6.11181 37.1123 7.2229 37.3565 8.27083C37.7761 10.0713 38.7957 11.6771 39.164 13.5054C40.5956 20.6113 40.3955 28.3052 40.9522 35.5209C41.198 38.7079 40.5887 39.442 37.4169 39.8373L28.9988 40.8865C25.7343 41.2934 24.9543 40.7077 24.4877 37.4509L23.0257 27.2461\"\/>\n<path d=\"M15.001 24C16.522 25.5211 17.3962 27 19.6578 27H22.3441C24.6058 27 25.4799 25.5211 27.001 24\"\/>\n<path d=\"M5.00098 7H37.001\"\/>\n<path d=\"M3.00098 19C11.001 19.0135 11.001 11.0045 11.001 7\"\/>\n<path d=\"M31.001 7C31.001 11.0045 31.001 19.0135 39.001 19\"\/>\n<\/svg>\n                                <\/div>\n                                <div class=\"lulla-card-face lulla-card-back\"><\/div>\n                            <\/div>\n\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n            `;\n    }\n    \/* =========================================================\n       ERROR\n       ========================================================= *\/\n    function renderError(){\n        root.innerHTML =\n            \"\";\n        const message =\n            document.createElement(\n                \"div\"\n            );\n        message.className =\n            \"lulla-products-error\";\n        message.textContent =\n            \"Unable to load products.\";\n        root.appendChild(\n            message\n        );\n    }\n    \/* =========================================================\n       API RESPONSE\n       ========================================================= *\/\n    function normalizeApiResponse(\n        payload\n    ){\n        if(\n            Array.isArray(\n                payload\n            )\n        ){\n            return payload;\n        }\n        if(\n            payload &&\n            Array.isArray(\n                payload.data\n            )\n        ){\n            return payload.data;\n        }\n        return [];\n    }\n    \/* =========================================================\n       AUDIENCE\n       ========================================================= *\/\n    function normalizeAudience(\n        audience\n    ){\n        if(\n            !Array.isArray(\n                audience\n            )\n        ){\n            return [];\n        }\n        return audience\n            .map(\n                function(item){\n                    if(\n                        typeof item ===\n                        \"string\"\n                    ){\n                        return item\n                            .toLowerCase()\n                            .trim();\n                    }\n                    if(\n                        item &&\n                        item.slug\n                    ){\n                        return String(\n                            item.slug\n                        )\n                        .toLowerCase()\n                        .trim();\n                    }\n                    return \"\";\n                }\n            )\n            .filter(\n                function(item){\n                    return !!item;\n                }\n            );\n    }\n    \/* =========================================================\n       AGE\n       ========================================================= *\/\n    function normalizeAgeValue(\n        value\n    ){\n        if(\n            !value ||\n            typeof value !==\n            \"string\"\n        ){\n            return \"\";\n        }\n        return String(\n            value\n        )\n        .toLowerCase()\n        .trim();\n    }\n    \/* =========================================================\n       CARD\n       ========================================================= *\/\n    function normalizeCard(\n        card\n    ){\n        if(\n            !card ||\n            typeof card !==\n            \"object\"\n        ){\n            return null;\n        }\n        const ages =\n            Array.isArray(\n                card.available_ages\n            )\n            ? card.available_ages\n                .map(\n                    normalizeAgeValue\n                )\n                .filter(\n                    function(age){\n                        return !!age;\n                    }\n                )\n            : [];\n        const sizes =\n            Array.isArray(\n                card.sizes\n            )\n            ? card.sizes\n                .map(\n                    function(size){\n                        if(\n                            !size ||\n                            typeof size !==\n                            \"object\"\n                        ){\n                            return null;\n                        }\n                        return {\n                            value:\n                                size.value ||\n                                \"\",\n                            label:\n                                size.label ||\n                                \"\",\n                            builderAge:\n                                normalizeAgeValue(\n                                    size.builder_age\n                                ),\n                            variationId:\n                                Number(\n                                    size.variation_id\n                                ) || 0,\n                            purchasable:\n                                !!size.purchasable,\n                            isInStock:\n                                !!size.is_in_stock\n                        };\n                    }\n                )\n                .filter(\n                    function(size){\n                        return !!size;\n                    }\n                )\n            : [];\n        return {\n            type:\n                card.type ||\n                \"color\",\n            value:\n                card.value ||\n                \"\",\n            label:\n                card.label ||\n                card.value ||\n                \"\",\n            image:\n                card.card_image ||\n                \"\",\n            \/*\n             * Optional small preview variant. Not produced by\n             * the API yet \u2014 this reads it if\/when the backend\n             * starts sending a `card_image_thumb` (or\n             * `card_image_preview`) field alongside the\n             * full-size `card_image`, so the catalog grid can\n             * switch to a much lighter file without any other\n             * front-end change. Until then this is simply\n             * empty and the full image is used, exactly as\n             * before.\n             *\/\n            imageThumb:\n                card.card_image_thumb ||\n                card.card_image_preview ||\n                \"\",\n            availableAges:\n                ages,\n            sizes:\n                sizes\n        };\n    }\n    \/* =========================================================\n       PRODUCT\n       ========================================================= *\/\n    function normalizeProduct(\n        product\n    ){\n        if(\n            !product ||\n            typeof product !==\n            \"object\"\n        ){\n            return null;\n        }\n        const category =\n            typeof product.category ===\n            \"string\"\n            ? product.category\n            : (\n                product.category &&\n                product.category.slug\n                    ? product.category.slug\n                    : \"\"\n            );\n        if(\n            !category\n        ){\n            return null;\n        }\n        const availableAges =\n            Array.isArray(\n                product.available_ages\n            )\n            ? product.available_ages\n                .map(\n                    normalizeAgeValue\n                )\n                .filter(\n                    function(age){\n                        return !!age;\n                    }\n                )\n            : [];\n        const cards =\n            Array.isArray(\n                product.cards\n            )\n            ? product.cards\n                .map(\n                    normalizeCard\n                )\n                .filter(\n                    function(card){\n                        return !!card;\n                    }\n                )\n            : [];\n        return {\n            id:\n                Number(\n                    product.id\n                ) || 0,\n            title:\n                product.title ||\n                \"\",\n            permalink:\n                product.permalink ||\n                \"\",\n            price:\n                Number(\n                    product.price\n                ) || 0,\n            priceHtml:\n                product.price_html ||\n                \"\",\n            category:\n                category,\n            audience:\n                normalizeAudience(\n                    product.audience\n                ),\n            availableAges:\n                availableAges,\n            sizeGuideImage:\n                product.size_guide_image ||\n                \"\",\n            sizeGuideImageId:\n                Number(\n                    product.size_guide_image_id\n                ) || 0,\n            cards:\n                cards\n        };\n    }\n    \/* =========================================================\n       CATALOG\n       ========================================================= *\/\n    function normalizeCatalog(\n        payload\n    ){\n        return normalizeApiResponse(\n            payload\n        )\n        .map(\n            normalizeProduct\n        )\n        .filter(\n            function(product){\n                return !!product;\n            }\n        );\n    }\n    \/* =========================================================\n       LOAD CATALOG\n       ========================================================= *\/\n    function loadCatalog(){\n        if(\n            state.catalogLoaded\n        ){\n            return Promise.resolve(\n                state.catalog\n            );\n        }\n        if(\n            fetchPromise\n        ){\n            return fetchPromise;\n        }\n        state.catalogLoading =\n            true;\n        renderLoading();\n        const apiUrl =\n            CONFIG.apiUrl +\n            (\n                CONFIG.apiUrl.includes(\"?\")\n                    ? \"&\"\n                    : \"?\"\n            ) +\n            \"lulla_catalog=\" +\n            Date.now();\n        fetchPromise =\n            fetch(\n                apiUrl,\n                {\n                    method:\"GET\",\n                    credentials:\n                        \"same-origin\",\n                    headers:{\n                        \"Accept\":\n                            \"application\/json\"\n                    },\n                    cache:\n                        \"no-store\"\n                }\n            )\n            .then(\n                function(response){\n                    if(\n                        !response.ok\n                    ){\n                        throw new Error(\n                            \"HTTP \" +\n                            response.status\n                        );\n                    }\n                    return response.json();\n                }\n            )\n            .then(\n                function(payload){\n                    const catalog =\n                        normalizeCatalog(\n                            payload\n                        );\n                    state.catalog =\n                        catalog;\n                    state.catalogLoaded =\n                        true;\n                    state.catalogLoading =\n                        false;\n                    state.catalogError =\n                        null;\n                    return catalog;\n                }\n            )\n            .catch(\n                function(error){\n                    console.error(\n                        \"[LULLA Product Scroll]\",\n                        error\n                    );\n                    state.catalog =\n                        [];\n                    state.catalogLoaded =\n                        false;\n                    state.catalogLoading =\n                        false;\n                    state.catalogError =\n                        error;\n                    renderError();\n                    throw error;\n                }\n            );\n        return fetchPromise;\n    }\n    \/* =========================================================\n       FILTERS\n       ========================================================= *\/\n    function productMatchesGender(\n        product\n    ){\n        const audience =\n            product.audience;\n        if(\n            !audience.length\n        ){\n            return false;\n        }\n        if(\n            audience.includes(\n                \"unisex\"\n            )\n        ){\n            return true;\n        }\n        if(\n            state.gender ===\n            \"boys\"\n        ){\n            return audience.includes(\n                \"boys\"\n            );\n        }\n        if(\n            state.gender ===\n            \"girls\"\n        ){\n            return audience.includes(\n                \"girls\"\n            );\n        }\n        return false;\n    }\n    function productMatchesAge(\n        product\n    ){\n        return product\n            .availableAges\n            .includes(\n                state.ageRange\n            );\n    }\n    function cardMatchesAge(\n        card\n    ){\n        return card\n            .availableAges\n            .includes(\n                state.ageRange\n            );\n    }\n    function getVisibleProducts(){\n        return state.catalog.filter(\n            function(product){\n                return (\n                    productMatchesGender(\n                        product\n                    )\n                    &&\n                    productMatchesAge(\n                        product\n                    )\n                );\n            }\n        );\n    }\n    function getVisibleCards(\n        product\n    ){\n        return product.cards.filter(\n            function(card){\n                return cardMatchesAge(\n                    card\n                );\n            }\n        );\n    }\n    \/* =========================================================\n       CATEGORY HELPER\n       ========================================================= *\/\n    function getCategoryDefinition(\n        slug\n    ){\n        return CONFIG.categories.find(\n            function(category){\n                return category.slug ===\n                    slug;\n            }\n        ) || null;\n    }\n    \/* =========================================================\n       SELECTED PRODUCT\n       ========================================================= *\/\n    function buildSelectedProduct(\n        product,\n        card\n    ){\n        const definition =\n            getCategoryDefinition(\n                product.category\n            );\n        return {\n            id:\n                product.id,\n            productId:\n                product.id,\n            title:\n                product.title,\n            name:\n                product.title,\n            image:\n                card.image,\n            price:\n                product.price,\n            priceHtml:\n                product.priceHtml,\n            category:\n                product.category,\n            categoryLabel:\n                definition\n                    ? definition.label\n                    : product.category,\n            sizes:\n                card.sizes,\n            variationIds:\n                card.sizes\n                    .map(\n                        function(size){\n                            return size.variationId;\n                        }\n                    )\n                    .filter(\n                        function(id){\n                            return !!id;\n                        }\n                    ),\n            variantType:\n                card.type,\n            variantValue:\n                card.value,\n            variantLabel:\n                card.label,\n            availableAges:\n                card.availableAges,\n            sizeGuideImage:\n                product.sizeGuideImage,\n            sizeGuideImageId:\n                product.sizeGuideImageId\n        };\n    }\n    \/* =========================================================\n       CLEAR ACTIVE PRODUCTS\n       ========================================================= *\/\n    function clearActiveProducts(){\n        const previous =\n            Object.keys(\n                state.activeProducts\n            );\n        state.activeProducts =\n            {};\n        \/*\n         * One consolidated event.\n         *\n         * The final state is empty, so all listeners\n         * can synchronize once instead of once per category.\n         *\/\n        if(\n            previous.length\n        ){\n            root.dispatchEvent(\n                new CustomEvent(\n                    \"lulla:product-change\",\n                    {\n                        bubbles:true,\n                        detail:{\n                            gender:\n                                state.gender,\n                            ageRange:\n                                state.ageRange,\n                            category:null,\n                            product:null,\n                            activeProducts:\n                                state.activeProducts\n                        }\n                    }\n                )\n            );\n        }\n    }\n    \/* =========================================================\n       EXCLUSIVE CATEGORY RULES\n       ========================================================= *\/\n    function getConflictingCategories(\n        selectedCategory\n    ){\n        if(\n            selectedCategory ===\n                \"onepiece-sets\"\n            ||\n            selectedCategory ===\n                \"dresses\"\n        ){\n            return [\n                \"bottoms\"\n            ];\n        }\n        if(\n            selectedCategory ===\n                \"bottoms\"\n        ){\n            return [\n                \"onepiece-sets\",\n                \"dresses\"\n            ];\n        }\n        return [];\n    }\n    \/* =========================================================\n       REMOVE CONFLICTING PRODUCTS\n       ========================================================= *\/\n    function clearConflictingSelections(\n        selectedCategory\n    ){\n        const conflicts =\n            getConflictingCategories(\n                selectedCategory\n            );\n        if(\n            !conflicts.length\n        ){\n            return;\n        }\n        conflicts.forEach(\n            function(category){\n                if(\n                    !state.activeProducts[\n                        category\n                    ]\n                ){\n                    return;\n                }\n                delete state.activeProducts[\n                    category\n                ];\n                \/*\n                 * Only update the visual selection here.\n                 *\n                 * DO NOT dispatch lulla:product-change.\n                 *\n                 * The new final state will be dispatched\n                 * once by selectCard().\n                 *\/\n                root\n                    .querySelectorAll(\n                        '.builder-product-card.is-selected[data-category=\"' +\n                        category +\n                        '\"]'\n                    )\n                    .forEach(\n                        function(cardElement){\n                            cardElement.classList.remove(\n                                \"is-selected\"\n                            );\n                        }\n                    );\n            }\n        );\n    }\n    \/* =========================================================\n       SELECT CARD\n       ========================================================= *\/\n    function selectCard(\n        product,\n        card,\n        cardElement,\n        rail\n    ){\n        const category =\n            product.category;\n        \/*\n         * Check the current selection BEFORE\n         * changing any state.\n         *\/\n        const existing =\n            state.activeProducts[\n                category\n            ];\n        const sameSelection =\n            existing &&\n            existing.product &&\n            existing.card &&\n            existing.product.id ===\n                product.id &&\n            existing.card.type ===\n                card.type &&\n            existing.card.value ===\n                card.value;\n        \/*\n         * Same card = toggle OFF.\n         *\n         * This produces exactly one event.\n         *\/\n        if(\n            sameSelection\n        ){\n            delete state.activeProducts[\n                category\n            ];\n            cardElement.classList.remove(\n                \"is-selected\"\n            );\n            root.dispatchEvent(\n                new CustomEvent(\n                    \"lulla:product-change\",\n                    {\n                        bubbles:true,\n                        detail:{\n                            gender:\n                                state.gender,\n                            ageRange:\n                                state.ageRange,\n                            category:\n                                category,\n                            product:null,\n                            activeProducts:\n                                state.activeProducts\n                        }\n                    }\n                )\n            );\n            return;\n        }\n        \/*\n         * FIRST:\n         *\n         * Remove incompatible selections.\n         *\n         * No event is dispatched here.\n         *\/\n        clearConflictingSelections(\n            category\n        );\n        \/*\n         * One selected card inside the\n         * current category rail.\n         *\/\n        rail\n            .querySelectorAll(\n                \".builder-product-card\"\n            )\n            .forEach(\n                function(other){\n                    other.classList.remove(\n                        \"is-selected\"\n                    );\n                }\n            );\n        \/*\n         * Build the new selected product.\n         *\/\n        const selectedProduct =\n            buildSelectedProduct(\n                product,\n                card\n            );\n        \/*\n         * Update the FINAL state.\n         *\/\n        state.activeProducts[\n            category\n        ] = {\n            product:\n                selectedProduct,\n            sourceProduct:\n                product,\n            card:\n                card\n        };\n        cardElement.classList.add(\n            \"is-selected\"\n        );\n        \/*\n         * ONE SINGLE EVENT.\n         *\n         * This event contains the final complete\n         * activeProducts object.\n         *\/\n        root.dispatchEvent(\n            new CustomEvent(\n                \"lulla:product-change\",\n                {\n                    bubbles:true,\n                    detail:{\n                        gender:\n                            state.gender,\n                        ageRange:\n                            state.ageRange,\n                        category:\n                            category,\n                        product:\n                            selectedProduct,\n                        activeProducts:\n                            state.activeProducts\n                    }\n                }\n            )\n        );\n    }\n    \/* =========================================================\n       IMAGE WAIT HELPER\n       ========================================================= *\/\n    function waitForImage(\n        img,\n        timeoutMs\n    ){\n        return new Promise(\n            function(resolve){\n                if(\n                    !img ||\n                    img.complete\n                ){\n                    resolve();\n                    return;\n                }\n                let done =\n                    false;\n                function finish(){\n                    if(\n                        done\n                    ){\n                        return;\n                    }\n                    done =\n                        true;\n                    img.removeEventListener(\n                        \"load\",\n                        finish\n                    );\n                    img.removeEventListener(\n                        \"error\",\n                        finish\n                    );\n                    resolve();\n                }\n                img.addEventListener(\n                    \"load\",\n                    finish,\n                    {\n                        once:true\n                    }\n                );\n                img.addEventListener(\n                    \"error\",\n                    finish,\n                    {\n                        once:true\n                    }\n                );\n                setTimeout(\n                    finish,\n                    timeoutMs\n                );\n            }\n        );\n    }\n\n    let canvasPreloadScheduleToken =\n        0;\n\n    \/* =========================================================\n       SCHEDULE FULL CANVAS IMAGE PRELOAD\n       ========================================================= *\/\n    function scheduleCanvasImagePreload(\n        visibleProducts\n    ){\n        const preloader =\n            ensureLullaImagePreloader();\n\n        if(!preloader){\n            return;\n        }\n\n        const scheduleToken =\n            ++canvasPreloadScheduleToken;\n\n        preloader.clearQueue();\n\n        const firstByCategory = [];\n        const remainderByCategory = [];\n\n        CONFIG.categories.forEach(\n            function(definition){\n                const categoryProducts =\n                    visibleProducts.filter(\n                        function(product){\n                            return (\n                                product.category ===\n                                definition.slug\n                            );\n                        }\n                    );\n\n                const firstUrls = [];\n                const remainderUrls = [];\n                let cardIndex = 0;\n\n                categoryProducts.forEach(\n                    function(product){\n                        getVisibleCards(product).forEach(\n                            function(card){\n                                const image =\n                                    String(\n                                        card.image ||\n                                        \"\"\n                                    ).trim();\n\n                                if(!image){\n                                    return;\n                                }\n\n                                if(cardIndex < 7){\n                                    firstUrls.push(image);\n                                }else{\n                                    remainderUrls.push(image);\n                                }\n\n                                cardIndex += 1;\n                            }\n                        );\n                    }\n                );\n\n                firstByCategory.push(firstUrls);\n                remainderByCategory.push(remainderUrls);\n            }\n        );\n\n        const priorityUrls = [];\n\n        for(\n            let index = 0;\n            index < 7;\n            index += 1\n        ){\n            firstByCategory.forEach(\n                function(urls){\n                    if(urls[index]){\n                        priorityUrls.push(\n                            urls[index]\n                        );\n                    }\n                }\n            );\n        }\n\n        const remainderUrls = [];\n\n        remainderByCategory.forEach(\n            function(urls){\n                urls.forEach(\n                    function(url){\n                        remainderUrls.push(url);\n                    }\n                );\n            }\n        );\n\n        function startBackgroundPreload(){\n\n            if(\n                scheduleToken !==\n                canvasPreloadScheduleToken\n            ){\n                return;\n            }\n\n            preloader.enqueue(\n                priorityUrls\n            );\n\n            const idle =\n                window.requestIdleCallback;\n\n            if(\n                typeof idle ===\n                \"function\"\n            ){\n                idle(\n                    function(){\n                        if(\n                            scheduleToken !==\n                            canvasPreloadScheduleToken\n                        ){\n                            return;\n                        }\n\n                        preloader.enqueue(\n                            remainderUrls\n                        );\n                    },\n                    {\n                        timeout:1200\n                    }\n                );\n            }else{\n                setTimeout(\n                    function(){\n                        if(\n                            scheduleToken !==\n                            canvasPreloadScheduleToken\n                        ){\n                            return;\n                        }\n\n                        preloader.enqueue(\n                            remainderUrls\n                        );\n                    },\n                    900\n                );\n            }\n        }\n\n        requestAnimationFrame(\n            function(){\n                requestAnimationFrame(\n                    startBackgroundPreload\n                );\n            }\n        );\n    }\n\n    \/* =========================================================\n       CARD\n       ========================================================= *\/\n    function createCard(\n        product,\n        card,\n        rail,\n        index,\n        isPriority,\n        priorityImages\n    ){\n        const element =\n            document.createElement(\n                \"button\"\n            );\n        element.type =\n            \"button\";\n        element.className =\n            \"builder-product-card\";\n        element.style.setProperty(\n            \"--card-index\",\n            index\n        );\n        element.dataset.productId =\n            String(\n                product.id\n            );\n        element.dataset.category =\n            product.category;\n        element.dataset.variantType =\n            card.type;\n        element.dataset.variantValue =\n            card.value;\n        if(\n            product.category ===\n            \"onepiece-sets\"\n        ){\n            element.classList.add(\n                \"is-onepiece\"\n            );\n        }\n        const existing =\n            state.activeProducts[\n                product.category\n            ];\n        if(\n            existing &&\n            existing.product &&\n            existing.card &&\n            existing.product.id ===\n                product.id &&\n            existing.card.type ===\n                card.type &&\n            existing.card.value ===\n                card.value\n        ){\n            element.classList.add(\n                \"is-selected\"\n            );\n        }\n        const cardImageSrc =\n            card.imageThumb ||\n            card.image;\n        if(\n            cardImageSrc\n        ){\n            const image =\n                document.createElement(\n                    \"img\"\n                );\n            image.src =\n                cardImageSrc;\n            image.alt =\n                product.title +\n                \" \u2014 \" +\n                card.label;\n            image.decoding =\n                \"async\";\n            \/*\n             * Only the first screenful of cards per rail\n             * loads eagerly with high priority. Everything\n             * else is deferred so it doesn't compete for\n             * bandwidth with the photos the person actually\n             * sees first \u2014 this is what was causing the long\n             * spell of blank white cards on slower connections.\n             *\/\n            if(\n                isPriority\n            ){\n                image.loading =\n                    \"eager\";\n                image.fetchPriority =\n                    \"high\";\n                if(\n                    priorityImages\n                ){\n                    priorityImages.push(\n                        image\n                    );\n                }\n            }else{\n                image.loading =\n                    \"lazy\";\n                image.fetchPriority =\n                    \"low\";\n            }\n            image.addEventListener(\n                \"load\",\n                function(){\n                    const currentRail =\n                        element.closest(\n                            \".builder-product-rail\"\n                        );\n                    const currentWrap =\n                        element.closest(\n                            \".builder-product-wrap\"\n                        );\n                    if(\n                        currentRail &&\n                        currentWrap\n                    ){\n                        refreshRail(\n                            currentRail,\n                            currentWrap\n                        );\n                    }\n                },\n                {\n                    once:true\n                }\n            );\n            element.appendChild(\n                image\n            );\n        }else{\n            element.classList.add(\n                \"is-no-image\"\n            );\n        }\n        element.addEventListener(\n            \"pointerdown\",\n            function(){\n                ensureLullaImagePreloader()\n                    .preload(\n                        card.image,\n                        \"high\"\n                    );\n            },\n            {\n                passive:true\n            }\n        );\n\n        element.addEventListener(\n            \"click\",\n            function(){\n                selectCard(\n                    product,\n                    card,\n                    element,\n                    rail\n                );\n            }\n        );\n        return element;\n    }\n    \/* =========================================================\n       LANDSCAPE SCALE\n       ========================================================= *\/\n    function fitLandscape(){\n        const isLandscape =\n            window.innerWidth >= 601\n            &&\n            window.innerWidth >\n                window.innerHeight;\n        if(\n            !isLandscape\n        ){\n            root.style.removeProperty(\n                \"--fit-card-size\"\n            );\n            root.classList.remove(\n                \"is-compact-fit\",\n                \"is-scroll-fallback\"\n            );\n            return;\n        }\n        const categories =\n            root.querySelectorAll(\n                \".builder-category\"\n            );\n        if(\n            !categories.length\n        ){\n            return;\n        }\n        const rootHeight =\n            root.clientHeight;\n        if(\n            !rootHeight\n        ){\n            return;\n        }\n        const rootStyles =\n            getComputedStyle(\n                root\n            );\n        const paddingTop =\n            parseFloat(\n                rootStyles.paddingTop\n            ) || 0;\n        const paddingBottom =\n            parseFloat(\n                rootStyles.paddingBottom\n            ) || 0;\n        const gap =\n            parseFloat(\n                rootStyles.rowGap\n                ||\n                rootStyles.gap\n            ) || 0;\n        const categoryCount =\n            categories.length;\n        let titleHeight =\n            16;\n        const firstTitle =\n            categories[0]\n                .querySelector(\n                    \".builder-category-title\"\n                );\n        if(\n            firstTitle\n        ){\n            titleHeight =\n                firstTitle\n                    .getBoundingClientRect()\n                    .height\n                +\n                (\n                    parseFloat(\n                        getComputedStyle(\n                            firstTitle\n                        ).marginBottom\n                    )\n                    || 0\n                );\n        }\n        const verticalBreathingRoom =\n            8;\n        const minCardSize =\n            52;\n        const maxCardSize =\n            124;\n        \/*\n         * The onepiece-sets card is 1.333x TALLER than a\n         * square card for the same edge size (see the\n         * .is-onepiece CSS rule). Splitting the available\n         * height into equal slices per category \u2014 ignoring\n         * that \u2014 under-budgets the onepiece row and is what\n         * was clipping it on tablet\/landscape. Give every\n         * category a \"weight\" (1 for square, 1.333 for\n         * onepiece) and size the shared card edge so that\n         * ALL rows, at that one shared size, fit within the\n         * available height together.\n         *\/\n        const onepieceAspect =\n            1.333333;\n        let totalWeight =\n            0;\n        categories.forEach(\n            function(categoryEl){\n                const isOnepiece =\n                    categoryEl.dataset.category ===\n                    \"onepiece-sets\";\n                totalWeight +=\n                    isOnepiece\n                        ? onepieceAspect\n                        : 1;\n            }\n        );\n        const fixedHeight =\n            paddingTop\n            +\n            paddingBottom\n            +\n            gap *\n            (categoryCount - 1)\n            +\n            categoryCount *\n            (\n                titleHeight\n                +\n                verticalBreathingRoom\n            );\n        const availableForCards =\n            rootHeight\n            -\n            fixedHeight;\n        \/*\n         * Would every active category fit on screen at all,\n         * even at the smallest legible card size? If not,\n         * don't force it \u2014 that's what was compressing rows\n         * thinner than their own cards and causing the\n         * clipping \/ overlap between categories. Fall back to\n         * a normal scroll instead.\n         *\/\n        if(\n            availableForCards <\n            minCardSize *\n                totalWeight\n        ){\n            root.classList.remove(\n                \"is-compact-fit\"\n            );\n            root.classList.add(\n                \"is-scroll-fallback\"\n            );\n            root.style.removeProperty(\n                \"--fit-card-size\"\n            );\n            return;\n        }\n        root.classList.remove(\n            \"is-scroll-fallback\"\n        );\n        const rawSize =\n            availableForCards\n            \/\n            totalWeight;\n        \/*\n         * Max size reached with room left over (few active\n         * categories) \u2014 stop stretching every row to fill\n         * that leftover space and just stack them at their\n         * natural height instead, top to bottom, in order.\n         *\/\n        root.classList.remove(\n            \"is-compact-fit\"\n        );\n        root.classList.toggle(\n            \"is-compact-fit\",\n            rawSize >\n            maxCardSize\n        );\n        const size =\n            Math.max(\n                minCardSize,\n                Math.min(\n                    maxCardSize,\n                    rawSize\n                )\n            );\n        root.style.setProperty(\n            \"--fit-card-size\",\n            size + \"px\"\n        );\n    }\n    \/* =========================================================\n       SCROLL STEP\n       ========================================================= *\/\n    function getScrollStep(\n        rail\n    ){\n        const firstCard =\n            rail.querySelector(\n                \".builder-product-card\"\n            );\n        if(\n            !firstCard\n        ){\n            return 120;\n        }\n        const cardWidth =\n            firstCard\n                .getBoundingClientRect()\n                .width;\n        const styles =\n            getComputedStyle(\n                rail\n            );\n        const gap =\n            parseFloat(\n                styles.columnGap\n                ||\n                styles.gap\n            ) || 0;\n        const cardsPerStep =\n            window.innerWidth <= 420\n                ? 1\n                : 2;\n        return (\n            cardWidth *\n            cardsPerStep\n        )\n        +\n        (\n            gap *\n            (cardsPerStep - 1)\n        )\n        +\n        2;\n    }\n    \/* =========================================================\n       RAIL STATE\n       ========================================================= *\/\n    function updateRailState(\n        rail,\n        wrap\n    ){\n        const maxScroll =\n            Math.max(\n                0,\n                Math.ceil(\n                    rail.scrollWidth\n                    -\n                    rail.clientWidth\n                )\n            );\n        const currentScroll =\n            Math.max(\n                0,\n                rail.scrollLeft\n            );\n        const hasMore =\n            maxScroll > 2\n            &&\n            currentScroll <\n                maxScroll - 2;\n        const hasLeft =\n            currentScroll > 2;\n        const atEnd =\n            maxScroll <= 2\n            ||\n            currentScroll >=\n                maxScroll - 2;\n        const atStart =\n            currentScroll <= 2;\n        wrap.classList.toggle(\n            \"has-more\",\n            hasMore\n        );\n        wrap.classList.toggle(\n            \"has-left\",\n            hasLeft\n        );\n        wrap.classList.toggle(\n            \"at-end\",\n            atEnd\n        );\n        wrap.classList.toggle(\n            \"at-start\",\n            atStart\n        );\n    }\n    \/* =========================================================\n       REFRESH\n       ========================================================= *\/\n    function refreshRail(\n        rail,\n        wrap\n    ){\n        updateRailState(\n            rail,\n            wrap\n        );\n        requestAnimationFrame(\n            function(){\n                updateRailState(\n                    rail,\n                    wrap\n                );\n            }\n        );\n        setTimeout(\n            function(){\n                updateRailState(\n                    rail,\n                    wrap\n                );\n            },\n            100\n        );\n        setTimeout(\n            function(){\n                updateRailState(\n                    rail,\n                    wrap\n                );\n            },\n            300\n        );\n        setTimeout(\n            function(){\n                updateRailState(\n                    rail,\n                    wrap\n                );\n            },\n            700\n        );\n    }\n    \/* =========================================================\n       RAIL CONTROLS\n       ========================================================= *\/\n    function createRailControls(\n        rail,\n        wrap\n    ){\n        const rightEdge =\n            document.createElement(\n                \"div\"\n            );\n        rightEdge.className =\n            \"builder-product-edge builder-product-edge-right\";\n        const leftEdge =\n            document.createElement(\n                \"div\"\n            );\n        leftEdge.className =\n            \"builder-product-edge builder-product-edge-left\";\n        const rightArrow =\n            document.createElement(\n                \"button\"\n            );\n        rightArrow.type =\n            \"button\";\n        rightArrow.className =\n            \"builder-product-arrow builder-product-arrow-right\";\n        rightArrow.setAttribute(\n            \"aria-label\",\n            \"Next products\"\n        );\n        rightArrow.innerHTML =\n            '<svg viewBox=\"0 0 10 14\">' +\n            '<path d=\"M2 1.5 L7.5 7 L2 12.5\"><\/path>' +\n            '<\/svg>';\n        const leftArrow =\n            document.createElement(\n                \"button\"\n            );\n        leftArrow.type =\n            \"button\";\n        leftArrow.className =\n            \"builder-product-arrow builder-product-arrow-left\";\n        leftArrow.setAttribute(\n            \"aria-label\",\n            \"Previous products\"\n        );\n        leftArrow.innerHTML =\n            '<svg viewBox=\"0 0 10 14\">' +\n            '<path d=\"M8 1.5 L2.5 7 L8 12.5\"><\/path>' +\n            '<\/svg>';\n        rightArrow.addEventListener(\n            \"click\",\n            function(event){\n                event.preventDefault();\n                event.stopPropagation();\n                rail.scrollBy({\n                    left:\n                        getScrollStep(\n                            rail\n                        ),\n                    behavior:\n                        \"smooth\"\n                });\n                refreshRail(\n                    rail,\n                    wrap\n                );\n            }\n        );\n        leftArrow.addEventListener(\n            \"click\",\n            function(event){\n                event.preventDefault();\n                event.stopPropagation();\n                rail.scrollBy({\n                    left:\n                        -getScrollStep(\n                            rail\n                        ),\n                    behavior:\n                        \"smooth\"\n                });\n                refreshRail(\n                    rail,\n                    wrap\n                );\n            }\n        );\n        wrap.appendChild(\n            leftEdge\n        );\n        wrap.appendChild(\n            rightEdge\n        );\n        wrap.appendChild(\n            leftArrow\n        );\n        wrap.appendChild(\n            rightArrow\n        );\n        rail.addEventListener(\n            \"scroll\",\n            function(){\n                updateRailState(\n                    rail,\n                    wrap\n                );\n            },\n            {\n                passive:true\n            }\n        );\n        if(\n            typeof ResizeObserver !==\n            \"undefined\"\n        ){\n            const observer =\n                new ResizeObserver(\n                    function(){\n                        refreshRail(\n                            rail,\n                            wrap\n                        );\n                    }\n                );\n            observer.observe(\n                rail\n            );\n        }\n        refreshRail(\n            rail,\n            wrap\n        );\n    }\n    \/* =========================================================\n       TOUCH\n       ========================================================= *\/\n    function enableTouchTapGuard(\n        rail\n    ){\n        let touching =\n            false;\n        let startX =\n            0;\n        let startY =\n            0;\n        let moved =\n            false;\n        let gestureDirection =\n            null;\n        rail.addEventListener(\n            \"touchstart\",\n            function(event){\n                if(\n                    event.touches.length !==\n                    1\n                ){\n                    return;\n                }\n                const touch =\n                    event.touches[0];\n                touching =\n                    true;\n                moved =\n                    false;\n                gestureDirection =\n                    null;\n                startX =\n                    touch.clientX;\n                startY =\n                    touch.clientY;\n            },\n            {\n                passive:true\n            }\n        );\n        rail.addEventListener(\n            \"touchmove\",\n            function(event){\n                if(\n                    !touching\n                ){\n                    return;\n                }\n                if(\n                    event.touches.length !==\n                    1\n                ){\n                    return;\n                }\n                const touch =\n                    event.touches[0];\n                const dx =\n                    touch.clientX -\n                    startX;\n                const dy =\n                    touch.clientY -\n                    startY;\n                if(\n                    Math.abs(dx) < 6\n                    &&\n                    Math.abs(dy) < 6\n                ){\n                    return;\n                }\n                moved =\n                    true;\n                if(\n                    gestureDirection ===\n                    null\n                ){\n                    gestureDirection =\n                        Math.abs(dx) >\n                        Math.abs(dy)\n                            ? \"horizontal\"\n                            : \"vertical\";\n                }\n            },\n            {\n                passive:true\n            }\n        );\n        rail.addEventListener(\n            \"touchend\",\n            function(){\n                if(\n                    !touching\n                ){\n                    return;\n                }\n                touching =\n                    false;\n                if(\n                    moved\n                ){\n                    setTimeout(\n                        function(){\n                            moved =\n                                false;\n                            gestureDirection =\n                                null;\n                        },\n                        0\n                    );\n                }\n            },\n            {\n                passive:true\n            }\n        );\n        rail.addEventListener(\n            \"click\",\n            function(event){\n                if(\n                    moved\n                    &&\n                    gestureDirection ===\n                    \"horizontal\"\n                ){\n                    event.preventDefault();\n                    event.stopPropagation();\n                    moved =\n                        false;\n                    gestureDirection =\n                        null;\n                }\n            },\n            true\n        );\n    }\n    \/* =========================================================\n       DESKTOP DRAG\n       ========================================================= *\/\n    function enableDesktopDrag(\n        rail\n    ){\n        let isDown =\n            false;\n        let startX =\n            0;\n        let startScroll =\n            0;\n        let moved =\n            false;\n        rail.addEventListener(\n            \"pointerdown\",\n            function(event){\n                if(\n                    event.pointerType !==\n                    \"mouse\"\n                ){\n                    return;\n                }\n                if(\n                    event.button !==\n                    0\n                ){\n                    return;\n                }\n                isDown =\n                    true;\n                moved =\n                    false;\n                startX =\n                    event.clientX;\n                startScroll =\n                    rail.scrollLeft;\n                rail.classList.add(\n                    \"is-mouse-dragging\"\n                );\n            }\n        );\n        window.addEventListener(\n            \"pointermove\",\n            function(event){\n                if(\n                    !isDown\n                ){\n                    return;\n                }\n                const delta =\n                    event.clientX -\n                    startX;\n                if(\n                    Math.abs(delta) >\n                    5\n                ){\n                    moved =\n                        true;\n                }\n                rail.scrollLeft =\n                    startScroll -\n                    delta;\n            }\n        );\n        window.addEventListener(\n            \"pointerup\",\n            function(){\n                if(\n                    !isDown\n                ){\n                    return;\n                }\n                isDown =\n                    false;\n                rail.classList.remove(\n                    \"is-mouse-dragging\"\n                );\n            }\n        );\n        window.addEventListener(\n            \"pointercancel\",\n            function(){\n                isDown =\n                    false;\n                rail.classList.remove(\n                    \"is-mouse-dragging\"\n                );\n            }\n        );\n        rail.addEventListener(\n            \"click\",\n            function(event){\n                if(\n                    moved\n                ){\n                    event.preventDefault();\n                    event.stopPropagation();\n                    moved =\n                        false;\n                }\n            },\n            true\n        );\n    }\n    \/* =========================================================\n       CREATE CATEGORY\n       ========================================================= *\/\n    function createCategory(\n        definition,\n        products,\n        priorityImages,\n        categoryIndex\n    ){\n        const categoryEl =\n            document.createElement(\n                \"section\"\n            );\n        categoryEl.className =\n            \"builder-category\";\n        categoryEl.dataset.category =\n            definition.slug;\n        categoryEl.style.setProperty(\n            \"--category-index\",\n            categoryIndex\n        );\n        const titleEl =\n            document.createElement(\n                \"div\"\n            );\n        titleEl.className =\n            \"builder-category-title\";\n        titleEl.textContent =\n            definition.label;\n        const wrapEl =\n            document.createElement(\n                \"div\"\n            );\n        wrapEl.className =\n            \"builder-product-wrap\";\n        const railEl =\n            document.createElement(\n                \"div\"\n            );\n        railEl.className =\n            \"builder-product-rail\";\n        let cardIndex =\n            0;\n        products.forEach(\n            function(product){\n                const cards =\n                    getVisibleCards(\n                        product\n                    );\n                cards.forEach(\n                    function(card){\n                        const isPriority =\n                            cardIndex <\n                            CONFIG.priorityCardsPerRail;\n                        const cardElement =\n                            createCard(\n                                product,\n                                card,\n                                railEl,\n                                cardIndex,\n                                isPriority,\n                                priorityImages\n                            );\n                        cardIndex +=\n                            1;\n                        railEl.appendChild(\n                            cardElement\n                        );\n                    }\n                );\n            }\n        );\n        if(\n            !railEl.children.length\n        ){\n            return null;\n        }\n        wrapEl.appendChild(\n            railEl\n        );\n        categoryEl.appendChild(\n            titleEl\n        );\n        categoryEl.appendChild(\n            wrapEl\n        );\n        createRailControls(\n            railEl,\n            wrapEl\n        );\n        enableTouchTapGuard(\n            railEl\n        );\n        enableDesktopDrag(\n            railEl\n        );\n        return categoryEl;\n    }\n    \/* =========================================================\n       RENDER\n       ========================================================= *\/\n    function render(){\n        const loading =\n            root.querySelector(\n                \".lulla-products-loading\"\n            );\n        \/*\n         * Build the catalog markup off-DOM first. This lets\n         * us start every card's <img> loading immediately\n         * (browsers begin the fetch as soon as src is set,\n         * even while detached) without touching what's on\n         * screen yet, so the loader stays up until there's\n         * something worth showing instead of swapping to a\n         * screenful of blank white cards.\n         *\/\n        const visibleProducts =\n            getVisibleProducts();\n        const fragment =\n            document.createDocumentFragment();\n        const priorityImages =\n            [];\n        let categoryIndex =\n            0;\n        CONFIG.categories.forEach(\n            function(definition){\n                const categoryProducts =\n                    visibleProducts.filter(\n                        function(product){\n                            return (\n                                product.category ===\n                                definition.slug\n                            );\n                        }\n                    );\n                if(\n                    !categoryProducts.length\n                ){\n                    return;\n                }\n                const categoryElement =\n                    createCategory(\n                        definition,\n                        categoryProducts,\n                        priorityImages,\n                        categoryIndex\n                    );\n                if(\n                    categoryElement\n                ){\n                    fragment.appendChild(\n                        categoryElement\n                    );\n                    categoryIndex +=\n                        1;\n                }\n            }\n        );\n\n        function swapIn(){\n            const hasVisibleCatalog =\n                !!root.querySelector(\n                    \".builder-category\"\n                );\n\n            function commit(){\n                root.innerHTML =\n                    \"\";\n                if(\n                    fragment.childNodes.length\n                ){\n                    root.appendChild(\n                        fragment\n                    );\n                }else{\n                    const empty =\n                        document.createElement(\n                            \"div\"\n                        );\n                    empty.className =\n                        \"lulla-products-loading\";\n                    empty.textContent =\n                        \"No products available.\";\n                    root.appendChild(\n                        empty\n                    );\n                }\n                requestAnimationFrame(\n                    function(){\n                        scheduleCanvasImagePreload(\n                            visibleProducts\n                        );\n                        fitLandscape();\n                        requestAnimationFrame(\n                            function(){\n                                fitLandscape();\n                                root.classList.remove(\n                                    \"is-catalog-swapping\"\n                                );\n                            }\n                        );\n                    }\n                );\n            }\n\n            if(\n                hasVisibleCatalog\n            ){\n                root.classList.add(\n                    \"is-catalog-swapping\"\n                );\n                setTimeout(\n                    commit,\n                    160\n                );\n            }else{\n                commit();\n            }\n        }\n\n        \/*\n         * Wait for the first screenful of photos on EVERY\n         * render \u2014 not only the very first catalog load. A\n         * gender\/age filter switch calls render() directly\n         * with no loader overlay present, and that path was\n         * previously skipping the image wait entirely and\n         * swapping in immediately, which is exactly what kept\n         * showing empty cards on filter changes. Each image is\n         * capped individually so one slow photo on a bad\n         * connection can never hold up the whole reveal.\n         *\/\n        const imagesReady =\n            Promise.all(\n                priorityImages.map(\n                    function(img){\n                        return waitForImage(\n                            img,\n                            CONFIG.priorityImageTimeout\n                        );\n                    }\n                )\n            );\n        if(\n            loading\n        ){\n            loading.classList.add(\n                \"is-exiting\"\n            );\n            \/*\n             * First load only: also respect the loader's own\n             * fade-out transition length so it doesn't get cut\n             * off mid-animation.\n             *\/\n            const minDelay =\n                new Promise(\n                    function(resolve){\n                        setTimeout(\n                            resolve,\n                            CONFIG.loaderFadeDelay\n                        );\n                    }\n                );\n            Promise.all(\n                [\n                    minDelay,\n                    imagesReady\n                ]\n            ).then(\n                swapIn\n            );\n        }else{\n            imagesReady.then(\n                swapIn\n            );\n        }\n    }\n    \/* =========================================================\n       APPLY FILTER\n       ========================================================= *\/\n    function applyFilter(\n        gender,\n        ageRange\n    ){\n        if(\n            gender === \"boys\"\n            ||\n            gender === \"girls\"\n        ){\n            state.gender =\n                gender;\n        }\n        if(\n            ageRange\n        ){\n            state.ageRange =\n                normalizeAgeValue(\n                    ageRange\n                );\n        }\n        clearActiveProducts();\n        if(state.catalogLoaded){\n            render();\n            return;\n        }\n        loadCatalog()\n            .then(\n                function(){\n                    render();\n                }\n            )\n            .catch(\n                function(){\n                    \/* Error already rendered. *\/\n                }\n            );\n    }\n    \/* =========================================================\n       FILTER EVENT\n       ========================================================= *\/\n    function handleFilterEvent(\n        event\n    ){\n        if(\n            !event ||\n            !event.detail\n        ){\n            return;\n        }\n        const detail =\n            event.detail;\n        const signature =\n            (\n                detail.gender ||\n                \"\"\n            )\n            +\n            \"|\"\n            +\n            (\n                detail.ageRange ||\n                \"\"\n            );\n        if(\n            signature ===\n            lastFilterSignature\n        ){\n            return;\n        }\n        lastFilterSignature =\n            signature;\n        applyFilter(\n            detail.gender,\n            detail.ageRange\n        );\n    }\n    document.addEventListener(\n        \"lulla:gender-change\",\n        handleFilterEvent\n    );\n    document.addEventListener(\n        \"lulla:catalog-filter-change\",\n        handleFilterEvent\n    );\n    \/* =========================================================\n       INITIALIZATION\n       ========================================================= *\/\n    function init(){\n        if(\n            state.initialized\n        ){\n            return;\n        }\n        state.initialized =\n            true;\n    }\n    if(\n        document.readyState ===\n        \"loading\"\n    ){\n        document.addEventListener(\n            \"DOMContentLoaded\",\n            init,\n            {\n                once:true\n            }\n        );\n    }else{\n        init();\n    }\n    if(\n        typeof jQuery !==\n        \"undefined\"\n    ){\n        jQuery(window).on(\n            \"elementor\/frontend\/init\",\n            init\n        );\n    }\n    \/* =========================================================\n       ROOT RESIZE OBSERVER\n       ========================================================= *\/\n    if(\n        typeof ResizeObserver !==\n        \"undefined\"\n    ){\n        const rootResizeObserver =\n            new ResizeObserver(\n                function(){\n                    fitLandscape();\n                    root\n                        .querySelectorAll(\n                            \".builder-product-rail\"\n                        )\n                        .forEach(\n                            function(rail){\n                                const wrap =\n                                    rail.closest(\n                                        \".builder-product-wrap\"\n                                    );\n                                if(\n                                    wrap\n                                ){\n                                    refreshRail(\n                                        rail,\n                                        wrap\n                                    );\n                                }\n                            }\n                        );\n                }\n            );\n        rootResizeObserver.observe(\n            root\n        );\n    }\n    \/* =========================================================\n       WINDOW RESIZE\n       ========================================================= *\/\n    window.addEventListener(\n        \"resize\",\n        function(){\n            fitLandscape();\n        },\n        {\n            passive:true\n        }\n    );\n    \/* =========================================================\n       DEBUG API\n       ========================================================= *\/\n    window.LullaProductScroll = {\n        getState:\n            function(){\n                return {\n                    gender:\n                        state.gender,\n                    ageRange:\n                        state.ageRange,\n                    catalogLoaded:\n                        state.catalogLoaded,\n                    productCount:\n                        state.catalog.length,\n                    activeProducts:\n                        state.activeProducts\n                };\n            },\n        reload:\n            function(){\n                state.catalogLoaded =\n                    false;\n                state.catalog =\n                    [];\n                fetchPromise =\n                    null;\n                loadCatalog()\n                    .then(\n                        function(){\n                            render();\n                        }\n                    );\n            }\n    };\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b9429ba e-con-full e-flex e-con e-child\" data-id=\"b9429ba\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-510e194 elementor-widget elementor-widget-html\" data-id=\"510e194\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!--\n=========================================================\nLULLA \u2014 STATE 3 \/ SIZE BUILDER\n=========================================================\n-->\n<div\n  class=\"lulla-size-screen\"\n  aria-hidden=\"true\"\n>\n  <div class=\"lulla-size-header\">\n    <span class=\"lulla-size-header-text\">\n      Choose Your Sizes\n    <\/span>\n  <\/div>\n  <div class=\"lulla-size-builder\">\n    <div class=\"lulla-size-list\"><\/div>\n  <\/div>\n  <div\n    class=\"lulla-size-success-screen\"\n    aria-hidden=\"true\"\n  >\n    <div class=\"lulla-size-success-content\">\n      <div class=\"lulla-size-success-check-wrap\">\n        <div class=\"lulla-size-success-check\">\n          <img decoding=\"async\" class=\"lulla-size-success-bag-icon\" src=\"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/shopping-bag-icon.svg\" alt=\"\" aria-hidden=\"true\">\n        <\/div>\n      <\/div>\n      <div class=\"lulla-size-success-title\">\n        Added to bag\n      <\/div>\n      <div class=\"lulla-size-success-text\">\n        \n      <\/div>\n      <div class=\"lulla-size-success-actions\">\n        <button\n          type=\"button\"\n          class=\"lulla-size-another-button\"\n        >\n          MAKE ANOTHER OUTFIT\n        <\/button>\n        <button\n          type=\"button\"\n          class=\"lulla-size-home-button\"\n        >\n          BACK TO HOME\n        <\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n  <div class=\"lulla-size-footer\">\n    <div class=\"lulla-size-footer-total\">\n      <span\n        class=\"lulla-size-total-label\"\n        data-size-count\n      >\n        0 ITEMS\n      <\/span>\n      <span\n        class=\"lulla-size-total-price\"\n        data-size-total\n      >\n        \u20ac0,00\n      <\/span>\n    <\/div>\n    <button\n      type=\"button\"\n      class=\"lulla-size-cart-button\"\n      disabled\n    >\n      ADD OUTFIT TO CART\n    <\/button>\n  <\/div>\n<\/div>\n<script>\n(function(){\n  \"use strict\";\n  \/* =========================================================\n     ELEMENTS\n  ========================================================= *\/\n  var root =\n    document.querySelector(\n      \".lulla-size-screen\"\n    );\n  if(!root){\n    return;\n  }\n\n  \/* =========================================================\n     SIZE GUIDE \u2014 MOVE GLOBAL MODAL TO BODY\n     Keeps the existing Size Guide UX unchanged, but removes\n     the modal from the right State 3 stacking context so the\n     overlay + blur can cover the entire interface.\n  ========================================================= *\/\n  function moveSizeGuideModalToBody(){\n    var modal =\n      document.querySelector(\n        \".lulla-size-guide-modal\"\n      );\n\n    if(\n      modal &&\n      modal.parentNode !==\n        document.body\n    ){\n      document.body.appendChild(\n        modal\n      );\n    }\n\n    return modal;\n  }\n\n  moveSizeGuideModalToBody();\n\n  var list =\n    root.querySelector(\n      \".lulla-size-list\"\n    );\n  var totalEl =\n    root.querySelector(\n      \"[data-size-total]\"\n    );\n  var countEl =\n    root.querySelector(\n      \"[data-size-count]\"\n    );\n  var cartButton =\n    root.querySelector(\n      \".lulla-size-cart-button\"\n    );\n  var footer =\n    root.querySelector(\n      \".lulla-size-footer\"\n    );\n  var successScreen =\n    root.querySelector(\n      \".lulla-size-success-screen\"\n    );\n\n  var anotherButton =\n    root.querySelector(\n      \".lulla-size-another-button\"\n    );\n  var homeButton =\n    root.querySelector(\n      \".lulla-size-home-button\"\n    );\n  var productsRoot =\n    document.getElementById(\n      \"builder-products-root\"\n    );\n  \/* =========================================================\n     STATE\n  ========================================================= *\/\n  var activeProducts = {};\n  var itemOrder = [];\n  var cardMap = {};\n  var confirmedSizes = {};\n  var selectedSizes = {};\n  var activeCategory = null;\n  var outfitAdded = false;\n  var cartRequestInFlight = false;\n  var visibilityState = \"hidden\";\n  var renderVersion = 0;\n  var detailsCache = {};\n  var detailsPending = {};\n  var MOBILE_COLLAPSE_MS = 460;\n  var CARD_REMOVE_ANIMATION_MS = 340;\n  var EMPTY_CLOSE_ANIMATION_MS = 440;\n  var EMPTY_CLOSE_HANDOFF_MS = 250;\n  var SIZE_GUIDE_ICON_URL =\n    \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/scale-ruler-icon.svg\";\n  var CHECK_ICON_URL =\n    \"https:\/\/lullastudio.com\/wp-content\/uploads\/2026\/09\/action-check-checkmark-ok-icon-svgrepo-com.svg\";\n  var closingTimers = {};\n  var mobileFooterMotionTimer = null;\n  var emptyCloseInProgress = false;\n  function animateMobileFooterOut(){\n    if(\n      !footer ||\n      !isPhoneView() ||\n      !root.classList.contains(\"is-mobile-footer-visible\") ||\n      outfitAdded\n    ){\n      return;\n    }\n    if(mobileFooterMotionTimer){\n      window.clearTimeout(mobileFooterMotionTimer);\n      mobileFooterMotionTimer = null;\n    }\n    root.classList.remove(\"is-mobile-footer-entering\");\n    root.classList.add(\"is-mobile-footer-visible\",\"is-mobile-footer-leaving\");\n    void footer.offsetWidth;\n    mobileFooterMotionTimer = window.setTimeout(function(){\n      root.classList.remove(\n        \"is-mobile-footer-visible\",\n        \"is-mobile-footer-leaving\"\n      );\n      mobileFooterMotionTimer = null;\n    }, 360);\n  }\n\n  function animateMobileFooterIn(){\n    if(\n      !footer ||\n      !isPhoneView() ||\n      outfitAdded ||\n      !allSizesConfirmed()\n    ){\n      return;\n    }\n    if(mobileFooterMotionTimer){\n      window.clearTimeout(mobileFooterMotionTimer);\n      mobileFooterMotionTimer = null;\n    }\n    root.classList.remove(\"is-mobile-footer-leaving\");\n    root.classList.add(\n      \"is-mobile-footer-visible\",\n      \"is-mobile-footer-entering\"\n    );\n    void footer.offsetWidth;\n    window.requestAnimationFrame(function(){\n      if(\n        !outfitAdded &&\n        isPhoneView() &&\n        allSizesConfirmed()\n      ){\n        root.classList.remove(\"is-mobile-footer-entering\");\n      }\n    });\n  }\n\n  \/* =========================================================\n     STATE 3 CONNECTION\n  ========================================================= *\/\n  function notifyState3SizeState(){\n    var state = {\n      activeProducts:\n        activeProducts || {},\n      confirmedSizes:\n        confirmedSizes || {}\n    };\n    document.dispatchEvent(\n      new CustomEvent(\n        \"lulla:size-state-change\",\n        {\n          bubbles:true,\n          detail:\n            state\n        }\n      )\n    );\n    if(\n      window.LullaState3SetSizeState\n    ){\n      window.LullaState3SetSizeState(\n        state.activeProducts,\n        state.confirmedSizes\n      );\n    }\n  }\n  window.LullaState3GetSizeState =\n    function(){\n      return {\n        activeProducts:\n          activeProducts || {},\n        confirmedSizes:\n          confirmedSizes || {}\n      };\n    };\n  \/* =========================================================\n     HELPERS\n  ========================================================= *\/\n  function isPhoneView(){\n    var width =\n      window.innerWidth ||\n      document.documentElement.clientWidth ||\n      0;\n    var height =\n      window.innerHeight ||\n      document.documentElement.clientHeight ||\n      0;\n    return (\n      width <= 600 ||\n      (\n        width > 600 &&\n        height <= 500\n      )\n    );\n  }\n\n  \/* =========================================================\n     MOBILE HEADER SLOT \u2014 KEEP REAL HEADER SPACE DURING MORPH\n     ---------------------------------------------------------\n     The mobile card must expand ABOVE the existing layout,\n     not make the builder\/list jump upward by removing the\n     header's physical 34px slot.\n\n     The real header remains in the flex layout and is visually\n     covered by the fixed morph card. No fake visible spacer is\n     inserted into the UI.\n  ========================================================= *\/\n  function lockMobileHeaderSlot(){\n    if(!isPhoneView()){\n      return;\n    }\n\n    var header =\n      root.querySelector(\n        \".lulla-size-header\"\n      );\n    var builder =\n      root.querySelector(\n        \".lulla-size-builder\"\n      );\n\n    if(header){\n      var headerRect =\n        header.getBoundingClientRect();\n      var computedHeader =\n        window.getComputedStyle(\n          header\n        );\n      var headerHeight =\n        headerRect.height ||\n        parseFloat(\n          computedHeader.height\n        ) ||\n        34;\n\n      header.style.setProperty(\n        \"position\",\n        \"relative\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"display\",\n        \"flex\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"height\",\n        headerHeight + \"px\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"min-height\",\n        headerHeight + \"px\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"max-height\",\n        headerHeight + \"px\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"flex\",\n        \"0 0 \" + headerHeight + \"px\",\n        \"important\"\n      );\n\n      \/*\n       * Keep the header physically present. The active card is\n       * above it, so this does NOT create a visible rectangle.\n       *\/\n      header.style.setProperty(\n        \"visibility\",\n        \"visible\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"opacity\",\n        \"1\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"transform\",\n        \"none\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"pointer-events\",\n        \"none\",\n        \"important\"\n      );\n      header.style.setProperty(\n        \"z-index\",\n        \"0\",\n        \"important\"\n      );\n    }\n\n    if(builder){\n      \/*\n       * Critical part:\n       * keep Builder below the real Header in the flex layout.\n       * The morph card itself is fixed and can cover the Header.\n       *\/\n      builder.style.setProperty(\n        \"position\",\n        \"relative\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"top\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"right\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"bottom\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"left\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"inset\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"width\",\n        \"100%\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"height\",\n        \"auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"min-height\",\n        \"0\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"flex\",\n        \"1 1 auto\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"z-index\",\n        \"300\",\n        \"important\"\n      );\n      builder.style.setProperty(\n        \"isolation\",\n        \"isolate\",\n        \"important\"\n      );\n    }\n\n    if(list){\n      \/*\n       * The list stays inside the Builder's real area, which now\n       * begins BELOW the header. This is the preserved slot.\n       *\/\n      list.style.setProperty(\n        \"position\",\n        \"absolute\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"top\",\n        \"0\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"right\",\n        \"0\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"bottom\",\n        \"0\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"left\",\n        \"0\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"width\",\n        \"100%\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"height\",\n        \"100%\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"overflow\",\n        \"hidden\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"overflow-y\",\n        \"hidden\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"overflow-x\",\n        \"hidden\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"touch-action\",\n        \"none\",\n        \"important\"\n      );\n      list.style.setProperty(\n        \"overscroll-behavior\",\n        \"none\",\n        \"important\"\n      );\n    }\n  }\n\n  function unlockMobileHeaderSlot(){\n    var header =\n      root.querySelector(\n        \".lulla-size-header\"\n      );\n    var builder =\n      root.querySelector(\n        \".lulla-size-builder\"\n      );\n\n    [\n      header,\n      builder,\n      list\n    ].forEach(function(element){\n      if(!element){\n        return;\n      }\n\n      [\n        \"position\",\n        \"display\",\n        \"height\",\n        \"min-height\",\n        \"max-height\",\n        \"flex\",\n        \"visibility\",\n        \"opacity\",\n        \"transform\",\n        \"pointer-events\",\n        \"z-index\",\n        \"top\",\n        \"right\",\n        \"bottom\",\n        \"left\",\n        \"inset\",\n        \"width\",\n        \"isolation\",\n        \"overflow\",\n        \"overflow-y\",\n        \"overflow-x\",\n        \"touch-action\",\n        \"overscroll-behavior\"\n      ].forEach(function(property){\n        element.style.removeProperty(\n          property\n        );\n      });\n    });\n  }\n  function setStatusHidden(\n    status,\n    hidden\n  ){\n    if(!status){\n      return;\n    }\n    status.classList.toggle(\n      \"is-status-hidden\",\n      !!hidden\n    );\n    status.style.opacity =\n      hidden\n        ? \"0\"\n        : \"\";\n    status.style.pointerEvents =\n      hidden\n        ? \"none\"\n        : \"\";\n  }\n\n  function fadeStatusInAfterClose(status){\n    if(!status){\n      return;\n    }\n    status.classList.remove(\"is-status-hidden\");\n    status.style.transition =\n      \"opacity .24s cubic-bezier(.22,.61,.36,1)\";\n    status.style.opacity = \"0\";\n    status.style.pointerEvents = \"none\";\n    void status.offsetWidth;\n    window.requestAnimationFrame(function(){\n      window.requestAnimationFrame(function(){\n        status.style.opacity = \"1\";\n        status.style.pointerEvents = \"\";\n        window.setTimeout(function(){\n          status.style.removeProperty(\"transition\");\n          status.style.removeProperty(\"opacity\");\n        }, 260);\n      });\n    });\n  }\n  var TOGGLE_ICONS = {\n    add:\n      '<svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">' +\n      '<path d=\"M10 4v12M4 10h12\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"\/>' +\n      '<\/svg>',\n    expand:\n      '<svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">' +\n      '<path d=\"M5 8l5 5 5-5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>' +\n      '<\/svg>',\n    close:\n      '<svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">' +\n      '<path d=\"M5 12l5-5 5 5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>' +\n      '<\/svg>'\n  };\n  function setToggleIcon(\n    toggle,\n    state\n  ){\n    if(!toggle){\n      return;\n    }\n    if(\n      !toggle.querySelector(\n        \".lulla-toggle-icon\"\n      )\n    ){\n      toggle.innerHTML =\n        '<span class=\"lulla-toggle-surface\" aria-hidden=\"true\"><\/span>' +\n        '<span class=\"lulla-toggle-label lulla-toggle-label-add\" aria-hidden=\"true\">' +\n          \"ADD SIZE\" +\n        '<\/span>' +\n        '<span class=\"lulla-toggle-icon lulla-toggle-icon-add\" aria-hidden=\"true\">' +\n          TOGGLE_ICONS.add +\n        '<\/span>' +\n        '<span class=\"lulla-toggle-icon lulla-toggle-icon-expand\" aria-hidden=\"true\">' +\n          TOGGLE_ICONS.expand +\n        '<\/span>' +\n        '<span class=\"lulla-toggle-icon lulla-toggle-icon-close\" aria-hidden=\"true\">' +\n          TOGGLE_ICONS.close +\n        '<\/span>';\n    }\n    toggle.classList.remove(\n      \"is-add\",\n      \"is-expand\",\n      \"is-close\"\n    );\n    toggle.classList.add(\n      \"is-\" +\n      state\n    );\n    toggle.dataset.toggleState =\n      state;\n    var labels = {\n      add:\n        \"Add size\",\n      expand:\n        \"Open size\",\n      close:\n        \"Close\"\n    };\n    toggle.setAttribute(\n      \"aria-label\",\n      labels[state] ||\n      labels.add\n    );\n  }\n  function toggleStateFor(\n    category\n  ){\n    if(\n      activeCategory ===\n      category\n    ){\n      return \"close\";\n    }\n    if(\n      confirmedSizes[\n        category\n      ]\n    ){\n      return \"expand\";\n    }\n    return \"add\";\n  }\n  function formatPrice(\n    value\n  ){\n    var number =\n      Number(value) || 0;\n    return (\n      \"\u20ac\" +\n      number\n        .toFixed(2)\n        .replace(\".\",\",\")\n    );\n  }\n  \/* =========================================================\n     PRODUCT IDENTITY\n     ---------------------------------------------------------\n     State 3 builds each card from a snapshot of the selected\n     product (title\/price\/image\/sizes\/variation IDs) and closes\n     over that snapshot in the card's event handlers. If State 2\n     swaps the selected product for a category (Top A -> Top B)\n     without the category ever disappearing from activeProducts,\n     an existing card in `cardMap` must not be silently reused \u2014\n     it still represents the OLD product. This gives every card\n     a stable identity string so renderProducts() can detect that\n     mismatch and treat it as a real replacement (see the\n     `changedCategories` handling in renderProducts()).\n  ========================================================= *\/\n  function getProductIdentity(\n    product\n  ){\n    if(!product){\n      return \"\";\n    }\n    var productId =\n      product.productId ||\n      product.id ||\n      \"\";\n    var variantType =\n      product.variantType ||\n      \"\";\n    var variantValue =\n      product.variantValue ||\n      \"\";\n    return (\n      String(productId) +\n      \":\" +\n      String(variantType) +\n      \":\" +\n      String(variantValue)\n    );\n  }\n  var STATE3_CATEGORY_ORDER = [\n    \"hats\",\n    \"tops\",\n    \"onepiece-sets\",\n    \"outwear\",\n    \"bottoms\",\n    \"accessories\"\n  ];\n\n  function getState3CategoryOrderIndex(\n    category\n  ){\n    var index =\n      STATE3_CATEGORY_ORDER.indexOf(\n        category\n      );\n    return index === -1\n      ? STATE3_CATEGORY_ORDER.length\n      : index;\n  }\n\n  function insertCardInState3Order(\n    card,\n    category\n  ){\n    if(!card || !list){\n      return;\n    }\n    var targetIndex =\n      getState3CategoryOrderIndex(\n        category\n      );\n    var children =\n      Array.prototype.slice.call(\n        list.querySelectorAll(\n          \".lulla-size-card\"\n        )\n      );\n    var insertBefore = null;\n    children.some(function(existingCard){\n      if(existingCard === card){\n        return false;\n      }\n      var existingCategory =\n        existingCard.dataset\n          ? existingCard.dataset.category\n          : \"\";\n      if(\n        getState3CategoryOrderIndex(\n          existingCategory\n        ) > targetIndex\n      ){\n        insertBefore = existingCard;\n        return true;\n      }\n      return false;\n    });\n    if(insertBefore){\n      list.insertBefore(\n        card,\n        insertBefore\n      );\n    }else{\n      list.appendChild(card);\n    }\n  }\n  function calculateTotal(){\n    var total =\n      0;\n    itemOrder.forEach(\n      function(category){\n        var entry =\n          activeProducts[\n            category\n          ];\n        if(\n          !entry ||\n          !entry.product\n        ){\n          return;\n        }\n        total +=\n          Number(\n            entry.product.price\n          ) || 0;\n      }\n    );\n    return total;\n  }\n  function countConfirmedItems(){\n    return itemOrder.filter(\n      function(category){\n        return !!confirmedSizes[\n          category\n        ];\n      }\n    ).length;\n  }\n  function allSizesConfirmed(){\n    if(\n      !itemOrder.length\n    ){\n      return false;\n    }\n    return itemOrder.every(\n      function(category){\n        return !!confirmedSizes[\n          category\n        ];\n      }\n    );\n  }\n  function updateFooter(){\n    if(totalEl){\n      totalEl.textContent =\n        formatPrice(\n          calculateTotal()\n        );\n    }\n    if(countEl){\n      var count =\n        itemOrder.length;\n      countEl.textContent =\n        count +\n        (\n          count === 1\n            ? \" ITEM\"\n            : \" ITEMS\"\n        );\n    }\n    var confirmed =\n      allSizesConfirmed();\n    if(cartButton){\n      cartButton.disabled =\n        !confirmed ||\n        cartRequestInFlight ||\n        outfitAdded;\n    }\n    if(\n      isPhoneView()\n    ){\n      if(\n        confirmed &&\n        !activeCategory &&\n        !outfitAdded\n      ){\n        animateMobileFooterIn();\n      }else{\n        animateMobileFooterOut();\n      }\n    }else{\n      root.classList.remove(\n        \"is-mobile-footer-visible\",\n        \"is-mobile-footer-entering\",\n        \"is-mobile-footer-leaving\"\n      );\n    }\n  }\n  function removeGeneratedViewCart(){\n    if(!footer){\n      return;\n    }\n    footer\n      .querySelectorAll(\n        \"a.added_to_cart.wc-forward\"\n      )\n      .forEach(\n        function(link){\n          link.remove();\n        }\n      );\n  }\n  if(footer){\n    removeGeneratedViewCart();\n    var cartLinkObserver =\n      new MutationObserver(\n        function(){\n          removeGeneratedViewCart();\n        }\n      );\n    cartLinkObserver.observe(\n      footer,\n      {\n        childList:true,\n        subtree:true\n      }\n    );\n  }\n  \/* =========================================================\n     DETAILS\n  ========================================================= *\/\n  function setRichText(\n    element,\n    value\n  ){\n    if(!element){\n      return;\n    }\n    var html =\n      value == null\n        ? \"\"\n        : String(value);\n    var parser =\n      new DOMParser();\n    var parsed =\n      parser.parseFromString(\n        \"<div>\" +\n        html +\n        \"<\/div>\",\n        \"text\/html\"\n      );\n    parsed\n      .querySelectorAll(\n        \"script,iframe,object,embed,base,form\"\n      )\n      .forEach(\n        function(node){\n          node.remove();\n        }\n      );\n    parsed\n      .querySelectorAll(\"*\")\n      .forEach(\n        function(node){\n          Array.prototype\n            .slice\n            .call(\n              node.attributes\n            )\n            .forEach(\n              function(attribute){\n                if(\n                  attribute.name\n                    .toLowerCase()\n                    .indexOf(\"on\") === 0\n                ){\n                  node.removeAttribute(\n                    attribute.name\n                  );\n                }\n              }\n            );\n        }\n      );\n    element.innerHTML =\n      parsed.body.firstElementChild\n        ? parsed.body.firstElementChild.innerHTML\n        : \"\";\n  }\n  function fetchItemDetails(\n    productId\n  ){\n    if(!productId){\n      return Promise.resolve(\n        {}\n      );\n    }\n    if(\n      detailsCache[\n        productId\n      ]\n    ){\n      return Promise.resolve(\n        detailsCache[\n          productId\n        ]\n      );\n    }\n    if(\n      detailsPending[\n        productId\n      ]\n    ){\n      return detailsPending[\n        productId\n      ];\n    }\n    detailsPending[\n      productId\n    ] =\n      fetch(\n        \"\/wp-json\/lulla\/v1\/mixmatch-item\/\" +\n        productId,\n        {\n          credentials:\n            \"same-origin\"\n        }\n      )\n      .then(\n        function(response){\n          if(!response.ok){\n            throw new Error(\n              \"Product details unavailable.\"\n            );\n          }\n          return response.json();\n        }\n      )\n      .then(\n        function(data){\n          detailsCache[\n            productId\n          ] =\n            data || {};\n          return data || {};\n        }\n      )\n      .catch(\n        function(){\n          return {};\n        }\n      )\n      .finally(\n        function(){\n          delete detailsPending[\n            productId\n          ];\n        }\n      );\n    return detailsPending[\n      productId\n    ];\n  }\n  \/* =========================================================\n     RESET ALL CARDS\n  ========================================================= *\/\n  function resetAllCardsToClosed(\n    options\n  ){\n    options =\n      options ||\n      {};\n    var clearGallery =\n      options.clearGallery !== false;\n    Object.keys(\n      closingTimers\n    )\n    .forEach(\n      function(category){\n        window.clearTimeout(\n          closingTimers[\n            category\n          ]\n        );\n      }\n    );\n    closingTimers =\n      {};\n    activeCategory =\n      null;\n    root.classList.remove(\n      \"is-card-open\",\n      \"is-mobile-card-open\",\n      \"is-list-locked\",\n      \"is-list-revealing\",\n      \"is-cart-locked\",\n      \"is-empty-closing\",\n      \"is-mobile-footer-entering\",\n      \"is-mobile-footer-leaving\"\n    );\n    unlockMobileHeaderSlot();\n    if(mobileFooterMotionTimer){\n      window.clearTimeout(mobileFooterMotionTimer);\n      mobileFooterMotionTimer = null;\n    }\n    Object.keys(\n      cardMap\n    ).forEach(function(category){\n      removeMorphPlaceholder(\n        cardMap[category]\n      );\n      clearMorphGeometry(\n        cardMap[category]\n      );\n    });\n    Object.keys(\n      cardMap\n    )\n    .forEach(\n      function(category){\n        var card =\n          cardMap[\n            category\n          ];\n        if(!card){\n          return;\n        }\n        card.style.removeProperty(\"z-index\");\n        card.classList.remove(\n          \"is-active\",\n          \"is-closing\",\n          \"is-next-arriving\"\n        );\n        var status =\n          card.querySelector(\n            \".lulla-size-card-status\"\n          );\n        if(status){\n          setStatusHidden(\n            status,\n            false\n          );\n        }\n        setToggleIcon(\n          card.querySelector(\n            \".lulla-size-card-toggle\"\n          ),\n          toggleStateFor(\n            category\n          )\n        );\n        updateCardStatus(\n          card,\n          category\n        );\n        updateConfirmButton(\n          card,\n          category\n        );\n        syncCardSizeOptions(\n          card,\n          category\n        );\n      }\n    );\n    if(clearGallery){\n      if(\n        window.LullaClearItemInfo\n      ){\n        window.LullaClearItemInfo();\n      }\n    }\n    updateFooter();\n    updateMobileScrollState();\n    notifyState3SizeState();\n  }\n  \/* =========================================================\n     LIGHTWEIGHT MOBILE VISUAL PREWARM\n     Prepare the already-rendered card geometry and decode active\n     product images before the first tap. No loops or timers persist.\n  ========================================================= *\/\n  function prewarmMobileVisuals(){\n    if(!isPhoneView()){\n      return;\n    }\n\n    var images = [];\n\n    itemOrder.forEach(function(category){\n      var card = cardMap[category];\n      if(card){\n        var thumb = card.querySelector(\".lulla-size-card-thumb\");\n        if(thumb){\n          images.push(thumb);\n        }\n      }\n\n      var entry = activeProducts[category];\n      var product = entry && entry.product;\n      if(product && product.image){\n        var preloaded = new Image();\n        preloaded.decoding = \"async\";\n        preloaded.src = product.image;\n        images.push(preloaded);\n      }\n    });\n\n    window.requestAnimationFrame(function(){\n      itemOrder.forEach(function(category){\n        var card = cardMap[category];\n        if(card){\n          card.getBoundingClientRect();\n        }\n      });\n\n      images.forEach(function(image){\n        if(image && typeof image.decode === \"function\" && !image.complete){\n          image.decode().catch(function(){});\n        }\n      });\n    });\n  }\n\n  \/* =========================================================\n     SHOW \/ HIDE PANEL\n  ========================================================= *\/\n  function showPanel(){\n    emptyCloseInProgress = false;\n    root.style.pointerEvents = \"auto\";\n    root.classList.remove(\"is-phone-empty-closing\",\"is-empty-closing\",\"is-empty-closing-active\");\n    if(footer){\n      footer.style.pointerEvents = \"\";\n    }\n    if(cartButton){\n      cartButton.style.pointerEvents = \"\";\n    }\n    resetAllCardsToClosed({\n      clearGallery:true\n    });\n    if(\n      visibilityState ===\n      \"visible\" ||\n      visibilityState ===\n      \"entering\"\n    ){\n      updateFooter();\n      notifyState3SizeState();\n      return;\n    }\n    root.classList.remove(\n      \"is-leaving\"\n    );\n    root.classList.add(\n      \"is-entering\"\n    );\n    root.setAttribute(\n      \"aria-hidden\",\n      \"false\"\n    );\n    visibilityState =\n      \"entering\";\n    requestAnimationFrame(\n      function(){\n        requestAnimationFrame(\n          function(){\n            if(\n              visibilityState !==\n              \"entering\"\n            ){\n              return;\n            }\n            root.classList.remove(\n              \"is-entering\"\n            );\n            root.classList.add(\n              \"is-visible\"\n            );\n            visibilityState =\n              \"visible\";\n            resetAllCardsToClosed({\n              clearGallery:true\n            });\n            notifyState3SizeState();\n            updateFooter();\n          }\n        );\n      }\n    );\n  }\n  function hidePanel(){\n    resetAllCardsToClosed({\n      clearGallery:true\n    });\n    if(\n      visibilityState ===\n      \"hidden\"\n    ){\n      return;\n    }\n    root.classList.remove(\n      \"is-entering\",\n      \"is-visible\"\n    );\n    root.classList.add(\n      \"is-leaving\"\n    );\n    if(\n      root.contains(\n        document.activeElement\n      ) &&\n      typeof document.activeElement.blur ===\n        \"function\"\n    ){\n      document.activeElement.blur();\n    }\n    root.setAttribute(\n      \"aria-hidden\",\n      \"true\"\n    );\n    visibilityState =\n      \"leaving\";\n    window.setTimeout(\n      function(){\n        root.classList.remove(\n          \"is-leaving\"\n        );\n        visibilityState =\n          \"hidden\";\n        resetAllCardsToClosed({\n          clearGallery:true\n        });\n      },\n      500\n    );\n  }\n  \/* =========================================================\n     TABS\n  ========================================================= *\/\n  function setActiveTab(\n    card,\n    tab\n  ){\n    card\n      .querySelectorAll(\n        \".lulla-size-card-tab\"\n      )\n      .forEach(\n        function(button){\n          button.classList.toggle(\n            \"is-active\",\n            button.dataset.tab ===\n            tab\n          );\n        }\n      );\n    card\n      .querySelectorAll(\n        \".lulla-size-card-tab-panel\"\n      )\n      .forEach(\n        function(panel){\n          panel.classList.toggle(\n            \"is-active\",\n            panel.dataset.tabPanel ===\n            tab\n          );\n        }\n      );\n  }\n  \/* =========================================================\n     STATUS\n  ========================================================= *\/\n  function updateCardStatus(\n    card,\n    category\n  ){\n    var status =\n      card.querySelector(\n        \".lulla-size-card-status\"\n      );\n    if(!status){\n      return;\n    }\n    var confirmed =\n      confirmedSizes[\n        category\n      ];\n    var pill =\n      status.querySelector(\n        \".lulla-size-card-status-pill\"\n      );\n    if(!pill){\n      pill =\n        document.createElement(\n          \"span\"\n        );\n      pill.className =\n        \"lulla-size-card-status-pill\";\n      var size =\n        document.createElement(\n          \"span\"\n        );\n      size.className =\n        \"lulla-size-card-status-size\";\n      var check =\n        document.createElement(\n          \"span\"\n        );\n      check.className =\n        \"lulla-size-card-status-check\";\n      check.innerHTML =\n        '<img decoding=\"async\" src=\"' +\n        CHECK_ICON_URL +\n        '\" alt=\"\" aria-hidden=\"true\">';\n      pill.appendChild(\n        size\n      );\n      pill.appendChild(\n        check\n      );\n      status.appendChild(\n        pill\n      );\n    }\n    if(confirmed){\n      pill\n        .querySelector(\n          \".lulla-size-card-status-size\"\n        )\n        .textContent =\n          confirmed.sizeLabel;\n    }\n    status.classList.toggle(\n      \"is-confirmed\",\n      !!confirmed\n    );\n  }\n  function syncCardSizeOptions(\n    card,\n    category\n  ){\n    var selected =\n      selectedSizes[\n        category\n      ];\n    var confirmed =\n      confirmedSizes[\n        category\n      ];\n    var active =\n      selected ||\n      confirmed;\n    card\n      .querySelectorAll(\n        \".lulla-size-option\"\n      )\n      .forEach(\n        function(button){\n          var variationId =\n            Number(\n              button.dataset.variationId\n            );\n          button.classList.toggle(\n            \"is-selected\",\n            !!active &&\n            variationId ===\n            Number(\n              active.variationId\n            )\n          );\n        }\n      );\n  }\n  \/* =========================================================\n     OPEN CARD\n     MOBILE = REAL GEOMETRY MORPH\n     Desktop logic below remains unchanged.\n  ========================================================= *\/\n  function ensureMorphPlaceholder(card){\n    if(!card){\n      return null;\n    }\n    if(card._lullaMorphPlaceholder && card._lullaMorphPlaceholder.parentNode){\n      return card._lullaMorphPlaceholder;\n    }\n    var rect = card.getBoundingClientRect();\n    var placeholder = document.createElement(\"div\");\n    placeholder.className = \"lulla-size-card-placeholder\";\n    placeholder.setAttribute(\"aria-hidden\",\"true\");\n    placeholder.style.height = rect.height + \"px\";\n    placeholder.style.minHeight = rect.height + \"px\";\n    placeholder.style.width = rect.width + \"px\";\n    placeholder.style.minWidth = rect.width + \"px\";\n    placeholder.__lullaMorphCard = card;\n    card.parentNode.insertBefore(placeholder, card);\n    card._lullaMorphPlaceholder = placeholder;\n    return placeholder;\n  }\n\n  function removeMorphPlaceholder(card){\n    if(!card){\n      return;\n    }\n    var placeholder =\n      card._lullaMorphPlaceholder;\n    if(placeholder && placeholder.parentNode){\n      placeholder.parentNode.removeChild(placeholder);\n    }\n    card._lullaMorphPlaceholder = null;\n  }\n\n  function setMorphGeometry(card, rect){\n    if(!card || !rect){\n      return;\n    }\n\n    \/*\n     * Mobile morph geometry is viewport-based, not list-based.\n     * This is important for cards 4\u20135 when the size list has been\n     * scrolled: their real on-screen start position must be preserved\n     * exactly, while the reserved placeholder remains in the list.\n     *\/\n    card.style.setProperty(\"position\", \"fixed\", \"important\");\n    card.style.setProperty(\"left\", rect.left + \"px\", \"important\");\n    card.style.setProperty(\"top\", rect.top + \"px\", \"important\");\n    card.style.setProperty(\"width\", rect.width + \"px\", \"important\");\n    card.style.setProperty(\"height\", rect.height + \"px\", \"important\");\n    card.style.setProperty(\"min-height\", rect.height + \"px\", \"important\");\n    card.style.setProperty(\"right\", \"auto\", \"important\");\n    card.style.setProperty(\"bottom\", \"auto\", \"important\");\n  }\n\n  function setMorphEndGeometry(card){\n    if(!card){\n      return;\n    }\n\n    var rootRect =\n      root.getBoundingClientRect();\n\n    \/* Expand to the complete State 3 viewport. *\/\n    card.style.setProperty(\"position\", \"fixed\", \"important\");\n    card.style.setProperty(\"left\", rootRect.left + \"px\", \"important\");\n    card.style.setProperty(\"top\", rootRect.top + \"px\", \"important\");\n    card.style.setProperty(\"width\", rootRect.width + \"px\", \"important\");\n    card.style.setProperty(\"height\", rootRect.height + \"px\", \"important\");\n    card.style.setProperty(\"min-height\", rootRect.height + \"px\", \"important\");\n    card.style.setProperty(\"right\", \"auto\", \"important\");\n    card.style.setProperty(\"bottom\", \"auto\", \"important\");\n  }\n\n  function clearMorphGeometry(card){\n    if(!card){\n      return;\n    }\n    [\n      \"position\",\n      \"left\",\n      \"top\",\n      \"width\",\n      \"height\",\n      \"min-height\",\n      \"right\",\n      \"bottom\",\n      \"transition\",\n      \"will-change\"\n    ].forEach(function(property){\n      card.style.removeProperty(property);\n    });\n  }\n\n  function observeMorphPlaceholders(){\n    if(!list || list.__lullaMorphObserver){\n      return;\n    }\n    if(typeof MutationObserver === \"undefined\"){\n      return;\n    }\n    var observer =\n      new MutationObserver(function(){\n        list\n          .querySelectorAll(\".lulla-size-card-placeholder\")\n          .forEach(function(placeholder){\n            var morphCard =\n              placeholder.__lullaMorphCard;\n            if(!morphCard || !morphCard.isConnected){\n              placeholder.remove();\n            }\n          });\n      });\n    observer.observe(\n      list,\n      {\n        childList:true\n      }\n    );\n    list.__lullaMorphObserver = observer;\n  }\n\n  observeMorphPlaceholders();\n\n  function openCard(\n    category,\n    renderGallery\n  ){\n    var card =\n      cardMap[\n        category\n      ];\n    if(\n      !card ||\n      outfitAdded\n    ){\n      return;\n    }\n    if(\n      activeCategory ===\n      category\n    ){\n      return;\n    }\n    if(\n      closingTimers[\n        category\n      ]\n    ){\n      window.clearTimeout(\n        closingTimers[\n          category\n        ]\n      );\n      delete closingTimers[\n        category\n      ];\n    }\n\n    \/*\n     * IMPORTANT MOBILE MORPH FIX:\n     * If another card was previously opened, it may still carry\n     * is-morph-card + fixed viewport geometry. That old fixed card\n     * must be fully returned to the normal list before a new card\n     * starts opening. Otherwise every new open can leave another\n     * invisible\/stacked fixed card behind the next one.\n     *\/\n    Object.keys(cardMap).forEach(function(otherCategory){\n      if(otherCategory === category){\n        return;\n      }\n\n      if(closingTimers[otherCategory]){\n        window.clearTimeout(closingTimers[otherCategory]);\n        delete closingTimers[otherCategory];\n      }\n\n      var oldCard = cardMap[otherCategory];\n      if(!oldCard){\n        return;\n      }\n\n      if(oldCard.classList.contains(\"is-morph-card\")){\n        removeMorphPlaceholder(oldCard);\n        clearMorphGeometry(oldCard);\n        oldCard.classList.remove(\n          \"is-morph-card\",\n          \"is-closing-settle\"\n        );\n      }\n\n      \/*\n       * A previously opened card can keep its inline z-index even\n       * after its morph class was removed. That stale z-index is what\n       * causes cards 2\/3\/4\/etc. to sit above a card when it is opened\n       * for the second time. Every non-active card must return to the\n       * normal stacking order before a new morph starts.\n       *\/\n      oldCard.style.removeProperty(\"z-index\");\n    });\n\n    Object.keys(\n      cardMap\n    ).forEach(\n      function(otherCategory){\n        if(\n          otherCategory ===\n          category\n        ){\n          return;\n        }\n        var otherCard =\n          cardMap[\n            otherCategory\n          ];\n        if(!otherCard){\n          return;\n        }\n        otherCard.classList.remove(\n          \"is-active\",\n          \"is-closing\",\n          \"is-next-arriving\"\n        );\n        setToggleIcon(\n          otherCard.querySelector(\n            \".lulla-size-card-toggle\"\n          ),\n          toggleStateFor(\n            otherCategory\n          )\n        );\n        setStatusHidden(\n          otherCard.querySelector(\n            \".lulla-size-card-status\"\n          ),\n          false\n        );\n      }\n    );\n    root.classList.remove(\n      \"is-list-revealing\"\n    );\n\n    var phone =\n      isPhoneView();\n\n    if(phone && root.classList.contains(\"is-mobile-footer-visible\")){\n      animateMobileFooterOut();\n    }\n\n    var startRect =\n      card.getBoundingClientRect();\n\n    if(phone){\n      ensureMorphPlaceholder(card);\n      \/*\n       * Keep the real Choose Your Sizes header slot in the layout.\n       * The morph card will cover it visually because the morph is\n       * fixed and sits above the builder\/header layers.\n       *\/\n      lockMobileHeaderSlot();\n    }\n\n    activeCategory =\n      category;\n    root.classList.add(\n      \"is-card-open\",\n      \"is-cart-locked\"\n    );\n    if(phone){\n      root.classList.add(\n        \"is-mobile-card-open\",\n        \"is-list-locked\"\n      );\n    }\n    var openingStatus =\n      card.querySelector(\n        \".lulla-size-card-status\"\n      );\n    if(openingStatus){\n      openingStatus.classList.remove(\"is-status-hidden\");\n      openingStatus.style.opacity = \"1\";\n      openingStatus.style.pointerEvents = \"none\";\n    }\n    card.classList.remove(\n      \"is-closing\",\n      \"is-next-arriving\"\n    );\n    card.classList.add(\n      \"is-active\"\n    );\n    if(phone){\n      card.classList.add(\n        \"is-morph-card\"\n      );\n      card.style.setProperty(\n        \"z-index\",\n        \"1000\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"transition\",\n        \"top 520ms cubic-bezier(.22,.80,.36,1),left 520ms cubic-bezier(.22,.80,.36,1),width 520ms cubic-bezier(.22,.80,.36,1),height 520ms cubic-bezier(.22,.80,.36,1),min-height 520ms cubic-bezier(.22,.80,.36,1)\",\n        \"important\"\n      );\n      setMorphGeometry(\n        card,\n        startRect\n      );\n    }\n    setToggleIcon(\n      card.querySelector(\n        \".lulla-size-card-toggle\"\n      ),\n      \"close\"\n    );\n    setActiveTab(\n      card,\n      \"size\"\n    );\n    syncCardSizeOptions(\n      card,\n      category\n    );\n    updateCardStatus(\n      card,\n      category\n    );\n    updateConfirmButton(\n      card,\n      category\n    );\n    if(\n      renderGallery !==\n      false\n    ){\n      var entry =\n        activeProducts[\n          category\n        ];\n      if(\n        entry &&\n        entry.product &&\n        window.LullaRenderItemInfo\n      ){\n        var productForGallery =\n          entry.product;\n        window.requestAnimationFrame(\n          function(){\n            window.requestAnimationFrame(\n              function(){\n                if(\n                  outfitAdded ||\n                  activeCategory !== category\n                ){\n                  return;\n                }\n                window.LullaRenderItemInfo(\n                  productForGallery\n                );\n              }\n            );\n          }\n        );\n      }\n    }\n    updateAllCards();\n    updateMobileScrollState();\n    updateFooter();\n\n    if(openingStatus){\n      openingStatus.style.transition = \"opacity .20s ease\";\n      window.requestAnimationFrame(function(){\n        openingStatus.style.opacity = \"0\";\n      });\n    }\n\n    if(phone){\n      requestAnimationFrame(function(){\n        requestAnimationFrame(function(){\n          if(\n            activeCategory !== category ||\n            !card.classList.contains(\"is-morph-card\")\n          ){\n            return;\n          }\n          setMorphEndGeometry(card);\n        });\n      });\n    }\n  }\n  \/* =========================================================\n     STATE 3 MARKER CLICK\n  ========================================================= *\/\n  document.addEventListener(\n    \"lulla:state3-open-item\",\n    function(event){\n      if(\n        !event ||\n        !event.detail\n      ){\n        return;\n      }\n      var category =\n        event.detail.category;\n      if(\n        !category\n      ){\n        return;\n      }\n      if(\n        !cardMap[\n          category\n        ]\n      ){\n        return;\n      }\n      openCard(\n        category,\n        true\n      );\n    }\n  );\n  \/* =========================================================\n     CLOSE CARD\n     MOBILE = RETURN DIRECTLY INTO RESERVED SLOT\n  ========================================================= *\/\n  function closeCard(\n    category,\n    afterClose\n  ){\n    var card =\n      cardMap[\n        category\n      ];\n    if(!card){\n      if(\n        typeof afterClose ===\n        \"function\"\n      ){\n        afterClose();\n      }\n      return;\n    }\n    var wasActive =\n      activeCategory ===\n      category;\n    if(!wasActive){\n      if(\n        typeof afterClose ===\n        \"function\"\n      ){\n        afterClose();\n      }\n      return;\n    }\n\n    var confirmedBeforeClose =\n      confirmedSizes[\n        category\n      ];\n    var selectedBeforeClose =\n      selectedSizes[\n        category\n      ];\n    var hasUnconfirmedSizeChange =\n      !!selectedBeforeClose &&\n      !!confirmedBeforeClose &&\n      Number(\n        selectedBeforeClose.variationId\n      ) !==\n      Number(\n        confirmedBeforeClose.variationId\n      );\n\n    if(hasUnconfirmedSizeChange){\n      delete confirmedSizes[\n        category\n      ];\n    }\n\n    delete selectedSizes[\n      category\n    ];\n\n    if(hasUnconfirmedSizeChange){\n      notifyState3SizeState();\n    }\n\n    if(\n      isPhoneView()\n    ){\n      var closingStatus =\n        card.querySelector(\n          \".lulla-size-card-status\"\n        );\n      if(closingStatus){\n        setStatusHidden(\n          closingStatus,\n          true\n        );\n      }\n\n      var placeholder =\n        ensureMorphPlaceholder(card);\n\n      card.style.setProperty(\n        \"transition\",\n        \"top 480ms cubic-bezier(.22,.80,.36,1),left 480ms cubic-bezier(.22,.80,.36,1),width 480ms cubic-bezier(.22,.80,.36,1),height 480ms cubic-bezier(.22,.80,.36,1),min-height 480ms cubic-bezier(.22,.80,.36,1)\",\n        \"important\"\n      );\n\n      if(window.LullaClearItemInfo){\n        window.LullaClearItemInfo();\n      }\n\n      card.classList.add(\n        \"is-closing\",\n        \"is-morph-card\"\n      );\n      card.classList.remove(\n        \"is-active\",\n        \"is-next-arriving\"\n      );\n\n      setToggleIcon(\n        card.querySelector(\n          \".lulla-size-card-toggle\"\n        ),\n        toggleStateFor(\n          category\n        )\n      );\n\n      lockMobileHeaderSlot();\n\n      root.classList.add(\n        \"is-card-open\",\n        \"is-mobile-card-open\",\n        \"is-list-locked\",\n        \"is-cart-locked\",\n        \"is-mobile-card-closing\"\n      );\n\n      activeCategory =\n        category;\n\n      if(allSizesConfirmed() && !outfitAdded){\n        animateMobileFooterIn();\n      }\n\n      if(\n        closingTimers[\n          category\n        ]\n      ){\n        window.clearTimeout(\n          closingTimers[\n            category\n          ]\n        );\n      }\n\n      if(!placeholder || !placeholder.parentNode){\n        removeMorphPlaceholder(card);\n        clearMorphGeometry(card);\n        card.classList.remove(\n          \"is-closing\",\n          \"is-morph-card\"\n        );\n        root.classList.remove(\n          \"is-mobile-card-open\",\n          \"is-list-locked\",\n          \"is-mobile-card-closing\",\n          \"is-card-open\",\n          \"is-cart-locked\"\n        );\n        unlockMobileHeaderSlot();\n        activeCategory = null;\n        card.style.removeProperty(\"z-index\");\n        updateAllCards();\n        updateMobileScrollState();\n        updateFooter();\n        if(typeof afterClose === \"function\"){\n          afterClose();\n        }\n        return;\n      }\n\n      \/* Paint the compact card state first, then move it directly into\n         its reserved slot. There is no intermediate top-of-screen state. *\/\n      void card.offsetWidth;\n\n      var targetRect =\n        placeholder.getBoundingClientRect();\n\n      \/*\n       * Return directly to the placeholder's actual viewport position.\n       * This keeps cards 4\u20135 from teleporting when the list was scrolled.\n       *\/\n      card.style.setProperty(\n        \"position\",\n        \"fixed\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"left\",\n        targetRect.left + \"px\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"top\",\n        targetRect.top + \"px\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"width\",\n        targetRect.width + \"px\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"height\",\n        targetRect.height + \"px\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"min-height\",\n        targetRect.height + \"px\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"right\",\n        \"auto\",\n        \"important\"\n      );\n      card.style.setProperty(\n        \"bottom\",\n        \"auto\",\n        \"important\"\n      );\n\n      closingTimers[\n        category\n      ] =\n        window.setTimeout(\n          function(){\n            removeMorphPlaceholder(card);\n\n            card.classList.remove(\n              \"is-closing\",\n              \"is-morph-card\"\n            );\n\n            root.classList.remove(\n              \"is-mobile-card-open\",\n              \"is-list-locked\",\n              \"is-mobile-card-closing\",\n              \"is-card-open\"\n            );\n\n            activeCategory =\n              null;\n\n            card.style.removeProperty(\"z-index\");\n            clearMorphGeometry(card);\n            unlockMobileHeaderSlot();\n\n            updateAllCards();\n            updateMobileScrollState();\n            updateFooter();\n\n            if(closingStatus){\n              if(confirmedSizes[category]){\n                fadeStatusInAfterClose(\n                  closingStatus\n                );\n              }else{\n                setStatusHidden(\n                  closingStatus,\n                  false\n                );\n              }\n            }\n\n            root.classList.remove(\n              \"is-list-revealing\"\n            );\n            root.classList.remove(\n              \"is-cart-locked\"\n            );\n\n            delete closingTimers[\n              category\n            ];\n\n            if(\n              typeof afterClose ===\n              \"function\"\n            ){\n              afterClose();\n            }\n          },\n          520\n        );\n    \n      return;\n    }\n\n    var desktopStatus =\n      card.querySelector(\n        \".lulla-size-card-status\"\n      );\n    if(desktopStatus){\n      setStatusHidden(\n        desktopStatus,\n        true\n      );\n    }\n    card.classList.remove(\n      \"is-active\"\n    );\n    setToggleIcon(\n      card.querySelector(\n        \".lulla-size-card-toggle\"\n      ),\n      toggleStateFor(\n        category\n      )\n    );\n    activeCategory =\n      null;\n    root.classList.remove(\n      \"is-card-open\",\n      \"is-mobile-card-open\",\n      \"is-list-locked\",\n      \"is-cart-locked\"\n    );\n    if(\n      window.LullaClearItemInfo\n    ){\n      window.LullaClearItemInfo();\n    }\n    updateAllCards();\n    updateMobileScrollState();\n    updateFooter();\n    requestAnimationFrame(\n      function(){\n        if(desktopStatus){\n          setStatusHidden(\n            desktopStatus,\n            false\n          );\n        }\n        if(\n          typeof afterClose ===\n          \"function\"\n        ){\n          afterClose();\n        }\n      }\n    );\n  }\n  \/* =========================================================\n     MOBILE\n  ========================================================= *\/\n  function updateMobileScrollState(){\n    if(\n      isPhoneView() &&\n      activeCategory\n    ){\n      root.classList.add(\n        \"is-mobile-card-open\",\n        \"is-list-locked\"\n      );\n      return;\n    }\n    if(\n      !Object.keys(\n        closingTimers\n      ).length &&\n      !root.classList.contains(\n        \"is-card-open\"\n      )\n    ){\n      root.classList.remove(\n        \"is-mobile-card-open\",\n        \"is-list-locked\"\n      );\n    }\n  }\n  \/* =========================================================\n     SIZE\n  ========================================================= *\/\n  function selectSize(\n    category,\n    variationId,\n    sizeLabel\n  ){\n    if(\n      outfitAdded ||\n      !variationId\n    ){\n      return;\n    }\n    selectedSizes[\n      category\n    ] = {\n      variationId:\n        variationId,\n      sizeLabel:\n        sizeLabel\n    };\n    var card =\n      cardMap[\n        category\n      ];\n    if(!card){\n      return;\n    }\n    syncCardSizeOptions(\n      card,\n      category\n    );\n    updateConfirmButton(\n      card,\n      category\n    );\n    updateFooter();\n  }\n  function setSelectedSizeOption(\n    button,\n    options\n  ){\n    if(!button || !options){\n      return;\n    }\n    Array.prototype.forEach.call(\n      options.querySelectorAll(\n        \".lulla-size-option.is-selected\"\n      ),\n      function(other){\n        if(other !== button){\n          other.classList.remove(\"is-selected\");\n        }\n      }\n    );\n    button.classList.add(\"is-selected\");\n  }\n  function transitionToStudioAfterEmpty(){\n    if(emptyCloseInProgress){\n      return;\n    }\n    emptyCloseInProgress = true;\n    root.classList.remove(\n      \"is-card-open\",\n      \"is-mobile-card-open\",\n      \"is-list-locked\",\n      \"is-mobile-footer-visible\",\n      \"is-list-revealing\"\n    );\n    root.classList.add(\"is-empty-closing\");\n    root.setAttribute(\"aria-hidden\",\"true\");\n    root.style.pointerEvents = \"none\";\n    if(footer){\n      footer.style.pointerEvents = \"none\";\n    }\n    if(cartButton){\n      cartButton.style.pointerEvents = \"none\";\n    }\n    if(window.LullaClearItemInfo){\n      window.LullaClearItemInfo();\n    }\n    notifyState3SizeState();\n    updateFooter();\n    requestAnimationFrame(function(){\n      requestAnimationFrame(function(){\n        root.classList.add(\"is-empty-closing-active\");\n      });\n    });\n    window.setTimeout(function(){\n      root.classList.remove(\"is-empty-closing\",\"is-empty-closing-active\");\n      document.dispatchEvent(new CustomEvent(\"lulla:size-screen-close\",{\n        bubbles:true,\n        detail:{reason:\"all-items-removed\"}\n      }));\n      emptyCloseInProgress = false;\n    }, 360);\n  }\n  function updateConfirmButton(\n    card,\n    category\n  ){\n    var button =\n      card.querySelector(\n        \".lulla-size-confirm-button\"\n      );\n    if(!button){\n      return;\n    }\n    var enabled =\n      !!selectedSizes[\n        category\n      ];\n    button.disabled =\n      !enabled;\n    button.classList.toggle(\n      \"is-enabled\",\n      enabled\n    );\n    button.textContent =\n      \"CONFIRM SIZE\";\n  }\n  function getNextUnconfirmed(\n    category\n  ){\n    var currentIndex =\n      itemOrder.indexOf(\n        category\n      );\n    if(\n      currentIndex ===\n      -1\n    ){\n      return null;\n    }\n    for(\n      var i =\n        currentIndex + 1;\n      i <\n      itemOrder.length;\n      i++\n    ){\n      var next =\n        itemOrder[\n          i\n        ];\n      if(\n        activeProducts[\n          next\n        ] &&\n        !confirmedSizes[\n          next\n        ]\n      ){\n        return next;\n      }\n    }\n    for(\n      var j =\n        0;\n      j <\n      currentIndex;\n      j++\n    ){\n      var wrapped =\n        itemOrder[\n          j\n        ];\n      if(\n        activeProducts[\n          wrapped\n        ] &&\n        !confirmedSizes[\n          wrapped\n        ]\n      ){\n        return wrapped;\n      }\n    }\n    return null;\n  }\n  \/* =========================================================\n     CONFIRM\n  ========================================================= *\/\n  function confirmCurrentCard(\n    category\n  ){\n    var selected =\n      selectedSizes[\n        category\n      ];\n    if(!selected){\n      return;\n    }\n    var currentCard =\n      cardMap[\n        category\n      ];\n    if(!currentCard){\n      return;\n    }\n    confirmedSizes[\n      category\n    ] = {\n      variationId:\n        selected.variationId,\n      sizeLabel:\n        selected.sizeLabel\n    };\n    updateCardStatus(\n      currentCard,\n      category\n    );\n    notifyState3SizeState();\n    updateFooter();\n    closeCard(\n      category\n    );\n  }\n  \/* =========================================================\n     BUILD CARD\n  ========================================================= *\/\n  function buildCard(\n    category\n  ){\n    var entry =\n      activeProducts[\n        category\n      ];\n    if(\n      !entry ||\n      !entry.product\n    ){\n      return null;\n    }\n    var product =\n      entry.product;\n    var card =\n      document.createElement(\n        \"article\"\n      );\n    card.className =\n      \"lulla-size-card\";\n    card.dataset.category =\n      category;\n    \/*\n     * Stamp the identity of the product this card was built\n     * from. renderProducts() compares this against the incoming\n     * activeProducts entry on every render so a same-category\n     * product swap (Top A -> Top B) is detected even though the\n     * category key itself never disappears.\n     *\/\n    card.dataset.lullaProductIdentity =\n      getProductIdentity(\n        product\n      );\n    var mainRow =\n      document.createElement(\n        \"div\"\n      );\n    mainRow.className =\n      \"lulla-size-card-main-row\";\n    var image =\n      document.createElement(\n        \"img\"\n      );\n    image.className =\n      \"lulla-size-card-thumb\";\n    image.src =\n      product.image ||\n      \"\";\n    image.alt =\n      \"\";\n    var info =\n      document.createElement(\n        \"div\"\n      );\n    info.className =\n      \"lulla-size-card-info\";\n    var title =\n      document.createElement(\n        \"div\"\n      );\n    title.className =\n      \"lulla-size-card-title\";\n    setRichText(\n      title,\n      product.title ||\n      product.name ||\n      \"\"\n    );\n    var price =\n      document.createElement(\n        \"div\"\n      );\n    price.className =\n      \"lulla-size-card-price\";\n    price.textContent =\n      formatPrice(\n        product.price\n      );\n    var remove =\n      document.createElement(\n        \"button\"\n      );\n    remove.type =\n      \"button\";\n    remove.className =\n      \"lulla-size-card-remove\";\n    remove.innerHTML =\n      '<svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">' +\n      '<path d=\"M4 6h12M8 6V4.7c0-.65.5-1.2 1.15-1.2h1.7c.65 0 1.15.55 1.15 1.2V6M6 6l.7 9c.05.7.6 1.3 1.3 1.3h4c.7 0 1.25-.6 1.3-1.3L14 6\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>' +\n      '<span>REMOVE ITEM<\/span>';\n    info.appendChild(\n      title\n    );\n    info.appendChild(\n      price\n    );\n    info.appendChild(\n      remove\n    );\n    var status =\n      document.createElement(\n        \"div\"\n      );\n    status.className =\n      \"lulla-size-card-status\";\n    var toggle =\n      document.createElement(\n        \"button\"\n      );\n    toggle.type =\n      \"button\";\n    toggle.className =\n      \"lulla-size-card-toggle\";\n    setToggleIcon(\n      toggle,\n      \"add\"\n    );\n    mainRow.appendChild(\n      image\n    );\n    mainRow.appendChild(\n      info\n    );\n    mainRow.appendChild(\n      status\n    );\n    mainRow.appendChild(\n      toggle\n    );\n    card.appendChild(\n      mainRow\n    );\n    var body =\n      document.createElement(\n        \"div\"\n      );\n    body.className =\n      \"lulla-size-card-body\";\n    var bodyInner =\n      document.createElement(\n        \"div\"\n      );\n    bodyInner.className =\n      \"lulla-size-card-body-inner\";\n    var tabs =\n      document.createElement(\n        \"div\"\n      );\n    tabs.className =\n      \"lulla-size-card-tabs\";\n    [\n      [\n        \"size\",\n        \"CHOOSE SIZE\"\n      ],\n      [\n        \"description\",\n        \"DESCRIPTION\"\n      ],\n      [\n        \"care\",\n        \"CARE\"\n      ]\n    ]\n    .forEach(\n      function(def){\n        var button =\n          document.createElement(\n            \"button\"\n          );\n        button.type =\n          \"button\";\n        button.className =\n          \"lulla-size-card-tab\";\n        button.dataset.tab =\n          def[0];\n        button.textContent =\n          def[1];\n        if(\n          def[0] ===\n          \"size\"\n        ){\n          button.classList.add(\n            \"is-active\"\n          );\n        }\n        button.addEventListener(\n          \"click\",\n          function(event){\n            event.preventDefault();\n            event.stopPropagation();\n            setActiveTab(\n              card,\n              def[0]\n            );\n          }\n        );\n        tabs.appendChild(\n          button\n        );\n      }\n    );\n    bodyInner.appendChild(\n      tabs\n    );\n    var sizePanel =\n      document.createElement(\n        \"div\"\n      );\n    sizePanel.className =\n      \"lulla-size-card-tab-panel is-active\";\n    sizePanel.dataset.tabPanel =\n      \"size\";\n    var options =\n      document.createElement(\n        \"div\"\n      );\n    options.className =\n      \"lulla-size-options\";\n    var sizes =\n      Array.isArray(\n        product.sizes\n      )\n        ? product.sizes\n        : [];\n    sizes.forEach(\n      function(size){\n        var button =\n          document.createElement(\n            \"button\"\n          );\n        button.type =\n          \"button\";\n        button.className =\n          \"lulla-size-option\";\n        button.textContent =\n          size.label ||\n          size.value ||\n          \"\";\n        button.dataset.variationId =\n          size.variationId ||\n          \"\";\n        if(\n          !size.purchasable ||\n          !size.isInStock\n        ){\n          button.disabled =\n            true;\n        }\n        button.addEventListener(\n          \"click\",\n          function(event){\n            event.preventDefault();\n            event.stopPropagation();\n            if(\n              button.disabled ||\n              outfitAdded\n            ){\n              return;\n            }\n            setSelectedSizeOption(\n              button,\n              options\n            );\n            selectSize(\n              category,\n              Number(\n                button.dataset.variationId\n              ),\n              button.textContent\n            );\n          }\n        );\n        options.appendChild(\n          button\n        );\n      }\n    );\n    sizePanel.appendChild(\n      options\n    );\n    var actionRow =\n      document.createElement(\n        \"div\"\n      );\n    actionRow.className =\n      \"lulla-size-action-row\";\n    var sizeGuide =\n      document.createElement(\n        \"button\"\n      );\n    sizeGuide.type =\n      \"button\";\n    sizeGuide.className =\n      \"lulla-size-card-size-guide\";\n    sizeGuide.innerHTML =\n      '<img decoding=\"async\" class=\"lulla-size-guide-icon\" src=\"' +\n      SIZE_GUIDE_ICON_URL +\n      '\" alt=\"\" aria-hidden=\"true\">' +\n      '<span>SIZE GUIDE<\/span>';\n    sizeGuide.addEventListener(\n      \"click\",\n      function(event){\n        event.preventDefault();\n        event.stopPropagation();\n        if(\n          product.sizeGuideImage &&\n          window.LullaOpenSizeGuide\n        ){\n          window.LullaOpenSizeGuide(\n            product.sizeGuideImage\n          );\n        }\n      }\n    );\n    var confirm =\n      document.createElement(\n        \"button\"\n      );\n    confirm.type =\n      \"button\";\n    confirm.className =\n      \"lulla-size-confirm-button\";\n    confirm.disabled =\n      true;\n    confirm.textContent =\n      \"CONFIRM SIZE\";\n    confirm.addEventListener(\n      \"click\",\n      function(event){\n        event.preventDefault();\n        event.stopPropagation();\n        if(\n          confirm.disabled\n        ){\n          return;\n        }\n        confirmCurrentCard(\n          category\n        );\n      }\n    );\n    actionRow.appendChild(\n      sizeGuide\n    );\n    actionRow.appendChild(\n      confirm\n    );\n    sizePanel.appendChild(\n      actionRow\n    );\n    bodyInner.appendChild(\n      sizePanel\n    );\n    var descriptionPanel =\n      document.createElement(\n        \"div\"\n      );\n    descriptionPanel.className =\n      \"lulla-size-card-tab-panel\";\n    descriptionPanel.dataset.tabPanel =\n      \"description\";\n    var descriptionViewport =\n      document.createElement(\n        \"div\"\n      );\n    descriptionViewport.className =\n      \"lulla-size-card-text-viewport\";\n    var descriptionText =\n      document.createElement(\n        \"div\"\n      );\n    descriptionText.className =\n      \"lulla-size-card-text is-loading\";\n    descriptionText.textContent =\n      \"Loading product details\u2026\";\n    descriptionViewport.appendChild(\n      descriptionText\n    );\n    descriptionPanel.appendChild(\n      descriptionViewport\n    );\n    bodyInner.appendChild(\n      descriptionPanel\n    );\n    var carePanel =\n      document.createElement(\n        \"div\"\n      );\n    carePanel.className =\n      \"lulla-size-card-tab-panel\";\n    carePanel.dataset.tabPanel =\n      \"care\";\n    var careViewport =\n      document.createElement(\n        \"div\"\n      );\n    careViewport.className =\n      \"lulla-size-card-text-viewport\";\n    var careText =\n      document.createElement(\n        \"div\"\n      );\n    careText.className =\n      \"lulla-size-card-text is-loading\";\n    careText.textContent =\n      \"Loading care information\u2026\";\n    careViewport.appendChild(\n      careText\n    );\n    carePanel.appendChild(\n      careViewport\n    );\n    bodyInner.appendChild(\n      carePanel\n    );\n    body.appendChild(\n      bodyInner\n    );\n    card.appendChild(\n      body\n    );\n    toggle.addEventListener(\n      \"click\",\n      function(event){\n        event.preventDefault();\n        event.stopPropagation();\n        if(\n          activeCategory ===\n          category\n        ){\n          closeCard(\n            category\n          );\n        }else{\n          openCard(\n            category\n          );\n        }\n      }\n    );\n    mainRow.addEventListener(\n      \"click\",\n      function(event){\n        if(\n          event.target.closest &&\n          (\n            event.target.closest(\n              \".lulla-size-card-remove\"\n            ) ||\n            event.target.closest(\n              \".lulla-size-card-toggle\"\n            )\n          )\n        ){\n          return;\n        }\n        if(\n          activeCategory !==\n          category\n        ){\n          openCard(\n            category\n          );\n        }\n      }\n    );\n    remove.addEventListener(\n      \"click\",\n      function(event){\n        event.preventDefault();\n        event.stopPropagation();\n        if(\n          !productsRoot\n        ){\n          return;\n        }\n        var selectedCard =\n          productsRoot.querySelector(\n            '.builder-product-card.is-selected[data-category=\"' +\n            category +\n            '\"]'\n          );\n        if(selectedCard){\n          selectedCard.click();\n        }\n      }\n    );\n    fetchItemDetails(\n      product.productId ||\n      product.id\n    )\n    .then(\n      function(details){\n        var description =\n          details.short_description ||\n          \"\";\n        setRichText(\n          descriptionText,\n          description ||\n          \"Product details unavailable.\"\n        );\n        descriptionText.classList.remove(\n          \"is-loading\"\n        );\n        var care =\n          details.description ||\n          \"\";\n        setRichText(\n          careText,\n          care ||\n          \"Care information unavailable.\"\n        );\n        careText.classList.remove(\n          \"is-loading\"\n        );\n      }\n    );\n    return card;\n  }\n  \/* =========================================================\n     UPDATE CARDS\n  ========================================================= *\/\n  function updateAllCards(){\n    itemOrder.forEach(\n      function(category){\n        var card =\n          cardMap[\n            category\n          ];\n        if(!card){\n          return;\n        }\n        updateCardStatus(\n          card,\n          category\n        );\n        updateConfirmButton(\n          card,\n          category\n        );\n        syncCardSizeOptions(\n          card,\n          category\n        );\n        setToggleIcon(\n          card.querySelector(\n            \".lulla-size-card-toggle\"\n          ),\n          toggleStateFor(\n            category\n          )\n        );\n      }\n    );\n  }\n  \/* =========================================================\n     RENDER PRODUCTS\n  ========================================================= *\/\n  function renderProducts(\n    products\n  ){\n    if(\n      outfitAdded\n    ){\n      return;\n    }\n    var version =\n      ++renderVersion;\n    var hadItemsBeforeRender =\n      itemOrder.length > 0 ||\n      Object.keys(cardMap).length > 0;\n    activeProducts =\n      products ||\n      {};\n    var categories =\n      Object.keys(\n        activeProducts\n      )\n      .filter(\n        function(category){\n          return (\n            activeProducts[\n              category\n            ] &&\n            activeProducts[\n              category\n            ].product\n          );\n        }\n      );\n    var missingCategories =\n      Object.keys(cardMap).filter(function(category){\n        return categories.indexOf(category) === -1;\n      });\n    \/*\n     * A category that is still present but whose selected\n     * product changed identity (Top A -> Top B selected\n     * directly, without removing A first). The existing DOM\n     * card for that category was built from \u2014 and its handlers\n     * still close over \u2014 the OLD product, so it must be treated\n     * as a real replacement, not left in place. This is what\n     * fixes the same-category direct-replacement bug: without\n     * it, `cardMap[category]` already existing was enough for\n     * the rebuild step below to skip the category entirely.\n     *\/\n    var changedCategories =\n      Object.keys(cardMap).filter(function(category){\n        if(categories.indexOf(category) === -1){\n          \/* already covered by missingCategories *\/\n          return false;\n        }\n        var existingCard =\n          cardMap[category];\n        var entry =\n          activeProducts[category];\n        if(\n          !existingCard ||\n          !entry ||\n          !entry.product\n        ){\n          return false;\n        }\n        var existingIdentity =\n          (\n            existingCard.dataset &&\n            existingCard.dataset.lullaProductIdentity\n          ) ||\n          \"\";\n        return (\n          existingIdentity !==\n          getProductIdentity(entry.product)\n        );\n      });\n    \/*\n     * Categories whose DOM card must be torn down and rebuilt\n     * this render \u2014 either because the category disappeared\n     * entirely, or because it now points at a different product.\n     * Everything below that previously only handled\n     * `missingCategories` also handles same-category product\n     * swaps by operating on this combined list, reusing the\n     * exact same removal-animation \/ cleanup \/ rebuild pipeline\n     * for both cases.\n     *\/\n    var categoriesToRemove =\n      missingCategories.concat(changedCategories);\n    var phoneEmptyRemoval =\n      isPhoneView() &&\n      hadItemsBeforeRender &&\n      categoriesToRemove.length > 0 &&\n      categories.length === 0 &&\n      !outfitAdded;\n    \/*\n     * Capture the current geometry of cards that will remain.\n     * After the removed card leaves the flex flow, the remaining\n     * cards get a new position. We animate from the old position to\n     * the new one so the layout feels physical instead of teleporting.\n     *\/\n    var remainingCardRects = {};\n    if(\n      categoriesToRemove.length &&\n      categories.length\n    ){\n      categories.forEach(function(category){\n        var existingCard = cardMap[category];\n        if(existingCard){\n          remainingCardRects[category] =\n            existingCard.getBoundingClientRect();\n        }\n      });\n    }\n    if(\n      categoriesToRemove.length &&\n      activeCategory &&\n      categoriesToRemove.indexOf(activeCategory) !== -1\n    ){\n      activeCategory = null;\n      \/*\n       * Keep the mobile full-screen card state during the\n       * zoom-out\/fade-out. Removing these classes here would\n       * collapse the card before its removal animation starts.\n       *\/\n      root.classList.add(\"is-cart-locked\");\n      if(window.LullaClearItemInfo){\n        window.LullaClearItemInfo();\n      }\n    }\n    if(phoneEmptyRemoval){\n      root.classList.add(\"is-phone-empty-closing\");\n      root.style.pointerEvents = \"none\";\n      if(footer){\n        footer.style.pointerEvents = \"none\";\n      }\n      if(cartButton){\n        cartButton.style.pointerEvents = \"none\";\n      }\n    }\n    categoriesToRemove.forEach(function(category){\n      if(closingTimers[category]){\n        window.clearTimeout(closingTimers[category]);\n        delete closingTimers[category];\n      }\n      var card = cardMap[category];\n      if(card){\n        card.style.pointerEvents = \"none\";\n        if(!phoneEmptyRemoval){\n          card.classList.add(\"is-removing-item\");\n        }\n      }\n    });\n    function finalizeMissingCards(){\n      categoriesToRemove.forEach(function(category){\n        var card = cardMap[category];\n        if(card && card.parentNode){\n          card.parentNode.removeChild(card);\n        }\n        delete cardMap[category];\n        delete confirmedSizes[category];\n        delete selectedSizes[category];\n      });\n      itemOrder = itemOrder.filter(function(category){\n        return categories.indexOf(category) !== -1;\n      });\n\n      \/*\n       * FLIP the cards that remain: they already occupy their new flex\n       * positions after the removal above, so temporarily place them at\n       * their previous coordinates and let them glide into place.\n       *\/\n      var cardsToMove = [];\n      categories.forEach(function(category){\n        var previousRect = remainingCardRects[category];\n        var card = cardMap[category];\n        if(!previousRect || !card){\n          return;\n        }\n        var nextRect = card.getBoundingClientRect();\n        var deltaX = previousRect.left - nextRect.left;\n        var deltaY = previousRect.top - nextRect.top;\n        if(\n          Math.abs(deltaX) < 0.5 &&\n          Math.abs(deltaY) < 0.5\n        ){\n          return;\n        }\n        card.style.transition = \"none\";\n        card.style.transform =\n          \"translate3d(\" +\n          deltaX +\n          \"px,\" +\n          deltaY +\n          \"px,0)\";\n        card.style.willChange = \"transform\";\n        cardsToMove.push(card);\n      });\n\n      if(cardsToMove.length){\n        \/* Force the inverse transform to be painted before releasing it. *\/\n        void list.offsetHeight;\n        requestAnimationFrame(function(){\n          cardsToMove.forEach(function(card){\n            card.style.transition =\n              \"transform \" +\n              CARD_REMOVE_ANIMATION_MS +\n              \"ms cubic-bezier(.22,.80,.36,1)\";\n            card.style.transform = \"translate3d(0,0,0)\";\n          });\n          window.setTimeout(function(){\n            cardsToMove.forEach(function(card){\n              card.style.transition = \"\";\n              card.style.transform = \"\";\n              card.style.willChange = \"\";\n            });\n          }, CARD_REMOVE_ANIMATION_MS + 40);\n        });\n      }\n      if(\n        hadItemsBeforeRender &&\n        categories.length === 0 &&\n        !outfitAdded\n      ){\n        if(\n          visibilityState === \"visible\" ||\n          visibilityState === \"entering\"\n        ){\n          transitionToStudioAfterEmpty();\n        }else{\n          itemOrder = [];\n        }\n        notifyState3SizeState();\n        updateFooter();\n        return true;\n      }\n      root.classList.remove(\n        \"is-mobile-card-open\",\n        \"is-list-locked\",\n        \"is-card-open\",\n        \"is-cart-locked\"\n      );\n      return false;\n    }\n    if(categoriesToRemove.length){\n      window.setTimeout(function(){\n        if(version !== renderVersion){\n          return;\n        }\n        var empty = finalizeMissingCards();\n        if(empty){\n          return;\n        }\n        categories.forEach(function(category){\n          if(cardMap[category]){\n            return;\n          }\n          var card = buildCard(category);\n          if(!card){\n            return;\n          }\n          cardMap[category] = card;\n          insertCardInState3Order(card,category);\n        });\n        updateAllCards();\n        updateFooter();\n        updateMobileScrollState();\n        if(!activeCategory){\n          root.classList.remove(\n            \"is-card-open\",\n            \"is-mobile-card-open\",\n            \"is-list-locked\"\n          );\n        }\n        notifyState3SizeState();\n      }, CARD_REMOVE_ANIMATION_MS);\n      return;\n    }\n    itemOrder = itemOrder.filter(function(category){\n      return categories.indexOf(category) !== -1;\n    });\n    categories.forEach(\n      function(category){\n        if(\n          itemOrder.indexOf(\n            category\n          ) ===\n          -1\n        ){\n          itemOrder.push(\n            category\n          );\n        }\n      }\n    );\n    itemOrder =\n      itemOrder.filter(\n        function(category){\n          return (\n            categories.indexOf(\n              category\n            ) !==\n            -1\n          );\n        }\n      );\n    if(\n      hadItemsBeforeRender &&\n      categories.length === 0 &&\n      !outfitAdded\n    ){\n      if(\n        visibilityState === \"visible\" ||\n        visibilityState === \"entering\"\n      ){\n        transitionToStudioAfterEmpty();\n      }else{\n        itemOrder = [];\n      }\n      notifyState3SizeState();\n      updateFooter();\n      return;\n    }\n    categories.forEach(\n      function(category){\n        if(\n          cardMap[\n            category\n          ]\n        ){\n          return;\n        }\n        var card =\n          buildCard(\n            category\n          );\n        if(!card){\n          return;\n        }\n        cardMap[\n          category\n        ] =\n          card;\n        insertCardInState3Order(\n          card,\n          category\n        );\n      }\n    );\n    updateAllCards();\n    updateFooter();\n    updateMobileScrollState();\n    if(\n      !activeCategory\n    ){\n      root.classList.remove(\n        \"is-card-open\",\n        \"is-mobile-card-open\",\n        \"is-list-locked\"\n      );\n    }\n    if(\n      visibilityState ===\n      \"hidden\" ||\n      visibilityState ===\n      \"entering\"\n    ){\n      resetAllCardsToClosed({\n        clearGallery:true\n      });\n    }\n    notifyState3SizeState();\n    if(\n      version !==\n      renderVersion\n    ){\n      return;\n    }\n  }\n  \/* =========================================================\n     CHOOSE SIZE\n  ========================================================= *\/\n  document.addEventListener(\n    \"lulla:choose-size\",\n    function(){\n      outfitAdded =\n        false;\n      cartRequestInFlight =\n        false;\n      root.classList.remove(\n        \"is-success\",\n        \"is-list-revealing\"\n      );\n      successScreen.setAttribute(\n        \"aria-hidden\",\n        \"true\"\n      );\n      resetAllCardsToClosed({\n        clearGallery:true\n      });\n      showPanel();\n      if(\n        window.LullaShowItemInfoPanel\n      ){\n        window.LullaShowItemInfoPanel();\n      }\n      if(\n        !Object.keys(\n          cardMap\n        ).length\n      ){\n        itemOrder =\n          [];\n        confirmedSizes =\n          {};\n        selectedSizes =\n          {};\n        activeCategory =\n          null;\n      }\n      renderProducts(\n        activeProducts\n      );\n      resetAllCardsToClosed({\n        clearGallery:true\n      });\n      prewarmMobileVisuals();\n      notifyState3SizeState();\n      updateFooter();\n    }\n  );\n  \/* =========================================================\n     PRODUCT CHANGE\n  ========================================================= *\/\n  document.addEventListener(\n    \"lulla:product-change\",\n    function(event){\n      if(\n        !event ||\n        !event.detail\n      ){\n        return;\n      }\n      if(\n        outfitAdded\n      ){\n        return;\n      }\n      renderProducts(\n        event.detail.activeProducts ||\n        {}\n      );\n      prewarmMobileVisuals();\n      notifyState3SizeState();\n      if(\n        visibilityState !==\n        \"visible\"\n      ){\n        resetAllCardsToClosed({\n          clearGallery:true\n        });\n      }\n    }\n  );\n  \/* =========================================================\n     CLOSE STATE 3\n  ========================================================= *\/\n  document.addEventListener(\n    \"lulla:size-screen-close\",\n    function(event){\n      root.classList.remove(\"is-phone-empty-closing\",\"is-empty-closing\",\"is-empty-closing-active\");\n      root.style.pointerEvents = \"none\";\n      if(footer){\n        footer.style.pointerEvents = \"none\";\n      }\n      if(cartButton){\n        cartButton.style.pointerEvents = \"none\";\n      }\n      if(\n        event &&\n        event.detail &&\n        event.detail.reason === \"all-items-removed\"\n      ){\n        root.classList.remove(\n          \"is-empty-closing\",\n          \"is-empty-closing-active\"\n        );\n      }\n      resetAllCardsToClosed({\n        clearGallery:true\n      });\n      hidePanel();\n      if(\n        window.LullaHideItemInfoPanel\n      ){\n        window.LullaHideItemInfoPanel();\n      }\n    }\n  );\n  \/* =========================================================\n     CART\n  ========================================================= *\/\n  cartButton.addEventListener(\n    \"click\",\n    function(){\n      if(\n        root.style.pointerEvents === \"none\" ||\n        (!root.classList.contains(\"is-visible\") && !root.classList.contains(\"is-entering\")) ||\n        cartRequestInFlight ||\n        outfitAdded ||\n        activeCategory ||\n        root.classList.contains(\"is-card-open\") ||\n        root.classList.contains(\"is-mobile-card-open\") ||\n        root.classList.contains(\"is-cart-locked\") ||\n        root.classList.contains(\"is-list-revealing\") ||\n        !allSizesConfirmed()\n      ){\n        return;\n      }\n      var ajax =\n        window.LullaAjax;\n      if(\n        !ajax ||\n        !ajax.url\n      ){\n        console.error(\n          \"LullaAjax.url is missing.\"\n        );\n        return;\n      }\n      cartRequestInFlight =\n        true;\n      cartButton.disabled =\n        true;\n      cartButton.textContent =\n        \"ADDING\u2026\";\n      var items =\n        itemOrder\n          .map(\n            function(category){\n              var selected =\n                confirmedSizes[\n                  category\n                ];\n              if(!selected){\n                return null;\n              }\n              return {\n                variation_id:\n                  selected.variationId,\n                quantity:1\n              };\n            }\n          )\n          .filter(Boolean);\n      var payload =\n        new URLSearchParams();\n      payload.set(\n        \"nonce\",\n        ajax.nonce ||\n        \"\"\n      );\n      payload.set(\n        \"items\",\n        JSON.stringify(\n          items\n        )\n      );\n      fetch(\n        ajax.url,\n        {\n          method:\n            \"POST\",\n          credentials:\n            \"same-origin\",\n          headers:{\n            \"Content-Type\":\n              \"application\/x-www-form-urlencoded; charset=UTF-8\"\n          },\n          body:\n            payload.toString()\n        }\n      )\n      .then(\n        function(response){\n          if(!response.ok){\n            throw new Error(\n              \"Cart request failed.\"\n            );\n          }\n          return response.json();\n        }\n      )\n      .then(\n        function(result){\n          if(\n            !result ||\n            result.success === false\n          ){\n            throw new Error(\n              (\n                result &&\n                result.data &&\n                result.data.message\n              ) ||\n              \"Could not add outfit to cart.\"\n            );\n          }\n          outfitAdded =\n            true;\n          cartRequestInFlight =\n            false;\n          cartButton.textContent =\n            \"ADDED\";\n          var data =\n            result.data ||\n            result;\n          if(\n            window.jQuery &&\n            data.fragments\n          ){\n            window.jQuery.each(\n              data.fragments,\n              function(\n                selector,\n                markup\n              ){\n                window.jQuery(\n                  selector\n                ).replaceWith(\n                  markup\n                );\n              }\n            );\n            window.jQuery(\n              document.body\n            ).trigger(\n              \"added_to_cart\",\n              [\n                data.fragments ||\n                  {},\n                data.cart_hash ||\n                  \"\",\n                window.jQuery(\n                  cartButton\n                )\n              ]\n            );\n          }\n          removeGeneratedViewCart();\n          window.setTimeout(\n            removeGeneratedViewCart,\n            0\n          );\n          window.setTimeout(\n            removeGeneratedViewCart,\n            100\n          );\n          window.setTimeout(\n            removeGeneratedViewCart,\n            300\n          );\n          root.classList.add(\n            \"is-success\"\n          );\n          successScreen.setAttribute(\n            \"aria-hidden\",\n            \"false\"\n          );\n          document.dispatchEvent(\n            new CustomEvent(\n              \"lulla:outfit-added\",\n              {\n                bubbles:true\n              }\n            )\n          );\n          updateFooter();\n        }\n      )\n      .catch(\n        function(error){\n          console.error(\n            \"Lulla cart error:\",\n            error\n          );\n          cartRequestInFlight =\n            false;\n          cartButton.textContent =\n            \"ADD OUTFIT TO CART\";\n          updateFooter();\n          alert(\n            error.message ||\n            \"Something went wrong. Please try again.\"\n          );\n        }\n      );\n    }\n  );\n  \/* =========================================================\n     MAKE ANOTHER OUTFIT\n  ========================================================= *\/\n  if(\n    anotherButton\n  ){\n    anotherButton.addEventListener(\n      \"click\",\n      function(){\n        outfitAdded =\n          false;\n        document.dispatchEvent(\n          new CustomEvent(\n            \"lulla:outfit-reset\",\n            {\n              bubbles:true\n            }\n          )\n        );\n        cartRequestInFlight =\n          false;\n        itemOrder =\n          [];\n        confirmedSizes =\n          {};\n        selectedSizes =\n          {};\n        activeCategory =\n          null;\n        activeProducts =\n          {};\n        Object.keys(\n          closingTimers\n        )\n        .forEach(\n          function(category){\n            window.clearTimeout(\n              closingTimers[\n                category\n              ]\n            );\n          }\n        );\n        closingTimers =\n          {};\n        cardMap =\n          {};\n        list.innerHTML =\n          \"\";\n        root.classList.remove(\n          \"is-success\",\n          \"is-card-open\",\n          \"is-mobile-card-open\",\n          \"is-list-locked\",\n          \"is-mobile-footer-visible\",\n          \"is-list-revealing\"\n        );\n        successScreen.setAttribute(\n          \"aria-hidden\",\n          \"true\"\n        );\n        cartButton.textContent =\n          \"ADD OUTFIT TO CART\";\n        cartButton.disabled =\n          true;\n        removeGeneratedViewCart();\n        notifyState3SizeState();\n        if(\n          window.LullaClearItemInfo\n        ){\n          window.LullaClearItemInfo();\n        }\n        if(\n          productsRoot\n        ){\n          productsRoot\n            .querySelectorAll(\n              \".builder-product-card.is-selected\"\n            )\n            .forEach(\n              function(card){\n                card.click();\n              }\n            );\n        }\n        document.dispatchEvent(\n          new CustomEvent(\n            \"lulla:size-screen-close\",\n            {\n              bubbles:true\n            }\n          )\n        );\n      }\n    );\n  }\n  \/* =========================================================\n     HOME\n  ========================================================= *\/\n  if(\n    homeButton\n  ){\n    homeButton.addEventListener(\n      \"click\",\n      function(){\n        window.location.href =\n          \"\/\";\n      }\n    );\n  }\n  \/* =========================================================\n     RESIZE\n  ========================================================= *\/\n  window.addEventListener(\n    \"resize\",\n    function(){\n      updateFooter();\n      updateMobileScrollState();\n    }\n  );\n  \/* =========================================================\n     INITIAL STATE\n  ========================================================= *\/\n  resetAllCardsToClosed({\n    clearGallery:true\n  });\n  root.setAttribute(\n    \"aria-hidden\",\n    \"true\"\n  );\n  notifyState3SizeState();\n  updateFooter();\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c1359a5 elementor-widget elementor-widget-html\" data-id=\"c1359a5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\r\nhtml,\r\nbody{\r\n  overflow:hidden !important;\r\n  overscroll-behavior-y:none !important;\r\n}\r\n<\/style>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>BACK Build your look Start with one item. \u2193 Choose your sizes Find the right fit. \u2193 Add to bag Complete your outfit. TOTAL &euro;0,00 CHOOSE SIZES &lsaquo; &rsaquo; &times; Outfit Studio MIX IT, MATCH IT, MAKE IT YOURS Who are we dressing? Who are we dressing? Boy Girl What age? 9\u201312M 12\u201318M 2\u20133Y 3\u20134Y [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-6706","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/pages\/6706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/comments?post=6706"}],"version-history":[{"count":494,"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/pages\/6706\/revisions"}],"predecessor-version":[{"id":12184,"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/pages\/6706\/revisions\/12184"}],"wp:attachment":[{"href":"https:\/\/lullastudio.com\/lv\/wp-json\/wp\/v2\/media?parent=6706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}