/* Styling for apps.html only. Deliberately NOT a copy of the old site's app browser: that one
   kept every app's real description/features in a JS data object and only rendered them into
   a modal on click, which meant none of that content existed in the page for a crawler (or
   anyone without JS) to see. Here, every card's title/description/category is real HTML
   present on page load - the filter tabs and search box below only toggle a `hidden` class on
   cards that already exist, they never inject content. */

.catalogue-hero {
  padding: 64px 0 8px;
  text-align: center;
}

.catalogue-hero h1 {
  margin: 0;
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.catalogue-hero .lede {
  max-width: 620px;
  margin: 18px auto 0;
  font-size: 17px;
  line-height: 1.65;
  color: var(--body-text);
}

/* ---- Search + filter controls ---- */

.catalogue-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  margin-bottom: 36px;
}

.catalogue-search {
  position: relative;
  width: 100%;
  max-width: 360px;
}

.catalogue-search input {
  width: 100%;
  padding: 11px 38px 11px 38px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #ffffff;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s ease;
}

.catalogue-search input:focus { border-color: var(--accent-light); }

.catalogue-search svg.search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--muted);
  pointer-events: none;
}

.catalogue-search button.search-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  display: none;
}

.catalogue-search button.search-clear.visible { display: block; }
.catalogue-search button.search-clear:hover { color: var(--accent); }

.catalogue-filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

.filter-tab {
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #ffffff;
  color: var(--body-text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.filter-tab:hover { border-color: var(--accent-light); }

.filter-tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
}

/* ---- Catalogue grid ---- */

/* Widened from the shared 1080px .wrap so 4 cards (260px basis + 24px gaps = 1112px of content)
   actually fit in a row on typical desktop widths, instead of wrapping down to 3. Rob asked for
   the catalogue to page 4 x 2 (8 per page) instead of 1 x 3 - this is the "make 4 fit" half of
   that; the JS below paginates by 2x whatever row size actually measures, so it stays "N x 2"
   rather than hardcoding 8 and breaking on narrower screens. */
.catalogue-wrap {
  max-width: 1200px;
}

.catalogue-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
}

.catalogue-card {
  flex: 0 1 260px;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 16px 36px rgba(15, 23, 42, 0.06);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.catalogue-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 22px 44px rgba(15, 23, 42, 0.10);
}

.catalogue-card.hidden { display: none; }

.catalogue-card .catalogue-img-wrap {
  position: relative;
  height: 150px;
  overflow: hidden;
  background: var(--panel);
}

.catalogue-card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

.catalogue-card .category-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  backdrop-filter: blur(2px);
}

.catalogue-card .catalogue-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 18px 20px 20px;
}

.catalogue-card h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 760;
  color: var(--ink);
}

.catalogue-card p {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--body-text);
  /* Grows to fill any leftover vertical space in the card, so "Learn more" always sits at the
     same baseline as the cards next to it in the row, regardless of description length. */
  flex: 1 0 auto;
}

/* Price row for apps with locked pricing (Vector, Forma) - uses the shared .price-pill/.price-
   block/.price-detail components from site.css. A <div>, not a <p>, so it's naturally exempt
   from the `.catalogue-card p { flex: 1 0 auto }` baseline-alignment rule above. */
.catalogue-price {
  margin: -10px 0 14px;
}

.catalogue-price .price-detail { font-size: 11px; }

.catalogue-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.catalogue-card .learn-more {
  display: inline-block;
  color: var(--accent);
  text-decoration: none;
  font-size: 13px;
  font-weight: 700;
}

.catalogue-card .learn-more:hover { color: var(--accent-dark); }

.catalogue-download {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--accent);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.catalogue-download svg { width: 15px; height: 15px; }

.catalogue-download:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
  transform: translateY(-1px);
}

.catalogue-empty {
  display: none;
  text-align: center;
  padding: 48px 0;
  color: var(--muted);
  font-size: 14px;
}

.catalogue-empty.visible { display: block; }

/* ---- Pagination ---- */

.catalogue-pagination {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 20px;
  margin-top: 40px;
}

.catalogue-pagination.visible { display: flex; }

.pagination-btn {
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #ffffff;
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.pagination-btn:hover:not(:disabled) {
  border-color: var(--accent-light);
  color: var(--accent);
}

.pagination-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.pagination-status {
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
}

@media (max-width: 640px) {
  .catalogue-hero { padding: 48px 0 8px; }
  .catalogue-hero h1 { font-size: 28px; }
  .catalogue-hero .lede { font-size: 15px; }
  .catalogue-card { flex-basis: 100%; }
}
