/* ==========================================================================
   Products page — catalog hero (title + live status dot + filters) and
   the 9-card grid. Product detail page styles live in a separate file,
   product-detail.css, shared across every "View Specifications" page.
   ========================================================================== */

/* ---------- Catalog hero (dark intro banner, same family as the home
   hero / about-hero) ---------- */
.products-hero {
  position: relative;
  padding-top: calc(var(--header-h) + var(--space-4));
  padding-bottom: var(--space-5);
  background: var(--navy-900);
  overflow: hidden;
  color: var(--text-on-dark);
}

.products-hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(55% 50% at 15% 10%, rgba(0, 163, 255, 0.16) 0%, rgba(0, 163, 255, 0) 60%),
    radial-gradient(45% 40% at 95% 90%, rgba(38, 56, 128, 0.45) 0%, rgba(38, 56, 128, 0) 65%),
    linear-gradient(180deg, var(--navy-950) 0%, var(--navy-900) 45%, var(--navy-900) 100%);
}

.products-hero-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(55% 60% at 20% 20%, black 0%, transparent 75%);
}

.products-hero .container {
  position: relative;
  z-index: 1;
}

/* Title row: small pulsing status dot immediately left of "Products",
   like a live-catalog / systems-nominal indicator. */
.products-title {
  display: flex;
  align-items: center;
  gap: 14px;
}

.status-dot {
  position: relative;
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--status-green);
}

.status-dot::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: var(--status-green);
  opacity: 0.35;
  animation: status-dot-pulse 2.2s ease-out infinite;
}

@keyframes status-dot-pulse {
  0% {
    transform: scale(0.6);
    opacity: 0.45;
  }
  100% {
    transform: scale(1.8);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .status-dot::after {
    animation: none;
    opacity: 0;
  }
}

.products-title h1 {
  /* Reduced back down from fs-h1 — that was sized to match the
     reference screenshot, but ended up reading too big/bold in
     practice. fs-h2 (max ~40px) plus a lighter weight below is more
     proportionate for a single short word.
     Sized down again from fs-h2 — still reading too large/heavy next
     to the small status dot. Also moved off the hero's default white
     (--text-on-dark) to --ash so the title sits a step quieter than
     pure white, matching --mist's role on .products-lead. */
  font-size: calc(var(--fs-h2) * 0.8);
  font-weight: 600;
  color: var(--ash);
}

.products-lead {
  margin-top: var(--space-2);
  /* Reduced again — from ~17-17.6px down to 15px (fs-body-sm, the
     site's standard small-text token) — still reading too large at
     the previous size. */
  font-size: var(--fs-body-sm);
  color: var(--mist);
  max-width: 46ch;
}

/* ---------- Category filters ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: var(--space-4);
}

.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* Reduced padding, font, and switched to the mono font — was using
     the default body font (Inter) at 15px/10px-18px padding; the
     reference's pills use a mono font at 12px/9px-16px, and the
     client asked for these to read "extremely smaller." */
  padding: 8px 15px;
  border-radius: var(--radius-full);
  border: 1.5px solid var(--border-dark-strong);
  background: transparent;
  color: var(--mist);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  font-weight: 500;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.filter-pill:hover {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.3);
  background: var(--glass-fill);
}

.filter-pill.is-active {
  background: var(--white);
  color: var(--ink);
  border-color: var(--white);
}

.filter-dot {
  /* Reduced from 8px to stay proportional to the smaller pill. */
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}

/* Each pill's dot keeps its category color even when currentColor
   would otherwise flip (e.g. on the active/inverted state) — using a
   background color directly rather than currentColor avoids that. */
.filter-dot--all {
  background: var(--mist);
}
.filter-pill.is-active .filter-dot--all {
  background: var(--ink-soft);
}

.filter-dot--vision {
  background: var(--electric);
}

.filter-dot--refraction {
  background: var(--whatsapp-teal);
}

.filter-dot--lens {
  background: var(--accent-amber);
}

/* ---------- Catalog grid ---------- */
.catalog-section {
  padding-block: var(--space-5);
}

.catalog-section .product-grid {
  gap: var(--space-4);
}

/* ---------- Product card visual refinements ---------- */

/* Every card in a row is stretched to the same height (the grid
   default) so the grid reads as one uniform block regardless of how
   tall a given product name happens to wrap. The card itself becomes
   a column flexbox so that stretched extra height is handed to
   .product-body (which then pins the footer to the bottom) instead
   of sitting as dead space under the card. */
.catalog-section .product-grid {
  align-items: stretch;
}

.catalog-section .product-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* Product photos are supplied on a plain white canvas at wildly
   different real-world proportions — tall chair-and-table rigs
   (ORT 1/2) vs. squat desktop units (RM-Lite). A fixed-ratio box is
   what keeps every card the same size no matter which photo lands in
   it; object-fit: contain is what guarantees the *complete* photo is
   always visible inside that box (it letterboxes on the short sides
   instead of cropping, rather than growing the box to match the
   image — which is what previously broke the grid's uniform height).
   flex: none keeps the thumb's height locked even though the card
   around it is now allowed to stretch taller than its content. */
.catalog-section .product-card .product-thumb {
  position: relative;
  background: #fff;
  overflow: hidden;
  /* Shorter than the previous 1/1 — a wider-than-tall box trims the
     overall card height while still comfortably fitting every photo,
     tall or squat, without cropping any of them. */
  aspect-ratio: 4 / 3;
  height: auto;
  flex: none;
}

.catalog-section .product-card .product-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  /* Near-zero margin — object-fit: contain still guarantees the photo
     is never cropped (it's the box's own 4:3 shape, not this padding,
     that decides how much of the box a given photo's silhouette can
     fill), so shrinking this just lets every photo scale up to the
     largest size that still fits cleanly inside the box. */
  padding: 1%;
  background: #fff;
  box-sizing: border-box;
}

/* Absorbs the stretched extra height from taller neighbors in the
   same row, and pins the "View Specifications" footer to a consistent
   baseline even when a product name wraps to two lines instead of
   one. */
.catalog-section .product-card .product-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* One step down from the shared component's uniform space-3 (24px)
     bottom padding — tightens the gap under the "Product Details"
     divider without touching the padding above the product name. */
  padding-bottom: var(--space-2);
}

/* Product names are supporting catalog labels, not headings. Sized
   down from the base component's 1.0625rem — that read too large/
   heavy for a 9-card grid of short labels. */
.catalog-section .product-card .product-name {
  font-size: 0.9375rem;
  font-weight: 500;
}

/* Category tag colors — NOT currently used on the catalog grid (the
   client asked for photo + name only, no badge). Kept here, unused,
   in case a future page (e.g. a product detail header) wants a
   category tag — reuses the same product-category badge component
   from components.css, just with per-category tint. Fully opaque (not
   translucent like the base rule) and using the "dim" variant of each
   hue — tested against the lightest part of the thumb's own background
   gradient, translucent versions dropped as low as 2.4:1 for white
   text; these guarantee >= 4.5:1 regardless of what's behind them. */
.tag-vision {
  background: var(--electric-dim);
  border-color: var(--electric-dim);
}
.tag-refraction {
  background: var(--whatsapp-teal);
  border-color: var(--whatsapp-teal);
}
.tag-lens {
  background: var(--accent-amber-dim);
  border-color: var(--accent-amber-dim);
}
