/* ==========================================================================
   Kedn Hub — Homepage sections (Stage 2). Shared shell/tokens/primitives
   live in tokens.css + style.css; this file is homepage-specific.
   ========================================================================== */

/* ---- Hero product carousel ----
   Dark green/lime hero (2026-08-26 revision) that rotates through 5 real
   products one at a time — own photo, name, price, CTA — a pattern the
   user asked to copy from vmtacticals.com's hero slider. Colors are the
   --color-lime*/--color-hero-green* tokens from tokens.css, scoped to this
   hero + the category-card lime touches only. Pure CSS class-toggle +
   js/hero-carousel.js; ships with slide 1 marked .is-active so it still
   renders correctly with JS disabled (just no rotation).
   The lifestyle photo (hero-lifestyle.jpg) sits as a fixed background
   behind every slide, with a dark scrim so text stays legible; each
   product's own photo then sits on top of it in a same-size card. */
/* min-height must fit the TALLEST slide's stacked mobile content (image +
   price + eyebrow + name + description + CTA, all in a column) since
   .hero-carousel__slide is position:absolute + inset:0 for the crossfade —
   its height always exactly matches this min-height regardless of its own
   content, and overflow:hidden below means anything taller gets clipped,
   not pushed. 44rem covers a long wrapped product name (worked through the
   worst case at 320px: ~42rem) with a safety margin.
   Below 640px this is overridden to a hard-capped 12rem — see the
   "Compact mobile hero" block right after this section. */
.hero-carousel {
  position: relative;
  min-height: 44rem;
  overflow: hidden;
  background: var(--color-hero-green-deep) url("/assets/img/hero/hero-lifestyle.jpg") center 20% / cover no-repeat;
}

.hero-carousel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(100deg, rgba(12, 22, 16, 0.92) 0%, rgba(12, 22, 16, 0.8) 40%, rgba(12, 22, 16, 0.62) 100%),
    linear-gradient(0deg, rgba(12, 22, 16, 0.55) 0%, transparent 40%);
}

/* padding-top/bottom (not just min-height) so the content is genuinely
   framed with breathing room under the sticky nav, and stays centered in
   that padded space rather than butting up against the header. */
.hero-carousel__slide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: var(--space-7) 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-slower) var(--ease-standard);
  pointer-events: none;
}

.hero-carousel__slide.is-active {
  position: relative;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Mobile (base): image-over-text, centered — the only layout that can't
   overflow a narrow viewport, since row-with-a-fixed-width-image was the
   actual cause of the hero clipping past the screen edge on phones (a
   long product name has no room to shrink next to a 208px non-shrinking
   image + 64px gap once min-width:0 isn't set — see .hero-carousel__content
   below). Row-with-image-left restores at 640px+, where there's genuinely
   enough width for it. Capped inner width + auto margins keep the whole
   cluster centered within the section rather than hugging an edge on wide
   screens. The CTA lives outside .hero-carousel__row, as a sibling, so it
   can center itself under the whole image+text group. */
.hero-carousel__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  max-width: 42rem;
  margin-inline: auto;
}

.hero-carousel__row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
}

.hero-carousel__media-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* Fixed, deliberately small card size (10rem) + object-fit: cover so every
   slide's product photo renders at the same visual size, floating over
   the section's shared background photo rather than each scaling to its
   own aspect ratio. */
.hero-carousel__media {
  position: relative;
  z-index: 1;
  width: 11rem;
  aspect-ratio: 4 / 5;
  border-radius: 12px;
  overflow: hidden;
  background: var(--color-hero-green);
  box-shadow: var(--shadow-lg);
}

.hero-carousel__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* min-width: 0 is the actual fix — without it a flex item's default
   min-width:auto refuses to shrink below its content's widest unbreakable
   word (a long bold product name in the row layout), which is exactly
   what was pushing the hero past the viewport edge on phones. */
.hero-carousel__content {
  min-width: 0;
  max-width: 26rem;
  width: 100%;
  text-align: center;
  color: var(--color-off-white);
}

.eyebrow--lime {
  color: var(--color-lime);
}

.hero-carousel__badge {
  font-family: "Jost", var(--font-body);
}

/* Jost (not the site's usual Fraunces serif) for this band specifically —
   it's the same bold geometric sans now used on the nav, and it reads as a
   more modern, tactical-adjacent "hero moment" that suits the dark/lime
   carousel; Fraunces stays the voice for the rest of the site. Sized to
   --text-h2 rather than --text-h1 so it sits in proportion with the
   smaller 10rem product card next to it. */
.hero-carousel__name {
  font-family: "Jost", var(--font-body);
  font-weight: 700;
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin-top: var(--space-2);
}

.hero-carousel__desc {
  margin: var(--space-3) auto 0;
  max-width: 32ch;
  color: var(--color-warm-neutral);
}

.hero-carousel__price {
  font-family: "Jost", var(--font-body);
  font-weight: 600;
  font-size: var(--text-h3);
  color: var(--color-lime-tint);
  text-align: center;
}

.hero-carousel__cta {
  display: inline-flex;
  margin-top: var(--space-5);
  border-radius: var(--radius-pill);
  background: var(--color-lime);
  color: var(--color-hero-green-deep);
  font-family: "Jost", var(--font-body);
  font-weight: 600;
}

.hero-carousel__cta:hover {
  background: var(--color-lime-strong);
}

.hero-carousel__arrow {
  position: absolute;
  top: 50%;
  z-index: 3;
  transform: translateY(-50%);
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(247, 244, 238, 0.35);
  background: rgba(12, 22, 16, 0.4);
  color: var(--color-off-white);
}

.hero-carousel__arrow svg {
  width: 1.25rem;
  height: 1.25rem;
}

.hero-carousel__arrow:hover {
  border-color: var(--color-lime);
  color: var(--color-lime);
}

.hero-carousel__arrow--prev {
  left: var(--space-4);
}

.hero-carousel__arrow--next {
  right: var(--space-4);
}

.hero-carousel__dots {
  position: absolute;
  left: 50%;
  bottom: var(--space-5);
  z-index: 3;
  transform: translateX(-50%);
  display: flex;
  gap: var(--space-2);
}

.hero-carousel__dots button {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: rgba(247, 244, 238, 0.35);
  transition: background var(--duration-standard) var(--ease-standard),
    transform var(--duration-standard) var(--ease-standard);
}

.hero-carousel__dots button.is-active {
  background: var(--color-lime);
  transform: scale(1.3);
}


/* ---- Compact mobile hero (max 9.5rem tall) ----
   height (not min-height) is a hard cap, paired with overflow:hidden on
   .hero-carousel above, so this box is ALWAYS exactly 9.5rem regardless of
   content - min-height:0 here stops the 44rem floor from the base rule
   above winning (min-height always wins over a smaller height). A fixed,
   unambiguous number is what keeps the arrows/dots/pill below correctly
   anchored (a min-height that real content could silently exceed is
   exactly what caused them to land in the wrong place before). Unlike a
   min-height mismatch, an under-estimate here just clips content at the
   box edge instead of breaking layout elsewhere - a safe failure mode.
   Image and text switch to a compact side-by-side row and the description
   is dropped entirely - there's no vertical room for it at this size. The
   section box itself is sized tightly to that compact content (not just
   the content shrunk inside a still-generous box). */
@media (max-width: 639px) {
  .hero-carousel {
    height: 9.5rem;
    min-height: 0;
  }

  .hero-carousel__slide {
    padding: var(--space-2) 0;
  }

  .hero-carousel__row {
    flex-direction: row;
    align-items: center;
    gap: var(--space-3);
  }

  .hero-carousel__media-col {
    gap: var(--space-1);
  }

  .hero-carousel__media {
    width: 4.5rem;
  }

  .hero-carousel__content {
    text-align: left;
  }

  .hero-carousel__price {
    font-size: var(--text-small);
  }

  .hero-carousel__name {
    font-size: 0.9rem;
    line-height: 1.2;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }

  .hero-carousel__desc {
    display: none;
  }

  .hero-carousel__cta {
    margin-top: var(--space-2);
    padding: var(--space-2) var(--space-4);
    font-size: 0.65rem;
  }

  .hero-carousel__dots {
    bottom: var(--space-2);
  }
}


/* ---- Featured categories ---- */
.categories {
  padding-top: var(--space-9);
}

/* Was an absolutely-positioned pill overlaid on the hero, linking down to
   this section; now it's the section's own visible heading, sitting
   directly above the cards it labels. */
.categories__label {
  display: inline-flex;
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-pill);
  font-family: "Jost", var(--font-body);
  font-size: var(--text-label);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text);
}

/* One horizontally-scrolling row of small tiles on mobile (same flex/
   scroll-snap recipe as .product-rail__track), instead of a wrapping
   grid; restores to the original larger single/2-up wrapping grid at
   640px+ - see that breakpoint. */
.categories__grid {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
  scrollbar-color: var(--color-warm-neutral) transparent;
}

.category-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: var(--space-1);
  flex: 0 0 8rem;
  scroll-snap-align: start;
  padding: var(--space-3) var(--space-2);
  min-height: 10rem;
  overflow: hidden;
  color: var(--color-off-white);
}

.category-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  transition: transform var(--duration-slow) var(--ease-out);
}

.category-card:hover::before {
  transform: scale(1.04);
}

.category-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(0deg, rgba(11, 10, 8, 0.72) 0%, rgba(11, 10, 8, 0.15) 55%, rgba(11, 10, 8, 0.05) 100%);
}

.category-card > * {
  position: relative;
  z-index: 3;
}

/* ---- Category card photo slideshow (Watches, Perfumes, Sunglasses —
   the categories with real product photography). Cycled by
   js/category-slideshow.js; the first image ships marked .is-active so
   the card still shows a photo correctly if the script never runs. ---- */
.category-card__slideshow {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  transition: transform var(--duration-slow) var(--ease-out);
}

.category-card:hover .category-card__slideshow {
  transform: scale(1.04);
}

.category-card__slideshow img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 900ms var(--ease-standard);
}

.category-card__slideshow img.is-active {
  opacity: 1;
}

.category-card--watches::before {
  background: linear-gradient(150deg, var(--color-charcoal) 0%, var(--color-black) 100%);
}

.category-card--perfumes::before {
  background: linear-gradient(150deg, #46403a 0%, var(--color-charcoal) 100%);
}

.category-card--gifts::before {
  background:
    radial-gradient(120% 100% at 100% 0%, rgba(182, 146, 79, 0.35), transparent 55%),
    linear-gradient(150deg, var(--color-black) 0%, #171410 100%);
}

.category-card--boots::before {
  background: linear-gradient(155deg, var(--color-charcoal-soft) 0%, var(--color-charcoal) 100%);
}

.category-card--sunglasses::before {
  background: linear-gradient(155deg, #3a352c 0%, var(--color-black) 100%);
}

.category-card--jewelry::before {
  background: linear-gradient(155deg, #2e1620 0%, var(--color-black) 100%);
}

/* Icon and subtitle are hidden at the small 10rem mobile card size - no
   room for them without crowding the title, and the photo + title already
   identify the category; both come back at 640px+ - see that breakpoint. */
.category-card__icon {
  display: none;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--color-gold-tint);
  margin-bottom: var(--space-4);
}

.category-card__icon svg {
  width: 100%;
  height: 100%;
}

.category-card__title {
  font-family: var(--font-display);
  font-size: 0.95rem;
  line-height: var(--leading-tight);
}

.category-card__sub {
  display: none;
  font-size: var(--text-small);
  color: var(--color-warm-neutral);
}

.category-card__cta {
  margin-top: auto;
  padding-top: var(--space-2);
  font-size: 0.65rem;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-gold-tint);
}

/* ---- Product rails ----
   flex-wrap + min-width:0 so a long heading next to the nowrap "View
   All" link drops to its own line on a narrow phone instead of
   refusing to shrink and pushing the page wider than the viewport. */
.product-rail__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-1) var(--space-4);
  margin-bottom: var(--space-6);
}

.product-rail__head > div {
  min-width: 0;
}

.product-rail__head h2 {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  margin-top: var(--space-2);
}

.product-rail__track {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
  scrollbar-color: var(--color-warm-neutral) transparent;
}

/* 8rem on mobile so the rail shows more of the row at once; back to the
   original 16rem at 640px+ - see that breakpoint. */
.product-card {
  flex: 0 0 8rem;
  scroll-snap-align: start;
}

/* ---- Editorial / featured collection ---- */
.editorial {
  background: var(--color-surface);
}

.editorial__intro {
  max-width: 42rem;
  margin-bottom: var(--space-7);
}

.editorial__intro h2 {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  margin-top: var(--space-2);
}

.editorial__intro p {
  margin-top: var(--space-4);
  color: var(--color-text-muted);
  max-width: 42ch;
}

/* One stacked row per brand, each independently horizontally-scrollable
   (same flex/scroll-snap recipe as .product-rail__track) - always, not
   just on mobile, since a wrapping grid doesn't make sense once there
   are several of these rows stacked down the section. */
.editorial__brands {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* flex-wrap + min-width:0 on the heading so a long brand name (Yves
   Saint Laurent, The North Face...) next to the nowrap "Shop X" link
   drops to its own line on a narrow phone instead of refusing to
   shrink and pushing the whole page wider than the viewport - the same
   min-width:auto flex trap noted on .hero-carousel__content above. */
.editorial__brand-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-4);
  margin-bottom: var(--space-3);
}

.editorial__brand-head h3 {
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--text-h3);
}

.editorial__products {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
  scrollbar-color: var(--color-warm-neutral) transparent;
}

.editorial__product {
  display: block;
  flex: 0 0 8rem;
  scroll-snap-align: start;
}

.editorial__product-media {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--color-charcoal-soft);
  background: linear-gradient(155deg, var(--color-warm-neutral-soft) 0%, var(--color-off-white) 100%);
}

.editorial__product-media svg {
  width: 42%;
  height: 42%;
}

.editorial__product-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slower) var(--ease-out);
}

.editorial__product:hover .editorial__product-media img {
  transform: scale(1.055);
}

.editorial__product-name {
  display: block;
  padding: var(--space-3) 0 0;
  font-family: var(--font-display);
  font-size: var(--text-body);
}

.editorial__product-price {
  display: block;
  padding: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-small);
}

/* ---- Discover (finders) ---- */
.discover {
  background: var(--color-warm-neutral-soft);
}

.discover__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

.discover-card {
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-text);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
}

.discover-card h3 {
  font-family: var(--font-display);
  font-size: var(--text-h3);
}

.discover-card p {
  color: var(--color-text-muted);
  flex: 1;
}

/* ---- Build Your Gift ---- */
.gift-builder {
  background: var(--color-black);
  color: var(--color-off-white);
  text-align: center;
}

.gift-builder__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gift-builder .section-head {
  margin-inline: auto;
}

.gift-builder .section-head p {
  color: var(--color-warm-neutral);
}

.gift-builder__steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
  margin: var(--space-7) 0;
  max-width: 42rem;
}

.gift-builder__steps li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-small);
  color: var(--color-warm-neutral);
}

.gift-builder__step-number {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  color: var(--color-gold-tint);
}

/* ---- Compact mobile Discover + Gift Builder (max 12rem tall each) ----
   Same height-cap + overflow:hidden recipe as the mobile hero - see that
   section's comment for why a hard cap beats a min-height guess. Both
   drop their descriptive paragraph and eyebrow (no vertical room) and
   turn their multi-item content into one horizontally-scrolling row. */
@media (max-width: 639px) {
  .discover {
    height: 12rem;
    overflow: hidden;
    padding-block: var(--space-3);
  }

  .discover .section-head {
    margin-bottom: var(--space-2);
  }

  .discover .section-head .eyebrow {
    display: none;
  }

  .discover .section-head h2 {
    font-size: 1.1rem;
  }

  .discover__grid {
    display: flex;
    gap: var(--space-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
    scrollbar-color: var(--color-warm-neutral) transparent;
  }

  .discover-card {
    flex: 0 0 9rem;
    scroll-snap-align: start;
    gap: var(--space-1);
    padding-top: var(--space-2);
  }

  .discover-card h3 {
    font-size: 0.85rem;
  }

  .discover-card p {
    display: none;
  }

  .discover-card .btn {
    padding: var(--space-1) var(--space-3);
    font-size: 0.6rem;
  }

  .gift-builder {
    height: 12rem;
    overflow: hidden;
    padding-block: var(--space-3);
  }

  .gift-builder .section-head {
    margin-bottom: var(--space-2);
  }

  .gift-builder .section-head .eyebrow {
    display: none;
  }

  .gift-builder .section-head h2 {
    font-size: 1.1rem;
  }

  .gift-builder .section-head p {
    display: none;
  }

  .gift-builder__steps {
    display: flex;
    gap: var(--space-4);
    margin: var(--space-3) 0;
    max-width: none;
    overflow-x: auto;
  }

  .gift-builder__steps li {
    flex: 0 0 auto;
    font-size: 0.6rem;
  }

  .gift-builder__step-number {
    font-size: var(--text-body);
  }

  .gift-builder__inner .btn {
    padding: var(--space-2) var(--space-5);
    font-size: 0.7rem;
  }
}

/* ---- Why Kedn Hub (trust) ---- */
.trust__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
  text-align: center;
}

.trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text-muted);
}

.trust-item svg {
  width: 28px;
  height: 28px;
  color: var(--color-accent-strong);
}

.trust-item p {
  font-size: var(--text-small);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text);
}

/* Staggered reveal, 1s apart - js/scroll-reveal.js adds .is-revealed to
   every .trust-item at roughly the same moment (they all enter the
   viewport together), so the sequencing comes entirely from delaying
   each item's own transition rather than from JS timing. */
.trust-item.reveal:nth-child(1) { transition-delay: 0s; }
.trust-item.reveal:nth-child(2) { transition-delay: 1s; }
.trust-item.reveal:nth-child(3) { transition-delay: 2s; }
.trust-item.reveal:nth-child(4) { transition-delay: 3s; }
.trust-item.reveal:nth-child(5) { transition-delay: 4s; }
.trust-item.reveal:nth-child(6) { transition-delay: 5s; }

/* One horizontally-scrolling row on mobile (same flex/scroll-snap recipe
   used elsewhere), hard-capped at 12rem tall - see the mobile hero's CSS
   comment for why height+overflow:hidden beats a min-height guess.
   Restores to the grid above at 640px+, unchanged. */
@media (max-width: 639px) {
  .trust {
    height: 12rem;
    overflow: hidden;
    padding-block: var(--space-5);
  }

  .trust__grid {
    display: flex;
    gap: var(--space-5);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
    scrollbar-color: var(--color-warm-neutral) transparent;
  }

  .trust-item {
    flex: 0 0 6.5rem;
    scroll-snap-align: start;
  }
}

/* ---- Reviews ---- */
.reviews {
  background: var(--color-surface);
}

/* Mobile: .reviews__track auto-scrolls right-to-left, continuously, via
   the duplicated-content + translateX(-50%) loop technique already used
   for the hero marquee. Desktop restores the plain static 3-up grid (see
   the 1024px breakpoint) — the motion is a mobile-only touch. */
.reviews__grid {
  overflow: hidden;
}

.reviews__track {
  display: flex;
  gap: var(--space-5);
  width: max-content;
  animation: reviews-marquee 26s linear infinite;
}

@keyframes reviews-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.review-card {
  flex: 0 0 82vw;
  max-width: 22rem;
  margin: 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-hairline);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.review-card p {
  font-family: var(--font-display);
  font-size: var(--text-body-lg);
  line-height: var(--leading-snug);
}

.review-card cite {
  font-style: normal;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-small);
  color: var(--color-text-muted);
}

.review-card__badge {
  font-size: var(--text-label);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent-strong);
}

/* ---- Social ---- one centered CTA card instead of a photo grid. */
.social-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  max-width: 32rem;
  margin-inline: auto;
  padding: var(--space-8) var(--space-6);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.social-cta__icon {
  width: 2.5rem;
  height: 2.5rem;
  color: var(--color-accent-strong);
}

.social-cta p {
  color: var(--color-text-muted);
}

.social-cta .btn {
  margin-top: var(--space-2);
}

/* ==========================================================================
   Breakpoints
   ========================================================================== */

/* Row layout (image-left/text-right) only resumes once there's genuinely
   enough width for it — image (11-13rem) + gap + wrapped text all need
   room, which a phone-width viewport doesn't have (see the mobile-first
   base rules above for why forcing row at every breakpoint overflowed). */
@media (min-width: 640px) {
  .hero-carousel {
    min-height: 32rem;
  }

  .hero-carousel__row {
    flex-direction: row;
    align-items: center;
    gap: var(--space-6);
  }

  .hero-carousel__media {
    width: 13rem;
  }

  .hero-carousel__content {
    text-align: left;
  }

  .hero-carousel__desc {
    margin-inline: 0;
  }

  /* Restore the original larger category cards - the compact scrolling
     row above is mobile-only. */
  .categories__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    overflow-x: visible;
  }

  .category-card {
    justify-content: flex-start;
    gap: var(--space-2);
    flex: none;
    padding: var(--space-7) var(--space-6);
    min-height: 20rem;
  }

  .category-card__icon {
    display: block;
  }

  .category-card__title {
    font-size: var(--text-h3);
  }

  .category-card__sub {
    display: block;
  }

  .category-card__cta {
    padding-top: var(--space-5);
    font-size: var(--text-label);
  }

  /* Restore the original 16rem rail cards - the compact 8rem
     horizontal-scroll rows above are mobile-only. */
  .product-card {
    flex: 0 0 16rem;
  }

  .editorial__product {
    flex: 0 0 16rem;
  }
}

@media (min-width: 768px) {
  .hero-carousel {
    min-height: 32rem;
  }

  .categories__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .discover__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .trust__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .gift-builder__steps {
    grid-template-columns: repeat(4, 1fr);
    max-width: none;
  }
}

@media (min-width: 1024px) {
  .hero-carousel {
    min-height: 38rem;
  }

  /* Wider cap + space-between spread the image toward the left edge and
     the text toward the right, with a deliberate open gap between them,
     instead of the compact clustered layout mobile/tablet use — matches
     the desktop composition the user sketched out. */
  .hero-carousel__slide {
    padding: var(--space-9) 0;
  }

  .hero-carousel__inner {
    max-width: 64rem;
  }

  .hero-carousel__row {
    justify-content: space-between;
  }

  .hero-carousel__media {
    width: 16rem;
  }

  .hero-carousel__arrow--prev {
    left: var(--container-pad);
  }

  .hero-carousel__arrow--next {
    right: var(--container-pad);
  }
}

@media (min-width: 1024px) {
  .categories__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .reviews__grid {
    overflow: visible;
  }

  .reviews__track {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-5);
    width: auto;
    animation: none;
    transform: none;
  }

  .review-card {
    flex: none;
    max-width: none;
  }

  .review-card[aria-hidden="true"] {
    display: none;
  }

  .trust__grid {
    grid-template-columns: repeat(6, 1fr);
  }
}
