/* Unified WooCommerce loop cards: homepage, shop, sale and category archives.
   This intentionally affects catalogue cards only, never the single-product UI. */
body.kajo-catalogue .wd-product{
    min-width: 0 !important;
    height: 100% !important;}

/* Stable glass finish for the variable-product selector. */
.kajo-loop-options-modal{ opacity: 0; pointer-events: none; visibility: hidden; transition: opacity .24s ease, visibility 0s linear .24s;}
.kajo-loop-options-modal.is-open{ opacity: 1; pointer-events: auto; visibility: visible; transition: opacity .24s ease;}
.kajo-loop-options-modal.is-closing{ opacity: 0; pointer-events: none; visibility: hidden;}
.kajo-loop-options-backdrop{ margin: 0; padding: 0; border: 0 !important; border-radius: 0 !important; background: rgba(6, 21, 37, .36) !important; box-shadow: none !important; color: transparent !important; cursor: default; opacity: 1 !important; -webkit-backdrop-filter: blur(14px) saturate(115%); backdrop-filter: blur(14px) saturate(115%);}
.kajo-loop-options-backdrop:hover,

.kajo-loop-options-backdrop:focus,

.kajo-loop-options-backdrop:active{ background: rgba(6, 21, 37, .36) !important;}
.kajo-loop-options-dialog{ border: 1px solid rgba(255, 255, 255, .7); border-radius: 22px; background: linear-gradient(135deg, rgba(255, 255, 255, .82), rgba(237, 244, 232, .66)); box-shadow: 0 28px 70px rgba(6, 21, 37, .3); -webkit-backdrop-filter: blur(22px) saturate(125%); backdrop-filter: blur(22px) saturate(125%); transition: opacity .2s ease, transform .28s cubic-bezier(.2, .8, .2, 1);}
.kajo-loop-options-modal.is-open .kajo-loop-options-dialog{ opacity: 1; transform: translateY(0) scale(1);}
.kajo-loop-options-modal.is-closing .kajo-loop-options-dialog{ opacity: 0; transform: translateY(14px) scale(.985);}
.kajo-loop-options-close{ width: 42px; height: 42px; min-width: 42px; min-height: 42px; padding: 0; border: 0 !important; border-radius: 50% !important; background: rgba(255, 255, 255, .48) !important; box-shadow: 0 8px 20px rgba(6, 21, 37, .1); color: transparent !important; font-size: 0 !important; transition: background-color .2s ease, box-shadow .2s ease, transform .28s cubic-bezier(.2, .8, .2, 1);}
.kajo-loop-options-close::before,

.kajo-loop-options-close::after{ position: absolute; width: 17px; height: 2px; border-radius: 99px; background: #061525; content: ""; transition: background-color .2s ease;}
.kajo-loop-options-close::before{ transform: rotate(45deg);}
.kajo-loop-options-close::after{ transform: rotate(-45deg);}
.kajo-loop-options-close:hover{ background: #f58634 !important; box-shadow: 0 10px 24px rgba(216, 141, 75, .35); transform: rotate(90deg) scale(.94);}
.kajo-loop-options-close:hover::before,

.kajo-loop-options-close:hover::after{ background: #fffaf3;}
.kajo-loop-options-close:focus-visible{ outline: 2px solid #f58634; outline-offset: 3px;}
.kajo-loop-options-product{ padding-inline-end: 62px; background: rgba(255, 255, 255, .26);}
.kajo-loop-options-image{ border: 1px solid rgba(255, 255, 255, .56); border-radius: 12px; background: rgba(255, 255, 255, .52);}
.kajo-loop-options-pill{ background: rgba(255, 255, 255, .6);}
.kajo-loop-options-pill.kajo-variation-color{ position: relative; isolation: isolate; width: 30px; min-width: 30px; height: 30px; min-height: 30px; overflow: hidden; border: 2px solid rgba(255, 255, 255, .9) !important; box-shadow: 0 0 0 1px rgba(6, 21, 37, .2) !important;}
.kajo-loop-options-pill.kajo-variation-color::before{ display: none !important; content: none !important;}
.kajo-loop-options-pill.kajo-variation-color.is-selected{ box-shadow: 0 0 0 2px #6f875f, 0 0 0 4px rgba(111, 135, 95, .26) !important;}
.kajo-loop-options-pill.kajo-variation-color.is-selected::after{ position: absolute; z-index: 2; inset: 0; display: grid; background: rgba(6, 21, 37, .22); color: #fff; content: "\2713"; font-size: 15px; font-weight: 800; line-height: 1; place-items: center; text-shadow: 0 1px 2px rgba(6, 21, 37, .5);}
.kajo-loop-options-view{ background: rgba(255, 255, 255, .52);}
@media (max-width: 767px) {
    .kajo-loop-options-close{ top: 10px; right: 12px; width: 40px; height: 40px; min-width: 40px; min-height: 40px;}
    .kajo-loop-options-product{ padding-inline-end: 56px;}
    .kajo-loop-options-copy h2{ font-size: 17px !important; line-height: 1.18 !important;}
    .kajo-loop-options-actions{ grid-template-columns: .95fr 1.55fr; gap: 8px; padding: 16px 18px 18px;}
    .kajo-loop-options-actions > *{ min-height: 44px; padding-inline: 12px; font-size: 11px; white-space: nowrap;}}

body.kajo-catalogue .wd-product .product-wrapper{
    position: relative !important;
    display: flex !important;
    height: 100% !important;
    min-height: 0 !important;
    overflow: hidden !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: #ffffff !important;
    box-shadow: none !important;}

body.kajo-catalogue .wd-product .product-element-top{
    position: relative !important;
    flex: 0 0 auto !important;
    width: 100% !important;
    min-height: 0 !important;
    aspect-ratio: 1 / 1 !important;
    overflow: hidden !important;
    background: #f7f7f5 !important;}

body.kajo-catalogue .wd-product .wd-product-img-link{
    display: block !important;
    width: 100% !important;
    height: 100% !important;}

body.kajo-catalogue .wd-product .product-element-top > .wd-product-img-link > img{
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    max-height: none !important;
    padding: clamp(12px, 2vw, 28px) !important;
    object-fit: contain !important;
    transition: transform .28s ease !important;}

body.kajo-catalogue .wd-product:hover .product-element-top > .wd-product-img-link > img{
    transform: scale(1.025) !important;}

/* The reference uses one clean primary image rather than a hover image swap. */
body.kajo-catalogue .wd-product .wd-product-img-hover,

body.kajo-catalogue .wd-product .wd-action-buttons,

body.kajo-catalogue .wd-product .wd-quick-view-btn{
    display: none !important;}

/* Sale/featured markers stay inside the image at top left. */
body.kajo-catalogue .wd-product .product-labels,

body.kajo-catalogue .wd-product .kajo-sale-hot-labels{
    position: absolute !important;
    top: 12px !important;
    inset-inline-end: auto !important;
    bottom: auto !important;
    inset-inline-start: 12px !important;
    z-index: 5 !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 5px !important;
    margin: 0 !important;
    padding: 0 !important;}

body.kajo-catalogue .wd-product .product-labels .product-label,


body.kajo-catalogue .wd-product .kajo-sale-hot-label{
    min-height: 24px !important;
    margin: 0 !important;
    padding: 0 9px !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: #f58634 !important;
    color: #ffffff !important;
    font-size: 11px !important;
    font-weight: 800 !important;
    line-height: 24px !important;}

/* Wishlist is the only image action, placed like the supplied reference. */
body.kajo-catalogue .wd-product .wd-buttons.wd-pos-r-t{
    position: absolute !important;
    top: 10px !important;
    inset-inline-end: 10px !important;
    bottom: auto !important;
    inset-inline-start: auto !important;
    z-index: 7 !important;}

body.kajo-catalogue .wd-product .wd-wishlist-btn a{
    display: grid !important;
    width: 34px !important;
    min-width: 34px !important;
    height: 34px !important;
    min-height: 34px !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 50% !important;
    background: transparent !important;
    color: #7b805e !important;
    box-shadow: none !important;
    place-items: center !important;}

body.kajo-catalogue .wd-product .wd-wishlist-btn a:hover,


body.kajo-catalogue .wd-product .wd-wishlist-btn a:focus-visible{
    color: #f58634 !important;}

/* Stock sits neatly below the heart and remains dynamic per WooCommerce state. */
body.kajo-catalogue .wd-product .kajo-image-stock-badge,

body.kajo-catalogue .wd-product .wd-product-stock{
    position: absolute !important;
    top: 46px !important;
    inset-inline-end: 10px !important;
    bottom: auto !important;
    inset-inline-start: auto !important;
    z-index: 6 !important;
    display: inline-flex !important;
    min-height: 21px !important;
    align-items: center !important;
    margin: 0 !important;
    padding: 0 8px !important;
    border: 0 !important;
    border-radius: 999px !important;
    background: #edf3e8 !important;
    color: #557145 !important;
    font-size: 9px !important;
    font-weight: 800 !important;
    line-height: 1 !important;
    text-transform: uppercase !important;}

body.kajo-catalogue .wd-product.outofstock .kajo-image-stock-badge,


body.kajo-catalogue .wd-product.outofstock .wd-product-stock{
    background: #fff0ed !important;
    color: #bd4b38 !important;}

/* Compact metadata row, matching the image-first reference. */
body.kajo-catalogue .wd-product .product-element-bottom{
    position: static !important;
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) 44px !important;
    grid-template-areas: "title action" "price action" !important;
    align-items: end !important;
    gap: 5px 12px !important;
    flex: 1 1 auto !important;
    min-height: 118px !important;
    padding: 14px 14px 16px !important;
    background: #ffffff !important;
    overflow: visible !important;}

body.kajo-catalogue .wd-product .wd-product-header{
    grid-area: title !important;
    min-width: 0 !important;}

body.kajo-catalogue .wd-product .wd-entities-title{
    display: -webkit-box !important;
    min-height: 40px !important;
    margin: 0 !important;
    overflow: hidden !important;
    color: #061525 !important;
    font-size: 15px !important;
    font-weight: 400 !important;
    line-height: 1.32 !important;
    -webkit-box-orient: vertical !important;
    -webkit-line-clamp: 2 !important;}

/* Variable products previously carried an olive fill here to signal that the
   action opens the option selector rather than adding at once. It read as two
   different buttons on one grid, so both product types now use the identical
   navy action and the distinction is carried by what the tap does. To bring
   the signal back, restore `background: #6f875f !important` below. */
body.kajo-catalogue .wd-product.product-type-variable .kajo-archive-options-link{
    background: #061525 !important;
    box-shadow: none !important;}

/* Lightweight shared selector dialog for variable loop products. */
.kajo-loop-options-modal{
    position: fixed;
    z-index: 99999;
    inset: 0;
    display: grid;
    padding: 24px;
    place-items: center;}

.kajo-loop-options-modal[hidden]{ display: none !important;}

.kajo-loop-options-backdrop{
    position: absolute;
    inset: 0;
    border: 0;
    background: rgba(6, 21, 37, .42);
    backdrop-filter: blur(5px);
    opacity: 0;
    transition: opacity .18s ease;}

.kajo-loop-options-dialog{
    position: relative;
    z-index: 1;
    width: min(100%, 540px);
    overflow: hidden;
    border: 1px solid rgba(6, 21, 37, .1);
    border-radius: 18px;
    background: #fffdf9;
    box-shadow: 0 24px 60px rgba(6, 21, 37, .25);
    opacity: 0;
    transform: translateY(20px) scale(.98);
    transition: opacity .18s ease, transform .22s ease;}

.kajo-loop-options-modal.is-open .kajo-loop-options-backdrop{ opacity: 1;}
.kajo-loop-options-modal.is-open .kajo-loop-options-dialog{ opacity: 1; transform: translateY(0) scale(1);}
.kajo-loop-options-modal.is-closing .kajo-loop-options-backdrop{ opacity: 0;}
.kajo-loop-options-modal.is-closing .kajo-loop-options-dialog{ opacity: 0; transform: translateY(14px) scale(.985);}

.kajo-loop-options-close{
    position: absolute;
    z-index: 2;
    top: 12px;
    right: 12px;
    display: grid;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid rgba(6, 21, 37, .12);
    border-radius: 50%;
    background: rgba(255, 253, 249, .94);
    color: #061525;
    font-size: 25px;
    font-weight: 300;
    line-height: 1;
    place-items: center;}

.kajo-loop-options-product{
    display: grid;
    grid-template-columns: 148px minmax(0, 1fr);
    gap: 20px;
    align-items: center;
    padding: 26px 52px 20px 24px;
    background: #f7f7f5;}

.kajo-loop-options-image{
    display: grid;
    aspect-ratio: 1;
    overflow: hidden;
    background: #fff;
    place-items: center;}

.kajo-loop-options-image img{ width: 100%; height: 100%; object-fit: contain; padding: 10px;}
.kajo-loop-options-copy h2{ margin: 0 0 8px; color: #061525; font-size: 21px; font-weight: 500; line-height: 1.2;}
.kajo-loop-options-price .price{ color: #6f875f; font-size: 17px; font-weight: 700;}
.kajo-loop-options-price del{ margin-inline-end: 5px; color: #a3a9a1; font-size: 12px; font-weight: 500;}
.kajo-loop-options-stock{ display: inline-flex; margin-top: 10px; padding: 5px 9px; border-radius: 999px; background: #edf3e8; color: #557145; font-size: 10px; font-weight: 700; line-height: 1; text-transform: uppercase;}
.kajo-loop-options-stock.is-out{ background: #fff0ed; color: #bd4b38;}

.kajo-loop-options-choices{ display: grid; gap: 14px; padding: 20px 24px 0;}
.kajo-loop-options-row{ display: grid; gap: 8px;}
.kajo-loop-options-label{ color: #5d6f62; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;}
.kajo-loop-options-pills{ display: flex; flex-wrap: wrap; gap: 9px;}
.kajo-loop-options-pill{ display: inline-grid; min-width: 32px; min-height: 32px; margin: 0; padding: 0 10px; border: 1px solid rgba(6, 21, 37, .14); border-radius: 999px; background: #fff; color: #061525; font-size: 12px; font-weight: 500; place-items: center;}
.kajo-loop-options-pill.kajo-variation-color{ width: 28px; min-width: 28px; height: 28px; min-height: 28px; padding: 0; border-radius: 50%;}
.kajo-loop-options-pill.kajo-variation-color .kajo-variation-text{ display: none !important;}
.kajo-loop-options-pill.is-selected{ border-color: #6f875f; box-shadow: 0 0 0 3px rgba(111, 135, 95, .18);}
.kajo-loop-options-pill.kajo-variation-color.is-selected::after{ content: "✓"; color: #fff; font-size: 15px; font-weight: 800; text-shadow: 0 1px 2px rgba(6, 21, 37, .5);}
.kajo-loop-options-pill:disabled{ opacity: .42; cursor: not-allowed;}

.kajo-loop-options-actions{ display: grid; grid-template-columns: 1fr 1.45fr; gap: 10px; padding: 22px 24px 24px;}
.kajo-loop-options-actions > *{ display: grid; min-height: 46px; padding: 0 18px; border: 1px solid #dce3d6; border-radius: 999px; font-size: 13px; font-weight: 700; place-items: center; text-align: center; text-transform: uppercase;}
.kajo-loop-options-view{ color: #557145; background: #fffdf9;}

@media (max-width: 767px) {
    .kajo-loop-options-modal{ padding: 0; align-items: end;}
    .kajo-loop-options-dialog{ width: 100%; max-height: min(90dvh, 720px); border-radius: 22px 22px 0 0; transform: translateY(32px); overflow-y: auto;}
    .kajo-loop-options-product{ grid-template-columns: 112px minmax(0, 1fr); gap: 14px; padding: 20px 48px 16px 18px;}
    .kajo-loop-options-copy h2{ font-size: 17px;}
    .kajo-loop-options-choices{ padding: 16px 18px 0;}
    .kajo-loop-options-actions{ padding: 18px;}}

body.kajo-catalogue .wd-product .wd-entities-title a{
    color: inherit !important;}

body.kajo-catalogue .wd-product .wrap-price{
    grid-area: price !important;
    min-width: 0 !important;
    margin: 0 !important;}

body.kajo-catalogue .wd-product .price{
    color: #6f875f !important;
    font-size: 15px !important;
    font-weight: 700 !important;
    line-height: 1.2 !important;}

body.kajo-catalogue .wd-product .price del{
    margin-inline-end: 4px !important;
    color: #a3a9a1 !important;
    font-size: 11px !important;
    font-weight: 500 !important;}

/* A variable card keeps a single route to its real product selector. */
body.kajo-catalogue .wd-product .kajo-archive-variation{
    display: contents !important;}

body.kajo-catalogue .wd-product .kajo-archive-variation .kajo-variation-group,


body.kajo-catalogue .wd-product .kajo-archive-variation .kajo-archive-variable-add{
    display: none !important;}

/* The former mobile-only route is superseded by the shared selector link. */
body.kajo-catalogue .wd-product .kajo-mobile-options-link{
    display: none !important;}

body.kajo-catalogue .wd-product .wd-product-footer{
    grid-area: action !important;
    align-self: end !important;
    min-width: 44px !important;
    margin: 0 !important;
    position: relative !important;
    z-index: 8 !important;
    visibility: visible !important;
    opacity: 1 !important;}

body.kajo-catalogue .wd-product .wd-add-btn,


body.kajo-catalogue .wd-product .wd-add-btn-replace{
    display: block !important;
    margin: 0 !important;
    visibility: visible !important;
    opacity: 1 !important;}

body.kajo-catalogue .wd-product .wd-add-btn > a,


body.kajo-catalogue .wd-product .kajo-archive-options-link,


body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link{
    position: relative !important;
    display: grid !important;
    width: 44px !important;
    min-width: 44px !important;
    height: 44px !important;
    min-height: 44px !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 50% !important;
    background: #061525 !important;
    color: transparent !important;
    font-size: 0 !important;
    line-height: 0 !important;
    box-shadow: none !important;
    visibility: visible !important;
    opacity: 1 !important;
    transform: none !important;
    place-items: center !important;
    z-index: 9 !important;}

body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link{
    margin: 0 !important;}

body.kajo-catalogue .wd-product .kajo-archive-options-link{
    grid-area: action !important;
    align-self: end !important;}

/* Woodmart's homepage card pass has a stronger white-action declaration.
 * Keep the shared simple-product action legible across every catalogue loop.
 * `.kajo-action-locked` is added by ohmykajo-loop-options.js after that pass
 * runs; it carries no styles of its own beyond raising specificity here, which
 * is what used to require an inline !important. Keeping it in the stylesheet
 * is what allows the :hover rule below to win. */
body.kajo-catalogue .wd-product .wd-add-btn > a.add_to_cart_button,

.wd-product .wd-add-btn > a.add_to_cart_button.kajo-action-locked{
    background: #061525 !important;
    border-color: #061525 !important;}

/* The pointer state, stated after the resting colour and matching its
 * specificity, so it wins without depending on the JS class: the general
 * :hover rule earlier in this file is less specific than the resting rule
 * above and was being outranked on every simple product. A few cards are
 * rendered after the script's last pass and never receive
 * `.kajo-action-locked`, so hover must not be conditional on it. */
body.kajo-catalogue .wd-product .wd-add-btn > a.add_to_cart_button:hover,

body.kajo-catalogue .wd-product .wd-add-btn > a.add_to_cart_button:focus-visible,

.wd-product .wd-add-btn > a.add_to_cart_button.kajo-action-locked:hover,

.wd-product .wd-add-btn > a.add_to_cart_button.kajo-action-locked:focus-visible{
    background: #f58634 !important;
    border-color: #f58634 !important;}

/* Small authored bag glyph, avoiding a dependency on a separate icon package. */
body.kajo-catalogue .wd-product .wd-add-btn > a::before,

body.kajo-catalogue .wd-product .kajo-archive-options-link::before,

body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::before{
    content: "" !important;
    position: absolute !important;
    top: 18px !important;
    inset-inline-start: 14px !important;
    inset-inline-end: auto !important;
    width: 16px !important;
    height: 13px !important;
    border: 1.8px solid #fffaf3 !important;
    border-radius: 2px !important;
    display: block !important;
    opacity: 1 !important;
    transform: none !important;}

body.kajo-catalogue .wd-product .wd-add-btn > a::after,


body.kajo-catalogue .wd-product .kajo-archive-options-link::after,


body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::after{
    content: "" !important;
    position: absolute !important;
    top: 13px !important;
    inset-inline-start: 18px !important;
    inset-inline-end: auto !important;
    width: 8px !important;
    height: 8px !important;
    border: 1.8px solid #fffaf3 !important;
    border-bottom: 0 !important;
    border-radius: 6px 6px 0 0 !important;
    display: block !important;
    opacity: 1 !important;
    transform: none !important;}

body.kajo-catalogue .wd-product .wd-add-btn > a:hover,


body.kajo-catalogue .wd-product .wd-add-btn > a:focus-visible,


body.kajo-catalogue .wd-product .kajo-archive-options-link:hover,


body.kajo-catalogue .wd-product .kajo-archive-options-link:focus-visible,


body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link:hover,


body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link:focus-visible{
    background: #f58634 !important;}

body.kajo-catalogue .wd-product .wd-add-btn .wd-action-icon,


body.kajo-catalogue .wd-product .wd-add-btn .wd-action-text{
    display: none !important;}

/* WooCommerce may inject this after AJAX add-to-cart; it must not create a second CTA. */
body.kajo-catalogue .wd-product a.added_to_cart{
    display: none !important;}

/* Keep unavailable cards structurally consistent without making them purchasable. */
body.kajo-catalogue .wd-product .kajo-archive-disabled-add{
    position: relative !important;
    display: grid !important;
    width: 44px !important;
    min-width: 44px !important;
    height: 44px !important;
    min-height: 44px !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 1px solid rgba(6, 21, 37, 0.12) !important;
    border-radius: 50% !important;
    background: #f2f3ee !important;
    color: transparent !important;
    font-size: 0 !important;
    line-height: 0 !important;
    place-items: center !important;
    opacity: 1 !important;
    visibility: visible !important;
    cursor: not-allowed !important;}

body.kajo-catalogue .wd-product .kajo-archive-disabled-add::before{
    content: "" !important;
    position: absolute !important;
    top: 18px !important;
    inset-inline-start: 14px !important;
    inset-inline-end: auto !important;
    width: 16px !important;
    height: 13px !important;
    border: 1.8px solid #9aa68f !important;
    border-radius: 2px !important;}

body.kajo-catalogue .wd-product .kajo-archive-disabled-add::after{
    content: "" !important;
    position: absolute !important;
    top: 13px !important;
    inset-inline-start: 18px !important;
    inset-inline-end: auto !important;
    width: 8px !important;
    height: 8px !important;
    border: 1.8px solid #9aa68f !important;
    border-bottom: 0 !important;
    border-radius: 6px 6px 0 0 !important;}

/* Let the shared image and metadata stack define the card height. Woodmart's
 * fixed shell was shorter than its own action row and clipped that control. */
@media (min-width: 768px) {
    body.kajo-catalogue .wd-product{
        height: 400px !important;}

    body.kajo-catalogue .wd-product .product-wrapper{
        height: 400px !important;
        min-height: 400px !important;
        overflow: hidden !important;}

    body.kajo-catalogue .wd-product .product-element-bottom{
        flex: 0 0 118px !important;
        height: 118px !important;
        min-height: 118px !important;
        grid-template-rows: 48px 28px !important;
        box-sizing: border-box !important;}}

@media (max-width: 767px) {
    body.kajo-catalogue .wd-product .product-element-bottom{
        grid-template-columns: minmax(0, 1fr) 38px !important;
        min-height: 102px !important;
        padding: 10px 10px 12px !important;
        gap: 4px 8px !important;}

    /* Two lines exactly. The box is also capped, not just floored: the title is
     * a grid item inside the card footer, which blockifies -webkit-box and
     * leaves -webkit-line-clamp inert, so a taller box let a few pixels of a
     * third line show under the clamp. 2 x 1.32 x 12px = 31.68px. */
    body.kajo-catalogue .wd-product .wd-entities-title{
        min-height: 31.68px !important;
        max-height: 31.68px !important;
        font-size: 12px !important;
        line-height: 1.32 !important;}

    body.kajo-catalogue .wd-product .price{
        font-size: 12px !important;}

    body.kajo-catalogue .wd-product .wd-add-btn > a,


    body.kajo-catalogue .wd-product .kajo-archive-options-link,


    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link,


    body.kajo-catalogue .wd-product .kajo-archive-disabled-add{
        width: 38px !important;
        min-width: 38px !important;
        height: 38px !important;
        min-height: 38px !important;}

    body.kajo-catalogue .wd-product .wd-add-btn > a::before,


    body.kajo-catalogue .wd-product .kajo-archive-options-link::before,


    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::before,


    body.kajo-catalogue .wd-product .kajo-archive-disabled-add::before{
        top: 15px !important;
        inset-inline-start: 11px !important;
        inset-inline-end: auto !important;}

    body.kajo-catalogue .wd-product .wd-add-btn > a::after,


    body.kajo-catalogue .wd-product .kajo-archive-options-link::after,


    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::after,


    body.kajo-catalogue .wd-product .kajo-archive-disabled-add::after{
        top: 10px !important;
        inset-inline-start: 15px !important;
        inset-inline-end: auto !important;}

    body.kajo-catalogue .wd-product .product-labels,


    body.kajo-catalogue .wd-product .kajo-sale-hot-labels{
        top: 8px !important;
        inset-inline-start: 8px !important;
        gap: 4px !important;}

    body.kajo-catalogue .wd-product .product-labels .product-label,


    body.kajo-catalogue .wd-product .kajo-sale-hot-label{
        min-height: 20px !important;
        padding: 0 7px !important;
        font-size: 9px !important;
        line-height: 20px !important;}

    body.kajo-catalogue .wd-product .wd-buttons.wd-pos-r-t{
        top: 7px !important;
        inset-inline-end: 7px !important;}

    body.kajo-catalogue .wd-product .wd-wishlist-btn a{
        width: 29px !important;
        min-width: 29px !important;
        height: 29px !important;
        min-height: 29px !important;}

    body.kajo-catalogue .wd-product .kajo-image-stock-badge,


    body.kajo-catalogue .wd-product .wd-product-stock{
        top: 39px !important;
        inset-inline-end: 7px !important;
        min-height: 18px !important;
        padding: 0 6px !important;
        font-size: 8px !important;}

    /* Beat the earlier mobile experiment rules without touching non-catalogue UI. */
    body.kajo-catalogue .kajo-home-products-section.is-mobile-grid .wd-product .product-wrapper,

    body.kajo-catalogue .kajo-home-picks.is-mobile-grid .wd-product .product-wrapper,

    body.kajo-catalogue .wd-product .product-wrapper{
        min-height: 0 !important;
        height: 100% !important;
        max-height: none !important;}

    body.kajo-catalogue .kajo-home-products-section.is-mobile-grid .wd-product .product-element-bottom,


    body.kajo-catalogue .kajo-home-picks.is-mobile-grid .wd-product .product-element-bottom,


    body.kajo-catalogue .wd-product .product-element-bottom{
        display: grid !important;
        grid-template-columns: minmax(0, 1fr) 38px !important;
        grid-template-rows: auto auto !important;
        grid-template-areas: "title action" "price action" !important;
        min-height: 102px !important;
        height: auto !important;
        flex: 1 1 auto !important;
        padding: 10px 10px 12px !important;
        gap: 4px 8px !important;
        align-content: end !important;}

    /* The existing mobile selector script inserts this route for variables.
       Make it use the same single bag action, without a second text CTA. */
    body.kajo-catalogue .kajo-home-products-section.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link,

    body.kajo-catalogue .kajo-home-picks.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link,

    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link{
        display: grid !important;
        width: 38px !important;
        min-width: 38px !important;
        height: 38px !important;
        min-height: 38px !important;
        margin: 0 !important;
        padding: 0 !important;
        border: 0 !important;
        border-radius: 50% !important;
        background: #061525 !important;
        color: transparent !important;
        font-size: 0 !important;
        line-height: 0 !important;
        place-items: center !important;}

    body.kajo-catalogue .kajo-home-products-section.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link::before,


    body.kajo-catalogue .kajo-home-picks.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link::before,


    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::before{
        display: block !important;
        top: 15px !important;
        inset-inline-start: 11px !important;
        inset-inline-end: auto !important;
        opacity: 1 !important;
        transform: none !important;}

    body.kajo-catalogue .kajo-home-products-section.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link::after,


    body.kajo-catalogue .kajo-home-picks.is-mobile-grid .wd-product.product-type-variable .kajo-mobile-options-link::after,


    body.kajo-catalogue .wd-product.product-type-variable .kajo-mobile-options-link::after{
        display: block !important;
        top: 10px !important;
        inset-inline-start: 15px !important;
        inset-inline-end: auto !important;
        opacity: 1 !important;
        transform: none !important;}

    /* Keep the retired mobile duplicate from reappearing after legacy scripts
       refresh a product loop. */
    body.kajo-catalogue .wd-product .kajo-mobile-options-link{
        display: none !important;}}

/* Keep selector styles after the legacy loop rules so Woodmart cannot reset them. */
.kajo-loop-options-modal{ opacity: 0; pointer-events: none; visibility: hidden; transition: opacity .24s ease, visibility 0s linear .24s;}
.kajo-loop-options-modal.is-open{ opacity: 1; pointer-events: auto; visibility: visible; transition: opacity .24s ease;}
.kajo-loop-options-modal.is-closing{ opacity: 0; pointer-events: none; visibility: hidden;}
.kajo-loop-options-backdrop{ margin: 0; padding: 0; border: 0 !important; border-radius: 0 !important; background: rgba(6, 21, 37, .36) !important; box-shadow: none !important; color: transparent !important; cursor: default; opacity: 1 !important; -webkit-backdrop-filter: blur(14px) saturate(115%); backdrop-filter: blur(14px) saturate(115%);}
.kajo-loop-options-backdrop:hover,

.kajo-loop-options-backdrop:focus,

.kajo-loop-options-backdrop:active{ background: rgba(6, 21, 37, .36) !important;}
.kajo-loop-options-dialog{ border: 1px solid rgba(255, 255, 255, .7); border-radius: 22px; background: linear-gradient(135deg, rgba(255, 255, 255, .82), rgba(237, 244, 232, .66)); box-shadow: 0 28px 70px rgba(6, 21, 37, .3); -webkit-backdrop-filter: blur(22px) saturate(125%); backdrop-filter: blur(22px) saturate(125%); transition: opacity .2s ease, transform .28s cubic-bezier(.2, .8, .2, 1);}
.kajo-loop-options-modal.is-open .kajo-loop-options-dialog{ opacity: 1; transform: translateY(0) scale(1);}
.kajo-loop-options-modal.is-closing .kajo-loop-options-dialog{ opacity: 0; transform: translateY(14px) scale(.985);}
.kajo-loop-options-close{ width: 42px; height: 42px; min-width: 42px; min-height: 42px; padding: 0; border: 0 !important; border-radius: 50% !important; background: rgba(255, 255, 255, .48) !important; box-shadow: 0 8px 20px rgba(6, 21, 37, .1); color: transparent !important; font-size: 0 !important; transition: background-color .2s ease, box-shadow .2s ease, transform .28s cubic-bezier(.2, .8, .2, 1);}
.kajo-loop-options-close::before,

.kajo-loop-options-close::after{ position: absolute; width: 17px; height: 2px; border-radius: 99px; background: #061525; content: ""; transition: background-color .2s ease;}
.kajo-loop-options-close::before{ transform: rotate(45deg);}
.kajo-loop-options-close::after{ transform: rotate(-45deg);}
.kajo-loop-options-close:hover{ background: #f58634 !important; box-shadow: 0 10px 24px rgba(216, 141, 75, .35); transform: rotate(90deg) scale(.94);}
.kajo-loop-options-close:hover::before,

.kajo-loop-options-close:hover::after{ background: #fffaf3;}
.kajo-loop-options-close:focus-visible{ outline: 2px solid #f58634; outline-offset: 3px;}
.kajo-loop-options-product{ padding-inline-end: 62px; background: rgba(255, 255, 255, .26);}
.kajo-loop-options-image{ border: 1px solid rgba(255, 255, 255, .56); border-radius: 12px; background: rgba(255, 255, 255, .52);}
.kajo-loop-options-pill{ background: rgba(255, 255, 255, .6);}
.kajo-loop-options-pill.kajo-variation-color{ position: relative; isolation: isolate; width: 30px; min-width: 30px; height: 30px; min-height: 30px; overflow: hidden; border: 2px solid rgba(255, 255, 255, .9) !important; box-shadow: 0 0 0 1px rgba(6, 21, 37, .2) !important;}
.kajo-loop-options-pill.kajo-variation-color::before{ display: none !important; content: none !important;}
.kajo-loop-options-pill.kajo-variation-color.is-selected{ box-shadow: 0 0 0 2px #6f875f, 0 0 0 4px rgba(111, 135, 95, .26) !important;}
.kajo-loop-options-pill.kajo-variation-color.is-selected::after{ position: absolute; z-index: 2; inset: 0; display: grid; background: rgba(6, 21, 37, .22); color: #fff; content: "\2713"; font-size: 15px; font-weight: 800; line-height: 1; place-items: center; text-shadow: 0 1px 2px rgba(6, 21, 37, .5);}
.kajo-loop-options-view{ background: rgba(255, 255, 255, .52);}
@media (max-width: 767px) {
    .kajo-loop-options-close{ top: 10px; right: 12px; width: 40px; height: 40px; min-width: 40px; min-height: 40px;}
    .kajo-loop-options-product{ padding-inline-end: 56px;}
    .kajo-loop-options-copy h2{ font-size: 17px !important; line-height: 1.18 !important;}
    .kajo-loop-options-actions{ grid-template-columns: .95fr 1.55fr; gap: 8px; padding: 16px 18px 18px;}
    .kajo-loop-options-actions > *{ min-height: 44px; padding-inline: 12px; font-size: 11px; white-space: nowrap;}}

/* Variable-product selector modal CTA. This is the modal opened by a card's
   Add to Basket action, not the separate product quick-view component. */
@media (max-width: 767px) {
@media (max-width: 767px) {
    .kajo-loop-options-modal .kajo-loop-options-actions{ grid-template-columns: .8fr 1.8fr !important;}}}

/* ── Variable-product selector CTA ──────────────────────────────────────────
   The single definition of the Add to Basket button inside the variation
   selector modal. Every selector below is scoped to .kajo-loop-options-modal,
   so no other add-to-cart control in the catalogue, the quick view or the
   single-product page can be reached from here.

   The cart travels. At rest it parks in a cream disc on the trailing edge of
   the pill. On press it runs the full journey: the label clears, the cart
   enters from the leading edge and halts mid-pill, the item drops into it,
   the tick draws, the cart runs on and off the trailing edge, and then cart
   and label return from the leading edge to their resting places.

   The cart is moved with `left` rather than a transform because the distance
   it covers is the width of the button, which CSS cannot read. Percentages of
   the button solve that at every width with no per-breakpoint retuning, and
   the element is absolutely positioned, so only it repaints - nothing around
   it reflows. Start, middle, end and rest are held in custom properties and
   swapped wholesale for RTL, which mirrors the journey without flipping the
   cart graphic itself. */

/* The add-to-basket control below is a component, not a modal part: the same
 * button, markup and journey animation are used by the variation modal and by
 * the single product page. Its rules are therefore keyed on
 * .kajo-loop-options-add alone, with no ancestor - adding a context is a
 * matter of putting the class on a button, and there is one definition to
 * maintain rather than two. */
.kajo-loop-options-add{
    --kajo-add-olive: #6f875f;
    --kajo-add-olive-dark: #557145;
    --kajo-add-cream: #fff8ef;
    --kajo-add-accent: #f58634;
    --kajo-add-well: 44px;
    --kajo-add-well-edge: 6px;

    /* The four stations of the journey. */
    --kajo-add-cart-rest: calc(100% - var(--kajo-add-well) - var(--kajo-add-well-edge));
    --kajo-add-cart-mid: calc(50% - (var(--kajo-add-well) / 2));
    --kajo-add-cart-in: calc(-8px - var(--kajo-add-well));
    --kajo-add-cart-out: 100%;

    position: relative;
    display: grid;
    width: 100%;
    min-height: 56px;
    padding-block: 8px;
    /* Asymmetric: the label centres in the space left of the parked disc. */
    padding-inline: 18px calc(var(--kajo-add-well) + 12px);
    overflow: hidden;
    border: 0;
    border-radius: 999px;
    background: var(--kajo-add-olive);
    box-shadow: 0 10px 22px rgba(85, 113, 69, .22);
    cursor: pointer;
    place-items: center;
    transition: background-color .2s ease, box-shadow .2s ease;}

/* Only the stations flip. The padding above is already stated logically, and
 * inline-end resolves to the left here - the same side the cart parks on - so
 * overriding it would move the clearance to the wrong edge. */
[dir="rtl"] .kajo-loop-options-add,
body.kajo-rtl .kajo-loop-options-add{
    --kajo-add-cart-rest: var(--kajo-add-well-edge);
    --kajo-add-cart-in: 100%;
    --kajo-add-cart-out: calc(-8px - var(--kajo-add-well));}

.kajo-loop-options-add:not(:disabled):not(.disabled):hover,


.kajo-loop-options-add:not(:disabled):not(.disabled):focus-visible{
    background: var(--kajo-add-olive-dark);
    box-shadow: 0 12px 26px rgba(85, 113, 69, .3);}

.kajo-loop-options-add:focus-visible{
    outline: 2px solid var(--kajo-add-accent);
    outline-offset: 3px;}

/* Disabled until a variation is chosen. Deliberately a pale fill with dark
 * ink rather than a faded copy of the enabled button: lowering opacity took
 * the label to 2.5:1 and made the cart almost invisible. This measures 6.1:1,
 * and the disc keeps its full contrast. */
/* While the add is in flight Woodmart puts .loading on the button and draws a
 * rotating ring with ::after. On this control that ring spun behind the
 * label at the same time as the cart was making its run - two different
 * progress indicators for one action. The journey is the indicator here, so
 * the ring is suppressed. The component itself uses neither pseudo. */
.kajo-loop-options-add.loading::before,
.kajo-loop-options-add.loading::after,
.kajo-loop-options-add.is-animating::before,
.kajo-loop-options-add.is-animating::after {
    content: none !important;
    display: none !important;
    animation: none !important;}

/* WooCommerce marks the single product button unavailable with a .disabled
 * class and no disabled attribute - a variation has not been chosen yet - so
 * the component answers to both forms. */
.kajo-loop-options-add:disabled,
.kajo-loop-options-add.disabled{
    background: #d9dfd3;
    box-shadow: none;
    /* Woodmart's base.min.css carries button[disabled] { opacity: .6 !important },
     * which is what washed this button out. An !important is the only way past
     * another !important, so it is used here and nowhere else in this block. */
    opacity: 1 !important;
    cursor: not-allowed;}

.kajo-loop-options-add-label,


.kajo-loop-options-add-success{
    grid-area: 1 / 1;
    z-index: 2;
    min-width: 0;
    padding: 0;
    color: #fffaf3;
    font-size: 14px;
    font-weight: 800;
    letter-spacing: .04em;
    line-height: 1.1;
    text-align: center;
    text-transform: uppercase;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;}

.kajo-loop-options-add:disabled,
.kajo-loop-options-add.disabled .kajo-loop-options-add-label,


.kajo-loop-options-add:disabled,
.kajo-loop-options-add.disabled .kajo-loop-options-add-success{ color: #44513f;}

.kajo-loop-options-add-label{ opacity: 1;}
.kajo-loop-options-add-success{ opacity: 0;}

/* Left over from an earlier liquid-morph treatment; the markup still ships it. */
.kajo-loop-options-add-morph{ display: none;}

/* The cart, in its cream disc. The disc is what makes the olive-stroked cart
 * legible while it crosses the olive fill, so the two always travel together. */
.kajo-loop-options-add-cart{
    position: absolute;
    z-index: 3;
    top: 50%;
    left: var(--kajo-add-cart-rest);
    display: grid;
    width: var(--kajo-add-well);
    height: var(--kajo-add-well);
    margin-top: calc(var(--kajo-add-well) / -2);
    border-radius: 50%;
    background: var(--kajo-add-cream);
    opacity: 1;
    pointer-events: none;
    place-items: center;
    transition: background-color .2s ease;}

.kajo-loop-options-add-cart svg{
    width: 24px;
    height: 18px;
    overflow: visible;
    fill: none;
    stroke: var(--kajo-add-olive);
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 2.2;}

.kajo-loop-options-add-cart .wheel{ stroke-width: 1.8;}
.kajo-loop-options-add-cart .tick{
    stroke: var(--kajo-add-accent);
    stroke-dasharray: 10;
    stroke-dashoffset: 10;}

/* The falling item, parked over the midpoint where the cart halts. */
.kajo-loop-options-add-shirt{
    position: absolute;
    z-index: 4;
    top: 50%;
    left: 50%;
    width: 24px;
    height: 24px;
    margin: -12px 0 0 -12px;
    opacity: 0;
    pointer-events: none;}

.kajo-loop-options-add-shirt svg{
    position: absolute;
    inset: 0;
    width: 24px;
    height: 24px;
    fill: var(--kajo-add-accent);
    stroke: none;}

.kajo-loop-options-add-shirt-second{
    clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
    fill: var(--kajo-add-cream);}

/* ── The journey ────────────────────────────────────────────────────────────
   2000ms, shared by every part so the phases stay in step. The script holds
   the class for the full duration before swapping to the settled state, so
   the sequence is never cut short by a fast server response.

      0 -  320ms  label clears, cart enters from the leading edge
    320 -  440ms  cart holds at the midpoint
    360 -  900ms  item falls in, cart takes the impact
    920 - 1160ms  tick draws
   1160 - 1520ms  cart runs on and off the trailing edge
   1560 - 2000ms  cart and label return from the leading edge               */

.kajo-loop-options-add.is-animating{ cursor: progress;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-label{ animation: kajo-add-label-move 2s linear both, kajo-add-label-fade 2s linear both;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-cart{ animation: kajo-add-cart-journey 2s linear both;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-cart svg{ animation: kajo-add-cart-impact 2s linear both;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-cart .tick{ animation: kajo-add-tick-draw 2s linear both;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-shirt{ animation: kajo-add-item-drop 2s linear both;}
.kajo-loop-options-add.is-animating .kajo-loop-options-add-shirt-second{ animation: kajo-add-item-fill 2s linear both;}

/* A disabled button is normally pale; while the journey runs the press has
 * already been accepted, so it keeps the enabled skin. */
.kajo-loop-options-add.is-animating:disabled{
    background: var(--kajo-add-olive);
    box-shadow: 0 10px 22px rgba(85, 113, 69, .22);}
.kajo-loop-options-add.is-animating:disabled .kajo-loop-options-add-label,

.kajo-loop-options-add.is-animating:disabled .kajo-loop-options-add-success{ color: #fffaf3;}

/* Settled state, entered once the journey has finished and the item is
 * confirmed in the basket. The cart is already back at rest, so this only
 * swaps the wording and leaves the tick drawn. */
.kajo-loop-options-add.is-added{ background: var(--kajo-add-olive-dark);}
.kajo-loop-options-add.is-added:disabled{
    background: var(--kajo-add-olive-dark);
    box-shadow: 0 10px 22px rgba(85, 113, 69, .22);}
.kajo-loop-options-add.is-added .kajo-loop-options-add-label{ opacity: 0; transition: opacity .2s ease;}
.kajo-loop-options-add.is-added .kajo-loop-options-add-success{ opacity: 1; color: #fffaf3; transition: opacity .2s ease;}
.kajo-loop-options-add.is-added .kajo-loop-options-add-cart .tick{ stroke-dashoffset: 0;}
.kajo-loop-options-add.is-added .kajo-loop-options-add-cart .shape,

.kajo-loop-options-add.is-added .kajo-loop-options-add-cart .wheel{ opacity: .4;}

/* Out to the trailing side as the cart arrives, then back in from the leading
 * side at the end. The reposition between the two happens while the label is
 * fully transparent, so the jump is never seen. */
/* Movement and fade are split across two animations on purpose. The return
 * glide wants an ease-out, but that same curve front-loads opacity and brings
 * the wording back while the cart is still crossing its ground, which looks
 * like the disc is cropping the text. Separating them lets the glide ease and
 * the fade hold off until the cart is past. */
@keyframes kajo-add-label-move {
    0%{ transform: translateX(0); animation-timing-function: ease-in;}
    9%{ transform: translateX(18px);}
    88%{ transform: translateX(-22px); animation-timing-function: cubic-bezier(.2, .8, .3, 1);}
    100%{ transform: translateX(0);}}

@keyframes kajo-add-label-fade {
    0%{ opacity: 1;}
    9%,

    93%{ opacity: 0;}
    100%{ opacity: 1;}}

/* In from the leading edge, a hold at the midpoint, away past the trailing
 * edge, then a reposition off-screen and a return to rest. The reposition at
 * 76.5% happens outside the pill, which clips its overflow, so it is unseen. */
@keyframes kajo-add-cart-journey {
    0%{ left: var(--kajo-add-cart-in); animation-timing-function: cubic-bezier(.2, .8, .3, 1);}
    16%,

    58%{ left: var(--kajo-add-cart-mid); animation-timing-function: cubic-bezier(.5, 0, .85, .4);}
    76%,

    76.4%{ left: var(--kajo-add-cart-out);}
    76.5%{ left: var(--kajo-add-cart-in); animation-timing-function: cubic-bezier(.2, .8, .3, 1);}
    78%{ left: var(--kajo-add-cart-in);}
    100%{ left: var(--kajo-add-cart-rest);}}

/* The cart takes the weight of the item as it lands. */
@keyframes kajo-add-cart-impact {
    0%,

    42%{ transform: scale(1); animation-timing-function: ease-out;}
    47%{ transform: scale(1.18); animation-timing-function: ease-in-out;}
    53%{ transform: scale(.94); animation-timing-function: ease-out;}
    58%,

    100%{ transform: scale(1);}}

/* Rises into view above the halted cart, falls under something like gravity,
 * then shrinks away as it passes the lip. The travel is kept inside the pill's
 * visible band: the button clips its overflow, so a taller fall would spend
 * its opening frames hidden above the top edge. */
@keyframes kajo-add-item-drop {
    0%,

    17%{ opacity: 0; transform: translateY(-26px) scale(.78); animation-timing-function: ease-out;}
    22%{ opacity: 1; transform: translateY(-22px) scale(1); animation-timing-function: cubic-bezier(.42, 0, .78, .6);}
    40%{ opacity: 1; transform: translateY(-3px) scale(.94); animation-timing-function: ease-out;}
    45%{ opacity: .9; transform: translateY(2px) scale(.6);}
    49%,

    100%{ opacity: 0; transform: translateY(4px) scale(.2);}}

@keyframes kajo-add-item-fill {
    0%,

    24%{ clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);}
    38%,

    100%{ clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);}}

/* Draws once the item is in, and is cleared again while the cart is off-pill
 * so it returns to rest empty. */
@keyframes kajo-add-tick-draw {
    0%,

    46%{ stroke-dashoffset: 10; animation-timing-function: ease-out;}
    58%,

    76%{ stroke-dashoffset: 0;}
    76.5%,

    100%{ stroke-dashoffset: 10;}}

/* Reduced motion: no journey. The cart stays parked, the item never falls,
 * and the wording crossfades in place. */
@media (prefers-reduced-motion: reduce) {
    .kajo-loop-options-add.is-animating .kajo-loop-options-add-label,

    .kajo-loop-options-add.is-animating .kajo-loop-options-add-cart,

    .kajo-loop-options-add.is-animating .kajo-loop-options-add-cart svg,

    .kajo-loop-options-add.is-animating .kajo-loop-options-add-cart .tick,

    .kajo-loop-options-add.is-animating .kajo-loop-options-add-shirt,

    .kajo-loop-options-add.is-animating .kajo-loop-options-add-shirt-second{ animation: none;}}

@media (max-width: 767px) {
    .kajo-loop-options-add{
        --kajo-add-well: 38px;
        min-height: 52px;
        padding-inline: 12px calc(var(--kajo-add-well) + 10px);}

    .kajo-loop-options-add-label,


    .kajo-loop-options-add-success{ font-size: 13px; letter-spacing: .02em;}

    .kajo-loop-options-add-cart svg{ width: 21px; height: 16px;}}

/* ── Hover: keep the card still ─────────────────────────────────────────────
   Woodmart's "buttons on hover" card slides .product-element-bottom up by the
   height of its action row, to reveal buttons that are normally tucked below.
   This card keeps its single action visible at all times, so that slide had
   nothing to reveal: it just shunted the title, price and footer up by 48px
   on hover and pushed the stock badge out of place. The gentle lift of the
   whole wrapper is kept, which is the part that reads as a hover.

   This was previously disabled for body.home alone, which is why the same card
   sat still on the home page and jumped on sale and the archives. */
body.kajo-catalogue .wd-product.wd-hover-buttons-on-hover:not(:is(.quick-shop-shown,

.wd-loading)):is(:hover,

.wd-variation-active) :is(.product-element-bottom,

.wd-product-grid-slider-pagin){
    transform: none !important;}

/* ── Three things the sale page did differently ─────────────────────────────
   All three had the same cause: the rule existed twice, once for body.home and
   once for body.post-type-archive-product / body.page-id-20970, and the sale
   page (body.page-id-705) was in neither list. */

/* 1. Column count. Every full catalogue listing shares one density, so the
      same card comes out the same width on the shop page, the sale page and
      the category archives - the sale grid was built by the page builder with
      --wd-col-lg:5 inline while the other two use 4. Setting the variable
      rather than the tracks keeps Woodmart's own responsive steps intact; the
      tablet and phone counts already matched and are untouched.

      The homepage strips are excluded by structure, not by page: they are
      curated rows inside .kajo-home-section, some of them carousels, and they
      keep whatever density their section sets. */
body.kajo-catalogue .wd-products:not(.kajo-home-section .wd-products) {
    --wd-col-lg: 4 !important;}

/* 2. The stock pill stopped breathing. The keyframes live in style.css and are
      global; only the rule that applies them was missing this context. */
body.kajo-catalogue :is(.kajo-image-stock-badge,

.wd-product-stock){
    animation: kajo-stock-pulse-green 1.45s ease-in-out infinite;}

body.kajo-catalogue :is(.kajo-image-stock-badge,


.wd-product-stock).out-of-stock{
    animation-name: kajo-stock-pulse-red;}

/* 3. Colour swatches in the selector modal rendered blank. The modal is
      appended to <body>, outside any product card, and the only rule painting
      a swatch was scoped to body.home - so everywhere else the generic pale
      pill background showed through instead of the colour. Stated here against
      the modal's own class, so it holds on every page without a body scope.
      The custom property is set inline on the source pill by PHP and survives
      the clone. */
.kajo-loop-options-pill.kajo-variation-color{
    background: var(--kajo-swatch-color, #f5f3ed);}

/* ---------------------------------------------------------------------------
   Carousels are not grids
   ---------------------------------------------------------------------------
   A Woodmart carousel container carries the class .products as well, so the
   catalogue grid above lands on it and lays its slide track out in columns.
   The track positions itself with a transform, so the result is the heading
   squeezed into column one and the slides pushed off the right edge - which
   is what happened to "You may also like" on product pages the moment single
   products joined the card context.

   The cards inside keep the component styling; only the container is handed
   back to the carousel. --wd-col-* is left as the catalogue sets it, since
   that is what the carousel reads for slides-per-view.
   --------------------------------------------------------------------------- */
body.kajo-catalogue .products.wd-carousel-container,
body.kajo-catalogue .wd-products.wd-carousel-container {
    display: block !important;
    grid-template-columns: none !important;
    gap: 0 !important;}

/* On phones a catalogue card lets its title block size to content - measured
   at 32px, with the two-line cap still on the title itself. Cards inside a
   carousel were missing that reset and kept the desktop fixed header,
   min-height and max-height both 112px, which left 80px of empty space above
   the title and again between the title and the price. Only the header is
   reset; the title keeps its own max-height and line clamp. */
@media (max-width: 767px) {
    body.kajo-catalogue .wd-carousel-container .wd-product-header {
        min-height: 0 !important;
        max-height: none !important;}
}

/* ===========================================================================
   The card's touch targets.

   A card offers three things to act on, and each should do something
   different: the add button adds (or opens the option selector), the image
   goes to the product page, and the title opens the quick view on a phone.
   The behaviour is in ohmykajo-card-touch.js; what is here is the part a
   visitor needs to SEE.

   On desktop the title still links to the product page, so it gets a hover
   colour - without one there was no way to tell the title was clickable at
   all. The resting colour is set by `.wd-entities-title a { color: inherit }`
   above with !important, so the hover has to match that weight to win.

   Guarded by (hover: hover) as well as the width, so a touch device wide
   enough to pass the breakpoint cannot get a hover colour stuck on after a
   tap - which is what happens when a :hover rule meets a touchscreen.
   =========================================================================== */

@media (min-width: 1025px) and (hover: hover) {
    body.kajo-catalogue .wd-product .wd-entities-title a,
    .kajo-reco-v2__card .kajo-reco-v2__title a {
        transition: color .18s ease;}

    body.kajo-catalogue .wd-product .wd-entities-title a:hover,
    body.kajo-catalogue .wd-product .wd-entities-title a:focus-visible,
    .kajo-reco-v2__card .kajo-reco-v2__title a:hover,
    .kajo-reco-v2__card .kajo-reco-v2__title a:focus-visible {
        color: #f58634 !important;}
}

/* Below the breakpoint the title opens the quick view rather than following
   its own href, so it is a control, not a destination: it gets the larger tap
   target that implies and stops the browser offering a link preview on a long
   press. The href stays in the markup as the no-JavaScript fallback. */
@media (max-width: 1024px) {
    body.kajo-catalogue .wd-product .wd-entities-title a,
    .kajo-reco-v2__card .kajo-reco-v2__title a {
        -webkit-touch-callout: none;
        -webkit-tap-highlight-color: rgba(245, 134, 52, .14);}
}

@media (prefers-reduced-motion: reduce) {
    body.kajo-catalogue .wd-product .wd-entities-title a,
    .kajo-reco-v2__card .kajo-reco-v2__title a {
        transition: none;}
}

/* ---------------------------------------------------------------------------
   Why these six are logical and the rest of this file is not.

   Woodmart already positions these three elements logically and correctly:

       .product-labels          inset-inline-start: 7px
       .wd-buttons.wd-pos-r-t   inset-inline-end: var(--wd-btn-inset)

   The child theme overrode them with PHYSICAL left/right, which pinned the
   badge to the left and the heart and stock pill to the right in Arabic as
   well - so half the card mirrored (title, price and the cart button follow
   `direction`) and half did not. Restoring the logical axis here gives the
   parent's RTL behaviour back while keeping our own spacing values.

   Deliberately limited to these six declarations, each one checked against the
   rendered cascade. An earlier attempt converted every physical offset in this
   file and in the homepage card stylesheet with a regex; that piled the badge,
   heart and stock pill on top of each other, because several offsets in those
   files are genuinely physical. That attempt was reverted.
   ------------------------------------------------------------------------ */
