/* nearswaps motion layer (spec part B rule 7). One stylesheet plus assets/motion.js; nothing inline.
   Timings come from brand.css: --ns-t-touch 120ms, --ns-t-panel 240ms, --ns-t-page 360ms, --ns-ease
   cubic-bezier(0.2, 0.8, 0.2, 1). Nothing bounces. prefers-reduced-motion drops every slide and scale;
   the price flash stays, because it carries information.

   HOW A PAGE ADOPTS IT
     <link rel="stylesheet" href="assets/motion.css">          after brand.css
     <script src="assets/motion.js" defer></script>            a plain script (not a module); sets window.nsMotion

   CLASS NAMES (add them to existing elements; none of them changes layout)
     .ns-press            Any button or tappable row: 120 ms, scales to 98% while pressed, the hairline lifts on hover.
     .ns-pill             A chip or pill (collection chips, amount presets, filters): .ns-press plus a 120 ms colour
                          change when it becomes selected (aria-pressed="true", aria-selected="true" or .is-on).
     .ns-tabrow           A row of tabs or a segmented control. Its children are the tabs; the selected one carries
                          aria-selected="true", aria-pressed="true", aria-current or .is-on. motion.js adds one
                          .ns-tabrow-ink bar that slides to the selected tab in 240 ms (re-measured on change and resize).
                          Add .ns-tabrow--fill for a filled pill behind the tab instead of an underline.
     .ns-panel            A panel that is shown and hidden (Trade / Auto orders / 1-click, a sheet's steps, a route view).
                          Each time it becomes visible (the hidden attribute removed, display none to block, or
                          nsMotion.panel(el)) it cross-fades in with a 12 px slide over 240 ms. The chart never gets it.
     .ns-panel--left      The same, sliding from the left (going back).
     .ns-sheet            A bottom sheet on phones (the Terminal's trade panel, the market's buy sheet): slides up
                          240 ms when it gets .is-open; .ns-sheet-scrim is its backdrop (fades).
     [data-ns-flash]      An element showing a price or an amount. Set its text as usual; motion.js flashes the digits
                          that changed, mint when the number went up, red when it went down, for 600 ms. Nothing else
                          moves. Mono and tabular already come from .num in brand.css.
     .ns-pending          The old number dims to 60% while a new quote is on its way (no spinner). Remove it when the
                          new value lands.
     .ns-tabrow--accent   The ink is the mint underline (the Terminal's activity tabs).
     .ns-vt-token, .ns-vt-price
                          Shared elements for page moves: the token pill and the price travel between pages (for
                          example the swap card to the Terminal) in 360 ms with the View Transitions API, the rest of
                          the page cross-fades. One of each per page. Browsers without the API just load the page.

   JAVASCRIPT (window.nsMotion, all optional)
     nsMotion.panel(el, { back })            replay a panel's entrance (when content is swapped without hiding it)
     nsMotion.go(updateFn)                   run a same-page view change (pushState routes) inside a 360 ms view transition
     nsMotion.flash(el, newText)             set text and flash the changed digits (what [data-ns-flash] does by itself)
     nsMotion.countUp(el, from, to, { ms, format })   the fill moment: a balance counts up over 500 ms
     nsMotion.haptic()                       one short vibration on phones that allow it (fills only)
     nsMotion.reduced                        true when the visitor asked for reduced motion
     nsMotion.refresh(root)                  re-scan for .ns-tabrow and [data-ns-flash] after a large re-render
*/

/* ---------- touch: buttons, rows, pills ---------- */
.ns-press,.ns-pill{
  transition:transform var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             border-color var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             background-color var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             color var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             box-shadow var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             opacity var(--ns-t-touch,120ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1));
  -webkit-tap-highlight-color:transparent;
}
.ns-press:active:not(:disabled):not([aria-disabled="true"]),
.ns-pill:active:not(:disabled):not([aria-disabled="true"]),
.ns-press.is-pressed,.ns-pill.is-pressed{transform:scale(0.98);}
@media (hover:hover){
  .ns-press:hover:not(:disabled),.ns-pill:hover:not(:disabled){border-color:var(--ns-line-strong,rgb(var(--ns-fg-rgb) / 0.14));}
}

/* ---------- tabs: one ink bar that slides to the selected tab ---------- */
.ns-tabrow{position:relative;}
.ns-tabrow > .ns-tabrow-ink{
  position:absolute;left:0;bottom:0;height:2px;width:0;border-radius:2px;background:var(--ns-ink,var(--ns-ink));
  pointer-events:none;transform:translateX(0);opacity:0;
  transition:transform var(--ns-t-panel,240ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             width var(--ns-t-panel,240ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),
             opacity var(--ns-t-touch,120ms) linear;
}
.ns-tabrow > .ns-tabrow-ink.is-on{opacity:1;}
.ns-tabrow > .ns-tabrow-ink.is-instant{transition:none;}
.ns-tabrow--fill > .ns-tabrow-ink{top:var(--ns-ink-top,4px);bottom:auto;height:var(--ns-ink-h,calc(100% - 8px));border-radius:var(--ns-r-pill,999px);background:rgb(var(--ns-fg-rgb) / 0.08);z-index:0;}
.ns-tabrow--fill > :not(.ns-tabrow-ink){position:relative;z-index:1;}

/* Rows adopted from the pages (motion.js ADOPT): once the ink is placed it carries the selected look, so the
   page's own fill or underline on the selected tab steps aside; without the ink (no script) the page's look stays. */
.ns-tabrow--fill.has-ink > :not(.ns-tabrow-ink){background:transparent !important;box-shadow:none !important;}
.ns-tabrow--accent.has-ink > :not(.ns-tabrow-ink){border-bottom-color:transparent !important;}
.ns-tabrow--accent > .ns-tabrow-ink{background:var(--ns-mint,var(--ns-mint));}

/* ---------- panels: 240 ms cross-fade with a 12 px slide ---------- */
@keyframes ns-panel-in{from{opacity:0;transform:translateX(12px);}to{opacity:1;transform:none;}}
@keyframes ns-panel-in-left{from{opacity:0;transform:translateX(-12px);}to{opacity:1;transform:none;}}
@keyframes ns-fade-in{from{opacity:0;}to{opacity:1;}}
.ns-panel:not([hidden]){animation:ns-panel-in var(--ns-t-panel,240ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)) both;}
.ns-panel--left:not([hidden]){animation-name:ns-panel-in-left;}
.ns-panel.is-replay{animation:none;}
.ns-panel[hidden]{display:none !important;}

/* ---------- bottom sheet ---------- */
.ns-sheet{transform:translateY(100%);transition:transform var(--ns-t-panel,240ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),visibility 0s linear var(--ns-t-panel,240ms);visibility:hidden;}
.ns-sheet.is-open{transform:none;visibility:visible;transition:transform var(--ns-t-panel,240ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)),visibility 0s;}
.ns-sheet-scrim{opacity:0;pointer-events:none;transition:opacity var(--ns-t-panel,240ms) linear;}
.ns-sheet-scrim.is-open{opacity:1;pointer-events:auto;}

/* ---------- numbers: the changed digits flash for 600 ms ---------- */
@keyframes ns-flash-up{0%,40%{color:var(--ns-mint,var(--ns-mint));}100%{color:inherit;}}
@keyframes ns-flash-down{0%,40%{color:var(--ns-red,var(--ns-red));}100%{color:inherit;}}
.ns-d{font:inherit;}
.ns-d.up{animation:ns-flash-up 600ms linear both;}
.ns-d.down{animation:ns-flash-down 600ms linear both;}
.ns-pending{opacity:0.6;transition:opacity var(--ns-t-touch,120ms) linear;}
[data-ns-flash]{transition:opacity var(--ns-t-touch,120ms) linear;}

/* ---------- page moves: View Transitions (same-origin navigations and nsMotion.go) ---------- */
@view-transition{navigation:auto;}
::view-transition-group(*){animation-duration:var(--ns-t-page,360ms);animation-timing-function:var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1));}
::view-transition-old(root){animation:ns-vt-out var(--ns-t-page,360ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)) both;}
::view-transition-new(root){animation:ns-vt-in var(--ns-t-page,360ms) var(--ns-ease,cubic-bezier(0.2,0.8,0.2,1)) both;}
@keyframes ns-vt-out{to{opacity:0;}}
@keyframes ns-vt-in{from{opacity:0;}}
.ns-vt-token{view-transition-name:ns-token;}
.ns-vt-price{view-transition-name:ns-price;}

/* ---------- the swap page's trending ticker (assets/swap.css lays it out) ---------- */
@keyframes sw-trend{from{transform:translateX(0);}to{transform:translateX(-50%);}}
.trend-track{animation:sw-trend var(--dur,60s) linear infinite;}
.trend:hover .trend-track,.trend:focus-within .trend-track{animation-play-state:paused;}

/* ---------- reduced motion: no slide, no scale, no travel; colour and the price flash stay ---------- */
@media (prefers-reduced-motion:reduce){
  .ns-press,.ns-pill{transition:border-color var(--ns-t-touch,120ms) linear,background-color var(--ns-t-touch,120ms) linear,color var(--ns-t-touch,120ms) linear;}
  .ns-press:active,.ns-pill:active,.ns-press.is-pressed,.ns-pill.is-pressed{transform:none !important;}
  .ns-tabrow > .ns-tabrow-ink{transition:none;}
  .ns-panel:not([hidden]),.ns-panel--left:not([hidden]){animation:none;}
  .ns-sheet,.ns-sheet.is-open{transition:none;}
  .ns-sheet-scrim{transition:none;}
  @view-transition{navigation:none;}
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none !important;}
  .ns-vt-token,.ns-vt-price{view-transition-name:none;}
  .trend-track{animation:none;}
}
