/* ============================================================
   newdgrie/default — _20_listing.css

   Catalog category listing page (Custom Suits / Pants / Shirts).
   Loaded only on catalog_category_view via local.xml.

   Reference: mockup screenshots — quiet luxury, generous
   whitespace, 2-column desktop (sidebar + grid), single column
   on mobile with floating Filters button.

   Sections:
     1. Page wrapper + header (h1 + subhead)
     2. 2-col row (sidebar + main)
     3. Sidebar (filter groups)
     4. Toolbar (count, sort, view)
     5. Product grid + card
     6. Empty state
     7. Pager (bottom toolbar)
     8. Mobile floating Filters button
     9. Responsive
   ============================================================ */


/* ════════════════════════════════════════════════════════════
   1. WRAPPER + HEADER
   ════════════════════════════════════════════════════════════ */

.dg-listing {
    background: var(--dg-paper);
    padding: 0 0 clamp(80px, 10vw, 140px);
}

.dg-listing__head {
    max-width: var(--dg-container-max);
    margin: 0 auto clamp(36px, 5vw, 72px);
    padding: 0 var(--dg-gutter);
}

/* Banner mode — when category has an Image uploaded.
   The image is set inline via style="background-image: url(...)".
   We fix a tall-letterbox height (~banner) and use background-size:
   cover + center so the image fills the frame and the overflow is
   clipped by the container. Text sits on top via z-index. */
.dg-listing__head.has-banner {
    position: relative;
    max-width: none;                       /* full-bleed banner */
    padding: clamp(52px, 7vw, 96px) var(--dg-gutter);
    margin-bottom: clamp(36px, 5vw, 72px);
    min-height: clamp(224px, 25.6vw, 352px);
    background-color: var(--dg-stone);
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Soft white scrim so text stays readable over any photo.
   Sits between the image (background) and the content. */
.dg-listing__head.has-banner::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.55) 0%,
        rgba(255, 255, 255, 0.75) 100%
    );
    z-index: 1;
}

.dg-listing__head.has-banner .dg-listing__head-inner {
    position: relative;
    z-index: 2;
    max-width: 720px;
}

.dg-listing__head-inner {
    max-width: 920px;
}

.dg-listing__title {
    font-family: var(--dg-font-serif);
    font-size: clamp(40px, 6vw, 76px);
    font-weight: var(--dg-weight-regular);
    line-height: 1.05;
    letter-spacing: -0.005em;
    color: var(--dg-ink);
    margin: 0 0 clamp(16px, 2vw, 24px);
}

.dg-listing__sub {
    font-family: var(--dg-font-sans);
    font-size: clamp(15px, 1.4vw, 17px);
    line-height: 1.6;
    color: var(--dg-muted);
    margin: 0 auto;
    max-width: 640px;
}

/* No-banner mode — when a category has no Image uploaded
   (e.g. cat 145 /custom/, or a sub-cat before its photoshoot
   is published). Renders as a centered editorial header on
   a cream background — same vertical rhythm as banner mode,
   minus the image. Once an Image is uploaded in admin, the
   .has-banner class kicks in and overrides this. */
.dg-listing__head:not(.has-banner) {
    max-width: none;                       /* full-bleed like banner */
    margin-left: 0;
    margin-right: 0;
    padding: clamp(52px, 7vw, 96px) var(--dg-gutter);
    margin-bottom: clamp(36px, 5vw, 72px);
    background-color: var(--dg-cream);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dg-listing__head:not(.has-banner) .dg-listing__head-inner {
    max-width: 720px;
    margin: 0 auto;
}
.dg-listing__head:not(.has-banner) .dg-listing__sub {
    margin: 0 auto;
    max-width: 640px;
}


/* ════════════════════════════════════════════════════════════
   2. 2-COL ROW — sidebar + main
   ════════════════════════════════════════════════════════════ */

.dg-listing__row {
    max-width: var(--dg-container-max);
    margin: 0 auto;
    padding: 0 var(--dg-gutter);
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: clamp(32px, 4vw, 64px);
    align-items: start;
}

/* When category is non-anchored (no filters), expand to single column */
.dg-listing__row.is-no-sidebar {
    grid-template-columns: 1fr;
}

.dg-listing__main {
    min-width: 0;  /* prevent grid blow-out */
}


/* ════════════════════════════════════════════════════════════
   3. SIDEBAR (filter groups)
   ════════════════════════════════════════════════════════════ */

.dg-listing__sidebar {
    /* Plain block — no sticky. With many filters (Pants has ~9
       groups), sticky would either crop the bottom of the sidebar
       on shorter viewports or require a nested scroll, both of
       which feel worse than letting the sidebar scroll with the
       page. We keep this as a normal column. */
    align-self: start;
}

.dg-listing__sidebar-close {
    /* Hidden on desktop; shown when sidebar becomes a drawer on mobile */
    display: none;
    position: absolute;
    top: 16px;
    right: 16px;
    width: 44px;
    height: 44px;
    background: transparent;
    border: 0;
    color: var(--dg-ink);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
}

/* Filter group structure (.dg-filter-group is rendered by
   the layered nav block — view.phtml + filter.phtml) */
.dg-filter-group {
    border-bottom: 1px solid var(--dg-line);
    padding: 18px 0;
}
.dg-filter-group:first-child { padding-top: 0; }

/* The CATEGORIES section sits at the top — it doesn't get the
   collapsible toggle, just a list */
.dg-filter-group--categories {
    border-bottom: 1px solid var(--dg-line);
    padding-bottom: 24px;
    margin-bottom: 8px;
}

.dg-filter-group__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: var(--dg-ink);
    text-align: left;
    font-family: var(--dg-font-sans);
    font-size: 14px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: 0.10em;
    text-transform: uppercase;
}

.dg-filter-group__toggle {
    color: var(--dg-muted);
    font-size: 18px;
    line-height: 1;
    transition: transform var(--dg-duration-fast) var(--dg-ease);
}

.dg-filter-group[data-state="closed"] .dg-filter-group__body {
    display: none;
}

.dg-filter-group__body {
    margin-top: 14px;
}


/* Categories list (top of sidebar) */
.dg-filter-cats {
    list-style: none;
    margin: 16px 0 0;            /* breathing room below "Categories" heading */
    padding: 0;
}
.dg-filter-cats__item {
    position: relative;
    margin-bottom: 4px;          /* gap between SUITS / PANTS / SHIRTS items */
}
.dg-filter-cats__item:last-child { margin-bottom: 0; }

.dg-filter-cats__link {
    display: block;
    padding: 10px 0 10px 14px;   /* slightly more vertical room per item */
    font-size: 14px;
    color: var(--dg-ink-soft);
    text-decoration: none;
    transition: color var(--dg-duration-fast) var(--dg-ease);
}
.dg-filter-cats__link:hover { color: var(--dg-ink); }
.dg-filter-cats__item.is-current .dg-filter-cats__link {
    color: var(--dg-ink);
    font-weight: var(--dg-weight-medium);
}
.dg-filter-cats__item.is-current::before {
    content: "";
    position: absolute;
    left: 0;
    top: 12px;
    bottom: 12px;
    width: 1px;
    background: var(--dg-ink);
}


/* Filter list (default — checkbox style) */
.dg-filter-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.dg-filter-list__item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 6px 0;
}
.dg-filter-list__item a {
    font-size: 14px;
    color: var(--dg-ink-soft);
    text-decoration: none;
    transition: color var(--dg-duration-fast) var(--dg-ease);
    flex: 1;
}
.dg-filter-list__item a:hover { color: var(--dg-ink); }
.dg-filter-list__count {
    font-size: 12px;
    color: var(--dg-faint);
    margin-left: 8px;
}


/* Color swatches grid */
.dg-filter-colors {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.dg-filter-colors__item { aspect-ratio: 1 / 1; }
.dg-filter-colors__btn {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 1px solid var(--dg-line);
    cursor: pointer;
    transition: border-color var(--dg-duration-fast) var(--dg-ease),
                transform var(--dg-duration-fast) var(--dg-ease);
    text-decoration: none;
    position: relative;
}
.dg-filter-colors__btn:hover {
    transform: scale(1.08);
    border-color: var(--dg-ink);
}
.dg-filter-colors__btn.is-active {
    border: 2px solid var(--dg-ink);
}
/* Selected indicator inside swatch */
.dg-filter-colors__btn.is-active::after {
    content: "✓";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    text-shadow: 0 1px 2px rgba(0,0,0,0.4);
    font-size: 12px;
}


/* State (active filters chips) — rendered by state.phtml */
.dg-filter-state {
    margin-bottom: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--dg-line);
}
.dg-filter-state__title {
    font-size: 11px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-faint);
    margin: 0 0 10px;
}
.dg-filter-state__list {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.dg-filter-state__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: var(--dg-stone);
    color: var(--dg-ink);
    font-size: 12px;
    text-decoration: none;
}
.dg-filter-state__chip:hover { background: var(--dg-line); }
.dg-filter-state__remove {
    color: var(--dg-muted);
    font-size: 14px;
    line-height: 1;
}
.dg-filter-state__clear {
    font-size: 11px;
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-muted);
    text-decoration: underline;
    text-underline-offset: 3px;
}


/* ════════════════════════════════════════════════════════════
   4. TOOLBAR (top + bottom)
   ════════════════════════════════════════════════════════════ */

.dg-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 24px;
    padding: 0 0 28px;
    border-bottom: 1px solid var(--dg-line);
    margin-bottom: 48px;
    font-size: 13px;
}

/* The bottom toolbar is the SECOND .dg-toolbar inside .dg-listing__main.
   We target by position because Magento renders both toolbars through
   the same template but doesn't reliably tag which is which.
   Same flex layout as top toolbar — just push it down with margin. */
.dg-listing__main .dg-toolbar:nth-of-type(2),
.dg-listing__main .dg-toolbar:last-of-type,
.dg-toolbar--bottom {
    padding: 40px 0 0;
    margin: 64px 0 0;
}

.dg-toolbar__count {
    font-family: var(--dg-font-sans);
    font-size: 14px;
    color: var(--dg-ink);
    font-weight: var(--dg-weight-medium);
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
}
.dg-toolbar__count-label {
    color: var(--dg-muted);
    font-weight: var(--dg-weight-regular);
}

.dg-toolbar__controls {
    display: inline-flex;
    align-items: center;
    gap: 18px;
}

.dg-toolbar__sort,
.dg-toolbar__view {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.dg-toolbar__label {
    font-size: 11px;
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-faint);
}
.dg-toolbar__select {
    background: transparent;
    border: 0;
    font-family: var(--dg-font-sans);
    font-size: 11px;
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-ink);
    cursor: pointer;
    padding: 6px 22px 6px 0;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6' fill='none' stroke='%231a1a1a' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='1 1 5 5 9 1'/></svg>");
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 9px;
}
.dg-toolbar__select:focus { outline: 0; }

.dg-toolbar__divider {
    color: var(--dg-line);
    font-weight: var(--dg-weight-light);
}


/* ════════════════════════════════════════════════════════════
   5. PRODUCT GRID + CARD
   ════════════════════════════════════════════════════════════ */

.dg-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(16px, 2vw, 28px) clamp(14px, 1.6vw, 22px);
}
.dg-grid--3up { grid-template-columns: repeat(3, 1fr); }
.dg-grid--2up { grid-template-columns: repeat(2, 1fr); }

.dg-grid__item { display: block; }


/* CARD */
.dg-card {
    display: block;
    text-decoration: none;
    color: var(--dg-ink);
}

.dg-card__media {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--dg-stone);
    overflow: hidden;
    margin-bottom: 12px;
}

.dg-card__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Two-image stack: primary + hover.
   Both fill the media frame. Hover sits on top with opacity 0
   and fades in when the user hovers the card. On touch devices
   we skip the swap so users on phones see the primary image. */
.dg-card.has-hover .dg-card__img--primary,
.dg-card.has-hover .dg-card__img--hover {
    position: absolute;
    inset: 0;
    transition: opacity 350ms var(--dg-ease);
}
.dg-card.has-hover .dg-card__img--primary { opacity: 1; z-index: 1; }
.dg-card.has-hover .dg-card__img--hover   { opacity: 0; z-index: 0; }

@media (hover: hover) {
    .dg-card.has-hover:hover .dg-card__img--primary { opacity: 0; }
    .dg-card.has-hover:hover .dg-card__img--hover   { opacity: 1; z-index: 2; }
}

/* Badges — NEW / LIMITED sit ON the fabric, top-left */
.dg-card__badge {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 2;
    display: inline-block;
    padding: 6px 12px;
    font-family: var(--dg-font-sans);
    font-size: 10px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-paper);
}
.dg-card__badge--new     { background: var(--dg-ink); }
.dg-card__badge--limited { background: var(--dg-gold); }


/* Wishlist heart — sits ON the fabric, bottom-right.
   States:
     default          → outline heart on paper bg
     hover            → ink bg (paper outline)
     [data-in-wishlist="1"]
                      → gold filled heart, paper bg
     [disabled]       → during in-flight AJAX (briefly) */
.dg-card__wishlist {
    position: absolute;
    bottom: 12px;
    right: 12px;
    z-index: 2;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--dg-paper);
    border: 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--dg-ink);
    box-shadow: var(--dg-shadow-sm);
    transition: background var(--dg-duration-fast) var(--dg-ease),
                color var(--dg-duration-fast) var(--dg-ease),
                transform var(--dg-duration-fast) var(--dg-ease);
}
.dg-card__wishlist:hover {
    background: var(--dg-ink);
    color: var(--dg-paper);
}

/* Filled state — gold heart, persistent paper bg.
   The svg's path uses fill: currentColor when this attribute
   is set, giving a nice solid heart shape. */
.dg-card__wishlist[data-in-wishlist="1"] {
    color: var(--dg-gold);
    background: var(--dg-paper);
}
.dg-card__wishlist[data-in-wishlist="1"] svg {
    fill: currentColor;
}
.dg-card__wishlist[data-in-wishlist="1"]:hover {
    /* Keep the gold but darken the bg slightly to show
       hover affordance. */
    background: var(--dg-cream);
    color: var(--dg-gold);
}

/* Tactile click feedback */
.dg-card__wishlist:active {
    transform: scale(0.92);
}
.dg-card__wishlist[disabled] {
    opacity: 0.6;
    cursor: wait;
}


/* Compare button — sits LEFT of wishlist heart at bottom-right.
   Same look as wishlist (paper circle, ink icon) but with a
   compare arrow glyph (⇄). When the product is in the compare
   list, the icon turns gold like the wishlist filled state.
   Layout: wishlist sits at right:12; compare sits at right:56
   (12 + 36 width + 8 gap). */
.dg-card__compare {
    position: absolute;
    bottom: 12px;
    right: 56px;
    z-index: 2;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--dg-paper);
    border: 0;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--dg-ink);
    box-shadow: var(--dg-shadow-sm);
    transition: background var(--dg-duration-fast) var(--dg-ease),
                color var(--dg-duration-fast) var(--dg-ease),
                transform var(--dg-duration-fast) var(--dg-ease);
}
.dg-card__compare:hover {
    background: var(--dg-ink);
    color: var(--dg-paper);
}

/* Active state — gold icon when in compare list.
   We keep the bg paper (rather than filling like the heart)
   because the compare glyph is two arrows; "filling" doesn't
   make visual sense the way a filled heart does. */
.dg-card__compare[data-in-compare="1"] {
    color: var(--dg-gold);
    background: var(--dg-paper);
}
.dg-card__compare[data-in-compare="1"]:hover {
    background: var(--dg-cream);
    color: var(--dg-gold);
}

.dg-card__compare:active {
    transform: scale(0.92);
}
.dg-card__compare[disabled] {
    opacity: 0.6;
    cursor: wait;
}


/* Card body */
.dg-card__body {
    padding-top: 4px;
}

.dg-card__name {
    font-family: var(--dg-font-sans);
    font-size: 14px;
    font-weight: var(--dg-weight-regular);
    color: var(--dg-ink);
    margin: 0 0 4px;
    line-height: 1.3;
}

.dg-card__meta {
    font-family: var(--dg-font-sans);
    font-size: 11px;
    letter-spacing: var(--dg-track-wider);
    text-transform: uppercase;
    color: var(--dg-faint);
    margin: 0 0 6px;
    line-height: 1.4;
}

.dg-card__price {
    font-family: var(--dg-font-sans);
    font-size: 14px;
    color: var(--dg-ink);
    font-weight: var(--dg-weight-regular);
}


/* ════════════════════════════════════════════════════════════
   6. EMPTY STATE
   ════════════════════════════════════════════════════════════ */

.dg-listing__empty {
    text-align: center;
    padding: clamp(60px, 10vw, 120px) var(--dg-gutter);
}
.dg-listing__empty-msg {
    font-family: var(--dg-font-serif);
    font-size: clamp(20px, 2.4vw, 26px);
    color: var(--dg-ink);
    margin: 0 0 12px;
    font-style: italic;
}
.dg-listing__empty-sub {
    font-size: 14px;
    color: var(--dg-muted);
    margin: 0;
}


/* ════════════════════════════════════════════════════════════
   7. PAGER (bottom toolbar)
   ════════════════════════════════════════════════════════════ */

.dg-pager {
    display: inline-flex;
    align-items: center;
    gap: 16px;
}
.dg-pager__nav {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-ink);
    text-decoration: none;
    padding: 8px 12px;
    transition: color var(--dg-duration-fast) var(--dg-ease);
}
.dg-pager__nav:hover { color: var(--dg-gold); }

.dg-pager__pages {
    list-style: none;
    margin: 0;
    padding: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.dg-pager__page {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    font-size: 13px;
    color: var(--dg-ink-soft);
    text-decoration: none;
    transition: color var(--dg-duration-fast) var(--dg-ease);
}
.dg-pager__page:hover { color: var(--dg-ink); }
.dg-pager__page.is-current {
    color: var(--dg-ink);
    font-weight: var(--dg-weight-medium);
    border-bottom: 1px solid var(--dg-ink);
}
.dg-pager__ellipsis {
    color: var(--dg-faint);
    padding: 0 4px;
}


/* ════════════════════════════════════════════════════════════
   8. MOBILE FILTERS FAB
   ════════════════════════════════════════════════════════════ */

.dg-listing__filter-fab {
    /* Hidden on desktop; shows fixed bottom-center on mobile.
       The 2× sized version: bigger touch target, more visible,
       won't get clipped by curved phone screens. */
    display: none;
    position: fixed;
    bottom: 24px;
    /* Center horizontally — same axis as the bottom sheet */
    left: 50%;
    transform: translateX(-50%)!important;
    right: auto;
    z-index: var(--dg-z-overlay);
    align-items: center;
    gap: 12px;
    padding: 18px 32px;            /* was 12px 18px — ~1.7× */
    background: var(--dg-ink);
    color: var(--dg-paper);
    border: 0;
    border-radius: 999px;
    font-family: var(--dg-font-sans);
    font-size: 16px;               /* was 12px */
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    box-shadow: var(--dg-shadow-md);
    cursor: pointer;
}
.dg-listing__filter-fab svg {
    width: 22px;                   /* enlarge icon to match */
    height: 22px;
}

.dg-listing__sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: calc(var(--dg-z-modal) - 1);
    opacity: 0;
    transition: opacity var(--dg-duration-base) var(--dg-ease);
}
.dg-listing__sidebar-overlay.is-visible {
    display: block;
    opacity: 1;
}


/* ════════════════════════════════════════════════════════════
   9. RESPONSIVE
   ════════════════════════════════════════════════════════════ */

@media (max-width: 1100px) {
    .dg-grid--3up { grid-template-columns: repeat(2, 1fr); }
    .dg-listing__row { grid-template-columns: 220px 1fr; gap: 32px; }
}

@media (max-width: 880px),
       (pointer: coarse) and (max-width: 1400px) {

    /* Single-column layout on mobile, sidebar becomes a drawer */
    .dg-listing__row {
        grid-template-columns: 1fr;
        gap: 0;
    }

    /* ── Mobile filter — BOTTOM SHEET ──
       Instead of a side drawer (which gets clipped by curved
       phone screens), we slide a sheet up from the bottom.

         ┌─────────────────────────────┐
         │         ─── (drag handle)   │  ← rounded top
         │  FILTERS              ×     │
         │                             │
         │  Categories                 │  ← scrollable
         │  Seasonality                │
         │  Colour ●●●○●●              │
         │                             │
         └─────────────────────────────┘  ← flush with bottom

       Full viewport width × ~85% tall — leaves a peek of the
       page above so users know it's a modal sheet, not a new
       page. Rounded corners only at the top.

       Why `svh` and not `vh`:
         Chrome on iOS (and Safari) has a dynamic URL bar that
         expands and collapses as the user scrolls. `100vh` is
         resolved against the LARGE viewport (URL bar hidden),
         so when the URL bar IS shown, `100vh` is taller than
         what the user can actually see — pushing our top-of-
         sheet content (close button, drag handle) underneath
         the URL bar.

         `svh` = "small viewport height" = the smaller of the
         two states — guaranteed to fit no matter what the URL
         bar is doing. Fallback to `vh` for browsers without
         `svh` support (mostly older non-iOS browsers, where
         `vh` works fine anyway). */
    .dg-listing__sidebar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;                       /* anchor to bottom only */
        width: 100%;
        max-width: 100vw;
        height: 85vh;
        max-height: 85vh;
        height: 85svh;                   /* preferred when supported */
        max-height: 85svh;
        z-index: var(--dg-z-modal);
        background: var(--dg-paper);
        padding: 56px 20px 32px;         /* 56 top = room for close btn + handle */
        border-radius: 20px 20px 0 0;    /* rounded top corners only */
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: none;
        touch-action: pan-y;
        /* Slide DOWN out of view by default, slide UP when open */
        transform: translateY(100%);
        transition: transform var(--dg-duration-base) var(--dg-ease);
        box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18);
    }
    .dg-listing__sidebar.is-open { transform: translateY(0); }

    /* Drag handle — small horizontal bar at the top center,
       a visual cue that this is a draggable bottom sheet. */
    .dg-listing__sidebar::before {
        content: "";
        position: absolute;
        top: 12px;
        left: 50%;
        transform: translateX(-50%);
        width: 44px;
        height: 4px;
        border-radius: 2px;
        background: var(--dg-line);
    }

    /* Close button — top-right, visible above first filter.
       Note: this scrolls WITH the drawer content. If we want
       it to stay sticky as the user scrolls down, that requires
       a more complex flex/absolute layout (see commit history)
       which had iOS Safari issues. The current behavior is the
       simplest one that works reliably across all platforms. */
    /* Close button — top-right of the bottom sheet. Sits below
       the drag handle, scrolls with the content. 44×44 = the
       Apple HIG minimum recommended touch target. */
    .dg-listing__sidebar-close {
        display: inline-flex;
        position: absolute;
        top: 14px;                     /* sits below drag handle */
        right: 12px;
        width: 44px;
        height: 44px;
        z-index: 2;
        background: transparent;
        border: 0;
        align-items: center;
        justify-content: center;
        font-size: 32px;               /* slightly bigger × glyph */
        line-height: 1;
        color: var(--dg-ink);
        cursor: pointer;
    }

    .dg-listing__filter-fab { display: inline-flex; }

    /* ── MOBILE filter list — bigger text, taller rows ──
       The desktop sidebar uses 14px text and tight 6px rows,
       which is fine for cursor pointing. On a touchscreen
       phone, the text feels small and rows are easy to tap by
       mistake. We bump filter values to 16px and double the
       row padding for comfortable thumb tapping. */
    .dg-filter-list__item {
        padding: 12px 0;               /* was 6px 0 */
    }
    .dg-filter-list__item a {
        font-size: 16px;               /* was 14px */
    }
    .dg-filter-list__count {
        font-size: 14px;               /* was 12px — keep ratio */
    }

    /* Categories list (SUITS / PANTS / SHIRTS) — same treatment */
    .dg-filter-cats__link {
        padding: 12px 0 12px 14px;
        font-size: 15px;
    }

    /* ── MOBILE color swatches — smaller, more rows ──
       Desktop: ~50px swatches (~6 cols × 3 rows for ~19 colors,
       takes ~360px vertical). On mobile, that's a lot of
       precious vertical space. 28px × same 6 cols brings the
       grid down to ~190px. Touch target is still ample because
       grid gap (10px) effectively widens the tap zone, plus
       the active state has visible feedback. */
    .dg-filter-colors {
        gap: 12px;                     /* slightly more breathing room */
    }
    .dg-filter-colors__item {
        max-width: 32px;               /* cap individual swatch width */
        margin: 0 auto;
    }
    /* The grid stays 6-col so we still get a clean row-of-six
       layout, but each cell now caps the swatch at ~32px. The
       remaining row space becomes margin which centers each
       swatch in its cell — feels lighter visually. */
    .dg-filter-colors__btn {
        width: 28px;
        height: 28px;
        border-width: 1.5px;           /* keep border visible at small size */
    }
    .dg-filter-colors__btn.is-active::after {
        font-size: 10px;               /* ✓ glyph proportional to swatch */
    }

    /* Toolbar adjusts on mobile */
    .dg-toolbar {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 12px;
        padding-bottom: 16px;
        margin-bottom: 24px;
    }
    .dg-toolbar__count { font-size: 13px; }
    .dg-toolbar__divider { display: none; }
    .dg-toolbar__view { display: none; }  /* hide view-size selector on mobile */

    /* Grid: 2 up on tablet, 2 up still on phone (cards remain readable) */
    .dg-grid--3up,
    .dg-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 14px 12px;
    }

    /* Title scales down */
    .dg-listing__head { margin-bottom: 28px; }
}

@media (max-width: 540px) {
    /* On narrow phones, stack to single column for clarity */
    .dg-grid--3up,
    .dg-grid {
        grid-template-columns: 1fr;
        gap: 24px;
    }
    .dg-card__media { aspect-ratio: 1 / 1; }
}


/* ════════════════════════════════════════════════════════════
   10. PRICE FILTER — Smartwave jQuery UI slider

   Smartwave's price filter renders this structure:

     .price-filter-slider
       .slider-range                   ← jQuery UI slider track
       .text-box
         .input-container.clearfix
           .price-container.minPrice-container.f-left
             label.minPrice-label      "from"
             input.priceTextBox.minPrice
           .price-container.maxPrice-container.f-right
             label.minPrice-label      "to"
             input.priceTextBox.maxPrice
         .btn-container
           input.button.go             "OK"
           input.btn-clear             "clear"

   We restyle each piece to match the rest of the sidebar.
   ════════════════════════════════════════════════════════════ */

.price-filter-slider {
    padding: 4px 0 0;
}

/* The jQuery UI slider widget has been hidden — users found it
   awkward on mobile (small handle, tiny track). The Min/Max
   inputs and OK/Clear buttons below are sufficient for setting
   a price range. We keep the JS active so the slider's
   double-click behaviour still updates the inputs, but the
   visual handle/track is hidden. */
.price-filter-slider .slider-range,
.price-filter-slider .ui-slider {
    display: none !important;
}

/* (Old slider track + handle styles kept here as comments in
   case we want to bring it back later — uncomment to restore.)

   .price-filter-slider .slider-range,
   .price-filter-slider .ui-slider {
       background: var(--dg-line) !important;
       height: 2px !important;
       border: 0 !important;
       margin: 8px 0 22px !important;
       border-radius: 0 !important;
   }
   .price-filter-slider .ui-slider .ui-slider-range {
       background: var(--dg-ink) !important;
       border: 0 !important;
   }
   .price-filter-slider .ui-slider .ui-slider-handle {
       background: var(--dg-ink) !important;
       width: 14px !important;
       height: 14px !important;
       border-radius: 50% !important;
       border: 2px solid var(--dg-paper) !important;
       box-shadow: 0 0 0 1px var(--dg-ink) !important;
       margin-top: -1px !important;
       cursor: pointer;
       top: -7px !important;
   }
   .price-filter-slider .ui-slider .ui-slider-handle:focus {
       outline: 0 !important;
   }
*/

/* Text-box row containing the two inputs */
.price-filter-slider .text-box {
    margin-top: 4px;
}

.price-filter-slider .input-container {
    display: flex;
    gap: 10px;
    margin-bottom: 12px;
}
.price-filter-slider .input-container::after {
    content: none;  /* kill .clearfix pseudo, we use flex */
}

.price-filter-slider .price-container {
    float: none !important;        /* override .f-left / .f-right */
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.price-filter-slider .minPrice-label,
.price-filter-slider label {
    font-family: var(--dg-font-sans);
    font-size: 10px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    color: var(--dg-faint);
    margin: 0;
    padding: 0;
    line-height: 1;
}

.price-filter-slider .priceTextBox,
.price-filter-slider input[type="text"] {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--dg-line);
    background: var(--dg-paper);
    font-family: var(--dg-font-sans);
    font-size: 13px;
    color: var(--dg-ink);
    border-radius: 0;
    box-sizing: border-box;
    appearance: none;
    -webkit-appearance: none;
    transition: border-color var(--dg-duration-fast) var(--dg-ease);
    float: none !important;        /* override .f-left */
}
.price-filter-slider .priceTextBox:focus {
    outline: 0;
    border-color: var(--dg-ink);
}

/* Buttons row */
.price-filter-slider .btn-container {
    display: flex;
    gap: 8px;
    align-items: center;
}

.price-filter-slider .button.go,
.price-filter-slider input[type="button"].go {
    padding: 9px 18px;
    background: var(--dg-ink);
    color: var(--dg-paper);
    border: 0;
    font-family: var(--dg-font-sans);
    font-size: 11px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 0;
    transition: opacity var(--dg-duration-fast) var(--dg-ease);
    appearance: none;
    -webkit-appearance: none;
}
.price-filter-slider .button.go:hover {
    opacity: 0.85;
}

.price-filter-slider .btn-clear,
.price-filter-slider input.btn-clear {
    padding: 8px 14px;
    background: transparent;
    color: var(--dg-muted);
    border: 1px solid var(--dg-line);
    font-family: var(--dg-font-sans);
    font-size: 11px;
    font-weight: var(--dg-weight-medium);
    letter-spacing: var(--dg-track-widest);
    text-transform: uppercase;
    cursor: pointer;
    border-radius: 0;
    transition: color var(--dg-duration-fast) var(--dg-ease),
                border-color var(--dg-duration-fast) var(--dg-ease);
    appearance: none;
    -webkit-appearance: none;
}
.price-filter-slider .btn-clear:hover {
    color: var(--dg-ink);
    border-color: var(--dg-ink);
}

/* Hidden #amount input (price label) — keep hidden */
.price-filter-slider .price-amount,
.price-filter-slider #amount {
    display: none;
}


/* ════════════════════════════════════════════════════════════
   11. (Body scroll lock removed)

   An earlier version added body.dg-no-scroll { overflow: hidden }
   to prevent the page underneath from scrolling while the
   drawer was open. On iOS Safari, overflow:hidden on <body>
   freezes ALL interaction inside the drawer too — taps, scroll,
   selection — which is the exact opposite of what we want.
   The drawer's own position:fixed + overflow:auto is enough to
   contain scroll touches, so we don't need to lock the body.
   ════════════════════════════════════════════════════════════ */


/* ════════════════════════════════════════════════════════════
   12. TOAST NOTIFICATION

   A single .dg-toast element gets injected into the body the
   first time wishlist.js needs to show a message. Animates in
   from below the viewport, holds, then fades out.

   Variants:
     .dg-toast--error      → red accent for error messages
     .dg-toast--clickable  → cursor pointer, used for the
                              "sign in to save items" CTA
   ════════════════════════════════════════════════════════════ */

.dg-toast {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%) translateY(20px);
    z-index: var(--dg-z-overlay);
    background: var(--dg-ink);
    color: var(--dg-paper);
    padding: 14px 22px;
    border-radius: 8px;
    font-family: var(--dg-font-sans);
    font-size: 14px;
    letter-spacing: 0.04em;
    box-shadow: var(--dg-shadow-md);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dg-duration-base) var(--dg-ease),
                transform var(--dg-duration-base) var(--dg-ease);
    max-width: calc(100vw - 40px);
    text-align: center;
}

.dg-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.dg-toast--error {
    background: #b94545;        /* muted red — fits the palette */
}

.dg-toast--clickable {
    cursor: pointer;
    pointer-events: auto;
}
.dg-toast--clickable:hover {
    background: var(--dg-gold);
    color: var(--dg-ink);
}

/* On mobile, toast sits above the FAB filter button so the
   two don't overlap. Pulled up with extra bottom space. */
@media (max-width: 880px),
       (pointer: coarse) and (max-width: 1400px) {
    .dg-toast {
        bottom: 100px;          /* clear of the FAB at bottom: 24 + ~76 fab height */
        font-size: 13px;
        padding: 12px 18px;
    }
}

