/* ==========================================================================
   IX · TESTIMONIALS — how four practitioner stories take the stage.

     body[data-rbs-testimonials="expand"]  the shipped expanding row, fixed:
                                           real morph on flex-grow, duotone
                                           strips, two-stage content reveal
     body[data-rbs-testimonials="slide"]   a centred carousel: one card at
                                           reading width, neighbours dimmed,
                                           arrows + dots

   With the attribute absent (Studio JS never ran) everything here resolves
   to the expand variant's resting behaviour, so the page stays correct.

   State is expressed as custom properties flipped by ONE collapsed-card
   rule; the elements below consume them and transition on the computed
   change, so every move retargets mid-flight instead of restarting:

     --rbs-t-mono / --rbs-t-tint   duotone amount (img filter / teal plate)
     --rbs-t-vlabel                vertical name label + its scrim
     --rbs-t-badge                 Rubrik badge on the photo
     --rbs-t-content / --rbs-t-y   panel children fade / lift
     --rbs-t-hold / --rbs-t-step   reveal delay after the size settles + stagger

   Knobs: --rbs-testimonials-open-fr (expand share), --rbs-testimonials-dur
   (the section clock), --rbs-testimonials-duotone (strip treatment), plus
   data-rbs-testimonials-nohover / data-rbs-testimonials-texture set by
   js/areas/testimonials.js.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TIMING BASE — the values the OPEN state transitions toward. Collapse
   overrides them per-slide below (transition params come from the
   destination state, so enters are held + staggered while exits are
   immediate and faster).
   -------------------------------------------------------------------------- */
.rb-testimonials {
  --rbs-t-hold: calc(var(--rbs-t-dur) * 0.7); /* content waits for the morph */
  --rbs-t-step: 70ms;                          /* sibling stagger */
  --rbs-t-badge-delay: calc(var(--rbs-t-dur) * 0.5);
}

/* The 12px content lift is position work — authored motion only. At every
   other level (and with Studio JS absent) the reveal is a pure fade. */
body[data-rbs-motion-level="authored"] .rb-testimonials { --rbs-t-lift: 12px; }

/* --------------------------------------------------------------------------
   TRANSITIONS — declared on the base state so they retarget mid-flight.
   flex-grow is the sanctioned layout morph for this section (the row is a
   fixed-height flex line, so nothing outside the section ever reflows).
   -------------------------------------------------------------------------- */
.rb-testimonials__slide {
  transition:
    flex-grow var(--rbs-t-dur) var(--rb-sys-ease-morph),
    opacity calc(var(--rbs-t-dur) * 0.8) var(--rb-sys-ease-swift);
}

.rb-testimonials__photo > img {
  transition: filter var(--rbs-t-dur) var(--rb-sys-ease-morph);
}
.rb-testimonials__photo::before,
.rb-testimonials__photo::after {
  transition: opacity var(--rbs-t-dur) var(--rb-sys-ease-morph);
}

.rb-testimonials__badge {
  transition: opacity var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
  transition-delay: var(--rbs-t-badge-delay, 0ms);
}
.rb-testimonials__vlabel {
  transition: opacity var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
  transition-delay: var(--rbs-t-vlabel-delay, 0ms);
}

/* Panel children: evidence → quote → byline. Opacity/transform only —
   plus discrete visibility, so a collapsed card's quote text leaves the
   accessibility tree and can't take focus while clipped invisible. */
.rb-testimonials__panel > * {
  opacity: var(--rbs-t-content, 1);
  transform: translateY(var(--rbs-t-y, 0px));
  visibility: var(--rbs-t-vis, visible);
  transition:
    opacity var(--rbs-t-content-dur, var(--rb-sys-duration-3)) var(--rb-sys-ease-swift),
    transform var(--rbs-t-content-dur, var(--rb-sys-duration-3)) var(--rb-sys-ease-swift),
    visibility var(--rbs-t-content-dur, var(--rb-sys-duration-3));
  transition-delay: calc(var(--rbs-t-hold, 0ms) + var(--rbs-t-n, 0) * var(--rbs-t-step, 0ms));
}
.rb-testimonials__evidence { --rbs-t-n: 0; }
.rb-testimonials__quote    { --rbs-t-n: 1; }
.rb-testimonials__byline   { --rbs-t-n: 2; }

/* --------------------------------------------------------------------------
   EXPAND — collapsed-card state. One rule flips every var; the pieces above
   follow. Two branches because the server-rendered --open class governs
   until the switcher takes over ([data-switch-active] demotes it).
   -------------------------------------------------------------------------- */
@media (min-width: 1200px) {
  body:not([data-rbs-testimonials="slide"]) :is(
    .rb-testimonials__slide:not(.rb-testimonials__slide--open):not([data-active="true"]),
    [data-switch-active] .rb-testimonials__slide--open:not([data-active="true"])
  ) {
    /* the portrait goes duotone-teal; expansion brings it alive */
    --rbs-t-mono: calc(var(--rbs-testimonials-duotone, 0.85) * 100%);
    --rbs-t-tint: var(--rbs-testimonials-duotone, 0.85);
    /* strips read as people: vertical name on, badge off */
    --rbs-t-vlabel: 1;
    --rbs-t-vlabel-delay: calc(var(--rbs-t-dur) * 0.55); /* waits for the shrink */
    --rbs-t-badge: 0;
    --rbs-t-badge-delay: 0ms;
    /* panel content hidden; exits are immediate and faster than enters */
    --rbs-t-content: 0;
    --rbs-t-vis: hidden;
    --rbs-t-y: var(--rbs-t-lift, 0px);
    --rbs-t-hold: 0ms;
    --rbs-t-step: 0ms;
    --rbs-t-content-dur: var(--rb-sys-duration-1);
  }
}

/* Hover preview: a collapsed strip leans open +0.2fr under a fine pointer,
   inviting the click. Studio toggle sets data-rbs-testimonials-nohover;
   Static motion keeps the workspace-01 row inert. */
@media (min-width: 1200px) and (hover: hover) and (pointer: fine) {
  body:not([data-rbs-testimonials="slide"]):not([data-rbs-motion-level="static"])
    .rb-testimonials:not([data-rbs-testimonials-nohover]) :is(
      .rb-testimonials__slide:not(.rb-testimonials__slide--open):not([data-active="true"]),
      [data-switch-active] .rb-testimonials__slide--open:not([data-active="true"])
    ):hover {
    flex-grow: 1.2;
  }
}

/* --------------------------------------------------------------------------
   SLIDE — centred carousel. The track translates to a px offset computed by
   js/areas/testimonials.js (it only writes --rbs-t-offset; this transition
   owns the movement, so it is direction-aware and interruptible for free).
   .is-rbs-snap suppresses the transition for first-layout and resize.
   -------------------------------------------------------------------------- */
@media (min-width: 1200px) {
  body[data-rbs-testimonials="slide"] .rb-testimonials__carousel {
    overflow: hidden;
  }

  body[data-rbs-testimonials="slide"] .rb-testimonials__track {
    gap: var(--rb-ref-space-6);
    transform: translateX(var(--rbs-t-offset, 0px));
    transition: transform var(--rbs-t-dur) var(--rb-sys-ease-morph);
  }
  body[data-rbs-testimonials="slide"] .rb-testimonials__track.is-rbs-snap {
    transition: none;
  }

  /* One card at reading width; neighbours peek at the edges. */
  body[data-rbs-testimonials="slide"] .rb-testimonials__track .rb-testimonials__slide {
    flex: 0 0 min(720px, 86%);
  }

  /* Dimmed + duotone until featured — the same "comes alive" move as the
     expand variant, restated for a carousel. */
  body[data-rbs-testimonials="slide"] .rb-testimonials__track .rb-testimonials__slide:not([data-active="true"]) {
    opacity: 0.45;
    --rbs-t-mono: calc(var(--rbs-testimonials-duotone, 0.85) * 100%);
    --rbs-t-tint: var(--rbs-testimonials-duotone, 0.85);
  }

  /* Every card is open here: fixed plate, no vertical label, and the row's
     hidden controls come back with the arrows. */
  body[data-rbs-testimonials="slide"] .rb-testimonials__photo { width: 288px; }
  body[data-rbs-testimonials="slide"] .rb-testimonials__vlabel { display: none; }
  body[data-rbs-testimonials="slide"] .rb-testimonials__controls { display: flex; }
  body[data-rbs-testimonials="slide"] .rb-testimonials__arrow { display: inline-flex; }
}

/* --------------------------------------------------------------------------
   PANEL TEXTURE — Studio knob. Default (grid) lives in the section file;
   these override it. Masks only, so the ink colour stays a token.
   -------------------------------------------------------------------------- */
.rb-testimonials[data-rbs-testimonials-texture="none"] .rb-testimonials__panel::before {
  content: none;
}

.rb-testimonials[data-rbs-testimonials-texture="corners"] .rb-testimonials__panel::before {
  background: color-mix(in srgb, var(--rb-ref-white) 16%, transparent);
  -webkit-mask-image: var(--rbs-t-plus-mark), var(--rbs-t-plus-mark),
                      var(--rbs-t-plus-mark), var(--rbs-t-plus-mark);
  mask-image: var(--rbs-t-plus-mark), var(--rbs-t-plus-mark),
              var(--rbs-t-plus-mark), var(--rbs-t-plus-mark);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 14px 14px;
  mask-size: 14px 14px;
  -webkit-mask-position:
    14px 14px, calc(100% - 14px) 14px,
    14px calc(100% - 14px), calc(100% - 14px) calc(100% - 14px);
  mask-position:
    14px 14px, calc(100% - 14px) 14px,
    14px calc(100% - 14px), calc(100% - 14px) calc(100% - 14px);
}

/* --------------------------------------------------------------------------
   MOTION LEVELS
   Static mirrors workspace 01's zero-motion baseline: state still flips
   (the section stays functional), nothing eases.
   -------------------------------------------------------------------------- */
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__slide,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__track,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__photo > img,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__photo::before,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__photo::after,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__badge,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__vlabel,
body[data-rbs-motion-level="static"] .rb-testimonials .rb-testimonials__panel > * {
  transition: none;
}

/* Reduced motion (and the kernel's Essential cap): sizes and travel snap,
   the fades stay — gentler, never dead. The authored guard lets the
   Studio's "Ignore" policy demo the full pass. */
@media (prefers-reduced-motion: reduce) {
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials {
    --rbs-t-hold: 0ms;
    --rbs-t-step: 40ms;
    --rbs-t-badge-delay: 0ms;
  }
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__slide,
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__track {
    transition-duration: 0ms;
  }
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__photo > img,
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__photo::before,
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__photo::after,
  body:not([data-rbs-motion-level="authored"]) .rb-testimonials .rb-testimonials__panel > * {
    transition-duration: var(--rb-sys-duration-2);
  }
}
