/* Repix Canvas Designer */

/* ---------- Theme tokens ---------- */
:root {
    --repix-bg: #ffffff;
    --repix-panel: #ffffff;
    --repix-border: #e3ebe9;     /* cool border, was warm #ece7e5 */
    --repix-border2: #eef3f1;    /* cool soft border, was warm #f5efed */
    --repix-text: #111827;       /* near-black slate for body text */
    --repix-muted: #475569;      /* darker slate for labels/secondary text */
    --repix-muted2: #64748b;     /* mid slate for hints / sub-text */
    --repix-shadow: 0 10px 30px rgba(106, 142, 135, .10);
    --repix-shadow2: 0 4px 16px rgba(106, 142, 135, .06);
    --repix-radius: 18px;
    --repix-radius-sm: 12px;
    --repix-accent: #6a8e87;
    --repix-accent-2: #557872;
    --repix-accent-soft: rgba(106, 142, 135, .10);
    --repix-accent-softer: #eef4f3;
    --repix-accent-light: #dde9e6;
    --repix-danger: #ef4444;
    /* Cool surface tones to use in place of any warm beige fallbacks */
    --repix-surface: #f4f7f6;    /* cool light surface, was warm #f9f6f5 */
    --repix-surface-2: #e9efed;  /* cool hover surface, was warm #f3ebe8 */
}

/* ---------- Wrapper ---------- */
.repix-designer-wrapper {
    margin: 24px 0 0;
    /* Defensive overflow guard. The page outside the designer (theme
       header, breadcrumbs, sticky cart badges, floating buttons, etc.)
       is out of our control, but the wrapper IS ours and we guarantee
       it stays inside the viewport even if something inside briefly
       overflows during init (e.g. a not-yet-styled cropper canvas
       reporting its natural pixel width before CSS clamps it). */
    max-width: 100%;
    overflow-x: clip;   /* clip > hidden — doesn't create a scroll container */
    min-width: 0;
}

/* When the designer is present, lock horizontal scroll at the document
   level so any out-of-bounds element from the theme or other plugins
   (sticky cart icons, drift-in CTAs, off-canvas menus) can't cause a
   right-shift of the entire page on mobile.

   We target a body class added by PHP (`add_designer_body_class`) — that
   approach works in every browser, including older Android WebViews where
   `:has()` is unreliable. The `:has()` selector is kept as a defensive
   double-bind for cases where the body class somehow doesn't make it
   onto the markup (custom themes that drop body_class filters, page-
   builder previews, etc.).

   `clip` is preferred over `hidden` because it does not establish a new
   scroll container — important for `position: sticky` elements elsewhere
   on the page to keep working. Falls back to `hidden` on Safari <16. */
@media (max-width: 991px) {
    html.has-repix-designer,
    body.has-repix-designer,
    html:has(.repix-designer-wrapper),
    body:has(.repix-designer-wrapper) {
        overflow-x: hidden;
        overflow-x: clip;
        max-width: 100vw;
        position: relative; /* establishes a containing block for absolute children that escape right */
    }
}

/* ---------- Main shell ---------- */
.repix-designer {
    max-width: 100%;
    width: 100%;
    margin: 0 auto;
    padding: 20px;
    background: #fff;
    border: 1px solid var(--repix-border);
    border-radius: var(--repix-radius);
    box-shadow: var(--repix-shadow);
    position: relative;
    box-sizing: border-box;
    display: grid;
    grid-template-columns: 380px 1fr;
    gap: 20px;
    align-items: start;
    counter-reset: repix-step;
    /* Belt + braces: grid children shrink to column, and any runaway inline
       content (a long filename, a wide canvas element) is clipped instead of
       pushing the layout past the viewport. */
    overflow-x: hidden;
    min-width: 0;
}

.repix-designer * {
    box-sizing: border-box;
}

/* Grid columns must not use their min-content width as a floor — without
   min-width:0, the preview wrap or a wide child can push its column past
   the screen edge, breaking the responsive 1-column collapse on mobile. */
.repix-designer-left,
.repix-designer-right {
    min-width: 0;
    max-width: 100%;
}

/* top accent stripe */
.repix-designer::before {
    content: "";
    position: absolute;
    left: 0; top: 0; right: 0;
    height: 4px;
    border-radius: var(--repix-radius) var(--repix-radius) 0 0;
    background: linear-gradient(90deg, var(--repix-accent), #a8c0b9);
}

/* ---------- Header (title/price moved by JS) ---------- */
.repix-designer-header .product_title {
    margin: 0 0 8px 0 !important;
    font-size: 22px !important;
    color: var(--repix-text);
}
.repix-designer-header .price {
    font-size: 20px !important;
    color: var(--repix-accent-2);
    font-weight: 700;
    margin: 0 0 10px 0 !important;
    display: block;
}
.repix-designer-header .quantity {
    display: inline-flex !important;
    align-items: center;
    gap: 0 !important;
    margin-bottom: 14px;
    max-width: 160px;
    background: var(--repix-border2);
    border: 1.5px solid var(--repix-border);
    border-radius: 12px;
    overflow: hidden;
    padding: 0 !important;
}
.repix-designer-header .quantity .qty,
.repix-designer-header .quantity input[type="number"] {
    width: 54px !important;
    height: 40px !important;
    padding: 0 !important;
    font-size: 16px !important;
    font-weight: 700 !important;
    text-align: center !important;
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
    -moz-appearance: textfield !important;
}
.repix-designer-header .quantity .qty::-webkit-outer-spin-button,
.repix-designer-header .quantity .qty::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.repix-designer-header .quantity .minus,
.repix-designer-header .quantity .plus {
    min-width: 40px !important;
    width: 40px !important;
    height: 40px !important;
    line-height: 40px !important;
    padding: 0 !important;
    font-size: 18px !important;
    font-weight: 400 !important;
    color: var(--repix-accent-2) !important;
    background: transparent !important;
    border: none !important;
    border-radius: 0 !important;
    cursor: pointer;
    transition: background .15s, color .15s;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
}
@media (hover: hover) {
.repix-designer-header .quantity .minus:hover,
.repix-designer-header .quantity .plus:hover {
    background: var(--repix-accent-soft) !important;
    color: var(--repix-accent-2) !important;
}
}

/* ---------- Columns as cards ---------- */
.repix-designer-left,
.repix-designer-right {
    background: var(--repix-panel);
    border: 1px solid var(--repix-border2);
    border-radius: var(--repix-radius);
    box-shadow: var(--repix-shadow2);
    padding: 20px;
}

.repix-designer-left {
    position: sticky;
    top: 14px;
}

/* ---------- Step headings ---------- */
.repix-designer-left h3,
.repix-designer-right h3 {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--repix-text);
    counter-increment: repix-step;
}

.repix-designer-left h3::before,
.repix-designer-right h3::before {
    content: counter(repix-step);
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border-radius: 9px;
    background: var(--repix-accent-soft);
    border: 1.5px solid rgba(106, 142, 135,.4);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 800;
    color: var(--repix-accent-2);
    line-height: 1;
}

/* ---------- Upload zone ---------- */
.repix-upload-zone {
    border: 2px dashed var(--repix-border);
    border-radius: var(--repix-radius-sm);
    background: #f8fafc;
    padding: 24px 20px 20px;
    text-align: center;
    cursor: pointer;
    transition: border-color .2s ease, background .2s ease;
    margin-bottom: 10px;
    position: relative;
    overflow: hidden;
}

@media (hover: hover) {
.repix-upload-zone:hover {
    border-color: var(--repix-accent);
    background: var(--repix-accent-soft);
}
}

.repix-upload-zone.drag-over {
    border-color: var(--repix-accent-2);
    background: var(--repix-accent-soft);
    transform: scale(1.01);
}

.repix-upload-icon {
    color: var(--repix-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
}

.repix-upload-icon--success {
    color: #22c55e;
}

.repix-upload-main-text {
    font-weight: 600;
    font-size: 14px;
    margin: 0 0 8px;
    color: var(--repix-muted);
}

.repix-upload-sub-text {
    font-size: 12px;
    color: var(--repix-muted2);
    margin: 6px 0 0;
}

.repix-upload-btn {
    display: inline-block;
    background: linear-gradient(180deg, var(--repix-accent), var(--repix-accent-2));
    border: none;
    border-radius: 999px;
    padding: 10px 24px;
    font-size: 14px;
    font-weight: 700;
    color: #fff;
    cursor: pointer;
    transition: filter .15s ease, transform .1s ease, box-shadow .15s ease;
    box-shadow: 0 6px 16px rgba(106, 142, 135,.3);
    letter-spacing: .2px;
    line-height: 1.2;
}

@media (hover: hover) {
.repix-upload-btn:hover {
    filter: brightness(1.05);
    transform: translateY(-1px);
    box-shadow: 0 8px 20px rgba(106, 142, 135,.38);
    color: #fff;
}
}

.repix-upload-btn:active {
    transform: translateY(0);
}

.repix-change-image-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding: 8px 20px;
    background: var(--repix-surface, #faf6f4);
    border: 1.5px solid var(--repix-border, #ece7e5);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    color: var(--repix-text, #1f1410);
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, box-shadow .15s;
}
.repix-change-image-btn::before {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    background-color: currentColor;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='17 8 12 3 7 8'/%3E%3Cline x1='12' y1='3' x2='12' y2='15'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='17 8 12 3 7 8'/%3E%3Cline x1='12' y1='3' x2='12' y2='15'/%3E%3C/svg%3E");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    flex-shrink: 0;
}
@media (hover: hover) {
.repix-change-image-btn:hover {
    background: #fff;
    border-color: var(--repix-accent, #6a8e87);
    color: var(--repix-accent-2, #557872);
    box-shadow: 0 2px 8px rgba(106, 142, 135, .18);
}
}

.repix-upload-status {
    margin-top: 8px;
    font-size: 13px;
    color: var(--repix-muted);
    min-height: 1em;
}

.repix-upload-progress {
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 4px;
    background: rgba(44, 58, 54, .06);
    overflow: hidden;
}

.repix-upload-progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--repix-accent), var(--repix-accent-2));
    transition: width .12s ease;
}

.repix-upload-progress-text {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 700;
    color: var(--repix-accent);
    text-align: center;
}

/* ---------- Product toggle ---------- */
.repix-product-toggle {
    display: flex;
    gap: 0;
    margin-bottom: 18px;
    background: var(--repix-border2);
    padding: 4px;
    border-radius: 12px;
    border: 1px solid var(--repix-border);
    width: 100%;
}

.repix-toggle-btn {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 11px 12px;
    border: none;
    background: transparent;
    border-radius: 9px;
    color: var(--repix-muted);
    font-weight: 600;
    cursor: pointer;
    /* Explicit list instead of `transition: all`. `transition: all`
       animates EVERY changing property — including ones triggered by
       layout shifts during scroll on Android Chrome — which causes
       visible flicker on the product-type toggle row. List exactly
       the properties that should animate on the active/hover state
       changes. */
    transition: background .18s ease, color .18s ease, box-shadow .18s ease;
    font-size: 14px;
    letter-spacing: .2px;
    white-space: nowrap;
}

@media (hover: hover) {
.repix-toggle-btn:hover {
    color: var(--repix-accent-2);
}
}

.repix-toggle-btn.active {
    background: #fff;
    color: var(--repix-accent-2);
    box-shadow: 0 2px 8px rgba(44, 58, 54, .12);
}

/* ---------- Form rows ---------- */
.repix-row {
    margin: 16px 0;
}

.repix-row label,
.repix-label-sm {
    display: block;
    font-weight: 700;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .6px;
    color: var(--repix-muted);
    margin: 0 0 8px;
}

/* ---------- Select ---------- */
.repix-designer select {
    width: 100%;
    min-height: 48px;
    border: 1.5px solid var(--repix-border);
    border-radius: var(--repix-radius-sm);
    background: #fff;
    padding: 12px 40px 12px 14px;
    font-size: 15px;
    font-weight: 500;
    color: var(--repix-text);
    outline: none;
    appearance: none;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--repix-muted) 50%),
        linear-gradient(135deg, var(--repix-muted) 50%, transparent 50%);
    background-position:
        calc(100% - 18px) 52%,
        calc(100% - 12px) 52%;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
}

.repix-designer select:focus {
    border-color: var(--repix-accent);
    box-shadow: 0 0 0 3px rgba(106, 142, 135,.18);
}

@media (hover: hover) {
.repix-designer select:hover {
    border-color: rgba(106, 142, 135,.6);
}
}

/* ---------- Orientation cards ---------- */
.repix-ori-toggle {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.repix-ori-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 16px 8px 14px;
    border: 2px solid var(--repix-border);
    border-radius: 14px;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease, box-shadow .15s ease;
    background: #f8fafc;
    font-size: 13px;
    font-weight: 600;
    color: var(--repix-muted);
    user-select: none;
    margin: 0;
    position: relative;
}

@media (hover: hover) {
.repix-ori-card:hover {
    border-color: rgba(106, 142, 135,.5);
    color: var(--repix-accent-2);
    background: var(--repix-accent-soft);
}
}

.repix-ori-card input[type="radio"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 0;
    height: 0;
}

/* works in all modern browsers; .is-active is set by JS for older ones */
.repix-ori-card:has(input:checked),
.repix-ori-card.is-active {
    border-color: var(--repix-accent);
    background: var(--repix-accent-soft);
    color: var(--repix-accent-2);
    box-shadow: 0 0 0 3px rgba(106, 142, 135,.12);
}

.repix-ori-icon {
    width: 44px;
    height: auto;
    flex-shrink: 0;
}

.repix-ori-icon--portrait {
    width: 31px;
}

/* ---------- Actions ---------- */
.repix-actions {
    margin-top: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 16px;
    border-top: 1px solid var(--repix-border2);
}

.repix-quality {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-weight: 600;
    font-size: 13px;
    color: var(--repix-muted);
    background: #f8fafc;
    border: 1px solid var(--repix-border2);
    border-radius: 12px;
    padding: 10px 14px;
}

.repix-quality-value {
    font-weight: 700;
    font-size: 13px;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(44, 58, 54, .06);
    color: var(--repix-text);
    transition: background .2s ease, color .2s ease;
}

.repix-quality-value[data-level="great"] { background: rgba(34,197,94,.15);  color: #16a34a; }
.repix-quality-value[data-level="good"]  { background: rgba(234,179,8,.15);   color: #b45309; }
.repix-quality-value[data-level="ok"]    { background: rgba(249,115,22,.15);  color: #c2410c; }
.repix-quality-value[data-level="low"]   { background: rgba(239,68,68,.15);   color: var(--repix-danger); }

/* ---------- Quantity paired with add-to-cart (Botiga-matched) ----------
   Mirrors .botiga-single-addtocart-wrapper styling from NFOTO theme so
   the designer's CTA row looks native: 54px tall, pill buttons, 14px
   radius, brand shadow. */
.repix-qty-wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-width: 132px;
    height: 54px;
    background: #fff;
    border: 1px solid var(--nf-border-soft, #ece7e5);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--nf-shadow-sm, 0 4px 14px rgba(0, 0, 0, 0.04));
    flex-shrink: 0;
    padding: 0;
    gap: 0;
}
.repix-qty-label {
    display: none; /* hidden visually — kept in DOM for screen readers if needed */
}
/* Hide WooCommerce's own label text inside .quantity */
.repix-qty-wrap .quantity > label,
.repix-qty-wrap .quantity .screen-reader-text {
    display: none !important;
}
.repix-qty-wrap .quantity {
    margin: 0;
    display: flex;
    align-items: center;
    height: 100%;
    width: 100%;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
}
/* Input field */
.repix-qty-wrap .quantity input.qty,
.repix-qty-wrap input.qty {
    width: 48px;
    min-width: 48px;
    height: 54px;
    border: 0 !important;
    background: #fff;
    box-shadow: none !important;
    text-align: center;
    font-size: 16px;
    font-weight: 600;
    color: var(--nf-heading, #222);
    padding: 0;
    margin: 0;
    appearance: textfield;
    -moz-appearance: textfield;
    font-family: var(--nf-font, inherit);
}
.repix-qty-wrap .quantity input.qty::-webkit-outer-spin-button,
.repix-qty-wrap .quantity input.qty::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
/* Plus/minus buttons (Botiga-style) */
.repix-qty-wrap .quantity .botiga-quantity-minus,
.repix-qty-wrap .quantity .botiga-quantity-plus,
.repix-qty-wrap .quantity .minus,
.repix-qty-wrap .quantity .plus {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    min-width: 42px;
    height: 54px;
    background: var(--nf-bg-surface, #f4f7f6);
    color: #4a5d57;
    font-size: 18px;
    font-weight: 600;
    text-decoration: none;
    border: 0;
    cursor: pointer;
    border-radius: 0;
    transition: background 0.2s ease, color 0.2s ease;
}
@media (hover: hover) {
.repix-qty-wrap .quantity .botiga-quantity-minus:hover,
.repix-qty-wrap .quantity .botiga-quantity-plus:hover,
.repix-qty-wrap .quantity .minus:hover,
.repix-qty-wrap .quantity .plus:hover {
    background: #e9efed;
    color: #2c3a36;
}
}

/* Pair qty + add-to-cart on one row when there's horizontal space.
   Uses grid so the add-to-cart button fills the remaining width. */
@media (min-width: 520px) {
    .repix-actions {
        display: grid;
        grid-template-columns: auto 1fr;
        gap: 12px;
    }
    .repix-actions .repix-quality,
    .repix-actions .repix-preview-btn { grid-column: 1 / -1; }
    .repix-actions .repix-qty-wrap { grid-column: 1; }
    .repix-actions .repix-add-to-cart { grid-column: 2; }
}
/* Stack on narrow screens */
@media (max-width: 519px) {
    .repix-qty-wrap { width: 100%; }
    .repix-qty-wrap .quantity input.qty { flex: 1 1 auto; width: auto; }
}

/* ---------- Add to cart button ---------- */
.repix-add-to-cart.button.alt {
    width: 100%;
    height: 54px;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border-radius: 14px !important;
    padding: 0 24px !important;
    font-size: 15px !important;
    font-weight: 700 !important;
    letter-spacing: .2px;
    border: none !important;
    background: linear-gradient(160deg, var(--repix-accent), var(--repix-accent-2)) !important;
    box-shadow: 0 8px 20px rgba(106, 142, 135,.3) !important;
    transition: filter .15s ease, transform .1s ease, box-shadow .15s ease;
    color: #fff !important;
}

@media (hover: hover) {
.repix-add-to-cart.button.alt:hover {
    filter: brightness(1.05);
    transform: translateY(-1px);
    box-shadow: 0 12px 24px rgba(106, 142, 135,.4) !important;
    color: #fff !important;
}
}

.repix-add-to-cart.button.alt:active {
    transform: translateY(0);
}

.repix-add-to-cart.button.alt:disabled {
    opacity: .5;
    cursor: not-allowed !important;
    box-shadow: none !important;
    background: #cbd5e1 !important;
    transform: none !important;
    filter: none !important;
    color: #fff !important;
}

/* ---------- Preview / crop area ---------- */
.repix-preview-wrap {
    border-radius: var(--repix-radius-sm);
    overflow: hidden;
    border: 1px solid var(--repix-border);
    background-color: var(--repix-border2);
    background-image:
        linear-gradient(45deg, rgba(0,0,0,.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(0,0,0,.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(0,0,0,.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(0,0,0,.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0;
    min-height: 320px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

.repix-preview-wrap:not(.has-image)::after {
    content: "Velg et bilde for å se forhåndsvisning";
    color: var(--repix-muted2);
    font-size: 14px;
    text-align: center;
    padding: 24px;
    pointer-events: none;
}

.repix-preview {
    display: block;
    width: 100%;
    height: auto;
    max-height: 600px;
    object-fit: contain;
    background: transparent;
}

.repix-preview:not([src]),
.repix-preview[src=""] {
    display: none;
}

/* ---------- Bleed / fold overlays ---------- */
.repix-fold-overlay {
    position: absolute;
    pointer-events: none;
    border: 2px dashed rgba(255,165,0,.9);
}

.repix-bleed-shade {
    position: absolute;
    background: rgba(0,0,0,.28);
    pointer-events: none;
}
.repix-bleed-shade.top    { left:0; right:0; top:0; height:0; }
.repix-bleed-shade.bottom { left:0; right:0; bottom:0; height:0; }
.repix-bleed-shade.left   { top:0; bottom:0; left:0; width:0; }
.repix-bleed-shade.right  { top:0; bottom:0; right:0; width:0; }

/* ---------- Hints ---------- */

/* Collapsible wrapper around the hints. Uses a plain <details> element so
   the behaviour is native and accessible (keyboard-toggleable, screen-
   reader-announced, no JS needed). Compact in its default closed state —
   one row showing "Tips: hvordan bruke designeren" — which reclaims the
   60-80px of vertical space the always-visible hints used to consume,
   especially valuable on mobile where the cropper card already pushes
   the buy button below the fold. */
.repix-hints-toggle {
    margin-top: 14px;
}

.repix-hints-summary {
    list-style: none;             /* hide native disclosure triangle (Firefox & modern Chrome) */
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    background: #f8fafc;
    border: 1px solid var(--repix-border2);
    border-radius: 8px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--repix-muted);
    -webkit-user-select: none;
    user-select: none;
    transition: background 0.15s ease, border-color 0.15s ease;
}
/* Belt-and-braces marker suppression. Different browsers expose the
   disclosure triangle via different pseudo-elements; we kill all of
   them so only our custom .repix-hints-chevron is visible. Themes
   sometimes also add chevrons via ::after on summary elements globally
   (Botiga, Astra, GeneratePress all do this on accordion blocks) —
   we override those too. */
.repix-hints-summary::-webkit-details-marker { display: none; } /* Safari/old Chrome */
.repix-hints-summary::marker                  { content: ''; }   /* Firefox / modern Chrome */
.repix-hints-summary::before,
.repix-hints-summary::after {
    content: none !important;
    display: none !important;
}
.repix-hints-summary:hover {
    background: #f1f5f4;
    border-color: var(--repix-accent);
}
.repix-hints-icon {
    flex: 0 0 auto;
    color: var(--repix-accent);
}
.repix-hints-summary > span {
    flex: 1 1 auto;
}
.repix-hints-chevron {
    flex: 0 0 auto;
    color: var(--repix-muted);
    transition: transform 0.2s ease;
}
.repix-hints-toggle[open] .repix-hints-chevron {
    transform: rotate(180deg);
}

.repix-hints {
    list-style: none;
    padding: 0;
    margin: 8px 0 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.repix-hints li {
    font-size: 12px;
    color: var(--repix-muted);
    padding: 8px 10px 8px 30px;
    position: relative;
    background: #f8fafc;
    border: 1px solid var(--repix-border2);
    border-radius: 8px;
    line-height: 1.45;
}

/* The bolded "action label" at the start of each hint (e.g. "Endre
   størrelse:"). Gives customers a scannable list — they can find the
   thing they want to do without reading every line. Slightly darker
   than the body text so it reads as a label, not as decoration. */
.repix-hints li strong {
    color: var(--repix-text);
    font-weight: 600;
}

.repix-hints li::before {
    content: "›";
    position: absolute;
    left: 11px;
    top: 5px;
    font-size: 18px;
    font-weight: 700;
    color: var(--repix-accent);
    line-height: 1.3;
}

/* The crop interaction model differs slightly between mouse and touch
   (touch users pan the image directly with one finger; mouse users can
   drag the crop box face). The hints adapt to the input modality the
   user actually has — detected via the `pointer: coarse` media feature,
   which is the standards-compliant way to ask "is this a touch device?"
   without relying on viewport width (a tablet held in landscape can
   still be touch). */
.repix-hint-touch   { display: none; }
@media (pointer: coarse) {
    .repix-hint-desktop { display: none; }
    .repix-hint-touch   { display: list-item; }
}

/* ---------- Cropper.js ---------- */
.cropper-container {
    width: 100% !important;
}

/* ─────────────────────────────────────────────────────────────────────────
   Crop handle ergonomics  (DESKTOP ONLY)
   ─────────────────────────────────────────────────────────────────────────
   Cropper.js's default corner handles are 5×5 px squares with 0.75 opacity.
   On desktop they're hard to spot and even harder to grab — especially
   after the user wheel-zooms the image and the cursor position shifts a
   couple of pixels relative to the handle.

   These overrides apply ONLY on hover-capable (mouse) devices. We
   deliberately do NOT touch the handles on touch devices because:
     - Cropper.js's own positioning uses negative offsets so the handle
       half-overflows the crop box edge to centre on the corner.
     - .repix-preview-wrap has overflow:hidden, so when WE enlarge the
       handles AND keep the negative offsets, the handle's own clip
       interacts badly with the mobile single-column layout where the
       crop box can sit flush against the wrapper edge — causing the
       handles (and apparently the crop lines themselves) to be hidden
       from view on some Android Chrome builds.
     - Touch users primarily move the crop box face, not the corners,
       and Cropper's 5px handles already work fine on touch.

   We:
     1. Make the four corners visibly larger (10×10 px) with a white
        fill, dark border, and subtle shadow so they read clearly
        against any photo content.
     2. Add an invisible ::before that grows the hit-area to ~24×24 px
        so the user doesn't need to land pixel-perfect.
   We do NOT change Cropper's positioning offsets (-3px) — only the
   visible size — to keep the handles working with overflow:hidden on
   the wrap. This means the handle's centre is slightly INSIDE the
   corner of the crop box rather than exactly on it, which is a
   negligible visual difference compared to the original 5×5 handles.
*/
@media (hover: hover) and (pointer: fine) {
    .cropper-point.point-nw,
    .cropper-point.point-ne,
    .cropper-point.point-sw,
    .cropper-point.point-se {
        width: 10px;
        height: 10px;
        background-color: #fff;
        border: 1.5px solid #2c3a36;
        border-radius: 2px;
        opacity: 1;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    }

    /* Invisible hit-area extension. inset:-7px grows the click target
       to ~24×24 px, so the user can grab anywhere near the visible
       handle. Stays inside the negative offsets Cropper set, so it
       extends mostly INTO the crop box (which has no overflow clip),
       not outward (which would clip). */
    .cropper-point.point-nw::before,
    .cropper-point.point-ne::before,
    .cropper-point.point-sw::before,
    .cropper-point.point-se::before {
        content: '';
        position: absolute;
        inset: -7px;
        background: transparent;
    }

    /* Edges: line itself stays at Cropper's 5px width but a ::before
       grows the click hit-area inward by 6px. */
    .cropper-line::before {
        content: '';
        position: absolute;
        inset: -6px;
        background: transparent;
    }
}

/* TOUCH DEVICES: handles need to be MUCH larger to hit reliably with
   a fingertip. Apple's HIG recommends 44pt min; Material says 48dp.
   Cropper's defaults (~5×5) are unusable on touch — the handles are
   technically there but customers can't reliably grab them.

   Visible handle: 14×14 (clearly findable but not so large it dominates
   the crop box on small phones). Invisible hit-area extension via
   ::before grows the touch target to ~40×40 — within HIG range while
   not so big that two corner targets overlap on a small crop box.

   Targeted via `pointer: coarse` (same as the hint-swap) so it applies
   to phones AND touch-screen tablets/laptops, but not to mouse users
   on hi-DPI screens that would otherwise match a viewport-based query. */
@media (pointer: coarse) {
    .cropper-point.point-nw,
    .cropper-point.point-ne,
    .cropper-point.point-sw,
    .cropper-point.point-se {
        width: 14px;
        height: 14px;
        background-color: #fff;
        border: 2px solid #2c3a36;
        border-radius: 3px;
        opacity: 1;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
    }

    /* ~40×40 invisible hit zone around each visible corner. inset:-13px
       expands outward AND inward from the 14×14 visible handle so a
       fingertip lands on the handle even with imprecise aim. */
    .cropper-point.point-nw::before,
    .cropper-point.point-ne::before,
    .cropper-point.point-sw::before,
    .cropper-point.point-se::before {
        content: '';
        position: absolute;
        inset: -13px;
        background: transparent;
    }

    /* Cropper's edge "lines" are also touch-resize handles on the
       midpoints. Grow their hit area too. The line itself stays
       visually thin — the bigger zone is the ::before pseudo. */
    .cropper-line::before {
        content: '';
        position: absolute;
        inset: -12px;
        background: transparent;
    }

    /* TOUCH MOVE HANDLE (the centre grab indicator)
       --------------------------------------------
       On touch, the crop-box face is configured as non-draggable so a
       finger landing on it pans the image. The centre indicator becomes
       the explicit "grab the frame" handle — small enough not to
       interfere with image panning, big enough to be a clear touch
       target, visually obvious as a button. We render a HAND icon
       (open-palm "grab") instead of a "+" because customers intuit
       "drag me" much faster from a hand than from a generic plus.

       IMPORTANT: In Cropper's DOM, .cropper-face comes AFTER .cropper-center
       in document order, so by default the face sits visually ABOVE the
       centre marker and intercepts all touches that would otherwise reach
       it. We need z-index:10 (above the face) AND explicit pointer-events
       so our pointerdown listener actually fires. */
    .cropper-center.repix-move-handle {
        width: 40px;
        height: 40px;
        margin: 0;
        transform: translate(-50%, -50%);
        background-color: rgba(255, 255, 255, 0.96);
        /* Inline SVG of an open-hand "move" icon (4-arrow + palm in a single
           glyph would be too busy at this size — a clean hand reads best).
           Stroke colour matches the handle border for a unified look. */
        background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232c3a36' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 11V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2'/%3E%3Cpath d='M14 10V4a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v6'/%3E%3Cpath d='M10 10.5V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v8'/%3E%3Cpath d='M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: center;
        background-size: 22px 22px;
        border: 1.5px solid #2c3a36;
        border-radius: 50%;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
        opacity: 1;
        cursor: grab;
        z-index: 10;
        pointer-events: auto;
        touch-action: none; /* let our pointer handlers run uninterrupted */
    }
    /* Cropper's default ::before / ::after draw a small "+" cross we no
       longer want — we have an SVG hand instead. Hide them. */
    .cropper-center.repix-move-handle::before,
    .cropper-center.repix-move-handle::after {
        display: none;
    }
    .cropper-center.repix-move-handle:active {
        cursor: grabbing;
        background-color: #f4f7f5;
    }
}

/* ---------- Responsive ---------- */
@media (max-width: 991px) {
    .repix-designer {
        grid-template-columns: 1fr;
        padding: 14px;
        gap: 14px;
    }

    .repix-designer-left {
        position: static;
        order: 1;
        padding: 16px;
    }

    .repix-designer-right {
        order: 2;
        padding: 14px;
    }

    .repix-preview-wrap {
        min-height: 260px;
    }

    /* Force the cropper container to own all gestures inside it on
       touch. Cropper's own CSS already sets touch-action:none on
       .cropper-container, but some themes / parent elements set
       touch-action:auto further up the tree, which can re-enable
       browser pan/zoom and create double-handling that makes the
       crop drag feel laggy or "stuck". Belt-and-braces. */
    .repix-preview-wrap,
    .repix-preview-wrap .cropper-container {
        touch-action: none;
    }

    .repix-designer-left h3,
    .repix-designer-right h3 {
        font-size: 15px;
    }

    /* When .repix-actions is moved below the cropper on mobile (by
       setupResponsiveActions() in designer.js), it needs to look like
       its own panel to match the white-card visual rhythm of the left
       and right columns. Drops the top-border separator that only made
       sense when it lived inside the left column, and gains the same
       white-card chrome the other blocks already have.

       CRITICAL: .repix-designer is a grid with .repix-designer-left set
       to `order:1` and .repix-designer-right set to `order:2` (mobile
       block at line ~1002 of this file). When JS moves .repix-actions
       to become a grid sibling, it lands with the default `order:0`
       and renders BEFORE both — which puts the buy button at the very
       top of the page. Setting `order:3` correctly places it last,
       below the cropper as intended.

       Width clamps (min-width:0, max-width:100%) protect against the
       relocated qty input or buy-button SVG reporting a larger natural
       width than the column, which would horizontally push the whole
       grid on mobile and cause the "content drifts to the right" bug. */
    .repix-actions.repix-actions--mobile-bottom {
        order: 3;
        background: #fff;
        border: 1px solid var(--repix-border);
        border-radius: var(--repix-radius);
        padding: 16px;
        margin-top: 0;
        border-top: 1px solid var(--repix-border);
        min-width: 0;
        max-width: 100%;
        box-sizing: border-box;
    }
    .repix-actions.repix-actions--mobile-bottom > * {
        min-width: 0;
        max-width: 100%;
    }
}

@media (max-width: 600px) {
    .repix-designer {
        padding: 10px;
        gap: 10px;
        border-radius: 14px;
    }

    .repix-designer-left,
    .repix-designer-right {
        padding: 14px;
        border-radius: 12px;
    }

    /* Larger upload zone on small screens */
    .repix-upload-zone {
        padding: 28px 16px 22px;
    }

    /* Bigger touch target on select */
    .repix-designer select {
        min-height: 52px;
        font-size: 16px; /* prevents iOS zoom */
        padding: 14px 42px 14px 14px;
    }

    /* Full-width pill upload button */
    .repix-upload-btn {
        width: 100%;
        padding: 12px 20px;
        font-size: 15px;
    }

    /* Taller add-to-cart on mobile — match qty wrap height (50px on mobile) */
    .repix-add-to-cart.button.alt {
        height: 50px;
        padding: 0 20px !important;
        font-size: 16px !important;
        border-radius: 14px !important;
    }
    /* Match qty wrap height on mobile too */
    .repix-qty-wrap,
    .repix-qty-wrap .quantity input.qty,
    .repix-qty-wrap .quantity .botiga-quantity-minus,
    .repix-qty-wrap .quantity .botiga-quantity-plus,
    .repix-qty-wrap .quantity .minus,
    .repix-qty-wrap .quantity .plus {
        height: 50px;
    }

    /* Orientation cards – a bit taller for touch */
    .repix-ori-card {
        padding: 18px 8px 16px;
    }

    .repix-ori-icon {
        width: 40px;
    }

    .repix-ori-icon--portrait {
        width: 28px;
    }

    /* Product toggle full width */
    .repix-product-toggle {
        max-width: none;
    }

    .repix-toggle-btn {
        padding: 12px 6px;
        font-size: 12px;
        gap: 4px;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Quality row slightly smaller on tiny screens */
    .repix-quality {
        font-size: 12px;
    }
}

/* ---------- Sveveramme toggle ---------- */
.repix-frame-row {
    margin: 0 0 4px;
}

/* Label = full-width flex row: text LEFT, switch RIGHT */
.repix-frame-toggle-label {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    padding: 11px 14px;
    border: 1.5px solid var(--repix-border);
    border-radius: 10px;
    background: #f8fafc;
    transition: border-color .15s, background .15s;
    width: 100%;
    box-sizing: border-box;
    margin: 0 !important;
    float: none !important;
}
@media (hover: hover) {
.repix-frame-toggle-label:hover {
    border-color: var(--repix-accent);
    background: var(--repix-accent-soft);
}
}
.repix-frame-toggle-label.is-checked {
    border-color: var(--repix-accent);
    background: var(--repix-accent-soft);
}

/* Hide real checkbox */
.repix-frame-checkbox,
.repix-paper-checkbox,
.repix-oppheng-checkbox,
.repix-ferdig-innrammet-checkbox {
    position: absolute !important;
    opacity: 0 !important;
    width: 0 !important;
    height: 0 !important;
    pointer-events: none !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* Text block — grows to fill space */
.repix-frame-toggle-text {
    flex: 1 1 auto;
    display: flex !important;
    flex-direction: row !important;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}
.repix-frame-toggle-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--repix-text);
    line-height: 1.2;
}
.repix-frame-toggle-sub {
    font-size: 12px;
    color: var(--repix-accent-2);
    font-weight: 700;
}

/* Toggle switch — sits on the RIGHT, never shrinks */
.repix-frame-toggle-track {
    flex: 0 0 auto;
    width: 40px;
    height: 22px;
    background: #cbd5e1;
    border-radius: 999px;
    position: relative;
    transition: background .2s ease;
    margin-left: auto;
}
.repix-frame-toggle-label.is-checked .repix-frame-toggle-track {
    background: var(--repix-accent);
}
.repix-frame-toggle-thumb {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0,0,0,.25);
    transition: transform .2s ease;
}
.repix-frame-toggle-label.is-checked .repix-frame-toggle-thumb {
    transform: translateX(18px);
}

/* Colour picker panel */
.repix-frame-colors {
    margin-top: 8px;
    padding: 10px 12px;
    background: var(--repix-accent-soft);
    border: 1.5px solid var(--repix-accent);
    border-radius: 10px;
}
.repix-frame-colors .repix-label-sm {
    margin: 0 0 8px;
    color: var(--repix-accent-2);
}
.repix-frame-color-btns {
    display: flex;
    gap: 6px;
}
.repix-frame-color-btn {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 6px;
    border: 1.5px solid rgba(0,0,0,.1);
    border-radius: 8px;
    background: rgba(255,255,255,.7);
    color: var(--repix-muted);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s, background .15s, box-shadow .15s, transform .1s;
}
@media (hover: hover) {
.repix-frame-color-btn:hover {
    background: #fff;
    color: var(--repix-text);
    transform: translateY(-1px);
    box-shadow: 0 3px 8px rgba(0,0,0,.1);
}
}
.repix-frame-color-btn.active {
    background: #fff;
    color: var(--repix-text);
    border-color: var(--repix-accent);
    box-shadow: 0 0 0 2px rgba(106, 142, 135,.25);
}
.repix-frame-color-dot {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 1px 3px rgba(0,0,0,.15);
}

/* ---------- Frame overlay on preview ---------- */
.repix-frame-overlay {
    position: absolute;
    pointer-events: none;
    box-sizing: border-box;
    z-index: 100;
    border-radius: 3px;
}

/* ---------- Preview button ---------- */
.repix-preview-btn {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 11px 16px;
    border: 1.5px solid var(--repix-accent);
    border-radius: 12px;
    background: transparent;
    color: var(--repix-accent-2);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s, color .15s, box-shadow .15s;
}
@media (hover: hover) {
.repix-preview-btn:hover {
    background: var(--repix-accent-soft);
    box-shadow: 0 3px 10px rgba(106, 142, 135,.2);
}
}
.repix-preview-btn:disabled {
    opacity: .4;
    cursor: not-allowed;
    box-shadow: none;
    pointer-events: none;
}

/* ---------- Preview modal ---------- */
.repix-modal {
    position: fixed !important;
    inset: 0 !important;
    z-index: 999999 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 16px;
    box-sizing: border-box;
}
.repix-modal[hidden] { display: none !important; }

.repix-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(44, 58, 54, .72);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.repix-modal-box {
    position: relative;
    background: #fff;
    border-radius: 20px;
    box-shadow: 0 32px 80px rgba(0,0,0,.35);
    max-width: 900px;
    width: 100%;
    max-height: 92vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    animation: repix-modal-in .22s cubic-bezier(.34,1.56,.64,1);
}

@keyframes repix-modal-in {
    from { opacity: 0; transform: scale(.93) translateY(14px); }
    to   { opacity: 1; transform: scale(1)   translateY(0); }
}

.repix-modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 34px;
    height: 34px;
    border: none;
    background: rgba(255,255,255,.9);
    border-radius: 50%;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    color: var(--repix-muted);
    display: flex !important;
    align-items: center;
    justify-content: center;
    transition: background .15s, color .15s;
    z-index: 10;
    box-shadow: 0 2px 8px rgba(0,0,0,.15);
}
@media (hover: hover) {
.repix-modal-close:hover {
    background: #fff;
    color: var(--repix-text);
}
}

.repix-modal-inner {
    display: grid;
    grid-template-columns: 1fr 230px;
    min-height: 0;
    flex: 1;
}

/* Canvas stage — warm wall background with light */
.repix-modal-stage {
    background: #ddd8d2;
    background-image:
        radial-gradient(ellipse 80% 60% at 35% 30%, rgba(255,255,255,.35) 0%, transparent 70%),
        radial-gradient(ellipse 60% 70% at 75% 80%, rgba(0,0,0,.12) 0%, transparent 60%);
    min-height: 360px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 40px;
    overflow: hidden;
}

/* Simulated canvas product with depth shadow */
.repix-modal-product {
    position: relative;
    box-shadow:
        2px 4px 0 rgba(0,0,0,.15),
        6px 10px 20px rgba(0,0,0,.22),
        12px 20px 48px rgba(0,0,0,.18);
    border-radius: 2px;
    max-width: 100%;
    max-height: 55vh;
    /* subtle left-top highlight like a real canvas on wall */
    outline: 1px solid rgba(255,255,255,.25);
    outline-offset: -1px;
}

.repix-modal-canvas {
    display: block;
    max-width: 100%;
    /* Fallback for older browsers that don't understand dvh.
       55vh on iOS Safari is calculated against the viewport with the
       URL bar COLLAPSED, so when the URL bar is visible the canvas
       overflows the modal. dvh (dynamic viewport height) reflects the
       currently-visible viewport and updates as the URL bar shows/
       hides. Supported in iOS 15.4+ and Chrome 108+ — older browsers
       use the vh line above and accept the (rare) slight overflow. */
    max-height: 55vh;
    max-height: 55dvh;
    object-fit: contain;
    border-radius: 2px;
}

.repix-modal-frame-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: 3px;
    box-sizing: border-box;
}

/* Info sidebar */
.repix-modal-info {
    padding: 32px 22px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    border-left: 1px solid var(--repix-border2);
    background: #fff;
    overflow-y: auto;
}

.repix-modal-info::before {
    content: 'Forhåndsvisning';
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .7px;
    color: var(--repix-muted2);
    margin-bottom: 4px;
}

.repix-modal-title {
    font-size: 16px;
    font-weight: 700;
    color: var(--repix-text);
    margin: 0;
    line-height: 1.35;
}

.repix-modal-price {
    font-size: 26px;
    font-weight: 800;
    color: var(--repix-accent-2);
    margin: 0;
    line-height: 1.1;
}

.repix-modal-details {
    font-size: 13px;
    font-weight: 500;
    color: var(--repix-muted);
    margin: 0;
    line-height: 1.5;
}

.repix-modal-details span {
    display: block;
}
.repix-modal-details span + span {
    margin-top: 2px;
}

/* Quantity row */
.repix-modal-qty-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 4px;
}
.repix-modal-qty-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--repix-text);
}
.repix-modal-qty {
    display: inline-flex;
    align-items: center;
    height: 44px;
    background: #fff;
    border: 1px solid var(--nf-border-soft, #ece7e5);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: var(--nf-shadow-sm, 0 4px 14px rgba(0, 0, 0, 0.04));
}
.repix-modal-qty-minus,
.repix-modal-qty-plus {
    width: 38px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--nf-bg-surface, #f4f7f6);
    color: #4a5d57;
    font-size: 18px;
    font-weight: 600;
    border: 0;
    cursor: pointer;
    padding: 0;
    line-height: 1;
    transition: background 0.2s ease, color 0.2s ease;
}
@media (hover: hover) {
    .repix-modal-qty-minus:hover,
    .repix-modal-qty-plus:hover {
        background: #e9efed;
        color: #2c3a36;
    }
}
.repix-modal-qty-minus:disabled {
    opacity: .45;
    cursor: not-allowed;
}
.repix-modal-qty-input {
    width: 44px;
    height: 44px;
    border: 0;
    background: #fff;
    text-align: center;
    font-size: 15px;
    font-weight: 600;
    color: var(--nf-heading, #222);
    padding: 0;
    margin: 0;
    box-shadow: none !important;
    appearance: textfield;
    -moz-appearance: textfield;
    font-family: var(--nf-font, inherit);
}
.repix-modal-qty-input::-webkit-outer-spin-button,
.repix-modal-qty-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.repix-modal-qty-input:focus {
    outline: none;
}

.repix-modal-unit-hint {
    margin: 0;
    font-size: 12px;
    color: var(--repix-muted);
}
.repix-modal-unit-hint[hidden] { display: none; }

.repix-modal-confirm {
    margin-top: auto;
    width: 100%;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 8px;
    border-radius: 14px !important;
    padding: 14px 16px !important;
    font-size: 14px !important;
    font-weight: 700 !important;
    letter-spacing: .2px;
    border: none !important;
    background: linear-gradient(160deg, var(--repix-accent), var(--repix-accent-2)) !important;
    color: #fff !important;
    box-shadow: 0 8px 20px rgba(106, 142, 135,.38) !important;
    cursor: pointer;
    transition: filter .15s, transform .1s, box-shadow .15s;
}
@media (hover: hover) {
.repix-modal-confirm:hover {
    filter: brightness(1.06);
    transform: translateY(-1px);
    box-shadow: 0 12px 24px rgba(106, 142, 135,.45) !important;
}
}

@media (max-width: 640px) {
    .repix-modal-inner {
        grid-template-columns: 1fr;
    }
    .repix-modal-info {
        border-left: none;
        border-top: 1px solid var(--repix-border2);
        padding: 16px 18px;
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    .repix-modal-info::before { display: none; }
    .repix-modal-confirm { margin-top: 4px; }
    .repix-modal-qty-row { margin-top: 0; }
    .repix-modal-stage {
        padding: 28px 20px;
        min-height: 220px;
    }
}

/* ─────────────────────────────────────────────────────────────────────────
   Enlargement paper picker (radio cards)
   ─────────────────────────────────────────────────────────────────────────
   Mobile-first: each paper stacks on its own row for easy tap targets.
   At 480px+ viewports, cards grid into 2 columns so the 4 papers fit
   without excessive vertical scroll on tablet/desktop.
*/
.repix-paper-cards-row .repix-label-sm {
    display: block;
    margin: 0 0 8px;
    font-weight: 600;
    font-size: 13px;
    color: #2a2a2a;
}
.repix-paper-cards {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
}
.repix-paper-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2px;
    min-height: 54px;
    padding: 10px 14px;
    background: #fff;
    border: 1.5px solid var(--repix-border);
    border-radius: 8px;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
    text-align: left;
    font: inherit;
    color: inherit;
    -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) {
.repix-paper-card:hover {
    border-color: var(--repix-accent);
    background: var(--repix-accent-softer);
}
}
.repix-paper-card.active {
    border-color: var(--repix-accent);
    background: var(--repix-accent-softer);
    box-shadow: 0 0 0 1px var(--repix-accent) inset;
}
.repix-paper-card-name {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.25;
    color: var(--repix-text);
}
.repix-paper-card-price {
    font-size: 12px;
    color: var(--repix-muted);
    font-weight: 500;
}
.repix-paper-card.active .repix-paper-card-price {
    color: var(--repix-accent-2);
}

@media (min-width: 480px) {
    .repix-paper-cards { grid-template-columns: 1fr 1fr; gap: 10px; }
}

/* ─────────────────────────────────────────────────────────────────────
   Campaign badge — rendered next to the price inside the designer when
   an active campaign applies to the currently-selected size. Label text
   comes from the admin (custom text + optional "-XX%" suffix).

   Kept visually loud (red fill, rounded) because its whole job is to
   catch the eye at the moment of the buying decision. Scales down on
   mobile to avoid wrapping the price line.
   ──────────────────────────────────────────────────────────────────── */
.repix-campaign-badge {
    display: inline-block;
    vertical-align: middle;
    margin-left: 8px;
    padding: 3px 9px;
    background: #d63638;
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.02em;
    border-radius: 999px;
    white-space: nowrap;
    text-transform: uppercase;
}
@media (max-width: 480px) {
    .repix-campaign-badge {
        font-size: 11px;
        padding: 2px 7px;
        margin-left: 6px;
    }
}

/* ─────────────────────────────────────────────────────────────────────────
   Mobile / Android Chrome flicker mitigation
   ─────────────────────────────────────────────────────────────────────────
   These rules address a small set of known repaint triggers that show up
   as "flicker on scroll" on Android (Samsung S25, Pixel, etc.). Each rule
   is scoped to the designer's own elements so it doesn't leak into the
   surrounding theme.
*/

/* 1. Prevent Android from auto-resizing fonts when the URL bar shows or
      hides on scroll — that resize causes a layout reflow which can
      flicker through the page. iOS already gets this via the meta-
      viewport setting; Android needs the CSS hint. */
.repix-designer,
.repix-designer-wrapper {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* 2. Promote the cropper preview to its own compositor layer. This stops
      paints inside the cropper (image, crop box, fold/bleed shades, frame
      overlay, all of which reposition during user interaction) from
      cascading repaints out into surrounding elements as the URL bar
      shows/hides during scroll. translateZ(0) is the universally-
      supported way to do this; will-change is more modern but reserves
      memory eagerly which we don't need here. */
.repix-preview-wrap {
    transform: translateZ(0);
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
}

/* 3. Disable any tap-highlight color flash on Android. Default is a
      semi-transparent grey rectangle that flashes briefly on tap, which
      reads as a "flicker" especially on cards that already have their
      own active styling. */
.repix-designer button,
.repix-designer .repix-upload-zone,
.repix-designer .repix-ori-card,
.repix-designer .repix-frame-color-btn,
.repix-designer .repix-paper-card,
.repix-designer .repix-toggle-btn {
    -webkit-tap-highlight-color: transparent;
}

/* ────────────────────────────────────────────────────────────────────
   Mobile upload via QR — button + pairing modal.
   The "Last opp fra mobil" trigger sits directly below the upload zone
   so customers see it as an obvious alternative to "Velg fil". The
   modal mimics the existing .repix-modal visual language so the two
   feel like siblings.
   ──────────────────────────────────────────────────────────────────── */

.repix-mobile-upload-trigger {
    appearance: none;
    -webkit-appearance: none;
    background: #fff;
    border: 1px solid #d8e3df;
    border-radius: 10px;
    padding: 11px 14px;
    margin-top: 12px;
    margin-bottom: 24px;
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: #2c3a36;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.repix-mobile-upload-trigger:hover {
    border-color: #6a8e87;
    color: #1a201e;
    background: #f8fbfa;
}
.repix-mobile-upload-trigger svg { color: #6a8e87; flex: 0 0 auto; }
.repix-mobile-upload-trigger:focus-visible {
    outline: 2px solid #6a8e87;
    outline-offset: 2px;
}

.repix-qr-modal {
    position: fixed;
    inset: 0;
    z-index: 100050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.repix-qr-modal[hidden] { display: none; }
.repix-qr-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 24, 22, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.repix-qr-box {
    position: relative;
    z-index: 1;
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.25);
    padding: 28px 28px 24px;
    max-width: 420px;
    width: 100%;
    text-align: center;
    animation: repix-qr-fadein .2s ease;
}
@keyframes repix-qr-fadein {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.repix-qr-close {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 32px;
    height: 32px;
    border: 1px solid #d8e3df;
    background: #fff;
    color: #5a6864;
    border-radius: 50%;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.repix-qr-close:hover {
    background: #6a8e87;
    color: #fff;
    border-color: #6a8e87;
}
.repix-qr-title {
    font-size: 19px;
    font-weight: 700;
    color: #1a201e;
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}
.repix-qr-sub {
    font-size: 14px;
    color: #5a6864;
    margin: 0 0 18px;
    line-height: 1.55;
}
.repix-qr-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 0 18px;
}
.repix-qr-canvas-wrap {
    position: relative;
    width: 240px;
    height: 240px;
    background: #f4f7f5;
    border: 1px solid #d8e3df;
    border-radius: 12px;
    padding: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.repix-qr-canvas { display: inline-block; }
.repix-qr-canvas img,
.repix-qr-canvas canvas {
    display: block;
    width: 100%;
    height: 100%;
}
.repix-qr-spinner {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-size: 13px;
    color: #5a6864;
    background: #f4f7f5;
    border-radius: 12px;
}
.repix-qr-spin {
    width: 28px;
    height: 28px;
    border: 3px solid #d8e3df;
    border-top-color: #6a8e87;
    border-radius: 50%;
    animation: repix-qr-spin 0.8s linear infinite;
}
@keyframes repix-qr-spin {
    to { transform: rotate(360deg); }
}
.repix-qr-fallback {
    font-size: 12.5px;
    color: #5a6864;
    margin: 0 0 14px;
    word-break: break-all;
}
.repix-qr-fallback-label { display: block; margin-bottom: 4px; }
.repix-qr-fallback-link {
    color: #6a8e87;
    text-decoration: underline;
    font-weight: 600;
}
.repix-qr-status {
    font-size: 13.5px;
    color: #5a6864;
    background: #f4f7f5;
    border: 1px solid #d8e3df;
    border-radius: 8px;
    padding: 10px 12px;
}
.repix-qr-status.is-success {
    color: #1f5e44;
    background: #e8f3ee;
    border-color: #cfe5d8;
}
.repix-qr-status.is-error {
    color: #8a2a2a;
    background: #fdecec;
    border-color: #f4cccc;
}

@media (max-width: 480px) {
    .repix-qr-box { padding: 22px 18px 18px; }
    .repix-qr-canvas-wrap { width: 220px; height: 220px; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Fit/fill toggle ("Bildetilpasning")
   ───────────────────────────────────────────────────────────────────────────
   Two-button pill placed at the top of the right column above the preview.
   Visually echoes .repix-product-toggle so customers recognize it as a
   modal-choice control. Hidden by JS for products that don't support fit
   mode (currently alu).
*/
.repix-fit-toggle {
    display: flex;
    gap: 0;
    margin: 0 0 12px;
    background: var(--repix-border2);
    padding: 4px;
    border-radius: 12px;
    border: 1px solid var(--repix-border);
    width: 100%;
}

.repix-fit-btn {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 9px 12px;
    border: none;
    background: transparent;
    border-radius: 9px;
    color: var(--repix-muted);
    font-weight: 600;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, box-shadow .18s ease;
    font-size: 14px;
    letter-spacing: .2px;
    white-space: nowrap;
}

@media (hover: hover) {
    .repix-fit-btn:hover {
        color: var(--repix-accent-2);
    }
}

.repix-fit-btn.is-active {
    background: #fff;
    color: var(--repix-accent-2);
    box-shadow: 0 2px 8px rgba(44, 58, 54, .12);
}

.repix-fit-btn svg {
    flex-shrink: 0;
}

/* ───────────────────────────────────────────────────────────────────────────
   Fit-mode auto-suggest hint
   ───────────────────────────────────────────────────────────────────────────
   Soft inline informational line. Shown when the uploaded image's aspect
   ratio is significantly different from the selected canvas, suggesting
   the customer might want fit mode. No close button, no banner styling —
   intentionally subtle so it doesn't pressure the customer's choice.
*/
.repix-fit-hint {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    margin: 0 0 12px;
    background: var(--repix-accent-softer);
    border: 1px solid var(--repix-accent-light);
    border-radius: 10px;
    color: var(--repix-accent-2);
    font-size: 13px;
    line-height: 1.4;
}

.repix-fit-hint svg {
    flex-shrink: 0;
    margin-top: 1px;
    opacity: .8;
}

.repix-fit-hint-text {
    flex: 1;
}

/* ───────────────────────────────────────────────────────────────────────────
   Fit-mode preview canvas
   ───────────────────────────────────────────────────────────────────────────
   Drawn when fitMode === 'fit'. Sits inside .repix-preview-wrap as a
   sibling to the cropper's <img>. The canvas paints a white background +
   the source image scaled to fit, so the customer sees exactly what will
   print (image + white borders). The Cropper.js DOM is hidden via JS in
   this mode.

   CRITICAL: do NOT set width:100% + height:auto + max-height here. That
   combination silently breaks aspect ratio: max-height clamps the
   display height while width stays at 100%, so the browser stretches
   the canvas's backing buffer to fill the non-matching display box.
   For a square 60×60 canvas the result is a landscape preview with
   the image visibly squashed and the white letterbox bars compressed
   out of visibility — exactly the bug v0.16.1 had in production.

   We instead let JS pick explicit display width/height that maintain
   the canvas's intrinsic backing ratio while fitting inside the wrap.
*/
.repix-fit-preview {
    display: block;
    background: transparent;
}

/* When fit mode is active, hide the cropper container so only the fit
   preview shows. We rely on a state class on the wrap rather than toggling
   `hidden` directly, because Cropper.js measures its container — if we
   hide via [hidden] it can mis-measure on the way back to fill mode. */
.repix-preview-wrap.is-fit-mode .repix-preview,
.repix-preview-wrap.is-fit-mode .cropper-container {
    display: none !important;
}

.repix-preview-wrap.is-fit-mode .repix-fit-preview {
    display: block;
}

/* Fit-mode information panel shown inside the preview wrap. Tells
   the customer what to expect — white edges on the face, white wrap
   on canvas products, auto-centering, and how to switch back to a
   movable crop. Content is populated from JS so it can adapt to the
   product type (canvas vs Fotopapir). */
.repix-fit-info {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--repix-accent-softer);
    border: 1px solid var(--repix-accent-light);
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--repix-muted);
}
.repix-fit-info svg {
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--repix-accent-2);
    opacity: .85;
}
.repix-fit-info-list {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
}
.repix-fit-info-list li {
    position: relative;
    padding-left: 14px;
    margin: 0 0 4px;
}
.repix-fit-info-list li:last-child {
    margin-bottom: 0;
}
.repix-fit-info-list li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 9px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--repix-accent);
    opacity: .65;
}
.repix-fit-info-list strong {
    font-weight: 600;
    color: var(--repix-muted);
}
