/**
 * ek-reviews.css — styles for the "Trusted by 100+ customers" homepage carousel.
 *
 * 2026-09-17 owner correction: rebuilt as a native horizontal carousel (structure borrowed from
 * the owner's Uptown reference — big statement headline, one prominent centered ivory card,
 * partially-visible neighbors, edge-fade/depth — NOT its teal accent, avatar photos, or invented
 * job titles). Brand stays EK: Fraunces headline, existing brass/charcoal palette, the site's
 * actual card material (`border-radius: 18px`, the same `--cohesion-shadow` treatment used
 * elsewhere), same focus-outline and reduced-motion conventions as the rest of the site.
 *
 * The carousel itself is native CSS scroll-snap (`overflow-x:auto; scroll-snap-type:x
 * mandatory`) — no JS animation library, no layout-shifting clones. The section background is a
 * neutral warm ambient gradient built from the existing charcoal/brass variables, not a photo —
 * the only candidate photo on this site (`house.webp`) is labelled an architectural
 * visualisation, not a real customer photo, and is deliberately not repurposed here.
 */

.reviews {
  --reviews-bg: var(--bg, #1c1d1a);
  --reviews-chalk: var(--chalk, #ece8db);
  --reviews-muted: var(--muted, #b9b4a4);
  --reviews-brass: var(--brass, #ccb480);
  --reviews-line: var(--line, #ece8db30);
  --reviews-panel: var(--panel, #282a25);
  --reviews-ease: var(--ease, cubic-bezier(.19, 1, .22, 1));
  --reviews-gutter: var(--gutter, clamp(22px, 4.5vw, 78px));
  --reviews-shadow: var(--cohesion-shadow, 0 16px 42px rgba(0, 0, 0, .18));
  /* Warm ivory card material — dark, legible text on a light surface (the carousel's one
     deliberate light panel against the site's otherwise dark section). */
  --reviews-ivory: #f6f1e2;
  --reviews-ivory-text: #2a2620;
  --reviews-ivory-muted: #6b6355;

  position: relative;
  overflow: hidden;
  color: var(--reviews-chalk);
  /* Neutral warm ambient backdrop — no photo, no provenance claim. Two soft radial glows (brass,
     very low alpha) over the site's own dark panel tone, matching the "layered depth against EK
     charcoal/gold" brief without pretending to be a real background photograph. */
  background:
    radial-gradient(120% 90% at 15% -10%, rgba(204, 180, 128, .10), transparent 55%),
    radial-gradient(120% 90% at 85% 110%, rgba(204, 180, 128, .07), transparent 55%),
    var(--reviews-bg);
}

.reviews-intro {
  text-align: center;
  max-width: 720px;
  margin: 0 auto clamp(36px, 5vw, 64px);
}

.reviews-eyebrow {
  margin: 0 0 12px;
  font: 600 12px/1.4 Arial, Helvetica, sans-serif;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--reviews-brass);
}

.reviews h2 {
  font-family: Fraunces, Georgia, serif;
  font-size: clamp(34px, 4.6vw, 58px);
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0;
  color: var(--reviews-chalk);
}

.reviews-synthetic-banner {
  margin: 0 auto 24px;
  padding: 10px 16px;
  border: 1px dashed var(--reviews-brass);
  color: var(--reviews-brass);
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  max-width: 620px;
  text-align: center;
}

/* ---- Carousel shell ------------------------------------------------------------------- */

.reviews-carousel {
  position: relative;
}

.reviews-track {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Edge fade/depth: the track's own content fades toward the section background at both
     horizontal edges, revealing partial neighboring cards without any hard clip line. Sized to
     a fixed 64px max on wide viewports, where the peek around each side of the centered card is
     comfortably larger than that (root visually confirmed this on desktop). Deliberately
     disabled below 641px (see the mobile media query) rather than scaled down proportionally —
     at narrow widths the peek shrinks enough that any fade zone risks bleeding onto the ACTIVE
     card's own edge, which root's visual review caught as a real defect ("active card edges
     shaded by dark stripes"); the fade must never touch the active card. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 min(8%, 64px), #000 calc(100% - min(8%, 64px)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 min(8%, 64px), #000 calc(100% - min(8%, 64px)), transparent 100%);
}

.reviews-track::-webkit-scrollbar {
  display: none;
}

.reviews-track:focus-visible {
  outline: 2px solid var(--reviews-brass);
  outline-offset: 6px;
}

.reviews-list {
  list-style: none;
  margin: 0;
  display: flex;
  gap: clamp(18px, 2.4vw, 32px);
  /* Half-empty inline padding either side lets the first/last card still center under
     scroll-snap, and is exactly what reveals the partial neighboring card at each edge —
     no clones needed. */
  padding-inline: calc((100% - min(640px, 78vw)) / 2);
  padding-block: 6px; /* room for the focus outline / active-card lift without clipping */
}

.review-card {
  flex: 0 0 min(640px, 78vw);
  scroll-snap-align: center;
  background: var(--reviews-ivory);
  color: var(--reviews-ivory-text);
  border: 1px solid rgba(42, 38, 32, .08);
  border-radius: 18px;
  box-shadow: 0 20px 46px rgba(20, 16, 8, .28);
  padding: clamp(28px, 3vw, 44px);
  min-width: 0;
  /* Dimming uses opacity/shadow only — deliberately NOT transform:scale(). A scale transform
     changes the element's rendered getBoundingClientRect, which would skew the
     IntersectionObserver-ratio math this carousel's active-slide detection depends on (verified:
     it was the actual cause of an edge-case mis-detection at the last slide during testing). */
  opacity: .55;
  transition: opacity .4s var(--reviews-ease), box-shadow .4s var(--reviews-ease);
}

.review-card--active {
  opacity: 1;
  box-shadow: 0 28px 60px rgba(20, 16, 8, .36);
}

.review-synthetic-badge {
  margin: 0 0 16px;
  padding: 3px 10px;
  display: inline-block;
  border: 1px solid #a8813f;
  border-radius: 999px;
  color: #7a5e2c;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.review-figure {
  margin: 0;
  min-width: 0;
}

.review-stars {
  display: flex;
  gap: 3px;
  margin: 0 0 16px;
  font-size: 16px;
  line-height: 1;
}

.review-star {
  color: rgba(42, 38, 32, .18);
}

.review-star--filled {
  /* Restrained gold, not the loud saturated gold a raw brand hex would give — kept close to the
     site's own --brass tone so it reads as EK gold, not a generic 5-star badge color. */
  color: #a8813f;
}

.review-quote {
  margin: 0 0 20px;
  font: 19px/1.6 Arial, Helvetica, sans-serif;
  color: var(--reviews-ivory-text);
  overflow-wrap: break-word;
  word-break: break-word;
  hyphens: auto;
}

.review-quote p {
  margin: 0 0 1em;
}

.review-quote p:last-child {
  margin-bottom: 0;
}

.review-quote::before {
  content: '\201C';
  font-family: Fraunces, Georgia, serif;
  font-size: 1.4em;
  color: #a8813f;
  line-height: 0;
  vertical-align: -0.05em;
  margin-right: 2px;
}

.review-quote--clamped:not(.review-quote--expanded) {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.review-attribution {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--reviews-ivory-muted);
}

.review-attribution cite {
  font-style: normal;
  color: var(--reviews-ivory-text);
  font-weight: 600;
}

.review-source-link,
.review-expand-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 12px;
  color: #8a6a30;
  border-bottom: 1px solid rgba(42, 38, 32, .2);
  cursor: pointer;
  min-height: 32px;
  transition: color 0.2s var(--reviews-ease), border-color 0.2s var(--reviews-ease);
}

.review-source-link:hover,
.review-expand-toggle:hover {
  color: var(--reviews-ivory-text);
  border-color: var(--reviews-ivory-text);
}

.review-expand-toggle {
  margin-top: 4px;
}

.review-card a:focus-visible,
.review-card button:focus-visible {
  outline: 2px solid #8a6a30;
  outline-offset: 3px;
}

/* ---- Controls: prev/next, current-index text, play/pause (no dot pagination) ----------- */

.reviews-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2vw, 28px);
  margin-top: clamp(24px, 3vw, 40px);
  flex-wrap: wrap;
}

.reviews-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--reviews-line);
  background: var(--reviews-panel);
  color: var(--reviews-chalk);
  cursor: pointer;
  transition: background .2s var(--reviews-ease), border-color .2s var(--reviews-ease), transform .15s var(--reviews-ease);
}

.reviews-arrow svg {
  width: 20px;
  height: 20px;
}

.reviews-arrow:hover {
  border-color: var(--reviews-brass);
  background: #32342d;
}

.reviews-arrow:active {
  transform: scale(.96);
}

.reviews-index {
  margin: 0;
  min-width: 52px;
  text-align: center;
  font: 12px/1 Arial, Helvetica, sans-serif;
  letter-spacing: 0.04em;
  color: var(--reviews-muted);
}

.reviews-playpause {
  border: 1px solid var(--reviews-line);
  background: var(--reviews-panel);
  color: var(--reviews-chalk);
  border-radius: 999px;
  padding: 0 18px;
  min-height: 44px;
  font: 12px/1 Arial, Helvetica, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s var(--reviews-ease), border-color .2s var(--reviews-ease);
}

.reviews-playpause:hover {
  border-color: var(--reviews-brass);
  background: #32342d;
}

/* Truthful disabled state under prefers-reduced-motion: reduce — see ek-reviews.js
   setPlayPauseLabel(). Dimmed and non-interactive rather than offering a "Play" that can never
   actually run. */
.reviews-playpause:disabled {
  opacity: .5;
  cursor: default;
}

.reviews-playpause:disabled:hover {
  border-color: var(--reviews-line);
  background: var(--reviews-panel);
}

.reviews-arrow:focus-visible,
.reviews-playpause:focus-visible {
  outline: 2px solid var(--reviews-brass);
  outline-offset: 3px;
}

@media (max-width: 1024px) {
  .review-card {
    flex-basis: min(560px, 82vw);
  }
}

@media (max-width: 640px) {
  .reviews h2 {
    font-size: 30px;
  }

  /* Root visual review (390px): 84vw left too little room for a visible neighbor peek once the
     site's own inherited section gutter (clamp(22px,4.5vw,78px) on each side) is subtracted from
     the actual scrollable track width — the peek came out at ~9px, which the inter-card gap then
     ate entirely, so no neighbor showed at all. 72vw against the real (gutter-narrowed) track
     width leaves a clearly visible ~20-30px peek on both sides at 320-640px, while the card
     itself stays comfortably legible. */
  .review-card {
    flex-basis: 72vw;
    padding: clamp(22px, 6vw, 30px);
  }

  .reviews-list {
    padding-inline: calc((100% - 72vw) / 2);
    gap: 14px;
  }

  .review-quote {
    font-size: 17px;
  }

  .reviews-controls {
    gap: 12px;
  }

  /* Root visual review (390px): the desktop fade zone (up to 64px) was wider than the actual
     peek at this card size, so it bled onto the ACTIVE card's own edges — a real defect ("active
     card edges shaded by dark stripes"). Disabling the mask below 641px is the fix root
     explicitly named as acceptable; the still-visible partial neighbor peek plus each card's own
     opacity dimming already carries the "layered depth" look without any fade-onto-active risk. */
  .reviews-track {
    -webkit-mask-image: none;
    mask-image: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .reviews-track {
    scroll-behavior: auto;
  }

  .review-card {
    transition: none;
  }

  .reviews-arrow,
  .reviews-playpause {
    transition: none;
  }

  .review-source-link,
  .review-expand-toggle {
    transition: none;
  }
}
