/* ============================================================
   KOGNEV — client reviews section.
   Rendered by scripts/build-reviews.mjs from reviews.json.
   Every review is an equal peer card; no featured review.
   Self-contained; sits fine on any light page (old or new system).

   The rating aggregate and prev/next/pause controls have been
   removed sitewide in favour of a continuous marquee: the track
   holds two identical .kg-rev__set copies (the second, decorative,
   marked aria-hidden) inside a .kg-rev__marquee row, which
   translates by exactly -50% on an endless loop. Removing the nav
   markup also stops reviews.js from initialising (it bails out if
   it can't find `.kg-rev__nav`), so this CSS animation is now the
   only thing driving the widget everywhere it appears.

   Pages on the new palette (body.kg2 + home.css) recolour the
   cards, stars and title on top of this file — see home.css
   section 17 — but the marquee mechanism itself is defined once,
   here, so every page shares the same moving strip.
   ============================================================ */
.kg-rev {
  background: #F3F4EF;
  border-top: 1px solid #E4E5E0;
  border-bottom: 1px solid #E4E5E0;
  padding: clamp(3.25rem, 2.6rem + 3vw, 5rem) 0;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
.kg-rev__inner { max-width: 1140px; margin: 0 auto; padding: 0 clamp(1rem, 3vw, 3rem); }

.kg-rev__head {
  margin-bottom: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem);
}
.kg-rev__title {
  font-family: 'DM Serif Display', Georgia, serif;
  font-weight: 400;
  font-size: clamp(1.75rem, 1.3rem + 1.9vw, 2.5rem);
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: #10201B;
}

/* ---- continuous marquee ----
   .kg-rev__track is the fixed-width mask; .kg-rev__marquee is an
   unbounded flex row holding two identical .kg-rev__set copies
   back to back. Translating it by exactly -50% of its own width
   is seamless: at that point the (invisible) second set sits
   pixel-for-pixel where the first one started, so the loop has no
   jump. The 1rem gap lives on .kg-rev__set's own trailing margin
   rather than between the two sets, which keeps that -50% exact
   instead of off by half a gap. */
.kg-rev__track {
  overflow: hidden;
  width: 100%;
  /* Cards clipping flush at the container edge read as an abrupt
     cut rather than a continuous strip. A soft fade at both edges
     signals "this keeps going" instead of "this got cut off". */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 3rem, #000 calc(100% - 3rem), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 3rem, #000 calc(100% - 3rem), transparent 100%);
}
.kg-rev__marquee {
  display: flex;
  width: max-content;
}
.kg-rev__set {
  display: flex;
  flex: none;
  gap: 1rem;
  margin-right: 1rem;
}
@media (prefers-reduced-motion: no-preference) {
  .kg-rev__marquee {
    animation: kg-rev-marquee 48s linear infinite;
  }
  /* Reading one card shouldn't require racing it across the
     screen — hovering or focusing anything inside the strip
     holds it still. */
  .kg-rev__track:hover .kg-rev__marquee,
  .kg-rev__track:focus-within .kg-rev__marquee {
    animation-play-state: paused;
  }
}
@keyframes kg-rev-marquee {
  to { transform: translateX(-50%); }
}
/* Reduce Motion: a continuously scrolling strip is exactly the
   automatic, repetitive motion the setting exists to stop. Show a
   static row of the real cards only — the duplicate, aria-hidden
   set is removed from layout so it can't leave dead space. */
@media (prefers-reduced-motion: reduce) {
  .kg-rev__track { overflow-x: auto; }
  .kg-rev__set[aria-hidden="true"] { display: none; }
}

.kg-rev__card {
  flex: 0 0 clamp(260px, 78vw, 320px);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: clamp(1.4rem, 1.2rem + 0.8vw, 1.75rem);
  background: #FFFFFF;
  border: 1px solid #E4E5E0;
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(6, 35, 28, 0.04);
  min-height: 19.25rem;
}

.kg-rev__body {
  flex: 1;
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.kg-rev__body p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  letter-spacing: -0.005em;
  color: #10201B;
  text-wrap: pretty;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 10;
  overflow: hidden;
}
.kg-rev__logo {
  height: calc(40px * var(--logo-scale, 1));
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: left center;
  align-self: flex-start;
  filter: grayscale(1) brightness(var(--logo-bright, 1));
  opacity: 0.92;
  mix-blend-mode: multiply;
}

.kg-rev__cite {
  border-top: 1px solid #E4E5E0;
  padding-top: 0.95rem;
}
.kg-rev__name { font-size: 0.9375rem; font-weight: 600; color: #10201B; }
.kg-rev__meta { display: block; margin-top: 0.15rem; font-size: 0.8125rem; line-height: 1.45; color: #55605B; }
.kg-rev__note { display: block; margin-top: 0.4rem; font-size: 0.75rem; font-style: italic; color: #8A938C; }

/* ---- stars ---- */
.kg-rev__stars { display: inline-flex; gap: 2px; line-height: 1; color: #0C5C4A; }
.kg-rev__stars svg { width: 14px; height: 14px; display: block; }

/* ---- phones: swipe instead of marquee ----
   The edge fade is 3rem a side. On a 1140px desktop that is a soft hint; on a 390px
   phone it covers about a quarter of the strip, and with the track still sliding the
   quote was being read mid-word ("had already audited my own site"). A testimonial that
   cannot be read is worse than no testimonial, so on a phone the strip becomes a
   swipeable, snapping carousel: one card at rest, fully legible, moved by the reader.
   This is the same mechanism the reduced-motion rule above already uses. */
@media (max-width: 700px) {
  .kg-rev__track {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 1.25rem), transparent 100%);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 1.25rem), transparent 100%);
  }
  .kg-rev__track::-webkit-scrollbar { display: none; }
  .kg-rev__marquee { animation: none; width: auto; }
  /* The duplicate set exists only to make the marquee loop seamlessly. */
  .kg-rev__set[aria-hidden="true"] { display: none; }
  .kg-rev__card { scroll-snap-align: center; }

  /* The quote and the name it is attributed to were both 15px, so
     the attribution carried as much weight as the testimonial. The
     quote is the content; give it the size and let the name sit
     under it. */
  .kg-rev__body p { font-size: 1rem; line-height: 1.6; }
  .kg-rev__note { font-size: 0.8125rem; }

  /* Matches the tightened section rhythm and 18px gutter in
     home.css, so the strip starts on the same margin as the copy
     in the sections above and below it. */
  .kg-rev { padding: 2.75rem 0; }
  .kg-rev__inner { padding-left: 18px; padding-right: 18px; }
}
