/* ==========================================================================
   06 · TESTIMONIALS
   One markup tree, two layouts. This file is the RESTING truth — layout,
   colour, and the redesigned card grammar. All motion, the collapsed-card
   choreography, and the Studio's "slide" variant live in
   css/interactions/testimonials.css keyed off body[data-rbs-testimonials].

   The card = portrait plate + ink panel:
     · evidence block anchors the panel — D2 stat over a mono label, so the
       number reads as a measured result, not decor
     · the quote hangs its opening mark outside the text edge
     · the byline is pinned to the panel floor behind a hairline
     · a faint plus-mark texture on the ink echoes the hero's graph paper

   <1200  scroll-snap carousel: portrait band over the ink panel, shared
          dot pagination beneath.
   ≥1200  the slides become a flex row. Three collapse to a portrait strip
          (fixed plate width, the card clips the rest); the open one takes
          --rbs-testimonials-open-fr and shows the panel.
   ========================================================================== */

.rb-testimonials {
  /* One clock for the whole section. Editorial-scale, so it follows the
     Studio's global Tempo in addition to its own Speed knob. */
  --rbs-t-dur: calc(var(--rbs-testimonials-dur, 600ms) * var(--rbs-motion-scale, 1));

  /* Plus silhouettes for the panel graphic. Only the shape lives in the SVG
     (as a mask); the ink colour stays a token, exactly like the hero grid. */
  --rbs-t-plus-tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56'%3E%3Crect x='27.25' y='22' width='1.5' height='12' fill='%23fff'/%3E%3Crect x='22' y='27.25' width='12' height='1.5' fill='%23fff'/%3E%3C/svg%3E");
  --rbs-t-plus-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'%3E%3Crect x='6.25' y='0' width='1.5' height='14' fill='%23fff'/%3E%3Crect x='0' y='6.25' width='14' height='1.5' fill='%23fff'/%3E%3C/svg%3E");
}

/* Off-canvas <symbol> host for the Rubrik mark; must not affect layout. */
.rb-testimonials__defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* --- Track ----------------------------------------------------------------
   A plain overflow scroller below 1200. `.rb-container` owns the page-edge
   padding, so the scroll region is inset with the rest of the page.
   -------------------------------------------------------------------------- */
.rb-testimonials__track {
  display: flex;
  gap: var(--rb-ref-space-4);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* The dots are the affordance; the native bar would sit under the cards. */
  scrollbar-width: none;
}
.rb-testimonials__track::-webkit-scrollbar { display: none; }

.rb-testimonials__slide {
  display: flex;
  flex: 0 0 100%;
  scroll-snap-align: start;
}

/* --- Card -----------------------------------------------------------------
   Below 1200 the card IS the dark box: hairline, 10px corners, portrait band
   above the panel. From 1200 the slide becomes a white shell around it.
   -------------------------------------------------------------------------- */
.rb-testimonials__card {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
  background: var(--rb-sys-bg-dark);
  border: var(--rb-ref-border-hairline) solid var(--rb-sys-border-teal);
  border-radius: var(--rb-ref-radius-lg);
  overflow: hidden;
}

/* --- Photo ----------------------------------------------------------------
   Four distinct 3:4 portraits (900×1200). The band crops them to 3:2 below
   1200; the crop var keeps the head in frame and stays overridable per
   slide if a portrait ever needs it.

   The duotone layers are always present and rest at zero:
     img filter   ← --rbs-t-mono  (grayscale amount)
     ::after      ← --rbs-t-tint  (teal colour-blend plate)
     ::before     ← --rbs-t-vlabel (bottom scrim, rides with the name label)
   The interaction pass flips those vars on collapsed/dimmed cards, so the
   featured portrait "comes alive" in full colour.
   -------------------------------------------------------------------------- */
.rb-testimonials__photo {
  flex: none;
  aspect-ratio: 3 / 2;
  background: var(--rb-sys-bg-muted);
  isolation: isolate;  /* keeps the colour-blend inside the plate */
}

.rb-testimonials__photo > img {
  object-position: 50% var(--rb-testimonials-crop-y, 20%);
  filter: grayscale(var(--rbs-t-mono, 0%));
}

/* Bottom scrim — legibility floor for the vertical name label. */
.rb-testimonials__photo::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 55%;
  background: linear-gradient(to top,
      color-mix(in srgb, var(--rb-ref-ink) 62%, transparent),
      transparent);
  opacity: var(--rbs-t-vlabel, 0);
  pointer-events: none;
}

/* Teal plate. `color` blend keeps the portrait's luminance and swaps its hue,
   which is what makes it read as duotone rather than a wash. */
.rb-testimonials__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--rb-ref-teal-900);
  mix-blend-mode: color;
  opacity: var(--rbs-t-tint, 0);
  pointer-events: none;
}

/* NORMALISED: reference badge was 114px wide; snapped to the 4px grid.
   The shared badge has no left padding, so the width is what insets the
   mark from the card edge. Rests visible; the interaction pass fades it
   out on collapsed strips via --rbs-t-badge. */
.rb-testimonials__badge {
  position: absolute;
  bottom: 0;
  left: 0;
  min-width: 112px;
  opacity: var(--rbs-t-badge, 1);
}

/* Vertical name label — collapsed strips read as people, not slivers.
   Desktop-row furniture only; the interaction pass raises --rbs-t-vlabel. */
.rb-testimonials__vlabel {
  position: absolute;
  left: var(--rb-ref-space-4);
  bottom: var(--rb-ref-space-4);
  display: none;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  color: var(--rb-ref-white);
  opacity: var(--rbs-t-vlabel, 0);
  pointer-events: none;
}

/* The whole photo plate is the hit target — on a collapsed strip the plate
   is wider than the card, so the entire card face is clickable. Sits above
   the badge in paint order without a z-index, being later in the DOM. */
.rb-testimonials__toggle {
  position: absolute;
  inset: 0;
  border-radius: var(--rb-ref-radius-lg);
}
/* The card clips, so the ring has to be drawn inside it. */
.rb-testimonials__toggle:focus-visible {
  outline-offset: calc(-1 * var(--rb-ref-space-1));
}

/* --- Quote panel -----------------------------------------------------------
   position + z-index 0 make a stacking context so the texture pseudo can sit
   above the dark card ground but below every line of text.
   -------------------------------------------------------------------------- */
.rb-testimonials__panel {
  position: relative;
  z-index: 0;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--rb-ref-space-5);
  min-width: 0;
  padding: var(--rb-ref-space-6);
  color: var(--rb-sys-fg-on-dark);
}

/* Plus-grid texture — hero graph paper restated in white ink at 7%.
   The Studio's Panel texture knob swaps this for corner marks or nothing
   (see css/interactions/testimonials.css). */
.rb-testimonials__panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--rb-ref-white) 7%, transparent);
  -webkit-mask-image: var(--rbs-t-plus-tile);
  mask-image: var(--rbs-t-plus-tile);
  -webkit-mask-size: 56px 56px;
  mask-size: 56px 56px;
  pointer-events: none;
}

/* Evidence block — the panel's anchor. Stat over its mono label, so the
   number carries a claim instead of floating as decoration. */
.rb-testimonials__evidence {
  display: flex;
  flex-direction: column;
  gap: var(--rb-ref-space-2);
}

/* A stat is one token — never wrap it, and never let `balance` split it. */
.rb-testimonials__stat {
  text-wrap: nowrap;
  font-variant-numeric: tabular-nums;
}

.rb-testimonials__statlabel {
  color: var(--rb-sys-fg-accent);
}

/* Hanging opening quote: the mark sits outside the text edge so every line
   of the quote starts on the same rail. The @supports guard prevents a
   double hang where the real property exists. */
.rb-testimonials__quote p {
  text-indent: -0.42em;
  hanging-punctuation: first;
}
@supports (hanging-punctuation: first) {
  .rb-testimonials__quote p { text-indent: 0; }
}

/* Byline pinned to the panel floor behind a hairline; slack collects under
   the quote, never under the name. */
.rb-testimonials__byline {
  display: flex;
  flex-direction: column;
  gap: var(--rb-ref-space-1);
  margin-block-start: auto;
  padding-block-start: var(--rb-ref-space-4);
  border-block-start: var(--rb-ref-border-hairline) solid var(--rb-sys-border-on-dark);
}

/* Name at label-medium, role a step quieter — a two-tone byline. */
.rb-testimonials__name {
  font-style: normal;
}

/* No semantic on-dark muted foreground exists yet; grey-350 is the value the
   reference uses and the one --rb-sys-fg-disabled happens to alias. */
.rb-testimonials__role {
  color: var(--rb-ref-grey-350);
}

/* --- Pagination + arrows ---------------------------------------------------
   The arrows belong to the Studio's "slide" variant only; the interaction
   pass reveals them. They rest hidden so the section is correct with no JS.
   -------------------------------------------------------------------------- */
.rb-testimonials__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--rb-ref-space-5);
  margin-block-start: var(--rb-ref-space-5);
}

.rb-testimonials__arrow { display: none; }
.rb-testimonials__arrow svg { width: 20px; height: 20px; }
.rb-testimonials__arrow:disabled {
  opacity: 0.35;
  pointer-events: none;
}

.rb-testimonials__dots {
  justify-content: center;
}

/* ==========================================================================
   TABLET — 768 to 1199
   Still the carousel, one card per slide. A full-width card at this size
   would stretch the portrait band, so the card is capped and centred.

   The reference does switch to the expanding row at 768 — and renders it
   broken: the open card is 336px, which leaves the quote panel 98px and
   clips the stat and every line of the quote mid-word. That is a defect,
   not a design, so the row waits for 1200 where it has the width to work.
   ========================================================================== */
@media (min-width: 768px) {
  .rb-testimonials__card {
    max-width: 560px;
    margin-inline: auto;
  }
}

/* ==========================================================================
   DESKTOP — 1200 and up: the expanding row (the shipped variant).
   The Studio's "slide" variant overrides this from the interactions layer.
   ========================================================================== */
@media (min-width: 1200px) {

  .rb-testimonials__track {
    gap: var(--rb-ref-space-4);
    overflow: visible;
    scroll-snap-type: none;
  }

  /* The slide becomes the white shell: hairline, 16px inset, square corners.
     flex-grow is the morph axis; its transition lives in the interaction
     layer so this file stays motion-free. */
  .rb-testimonials__slide {
    flex: 1 1 0;
    min-width: 0;
    background: var(--rb-sys-bg-canvas);
    border: var(--rb-ref-border-hairline) solid var(--rb-sys-border-teal);
    scroll-snap-align: none;
  }

  /* --open is the server-rendered resting state; [data-active] is what the
     switcher sets at runtime. Both mean the same thing, so both are styled.
     The open share is a Studio knob (2–4fr). */
  .rb-testimonials__slide--open,
  .rb-testimonials__slide[data-active="true"] {
    flex-grow: var(--rbs-testimonials-open-fr, 3);
  }
  /* Once the switcher has run it owns the state, so the static class defers. */
  [data-switch-active] .rb-testimonials__slide--open:not([data-active="true"]) {
    flex-grow: 1;
  }

  .rb-testimonials__card {
    flex-direction: row;
    align-items: stretch;
    max-width: none;
    /* The 16px inset is a MARGIN, not slide padding: padding would inflate
       every slide's flex base and skew the open/collapsed split. */
    margin: var(--rb-ref-space-4);
    /* 456px — the reference's fixed card interior; the 490px shell is that
       plus the 16px inset and the hairline on each edge. */
    height: 456px;
    border: 0;
  }

  /* Fixed plate width at every card width: a collapsed card simply clips it,
     so the portrait never stretches while the row morphs. Fluid between the
     1200 floor and the 1440 canvas cap so the open panel keeps a readable
     measure at both ends. */
  .rb-testimonials__photo {
    width: clamp(200px, 18.5vw, 268px);
    aspect-ratio: auto;
    border-radius: var(--rb-ref-radius-lg);
  }

  /* A 3:4 portrait covers the 456px plate by height, so only the sides crop
     — recentre horizontally and let the crop var stand down. */
  .rb-testimonials__photo > img {
    object-position: 50% 50%;
  }

  /* Basis 0 so a collapsed card leaves the panel nothing but its padding,
     exactly as the reference does — the card clips the overflow. */
  .rb-testimonials__panel {
    flex: 1 1 0;
    gap: var(--rb-ref-space-6);
  }

  /* 1.15 — H5's reading leading. The old 0.96 display leading was set for a
     one-line placeholder; real multi-line quotes collide at 0.96. */
  .rb-testimonials__quote {
    line-height: var(--rb-sys-text-h5-leading);
  }

  /* Desktop-row furniture: the vertical name label exists only where cards
     can collapse. (The slide variant re-hides it from the interaction layer.) */
  .rb-testimonials__vlabel { display: block; }

  /* Row layout: dots and arrows rest hidden; the slide variant re-shows its
     controls from the interaction layer. */
  .rb-testimonials__controls { display: none; }
}

/* The overlay toggle belongs to the desktop layouts, so it appears with them.
   Scoped to this section rather than reusing the global .rb-only-desktop so
   the switcher can still find the buttons in the DOM at every width. */
.rb-testimonials__toggle { display: none; }
@media (min-width: 1200px) { .rb-testimonials__toggle { display: block; } }
