/* ==========================================================================
   Catalogue page (catalogue.html, en/catalogue.html) — page header, search,
   category filter bar, grid, empty state and the floating filter shortcut.
   The cards are in css/components/product-card.css, the lightbox in
   css/components/product-dialog.css.
   ========================================================================== */

/* --- Page header ---------------------------------------------------------
   No hero carousel on this page — .gal-hero stands in for it, so its own
   top padding needs to clear the fixed .site-head the same way .hero-inner
   does on index.html (see that rule's own comment for the 76px-logo math
   this clamp is based on). */
.gal-hero {
  padding: clamp(148px, 19vw, 196px) 0 var(--space-6);
}
.gal-hero h1 { font-size: clamp(32px, 4.4vw, 50px); max-width: 20ch; }
.gal-hero-note {
  max-width: 62ch; margin-top: var(--space-3);
  color: color-mix(in srgb, var(--color-text) 65%, transparent);
}

/* --- Search bar --------------------------------------------------------- */
/* .gal-hero's own bottom padding already separates it from the search box —
   the .section top padding on top of that left a gap of over 120px. */
.gal-browse { padding-top: 0; }
.gal-search {
  position: relative;
  max-width: 420px;
  margin: 0 0 var(--space-4);
}
.gal-search-icon {
  position: absolute; top: 50%; inset-inline-start: 17px; transform: translateY(-50%);
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
  pointer-events: none;
}
.gal-search-input {
  width: 100%; height: 46px; font: inherit; font-size: 14px;
  color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-bg);
  border: 1px solid var(--color-divider); border-radius: 999px;
  padding-inline: 44px 40px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.gal-search-input::placeholder { color: color-mix(in srgb, var(--color-text) 65%, transparent); } /* 45% was 2.8:1 */
.gal-search-input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.gal-search-input:focus-visible {
  outline: none; border-color: var(--focus-ring-color);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
/* Hide native search decorations so the custom icon/clear button are the
   only ones shown, identically across browsers. */
.gal-search-input::-webkit-search-cancel-button,
.gal-search-input::-webkit-search-decoration { appearance: none; display: none; }
.gal-search-clear {
  position: absolute; top: 50%; inset-inline-end: 7px; transform: translateY(-50%);
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%; background: none; padding: 0; cursor: pointer;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  transition: background-color 0.2s ease, color 0.2s ease;
}
.gal-search-clear:hover { background: var(--color-surface); color: var(--color-text); }

/* --- Filter bar ------------------------------------------------------- */
.gal-filter-bar {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.gal-filter-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; cursor: pointer;
  padding: 9px 18px; border-radius: 999px;
  background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-divider);
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}
.gal-filter-btn:hover { border-color: var(--color-accent); transform: translateY(-1px); }
.gal-filter-btn:active { transform: translateY(0) scale(0.97); }
.gal-filter-btn.is-active {
  background: var(--color-accent-2-900); border-color: var(--color-accent-2-900); color: var(--color-neutral-100);
}
.gal-filter-count {
  font-family: var(--font-body); font-size: 11px; font-weight: 700;
  min-width: 20px; padding: 1px 6px; border-radius: 999px; text-align: center;
  background: color-mix(in srgb, var(--color-text) 10%, transparent);
  unicode-bidi: isolate;
}
.gal-filter-btn.is-active .gal-filter-count { background: color-mix(in srgb, #fff 22%, transparent); }

.gal-count {
  margin: 0 0 var(--space-4); font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 65%, transparent);
  unicode-bidi: isolate;
}

/* --- Grid ---------------------------------------------------------------*/
.gal-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--space-6);
}
/* The filter bar, count and grid are filled in by js/pages/catalogue.js just
   after the first paint. Holding their space until then stops the contact
   band and footer from jumping down when the cards arrive (they start below
   the fold instead). The grid rule skips the no-results state, where the
   empty message is showing. */
.gal-grid:empty:has(+ .gal-empty[hidden]) { min-height: 100vh; }
.gal-filter-bar:empty { min-height: 44px; }
.gal-count:empty::before { content: "\00a0"; }

.gal-empty {
  text-align: center; padding: var(--space-8) 0;
  color: color-mix(in srgb, var(--color-text) 65%, transparent);
}

/* --- Gallery: floating filter shortcut (catalogue.html only) -----------------
   Same fixed-corner FAB language as .to-top, stacked directly above it —
   a way back to the category filters without scrolling past however many
   rows of products sit below the real filter bar. Desktop and mobile both,
   by request (unlike most of the site's other mobile-only fixes). */
.filter-fab {
  position: fixed; z-index: 40; inset-inline-end: var(--space-6);
  bottom: calc(var(--space-6) + 48px + var(--space-3));
  width: 48px; height: 48px; padding: 0; border: 0; cursor: pointer;
  display: grid; place-items: center; border-radius: 999px;
  background: var(--color-accent-2-900); color: var(--color-neutral-100);
  box-shadow: var(--shadow-md);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s, background-color 0.2s ease;
}
.filter-fab.is-visible { opacity: 1; visibility: visible; transform: none; }
.filter-fab:hover { background: var(--color-accent-2-800); }
.filter-fab[aria-expanded="true"] { background: var(--color-accent); color: var(--color-text); }
/* Panel opens upward from the fab, same corner — width caps to the
   viewport so it can't push past the screen edge on a narrow phone. */
.filter-panel {
  position: fixed; z-index: 40; inset-inline-end: var(--space-6);
  bottom: calc(var(--space-6) + 48px + var(--space-3) + 48px + var(--space-3));
  width: min(300px, calc(100vw - var(--space-8)));
  max-height: min(360px, calc(100vh - var(--space-8) * 2));
  overflow-y: auto;
  background: var(--color-bg); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: var(--space-4);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}
.filter-panel.is-open { opacity: 1; visibility: visible; transform: none; }
.filter-panel-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
@media (prefers-reduced-motion: reduce) { .filter-fab, .filter-panel { transition: none; } }

/* --- Gallery responsive --------------------------------------------------*/
@media (max-width: 1020px) {
  .gal-grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--space-4); }
}
@media (max-width: 720px) {
  .gal-hero { padding-top: clamp(128px, 30vw, 168px); }
  .gal-search { max-width: none; }
  .gal-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
  /* Filter bar as a horizontal slider, mobile only, by request — was
     flex-wrap:wrap, stacking the ~11 category chips into several rows and
     pushing the actual gallery grid down. Same scroll-snap + thin-scrollbar
     treatment .about-grid uses elsewhere on the site for the same "grid of
     chips/cards becomes a swipeable row" pattern at this breakpoint. */
  .gal-filter-bar {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory;
    padding-bottom: var(--space-2);
    scrollbar-width: thin; scrollbar-color: var(--color-neutral-400) transparent;
  }
  .gal-filter-bar::-webkit-scrollbar { height: 6px; }
  .gal-filter-bar::-webkit-scrollbar-track { background: transparent; }
  .gal-filter-bar::-webkit-scrollbar-thumb { background: var(--color-neutral-400); border-radius: 999px; }
  .gal-filter-btn {
    flex: 0 0 auto; scroll-snap-align: start;
    padding: 7px 14px; font-size: 12px;
  }
}
@media (max-width: 460px) {
  .gal-grid { grid-template-columns: 1fr 1fr; }
}
