/** Shopify CDN: Minification failed

Line 160:27 Unexpected "/"

**/
/** Shopify CDN: Minification failed

Line 155:27 Unexpected "/"

**/
.pdp-dyo-modal {
  .pdp-dyo-header {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    padding: 16px 12px;

    @media screen and (min-width: 1025px) {
      padding: 24px;
      grid-template-columns: repeat(12, 1fr);
    }
  }

  .span-4-4 {
    grid-column: span 4 / span 4;
  }

  .pdp-dyo-button-wrapper {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
  }

  .pdp-dyo-save-button {
    text-decoration: underline;
    text-underline-position: under;
  }

  .pdp-dyo-close-button,
  .pdp-dyo-save-button {
    transition: opacity 0.3s ease;

    &:hover {
      opacity: 0.5;
    }
  }

  .pdp-dyo-logo {
    display: none;
    justify-content: center;
    align-items: center;

    @media screen and (min-width: 1025px) {
      display: flex;
    }
  }

  .pm__lowest-price {
    display: none;
  }

  .pdp-dyo-infos {
    font-weight: 400;
    margin-bottom: 4px;

    &:last-of-type {
      margin-bottom: 0;
    }

    @media screen and (min-width: 1025px) {
      font-size: 0.875rem;
    }
  }

  .pdp-dyo-product-title {
    font-size: 1rem;
    margin-bottom: 4px;

    @media screen and (min-width: 1025px) {
      font-size: 1.125rem;
      margin-bottom: 8px;
    }
  }
}

viewer-modal {
  position: relative;
  aspect-ratio: 210/211;
  display: block;
  width: 100%;
  flex-grow: 1;
  height: calc(100vh - 471px);

  @media screen and (min-width: 1025px) {
    height: calc(100vh - 532px);
    aspect-ratio: 580 / 328;
  }

  &.viewer-data-loading .viewer-modal-loader-wrapper {
    visibility: visible;
  }

  studio-viewer {
    display: block;
    width: 100%;
    height: 100%;
  }
}

variant-selects {
  @media screen and (min-width: 1025px) {
    padding-bottom: 10px;
  }
}

/* Loader overlay for viewer-modal */
.viewer-modal-loader {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.viewer-modal-loader__spinner {
  width: 48px;
  height: 48px;
  border: 4px solid #e0e0e0;
  border-top: 4px solid #333;
  border-radius: 50%;
  animation: viewer-modal-spin 1s linear infinite;
}

.viewer-modal-loader-wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  visibility: hidden;
}

@keyframes viewer-modal-spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

Append to the END of assets/pdp-dyo-modal.css (the viewer-modal block above it stays —
the plain 3D modal still uses it):

@media screen and (min-width: 1025px) {
  }

/* ---------- DYO viewer box ----------
   The DYO modal deliberately does NOT use the <viewer-modal> element: its JS is the old
   Product Module v2 controller, and attaching it put two controllers on one viewer,
   which is what crashed iOS Safari during scene swaps. The plain div below replaces it;
   the viewer-modal rules above stay, because the PLAIN 3D modal still uses them.
   See the comments in sections/main-pdp_product_module.liquid.

   Heights tuned on-device 2026-08-05:
   - PHONE is smaller than the old viewer-modal so the choices below it are not pushed
     off-screen. After the first colour change a phone shows a STATIC render, so it
     needs less room than a spinnable scene.
   - DESKTOP is taller: desktop keeps live 3D and is where people actually sit and
     configure, so the model should dominate. */
.pdp-dyo-viewer-box {
  position: relative;
  display: block;
  width: 100%;
  flex-grow: 1;
  aspect-ratio: 210 / 211;
  height: calc(100vh - 540px);
  min-height: 240px;
  max-height: 46vh;
}

@media screen and (min-width: 1025px) {
  .pdp-dyo-viewer-box {
    aspect-ratio: auto;
    height: calc(100vh - 300px);
    min-height: 520px;
    max-height: none;
  }
}

.pdp-dyo-viewer-box studio-viewer {
  display: block;
  width: 100%;
  height: 100%;
}

/* The static render (phones) and the swap cover (desktop) both live inside the box. */
.pdp-dyo-viewer-box .dyo-static-render,
.pdp-dyo-viewer-box .dyo-3d-cover {
  position: absolute;
  inset: 0;
}

/* ---------- static-render loading state ----------
   Every render is generated server-side on demand, so a colour tap can take a second or
   two. Without visible feedback the shopper assumes the swatch is broken and rage-taps.
   pdp-dyo-wizard.js adds .is-loading on tap (before the request) and removes it on load. */
.dyo-static-render img[data-static-render] {
  z-index: 2;
  transition: opacity 0.2s ease;
}

.dyo-static-render .viewer-modal-loader__spinner {
  z-index: 3;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.dyo-static-render.is-loading .viewer-modal-loader__spinner {
  opacity: 1;
}

/* Dim the previous render while the new one loads: it stays as context, so the box is
   never empty, but reads clearly as "not the current answer yet". */
.dyo-static-render.is-loading img[data-static-render] {
  opacity: 0.3;
}