/* ---------------------------------------------------------------------------
   Storefront

   Used only by _LayoutShop.cshtml. The admin/vendor chrome is untouched — a
   customer should never see a back-office sidebar wrapped around a shop.

   Colours come from the --wp-* tokens in site.css. No brand hex here.
   --------------------------------------------------------------------------- */

/* The root is 0.90rem, sized for dense admin grids. A storefront is read at arm's
   length by a customer, not scanned by an operator, so it sets its own baseline
   instead of inheriting the back-office scale. */
.shop-body {
    background: var(--wp-surface);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    font-size: 1rem;
}

.shop-container {
    width: 100%;
    max-width: 1360px;
    margin: 0 auto;
    padding: 0 1.25rem;
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.shop-main > .shop-container {
    display: block;
    padding-top: 1.5rem;
    padding-bottom: 2.5rem;
}

.shop-main {
    flex: 1 0 auto;
}

/* ----------------------------------------------------------------- Header */

.shop-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-bottom: 1px solid var(--wp-border);
}

.shop-header-main {
    padding: .55rem 0;
}

.shop-brand {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: 1.1rem;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--wp-text);
    text-decoration: none;
    white-space: nowrap;
}

/* Swap wwwroot/images/brand/logo.png to rebrand; height drives the size so a replacement of any
   width keeps the header rhythm. */
.shop-brand-logo {
    height: 30px;
    width: auto;
    max-width: 190px;
    object-fit: contain;
    flex-shrink: 0;
}

/* The square mark replaces the wordmark on a phone: at 196x40 the full logo eats roughly half
   a 360px header, leaving nothing for the search field. */
.shop-brand-icon {
    display: none;
    height: 30px;
    width: 30px;
    object-fit: contain;
    flex-shrink: 0;
}

/* Search takes the slack so the brand and actions stay put as it grows. */
.shop-search {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    max-width: 640px;
}

    .shop-search .form-control {
        height: 40px;
        padding-left: 2.4rem;
        padding-right: 5.5rem;
        border-radius: 999px;
        background: var(--wp-surface);
        border-color: var(--wp-border);
        transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
    }

    .shop-search .form-control:focus {
        background: var(--wp-surface-raised);
        border-color: var(--wp-purple-500);
    }

.shop-search-icon {
    position: absolute;
    left: .95rem;
    color: var(--wp-text-muted);
    pointer-events: none;
    font-size: .93rem;
}

/* ------------------------------------------------------------ Suggestions */

.shop-suggest {
    position: absolute;
    top: calc(100% + .35rem);
    left: 0;
    right: 0;
    z-index: 1040;
    max-height: 380px;
    overflow-y: auto;
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: 10px;
    box-shadow: var(--wp-shadow-lg);
    padding: .25rem;
}

    .shop-suggest[hidden] {
        display: none;
    }

.shop-suggest-item {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .45rem .55rem;
    border-radius: 7px;
    text-decoration: none;
    color: var(--wp-text);
}

    .shop-suggest-item:hover,
    .shop-suggest-item.active {
        background: var(--wp-purple-50);
    }

    .shop-suggest-item img,
    .shop-suggest-noimg {
        width: 38px;
        height: 38px;
        flex-shrink: 0;
        border-radius: 6px;
        object-fit: cover;
        background: var(--wp-surface);
    }

.shop-suggest-noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--wp-border-strong);
}

.shop-suggest-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.shop-suggest-name {
    font-size: .93rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shop-suggest-vendor {
    font-size: .8rem;
    color: var(--wp-text-muted);
}

.shop-suggest-price {
    font-size: .9rem;
    font-weight: 700;
    white-space: nowrap;
}

.shop-search-go {
    position: absolute;
    right: 4px;
    height: 32px;
    padding: 0 .9rem;
    border: 0;
    border-radius: 999px;
    font-size: .85rem;
    font-weight: 600;
    color: #fff;
    background: var(--wp-purple-600);
    cursor: pointer;
    transition: background-color .15s ease;
}

    .shop-search-go:hover {
        background: var(--wp-purple-700);
    }

.shop-actions {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin-left: auto;
}

.shop-action {
    display: flex;
    align-items: center;
    gap: .45rem;
    padding: .45rem .7rem;
    border-radius: 999px;
    color: var(--wp-text-muted);
    text-decoration: none;
    font-size: 1rem;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}

    .shop-action:hover {
        background: var(--wp-purple-50);
        color: var(--wp-purple-700);
    }

.shop-action-label {
    font-size: .85rem;
    font-weight: 500;
    letter-spacing: .01em;
}

.shop-avatar {
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: .8rem;
    font-weight: 700;
    color: #fff;
    background: var(--wp-accent-gradient);
}

/* The cart badge is rendered by the CartSummary view component, which is also
   used by the admin header — so style the anchor it emits rather than changing
   the component's markup. */
.shop-cart .nav-link {
    padding: 0;
    color: inherit;
}

.shop-cart .badge {
    font-size: .7rem;
}

.shop-account-menu {
    min-width: 250px;
    padding-top: 0;
    border-color: var(--wp-border);
    box-shadow: var(--wp-shadow-lg);
}

.shop-account-identity {
    padding: .75rem 1rem;
    background: var(--wp-indigo-50);
    border-bottom: 1px solid var(--wp-border);
}

.shop-account-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem 1rem;
}

    .shop-account-menu .dropdown-item i {
        width: 16px;
        color: var(--wp-text-muted);
    }

    .shop-account-menu .dropdown-item:hover i {
        color: var(--wp-indigo-600);
    }

/* -------------------------------------------------------------- Category nav */

.shop-header-nav {
    border-top: 1px solid var(--wp-border);
    background: var(--wp-surface-raised);
}

    /* No overflow above the phone breakpoint: a scroll container clips the dropdown panel, which
       is absolutely positioned outside it. Wrapping costs nothing here and keeps the panel visible. */
    .shop-header-nav .shop-container {
        gap: .25rem;
        flex-wrap: wrap;
    }

    @media (max-width: 767.98px) {
        .shop-header-nav .shop-container {
            flex-wrap: nowrap;
            overflow-x: auto;
            scrollbar-width: none;
            -ms-overflow-style: none;
            -webkit-overflow-scrolling: touch;
        }

            .shop-header-nav .shop-container::-webkit-scrollbar {
                display: none;
            }
    }

.shop-nav-link {
    position: relative;
    padding: .5rem .8rem;
    margin: .3rem 0;
    border-radius: 999px;
    font-size: .92rem;
    font-weight: 500;
    color: var(--wp-text-muted);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease;
}

    .shop-nav-link:hover {
        color: var(--wp-purple-700);
        background: var(--wp-purple-50);
    }

    .shop-nav-link.active {
        color: #fff;
        background: var(--wp-purple-600);
        font-weight: 600;
    }

        .shop-nav-link.active:hover {
            color: #fff;
            background: var(--wp-purple-700);
        }

.shop-nav-group {
    display: inline-flex;
    align-items: center;
    position: relative;
    flex: 0 0 auto;
}

.shop-nav-parent {
    border: 0;
    background: transparent;
    font-family: inherit;
    cursor: pointer;
}

.shop-nav-panel {
    position: absolute;
    top: calc(100% + .25rem);
    left: 0;
    z-index: 30;
    width: max-content;
    max-width: min(46rem, calc(100vw - 2rem));
    padding: .6rem;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
    box-shadow: 0 12px 28px rgba(33, 27, 38, .14);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-.35rem);
    transition: opacity .16s ease, transform .16s ease, visibility .16s;
}

.shop-nav-panel-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: .1rem;
}

.shop-nav-panel.cols-2 .shop-nav-panel-grid {
    grid-template-columns: repeat(2, minmax(11rem, 1fr));
}

.shop-nav-panel.cols-3 .shop-nav-panel-grid {
    grid-template-columns: repeat(3, minmax(11rem, 1fr));
}

.shop-nav-panel-link {
    display: block;
    padding: .45rem .6rem;
    border-radius: var(--wp-radius-sm);
    color: var(--wp-text);
    font-size: .9rem;
    text-decoration: none;
    white-space: nowrap;
}

    .shop-nav-panel-link:hover {
        color: var(--wp-purple-700);
        background: var(--wp-purple-50);
    }

    .shop-nav-panel-link.active {
        color: var(--wp-purple-700);
        font-weight: 600;
    }

.shop-nav-panel-all {
    display: block;
    margin-top: .35rem;
    padding: .55rem .6rem;
    border-top: 1px solid var(--wp-border);
    border-radius: 0 0 var(--wp-radius-sm) var(--wp-radius-sm);
    color: var(--wp-purple-600);
    font-size: .85rem;
    font-weight: 600;
    text-decoration: none;
}

    .shop-nav-panel-all:hover {
        color: var(--wp-purple-700);
        background: var(--wp-purple-50);
    }

    .shop-nav-panel-all.active {
        color: var(--wp-purple-700);
        background: var(--wp-purple-50);
    }

/* Unguarded by a hover media query on purpose: the parent is a button that only opens the panel,
   never navigates, so hover cannot steal a tap the way it would from a link. Touch simply never
   fires it and uses the click handler instead. */
.shop-nav-group:hover .shop-nav-panel,
.shop-nav-group:focus-within .shop-nav-panel,
.shop-nav-group.open .shop-nav-panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.shop-nav-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1035;
    background: rgba(33, 27, 38, .4);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease, visibility .2s;
}

body.shop-nav-open .shop-nav-backdrop {
    opacity: 1;
    visibility: visible;
}

/* ------------------------------------------------------------ Mobile drawer */

/* Below the phone breakpoint the horizontal strip is replaced entirely: a scrolling row of pills
   hides most of the tree and leaves no room for a panel. The drawer shows every level at once. */
.shop-menu-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    margin-left: -.4rem;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--wp-text);
    font-size: 1.1rem;
    cursor: pointer;
}

    .shop-menu-toggle:hover {
        background: var(--wp-purple-50);
        color: var(--wp-purple-700);
    }

.shop-drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    width: min(20rem, 84vw);
    display: flex;
    flex-direction: column;
    background: var(--wp-surface-raised);
    box-shadow: 4px 0 24px rgba(33, 27, 38, .18);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .24s ease, visibility .24s;
}

body.shop-nav-open .shop-drawer {
    transform: translateX(0);
    visibility: visible;
}

.shop-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .9rem 1rem;
    border-bottom: 1px solid var(--wp-border);
}

.shop-drawer-title {
    font-weight: 700;
}

.shop-drawer-close {
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--wp-text-muted);
    font-size: 1rem;
    cursor: pointer;
}

.shop-drawer-nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: .5rem 0 calc(1rem + env(safe-area-inset-bottom));
}

.shop-drawer-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .8rem 1rem;
    color: var(--wp-text);
    font-size: .95rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}

    .shop-drawer-link.active {
        color: var(--wp-purple-700);
        font-weight: 700;
        background: var(--wp-purple-50);
    }

    .shop-drawer-link::-webkit-details-marker {
        display: none;
    }

.shop-drawer-group {
    border-bottom: 1px solid var(--wp-border);
}

    .shop-drawer-group > summary {
        list-style: none;
    }

    .shop-drawer-group[open] .shop-drawer-caret {
        transform: rotate(180deg);
    }

.shop-drawer-caret {
    font-size: .7rem;
    color: var(--wp-text-muted);
    transition: transform .18s ease;
}

.shop-drawer-children {
    padding-bottom: .35rem;
    background: var(--wp-surface);
}

.shop-drawer-child {
    display: block;
    padding: .65rem 1rem .65rem 1.75rem;
    color: var(--wp-text-muted);
    font-size: .9rem;
    text-decoration: none;
}

    .shop-drawer-child.active {
        color: var(--wp-purple-700);
        font-weight: 600;
    }

.shop-drawer-all {
    color: var(--wp-purple-600);
    font-weight: 600;
}

.shop-drawer-offers {
    color: var(--wp-orange);
    gap: .45rem;
    justify-content: flex-start;
}

@media (max-width: 767.98px) {
    .shop-menu-toggle {
        display: inline-flex;
    }

    .shop-header-nav {
        display: none;
    }
}

/* Offers sits apart from the categories: it is a promotion, not a section. */
.shop-nav-offers {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    margin-left: auto;
    color: var(--wp-orange);
    font-weight: 600;
}

    .shop-nav-offers:hover {
        color: #fff;
        background: var(--wp-orange);
    }

/* ----------------------------------------------------------------- Footer */

.shop-footer {
    flex-shrink: 0;
    padding: 1.25rem 0;
    background: var(--wp-surface-raised);
    border-top: 1px solid var(--wp-border);
    font-size: .93rem;
    color: var(--wp-text-muted);
}

.shop-footer-links {
    display: flex;
    gap: 1.25rem;
    margin-left: auto;
}

    .shop-footer-links a {
        color: var(--wp-text-muted);
        text-decoration: none;
    }

    .shop-footer-links a:hover {
        color: var(--wp-indigo-600);
    }

/* --------------------------------------------------------------- Responsive */

@media (max-width: 991.98px) {
    .shop-action-label {
        display: none;
    }

    .shop-action {
        min-width: 44px;
    }
}

@media (max-width: 767.98px) {
    .shop-header-main .shop-container {
        flex-wrap: wrap;
        gap: .75rem;
    }

    .shop-search {
        order: 3;
        flex-basis: 100%;
        max-width: none;
    }

    .shop-brand-logo {
        display: none;
    }

    .shop-brand-icon {
        display: block;
    }

    .shop-header-nav .shop-container {
        gap: .35rem;
        padding: 0 .75rem;
    }

    /* Count, view toggle and sort do not fit one line on a phone. The sort select takes its own
       row rather than shrinking to an unreadable width. */
    .shop-toolbar {
        flex-wrap: wrap;
    }

    .shop-sort {
        flex-basis: 100%;
        min-width: 0;
    }

    .shop-view-toggle {
        margin-left: auto;
    }

    .shop-view-btn {
        width: 2.75rem;
        padding: .45rem 0;
    }
}

/* Two columns on a phone rather than one: a single 320px-wide card per row means one product
   visible at a time, which is worse for browsing than a slightly smaller card. */
@media (max-width: 575.98px) {
    .shop-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: .625rem;
    }

    .shop-card-body {
        padding: .625rem;
    }

    .shop-card-title {
        font-size: .9rem;
    }
}

/* ================================================================= Catalogue */

#shopStrings {
    display: none;
}

.shop-layout {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

/* ------------------------------------------------------------------ Filters */

/* A sticky element taller than the viewport has nothing left to stick to — it scrolls out
   of view with the page and the "sticky" reads as broken. Capping the height fixes that,
   but the panel itself must NOT be the scroll container: doing that carries the heading and
   the Search button away with the content, so the filter count disappears exactly when it
   is most useful and the submit button ends up below the fold. Only .shop-filter-body
   scrolls; head and actions are pinned to the panel edges.
   The 110px matches the sticky offset; the extra 1.5rem is .shop-layout's gap. */
.shop-filters {
    position: sticky;
    top: 110px;
    max-height: calc(100vh - 110px - 1.5rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    box-shadow: var(--wp-shadow-sm);
}

/* min-height:0 on both the form and the body is what actually lets the scroll engage — a
   flex child defaults to min-height:auto and refuses to shrink below its content. */
.shop-filter-form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.shop-filter-head {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .8rem 1rem;
    font-weight: 600;
    border-bottom: 1px solid var(--wp-border);
}

.shop-filter-heading {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}

.shop-filter-head-actions {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
}

/* Only where the panel is an overlay. On desktop it is a column in the grid, so there is nothing
   to dismiss and a close button would just remove the filters from view for no reason. */
.shop-filter-close {
    display: none;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--wp-text-muted);
    font-size: 1rem;
    cursor: pointer;
}

    .shop-filter-close:hover {
        background: var(--wp-purple-50);
        color: var(--wp-purple-700);
    }

    .shop-filter-heading i {
        font-size: .85em;
        color: var(--wp-purple-600);
    }

/* The count is the reason the header is worth pinning: once the list is scrolled, this is
   the only thing still telling you the results are filtered at all. */
.shop-filter-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.2rem;
    height: 1.2rem;
    padding: 0 .35rem;
    font-size: .7rem;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: var(--wp-purple-600);
    border-radius: 999px;
}

.shop-filter-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 1rem;
    /* Scroll shadows, pure CSS. The two `local` gradients are painted in content space so
       they sit flush against the ends of the list; the two `scroll` radials are painted in
       viewport space and are therefore covered by the cover gradients at rest, emerging
       only when there is actually more to scroll in that direction. */
    background:
        linear-gradient(var(--wp-surface-raised) 30%, rgba(255, 255, 255, 0)) top / 100% 14px no-repeat local,
        linear-gradient(rgba(255, 255, 255, 0), var(--wp-surface-raised) 70%) bottom / 100% 14px no-repeat local,
        radial-gradient(farthest-side at 50% 0, rgba(31, 22, 38, .14), rgba(31, 22, 38, 0)) top / 100% 6px no-repeat scroll,
        radial-gradient(farthest-side at 50% 100%, rgba(31, 22, 38, .14), rgba(31, 22, 38, 0)) bottom / 100% 6px no-repeat scroll;
}

.shop-filter-actions {
    flex: 0 0 auto;
    padding: .75rem 1rem;
    border-top: 1px solid var(--wp-border);
}

.shop-filter-clear {
    font-size: .75rem;
    font-weight: 500;
    color: var(--wp-indigo-600);
    text-decoration: none;
}

.shop-filter-block {
    padding: .875rem 0;
    border-bottom: 1px solid var(--wp-border);
}

    .shop-filter-block:last-of-type {
        border-bottom: 0;
    }

.shop-filter-title {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--wp-text-muted);
    margin-bottom: .6rem;
}

.shop-filter-scroll {
    max-height: 190px;
    overflow-y: auto;
}

.shop-check {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .2rem 0;
    font-size: .93rem;
    cursor: pointer;
}

    .shop-check input {
        margin: 0;
        flex-shrink: 0;
    }

.shop-price-row {
    display: flex;
    align-items: center;
    gap: .4rem;
    color: var(--wp-text-muted);
}

/* Category tree */
.shop-cat-tree,
.shop-cat-tree ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

    .shop-cat-tree ul {
        padding-left: .75rem;
        border-left: 1px solid var(--wp-border);
        margin-left: .25rem;
    }

    .shop-cat-tree a {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .5rem;
        padding: .28rem .4rem;
        border-radius: 5px;
        font-size: .93rem;
        color: var(--wp-text);
        text-decoration: none;
    }

        .shop-cat-tree a:hover {
            background: var(--wp-indigo-50);
            color: var(--wp-indigo-700);
        }

        .shop-cat-tree a.active {
            background: var(--wp-indigo-50);
            color: var(--wp-indigo-700);
            font-weight: 600;
        }

.shop-cat-count {
    font-size: .94rem;
    color: var(--wp-text-muted);
    background: var(--wp-surface);
    border-radius: 999px;
    padding: 0 .4rem;
}

/* ------------------------------------------------------------------ Toolbar */

.shop-toolbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: 1rem;
}

.shop-result-count {
    font-size: 1rem;
    color: var(--wp-text-muted);
}

/* The view toggle carries the auto margin, so it and the sort select travel together on the
   right edge instead of splitting the free space between them. */
.shop-sort {
    min-width: 190px;
}

.shop-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: 1rem;
}

.shop-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .2rem .6rem;
    font-size: .94rem;
    background: var(--wp-indigo-50);
    color: var(--wp-indigo-700);
    border-radius: 999px;
}

.shop-chip-remove {
    color: inherit;
    text-decoration: none;
    font-size: 1rem;
    line-height: 1;
    opacity: .65;
}

    .shop-chip-remove:hover {
        opacity: 1;
        color: inherit;
    }

/* --------------------------------------------------------------- Product grid */

.shop-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 1rem;
}

/* List view. The square media block is what makes a card tall, so the list swaps it for a
   fixed-width thumbnail and lets the body run horizontally — roughly four times the
   products per screen without shrinking any text. */
.shop-grid.is-list {
    grid-template-columns: minmax(0, 1fr);
    gap: .625rem;
}

    .shop-grid.is-list .shop-card {
        flex-direction: row;
    }

    .shop-grid.is-list .shop-card-media {
        flex: 0 0 132px;
        width: 132px;
        aspect-ratio: auto;
    }

    .shop-grid.is-list .shop-card-body {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "vendor price"
            "title  price"
            "pv     cart";
        align-items: center;
        column-gap: 1rem;
        padding: .75rem 1rem;
    }

    .shop-grid.is-list .shop-card-vendor {
        grid-area: vendor;
    }

    .shop-grid.is-list .shop-card-title {
        grid-area: title;
        align-self: start;
        /* The grid view reserves two lines to keep a row aligned; a list row is one line, so the
           reservation would only add dead space here. */
        min-height: 0;
    }

        /* Two-line clamping earns its keep in a narrow grid cell; across a full-width row
           the title fits, and clamping it there only truncates for no reason. */
        .shop-grid.is-list .shop-card-title a {
            -webkit-line-clamp: 1;
        }

    .shop-grid.is-list .shop-card-price {
        grid-area: price;
        justify-self: end;
    }

    .shop-grid.is-list .shop-pv {
        grid-area: pv;
    }

    .shop-grid.is-list .shop-card-body .add-to-cart {
        grid-area: cart;
        justify-self: end;
        margin-top: 0;
    }

        .shop-grid.is-list .shop-card-body .add-to-cart .btn {
            width: auto;
            padding-inline: 1rem;
        }

@media (max-width: 575.98px) {
    /* Below this the row collapses to something narrower than the thumbnail, so list and
       grid would render identically anyway — drop back to the card layout. */
    .shop-grid.is-list .shop-card {
        flex-direction: column;
    }

    .shop-grid.is-list .shop-card-media {
        flex: none;
        width: 100%;
        aspect-ratio: 1 / 1;
    }

    .shop-grid.is-list .shop-card-body {
        display: flex;
        flex-direction: column;
    }
}

/* ------------------------------------------------------------- View switcher */

.shop-view-toggle {
    display: inline-flex;
    margin-left: auto;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    overflow: hidden;
}

.shop-view-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    padding: .3rem 0;
    border: 0;
    background: var(--wp-surface-raised);
    color: var(--wp-text-muted);
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

    .shop-view-btn + .shop-view-btn {
        border-left: 1px solid var(--wp-border);
    }

    .shop-view-btn:hover {
        color: var(--wp-text);
    }

    .shop-view-btn[aria-pressed="true"] {
        background: var(--wp-purple-50);
        color: var(--wp-purple-700);
    }

.shop-card {
    position: relative;
    display: flex;
    flex-direction: column;
    /* Explicit rather than relying on the grid's default stretch, so a future align-items change
       cannot silently leave a row of ragged cards. */
    height: 100%;
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: 12px;
    overflow: hidden;
    transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}

    .shop-card:hover {
        box-shadow: 0 12px 28px rgba(31, 22, 38, .12);
        border-color: var(--wp-purple-100);
        transform: translateY(-3px);
    }

/* The add-to-cart button stays out of the way until the card is engaged with,
   so the grid reads as products rather than as a wall of buttons. */
.shop-card-body .add-to-cart .btn {
    opacity: .85;
    transition: opacity .18s ease;
}

.shop-card:hover .add-to-cart .btn,
.shop-card:focus-within .add-to-cart .btn {
    opacity: 1;
}

.shop-card-media {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    background: var(--wp-surface);
    overflow: hidden;
}

    .shop-card-media img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform .3s ease;
    }

.shop-card:hover .shop-card-media img {
    transform: scale(1.04);
}

.shop-card-noimage {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: 1.75rem;
    color: var(--wp-border-strong);
}

.shop-badge {
    position: absolute;
    top: .5rem;
    left: .5rem;
    padding: .15rem .5rem;
    font-size: .92rem;
    font-weight: 700;
    border-radius: 4px;
    color: #fff;
}

.shop-badge-offer {
    background: var(--wp-success);
}

.shop-badge-out {
    top: auto;
    bottom: .5rem;
    background: var(--wp-text-muted);
}

.shop-card-body {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding: .75rem;
    flex: 1 1 auto;
}

/* Truncated rather than wrapped: a long vendor name would take a second line and push the whole
   column down again, which is the problem the title min-height exists to solve. */
.shop-card-vendor {
    font-size: .94rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--wp-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Two lines are reserved whether or not the name needs both. The title is the only element that
   changes height between cards, so without this the price, PV badge and button step down by a
   line on any product with a longer name and the row stops reading as a grid. 2.6em = the
   clamped two lines at line-height 1.3. */
.shop-card-title {
    font-size: .97rem;
    font-weight: 600;
    line-height: 1.3;
    min-height: 2.6em;
    margin: 0;
}

    .shop-card-title a {
        color: var(--wp-text);
        text-decoration: none;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

        .shop-card-title a:hover {
            color: var(--wp-indigo-600);
        }

.shop-card-price {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    margin-top: .1rem;
}

.shop-price {
    font-size: 1.05rem;
    font-weight: 700;
}

.shop-price-was {
    font-size: .85rem;
    color: var(--wp-text-muted);
    text-decoration: line-through;
}

.shop-pv {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    align-self: flex-start;
    font-size: .78rem;
    font-weight: 600;
    padding: .1rem .45rem;
    border-radius: 4px;
    color: var(--wp-violet-600);
    background: #fdf3e3;
}

.shop-card-body .add-to-cart {
    margin-top: auto;
    padding-top: .5rem;
}

.shop-empty {
    text-align: center;
    padding: 4rem 1rem;
    color: var(--wp-text-muted);
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
}

    .shop-empty i {
        font-size: 2rem;
        opacity: .5;
        display: block;
        margin-bottom: .5rem;
    }

.shop-pager {
    display: flex;
    justify-content: center;
    margin-top: 1.5rem;
}

/* --------------------------------------------------------------- Responsive */

@media (max-width: 991.98px) {
    .shop-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Off-canvas drawer rather than a stacked block, so filters never push the
       grid below the fold on a phone. */
    .shop-filters {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 1045;
        width: 290px;
        max-width: 85vw;
        /* top/bottom pin the drawer to the full viewport here, so the desktop height cap
           has to be lifted or the drawer stops short of the bottom edge. Scrolling stays on
           .shop-filter-body, same as desktop — the drawer's header and Search button are
           worth pinning on a phone even more than they are on a desktop. */
        max-height: none;
        border-radius: 0;
        overflow: hidden;
        transform: translateX(-100%);
        transition: transform .22s ease;
    }

    .shop-filters-open {
        transform: none;
        box-shadow: var(--wp-shadow-lg);
    }

    .shop-filter-close {
        display: inline-flex;
    }
}

/* Its own body class, not the drawer's: sharing one was what let the category nav's outside-click
   close the drawer. Both dim the same element, neither knows about the other. */
body.shop-filter-open .shop-nav-backdrop {
    opacity: 1;
    visibility: visible;
}

/* ====================================================================== Cart */

.cart-heading {
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -.02em;
    margin-bottom: 1rem;
}

.cart-heading-count {
    font-weight: 500;
    color: var(--wp-text-muted);
}

.cart-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 1.5rem;
    align-items: start;
}

.cart-group {
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    margin-bottom: 1rem;
    overflow: hidden;
}

.cart-group-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .65rem 1rem;
    background: var(--wp-surface);
    border-bottom: 1px solid var(--wp-border);
    font-size: .97rem;
    font-weight: 600;
    color: var(--wp-text-muted);
}

    .cart-group-head i {
        color: var(--wp-indigo-500);
    }

.cart-line {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr) auto;
    gap: 1rem;
    padding: 1rem;
    border-bottom: 1px solid var(--wp-border);
    transition: opacity .15s ease, background-color .15s ease;
}

    .cart-line:last-child {
        border-bottom: 0;
    }

.cart-line-busy {
    opacity: .45;
    pointer-events: none;
}

.cart-line-warn {
    background: #fffbeb;
}

.cart-line-saved {
    opacity: .92;
}

.cart-line-media {
    width: 84px;
    height: 84px;
    border-radius: 6px;
    overflow: hidden;
    background: var(--wp-surface);
}

    .cart-line-media img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

.cart-line-info {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
}

.cart-line-name {
    font-weight: 600;
    font-size: 1rem;
    color: var(--wp-text);
    text-decoration: none;
}

    .cart-line-name:hover {
        color: var(--wp-indigo-600);
    }

.cart-line-gift {
    display: inline-flex;
    align-items: center;
    padding: .1rem .45rem;
    font-size: .78rem;
    font-weight: 600;
    color: var(--wp-purple-700);
    background: var(--wp-purple-50);
    border-radius: 4px;
}

.cart-line-meta {
    font-size: .92rem;
    color: var(--wp-text-muted);
}

.cart-line-stock {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .94rem;
    font-weight: 500;
    color: var(--wp-warning);
}

.cart-line-actions {
    display: flex;
    gap: 1rem;
    margin-top: auto;
    padding-top: .35rem;
}

.cart-link {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    border: 0;
    background: none;
    padding: 0;
    font-size: .94rem;
    color: var(--wp-text-muted);
    cursor: pointer;
}

    .cart-link:hover {
        color: var(--wp-indigo-600);
    }

    .cart-link.cart-remove:hover {
        color: var(--wp-danger);
    }

.cart-line-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .35rem;
    text-align: right;
    white-space: nowrap;
}

.cart-line-total {
    font-size: 1rem;
    font-weight: 700;
}

.cart-line-unit {
    font-size: .78rem;
    color: var(--wp-text-muted);
}

/* Stepper */
.cart-qty-group {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--wp-border-strong);
    border-radius: 6px;
    overflow: hidden;
    margin-top: auto;
}

.cart-step {
    width: 30px;
    height: 30px;
    border: 0;
    background: var(--wp-surface);
    color: var(--wp-text);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

    .cart-step:hover {
        background: var(--wp-indigo-50);
        color: var(--wp-indigo-700);
    }

.cart-qty {
    width: 46px;
    height: 30px;
    border: 0;
    border-left: 1px solid var(--wp-border);
    border-right: 1px solid var(--wp-border);
    text-align: center;
    font-size: .93rem;
    -moz-appearance: textfield;
}

    .cart-qty::-webkit-outer-spin-button,
    .cart-qty::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

/* ---------------------------------------------------------------- Summary */

.cart-summary {
    position: sticky;
    top: 110px;
}

.cart-summary-card {
    background: var(--wp-surface-raised);
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    overflow: hidden;
    box-shadow: var(--wp-shadow-sm);
}

.cart-summary-head {
    padding: .75rem 1rem;
    font-weight: 600;
    border-bottom: 1px solid var(--wp-border);
}

.cart-summary-body {
    padding: 1rem;
}

.cart-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    font-size: 1rem;
    padding: .25rem 0;
}

.cart-row-total {
    margin-top: .5rem;
    padding-top: .65rem;
    border-top: 1px solid var(--wp-border);
    font-size: 1.05rem;
    font-weight: 700;
}

.cart-ship {
    margin-top: .85rem;
}

.cart-ship-text {
    font-size: .94rem;
    color: var(--wp-text-muted);
    margin-bottom: .35rem;
}

.cart-ship-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--wp-surface);
    overflow: hidden;
}

    .cart-ship-bar span {
        display: block;
        height: 100%;
        border-radius: 999px;
        background: var(--wp-accent-gradient);
        transition: width .3s ease;
    }

.cart-ship-earned {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-top: .75rem;
    font-size: .85rem;
    font-weight: 600;
    color: var(--wp-success);
}

/* The MLM panel — the reason this is not a generic cart. */
.cart-earn {
    padding: .9rem 1rem;
    background: linear-gradient(135deg, var(--wp-indigo-50) 0%, #fdf3e3 100%);
    border-top: 1px solid var(--wp-border);
    border-bottom: 1px solid var(--wp-border);
}

.cart-earn-head {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .94rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--wp-violet-600);
    margin-bottom: .5rem;
}

.cart-earn-note {
    font-size: .94rem;
    color: var(--wp-text-muted);
    margin-top: .45rem;
    line-height: 1.4;
}

.cart-summary-foot {
    padding: 1rem;
}

.cart-min-note {
    font-size: .94rem;
    color: var(--wp-warning);
    margin-bottom: .5rem;
}

@media (max-width: 991.98px) {
    .cart-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    .cart-summary {
        position: static;
    }
}

@media (max-width: 575.98px) {
    .cart-line {
        grid-template-columns: 64px minmax(0, 1fr);
    }

    .cart-line-media {
        width: 64px;
        height: 64px;
    }

    .cart-line-right {
        grid-column: 2;
        align-items: flex-start;
        text-align: left;
    }
}

/* ========================================================== Product gallery */

.product-stage {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: 10px;
    overflow: hidden;
    background: var(--wp-surface);
    cursor: zoom-in;
}

.product-main {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: opacity .15s ease;
}

/* Magnified copy painted as a background, panned by --zoom-x/--zoom-y from the
   pointer. Cheaper than transforming the <img> and never overflows the frame. */
.product-stage.zooming {
    background-image: var(--zoom-src);
    background-repeat: no-repeat;
    background-size: 220%;
    background-position: var(--zoom-x, 50%) var(--zoom-y, 50%);
}

    .product-stage.zooming .product-main {
        opacity: 0;
    }

    .product-stage.zooming .product-zoom-hint {
        opacity: 0;
    }

.product-zoom-hint {
    position: absolute;
    right: .6rem;
    bottom: .6rem;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: .85rem;
    color: var(--wp-text);
    background: rgba(255, 255, 255, .9);
    box-shadow: var(--wp-shadow-sm);
    transition: opacity .15s ease;
    pointer-events: none;
}

.product-thumbs {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .75rem;
}

.product-thumb {
    width: 66px;
    height: 66px;
    object-fit: cover;
    border-radius: 8px;
    border: 2px solid var(--wp-border);
    cursor: pointer;
    transition: border-color .15s ease, transform .15s ease;
}

    .product-thumb:hover {
        transform: translateY(-2px);
    }

    .product-thumb.active {
        border-color: var(--wp-purple-600);
    }

/* ----------------------------------------------------------------- Lightbox */

body.lightbox-open {
    overflow: hidden;
}

.product-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2.5rem;
    background: rgba(31, 22, 38, .92);
    cursor: zoom-out;
}

    .product-lightbox[hidden] {
        display: none;
    }

    .product-lightbox img {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
        border-radius: 6px;
        cursor: default;
    }

.product-lightbox-close,
.product-lightbox-nav {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    color: #fff;
    background: rgba(255, 255, 255, .14);
    cursor: pointer;
    transition: background-color .15s ease;
}

    .product-lightbox-close:hover,
    .product-lightbox-nav:hover {
        background: rgba(255, 255, 255, .28);
    }

.product-lightbox-close {
    top: 1rem;
    right: 1rem;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    font-size: 1.6rem;
    line-height: 1;
}

.product-lightbox-nav {
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 64px;
    border-radius: 8px;
    font-size: 2rem;
    line-height: 1;
}

    .product-lightbox-nav.prev {
        left: 1rem;
    }

    .product-lightbox-nav.next {
        right: 1rem;
    }

.product-lightbox-count {
    position: absolute;
    bottom: 1.25rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: 1rem;
    color: rgba(255, 255, 255, .8);
}

@media (max-width: 767.98px) {
    .product-lightbox {
        padding: 1rem;
    }

    /* Touch has no hover, so the magnifier never engages — tap opens the lightbox. */
    .product-stage.zooming {
        background-image: none;
    }

        .product-stage.zooming .product-main {
            opacity: 1;
        }
}

/* ============================================================ Button sheen
   REVERTABLE: delete this whole block to return every storefront button to a flat fill.
   Nothing else references --wp-btn-sheen, and no markup depends on it.

   Scoped to .shop-body so the admin and vendor chrome is untouched. Applied only to the
   primary actions — outline and ghost buttons stay flat, which is what keeps this from
   reading as decoration. Offers keeps its amber fill: two competing gradients inches
   apart is the failure mode here.
   ------------------------------------------------------------------------ */

.shop-body .btn-primary,
.shop-search-go,
.shop-nav-link.active {
    background-image: var(--wp-btn-sheen);
}

/* Offers: the one storefront surface that carries two logo hues rather than a single-hue sheen.
   It is the arc of the mark, amber into orange, and it is the only element here whose job is to
   be noticed — every category pill beside it stays purple.

   Hover darkens with filter, not a second gradient: background-image does not interpolate, so
   swapping gradients would snap where every neighbouring pill fades. Both states are declared
   because the base rule above uses the background shorthand, which resets background-image. */
.shop-nav-offers,
.shop-nav-offers:hover {
    color: #fff;
    background-color: var(--wp-orange);
    background-image: linear-gradient(160deg, var(--wp-amber-400) 0%, var(--wp-orange) 100%);
}

.shop-nav-offers {
    transition: filter .15s ease;
}

    .shop-nav-offers:hover {
        filter: brightness(.93);
    }

/* Confirmation lands on the button itself, where the eye already is — the toast sits in a corner
   and is gone in four seconds, which is no help on a grid of near-identical cards. */
.add-to-cart-pulse {
    animation: add-to-cart-pop .45s ease;
}

@keyframes add-to-cart-pop {
    0% { transform: scale(1); }
    40% { transform: scale(1.05); }
    100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .add-to-cart-pulse {
        animation: none;
    }
}

/* Breadcrumb: the storefront had no "where am I" signal at all, which is the one piece of
   navigation a first-time visitor reads without being taught. It replaces the category tree that
   used to sit in the filter panel — categories now live in the nav only, so nothing is duplicated. */
.shop-crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
    margin: 0 0 1rem;
    font-size: .9rem;
    color: var(--wp-text-muted);
}

    .shop-crumbs a {
        color: var(--wp-purple-600);
        text-decoration: none;
    }

    .shop-crumbs a:hover {
        text-decoration: underline;
    }

    .shop-crumbs span[aria-current] {
        color: var(--wp-text);
        font-weight: 600;
    }

.shop-crumb-sep {
    font-size: .7rem;
    color: var(--wp-border-strong);
}

/* Related products reuse .shop-grid, so a card in the strip is the same card as in the listing —
   one set of rules, and the two can never drift apart visually. */
.shop-related {
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--wp-border);
}

.shop-related-title {
    margin: 0 0 1.1rem;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -.01em;
}

/* Specifications */

.shop-specs {
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--wp-border);
}

.shop-specs-title {
    margin: 0 0 1.1rem;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -.01em;
}

.shop-specs-table {
    max-width: 640px;
    margin: 0;
}

.shop-specs-table th {
    width: 40%;
    font-weight: 600;
    color: var(--wp-text-muted);
}

.shop-specs-table td {
    font-weight: 500;
}
