/* KeepEye motion layer: how things open, close, move and respond.
   Short and quiet on purpose: 120–260 ms, ease-out going in, a faster ease going out, no bounce.
   Loaded after neo.css. Exits are driven by app.js (it sets [data-leaving], waits, then sets [hidden]).
   Everything here switches off under prefers-reduced-motion (bottom of the file). */

:root{
  --ke-out:cubic-bezier(.2,.75,.25,1);
  --ke-in:cubic-bezier(.45,0,.8,.4);
  --ke-move:cubic-bezier(.3,.7,.3,1);
}
@property --p{syntax:"<percentage>";inherits:false;initial-value:50%}
@property --s{syntax:"<number>";inherits:false;initial-value:0}
@property --ax{syntax:"<length-percentage>";inherits:true;initial-value:50%}

/* ---------- controls: one consistent response to hover and press ---------- */
button,.pill,.tool,.ibtn,.sbtn,.wallet,.tp-act,.tp-back,.tp-copy,.close,.pfpaste,.pfgo,.swc-tok,.swc-set,.shl-net,.soc,.pack,.slot,.links a,
.hrow,.mcard,.rd-card,.prf-row,.ow-i,.ddp a,.tmp button,.mm a,.disc-chip,.cotok-r,.swp-it,.cexchip,.adx,.morebtn,.linkbtn,.fg ul a,.lg-toc a,.tp-crumbs a{
  transition:color .15s ease,background-color .15s ease,border-color .15s ease,box-shadow .2s ease,opacity .15s ease,filter .15s ease,transform .16s var(--ke-out)}
.pill:active,.tool:active,.ibtn:active,.sbtn:active,.wallet:active,.tp-act:active,.tp-back:active,.close:active,.pfpaste:active,.swc-tok:active,.swc-set:active,
.shl-net:active,.soc:active,.pack:active,.morebtn:active,.adx:active,.disc-chip:active,.vt button:active,.tabs button:active,.tp-tabs button:active,.presets button:active,.mm a:active{transform:scale(.96)}
.seg button:active,.tseg button:active,.tp-ints button:active,.tp-mode button:active,.tp-nav button:active{transform:scale(.94)}
.tabbar a:active svg,.tabbar button:active svg{transform:scale(.88)}
.tabbar svg{transition:transform .16s var(--ke-out)}
.tabbar a#mSwap:active svg{transform:translateX(-50%) scale(.9)}
input,select,textarea,.pfw,.sq,.swc-box,.conv-row{transition:border-color .15s ease,box-shadow .2s ease,background-color .15s ease}

/* icons that point somewhere lean that way on hover */
.tp-back svg,.ow-i .chev,.prf-chev,.slot em,.pp-more,.dd>button::after{transition:transform .2s var(--ke-out)}
.tp-back:hover svg{transform:translateX(-2px)}
.ow-i:hover .chev,a.prf-row:hover .prf-chev{transform:translateX(3px)}
.slot:hover em{transform:translateX(3px)}
.dd.open>button::after{transform:rotate(-135deg) translate(-1px,-1px)}

/* ---------- overlays: scrim, sheet, drawer, search, toast ---------- */
@keyframes keFadeIn{from{opacity:0}}
@keyframes keFadeOut{to{opacity:0}}
.scrim{animation:keFadeIn .22s ease-out}
.scrim[data-leaving]{animation:keFadeOut .18s ease-in forwards;pointer-events:none}

@keyframes keModalIn{from{opacity:0;transform:translate(-50%,-48%) scale(.97)}}
@keyframes keModalOut{to{opacity:0;transform:translate(-50%,-49%) scale(.98)}}
.modal{animation:keModalIn .22s var(--ke-out)}
.modal[data-leaving]{animation:keModalOut .16s var(--ke-in) forwards;pointer-events:none}
.modal.sizing{overflow:hidden}

@keyframes keDrawerIn{from{transform:translateX(100%)}}
@keyframes keDrawerOut{to{transform:translateX(100%)}}
.drawer{animation:keDrawerIn .28s var(--ke-out)}
.drawer[data-leaving]{animation:keDrawerOut .2s var(--ke-in) forwards;pointer-events:none}

@keyframes keSearchIn{from{opacity:0;transform:translate(-50%,-8px) scale(.985)}}
@keyframes keSearchOut{to{opacity:0;transform:translate(-50%,-6px) scale(.99)}}
.sbox{animation:keSearchIn .2s var(--ke-out)}
.sbox[data-leaving]{animation:keSearchOut .14s var(--ke-in) forwards;pointer-events:none}

@keyframes keToastIn{from{opacity:0;transform:translate(-50%,12px)}}
@keyframes keToastOut{to{opacity:0;transform:translate(-50%,8px)}}
.toast{animation:keToastIn .24s var(--ke-out);display:flex;align-items:center;gap:12px}
.toast[data-leaving]{animation:keToastOut .18s var(--ke-in) forwards}
.toast-act{border:0;background:none;color:var(--accent-txt);font:inherit;font-weight:800;padding:2px 2px 2px 0;cursor:pointer;flex:none}
.toast-act:hover{text-decoration:underline;text-underline-offset:3px}

/* header menus: Explore, For projects, theme, wallet */
@keyframes keMenuIn{from{opacity:0;transform:translateY(-6px) scale(.98)}}
@keyframes keMenuOut{to{opacity:0;transform:translateY(-4px) scale(.98)}}
.ddp,.tmp{transform-origin:top left;animation:keMenuIn .18s var(--ke-out)}
.tmp{transform-origin:top right}
.ddp[data-leaving],.tmp[data-leaving]{animation:keMenuOut .12s var(--ke-in) forwards;pointer-events:none}
.cotok-res{transform-origin:top center;animation:keMenuIn .16s var(--ke-out)}

@media (max-width:760px){
  @keyframes keSearchInM{from{opacity:0;transform:translateY(-10px)}}
  @keyframes keSearchOutM{to{opacity:0;transform:translateY(-8px)}}
  .sbox{animation-name:keSearchInM}
  .sbox[data-leaving]{animation-name:keSearchOutM}

  /* checkout, share and pickers become a bottom sheet on phones; drag the top edge down to close */
  .modal{left:0;right:0;top:auto!important;bottom:0;transform:none;width:100%;max-height:calc(100dvh - 32px - var(--tg-top,0px));
    border-radius:26px 26px 0 0!important;padding:26px 16px calc(18px + env(safe-area-inset-bottom,0px) + var(--tg-bottom,0px))}
  .modal::before{content:"";position:absolute;top:9px;left:50%;width:38px;height:4px;margin-left:-19px;border-radius:2px;background:var(--line2)}
  @keyframes keSheetIn{from{transform:translateY(100%)}}
  @keyframes keSheetOut{to{transform:translateY(100%)}}
  .modal{animation:keSheetIn .3s var(--ke-out)}
  .modal[data-leaving]{animation:keSheetOut .2s var(--ke-in) forwards}
}
.modal.dragging,.drawer.dragging{transition:none!important}
.modal.settle,.drawer.settle{transition:translate .22s var(--ke-out)}

/* ---------- page switches: the incoming page settles in ---------- */
@keyframes kePageIn{from{opacity:0;transform:translateY(6px)}}
@supports not (view-transition-name:none){main>.intro,main>.hl,main>.cols,.tp,.pp,.rd,.swp,.prf,.shp,.lg-page{animation:kePageIn .26s var(--ke-out)}}
/* with view transitions: the old page fades out, the new one rises in; header and tab bar are left alone */
header{view-transition-name:ke-head}
.tabbar{view-transition-name:ke-tabbar}
:root.vt-page::view-transition-old(root){animation:keFadeOut .16s ease-in both}
:root.vt-page::view-transition-new(root){animation:kePageIn .32s var(--ke-out) both}
:root.vt-page::view-transition-group(ke-head),:root.vt-page::view-transition-group(ke-tabbar){animation-duration:.32s}

/* ---------- things that expand in place ---------- */
.filters,.swc-slip,.swc-info{transform-origin:top}
.pp-faq summary,.comore summary{list-style:none;display:flex;align-items:center;justify-content:space-between;gap:12px}
.pp-faq summary::-webkit-details-marker{display:none}
.pp-faq summary::after{content:"";flex:none;width:8px;height:8px;margin-right:4px;border-right:1.6px solid var(--muted);border-bottom:1.6px solid var(--muted);transform:translateY(-2px) rotate(45deg);transition:transform .22s var(--ke-out)}
.pp-faq details[open]:not(.closing) summary::after{transform:translateY(1px) rotate(-135deg)}
.comore summary{justify-content:flex-start}
.comore summary::before{transition:transform .22s var(--ke-out)}
.comore[open]:not(.closing) summary::before{transform:rotate(180deg)}
details.sliding{overflow:hidden}

/* ---------- sliding selection in every single-choice row ----------
   app.js measures the selected option and sets --tx/--ty/--tw/--th/--tr. The pill is drawn above the options'
   own backgrounds and below their labels (wrapped in .tl), so it glides over solid tabs as well as plain ones.
   Rows that get rebuilt start the pill where the old one was, so the move still reads. */
.seg,.tseg,.tp-ints,.tp-mode,.tp-nav,.presets,.tabs,.tp-tabs,.disc-tabs,.lg-tabs,.ch-tabs,.packs,.vt{position:relative}
.thumbed::before{content:"";position:absolute;left:0;top:0;z-index:1;width:var(--tw);height:var(--th);border-radius:var(--tr,999px);pointer-events:none;
  transform:translate(var(--tx),var(--ty));transition:transform .34s var(--ke-move),width .34s var(--ke-move),height .34s var(--ke-move),border-radius .34s var(--ke-move)}
.thumbed.thumb-still::before{transition:none}
.thumbed>*{position:relative}
.tl{position:relative;z-index:2;display:inherit;gap:inherit;align-items:inherit;justify-items:inherit;justify-content:inherit;flex-direction:inherit;text-align:inherit;font:inherit;color:inherit;letter-spacing:inherit;
  transition:transform .16s var(--ke-out)}
/* the label shrinks on press (a pressed button can't scale itself here: it would slip under the pill) */
/* rules like ".pack span" and ".vt button span" were written for the inner text; the wrapper must not pick them up */
:is(.pack,.vt>button,.ch-tabs>button)>.tl{font-size:inherit;color:inherit;line-height:inherit;filter:none}
.thumbed>:active{transform:none!important;filter:none!important}
.thumbed>:active>.tl{transform:scale(.93)}
.thumbed>:hover{filter:none!important}
/* the selected option hands its look to the pill */
.thumbed>:is([aria-pressed="true"],[aria-current]:not([aria-current="false"]),[aria-checked="true"],[aria-selected="true"]){background:transparent!important;box-shadow:none!important;border-color:transparent!important}
:is(.seg,.tseg,.tp-ints,.tp-mode,.tp-nav,.tabs,.tp-tabs).thumbed::before{background:var(--accent);box-shadow:0 0 18px -6px var(--accent-glow),inset 0 -2px 0 rgba(0,0,0,.08)}
.presets.thumbed::before{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--accent-line)}
.vt.thumbed::before{background:color-mix(in srgb,var(--accent) 16%,var(--panel));box-shadow:inset 0 0 0 1px var(--warn)}
:is(.disc-tabs,.lg-tabs).thumbed::before{background:var(--fg)}
.packs.thumbed::before{background:var(--accent-soft);box-shadow:inset 0 0 0 1.5px var(--accent-line)}
.packs.thumbed>.pack[aria-pressed="true"]{color:var(--fg)!important}
.ch-tabs.thumbed::before{background:var(--panel);box-shadow:0 2px 8px -3px rgba(0,0,0,.18)}
:is(.seg,.tseg,.tp-ints,.tp-mode,.tp-nav,.presets,.tabs,.tp-tabs,.disc-tabs,.lg-tabs,.ch-tabs,.packs,.vt)>*{transition:color .22s ease,background-color .2s ease,border-color .2s ease,transform .16s var(--ke-out)}
/* phones: the active-tab dot under the bottom bar slides to the tab you open */
.tabbar.thumbed::before{width:5px;height:5px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);
  transform:translate(calc(var(--tx) + var(--tw) / 2 - 2.5px),calc(var(--ty) + var(--th) + 1px));transition:transform .36s var(--ke-move)}
.tabbar.thumbed .cur::after{display:none!important}
.tabbar>a#mSwap{z-index:2}

/* counts on tabs, presets and the Filters button */
.tabs .cnt,.presets .cnt,#filtB .cnt{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;margin-left:6px;border-radius:999px;font-size:11px;font-weight:800;line-height:1;
  background:var(--well);color:var(--muted);font-variant-numeric:tabular-nums}
.tabs button[aria-pressed="true"] .cnt{background:rgba(0,0,0,.12);color:inherit}
.presets .cnt{background:none;min-width:0;padding:0;margin-left:5px;height:auto;font-weight:700;color:var(--faint)}
.presets button.zero{color:var(--faint)!important}
#filtB .cnt{background:var(--accent);color:var(--accent-ink)}
.filters .f-reset{margin-left:auto}

/* ---------- token table ---------- */
#rows{transition:opacity .15s ease}
th .sc{display:inline-block;width:8px;height:8px;margin-left:5px;vertical-align:1px;opacity:0;transition:opacity .15s ease,transform .2s var(--ke-out)}
th .sc svg{display:block;width:8px;height:8px}
th:hover .sc{opacity:.45}
th:not([aria-sort="none"]) .sc{opacity:1}
th .sc.asc{transform:rotate(180deg)}
/* the token column gets a soft edge once the table has scrolled sideways */
.tbox td.col-tok,.tbox th.col-tok{transition:box-shadow .2s ease}
.tbox[data-sx] td.col-tok,.tbox[data-sx] th.col-tok{box-shadow:1px 0 0 var(--line),10px 0 14px -12px rgba(0,0,0,.45)}
/* rows coming back from Undo, or new in the watchlist */
@keyframes keRowIn{from{background:var(--accent-soft)}}
tr.just td{animation:keRowIn 1.4s ease-out}

/* edge fades on rows that scroll sideways, only on the side that has more */
.hsc[data-hs="l"]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px);mask-image:linear-gradient(90deg,transparent,#000 28px)}
.hsc[data-hs="r"]{-webkit-mask-image:linear-gradient(270deg,transparent,#000 28px);mask-image:linear-gradient(270deg,transparent,#000 28px)}
.hsc[data-hs="lr"]{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent)}

/* ---------- live bits ---------- */
.live{position:relative}
.live::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--up);opacity:0;animation:keLive 2.8s ease-out infinite}
@keyframes keLive{0%{opacity:.55;transform:scale(1)}70%,100%{opacity:0;transform:scale(2.8)}}
.tp-big{border-radius:8px;padding:0 4px;margin:0 -4px}
.tp-big.flash-up{animation:flashUp 1.6s ease-out}
.tp-big.flash-down{animation:flashDown 1.6s ease-out}
.swc-out{transition:color .2s ease}

/* logos fade in the first time they load (cached ones just appear) */
.lg.fresh img{opacity:0;transition:opacity .3s ease}
.lg.fresh.ok img{opacity:1}

/* watchlist star and reactions: a small pop when you pick them */
@keyframes kePop{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}
.star.pop svg,.tp-act.pop svg,.vt button.pop .tl>span:first-child{animation:kePop .32s var(--ke-out)}

/* copy buttons swap their icon for a check for a moment */
.copied{color:var(--up)!important}
.copied svg{color:var(--up)!important}

/* ---------- highlights ---------- */
.hcard h4 .hgo{display:inline-flex;align-items:center;gap:4px;color:inherit;font:inherit;background:none;border:0;padding:0;cursor:pointer;text-decoration:none}
.hcard h4 .hgo svg{width:12px;height:12px;opacity:0;transform:translateX(-3px);transition:opacity .15s ease,transform .2s var(--ke-out)}
.hcard h4 .hgo:hover svg,.hcard h4 .hgo:focus-visible svg{opacity:.7;transform:none}
.hcard.sk{min-height:228px;display:grid;align-content:start;gap:16px}
.hcard.sk .skel{display:block}

/* rail watchlist: remove from the row itself (mouse only) */
.wl .hrow{position:relative}
.wl-x{position:absolute;right:4px;top:50%;width:26px;height:26px;margin-top:-13px;border:0;border-radius:50%;background:var(--panel2);color:var(--muted);display:grid;place-items:center;cursor:pointer;opacity:0;pointer-events:none}
.wl-x svg{width:10px;height:10px}
.wl-x:hover{color:var(--down)}
@media (hover:hover){
  .wl .hrow:hover .wl-x,.wl .wl-x:focus-visible{opacity:1;pointer-events:auto}
  .wl .hrow:has(.wl-x):hover>.v{opacity:0}
}
.wl .hrow>.v{transition:opacity .15s ease}
.wl-empty{display:grid;gap:8px;justify-items:start;padding:2px 2px 4px}
.wl-empty p{margin:0}

/* updated-ago label keeps its width while the seconds tick */
#upd,#updTxt{font-variant-numeric:tabular-nums}

/* ---------- token page ---------- */
@keyframes keMiniIn{from{opacity:0;transform:translateX(-6px)}}
.tp-bar.stuck .tp-mini{animation:keMiniIn .22s var(--ke-out)}
.tp-bar{transition:border-color .2s,box-shadow .2s}
.tp-bar.stuck{box-shadow:0 10px 18px -16px rgba(0,0,0,.35)}
#tpAct,#tpChartBox{transition:opacity .15s ease}
.donut{transition:--p .5s var(--ke-move)}
.eye-ring{transition:--s .6s var(--ke-move)}
@keyframes keRingFill{from{--s:0}}
.eye-ring:not([data-settled]){animation:keRingFill .8s var(--ke-move) .1s backwards}
.vt-bar i,.ins-meter i,.ti-bar i,.share span,.bs i,.txbar i{transition:width .5s var(--ke-move)}
@keyframes keBarIn{from{clip-path:inset(0 100% 0 0 round 5px)}}
.hbar{animation:keBarIn .6s var(--ke-move)}
.conv-swap{transition:transform .3s var(--ke-move),background-color .15s}
.conv-swap.flipped{transform:translate(-50%,-50%) rotate(180deg)}
/* trades that arrived since the last refresh */
@keyframes keTradeIn{from{background:color-mix(in srgb,var(--accent) 16%,transparent)}}
table.tx tr.fresh td{animation:keTradeIn 1.8s ease-out}
.tp-copy .sv{transition:color .15s}

/* ---------- swap ---------- */
.swc-flip{transition:transform .32s var(--ke-move),background-color .15s,box-shadow .2s}
.swc-flip:active{transform:none}
.swc-amts{display:flex;gap:4px;align-items:center}
.swc-info>div:first-child{cursor:pointer}
.swc-info>div:first-child b{text-decoration:underline dotted var(--faint);text-underline-offset:3px}
.swc-go .spin,.pill .spin{width:15px;height:15px;border-width:2px;border-color:color-mix(in srgb,currentColor 25%,transparent);border-top-color:currentColor;vertical-align:-2px}

/* ---------- radar ---------- */
@keyframes keFresh{from{box-shadow:inset 0 0 0 1.5px var(--accent-line),0 0 0 4px var(--accent-soft)}}
.rd-card.fresh{animation:keFresh 2.4s ease-out}
.rd-card .rd-new{margin-left:auto;margin-right:-4px;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--accent-txt);background:var(--accent-soft);border-radius:999px;padding:3px 8px}
@keyframes keWait{50%{opacity:.35}}
.rd-checks i.wait{animation:keWait 1.4s ease-in-out infinite}

/* ---------- search ---------- */
.sres mark,.cotok-r mark,.swp-it mark{background:none;color:var(--accent-txt);font-weight:800}
.sres .hrow.kb,.swp-it.kb,.cotok-r.kb{background:var(--panel2)}
.sclr{flex:none;width:28px;height:28px;border:0;border-radius:50%;background:var(--panel);color:var(--muted);display:grid;place-items:center;cursor:pointer}
.sclr svg{width:10px;height:10px}
.sclr:hover{color:var(--fg)}
@keyframes keDim{50%{opacity:.5}}
.searching{animation:keDim 1.1s ease-in-out infinite}

/* ---------- tooltips (replace the browser's slow title boxes; info icons open on tap) ---------- */
.tip{position:fixed;z-index:70;left:0;top:0;max-width:260px;padding:7px 10px;border-radius:10px;background:var(--fg);color:var(--bg);font-size:12.5px;font-weight:600;line-height:1.4;
  pointer-events:none;box-shadow:0 8px 24px -10px rgba(0,0,0,.45);white-space:pre-line;transform-origin:var(--ax,50%) 100%;animation:keTipIn .18s var(--ke-out)}
/* small pointer toward the thing you're hovering */
.tip::after{content:"";position:absolute;left:var(--ax,50%);top:100%;width:8px;height:8px;margin:-4px 0 0 -4px;background:inherit;transform:rotate(45deg);border-radius:0 0 2px 0}
.tip.below{transform-origin:var(--ax,50%) 0;animation-name:keTipInB}
.tip.below::after{top:0;border-radius:2px 0 0 0}
@keyframes keTipIn{from{opacity:0;transform:translateY(5px) scale(.92)}}
@keyframes keTipInB{from{opacity:0;transform:translateY(-5px) scale(.92)}}
/* moving from one tooltip to the next: the same box glides over and resizes */
.tip.glide{animation:none;transition:left .2s var(--ke-move),top .2s var(--ke-move),--ax .2s var(--ke-move)}
.tip[data-leaving]{animation:keTipOut .12s var(--ke-in) forwards}
@keyframes keTipOut{to{opacity:0;transform:scale(.96)}}

/* ---------- header lifts a little once the page moves ---------- */
header .nav{transition:box-shadow .25s ease,background-color .25s ease}
html.lifted header .nav{box-shadow:var(--sh-pop),inset 0 1px 0 rgba(255,255,255,.05)}

/* ---------- back to top (desktop) ---------- */
.totop{position:fixed;right:max(20px,env(safe-area-inset-right,0px));bottom:24px;z-index:28;width:42px;height:42px;border-radius:50%;border:1px solid var(--line2);
  background:var(--glass-bar);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);color:var(--fg);display:grid;place-items:center;cursor:pointer;box-shadow:var(--sh-bar);
  opacity:0;transform:translateY(10px);pointer-events:none;transition:opacity .2s ease,transform .22s var(--ke-out),background-color .15s}
.totop svg{width:16px;height:16px}
.totop:hover{background:var(--panel)}
html.far .totop{opacity:1;transform:none;pointer-events:auto}
@media (max-width:760px){.totop{display:none}}

/* ---------- ads close by folding away ---------- */
.folding{overflow:hidden;pointer-events:none}

/* ---------- theme switch: a short cross-fade instead of a hard cut ---------- */
::view-transition-old(root),::view-transition-new(root){animation-duration:.24s;animation-timing-function:ease}

/* ---------- reduced motion: keep state changes, drop the movement ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  .live::after,.rd-checks i.wait,.searching{animation:none!important}
}
.mm a[aria-current="page"]{background:var(--accent-soft)!important;color:var(--accent-txt);box-shadow:inset 0 0 0 1px var(--accent-line)}
.wl .hrow.just{animation:keRowIn 1.4s ease-out}

/* ---------- icons answer when you press them ----------
   app.js tags the clicked control with .tapped for ~0.6 s; each icon gets its own small movement. */
button svg,.pill svg,.tabbar svg,.soc svg,.prf-ic svg,.ow-ic svg{transition:transform .2s var(--ke-out)}
button:not(#mSwap):active>svg,a.pill:active>svg,.soc:active svg{transform:scale(.86)}
@keyframes keRing{0%,100%{transform:rotate(0)}20%{transform:rotate(14deg)}40%{transform:rotate(-12deg)}60%{transform:rotate(7deg)}80%{transform:rotate(-4deg)}}
@keyframes keSpread{0%{transform:scale(1)}35%{transform:scale(1.16) rotate(-8deg)}100%{transform:none}}
@keyframes keNudgeL{0%,100%{transform:none}40%{transform:translateX(-4px)}}
@keyframes keNudgeR{0%,100%{transform:none}40%{transform:translateX(4px)}}
@keyframes keNudgeU{0%,100%{transform:none}40%{transform:translateY(-4px)}}
@keyframes keHop{0%,100%{transform:none}35%{transform:translateY(-4px) scale(1.06)}65%{transform:translateY(1px)}}
@keyframes keLens{0%,100%{transform:none}40%{transform:scale(1.18) rotate(-10deg)}}
@keyframes keTurn{to{transform:rotate(180deg)}}
@keyframes keDraw{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}
:is([data-alert],[data-dw="alerts"]).tapped svg{transform-origin:50% 15%;animation:keRing .6s ease-out}
:is([data-share],.pfshare,#shNative).tapped svg{animation:keSpread .45s var(--ke-out)}
.tp-back.tapped svg{animation:keNudgeL .4s var(--ke-out)}
:is(.pfgo,.ow-i,.prf-row).tapped :is(svg.chev,.prf-chev,.pfgo>svg),.pfgo.tapped>svg{animation:keNudgeR .4s var(--ke-out)}
.totop.tapped svg{animation:keNudgeU .4s var(--ke-out)}
#openS.tapped svg{animation:keLens .4s var(--ke-out)}
.tabbar :is(a,button).tapped:not(#mSwap) svg{animation:keHop .42s var(--ke-out)}
.tabbar a#mSwap.tapped svg{animation:keTurnSwap .45s var(--ke-move)}
@keyframes keTurnSwap{from{transform:translateX(-50%) rotate(0)}to{transform:translateX(-50%) rotate(180deg)}}
.prf-row.tapped .prf-ic svg,.ow-i.tapped .ow-ic svg,:is(.ddp a,.tmp button).tapped svg{animation:keHop .4s var(--ke-out)}
.tp-act.tapped:not([data-star]):not([data-share]):not([data-alert]) svg{animation:keHop .4s var(--ke-out)}
.copied svg path{stroke-dasharray:24;animation:keDraw .35s var(--ke-out) both}
/* little x's turn a quarter on hover */
.adx svg,.sclr svg,.wl-x svg{transition:transform .22s var(--ke-out)}
.adx:hover svg,.sclr:hover svg,.wl-x:hover svg{transform:rotate(90deg)}
.star:hover svg{transform:scale(1.15)}
.star svg path,.tp-act svg path{transition:fill .2s ease}
/* slider icons: the knobs slide apart when their panel is open (Filters, swap slippage) */
.knobs circle{transition:transform .3s var(--ke-move)}
[aria-expanded="true"] .knobs circle:first-of-type{transform:translateX(-6px)}
[aria-expanded="true"] .knobs circle:last-of-type{transform:translateX(6px)}
#filtB{display:inline-flex;align-items:center;gap:7px}
#filtB .knobs{width:15px;height:15px;flex:none}
/* token buttons in the swap card: the chevron flips while the picker is open */
.swc-tok svg:last-child{transition:transform .25s var(--ke-out)}
.swc-tok.open svg:last-child{transform:rotate(180deg)}
.tabbar a#mSwap svg{transition:none}

/* ---------- things that used to snap ---------- */
td{transition:background-color .15s ease}
/* chart interval switch: the old chart stays, dimmed, with a spinner, until the new one lands */
.tp-chartbox{transition:opacity .2s ease}
.tp-chartbox.busy{opacity:.45}
.tp-chartbox.busy::after{content:"";position:absolute;left:50%;top:50%;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;border:2.5px solid color-mix(in srgb,var(--fg) 15%,transparent);border-top-color:var(--accent-2);animation:kespin .8s linear infinite;z-index:5}
/* messages, panels and notes that get un-hidden ease in instead of popping */
@keyframes keAppear{from{opacity:0;transform:translateY(-3px)}}
:is(.swc-note,.pfw-err,.err,.shc-body,.swtrk,.f-reset,#coErr,#alErr,#tpErr,.wl-empty,.empty,#shPrevNote,.mkt-none,.disc-empty,.ctx,[data-ad]){animation:keAppear .24s var(--ke-out)}
.shc-body img,.share-prev img,img.adimg{animation:keFadeIn .35s ease-out}
/* clickable cards rise a hair under the pointer */
@media (hover:hover){
  .mcard,.rd-card,.slot,.hcard .hrow,.src-card,.prod{transition:transform .2s var(--ke-out),box-shadow .2s ease,border-color .15s ease,background-color .15s ease}
  .mcard:hover,.rd-card:hover,.slot:hover{transform:translateY(-2px);box-shadow:var(--lift),0 10px 22px -14px rgba(0,0,0,.28)}
  .prod:hover{box-shadow:var(--lift),0 14px 28px -18px rgba(0,0,0,.3)}
  .hcard .hrow:hover .lg{transform:scale(1.06)}
}
.lg{transition:transform .2s var(--ke-out)}
.mcard:active,.rd-card:active,.slot:active{transform:translateY(0) scale(.985)}
/* the phone menu: links arrive one after another, quickly */
@keyframes keItemIn{from{opacity:0;transform:translateX(14px)}}
.drawer:not([data-leaving]) .mm>a{animation:keItemIn .3s var(--ke-out) backwards}
.drawer .mm>a:nth-child(2){animation-delay:.02s}.drawer .mm>a:nth-child(3){animation-delay:.04s}.drawer .mm>a:nth-child(4){animation-delay:.06s}
.drawer .mm>a:nth-child(5){animation-delay:.08s}.drawer .mm>a:nth-child(6){animation-delay:.1s}.drawer .mm>a:nth-child(7){animation-delay:.12s}
.drawer .mm>a:nth-child(8){animation-delay:.14s}.drawer .mm>a:nth-child(9){animation-delay:.16s}
.drawer .tseg,.drawer .dw{animation:keItemIn .3s var(--ke-out) .14s backwards}
input[type="checkbox"]{accent-color:var(--accent-2);transition:transform .15s var(--ke-out)}
input[type="checkbox"]:active{transform:scale(.9)}
