/* =============================================================
   TransRisk v3 — testimonials.css
   The circular testimonial carousel: a stack of three product
   screenshots that rotates through depth on the left, with the
   matching quote on the right.

   Two layouts live in this file and the difference is one
   attribute:

     .tr-tstm                    — no JS. Every testimonial renders
                                   as a plain card in a responsive
                                   grid. This is what a crawler and
                                   a scripting-off browser see, and
                                   it is the layout the section had
                                   before the carousel existed.

     .tr-tstm[data-tstm-ready]   — testimonials.js has moved the
                                   figures into one stack and the
                                   quote bodies into one panel, and
                                   has appended the controls.

   Nothing here assumes the carousel: the fallback has to stand on
   its own, because a static export ships the markup whether or not
   the script ever runs.
============================================================= */

/* =============================================================
   1. NO-JS BASELINE — a grid of cards
============================================================= */

.tr-tstm {
  max-width: 1120px;
  margin: 0 auto;
}

.tr-tstm-track {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 28px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.tr-tstm-item {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0;
  padding: 28px;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.tr-tstm-media {
  margin: 0;
}

.tr-tstm-media img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.tr-tstm-tag {
  margin: 0 0 10px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-green);
}

.tr-tstm-quote {
  margin: 0;
  font-size: clamp(1rem, 1.6vw, 1.125rem);
  line-height: 1.75;
  color: var(--color-text);
}

.tr-tstm-name {
  margin: 20px 0 2px;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.tr-tstm-role {
  margin: 0;
  font-size: 0.875rem;
  color: var(--color-muted);
}

/* =============================================================
   2. ENHANCED LAYOUT — stage, stack, panel
============================================================= */

/* The original list is emptied rather than deleted, so the section
   keeps a stable landmark for anything that already resolved it. */
.tr-tstm[data-tstm-ready] .tr-tstm-track {
  display: none;
}

.tr-tstm-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 56px;
  align-items: center;
}

/* ── The image stack ─────────────────────────────────────────
   Perspective belongs on the stack, not on the figures: the
   rotation of the two side cards is only convincing when all
   three share one vanishing point.

   The stack reserves the fan rather than letting it escape. A side
   card travels exactly --tstm-fan across and --tstm-lift up, so a
   card filling the whole stack would draw that far outside its own
   grid column — over the quote beside it and over the section copy
   above, which is what it did on first fitting. Insetting every
   card by the same two values lands the fanned ones flush with the
   stack edge instead.

   The inset has to be written out. Padding on the stack would not
   do it: a padding box *includes* the padding, so `inset: 0` fills
   the whole area inside the border and an absolutely positioned
   card ignores the padding entirely. */
.tr-tstm-stack {
  position: relative;
  /* Sized so the card inside the inset stays near the 16:10 of the
     screenshots it holds — object-fit then has almost nothing to
     crop. */
  height: clamp(200px, 24vw, 292px);
  /* Deeper than the 1000px the reference uses. The rotated cards are
     scaled to 0.85, which leaves 7.5% of the card's width as slack on
     each side; a nearer vanishing point magnifies the edge tilted
     towards the viewer and eats into that slack, and does so hardest
     on a narrow screen where the card is a large share of the
     viewport. 1600px keeps the fan reading as depth without pushing
     an edge back out over the copy. */
  perspective: 1600px;
}

.tr-tstm-stage .tr-tstm-media {
  position: absolute;
  top: var(--tstm-lift);
  right: var(--tstm-fan);
  bottom: 0;
  left: var(--tstm-fan);
  margin: 0;
  transform-style: preserve-3d;
  transition:
    transform 0.8s cubic-bezier(0.4, 2, 0.3, 1),
    opacity 0.8s cubic-bezier(0.4, 2, 0.3, 1);
}

.tr-tstm-stage .tr-tstm-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}

/* The two cards behind the active one stick up and out by a
   proportion of the stack's own width, so the fan opens as the
   column grows instead of needing a resize listener to re-measure
   it in JavaScript. Both values are also the cards' inset — change
   one and the space reserved for the fan follows. */
.tr-tstm-stack {
  --tstm-fan: clamp(48px, 9vw, 86px);
  --tstm-lift: clamp(34px, 6.4vw, 62px);
}

.tr-tstm-media[data-pos="active"] {
  z-index: 3;
  opacity: 1;
  transform: none;
}

.tr-tstm-media[data-pos="left"],
.tr-tstm-media[data-pos="right"] {
  z-index: 2;
  opacity: 1;
  cursor: pointer;
}

.tr-tstm-media[data-pos="left"] {
  transform: translateX(calc(-1 * var(--tstm-fan))) translateY(calc(-1 * var(--tstm-lift))) scale(0.85) rotateY(15deg);
}

.tr-tstm-media[data-pos="right"] {
  transform: translateX(var(--tstm-fan)) translateY(calc(-1 * var(--tstm-lift))) scale(0.85) rotateY(-15deg);
}

.tr-tstm-media[data-pos="hidden"] {
  z-index: 1;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.8);
}

/* ── The quote panel ─────────────────────────────────────────
   Every body sits in the same grid cell, so the panel is as tall
   as the longest quote and the arrows never move when the
   carousel advances. */
.tr-tstm-panel {
  display: grid;
  align-items: start;
  /* Above the cards, which carry z-index up to 3. The stack's
     padding should keep them apart on its own; this is the net
     that stops a quote being painted over if it ever does not. */
  position: relative;
  z-index: 4;
}

.tr-tstm-stage .tr-tstm-body {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease,
    visibility 0.3s;
}

.tr-tstm-stage .tr-tstm-body.is-active {
  visibility: visible;
  opacity: 1;
  transform: none;
}

/* Each word of the active quote fades up out of a blur. The index
   comes from the span's own --i, set when the quote is split. */
.tr-tstm-word {
  display: inline-block;
  animation: tr-tstm-word-in 0.24s ease both;
  animation-delay: calc(var(--i) * 25ms);
}

@keyframes tr-tstm-word-in {
  from {
    filter: blur(10px);
    opacity: 0;
    transform: translateY(5px);
  }
  to {
    filter: blur(0);
    opacity: 1;
    transform: none;
  }
}

/* ── Controls ────────────────────────────────────────────────
   Built by testimonials.js, so with no JS there are no arrows
   and no dots to click at nothing. */
.tr-tstm-controls {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-top: 36px;
}

.tr-tstm-arrows {
  display: flex;
  gap: 12px;
}

.tr-tstm-arrow {
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--color-navy);
  color: var(--color-white);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--transition), transform var(--transition);
}

.tr-tstm-arrow:hover {
  background: var(--color-green);
}

.tr-tstm-arrow:active {
  transform: scale(0.94);
}

.tr-tstm-arrow:focus-visible {
  outline: 2px solid var(--color-green);
  outline-offset: 3px;
}

.tr-tstm-arrow svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.tr-tstm-dots {
  display: flex;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.tr-tstm-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--color-border);
  cursor: pointer;
  transition: background var(--transition), width var(--transition);
}

.tr-tstm-dot.is-active {
  width: 26px;
  border-radius: 5px;
  background: var(--color-green);
}

.tr-tstm-dot:focus-visible {
  outline: 2px solid var(--color-green);
  outline-offset: 3px;
}

/* =============================================================
   3. RESPONSIVE
============================================================= */

@media (max-width: 900px) {
  .tr-tstm-stage {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  /* One column now, so the stack has the full container width and
     the card inside the padding is correspondingly wider. */
  .tr-tstm-stack {
    height: clamp(180px, 52vw, 480px);
    --tstm-fan: clamp(36px, 9vw, 60px);
    --tstm-lift: clamp(24px, 6vw, 42px);
  }

  .tr-tstm-controls {
    margin-top: 28px;
  }
}

/* =============================================================
   4. REDUCED MOTION
   The carousel still works — it just arrives instead of
   travelling. testimonials.js reads the same query and skips
   both autoplay and the per-word split.
============================================================= */

@media (prefers-reduced-motion: reduce) {
  .tr-tstm-stage .tr-tstm-media,
  .tr-tstm-stage .tr-tstm-body,
  .tr-tstm-arrow,
  .tr-tstm-dot {
    transition: none;
  }

  .tr-tstm-word {
    animation: none;
  }
}
