.finishing-theme-svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.finishing-theme-svg svg {
    display: block;
    width: 100%;
    height: 100%;
}

#sdv-canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    -o-object-fit: cover;
    object-fit: cover;
    opacity: 1;
    transition: opacity 160ms ease;
}

#canvas-wrapper .sdv-loading-overlay {
    position: absolute;
    inset: 0;
    display: none;
    place-items: center;
    background: rgba(247, 247, 246, 0.85);
    z-index: 10;
}

#canvas-wrapper.is-loading .sdv-loading-overlay {
    display: grid;
}

#canvas-wrapper.is-loading #sdv-canvas {
    opacity: 0;
}

/* ShapeDiver Viewer 3.2.1 inserts .sdv-spinner-container as the first child of
   #canvas-wrapper, before #sdv-canvas. Both are position:absolute with no
   z-index, so the canvas paints over the spinner and it never becomes visible.
   Lift the container above the canvas, but below .sdv-loading-overlay (10) so
   our initial-load overlay still covers it.

   The bundle also ships `filter: invert(1) grayscale(100%)` and
   `mix-blend-mode: difference` on .sdv-spinner, tuned for ShapeDiver's dark
   default background (#393a45). Our canvas background is light (#f7f7f6), and
   the z-index above isolates the blending group regardless — so drop both and
   let the asset render in its native dark colour (#0a0a0a / #28292f). */
#canvas-wrapper .sdv-spinner-container {
    z-index: 5;

    /* Older rules clamped this container to 200x66 via
       `div:has(img[src$="spinner_ripple.svg"])`, which pinned it to the canvas
       top-left and clipped the spinner. It must span the whole canvas so the
       spinner can sit in the bottom-right corner. */
    width: 100%;
    height: 100%;
    inset: 0;
}

#canvas-wrapper .sdv-spinner {
    mix-blend-mode: normal;
    filter: none;

    /* The bundle caps the spinner at 15% of the canvas (~55px here) and the
       ripple animation sits well inside that box, so it reads as tiny. Size it
       explicitly and defeat the cap. */
    width: 80px;
    height: 80px;
    max-width: none;
    max-height: none;

    /* Pin bottom-right regardless of which .sdv-spinner-<pos> class the bundle
       applies. Swap right/bottom for left/top to move it back to a corner. */
    top: auto;
    left: auto;
    right: 18px;
    bottom: 18px;
}

/* Renamed from .sdv-spinner: ShapeDiver Viewer 3.2.1 uses that exact class for
   its own busy-mode spinner image, so the old name hijacked the viewer's
   spinner. This rule styles only our initial-load overlay. */
.clips-spinner {
    width: 40px;
    height: 40px;
    border: 4px solid rgba(0, 0, 0, 0.15);
    border-top-color: rgba(0, 0, 0, 0.65);
    border-radius: 50%;
    animation: sdvspin 0.9s linear infinite;
}

@keyframes sdvspin {
    to { transform: rotate(360deg); }
}

#fullImage .modal__container {
    padding: 0;
    height: 100%;
}

#fullImage .modal__content {
    width: 100%;
    height: 100%;
    max-width: none;
}

#fullImage .modal__img-full {
    position: relative;
    width: 100%;
    height: 100dvh;
    overflow: hidden;
}

form[data-product-form] .summary .summary-action a.btn[data-edit-form] {
    position: absolute;
    right: 0;
}
form[data-product-form] .step-input.stair-input-prev[data-step="0"] .step-input__header {
    position: relative;
}
form[data-product-form] .step-input.stair-input-prev[data-step="0"] .step-input__header a[data-popup-opener] {
    position: absolute;
    right: 0;
}
/* Default state: show errors, hide basket buttons */
.configuration.more-to-do { display: block; }
.configuration.add-or-edit { display: none; }
.configuration.employee-edit { display: none; }
.is-employee .cart-holder { display: none; }

/* Payment-status: hide all status sections by default; handlePaymentStatus reveals
   the one matching the order's status (.payment.payment-<status>). */
.clips-payment-status section.payment,
.clips-payment-status section.payment-video {
    display: none;
}
.clips-configurator .floor-input__price p {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
}
.void-input--v2 .floor-input__table-label.grid--xl > div:nth-child(3) {
    text-align: center !important;
}

.expert-review__message.success {
    color: green;
}

.expert-review__message.error {
    color: red;
}

.share-form__success button[data-share-btn] {
    position: static;
    transform: none;
    top: auto;
    right: auto;
    height: auto;
}
.share__holder:not(:has(.share-form__success.active)) {
    .share-configurator { display: block !important; }
    .share-configuration { display: inline-flex !important; }
}
.cart-holder.active .cart-dropdown.cart-dropdown-items-1 .cart-item__remove {
    display: inline-block;
}
.geometry__total > div > div:nth-child(2) {
    font-weight: 700;
}
body.clips-configurator[language-id="1"] .stair-finishing__option {
    max-width: 291px;
}
@media (min-width: 768px) {
    body[language-id="4"] [data-product-form] .step-input .step-input__slider label {
        font-size: 15px;
    }
}

.floor-input__quantity input[name="amountOfFloors"],
.floor-input__quantity input[name="quantity"] {
    pointer-events: none;
    cursor: default;
}

@supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {
    .input-next::before {
        -webkit-backdrop-filter: blur(12px);
        backdrop-filter: blur(12px);
        background-color: hsla(0, 0%, 100%, .4);
    }
    .modal__backdrop, .modal__fixed:before {
        -webkit-backdrop-filter: blur(10px) brightness(85%);
        backdrop-filter: blur(10px);
    }
}
/* BIM/IFC download modal — progress + error feedback.
   Generating an IFC takes one ShapeDiver session per unique staircase, so the
   visitor needs to see that something is happening. */
.modal__bim .bim-form__status {
    margin: 12px 0 0;
    font-size: 14px;
    line-height: 20px;
    color: #818181;
}

.modal__bim .bim-form__status.is-error {
    color: #ff8200;
}
