/* ---------------------------------------------------------------------------
 * Configurator image loader – 12-bar "tick" spinner
 *
 * Shown while a configuration is being rendered server-side. Two places emit
 * the same markup, one per breakpoint:
 *   - Frontend_TypeSpecificLayout::product/view/gallery.phtml  (>= 1024px: inside the PDP swiper)
 *   - Product_Configurator js/src/gallery.js showScreenLoader() (< 1024px: centred on the screen)
 *
 * Markup contract – 12 <i> children, nothing else required:
 *   <div class="config-spinner" role="status">
 *       <i></i> ... x12 ...
 *       <span class="sr-only">Loading...</span>
 *   </div>
 *
 * The bars are positioned in percentages of the container box, so changing
 * width/height alone rescales the whole spinner as long as it stays square.
 * `nth-of-type` (not `nth-child`) is deliberate: it keeps the opacity ramp
 * correct no matter where the sr-only span sits.
 * ------------------------------------------------------------------------- */

.config-spinner {
    position: relative;
    display: inline-block;
    width: 56px;
    height: 56px;
    color: #3c3c3c;
    animation: config-spinner-rotate 1s steps(12, end) infinite;
}

.config-spinner > i {
    position: absolute;
    display: block;
    top: 5%;
    left: 50%;
    width: 11%;
    height: 25%;
    margin-left: -5.5%;
    border-radius: 9999px;
    background-color: currentColor;

    /* 5% top + 1.8 x 25% height puts the pivot exactly on the container centre */
    transform-origin: 50% 180%;
}

.config-spinner > i:nth-of-type(1)  { transform: rotate(0deg);   opacity: 1;    }
.config-spinner > i:nth-of-type(2)  { transform: rotate(30deg);  opacity: .92;  }
.config-spinner > i:nth-of-type(3)  { transform: rotate(60deg);  opacity: .83;  }
.config-spinner > i:nth-of-type(4)  { transform: rotate(90deg);  opacity: .74;  }
.config-spinner > i:nth-of-type(5)  { transform: rotate(120deg); opacity: .65;  }
.config-spinner > i:nth-of-type(6)  { transform: rotate(150deg); opacity: .56;  }
.config-spinner > i:nth-of-type(7)  { transform: rotate(180deg); opacity: .47;  }
.config-spinner > i:nth-of-type(8)  { transform: rotate(210deg); opacity: .39;  }
.config-spinner > i:nth-of-type(9)  { transform: rotate(240deg); opacity: .32;  }
.config-spinner > i:nth-of-type(10) { transform: rotate(270deg); opacity: .26;  }
.config-spinner > i:nth-of-type(11) { transform: rotate(300deg); opacity: .21;  }
.config-spinner > i:nth-of-type(12) { transform: rotate(330deg); opacity: .16;  }

@keyframes config-spinner-rotate {
    to {
        transform: rotate(360deg);
    }
}

/* Size modifiers – percentages above make these all that is needed. */
.config-spinner--sm {
    width: 28px;
    height: 28px;
}

.config-spinner--lg {
    width: 56px;
    height: 56px;
}

@media (prefers-reduced-motion: reduce) {
    .config-spinner {
        animation-duration: 2.4s;
        animation-timing-function: steps(12, end);
    }
}

/* ---------------------------------------------------------------------------
 * Below 1024px the spinner is centred on the screen, not on a gallery.
 *
 * The large gallery scrolls out of view and the small one shrinks to the 200px
 * scroll thumbnail, so an overlay pinned to either is easily missed while the
 * user is working through the options. gallery.js appends
 * .configurator-screen-loader to <body> instead, and gallery.phtml renders its
 * in-swiper overlay only from 1024px up, so only one spinner is ever visible.
 * ------------------------------------------------------------------------- */

.configurator-screen-loader {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;

    /* Same wash as the in-gallery overlay, so the spinner reads over whatever
       part of the page happens to be on screen. */
    background-color: rgba(255, 255, 255, .7);

    /* Changing another option mid-render is supported (the request is aborted),
       so the backdrop must not swallow taps. */
    pointer-events: none;

    /* Held invisible for the first 120ms: a cached or already generated image
       comes back almost immediately and would otherwise flash the backdrop. */
    animation: configurator-screen-loader-fade-in .18s ease-out .12s both;
}

@keyframes configurator-screen-loader-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    /* Keep the 120ms hold (it prevents the flash), drop the fade itself. */
    .configurator-screen-loader {
        animation-duration: 0s;
    }
}

@media (min-width: 1024px) {
    /* Desktop keeps the in-gallery overlay; the screen loader is not created there. */
    .configurator-screen-loader {
        display: none;
    }
}
