/* ── 3D gallery state ── */
.aipaou-3d-active .woocommerce-product-gallery__image,
.aipaou-3d-active .woocommerce-product-gallery__image--placeholder {
    opacity: 0;
    pointer-events: none;
}

/* ── Shared 3D wrap ── */
.aipaou-3d-wrap {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
}
.aipaou-3d-wrap.pewc-hidden-field {
    display: none;
}

/* ── Print Only ── */
.aipaou-print-only {
    background: transparent;
}
.aipaou-print-only .aipaou-3d-main-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
}

/* ── Canvas 3D: CSS preserve-3d box ──
   All three faces live inside one preserve-3d container so their geometry
   is mathematically consistent. The container is rotated so the front face
   recedes to the right (left edge taller than right edge) and the top and
   left panels naturally connect.

   rotateY(-30deg): front face recedes to the right
   rotateX(10deg):  tilt slightly so we see the top face
*/
.aipaou-canvas-3d {
    --d: 35px;
    align-items: center;
    justify-content: center;
    perspective: 700px;
    filter: drop-shadow( 6px 18px 22px rgba(0,0,0,0.45) )
            drop-shadow( 2px 4px 6px rgba(0,0,0,0.22) );
}

.aipaou-3d-scene {
    position: relative;
    width: 75%;
    aspect-ratio: 1 / 1;
    transform-style: preserve-3d;
    transform: rotateX(3deg) rotateY(30deg) translateY(-9%);
    flex-shrink: 0;
}

/* Front face — fills the scene square, slightly rounded corners for canvas feel */
.aipaou-face-front {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
    backface-visibility: visible;
    border-radius: 3px;
    overflow: hidden;
}

/* Left panel */
.aipaou-face-left {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--d);
    height: 100%;
    transform-origin: right center;
    transform: translateX( calc( -1 * var(--d) ) ) rotateY( -90deg );
    background-color: #444;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: left center;
    backface-visibility: visible;
    border-radius: 3px 0 0 3px;
    overflow: hidden;
}

/* Top panel */
.aipaou-face-top {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--d);
    transform-origin: bottom center;
    transform: translateY( calc( -1 * var(--d) ) ) rotateX( 90deg );
    background-color: #555;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center top;
    backface-visibility: visible;
    border-radius: 3px 3px 0 0;
    overflow: hidden;
}

/* Edge colour overrides */
.aipaou-edge-white .aipaou-face-left {
    background-color: #d8d8d8;
}
.aipaou-edge-white .aipaou-face-top {
    background-color: #efefef;
}
/* Mirror: JS sets background-image and background-size inline on each panel */
.aipaou-edge-mirror .aipaou-face-left,
.aipaou-edge-mirror .aipaou-face-top {
    background-color: transparent;
}

.aipaou-customer-fields {
    margin-bottom: 15px;
}

.aipaou-customer-fields label.pewc-field-label {
    margin-top: 15px;
    display: block;
}

.woocommerce-product-gallery img {
    margin: 0 auto !important;
}

.aipaou-font-loading {
    color: blue;
}
.aipaou-font-error {
    color: red;
}
.selectGFontContainer .select2-results__option {
    margin-bottom: 0;
}
.aipaou-text-layer {
  text-align: center;
}
.pewc-has-image-preview .woocommerce-product-gallery__image {
  pointer-events: none;
}
.aipaou-thumb-flat,
.aipaou-thumb-3d {
  pointer-events: auto;
}
.woocommerce-product-gallery {
  position: relative;
}

/* ── Preview thumbnails ── */
.aipaou-thumb-flat {
    display: block;
    width: 100%;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.2s;
}
.aipaou-thumb-flat:hover,
.aipaou-thumb-flat.aipaou-thumb-active {
    opacity: 1;
}

/* 3D thumb: square block matching image thumb proportions */
.aipaou-thumb-3d {
    display: block;
    position: relative;
    width: 100%;
    padding-top: 100%;
    background: #f5f5f5;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.2s;
    box-sizing: border-box;
}
.aipaou-thumb-3d:hover,
.aipaou-thumb-3d.aipaou-thumb-active {
    opacity: 1;
}

/* mini 3d scene — centred inside the square span */
.aipaou-thumb-3d .aipaou-mini-scene-wrap {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.aipaou-mini-scene {
    --md: 6px;
    position: relative;
    width: 65%;
    aspect-ratio: 1 / 1;
    transform-style: preserve-3d;
    transform: perspective(200px) rotateX(3deg) rotateY(30deg);
}
.aipaou-mini-front {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    border-radius: 1px;
    overflow: hidden;
}
.aipaou-mini-left {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--md);
    height: 100%;
    transform-origin: right center;
    transform: translateX( calc( -1 * var(--md) ) ) rotateY( -90deg );
    background-color: #444;
    border-radius: 1px 0 0 1px;
    backface-visibility: visible;
}
.aipaou-mini-top {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--md);
    transform-origin: bottom center;
    transform: translateY( calc( -1 * var(--md) ) ) rotateX( 90deg );
    background-color: #555;
    border-radius: 1px 1px 0 0;
    backface-visibility: visible;
}

/* ── Thumbnail strip ── */
.aipaou-thumb-strip {
    clear: both;
    overflow: hidden;
    zoom: 1;
    margin: 0;
    padding: 0;
    list-style: none;
    position: relative;
    z-index: 20;
    transform: translateY(50px);
}
.aipaou-thumb-strip li {
    width: 25%;
    float: left;
    margin: 0;
    list-style: none;
}
.aipaou-thumb-strip li img {
    margin: 0;
}

/* Amazon-style drag & resize */
.aipaou-image-layer.aipaou-editable {
    cursor: move;
    touch-action: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    pointer-events: auto;
}
/* Dashed selection frame as a child element (not an outline on the layer): with a print mask
   the layer's z-index is dropped so this frame (z-index 999) and the resize handles (z-index
   1000) paint ABOVE the mask and stay visible, while the photo <img> stays below it (clipped). */
.aipaou-frame {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    box-sizing: border-box;
    /* high-contrast dashed selection border: dark + thicker so it's visible on the light plexi
       and white photos; a faint white halo keeps it visible on dark images too */
    border: 3px dashed #1d2327;
    box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.85);
    z-index: 999;
    pointer-events: none;
}
.aipaou-image-layer.aipaou-editable:hover .aipaou-frame {
    border-color: rgba(0, 0, 0, 0.85);
}
.aipaou-image-layer.aipaou-editable img {
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none; /* let the layer handle the gesture, not the image */
}
.aipaou-resize-handle {
    position: absolute;
    width: 20px;
    height: 20px;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    background: #1d2327;        /* DARK fill → clearly visible on light plexi / white photos */
    border: 3px solid #ffffff;  /* white ring */
    border-radius: 50%;
    /* outer dark ring + drop shadow → also visible on dark/busy areas of the artwork */
    box-shadow: 0 0 0 1.5px #1d2327, 0 1px 5px rgba(0, 0, 0, 0.6);
    touch-action: none;
    z-index: 1000;
}
/* Rotate-only field: the photo body is not draggable, so it must not swallow the page scroll or
   promise a move it will not make. The rotate handle keeps its own touch-action below. */
.aipaou-image-layer.aipaou-editable.aipaou-no-drag {
    cursor: default;
    touch-action: auto;
}

/* Rotation handle: above the photo, on a short stalk, the way every editor draws it — so it is
   never mistaken for one of the corner dots that resize. */
.aipaou-rotate-handle {
    position: absolute;
    top: -46px;
    left: 50%;
    width: 26px;
    height: 26px;
    margin-left: -13px;
    box-sizing: border-box;
    background: #1d2327 url( 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.4" stroke-linecap="round"><path d="M20 11a8 8 0 1 0-2.3 6"/><path d="M20 4v7h-7"/></svg>' ) center / 17px 17px no-repeat;
    border: 3px solid #ffffff;
    border-radius: 50%;
    box-shadow: 0 0 0 1.5px #1d2327, 0 1px 5px rgba( 0, 0, 0, 0.6 );
    cursor: grab;
    touch-action: none;
    z-index: 1000;
}
.aipaou-rotate-handle::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    width: 3px;
    height: 16px;
    margin-left: -1.5px;
    background: #1d2327;
    box-shadow: 0 0 0 1px rgba( 255, 255, 255, 0.85 );
}
.aipaou-frame-overlay .aipaou-rotate-handle { pointer-events: auto; }

.aipaou-handle-tl { top: -10px; left: -10px; cursor: nwse-resize; }
.aipaou-handle-tr { top: -10px; right: -10px; cursor: nesw-resize; }
.aipaou-handle-bl { bottom: -10px; left: -10px; cursor: nesw-resize; }
.aipaou-handle-br { bottom: -10px; right: -10px; cursor: nwse-resize; }

/* Frame + handles overlay: a sibling of the print mask, placed ABOVE it (z-index set inline by
   the JS). It mirrors the photo layer's box, so the dashed frame + corner handles inside it paint
   OVER the mask and stay fully visible, while the photo <img> stays clipped under the mask. The
   overlay is click-through (so dragging the photo body still reaches the layer); only the handles
   capture events. This avoids the layer's own transform trapping them below the mask. */
.aipaou-frame-overlay {
    box-sizing: border-box;
    pointer-events: none;
}
.aipaou-frame-overlay .aipaou-resize-handle { pointer-events: auto; }

/* Print mask: a PNG (transparent print window) overlaid on top of the customer image.
   `top: 50%` is a percentage of the layer_parent: on the products where that parent has no height
   (see `.aipaou-clip` above) `sync_clip_box()` overrides it inline, in px, so the mask stays centred
   on the same base-image box the photo is clipped to. */
.aipaou-mask-layer {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate( -50%, -50% );
    width: 100%;
    margin: 0;
    padding: 0;
    pointer-events: none; /* drag/resize works through the mask */
}
.aipaou-mask-layer img {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;
    pointer-events: none;
}
.aipaou-mask-layer.pewc-hidden-field { display: none; }

/* Proportional resize: beat any theme rule that locks the image height
   (e.g. Porto's per-product `.aipaou-image-layer img { height:150px }`). */
body .aipaou-image-layer.aipaou-editable img {
    width: 100% !important;
    height: auto !important;
    max-height: none !important;
    object-fit: fill !important;
}

/* "Personalizza" customization mode */
.aipaou-customize-controls { margin: 12px 0; }
.aipaou-customize-done { display: none; }
/* The mask fully clips the photo to its window even while editing: outside the transparent
   window the uploaded image is HIDDEN (covered by the mask) — matching the printed/composite
   result — instead of showing through faintly. The corner resize handles (z-index 1000) stay
   above the mask, so the photo is still draggable/resizable. */
.aipaou-customizing .aipaou-mask-layer { opacity: 1; }

/* Customization mode: isolate the gallery to ONLY the slide that hosts the overlay (the main
   image) so the customer sees just the customization area and cannot switch product images. */
.aipaou-gallery-locked { position: relative; }
.aipaou-gallery-locked .owl-nav,
.aipaou-gallery-locked .owl-dots,
.aipaou-gallery-locked .flex-control-nav,
.aipaou-gallery-locked .flex-direction-nav { display: none !important; }
/* Containers stay unclipped so the dashed frame + corner handles (in `.aipaou-frame-overlay`,
   a sibling above the mask) remain visible and grabbable even when the photo is enlarged past
   the slide. The PHOTO itself must NOT escape: it is clipped by `.aipaou-clip` below, because
   the print mask only covers the product-image area — without that wrapper an enlarged photo
   painted over the rest of the page (reported on mobile: photo spilling outside the card). */
.aipaou-gallery-locked .owl-stage-outer,
.aipaou-gallery-locked .inner,
.aipaou-gallery-locked .img-thumbnail,
.aipaou-gallery-locked .owl-item,
.aipaou-gallery-locked .product-image-slider { overflow: visible !important; }
/* Clipping wrapper for the customer photo: exactly the product-image box (inset:0 on the
   positioned layer_parent), so the layer's left/top/width percentages resolve unchanged.
   When that parent has no height of its own (its images are laid out absolutely — the surface
   artwork of "Inizia a personalizzare", or a theme that stacks the gallery) this collapses to 0 and
   overflow:hidden swallows the photo: `sync_clip_box()` in scripts.js then overrides top/height
   inline, in px, measured on the base image. */
.aipaou-clip {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: hidden;
    pointer-events: none; /* the photo layer inside re-enables it, so dragging still works */
}
.aipaou-clip .aipaou-image-layer { pointer-events: auto; }
/* Declare the photo layer's own display. Something on the site (theme/per-product CSS we cannot
   read — it is served minified from the CDN) applies `display:none` to `.aipaou-image-layer`, and
   since we never declared one, the layer collapsed to 0×0: the photo did not show and the frame
   overlay, sized from the layer's height, stayed 0 tall so the four corner handles piled up
   ("box minuscolo"/"un solo pallino"). Verified live: forcing display on the real layer restored
   the proportional size (400×900 → 164×369) and all four handles at four distinct corners. */
body .aipaou-clip .aipaou-image-layer { display: block !important; }
/* …but keep the legitimate hiding: PEWC marks the layer/wrapper when its conditional group is off. */
body .aipaou-clip .aipaou-image-layer.pewc-hidden-field,
.aipaou-clip.pewc-hidden-field { display: none !important; }
.aipaou-gallery-locked .owl-stage { transform: none !important; width: 100% !important; }
.aipaou-gallery-locked .owl-item { display: none !important; }
.aipaou-gallery-locked .owl-item.aipaou-host {
    display: block !important;
    width: 100% !important;
    float: none !important;
    margin: 0 auto !important;
    pointer-events: none !important; /* block carousel drag; overlay re-enabled below */
}
/* Owl clones slides for looping; after a (mobile) re-init a clone can carry a copy of the host
   slide + overlay. In the locked view (owl-stage forced to no-transform + 100% width) a visible
   clone would stack BELOW the real one and show the customization area twice — so never show
   cloned slides here, even if they picked up the host class. */
.aipaou-gallery-locked .owl-item.cloned,
.aipaou-gallery-locked .owl-item.cloned.aipaou-host { display: none !important; }

/* Porto sets .product-image-slider { z-index: 1 }, which traps the frame + resize handles in a
   LOW stacking context — so a sibling like the "-49%" sale badge (.labels/.onsale, z-index 7)
   paints OVER the handles wherever they reach a corner. Lift the slider above those siblings
   while customizing, and hide the sale badge (clutter in the isolated view). */
.aipaou-gallery-locked .product-image-slider { z-index: 50 !important; }
.aipaou-customizing .product-images .labels,
.aipaou-customizing .product-images .onsale,
.aipaou-customizing .product-images .pewc-discount-label { display: none !important; }
.aipaou-gallery-locked .aipaou-image-layer,
.aipaou-gallery-locked .aipaou-image-layer.aipaou-editable,
.aipaou-gallery-locked .aipaou-resize-handle,
/* text-preview overlay (apaou-) shares the locked gallery: keep it draggable too */
.aipaou-gallery-locked .apaou-text-layer,
.aipaou-gallery-locked .apaou-text-layer.apaou-editable,
.aipaou-gallery-locked .apaou-resize-handle { pointer-events: auto !important; }

/* Porto's thumbnail strip lives OUTSIDE .product-images, so the .aipaou-gallery-locked class
   never reaches it — hide it (and the synced thumbs carousel) whenever customizing, otherwise
   tapping a thumbnail still switches the main image. This was the "no gallery lock on mobile"
   bug (the thumbnails are the easy switch target on touch). Scoped to body.aipaou-customizing
   so it works regardless of where the strip sits in the DOM. */
body.aipaou-customizing .product-thumbnails,
body.aipaou-customizing .product-thumbs-slider { display: none !important; }

/* Belt-and-suspenders for touch devices: stop the main carousel from receiving any swipe/drag
   while locked, so a swipe on the image can't advance Owl. The overlay + resize handles are
   re-enabled to pointer-events:auto above, so dragging the photo/text still works. */
.aipaou-gallery-locked .owl-stage-outer,
.aipaou-gallery-locked .owl-stage {
    pointer-events: none !important;
    touch-action: none !important;
}

/* Floating close (×) button shown on the isolated canvas */
.aipaou-customize-close {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1100;
    width: 36px;
    height: 36px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba( 0, 0, 0, 0.6 );
    color: #fff;
    font-size: 22px;
    line-height: 36px;
    text-align: center;
    cursor: pointer;
}
.aipaou-customize-close:hover { background: rgba( 0, 0, 0, 0.8 ); }

/* "Inizia a personalizzare" (builder surfaces): the button that swaps the product image for the
   surface's own starting image and opens the isolated customization view. Styled as a clear call
   to action, and hidden while customizing (the × closes that view). */
.aipaou-start-btn {
    display: block;
    width: 100%;
    margin: 0 0 16px;
    padding: 14px 18px;
    box-sizing: border-box;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    text-align: center;
    cursor: pointer;
    color: #1d2327;
    background: #fff;
    border: 2px solid #e8a33d;
    border-radius: 4px;
}
.aipaou-start-btn:hover { background: #fdf6ea; }
body.aipaou-customizing .aipaou-start-btn { display: none !important; }
