/* LW Typesense font-size anchor.
   All sizing inside this file uses `em` so it remains independent of the
   site's html { font-size } (sites that use the 62.5%% trick would otherwise
   render at 62.5%% scale). Setting an explicit px baseline on each wrapper
   re-establishes a 16px reference for the entire subtree. */
.lw-ts-search-page,
.ais-InstantSearch,
.lw-ts-active-refinements,
.lw-card,
.lw-filter-stock-status,
.lw-filter-on-sale {
    font-size: 16px;
}
/* LW Typesense — Instant Search theme
   Layered on top of instantsearch.reset.min.css. Provides minimal styling for
   the InstantSearch widgets we use. The product cards (.lw-card__*) are
   styled separately by the existing lw-hits-card-styles snippet. */

/* Layout container */
.lw-ts-search-page { display: grid; grid-template-columns: 280px 1fr; gap: 2em; max-width: 1400px; margin: 0 auto; padding: 1em; }
@media (max-width: 768px) { .lw-ts-search-page { grid-template-columns: 1fr; } }

.lw-ts-search-page__filters { position: sticky; top: 1em; align-self: start; max-height: calc(100vh - 2em); overflow-y: auto; }
.lw-ts-search-page__results { min-width: 0; }

/* Search box */
.ais-SearchBox-form { position: relative; }
.ais-SearchBox-input {
    width: 100%;
    padding: 0.75em 2.5em 0.75em 1em;
    border: 1px solid #dcdcde;
    border-radius: 4px;
    font-size: 1em;
}
.ais-SearchBox-submit, .ais-SearchBox-reset {
    position: absolute; top: 50%; transform: translateY(-50%); border: 0; background: transparent; padding: 0.5em; cursor: pointer;
}
.ais-SearchBox-submit { right: 2em; }
.ais-SearchBox-reset  { right: 0.5em; }
.ais-SearchBox-loadingIndicator { position: absolute; right: 0.5em; top: 50%; transform: translateY(-50%); }

/* Stats + sort row */
.lw-ts-results-header {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 1em; padding-bottom: 0.75em; border-bottom: 1px solid #e3e3f0;
}
.ais-Stats { color: #50575e; font-size: 0.9em; }
.ais-SortBy-select { padding: 0.4em 0.6em; border: 1px solid #dcdcde; border-radius: 3px; background: #fff; }

/* Per-page + sort grouped on the right of the results header.
 * Order in DOM is per-page then sort, which renders left-to-right inside the group. */
.lw-ts-results-header__controls { display: flex; align-items: center; gap: 0.75em; }
.lw-ts-results-header__controls #lw-ts-per-page,
.lw-ts-results-header__controls #lw-ts-sort-by { display: inline-flex; align-items: center; }
.ais-HitsPerPage-select { padding: 0.4em 0.6em; border: 1px solid #dcdcde; border-radius: 3px; background: #fff; }

/* If stats is hidden the controls group should still hug the right edge. */
.lw-ts-results-header { gap: 0.75em; }
.lw-ts-results-header__controls { margin-left: auto; }

/* Hits grid */
.ais-Hits-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1.25em;
    list-style: none;
    padding: 0;
    margin: 0;
}
.ais-Hits-item { display: block; }

/* Empty / error states */
.lw-ts-no-results {
    padding: 3em 1em; text-align: center; color: #50575e; font-size: 1.1em;
}

/* Pagination */
.ais-Pagination-list {
    display: flex; gap: 0.25em; list-style: none; padding: 0; margin: 2em 0 0; justify-content: center; flex-wrap: wrap;
}
.ais-Pagination-link, .ais-Pagination-item--disabled .ais-Pagination-link {
    display: inline-block; padding: 0.5em 0.75em; border: 1px solid #dcdcde; border-radius: 3px;
    background: #fff; color: #1d2327; text-decoration: none; min-width: 2.25em; text-align: center;
}
.ais-Pagination-item--selected .ais-Pagination-link { background: #1E1E26; color: #fff; border-color: #1E1E26; }
.ais-Pagination-item--disabled .ais-Pagination-link { opacity: 0.5; cursor: not-allowed; }
.ais-Pagination-link:hover:not([disabled]) { background: #f4f4f9; }

/* Refinement panels (Phase 7b) */
.ais-Panel { margin-bottom: 1.5em; }
.ais-Panel-header { font-weight: 600; margin-bottom: 0.5em; padding-bottom: 0.5em; border-bottom: 1px solid #e3e3f0; cursor: pointer; }
.ais-Panel-collapseButton { background: transparent; border: 0; cursor: pointer; padding: 0; }
.ais-RefinementList-list { list-style: none; padding: 0; margin: 0; }
.ais-RefinementList-item { padding: 0.25em 0; }
.ais-RefinementList-label { display: flex; align-items: center; gap: 0.5em; cursor: pointer; }
.ais-RefinementList-checkbox { margin: 0; }
.ais-RefinementList-count { color: #50575e; font-size: 0.85em; margin-left: auto; }
.ais-RefinementList-showMore { background: transparent; border: 0; color: #2271b1; cursor: pointer; padding: 0.25em 0; font-size: 0.9em; }

/* Current refinements */
.ais-CurrentRefinements-list { display: flex; flex-wrap: wrap; gap: 0.5em; list-style: none; padding: 0; margin: 0 0 1em; }
.ais-CurrentRefinements-item { display: inline-flex; align-items: center; gap: 0.35em; padding: 0.25em 0.5em; background: #f4f4f9; border-radius: 3px; font-size: 0.875em; }
.ais-CurrentRefinements-delete { background: transparent; border: 0; cursor: pointer; padding: 0 0.25em; color: #50575e; }
.ais-CurrentRefinements-delete:hover { color: #b32d2e; }

.ais-ClearRefinements-button { padding: 0.4em 0.8em; background: #f4f4f9; border: 1px solid #dcdcde; border-radius: 3px; cursor: pointer; }
.ais-ClearRefinements-button--disabled { opacity: 0.5; cursor: not-allowed; }
/* ----------------------------------------------------------------------
 * Ported from WPCodeBox snippet "Typesense Style" (id 3, SCSS).
 * Selectors swapped from legacy .cmtsfwc-* markup to our .lw-ts-* + .ais-*.
 * Bug fix: original had `var(----primary)` (4 dashes) in two places —
 * silently ignored as invalid CSS in the original; fixed to `var(--primary)` here.
 * ---------------------------------------------------------------------- */

/* Card hover/border treatment.
 * Legacy: .cmtsfwc-Result li → ours: .ais-Hits-item (InstantSearch's standard
 * list-item class, which wraps each rendered hit). */
.ais-Hits-item {
  padding: 16px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
.ais-Hits-item:hover {
  border-color: #d1d5db;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04);
  transform: translateY(-1px);
}

/* Hide the duplicate header search box if one renders inside the InstantSearch
 * region. Our shortcode renders #lw-ts-searchbox in the results column, so the
 * theme/header search shouldn't compete with it. Kept as a safety rule from the
 * original snippet — only fires if the legacy .cmtsfwc-SearchBox is also present. */
.cmtsfwc-SearchBox { display: none; }

/* ---------- Current refinements pill row ---------- */
.ais-CurrentRefinements-list {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  list-style: none;
  padding: 0;
  margin: 0 0 12px;
  /* Horizontal scroll for overflow */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.ais-CurrentRefinements-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--primary-ultra-light, #f4f4f9);
  border: 1.5px solid var(--primary, #1E1E26);
  border-radius: 6px;
  font-size: 14px;
  color: var(--primary, #1E1E26);
  line-height: 1;
  flex-shrink: 0;
}

.ais-CurrentRefinements-label {
  font-weight: 600;
  color: var(--primary, #1E1E26);
}

.lw-ts-search-page .ais-CurrentRefinements-category {
  background-color: transparent;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 4px;
}

.ais-CurrentRefinements-categoryLabel {
  color: var(--primary, #1E1E26);
}

.lw-ts-search-page .ais-CurrentRefinements-delete {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: black;
  font-size: 10px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}
.ais-CurrentRefinements-delete:hover {
  background: white;
}

.ais-Highlight-highlighted {
  background-color: transparent;
}
/* Footer button (Add to cart / View Item): full-card width. */
.lw-card__cart { display: block; width: 100%; margin-top: 0.5em; }
.lw-card__cart > a { display: block; width: 100%; text-align: center; box-sizing: border-box; }
/* Stock indicator: 3 states. Convention: green (in stock), amber (low stock
 * urgency), muted red (out of stock). Uses inline-flex so the icon and text
 * align cleanly. Icons are pre-coloured SVGs from image.shoplw.ca. */
.lw-stock {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-size: 0.875em;
  font-weight: 500;
  line-height: 1.2;
  margin: 0.5em 0;
}
.lw-stock-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.lw-stock--in   { color: #15803d; }   /* green-700 */
.lw-stock--low  { color: #b45309; }   /* amber-700 — urgency without alarm */
.lw-stock--out  { color: #991b1b; }   /* red-800  — muted, not panicky */
/* =====================================================================
 * Card layout: equal heights, consistent image sizing, button alignment.
 * The .ais-Hits-list grid already gives equal-width columns and CSS Grid
 * makes all items in a row the same height when items are flex-column
 * with a flex-grow body — which is what we set up here.
 * ===================================================================== */

/* Card root — flex column so image / body / footer stack vertically and
 * the body can grow to fill, pushing the cart button to the bottom edge. */
.lw-card.lw-card--hit {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
}

/* Image: fixed 1:1 aspect ratio container, image scaled to fit without
 * cropping (object-fit: contain). All cards now have identical image heights
 * regardless of source dimensions. */
.lw-card__image-link { display: block; }
.lw-card__image-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: #fafafa;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lw-card__image {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
.lw-card__image--placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
}

/* Body fills available space so footer pins to bottom across all cards in a row. */
.lw-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  margin-top: 0.75em;
  min-width: 0;
}

/* Title — smaller, clamped to 2 lines for predictable card height. */
.lw-card__title {
  font-size: 0.95em;
  line-height: 1.3;
  margin: 0 0 0.4em 0;
  font-weight: 500;
  /* Two-line clamp */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Reserve the space for two lines so cards with shorter titles still
   * align with cards that have wrapping titles. */
  min-height: calc(0.95em * 1.3 * 2);
}
.lw-card__title-link {
  color: inherit;
  text-decoration: none;
}
.lw-card__title-link:hover { text-decoration: underline; }

.lw-card__price { margin: 0.25em 0 0.5em; }

/* Meta row — stock badge on the left, SKU on the right. Stock keeps its
 * existing styling; SKU is small and muted. */
.lw-card__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5em;
  margin: 0.5em 0;
  flex-wrap: wrap;
}
.lw-card__meta .lw-stock { margin: 0; }
.lw-card__sku {
  font-size: 0.75em;
  color: #6b7280;
  font-weight: 400;
  letter-spacing: 0.02em;
}

/* Cart wrapper sits at the bottom thanks to body flex-grow above. The
 * existing margin-top: 0.5em from earlier rules works here, but force
 * margin-top: auto so the gap between the card content and footer is
 * predictable regardless of body content height. */
.lw-card__cart { margin-top: auto; }
/* Rating slot inside cards — minimal wrapper. The .star-rating element itself
 * is styled by WooCommerce's woocommerce.css (already loaded site-wide). */
.lw-card__rating { margin: 0.25em 0; }
.lw-card__rating .star-rating {
  font-size: 0.85em;  /* slightly smaller than WC's default for our compact cards */
  margin: 0;
}
/* Force left alignment of the WC star bar inside our cards. WC's default rule
 * `.star-rating { margin: 0 auto }` centers it; this selector is more specific. */
.lw-card .lw-card__rating .star-rating { margin: 0; }
/* =====================================================================
 * Wishlist heart — absolute, top-right of the card.
 * The card root .lw-card already has position: relative as a side-effect
 * of being a flex column with `position: relative` set in card layout rules.
 * We pin the wrapper to the upper right corner. The wishlist plugin's own
 * CSS handles the heart's filled vs outlined states via .add / .remove.
 * ===================================================================== */
.lw-card__wishlist {
  /* Pull the heart out of the card's 16px padding so it sits flush to the
   * outer edge of the card, overlapping the upper-right corner of the image.
   * Using -8px (not -16px) keeps the pill from poking outside the
   * border-radius. */
  position: absolute;
  top: -8px;
  right: -8px;
  z-index: 2;
}
.lw-card__wishlist .alg-wc-wl-btn,
.lw-card__wishlist .lw-wishlist-heart {
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid #e5e7eb;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.lw-card__wishlist .lw-wishlist-heart:hover {
  background: #fff;
  border-color: #d1d5db;
  transform: scale(1.05);
}
.lw-card__wishlist .lw-heart-icon {
  width: 16px;
  height: 16px;
  color: #4b5563;          /* unfilled state — muted grey */
  transition: color 0.15s ease;
}
/* Filled state: button gets `.remove` class when item IS in the wishlist. */
.lw-card__wishlist .lw-wishlist-heart.remove .lw-heart-icon {
  color: #dc2626;          /* red when wishlisted */
}
.lw-card__wishlist .lw-wishlist-heart:hover .lw-heart-icon {
  color: #dc2626;
}
/* The wishlist plugin's two-state SVG containers — hide whichever isn't active. */
.lw-card__wishlist .alg-wc-wl-btn.add .alg-wc-wl-view-state-remove,
.lw-card__wishlist .alg-wc-wl-btn.remove .alg-wc-wl-view-state-add {
  display: none;
}
/* =====================================================================
 * Active refinements bar — lives at the top of the results column,
 * above the searchbox / stats / hits. Shows the currently applied filters
 * as a full-width row, with "Clear all filters" pinned to the right.
 * Hidden visually when there are no current refinements (no chips render).
 * ===================================================================== */
.lw-ts-active-refinements {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5em 1em;
  margin: 0 0 1em;
}
.lw-ts-active-refinements > #lw-ts-current-refinements {
  flex: 1 1 auto;
  min-width: 0;
}
.lw-ts-active-refinements > #lw-ts-clear-refinements {
  flex: 0 0 auto;
}

/* Hide the entire bar when no chips are active. The currentRefinements
 * widget always emits a wrapper, but we want zero visual footprint in that
 * case. Its `--noRefinement` modifier class is added by InstantSearch when
 * empty; if both children are empty/inactive, collapse the bar. */
.lw-ts-active-refinements:has(#lw-ts-current-refinements:empty):has(#lw-ts-clear-refinements .ais-ClearRefinements-button--disabled) {
  display: none;
}
/* Search query chip in the active-refinements bar. Inherits most styling
 * from .ais-CurrentRefinements-item; we mainly need to make sure the
 * delete button is a proper button-looking thing. */
.lw-ts-query-chip {
  /* Visually distinguish a search-query chip from facet chips with a tiny
   * accent. Comment this out if you'd prefer the chip to look identical. */
}
.lw-ts-query-chip .lw-ts-query-chip__delete {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 0.4em;
  font-size: inherit;
  color: inherit;
  line-height: 1;
}
.lw-ts-query-chip .lw-ts-query-chip__delete:hover {
  color: #dc2626;
}
/* =====================================================================
 * Collapsible filter panels
 * The InstantSearch panel widget auto-renders an .ais-Panel-collapseButton
 * in the header with a chevron icon. We need to:
 *   - style the header as a clickable area
 *   - hide the body when --collapsed is on the root
 *   - rotate the chevron based on collapsed state
 * ===================================================================== */

/* Header is a flex row — title on the left, collapse chevron on the right.
 * The widget puts the collapse button INSIDE the header, so we lay them out. */
.ais-Panel--collapsible .ais-Panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  user-select: none;
  gap: 0.5em;
}

/* The collapse button itself — reset native button chrome */
.ais-Panel-collapseButton {
  background: none;
  border: none;
  padding: 4px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #6b7280;
  border-radius: 4px;
  transition: color 0.15s ease, background 0.15s ease;
}
.ais-Panel-collapseButton:hover {
  color: #1f2937;
  background: #f3f4f6;
}
.ais-Panel-collapseIcon {
  transition: transform 0.2s ease;
  display: block;
}
/* Chevron points down by default; rotate 90deg when collapsed (points right). */
.ais-Panel--collapsed .ais-Panel-collapseIcon {
  transform: rotate(-90deg);
}

/* Hide the body when the panel is collapsed. */
.ais-Panel--collapsed .ais-Panel-body {
  display: none;
}

/* Subtle visual separation between panels */
.lw-ts-panel {
  border-bottom: 1px solid #e5e7eb;
  padding: 0.75em 0;
}
.lw-ts-panel:last-child {
  border-bottom: none;
}
.lw-ts-panel .ais-Panel-header {
  font-weight: 500;
  font-size: 0.95em;
  margin: 0;
  padding: 0;
}
/* =====================================================================
 * Tightened filter panel spacing
 * Overrides earlier rules that produced excessive vertical space between
 * panel headers and their items. Loaded last so cascade wins.
 * ===================================================================== */

/* Collapse the older .ais-Panel margin — we use .lw-ts-panel for separation */
.lw-ts-panel.ais-Panel { margin-bottom: 0; }

/* Outer panel padding: tighter top/bottom */
.lw-ts-panel { padding: 0.5em 0; }

/* Header: no bottom border (the panel itself has one), no extra padding */
.lw-ts-panel .ais-Panel-header {
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 0;
  font-weight: 500;
  font-size: 0.95em;
}

/* Body — small gap from header when expanded, zero gap when collapsed */
.lw-ts-panel .ais-Panel-body {
  margin-top: 0.4em;
}
.ais-Panel--collapsed .ais-Panel-body { margin-top: 0; }

/* Refinement items — tight rows */
.ais-RefinementList-list { padding: 0; margin: 0; }
.ais-RefinementList-item { padding: 0.15em 0; }
.ais-RefinementList-label {
  display: flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.875em;
  line-height: 1.3;
}
.ais-RefinementList-count {
  font-size: 0.75em;
  color: #6b7280;
  margin-left: auto;
}

/* Hierarchical menu (categories) — same tightening */
.ais-HierarchicalMenu-list { padding: 0; margin: 0; }
.ais-HierarchicalMenu-list .ais-HierarchicalMenu-list { margin-left: 0.75em; }
.ais-HierarchicalMenu-item { padding: 0.15em 0; }
.ais-HierarchicalMenu-link {
  font-size: 0.875em;
  line-height: 1.3;
  display: flex;
  align-items: center;
  gap: 0.4em;
}
.ais-HierarchicalMenu-count {
  font-size: 0.75em;
  color: #6b7280;
  margin-left: auto;
}

/* Search-box inside searchable refinement (Bricks/ACSS-friendly) */
.ais-RefinementList-searchBox { margin-bottom: 0.4em; }
.ais-RefinementList-searchBox input {
  padding: 0.3em 0.5em;
  font-size: 0.85em;
  width: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
}
/* =====================================================================
 * Disable the browser's default <mark> styling inside search results.
 * Typesense wraps matched tokens in <mark>...</mark>; browsers render that
 * with a yellow background by default. We want matched text to read as
 * plain content with no visual emphasis.
 * ===================================================================== */
.lw-ts-search-page mark,
.ais-Hits mark,
.lw-card mark {
  background: transparent;
  color: inherit;
  padding: 0;
  font-weight: inherit;
}
/* =====================================================================
 * Mobile filter drawer (≤ 768px)
 * Desktop: button + close-X + backdrop are hidden, sidebar shows inline.
 * Mobile:  sidebar collapses, button shows at top of results, sidebar
 *          becomes a fixed left-slide drawer when toggled open.
 * ===================================================================== */

/* DESKTOP DEFAULTS: drawer machinery hidden */
.lw-ts-filter-toggle,
.lw-ts-drawer-close,
.lw-ts-drawer-backdrop {
  display: none;
}

/* MOBILE BREAKPOINT */
@media (max-width: 768px) {
  /* Collapse the grid to a single column. The sidebar still exists in the
   * DOM — we just take it out of the document flow and reposition it. */
  .lw-ts-search-page {
    grid-template-columns: 1fr;
    gap: 0.5em;
    padding: 0.75em;
  }

  /* The aside becomes a fixed-position drawer, slid off-screen left.
   * It uses transform rather than left:-X for GPU-accelerated animation.
   * Visibility/aria-hidden management is handled by JS. */
  .lw-ts-search-page__filters {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    height: 100dvh;             /* better on iOS */
    width: min(85vw, 360px);    /* 85% of viewport, capped at 360px */
    background: #fff;
    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.15);
    z-index: 1000;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1em 1em 2em;
    transform: translateX(-100%);
    transition: transform 0.25s ease-out;
  }

  /* Show the drawer when the search-page wrapper has the open class */
  .lw-ts-search-page.is-drawer-open .lw-ts-search-page__filters {
    transform: translateX(0);
  }

  /* Show the toggle button at the top of the results column */
  .lw-ts-filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    padding: 0.55em 0.9em;
    background: #fff;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    font-size: 0.9em;
    font-weight: 500;
    color: #1f2937;
    cursor: pointer;
    margin: 0 0 0.75em;
    transition: background 0.15s ease, border-color 0.15s ease;
  }
  .lw-ts-filter-toggle:hover {
    background: #f9fafb;
    border-color: #9ca3af;
  }
  .lw-ts-filter-toggle__count {
    display: none;          /* shown by JS only when count > 0 */
    background: #1f2937;
    color: #fff;
    font-size: 0.7em;
    font-weight: 600;
    padding: 0.1em 0.45em;
    border-radius: 999px;
    line-height: 1.3;
  }
  .lw-ts-filter-toggle__count.is-active {
    display: inline-block;
  }

  /* Close X button inside the drawer */
  .lw-ts-drawer-close {
    display: block;
    position: absolute;
    top: 0.5em;
    right: 0.5em;
    background: none;
    border: none;
    font-size: 1.75em;
    line-height: 1;
    color: #6b7280;
    cursor: pointer;
    padding: 0.25em 0.6em;
    border-radius: 4px;
  }
  .lw-ts-drawer-close:hover { color: #1f2937; background: #f3f4f6; }

  /* Backdrop — fades in when drawer opens */
  .lw-ts-drawer-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0.25s ease;
    z-index: 999;             /* below drawer (1000), above page content */
  }
  .lw-ts-search-page.is-drawer-open .lw-ts-drawer-backdrop {
    opacity: 1;
    visibility: visible;
  }

  /* Lock body scroll while the drawer is open. The wrapper's class is the
   * trigger, so this scopes the lock without needing to set classes on body. */
  .lw-ts-search-page.is-drawer-open {
    /* No-op for the wrapper itself; the lock is applied to <body> via JS
     * because position:fixed on body is the most reliable cross-browser way
     * to prevent background scroll on iOS. */
  }
}
/* "Filters" heading at the top of the filter aside */
.lw-ts-filters-heading {
  font-size: 1.1em;
  font-weight: 600;
  color: #1f2937;
  margin: 0 0 0.75em;
  padding: 0 0 0.5em;
  border-bottom: 1px solid #e5e7eb;
  letter-spacing: 0.01em;
}

/* Stock and Sale toggle blocks should match the rhythm of .lw-ts-panel
 * (which wraps the Categories and pa_* refinements) so all filter sections
 * have consistent spacing and dividers. */
.lw-filter-stock-status,
.lw-filter-on-sale {
  border-bottom: 1px solid #e5e7eb;
  padding: 0.5em 0;
}
/* =====================================================================
 * Rating + Price filters (numericMenu)
 * ===================================================================== */

/* Tight item rows matching .ais-RefinementList styling */
.ais-NumericMenu-list { list-style: none; padding: 0; margin: 0; }
.ais-NumericMenu-item { padding: 0.15em 0; }
.ais-NumericMenu-label {
  display: flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.875em;
  line-height: 1.3;
  cursor: pointer;
}
.ais-NumericMenu-radio { margin: 0; }
.ais-NumericMenu-labelText {
  /* Avoid "& up" wrapping awkwardly when the row is narrow */
  white-space: nowrap;
}

/* Color the rating stars gold within the rating panel only.
 * The ★ character takes the current color, so we just set color: gold here.
 * Scoped tightly so we don't accidentally style stars elsewhere. */
.lw-ts-panel--rating .ais-NumericMenu-labelText {
  color: #f59e0b;             /* amber-500 — warm gold */
  font-size: 0.95em;
  letter-spacing: 0.05em;
}

/* Keep the price panel's labels in normal text color */
.lw-ts-panel--price .ais-NumericMenu-labelText {
  font-variant-numeric: tabular-nums;
}
/* =====================================================================
 * Discount percent badge — upper-left of the card, mirrors the wishlist
 * heart positioning. Compact red pill so it reads at a glance even when
 * the percentage runs to two digits.
 * ===================================================================== */
.lw-card__sale {
  position: absolute;
  top: -8px;
  left: -8px;
  z-index: 2;
  background: #dc2626;          /* red-600 */
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  line-height: 1.3;
  box-shadow: 0 1px 3px rgba(0,0,0,0.15);
  white-space: nowrap;
}
/* Star rating left-alignment.
 * WC's .star-rating is display: inline-block, and the wrapper inherits
 * a center alignment from somewhere in the theme cascade that wins over
 * text-align: left. Using display: flex sidesteps that — flex children
 * pin to the start (left in LTR) by default. */
.lw-card__rating { display: flex; }
/* =====================================================================
 * Mobile product grid — force 2 columns on phones/tablets-portrait.
 * Without this override, the auto-fill minmax(220px, 1fr) collapses to
 * 1 column on viewports under ~440px. Two columns is more efficient on
 * mobile (more products visible per scroll) without making cards too
 * cramped to read.
 * ===================================================================== */
@media (max-width: 768px) {
  .ais-Hits-list {
    grid-template-columns: 1fr 1fr;
    gap: 0.75em;
  }
  /* Tighten card padding so two cards comfortably fit on narrow screens */
  .ais-Hits-item {
    padding: 10px;
  }
  /* Smaller card title since the columns are narrower */
  .lw-card__title {
    font-size: 0.85rem;
  }
}
/* Mobile-only: prevent horizontal overflow caused by the sort-by select's
 * minimum content width. Long option labels (e.g. "Price: Low to High")
 * stretch the select wider than narrow viewports, pushing the whole page
 * past the viewport edge. Solution: let the results header wrap, and let
 * its select children shrink. */
@media (max-width: 768px) {
  .lw-ts-results-header {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5em;
  }
  .lw-ts-results-header__controls {
    flex-wrap: wrap;
    gap: 0.5em;
  }
  /* Let the selects shrink to fit. Without min-width: 0, flex children
   * default to their content's intrinsic minimum width. */
  .lw-ts-results-header__controls #lw-ts-per-page,
  .lw-ts-results-header__controls #lw-ts-sort-by {
    min-width: 0;
  }
  .ais-SortBy-select,
  .ais-HitsPerPage-select {
    max-width: 100%;
  }
  /* Belt-and-suspenders: the page wrapper itself should never overflow.
   * Prevents any other unforeseen wide child from creating horizontal
   * scroll on mobile. */
  .lw-ts-search-page {
    max-width: 100%;
    overflow-x: hidden;
  }
}