/* ==========================================================================
   IX · CAROUSEL — the stacked-surfaces section (04).

     body[data-rbs-carousel="switch"]  click-driven, staged card trade
     body[data-rbs-carousel="scrub"]   sticky runway, plain scrolling scrubs

   js/areas/carousel.js owns the imperative half: direction flag
   (data-rbs-dir on .rb-surfaces), the incoming card's planted start state
   (.is-rbs-plant), the rolling counter, inert sync, and — for scrub — the
   runway measurements and the per-card custom props written every frame.

   Gating:
     · feedback (arrow nudge, press, disabled fade, dot fill) — every level
     · the staged card choreography + counter roll — authored only
     · essential — a 220ms crossfade, gentler never dead
     · static / JS absent — instant swaps, exactly as workspace 01
   ========================================================================== */

/* --------------------------------------------------------------------------
   ARROWS — feedback, all motion levels.
   The glyph nudges in its travel direction on hover; the button dips on
   press; the disabled state fades instead of snapping. Icon rotations mirror
   the section css (left/right below 768, up/down above).
   -------------------------------------------------------------------------- */
.rb-surfaces__nav {
  transition: opacity var(--rb-sys-duration-2) ease,
              background-color var(--rb-sys-duration-2) ease,
              border-color var(--rb-sys-duration-2) ease,
              transform var(--rb-sys-duration-1) var(--rb-sys-ease-swift);
}

/* A disabled arrow must not paint hover chrome (CSS :hover still matches). */
.rb-surfaces__nav:disabled { pointer-events: none; }

.rb-surfaces__nav:not(:disabled):active { transform: scale(0.94); }

.rb-surfaces__nav-icon { transition: transform var(--rb-sys-duration-2) ease; }

@media (hover: hover) and (pointer: fine) {
  .rb-surfaces__nav:hover .rb-surfaces__nav-icon--prev { transform: translateX(-2px) rotate(90deg); }
  .rb-surfaces__nav:hover .rb-surfaces__nav-icon--next { transform: translateX(2px) rotate(-90deg); }
}

@media (hover: hover) and (pointer: fine) and (min-width: 768px) {
  .rb-surfaces__nav:hover .rb-surfaces__nav-icon--prev { transform: translateY(-2px) rotate(180deg); }
  .rb-surfaces__nav:hover .rb-surfaces__nav-icon--next { transform: translateY(2px); }
}

/* --------------------------------------------------------------------------
   DOTS — the active pill's accent fill wipes in from the travel side.
   Keyed on the body attribute so the shipped no-studio page keeps the plain
   component dot. The pill base stays hairline-teal; a clip-path inset()
   reveal carries the accent — width still grows via 05-components.
   -------------------------------------------------------------------------- */
body[data-rbs-carousel] .rb-surfaces .rb-dots__dot {
  background: var(--rb-sys-border-teal);
}

body[data-rbs-carousel] .rb-surfaces .rb-dots__dot::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--rb-sys-bg-accent);
  /* collapsed against the leading edge; travel = next by default */
  clip-path: inset(0 100% 0 0 round var(--rb-ref-radius-full));
  transition: clip-path var(--rb-sys-duration-3) var(--rb-sys-ease-swift);
}

body[data-rbs-carousel] .rb-surfaces[data-rbs-dir="prev"] .rb-dots__dot:not([aria-current="true"])::before {
  clip-path: inset(0 0 0 100% round var(--rb-ref-radius-full));
}

body[data-rbs-carousel] .rb-surfaces .rb-dots__dot[aria-current="true"]::before {
  clip-path: inset(0 0 0 0 round var(--rb-ref-radius-full));
}

/* --------------------------------------------------------------------------
   STAGED SWITCH — authored only.
   Outgoing eases back in z and drifts with the travel; incoming is planted
   12px low on the travel side (transition:none, released next frame) and
   rises in; its stat readout lands 80ms late. Exits run at 0.6× the enter.
   All transitions — retarget mid-flight, never restart.
   -------------------------------------------------------------------------- */
body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces {
  --rbs-carousel-dx: -1;  /* next: travel leftward */
  --_rbsc-enter: calc(var(--rbs-carousel-dur, 500ms) * var(--rbs-motion-scale, 1));
  --_rbsc-exit:  calc(var(--rbs-carousel-dur, 500ms) * 0.6 * var(--rbs-motion-scale, 1));
}
body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces[data-rbs-dir="prev"] {
  --rbs-carousel-dx: 1;
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card {
  transition: opacity var(--_rbsc-enter, 500ms) var(--rb-sys-ease-morph),
              transform var(--_rbsc-enter, 500ms) var(--rb-sys-ease-morph);
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card[data-active="false"] {
  transform: translateX(calc(var(--rbs-carousel-dx, -1) * 16px * var(--rbs-carousel-depth, 1)))
             scale(calc(1 - 0.02 * var(--rbs-carousel-depth, 1)));
  transition: opacity var(--_rbsc-exit, 300ms) var(--rb-sys-ease-swift),
              transform var(--_rbsc-exit, 300ms) var(--rb-sys-ease-swift),
              visibility 0s linear var(--_rbsc-exit, 300ms);
}

/* Stat: second stage of the enter. Follows the card out with no delay. */
body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card .rb-surfaces__stat {
  transition: opacity calc(var(--_rbsc-enter, 500ms) * 0.8) var(--rb-sys-ease-swift) 80ms,
              transform calc(var(--_rbsc-enter, 500ms) * 0.8) var(--rb-sys-ease-swift) 80ms;
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card[data-active="false"] .rb-surfaces__stat {
  opacity: 0;
  transform: translateY(10px);
  transition-duration: var(--_rbsc-exit, 300ms), var(--_rbsc-exit, 300ms);
  transition-delay: 0s, 0s;
}

/* Planted start state for the incoming card. JS adds the class, forces one
   reflow, removes it — the card then transitions from here to identity. */
body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card.is-rbs-plant {
  transition: none;
  opacity: 0;
  transform: translateY(12px) translateX(calc(var(--rbs-carousel-dx, -1) * -8px));
}
body[data-rbs-motion-level="authored"][data-rbs-carousel="switch"] .rb-surfaces__card.is-rbs-plant .rb-surfaces__stat {
  transition: none;
  opacity: 0;
  transform: translateY(10px);
}

/* --------------------------------------------------------------------------
   ESSENTIAL — a quiet 220ms crossfade on any variant. Micro-feedback class,
   so it deliberately ignores the tempo multiplier.
   -------------------------------------------------------------------------- */
body[data-rbs-motion-level="essential"] .rb-surfaces__card {
  transition: opacity var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
}
body[data-rbs-motion-level="essential"] .rb-surfaces__card[data-active="false"] {
  transition: opacity var(--rb-sys-duration-2) var(--rb-sys-ease-swift),
              visibility 0s linear var(--rb-sys-duration-2);
}

/* --------------------------------------------------------------------------
   COUNTER — rolling digits. The area JS builds a clone next to the original
   "01 / 03" (which main.js keeps rewriting) and hides the original once the
   roll is armed; JS absent, the original stays. Digit height comes from the
   L1 leading, so the window clips exactly one line.
   -------------------------------------------------------------------------- */
.rb-surfaces[data-rbs-counter="roll"] .rb-surfaces__counter[data-switch-counter] { display: none; }

.rbs-counter__win {
  display: inline-flex;
  overflow: hidden;
  height: calc(1em * var(--rb-sys-text-l1-leading, 1.5));
  vertical-align: bottom;
}

.rbs-counter__reel {
  display: flex;
  flex-direction: column;
  transform: translateY(calc(var(--rbs-counter-i, 0) * -1em * var(--rb-sys-text-l1-leading, 1.5)));
}

body[data-rbs-motion-level="authored"] .rbs-counter__reel {
  transition: transform calc(var(--rbs-carousel-dur, 500ms) * var(--rbs-motion-scale, 1)) var(--rb-sys-ease-morph);
}

/* --------------------------------------------------------------------------
   STICKY SCRUB — authored only, and only once JS has measured and armed the
   section (data-rbs-scrub-armed). The section becomes a runway of
   3 × --rbs-carousel-runway; the pin sticks; every visual value is a custom
   prop the JS maps from scroll progress — no transitions, so the motion is
   reversible and interruptible by construction. At essential/static the
   armed attribute never lands and the section keeps its normal height.
   -------------------------------------------------------------------------- */
body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] {
  min-height: calc(var(--rbs-carousel-runway, 100vh) * 3);
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] .rb-surfaces__pin {
  position: sticky;
  top: var(--rbs-carousel-sticky-top, 0px);
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] .rb-surfaces__card {
  transition: none;
  opacity: var(--rbs-carousel-o, 1);
  visibility: var(--rbs-carousel-vis, visible);
  transform: translate3d(var(--rbs-carousel-x, 0px), var(--rbs-carousel-y, 0px), 0)
             scale(var(--rbs-carousel-s, 1));
  will-change: transform, opacity;
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] .rb-surfaces__card[data-active="false"] {
  opacity: var(--rbs-carousel-o, 0);
  visibility: var(--rbs-carousel-vis, hidden);
}

body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] .rb-surfaces__card .rb-surfaces__stat {
  transition: none;
  opacity: var(--rbs-carousel-so, 1);
  transform: translateY(var(--rbs-carousel-sy, 0px));
}

/* Dot fill becomes a continuous segment-progress readout: scroll-linked,
   therefore linear and untransitioned. */
body[data-rbs-motion-level="authored"][data-rbs-carousel="scrub"] .rb-surfaces[data-rbs-scrub-armed] .rb-dots__dot[aria-current="true"]::before {
  transition: none;
  clip-path: inset(0 calc((1 - var(--rbs-carousel-seg, 1)) * 100%) 0 0 round var(--rb-ref-radius-full));
}
