/**
 * PUBLIC CATALOG — SHARED CONTROLS AND PAGE FURNITURE: .btn and its variants,
 * the results / sort bar, the similar-items rail, the search facet pills, the
 * lazy-image placeholder, the spinner and empty state, the footer, the back
 * button, and the desktop sidebar with its loading skeleton.
 *
 * SIXTH of ten sheets — after styles-detail.css, before styles-search.css.
 * Read the load-order block at the top of styles.css before moving a rule
 * between sheets: the split is a contiguous slice of one original file and the
 * cascade depends on it.
 *
 * These classes are used by MORE THAN ONE surface, which is why they get their
 * own sheet: a change here lands on browse, detail and search at once.
 */
/* ── Buttons ── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  border-radius: var(--radius-pill);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  transition: background 0.15s, transform 0.1s;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: linear-gradient(135deg, rgba(255, 107, 44, 0.92), rgba(255, 150, 66, 0.98));
  color: #111723;
}
.btn-primary:hover { background: linear-gradient(135deg, rgba(255, 132, 79, 0.98), rgba(255, 172, 89, 1)); }
.btn-outline { background: transparent; color: var(--text); border: var(--border-1); }
.btn-outline:hover { background: var(--bg-hover); border-color: var(--text-muted); }
.btn-success { background: var(--green); color: #fff; }

/* ── Sort bar ── */
.results-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border: var(--border-1);
  border-radius: 18px;
  background: rgba(255,255,255,0.025);
}
.results-info {
  font-size: 14px;
  color: var(--text-muted);
  font-weight: 500;
  font-family: var(--font-mono);
}
.sort-select {
  padding: 10px 12px;
  background: rgba(255,255,255,0.03);
  border: var(--border-1);
  border-radius: 14px;
  color: var(--text);
  font-size: 13px;
  outline: none;
  cursor: pointer;
}

/* ── Similar Items ── */
.similar-section {
  margin-top: 32px;
  padding-top: 24px;
  border-top: var(--border-1);
}
.similar-section.catalog-page-surface {
  margin-top: 32px;
  padding-top: 22px;
}
.similar-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 16px;
  color: var(--text);
}
.similar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.similar-card {
  background: var(--bg-card);
  border: var(--border-1);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.2s, transform 0.15s;
  overflow: hidden;
}
.similar-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.similar-card-thumb {
  aspect-ratio: 1;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.similar-card-thumb img { width: 100%; height: 100%; object-fit: cover; }
.similar-card-body { padding: 8px 10px; }
.similar-card-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.3;
}
.similar-card-cat {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
}
.adv-search-spacer {
  flex: 1;
}
/* `.adv-filter-tag-ai` sat here and now matches nothing. The active-filter row
   became REMOVABLE chips on 2026-09-17 (`.adv-filter-chip`, styles-search.css):
   every active filter is now one uniform, dismissible control, and the AI
   toggle is no longer a differently-coloured read-only tag among them. Its one
   producer was `searchActiveFiltersHtml` in data/catalog/search-advanced.js,
   which no longer emits the class. */
/* `.adv-results-empty-hint` sat here and matched nothing: the advanced-search
   empty state is `searchEmptyStateHtml()` in data/catalog/search-advanced.js,
   which renders the shared `.empty-state` block, and no producer anywhere emits
   this class. Deleted 2026-08-10 (no literal in any markup producer; absent from
   16 rendered surfaces including /search and /search with filters, where an empty
   state is the thing it would style; no dynamic composition of `*-empty-hint`). */
@media (max-width: 600px) {
  .similar-grid { grid-template-columns: 1fr; gap: 10px; }
  .catalog-page-surface { padding: 16px 14px 14px; border-radius: 18px; }
  .landing-panel { padding: 18px; border-radius: 22px; }
  .landing-hero { margin-bottom: 22px; }
  .landing-actions { margin-top: 18px; }
  .landing-action {
    width: 100%;
  }
  .landing-kicker {
    margin-bottom: 8px;
    letter-spacing: 0.18em;
  }
  .landing-title {
    font-size: clamp(28px, 9vw, 38px);
    margin-bottom: 12px;
  }
  .landing-copy {
    font-size: 14px;
  }
  .cat-card-status {
    font-size: 11px;
  }
  .cat-card-head {
    flex-direction: column;
    align-items: flex-start;
  }
  .catalog-page-summary { justify-content: flex-start; }
  .results-bar { padding: 10px 12px; }
  .results-bar {
    align-items: stretch;
  }
  .results-info {
    width: 100%;
  }
  .sort-select {
    width: 100%;
  }
  /* The `.search-facets` horizontal-scroll strip and its `.facet-pill` snap
     rules went with the facet UI itself on 2026-08-10 — see the note by the
     "Search Facets" section further down. */
  .detail-gallery { border-radius: 20px; }
  .detail-info { padding: 16px; gap: 12px; }
  .detail-page-summary {
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .detail-page-summary .catalog-pill {
    width: 100%;
  }
  .detail-title {
    font-size: clamp(22px, 7vw, 30px);
  }
  .catalog-inline-section {
    margin-bottom: 24px;
  }
  .catalog-inline-section-head {
    align-items: flex-start;
  }
  .catalog-inline-action {
    width: 100%;
  }
  .catalog-inline-center {
    text-align: center;
  }
  .request-form-actions {
    align-items: stretch;
  }
  .adv-results-shell {
    margin-top: 18px;
    padding: 18px 16px 16px;
  }
  .adv-search-panel {
    padding: 14px 12px;
    border-radius: 18px;
  }
  .adv-search-row {
    gap: 12px;
    margin-bottom: 12px;
  }
}

@media (max-width: 420px) {
  .container {
    padding: 18px 12px 22px;
  }
  .header {
    gap: 8px 10px;
  }
  .landing-panel {
    padding: 16px;
    border-radius: 20px;
  }
  .landing-facts {
    grid-template-columns: 1fr;
  }
  .landing-fact {
    padding: 8px 10px;
  }
  .category-surface-grid {
    gap: 12px;
  }
}

/* ── Search Facets ── DELETED 2026-08-10.
   `.search-facets`, `.facet-pill` (+ :hover / .active), `.facet-count` and the
   phone-width scroll-snap overrides above styled a category-facet strip that no
   client renders. Careful, because the obvious grep LIES here in both directions:
   the string `search-facets` DOES appear in the repo — as the API route path
   `GET /api/catalog/search-facets` (src/routes/catalog-meta-routes.ts) — so a
   substring search reports the class as live. Proven dead three ways instead:
   (1) no occurrence of `facet` in ANY markup producer — data/catalog/*.js,
   data/catalog.html, data/catalog/admin/*.js, or any src/routes template;
   (2) absent from the rendered DOM of 16 real Chromium surfaces, including
   /search and /search with a query + filters applied, which is where a facet
   strip would live; (3) no dynamic composition — nothing concatenates a
   `facet-*` class name anywhere.
   The ENDPOINT is still mounted and still tested and is left alone (this pass
   does not touch src/). It now has no consumer, which is a decision for whoever
   owns the search surface, not a stylesheet's business. */

/* ── Lazy-load placeholder ── */
img[data-src] {
  background: linear-gradient(90deg, var(--bg-hover) 25%, rgba(255,255,255,0.05) 50%, var(--bg-hover) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}
img[data-src].lazy-loaded {
  background: none;
  animation: none;
}

/* ── Spinner ── */
.spinner {
  display: inline-block;
  width: 24px; height: 24px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-center {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 120px 20px;
}
.empty-state {
  text-align: center;
  padding: 60px 24px;
  color: var(--text-muted);
  border: var(--border-1);
  border-radius: 24px;
  background: rgba(255,255,255,0.025);
  max-width: 640px;
  margin: 0 auto;
}
.empty-state .icon { font-size: 48px; margin-bottom: 12px; }

/* ── Footer ── */
.footer {
  text-align: center;
  padding: 30px 24px 40px;
  font-size: 12px;
  color: var(--text-dim);
  border-top: var(--border-1);
  margin-top: 52px;
}
.footer a { color: var(--accent); text-decoration: none; }
.footer-mark {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 8px;
}
.footer-copy {
  max-width: 56ch;
  margin: 0 auto 10px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-muted);
}
.footer-meta {
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11px;
}

/* ── Back button ── */
.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--accent);
  cursor: pointer;
  margin-bottom: 20px;
  padding: 8px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 107, 44, 0.18);
  background: rgba(255, 107, 44, 0.06);
  text-decoration: none;
}
.back-btn:hover { text-decoration: none; background: rgba(255, 107, 44, 0.1); }

/* ── Desktop Sidebar ── */
.sidebar {
  width: var(--sidebar-width);
  position: fixed;
  left: 0;
  top: var(--header-height);
  bottom: 0;
  background: rgba(8, 13, 20, 0.82);
  border-right: var(--border-1);
  overflow-y: auto;
  z-index: 50;
  display: flex;
  flex-direction: column;
  backdrop-filter: blur(16px);
}
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 18px 16px;
  border-bottom: var(--border-1);
  flex-shrink: 0;
}
.sidebar-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
}
.sidebar-subtitle {
  margin-top: 4px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.5;
  max-width: 22ch;
}
.sidebar-body {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0 18px;
}
.sidebar-body::-webkit-scrollbar { width: 4px; }
.sidebar-body::-webkit-scrollbar-track { background: transparent; }
.sidebar-body::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.sidebar-body::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
.sidebar-home {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  min-height: 44px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  border-bottom: 1px solid rgba(42, 46, 58, 0.32);
  margin-bottom: 2px;
  border-radius: 14px;
  margin-left: 8px;
  margin-right: 8px;
}
.sidebar-home:hover { background: var(--bg-hover); color: var(--accent); }
.sidebar-home.active { color: var(--accent); background: var(--accent-glow); }
.sidebar-home svg { width: 14px; height: 14px; flex-shrink: 0; }
.sb-parent {
  border-bottom: 1px solid rgba(42, 46, 58, 0.22);
  margin: 0 8px;
}
.sb-parent-header {
  display: flex;
  align-items: flex-start;
  padding: 10px 14px;
  min-height: 44px;
  cursor: pointer;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
  user-select: none;
  gap: 8px;
  border-radius: 14px;
}
.sb-parent-header:hover { background: var(--bg-hover); color: var(--accent); }
.sb-parent-header.active { color: var(--accent); background: var(--accent-glow); }
.sb-parent-name {
  flex: 1;
  min-width: 0;
  white-space: normal;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.25;
}
.sb-parent-count {
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 400;
  flex-shrink: 0;
  background: rgba(255,255,255,0.05);
  padding: 1px 7px;
  border-radius: 10px;
}
.sb-chevron {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  transition: transform 0.2s, color 0.15s;
  flex-shrink: 0;
  cursor: pointer;
  padding: 2px;
  border-radius: 4px;
}
.sb-chevron:hover { color: var(--accent); background: var(--bg-hover); }
.sb-parent.expanded .sb-chevron { transform: rotate(90deg); }
.sb-subcats {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  background: rgba(0,0,0,0.12);
}
.sb-parent.expanded .sb-subcats { max-height: 1200px; }
.sb-subcat {
  display: flex;
  align-items: flex-start;
  padding: 8px 14px 8px 34px;
  min-height: 44px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 12px;
  transition: background 0.15s, color 0.15s;
  gap: 8px;
  border-radius: 14px;
}
.sb-subcat:hover { background: var(--bg-hover); color: var(--accent); }
.sb-subcat.active { color: var(--accent); font-weight: 600; background: var(--accent-glow); }
.sb-subcat-name {
  flex: 1;
  min-width: 0;
  white-space: normal;
  line-height: 1.35;
}
.sb-subcat-count {
  font-size: 10px;
  color: var(--text-dim);
  flex-shrink: 0;
}

/* Main content shift */
.main-content {
  margin-left: var(--sidebar-width);
  min-height: calc(100vh - var(--header-height));
}

/* ── Sidebar skeleton loading ── */
.sb-skeleton { padding: 8px 16px; }
.sb-skeleton-item {
  height: 32px;
  background: linear-gradient(90deg, var(--bg-hover) 25%, rgba(255,255,255,0.05) 50%, var(--bg-hover) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: 6px;
  margin-bottom: 6px;
}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

@media (max-width: 768px) {
  .sidebar { display: none !important; }
  .main-content {
    margin-left: 0 !important;
    min-height: auto;
  }
}
