/* ==========================================================================
   IX · FAQ — how an answer opens, and how much ground it claims.

     body[data-rbs-faq="settle"]  two-stage settle: panel unfolds, text rises
     body[data-rbs-faq="ledger"]  + mono index column, hairline rail, teal rule
     body[data-rbs-faq="spread"]  + open row gains a warm sand inset

   js/main.js stays the state owner (aria-expanded / data-open / hidden).
   js/areas/faq.js only re-times how `hidden` lands so height can animate:
   it arms the machinery below with `data-rbs-faq-armed` on the accordion
   root, mirrors the open state onto `.is-rbs-open` (added after a forced
   reflow so the 0fr start is actually computed), and sets `hidden` on close
   only after the exit transition ends. Without that JS the attribute never
   appears and the accordion is workspace 01: instant, honest, zero motion.

   The height animation is grid-template-rows 0fr ⇄ 1fr — a deliberate,
   sanctioned exception to the transform/opacity-only rule, because it is the
   one primitive that animates an auto-height disclosure without measuring.
   The `hidden` attr always wins over the grid display, so a dead JS pipeline
   can never strand a visually-collapsed-but-technically-visible panel.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TIMING TABLE — one place, so the reduced-motion override can't lose a
   specificity fight with the open-state rules below.
     open   editorial reveal → knob × global tempo
     close  320ms swift — exits faster than enters
     text   second stage: 320ms, 150ms behind the panel
   -------------------------------------------------------------------------- */
[data-rbs-faq-armed] {
  --_faq-open:     calc(var(--rbs-faq-dur, 520ms) * var(--rbs-motion-scale, 1));
  --_faq-close:    var(--rb-sys-duration-3);
  --_faq-delay:    calc(150ms * var(--rbs-motion-scale, 1));
  --_faq-rise:     8px;
  --_faq-fade-in:  var(--rb-sys-duration-3);
  --_faq-fade-out: var(--rb-sys-duration-1);
}

/* Reduced motion (kernel caps 'authored' to 'essential'): the height snaps,
   the answer still greets you with a quiet fade — gentler, never dead. */
body[data-rbs-motion-level="essential"] [data-rbs-faq-armed] {
  --_faq-open:     0s;
  --_faq-close:    0s;
  --_faq-delay:    0s;
  --_faq-rise:     0px;
  --_faq-fade-in:  var(--rb-sys-duration-2);
  --_faq-fade-out: var(--rb-sys-duration-1);
}

/* --------------------------------------------------------------------------
   MACHINERY — all three variants share this motion.
   -------------------------------------------------------------------------- */

/* Base = the exit: leaving .is-rbs-open retargets onto this transition. */
[data-rbs-faq-armed] .rb-accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--_faq-close) var(--rb-sys-ease-swift);
}

/* `hidden` must keep winning — it is the no-JS truth and the settled state. */
[data-rbs-faq-armed] .rb-accordion__panel[hidden] { display: none; }

/* The one child the 0fr row clips against. */
[data-rbs-faq-armed] .rb-accordion__panel-inner {
  min-height: 0;
  overflow: hidden;
}

[data-rbs-faq-armed] .rb-accordion__item.is-rbs-open .rb-accordion__panel {
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--_faq-open) var(--rbs-ease-reveal, var(--rb-sys-ease-expo));
}

/* Second stage: the answer rises into the opened room, one beat behind.
   On close it drops out fast and undelayed, so the folding row is empty
   before the lid comes down. */
[data-rbs-faq-armed] .rb-accordion__answer {
  opacity: 0;
  transform: translateY(var(--_faq-rise));
  transition:
    opacity   var(--_faq-fade-out) var(--rb-sys-ease-swift),
    transform var(--_faq-fade-out) var(--rb-sys-ease-swift);
}

[data-rbs-faq-armed] .rb-accordion__item.is-rbs-open .rb-accordion__answer {
  opacity: 1;
  transform: none;
  transition:
    opacity   var(--_faq-fade-in) var(--rb-sys-ease-swift) var(--_faq-delay),
    transform var(--_faq-fade-in) var(--rb-sys-ease-swift) var(--_faq-delay);
}

/* The plus/minus turns on the panel's beat, not the component's 220ms. */
[data-rbs-faq-armed] .rb-accordion__icon::before,
[data-rbs-faq-armed] .rb-accordion__icon::after {
  transition-duration: var(--rb-sys-duration-3);
  transition-timing-function: var(--rb-sys-ease-swift);
}

/* --------------------------------------------------------------------------
   HOVER KNOB — None | Tint | Slide, set on the section by apply().
   Pure feedback: runs at every motion level. Fine pointers only.
   -------------------------------------------------------------------------- */
@media (hover: hover) and (pointer: fine) {
  .rb-faq[data-rbs-faq-hover="tint"] .rb-accordion__trigger {
    transition: color var(--rb-sys-duration-2) ease;
  }
  .rb-faq[data-rbs-faq-hover="tint"] .rb-accordion__trigger:hover {
    color: var(--rb-sys-fg-brand);
  }

  .rb-faq[data-rbs-faq-hover="slide"] .rb-accordion__question {
    transition: transform var(--rb-sys-duration-2) ease;
  }
  .rb-faq[data-rbs-faq-hover="slide"] .rb-accordion__trigger:hover .rb-accordion__question {
    transform: translateX(4px);
  }
}

/* --------------------------------------------------------------------------
   LEDGER — a documentary index. Mono row numbers, questions set against a
   vertical hairline, the open row's rail signed in brand teal, answers
   indented onto the question's own column.
   -------------------------------------------------------------------------- */

/* The index column is real estate all variants reserve nothing for: the
   numbers ship in the markup but stay dark until this variant asks. */
.rb-faq { --rbs-faq-col: 40px; }
@media (min-width: 768px) { .rb-faq { --rbs-faq-col: 56px; } }
.rb-faq__index { display: none; }

body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__trigger {
  display: grid;
  grid-template-columns: var(--rbs-faq-col) minmax(0, 1fr) auto;
  column-gap: var(--rb-ref-space-4);
  align-items: center;
}

body[data-rbs-faq="ledger"] .rb-faq .rb-faq__index {
  display: block;
  font-family: var(--rb-sys-font-label);
  font-size: var(--rb-sys-text-l1-size);
  line-height: var(--rb-sys-text-l1-leading);
  letter-spacing: var(--rb-sys-text-l1-tracking);
  font-weight: var(--rb-ref-weight-regular);
  color: var(--rb-sys-fg-muted);
  transition: color var(--rb-sys-duration-2) ease;
}

body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__item[data-open="true"] .rb-faq__index {
  color: var(--rb-sys-fg-brand);
}

/* The rail: one continuous hairline past trigger and answer alike, drawn on
   the item so the trigger/panel joint can't gap it. It stretches with the
   grid-rows animation for free, and stops above the row's 32px of air. */
body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__item { position: relative; }

body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__item::before {
  content: "";
  position: absolute;
  inset-inline-start: var(--rbs-faq-col);
  inset-block: 0 var(--rb-ref-space-7);
  width: var(--rb-ref-border-hairline);
  background: var(--rb-sys-border-rule);
  transition: background-color var(--rb-sys-duration-2) ease;
  pointer-events: none;
}

body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__item[data-open="true"]::before {
  background: var(--rb-sys-border-brand);
}

/* Answer indents onto the question's column: rail + the same 16px gap. */
body[data-rbs-faq="ledger"] .rb-faq .rb-accordion__answer {
  margin-inline-start: calc(var(--rbs-faq-col) + var(--rb-ref-space-4));
}

/* --------------------------------------------------------------------------
   SPREAD — the open row claims its ground. A sand-200 inset fades in and
   eases outward past the text column, faking the padding ease-in with a
   transform-only pseudo-element (the content itself never moves, so the
   height animation stays honest). Square corners; the hairlines stay on top.
   Bleed is capped below 1200 so it can never out-reach the page gutter.
   -------------------------------------------------------------------------- */
body[data-rbs-faq="spread"] .rb-faq { --rbs-faq-bleed: var(--rb-ref-space-3); }
@media (min-width: 1200px) {
  body[data-rbs-faq="spread"] .rb-faq { --rbs-faq-bleed: var(--rb-ref-space-6); }
}

/* isolation: without its own stacking context the negative-z tint would sink
   behind the section's sand ground and never paint. The hairlines live on the
   item's border box, above the pseudo's padding-box inset, so they stay
   crisp on top of the tint. */
body[data-rbs-faq="spread"] .rb-faq .rb-accordion__item {
  position: relative;
  isolation: isolate;
}

body[data-rbs-faq="spread"] .rb-faq .rb-accordion__item::before {
  content: "";
  position: absolute;
  inset: 0 calc(-1 * var(--rbs-faq-bleed)) var(--rb-ref-space-7);
  z-index: -1;
  background: var(--rb-ref-sand-200);
  border-radius: var(--rb-ref-radius-none);
  opacity: 0;
  transform: scaleX(0.98);
  pointer-events: none;
  /* base = exit: 220ms, faster than the 320ms arrival below */
  transition:
    opacity   var(--rb-sys-duration-2) var(--rb-sys-ease-swift),
    transform var(--rb-sys-duration-2) var(--rb-sys-ease-swift);
}

body[data-rbs-faq="spread"] .rb-faq .rb-accordion__item[data-open="true"]::before {
  opacity: 1;
  transform: none;
  transition-duration: var(--rb-sys-duration-3), var(--rb-sys-duration-3);
}
