/* ==========================================================================
   HOMEPAGE
   Sections in page order:
   1. Hero              5. Why choose us
   2. Proof strips      6. Working process
   3. Intro story       7. Clients
   4. Services          8. Reviews
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. HERO
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  display: flex;
  min-height: 100svh;
  padding: var(--header-offset) var(--grid-margin) 0;   /* no bottom padding: Lobo touches the edge */
  overflow: hidden;
  background-color: var(--blue-500);
  color: var(--white);
  isolation: isolate;
}

.hero__video,
.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
}

.hero__video {
  object-fit: cover;
}

.hero__overlay {
  /* Brand tint over the video in multiply mode: darkens the shadows and keeps
     the neon lights, so the background gains contrast instead of looking
     flat (Mike, 28-sep-2026). Darker or lighter: move the three colors along
     their scale (e.g. --blue-300 → --blue-500) or lower the opacity. */
  background: linear-gradient(160deg, var(--blue-300) 0%, var(--blue-500) 50%, var(--purple-300) 100%);
  mix-blend-mode: multiply;
}

/* Desktop layout on the 12-column grid:
   title (full width) / video + stats (cols 1–5) / Lobo (cols 5–9, from
   under the title to the bottom edge) / trust (bottom left) + CTA (bottom right) */
.hero__inner {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  grid-template-rows: auto auto auto 1fr auto;
  column-gap: var(--grid-gap);
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
}

.hero__title {
  grid-column: 1 / -1;
  grid-row: 1;
  position: relative;
  z-index: 1;
  font-size: clamp(3rem, 5.4vw, 6.5rem);
}

.hero__demo {
  grid-column: 1 / 6;
  grid-row: 2;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 16px;
  margin-top: var(--space-l);
  color: var(--white);
  font-size: var(--text-20);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.hero__demo-icon {
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  border: 1.5px solid currentColor;
  border-radius: var(--radius-pill);
}

.hero__demo-icon .icon {
  width: 26px;
  height: 26px;
  margin-left: 3px;
}

.hero__demo:hover {
  color: var(--gold-500);
}

.hero__stats {
  grid-column: 1 / 6;
  grid-row: 3;
  position: relative;
  z-index: 1;   /* stays above Lobo on narrow desktops (~1024px) */
  margin-top: var(--space-xl);
}

.hero__trust {
  grid-column: 1 / 5;
  grid-row: 5;
  align-self: end;
  margin-bottom: var(--space-xl);
}

.hero__cta {
  grid-column: 9 / -1;
  grid-row: 5;
  justify-self: end;
  align-self: end;
  margin-bottom: var(--space-xl);
}

/* Lobo fills the space under the title and sits on the bottom edge.
   contain: size keeps the image from stretching the hero; it scales to fit. */
.hero__lobo {
  grid-column: 5 / 10;
  grid-row: 2 / -1;
  position: relative;
  min-height: 360px;
  margin-top: var(--space-s);
  contain: size;
  pointer-events: none;
}

.hero__lobo img,
.hero__lobo canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
}

/* Pixel reveal (main.js › 29): the still picture waits hidden while the script
   draws the reveal on a canvas. If the script never runs, this animation shows
   the picture after 4 s anyway. Not applied with "reduce motion". */
@media (prefers-reduced-motion: no-preference) {
  .hero__lobo img {
    opacity: 0;
    animation: hero-lobo-failsafe 0.01s linear 4s forwards;
  }

  .hero__lobo.is-revealed img {
    opacity: 1;
    animation: none;
  }
}

@keyframes hero-lobo-failsafe {
  to { opacity: 1; }
}

/* Mouse-driven light (main.js › 16): once the canvas is drawing, it covers
   the still image, which stays in place for screen readers. */
.hero__lobo.is-lit img {
  opacity: 0;
}

/* Compact version of the About stats */
/* One tight group: same space on both sides of each thin divider */
.hero-stats {
  --stat-space: clamp(16px, 1.6vw, 28px);
  --stat-divider: var(--blue-300);
  display: flex;
}

.hero-stat {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-inline: var(--stat-space);
}

.hero-stat:first-child {
  padding-left: 0;
}

.hero-stat + .hero-stat {
  border-left: 1px solid var(--stat-divider);
}

.hero-stat__value {
  font-family: var(--font-display);
  font-size: clamp(2rem, 2.9vw, 3.25rem);
  font-weight: var(--weight-regular);
  line-height: var(--leading-none);
  white-space: nowrap;
}

.hero-stat__suffix {
  color: var(--gold-500);
  font-size: 0.6em;
}

.hero-stat__label {
  color: var(--blue-100);
  font-size: var(--text-12);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wider);
  line-height: var(--leading-cozy);
  text-transform: uppercase;
}

/* Phone + tablet: one centered column; Lobo at the bottom with the stats
   as a dark band over his lower part. No trust badge. */
@media (max-width: 991px) {
  .hero {
    min-height: 0;
  }

  .hero__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .hero__title {
    font-size: clamp(2rem, 8.6vw, 5rem);
  }

  .hero__demo {
    justify-self: auto;
    margin-top: var(--space-m);
  }

  .hero__cta {
    align-self: center;
    margin: var(--space-l) 0 0;
  }

  .hero__trust {
    display: none;
  }

  .hero__lobo {
    width: min(82%, 460px);
    min-height: 0;
    aspect-ratio: 1086 / 1448;
    margin-top: -0.5rem;   /* Lobo's ears almost touch "(We don't bite)" (Mike, 8-oct-2026) */
    contain: none;
  }

  .hero .hero__stats {   /* .hero prefix beats base.css ul[role="list"] { padding: 0 } */
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin: 0;
    padding: 22px var(--grid-margin) 24px;   /* breathing room above and below (Mike, 28-sep-2026) */
    background: rgb(17 22 39 / 0.78);   /* --blue-900 */
  }

  .hero-stat,
  .hero-stat:first-child {
    align-items: center;
    gap: 8px;
    padding-inline: 4px;
  }

  .hero-stat__value {
    font-size: clamp(1.5rem, 6.6vw, 2.625rem);
  }

  /* Four figures share one row here, so these labels are the one place the
     site goes under 12px: 11px on tablets, 10–11px on phones (was 9–10). */
  .hero-stat__label {
    font-size: 0.6875rem;
    letter-spacing: var(--tracking-wide);
  }
}

@media (max-width: 767px) {
  .hero__demo {
    gap: 14px;
    font-size: var(--text-18);
  }

  .hero__demo-icon {
    width: 54px;
    height: 54px;
  }

  .hero__demo-icon .icon {
    width: 22px;
    height: 22px;
  }
}

@media (max-width: 478px) {

  .hero__video {
    object-position: 80% 50%;
  }

  .hero-stat__label {
    font-size: clamp(0.5625rem, 2.7vw, 0.6875rem);
    letter-spacing: var(--tracking-ui);
  }
}

/* --------------------------------------------------------------------------
   2. TICKER (one black band under the hero, text loops right to left)
   Approved exception to the "no animations" rule (Mike, 28-sep-2026),
   (the work carousel that sat under "Why Run With Us" was removed 3-oct-2026).
   Speed: change --ticker-duration (longer = slower).
   -------------------------------------------------------------------------- */
.ticker {
  --ticker-duration: 60s;
  overflow: hidden;
  padding-block: 15px;
  background: var(--black);
  color: var(--white);
  font-size: var(--text-14);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-widest);
  line-height: var(--leading-normal);
  text-transform: uppercase;
  white-space: nowrap;
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker-scroll var(--ticker-duration) linear infinite;
}

.ticker__group {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Dot separator after every item, including the last, so the loop is seamless */
.ticker__group li::after {
  content: "·";
  margin-inline: 1.1em;
}

@keyframes ticker-scroll {
  to { transform: translateX(-50%); }
}

/* Reduced motion: no movement; the band scrolls sideways by hand instead */
@media (prefers-reduced-motion: reduce) {
  .ticker {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .ticker__track {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   3. INTRO STORY
   -------------------------------------------------------------------------- */
.intro {
  --texture-opacity: 0.3;   /* black texture at 30% over solid black (Mike, 28-sep-2026) */
  color: var(--white);
}

/* Desde tablet: al menos el 80% de la altura de la pantalla, contenido centrado vertical */
@media (min-width: 768px) {
  .intro {
    display: flex;
    align-items: center;
    min-height: 80vh;
    min-height: 80svh;
  }
}

/* Video on the left (5 columns, 4:3), statement on the right (6 columns), with
   one empty column between them. Model: "Our philosophy" on neiden.framer.media
   (Mike, 4-oct-2026). */
.intro__layout {
  align-items: center;
  row-gap: clamp(32px, 6vw, 48px);
}

.intro__statement {
  grid-column: 7 / 13;
  grid-row: 1;
  font-size: clamp(26px, 2.9vw, 46px);
  font-weight: var(--weight-medium);
  line-height: var(--leading-compact);
  letter-spacing: var(--tracking-tight);
}

/* Scroll reveal (approved by Mike, 4-oct-2026): main.js › 17 wraps each word
   in .intro__word and raises its opacity as the section scrolls by. Without
   JavaScript or with "reduce motion" the text stays fully white. */

.intro__media {
  grid-column: 1 / 6;
  grid-row: 1;
}

/* Parallax: main.js › 17 moves the video a little faster than the page */
.intro__video {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-card);
  will-change: transform;
}

/* Phones: statement first, video underneath at full width */
@media (max-width: 767px) {
  .intro__statement,
  .intro__media {
    grid-column: 1 / -1;
    grid-row: auto;
  }

  .intro__statement {
    font-size: clamp(25px, 6.6vw, 36px);
  }
}

/* --------------------------------------------------------------------------
   4. SERVICES
   Each service block uses a modifier for its background + accent bar:
   .service--branding / --digital / --design / --web
   -------------------------------------------------------------------------- */
/* Opener (Mike, 7-oct-2026; model: "Dot Enlarge" + "what we do" on
   arpeggio.framer.website). A full-screen dark panel, same black as the intro
   above, that pins to the top of the screen. A light circle grows from its
   center as you scroll until it covers the whole screen, and the heading
   inside grows with it; the heading only shows inside the circle. Once it is
   all light, the Branding panel slides over it like the rest of the stack.
   .services-opener__hold (an empty div right after) is how long it stays
   pinned: its height is the scroll distance the circle takes to finish.
   main.js › 25 adds .is-live and sets --opener-r (radius of the circle, px)
   and --opener-scale (size of the heading, 0.2 → 1) from the scroll. Without
   JavaScript or with "reduce motion" it is a plain light band with the
   heading, not pinned. */
.services-opener {
  --texture-opacity: 0.3;
  position: relative;
  min-height: max(70vh, 420px);
  overflow: clip;
  background-color: var(--black);
}

.services-opener__hold {
  display: none;
}

.services-opener.is-live {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
}

.services-opener.is-live + .services-opener__hold {
  display: block;
  height: 70vh;
}

.services-opener__fill {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  padding: var(--space-l) var(--container-gutter);
  background: var(--gray-100);
  text-align: center;
}

.services-opener.is-live .services-opener__fill {
  clip-path: circle(var(--opener-r, 0px) at 50% 50%);
}

.services-opener.is-live .services-opener__head {
  scale: var(--opener-scale, 0.2);
  will-change: scale;
}

.services-opener .eyebrow {
  margin-bottom: 14px;
}

.services-opener__title {
  color: var(--blue-900);
  font-size: clamp(2.75rem, 12vw, 11rem);
  line-height: 0.95;
  white-space: nowrap;
}

.services-opener__accent {
  color: var(--blue-500);
}

.service {
  --service-accent: var(--blue-500);
  --service-bg: var(--white);
  position: relative;
  padding-block: var(--space-xl);
  background: var(--service-bg);
  box-shadow: inset 12px 0 0 var(--service-accent);   /* accent bar, doesn't shift the grid */
  scroll-margin-top: 80px;
}

.service--branding { --service-accent: var(--service-branding); --service-bg: var(--gray-100); }
.service--digital  { --service-accent: var(--service-digital);  --service-bg: var(--white); }
.service--design   { --service-accent: var(--service-design);   --service-bg: var(--gray-100); }
.service--web      { --service-accent: var(--service-web);      --service-bg: var(--white); }

.service__title {
  margin-bottom: 35px;
  color: var(--blue-900);
  font-size: var(--text-7xl);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-caps);
}

.service__grid {
  row-gap: 36px;
  align-items: start;
  min-height: 440px;
}

.service__copy { grid-column: 1 / 9; }
.service__art  { grid-column: 9 / -1; }

.service__copy {
  max-width: 850px;
  font-size: var(--text-l);
  line-height: var(--leading-normal);
}

.service__copy > p {
  margin-bottom: 25px;
}

.service__expertise {
  display: inline-block;
  padding: 19px;
  border-left: 1px solid var(--blue-500);
  background: var(--cyan-100);
  font-size: clamp(16px, 1.39vw, 20px);
  font-style: italic;
  letter-spacing: var(--tracking-ui);
  line-height: var(--leading-relaxed);
  text-transform: uppercase;
}

.service__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px;
  padding-top: 9px;
}

/* The frame (.reveal, see components.css › IMAGE REVEAL) carries the size; the photo fills it */
.service__art {
  --reveal-overscan: 1.1;   /* the characters are cut-outs: less drift, less cropping than the photos (1.2) */
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-media);
}

/* Stack (Mike, 7-oct-2026; model: "Project Highlights" on arpeggio.framer.website)
   Each service is a full-screen panel that sticks to the top of the screen
   while the next one slides up and covers it. Its picture starts enlarged
   (1.4×) and shrinks to its real size as the panel travels up to the top, tied
   to the scroll, so it reverses when you scroll back.
   main.js › 24 adds .services--stack to #services (without JavaScript the
   sections simply follow one another) and sets on each panel:
   --stack-top  0, or a negative number when the panel is taller than the
                screen (phones), so it scrolls to its end before it sticks;
   --stack-zoom the size of the picture right now (1.4 → 1). */
.services--stack .service {
  position: sticky;
  top: var(--stack-top, 0px);
}

@media (min-width: 992px) {
  .services--stack .service {
    display: flex;
    align-items: center;
    min-height: 100vh;
    min-height: 100svh;
  }
}

/* Depth (Mike, 7-oct-2026): the panel that is being covered moves away. As
   the next panel slides up over it, it shrinks a little and darkens, so it
   reads as sinking behind. main.js › 24 sets --stack-cover (0 = not covered,
   1 = fully covered) and .is-covered while it is above 0. The black behind
   the panels is what shows around the one that shrinks.
   Tweaks: 0.1 = how much it shrinks (10%), 0.6 = how dark it gets. */
.services--stack {
  background: var(--black);
}

@media (prefers-reduced-motion: no-preference) {
  .services--stack .is-covered {
    transform-origin: 50% calc(50vh - var(--stack-top, 0px));   /* the middle of what is on screen */
    scale: calc(1 - 0.1 * var(--stack-cover, 0));
    filter: brightness(calc(1 - 0.6 * var(--stack-cover, 0)));
    will-change: scale, filter;
  }

  /* Entrance of the text (once per panel): each block of the copy fades in
     and rises a little, one after another. The title uses SLOT TEXT.
     main.js › 24 adds .services--motion and .is-in on each panel. */
  .services--motion .service__copy > * {
    opacity: 0;
    translate: 0 26px;
  }

  .services--motion .service.is-in .service__copy > * {
    opacity: 1;
    translate: 0 0;
    transition:
      opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1) var(--copy-delay, 0ms),
      translate 0.8s cubic-bezier(0.22, 1, 0.36, 1) var(--copy-delay, 0ms);
  }

  .services--motion .service__copy > :nth-child(2) { --copy-delay: 90ms; }
  .services--motion .service__copy > :nth-child(3) { --copy-delay: 180ms; }
  .services--motion .service__copy > :nth-child(4) { --copy-delay: 270ms; }
}

/* The picture opens from the top down when it first scrolls into view (IMAGE REVEAL,
   components.css; restored 7-oct-2026). Its zoom is not the timed one of that effect:
   it follows the scroll (--stack-zoom, main.js › 24). The soft drift inside the frame stays. */
@media (prefers-reduced-motion: no-preference) {
  .services--stack .service__art.reveal.is-armed > img {
    scale: var(--stack-zoom, 1.4);
    transition: none;
  }
}

@media (max-width: 991px) {
  .service__copy { grid-column: 1 / 8; }
  .service__art  { grid-column: 8 / -1; }
}

@media (max-width: 767px) {
  .service__grid {
    row-gap: 28px;
    min-height: 0;
  }

  .service__copy,
  .service__art { grid-column: 1 / -1; }

  .service__copy {
    order: 2;
    font-size: var(--text-20);
  }

  .service__art {
    aspect-ratio: 1.7 / 1;
    --reveal-position: 50% 40%;
  }

  .service__expertise {
    padding: 16px;
    font-size: var(--text-16);
  }

  .service__actions {
    gap: 20px;
  }
}

@media (max-width: 478px) {
  .service__copy > p {
    margin-bottom: 22px;
  }

  .service__actions {
    gap: 14px;
  }
}

/* --------------------------------------------------------------------------
   6. WORKING PROCESS ("Follow the Trail")
   Moved to components.css › PROCESS STACK (5-oct-2026): the industry pages
   use the same section.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   7. CLIENTS (logo wall)
   Border style from "Logo Cloud 2" by Efferd (21st.dev; Mike, 7-oct-2026):
   lines only between the logos, a line on each side, top and bottom lines that
   run the full width of the screen, and a small + where the inner lines cross.
   The logos stay grey and fade to color on hover (0.35 s; no fade with
   "reduce motion").
   The wall is always a full rectangle: 94 logos + 2 empty cells = 96, which
   divides into 6, 4 and 3 columns. If logos are added or removed, keep the
   total a multiple of 12 by adding or removing empty cells
   (<li class="logo-grid__cell logo-grid__cell--empty" aria-hidden="true">).
   -------------------------------------------------------------------------- */
.clients {
  overflow-x: clip;   /* the full-width top and bottom lines must not add a scrollbar */
  background: var(--gray-100);
}

.clients__title {
  margin-bottom: 42px;
  font-family: var(--font-body);
  font-size: var(--text-3xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  text-align: center;
}

.logo-grid {
  --logo-line: var(--gray-300);
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  border-inline: 1px solid var(--logo-line);
  list-style: none;
}

/* Top and bottom lines: as wide as the screen, not just the grid */
.logo-grid::before,
.logo-grid::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 100vw;
  border-top: 1px solid var(--logo-line);
  transform: translateX(-50%);
  pointer-events: none;
}

.logo-grid::before { top: -1px; }
.logo-grid::after { bottom: -1px; }

.logo-grid__cell {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 6 / 5;
  min-width: 0;
  padding: 13px;
  background: var(--gray-100);
}

/* The + that sits on each crossing of the inner lines (set per column count below) */
.logo-grid__cell::after {
  content: "";
  display: none;
  position: absolute;
  right: -7.5px;
  bottom: -7.5px;
  z-index: 1;
  width: 14px;
  height: 14px;
  background:
    linear-gradient(var(--ink), var(--ink)) center / 100% 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center / 1px 100% no-repeat;
  pointer-events: none;
}

.logo-grid__cell img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: grayscale(1);
  opacity: 0.85;
  transition: filter 0.35s ease, opacity 0.35s ease;
}

.logo-grid__cell:hover img {
  filter: grayscale(0);
  opacity: 1;
}

/* Inner lines per column count: no line after the last column or the last row,
   a + where both a column line and a row line continue */
@media (min-width: 992px) {
  .logo-grid__cell:not(:nth-child(6n)) { border-right: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-last-child(-n + 6)) { border-bottom: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-child(6n)):not(:nth-last-child(-n + 6))::after { display: block; }
}

@media (min-width: 768px) and (max-width: 991px) {
  .logo-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .logo-grid__cell:not(:nth-child(4n)) { border-right: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-last-child(-n + 4)) { border-bottom: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-child(4n)):not(:nth-last-child(-n + 4))::after { display: block; }
}

@media (max-width: 767px) {
  .logo-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .logo-grid__cell:not(:nth-child(3n)) { border-right: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-last-child(-n + 3)) { border-bottom: 1px solid var(--logo-line); }
  .logo-grid__cell:not(:nth-child(3n)):not(:nth-last-child(-n + 3))::after { display: block; }
}

@media (max-width: 478px) {
  .clients__title {
    font-size: var(--text-2xl);
    font-weight: var(--weight-medium);
  }

  .logo-grid__cell {
    padding: 8px;
  }
}

/* Entrance (Mike, 7-oct-2026): the lines are there from the start; each logo
   comes into focus as its row scrolls into view — it fades in, rises a little
   and sharpens, one after another from left to right. main.js › 23 adds
   .logo-grid--animate (so the logos are simply visible without JavaScript or
   with "reduce motion") and .is-in on each cell, with its --logo-delay. */
.logo-grid--animate .logo-grid__cell:not(.is-in) img {
  opacity: 0;
}

.logo-grid--animate .logo-grid__cell.is-in img {
  animation: logo-in 0.9s cubic-bezier(0.22, 1, 0.36, 1) var(--logo-delay, 0ms) backwards;
}

@keyframes logo-in {
  from {
    opacity: 0;
    filter: grayscale(1) blur(8px);
    transform: translateY(18px) scale(0.94);
  }
}

@media (prefers-reduced-motion: reduce) {
  .logo-grid__cell img {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   8. REVIEWS (dark section, cards in a loop)
   Same black texture as the intro under the hero. The cards move right to
   left without stopping and pause while the mouse is over them. Approved
   exception to the "no animations" rule (Mike, 4-oct-2026).
   Speed: change --reviews-duration (longer = slower).
   Drag (Mike, 7-oct-2026): the row can be dragged sideways with the finger
   or the mouse; on release it keeps looping from where it was left. main.js
   › 27 takes over the movement (class .is-draggable); without JavaScript the
   CSS loop below keeps running.
   -------------------------------------------------------------------------- */
.reviews {
  --texture-opacity: 0.3;   /* same as .intro */
  --reviews-duration: 70s;
  padding-top: var(--space-xl);
  padding-bottom: var(--space-section);
  color: var(--white);
  text-align: center;
  overflow: hidden;
}

.reviews__howl {
  width: 165px;
  height: 180px;
  margin: 0 auto 22px;
  object-fit: contain;
}

.reviews__title {
  margin-bottom: 20px;
  font-size: var(--text-4xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-compact);
}

.reviews__subtitle {
  margin-bottom: 42px;
  font-size: var(--text-xl);
}

.reviews-marquee__track {
  display: flex;
  width: max-content;
  animation: reviews-scroll var(--reviews-duration) linear infinite;
}

.reviews-marquee:hover .reviews-marquee__track {
  animation-play-state: paused;
}

.reviews .reviews-marquee__group {   /* .reviews prefix beats base.css ul[role="list"] { padding: 0 } */
  display: flex;
  gap: var(--grid-gap);
  margin: 0;
  padding: 0 var(--grid-gap) 0 0;   /* same as the gap, so the loop has no seam */
  list-style: none;
  text-align: left;
}

@keyframes reviews-scroll {
  to { transform: translateX(-50%); }
}

/* Dragging by hand: main.js moves the track, so the CSS loop is switched off */
.reviews-marquee.is-draggable {
  cursor: grab;
  touch-action: pan-y;   /* up/down still scrolls the page; sideways drags the row */
  -webkit-user-select: none;
  user-select: none;
}

.reviews-marquee.is-draggable .reviews-marquee__track {
  animation: none;
  will-change: transform;
}

.reviews-marquee.is-dragging {
  cursor: grabbing;
}

/* Reduced motion: no movement; the row scrolls sideways by hand and the copy is hidden */
@media (prefers-reduced-motion: reduce) {
  .reviews-marquee {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .reviews-marquee__track {
    padding-left: var(--container-gutter);
    animation: none;
  }

  .reviews-marquee__group[aria-hidden="true"] {
    display: none;
  }
}

/* Review card + its three colors */
.review-card {
  --card-bg: var(--gold-500);
  --card-fg: var(--blue-900);
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: flex-start;
  width: clamp(340px, 30vw, 460px);
  min-height: 340px;
  padding: 40px 40px 36px;
  border-radius: var(--radius-review);
  background: var(--card-bg);
  color: var(--card-fg);
}

.review-card--gold   { --card-bg: var(--gold-500);   --card-fg: var(--blue-900); }
.review-card--purple { --card-bg: var(--purple-500); --card-fg: var(--white); }
.review-card--green  { --card-bg: var(--green-500);  --card-fg: var(--blue-900); }

.review-card__mark {
  width: 34px;
  height: 29px;
  margin-bottom: 24px;
  fill: currentColor;
  stroke: none;
}

.review-card__quote {
  margin-bottom: 24px;
  font-size: var(--text-24);
  font-weight: var(--weight-bold);
  line-height: var(--leading-cozy);
}

.review-card__person {
  margin-top: auto;
  font-size: var(--text-18);
  font-style: normal;
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

@media (max-width: 767px) {
  .review-card {
    width: min(80vw, 340px);
    min-height: 380px;
    padding: 28px;
  }

  .review-card__quote {
    font-size: var(--text-20);
    line-height: var(--leading-normal);
  }

  .review-card__person {
    font-size: var(--text-18);
  }
}

@media (max-width: 478px) {
  .reviews__howl {
    width: 145px;
    height: 158px;
  }
}

/* Lobo voice label above "What Clients Say" */
.reviews__eyebrow {
  margin-bottom: 12px;
}
