/* ==========================================================================
   IX · TABS — the DATA / IDENTITY / AI switcher.

     body[data-rbs-tabs="click"]   the shipped tab bar, upgraded: one
                                   persistent object morphs between tabs
     body[data-rbs-tabs="scroll"]  the same object, but the section pins and
                                   scroll drives it through three segments

   js/areas/tabs.js owns the imperative half: it builds the indicator, keeps
   it measured, watches main.js flip aria-selected (selection state is never
   re-implemented here), and runs the panel choreography. Nothing in this
   file engages until JS arms the tablist (data-rbs-tabs-armed), so with all
   JS absent the shipped component styling — filled teal active tab — stands
   untouched, at identical geometry.

   Indicator looks (Studio knob → body class set in apply()):
     body.rbs-tabs-fill        the shipped teal block, now sliding (default)
     body.rbs-tabs-underline   2px hairline riding a baseline rule
     body.rbs-tabs-pill        rounded pill gliding behind the label
   ========================================================================== */

/* --------------------------------------------------------------------------
   THE PERSISTENT OBJECT
   One element, translated between equal-width tab cells — never rebuilt,
   never faded, so selection reads as a thing that travels, not a repaint.
   320ms is a knob; morph curve per the corpus. Interruptible: a mid-flight
   retarget folds toward the new tab from wherever it is.
   -------------------------------------------------------------------------- */

.rbs-tabs-ind { display: none; }

.rb-tabs[data-rbs-tabs-armed] {
  position: relative;
  isolation: isolate;           /* keep the object's stacking local */
}

.rb-tabs[data-rbs-tabs-armed] .rbs-tabs-ind {
  display: block;
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 0;                      /* JS sets width + translateX in px */
  pointer-events: none;
  will-change: transform;
  transition: transform var(--rbs-tabs-dur, 320ms) var(--rb-sys-ease-morph);
}

/* Label and dot ride above the object; the tab's own muted ground stays
   below it. (Positioned z1 > positioned z-auto > element background.) */
.rb-tabs[data-rbs-tabs-armed] .rb-tabs__label,
.rb-tabs[data-rbs-tabs-armed] .rb-tabs__marker {
  position: relative;
  z-index: 1;
}

/* The static active fill is retired — the traveling object IS that fill.
   Same muted ground on every cell so nothing else changes when it moves. */
.rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab[aria-selected="true"] {
  background: var(--rb-sys-bg-muted);
}

/* Labels crossfade colour under the arriving object — small UI, swift. */
.rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab {
  transition:
    background-color var(--rb-sys-duration-2) var(--rb-sys-ease-swift),
    color var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
}

@media (hover: hover) and (pointer: fine) {
  .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab:not([aria-selected="true"]):hover {
    color: var(--rb-sys-fg-primary);
  }
}

/* JS toggles this around programmatic placement (first paint, resizes) so
   the object only ever animates a real selection change. */
.rb-tabs[data-rbs-tabs-armed] .rbs-tabs-ind.is-rbs-noanim { transition: none; }

/* Scroll variant: scroll owns the object's position frame by frame. */
.rb-tabs[data-rbs-tabs-armed].is-rbs-scrub .rbs-tabs-ind { transition: none; }

/* Reduced motion (essential): keep the colour crossfade, drop the travel. */
body[data-rbs-motion-level="essential"]
  .rb-tabs[data-rbs-tabs-armed] .rbs-tabs-ind { transition: none; }

/* --- Look 1 · FILL (default, and any unrecognised body class) ------------- */
.rbs-tabs-ind__box {
  position: absolute;
  inset: 0;
  background: var(--rb-ref-teal-400);
}

/* --- Look 2 · UNDERLINE ---------------------------------------------------- */
body.rbs-tabs-underline .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab,
body.rbs-tabs-underline .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab[aria-selected="true"] {
  background: transparent;
}
body.rbs-tabs-underline .rb-tabs[data-rbs-tabs-armed] {
  box-shadow: inset 0 -1px 0 var(--rb-sys-border-subtle);   /* baseline rule */
}
body.rbs-tabs-underline .rb-tabs[data-rbs-tabs-armed] .rbs-tabs-ind__box {
  inset: auto 0 0 0;
  height: var(--rb-ref-border-medium);
  background: var(--rb-ref-teal-500);
}
/* No teal ground to sit on — the dot turns accent. */
body.rbs-tabs-underline .rb-tabs[data-rbs-tabs-armed] .rb-tabs__marker {
  background: var(--rb-ref-teal-500);
}

/* --- Look 3 · PILL --------------------------------------------------------- */
body.rbs-tabs-pill .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab,
body.rbs-tabs-pill .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab[aria-selected="true"] {
  background: transparent;
}
body.rbs-tabs-pill .rb-tabs[data-rbs-tabs-armed] .rbs-tabs-ind__box {
  inset: 6px 4px;
  border-radius: var(--rb-ref-radius-full);
  background: var(--rb-ref-teal-400);
}

/* --------------------------------------------------------------------------
   MARKER DOT — springs in on the arriving tab, timed to land as the object
   settles. `backwards` holds it invisible through the delay. Restarts are
   safe: the animation only replays when aria-selected actually flips.
   Never from 0 — from 0.5 with a ~1.15 overshoot.
   -------------------------------------------------------------------------- */

.rb-tabs[data-rbs-tabs-armed] .rb-tabs__marker {
  transition: opacity var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
}

body[data-rbs-motion-level="authored"]
  .rb-tabs[data-rbs-tabs-armed] .rb-tabs__tab[aria-selected="true"] .rb-tabs__marker {
  animation: rbs-tabs-dot
    calc(var(--rbs-tabs-dur, 320ms) * 0.8)
    var(--rb-sys-ease-swift)
    calc(var(--rbs-tabs-dur, 320ms) * 0.4)
    backwards;
}

@keyframes rbs-tabs-dot {
  from { transform: scale(0.5);  opacity: 0; }
  60%  { transform: scale(1.15); opacity: 1; }
  to   { transform: scale(1);    opacity: 1; }
}

/* --------------------------------------------------------------------------
   PANEL CHOREOGRAPHY
   main.js hides the outgoing panel instantly; the module immediately re-shows
   it as an overlay (`display:grid !important` outbids base's [hidden]) for a
   120ms fade while the incoming panel rises 8px underneath, staggered. The
   viewport's block-size is measured, eased between the two states, and unset
   — the one sanctioned layout animation in this area. Exits faster than
   enters. All transitions retarget mid-flight.
   -------------------------------------------------------------------------- */

/* Outgoing — overlaid in place, pointer-dead, fading. */
.rb-surfaces-tabbed__panel.is-rbs-exit {
  display: grid !important;      /* outranks base [hidden]{display:none!important} */
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  pointer-events: none;
  transition: opacity 120ms var(--rb-sys-ease-swift);
}
.rb-surfaces-tabbed__panel.is-rbs-exit-go { opacity: 0; }

/* Incoming — planted transparent (and 8px low when authored), then released. */
.rb-surfaces-tabbed__panel.is-rbs-enter {
  opacity: 0;
  transition: none;
}
body[data-rbs-motion-level="authored"] .rb-surfaces-tabbed__panel.is-rbs-enter {
  transform: translateY(8px);
}
.rb-surfaces-tabbed__panel.is-rbs-enter-go {
  opacity: 1;
  transform: none;
  transition:
    opacity   var(--rbs-tabs-dur, 320ms) var(--rb-sys-ease-swift) var(--rbs-tabs-stagger, 60ms),
    transform var(--rbs-tabs-dur, 320ms) var(--rb-sys-ease-swift) var(--rbs-tabs-stagger, 60ms);
}

/* Height ease — inline block-size is set by JS, transitioned, then unset. */
.rb-surfaces-tabbed__viewport.is-rbs-h {
  overflow: clip;
  transition: block-size var(--rbs-tabs-dur, 320ms) var(--rb-sys-ease-morph);
}

/* --------------------------------------------------------------------------
   SCROLL VARIANT — sticky scrub
   JS appends a runway spacer (3 × the per-tab knob) after the container and
   flags the section; the container pins while the section provides travel.
   The sticky top is computed by JS so tall content pins with its bottom in
   view rather than its heading. Engaged only at the two-column layout and
   only while motion is authored — everywhere else the variant behaves as
   plain click, and with JS absent none of this exists.
   -------------------------------------------------------------------------- */

body[data-rbs-tabs="scroll"] .rb-surfaces-tabbed.is-rbs-tabs-scroll > .rb-container {
  position: sticky;
  top: var(--rbs-tabs-sticky-top, 96px);
}

.rbs-tabs-runway {
  block-size: calc(var(--rbs-tabs-runway, 80vh) * 3);
  pointer-events: none;
}
