/* Storixa — motion layer.
   Loaded last so it composes with every surface above it instead of overriding it.
   Grammar: motion explains state, direction, causality or attention. Nothing else.
   Reduced motion is handled by the global .01ms switch in styles.css, so every rule
   here keeps meaning once its timing is removed. */

:root{
  /* Duration scale. 150ms is the responsiveness baseline. */
  --m-fast:150ms;      /* press, hover, focus */
  --m-base:200ms;      /* success flash, small reveal */
  --m-slow:250ms;      /* menus, popovers, small modals */
  --m-panel:300ms;     /* drawers, accordions, layout changes */
  --m-page:400ms;      /* full-section transitions */

  /* Decelerate out. Nothing here bounces. */
  --m-ease:cubic-bezier(.2,0,0,1);
  --m-ease-soft:cubic-bezier(.33,0,.15,1);
}

/* ─────────────────────────────────────────────────────────────────────────────
   1 · Press feedback.
   The standalone `scale` property composes with existing hover `transform`
   values instead of replacing them, so crafted lifts survive untouched.
   ───────────────────────────────────────────────────────────────────────────── */
:is(button,a,summary,[role="tab"],[role="button"]){
  -webkit-tap-highlight-color:transparent;
  transition-property:scale,transform,opacity,background-color,border-color,box-shadow,color;
  transition-duration:var(--m-fast);
  transition-timing-function:var(--m-ease);
}
:is(button,a,summary,[role="tab"],[role="button"]):active{scale:.97}
/* Large surfaces shrink less: 3% on a 245px card reads as a flinch. */
:is(.related-card,.capability-cta,.capabilities-main-cta,.v5-handoff):active{scale:.99}

/* ─────────────────────────────────────────────────────────────────────────────
   2 · Overlays. A dialog enters from the edge nearest its trigger, then settles.
   `allow-discrete` lets display/overlay animate so close is not a hard cut.
   ───────────────────────────────────────────────────────────────────────────── */
dialog{
  opacity:0;
  transform:translateY(10px) scale(.985);
  transition:
    opacity var(--m-slow) var(--m-ease),
    transform var(--m-slow) var(--m-ease),
    display var(--m-slow) allow-discrete,
    overlay var(--m-slow) allow-discrete;
}
dialog[open]{opacity:1;transform:translateY(0) scale(1)}
@starting-style{
  dialog[open]{opacity:0;transform:translateY(10px) scale(.985)}
}
dialog::backdrop{
  opacity:0;
  transition:
    opacity var(--m-slow) var(--m-ease),
    display var(--m-slow) allow-discrete,
    overlay var(--m-slow) allow-discrete;
}
dialog[open]::backdrop{opacity:1}
@starting-style{
  dialog[open]::backdrop{opacity:0}
}
/* Exits run shorter than entrances. */
dialog:not([open]){transition-duration:var(--m-fast),var(--m-fast),var(--m-fast),var(--m-fast)}
dialog:not([open])::backdrop{transition-duration:var(--m-fast),var(--m-fast),var(--m-fast)}

/* ─────────────────────────────────────────────────────────────────────────────
   3 · Navigation. The dropdown belongs to its summary; the mobile menu belongs
   to the button that opened it. Both fall from the trigger.
   ───────────────────────────────────────────────────────────────────────────── */
.nav-dropdown,
.site-header .nav-dropdown{
  opacity:0;
  transform:translateX(-50%) translateY(-6px) scale(.985);
  transform-origin:top center;
  transition:
    opacity var(--m-slow) var(--m-ease),
    transform var(--m-slow) var(--m-ease),
    display var(--m-slow) allow-discrete;
}
.nav-details[open] .nav-dropdown,
.site-header .nav-details[open] .nav-dropdown{
  opacity:1;
  transform:translateX(-50%) translateY(0) scale(1);
}
@starting-style{
  .nav-details[open] .nav-dropdown,
  .site-header .nav-details[open] .nav-dropdown{
    opacity:0;
    transform:translateX(-50%) translateY(-6px) scale(.985);
  }
}

.mobile-menu{
  opacity:0;
  transform:translateY(-8px);
  transition:
    opacity var(--m-slow) var(--m-ease),
    transform var(--m-slow) var(--m-ease),
    display var(--m-slow) allow-discrete;
}
.mobile-menu:not([hidden]){opacity:1;transform:translateY(0)}
@starting-style{
  .mobile-menu:not([hidden]){opacity:0;transform:translateY(-8px)}
}

/* ─────────────────────────────────────────────────────────────────────────────
   4 · Disclosure content. `hidden` toggles cannot be transitioned, so content
   that swaps in re-enters. This is the cheapest honest reveal for tabs, wizard
   steps and playground modes.
   ───────────────────────────────────────────────────────────────────────────── */
@keyframes panel-rise{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:translateY(0)}
}
.v5-play-mode:not([hidden]),
.v5-wizard-step:not([hidden]),
[data-step-panel]:not([hidden]){
  animation:panel-rise var(--m-panel) var(--m-ease) both;
}

/* ─────────────────────────────────────────────────────────────────────────────
   5 · Accordion. Heights animate through grid-template-rows 0fr → 1fr, which is
   the one height transition that does not force a layout thrash per frame.
   ───────────────────────────────────────────────────────────────────────────── */
.faq-body{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows var(--m-panel) var(--m-ease);
}
.faq-items details[open] .faq-body{grid-template-rows:1fr}
.faq-clip{overflow:hidden;min-height:0}
.faq-items details p{opacity:0;transition:opacity var(--m-base) var(--m-ease) 40ms}
.faq-items details[open] p{opacity:1}
/* The plus rotates into a minus: the glyph changes, not only the state. */
.faq-plus{transition:transform var(--m-panel) var(--m-ease),background-color var(--m-fast) var(--m-ease)}
.faq-items details[open] .faq-plus{transform:rotate(45deg)}

/* ─────────────────────────────────────────────────────────────────────────────
   6 · Selection and state change. Selection is not a colour swap alone: the
   chosen tab lifts and its marker fills.
   ───────────────────────────────────────────────────────────────────────────── */
.v5-play-tabs button[aria-selected="true"],
.mobile-demo-switcher button.active,
.demo-toolbar button[aria-selected="true"]{
  transition:background-color var(--m-fast) var(--m-ease),color var(--m-fast) var(--m-ease),box-shadow var(--m-slow) var(--m-ease),scale var(--m-fast) var(--m-ease);
}
.experience-step-nav button[aria-selected="true"]{animation:panel-rise var(--m-slow) var(--m-ease) both}

/* Feedback that a demo action registered, and that it changed nothing real. */
@keyframes confirm-settle{
  0%{box-shadow:inset 0 0 0 1px rgba(63,74,60,0),0 0 0 0 rgba(63,74,60,.24)}
  42%{box-shadow:inset 0 0 0 1px rgba(63,74,60,.42),0 0 0 6px rgba(63,74,60,.13)}
  100%{box-shadow:inset 0 0 0 1px rgba(63,74,60,.18),0 0 0 0 rgba(63,74,60,0)}
}
.v5-inline-status:not(:empty),
.growth-review-label.is-confirmed{
  animation:confirm-settle var(--m-page) var(--m-ease-soft) 1;
}

/* ─────────────────────────────────────────────────────────────────────────────
   7 · Waiting. A fixture that answers instantly is less believable than one
   that thinks. The dots are the interface staying accountable, not a lie about
   how slow anything is.
   ───────────────────────────────────────────────────────────────────────────── */
@keyframes draft-dot{
  0%,80%,100%{opacity:.28;transform:translateY(0) scale(.86)}
  40%{opacity:1;transform:translateY(-2px) scale(1)}
}
.v5-drafting{display:inline-flex;align-items:center;gap:5px;min-height:18px}
.v5-drafting i{
  width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.28;
  animation:draft-dot 1.1s var(--m-ease-soft) infinite;
}
.v5-drafting i:nth-child(2){animation-delay:.14s}
.v5-drafting i:nth-child(3){animation-delay:.28s}
/* The bubble holds its final width so the reply does not jump the layout. */
.v5-chat-bubble.seller.is-drafting,
.v5-grow-proposal.is-drafting{opacity:.72}

/* ─────────────────────────────────────────────────────────────────────────────
   8 · Section arrival. Targets are added only by the observer in storixa-v5.js,
   and only once the enhancement class is present, so a JS failure leaves the
   page intact. Cards inside a section are not staggered: the attention cost
   would repeat on every scroll.
   The hidden state carries no transition, so the enhancement class hides in the
   first frame instead of animating visible -> hidden on load. Only the reveal
   transitions, and the end state drops the transform, so no section keeps a
   containing block or a promoted layer for the visit.
   ───────────────────────────────────────────────────────────────────────────── */
.v5-animate-ready .v5-reveal{
  opacity:0;
  transform:translateY(14px);
}
.v5-animate-ready .v5-reveal.v5-visible{
  opacity:1;
  transform:none;
  transition:opacity var(--m-page) var(--m-ease),transform var(--m-page) var(--m-ease);
}
/* Shorter travel on phones, where the viewport shows less of the next section. */
@media(max-width:700px){
  .v5-animate-ready .v5-reveal{transform:translateY(8px)}
}

/* ─────────────────────────────────────────────────────────────────────────────
   9 · Bounded ambient loops.
   Anything moving on its own indefinitely needs a pause control or an end.
   These stop; the states they indicated remain legible without them.
   ───────────────────────────────────────────────────────────────────────────── */
/* Loops are bounded where each animation is declared, so there is one truth per
   loop: soft-pulse 4, pulse 6, connection-dash 3. None run indefinitely. */

/* ─────────────────────────────────────────────────────────────────────────────
   10 · Focus. The ring stays instant; it is a state, not a transition.
   ───────────────────────────────────────────────────────────────────────────── */
:is(button,a,summary,input,select,textarea,[tabindex]):focus-visible{
  transition-property:scale,transform,background-color,border-color,box-shadow,color;
}

/* ─────────────────────────────────────────────────────────────────────────────
   11 · Reduced motion. The global switch removes duration; these rules keep the
   meaning. Spatial travel becomes a fade, and nothing is lost that mattered.
   ───────────────────────────────────────────────────────────────────────────── */
@media(prefers-reduced-motion:reduce){
  .v5-animate-ready .v5-reveal{opacity:1!important;transform:none!important}
  .v5-play-mode:not([hidden]),
  .v5-wizard-step:not([hidden]),
  [data-step-panel]:not([hidden]),
  .experience-step-nav button[aria-selected="true"],
  .v5-inline-status:not(:empty){animation:none!important}
  .faq-body{transition:none!important;grid-template-rows:1fr!important}
  .faq-items details:not([open]) .faq-body{grid-template-rows:0fr!important}
  .faq-items details p{opacity:1!important}
  dialog,.nav-dropdown,.mobile-menu{transition:none!important}
  dialog:not([open]),.nav-dropdown,.mobile-menu{opacity:1!important;transform:none!important}
  .nav-dropdown,.site-header .nav-dropdown{transform:translateX(-50%)!important}
  :is(button,a,summary,[role="tab"]):active{scale:1!important}
  .v5-drafting i{animation:none!important;opacity:.6}
}
