.gallery {
  overflow: hidden;
}

.track {
  display: flex;
  gap: 1rem;
  width: 100%;
  height: 100%;
}

.panel {
  position: relative;
  flex: 1 1 0%;
  min-width: 0;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--color-kolabora-neutral-dark) 10%, transparent);
  transition: flex 500ms ease;

  img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.overlay,
.tint {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 300ms ease;
}

.overlay {
  display: flex;
  align-items: flex-end;
  padding: 1rem;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--color-kolabora-neutral-dark) 75%, transparent),
    transparent
  );
}

.tint {
  background: color-mix(in srgb, var(--color-kolabora-primary) 15%, transparent);
}

/* Desktop, hover-capable: expand-on-hover, horizontal — pure CSS. */
@media (hover: hover) and (min-width: 768px) {
  .panel {
    &:hover,
    &:focus-within {
      flex: 3 1 0%;

      .overlay,
      .tint {
        opacity: 1;
      }
    }
  }
}

/* Touch / no real hover, or narrow viewport: the same expand interaction as
   desktop, just vertical and scroll-driven instead of horizontal and
   hover-driven — `.active` is toggled by the IntersectionObserver in
   image-gallery.tsx, not by CSS alone. `.track`'s height is `auto` (sized
   by its content, not stretched to fill `.gallery`), which is exactly what
   lets that content be taller than `.gallery`'s own fixed height and
   actually require scrolling — but it also means each panel's flex-basis
   MUST be a plain length (vh), not a percentage: percentage flex-basis
   resolves against the flex container's (`.track`'s) own size, and an
   `auto`-height container has no definite size for that percentage to
   resolve against, so it'd silently fall back to being ignored. `vh` sidesteps
   that entirely — it's already an absolute length, nothing to resolve
   against `.track`. `scroll-snap` just settles on the nearest panel after a
   swipe instead of leaving it half-scrolled. */
@media (hover: none), (max-width: 767px) {
  .gallery {
    overflow-y: auto;
    overflow-x: hidden;
    scroll-snap-type: y proximity;
  }

  .track {
    flex-direction: column;
    height: auto;
  }

  .panel {
    flex: 0 0 38vh;
    scroll-snap-align: center;

    &.active {
      flex: 0 0 62vh;

      .overlay,
      .tint {
        opacity: 1;
      }
    }
  }
}

/* Reduced motion: static equal-size grid, no expand/scroll-driven animation
   in either mode. */
@media (prefers-reduced-motion: reduce) {
  .gallery {
    overflow: visible;
  }

  .track {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    width: 100%;
  }

  .panel {
    flex: none;
    transition: none;

    &:hover,
    &:focus-within,
    &.active {
      flex: none;
      transition: none;
    }
  }

  .overlay,
  .tint {
    transition: none;
  }
}
