/* ImageLauncher motion layer. Loads after app.css. Evidence: 05_handoffs/image-launcher/2026-10-21-trendtrack-gap/motion-evidence.md
   Only opacity / translate / scale (individual properties, so existing `transform` rules and hover lifts keep working). */
:root{--ease-smooth:cubic-bezier(.22,1,.36,1);--m-ease:var(--ease-smooth);--dur-instant:0s;--dur-fast:.1s;--dur-base:.15s;--dur-slow:.25s;
  --skeleton-fill:color-mix(in srgb,var(--r-ink) 8%,var(--r-panel))}

/* Press feedback (TT: .t-press / motion-press, scale dip) */
/* .t-press equivalent for every control (individual `scale` property so existing transforms keep working) */
.btn,.view,.seg button,.seg a,.tabs button,.tabs a,.an-tabs .view,.sortm-btn,.chip>button,.sel,.tri,.nav,.ucard,.t-press{transition:scale var(--dur-base) var(--ease-smooth)}
.btn:active:not([disabled]):not(.disabled),.view:active,.seg button:active,.seg a:active,.tabs button:active,.tabs a:active,.an-tabs .view:active,.sortm-btn:active,.chip>button:active,.sel:active,.tri:active,.nav:active,.t-press:active{scale:.97}

/* Chevron turn on open (TT: svg transform .2s ease-smooth) */
.view.pin .chev,.sortm-btn .chev{transition:transform .2s var(--m-ease)}
.view.pin[aria-expanded=true] .chev,.sortm-btn[aria-expanded=true] .chev{transform:translateY(2px) rotate(-135deg)}

/* Tab underline grows in on the active tab (TT: indicator transform,width .3s ease-smooth) */
.tabs button,.tabs a{position:relative}
.tabs [aria-selected=true]{border-bottom-color:transparent}
.tabs [aria-selected=true]::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;background:var(--r-act);transform-origin:left center;animation:m-tab-in .3s var(--m-ease)}
@keyframes m-tab-in{from{scale:.25 1;opacity:.4}}

/* Popovers: fade + scale from the anchor (TT popover: fade-in + zoom-in-95, ease-smooth) */
.sortm-menu{transform-origin:top right;animation:m-pop-in .15s var(--m-ease)}
.qpop{transform-origin:top center;animation:m-pop-in .15s var(--m-ease)}
.pop.m-in{transform-origin:top left;animation:m-pop-in .15s var(--m-ease)}
@keyframes m-pop-in{from{opacity:0;scale:.96}}
@keyframes m-sheet-in{from{opacity:.4;translate:0 24px}}
@media (max-width:860px){.pop.m-in{animation:m-sheet-in .2s var(--m-ease)}}

/* Ad drawer + scrim (TT dialog: fade-in + zoom-in-98, .2s ease-smooth; backdrop fades) */
.scrim{animation:m-fade .2s var(--m-ease)}
.drawer{animation:m-modal-in .2s var(--m-ease)}
@keyframes m-fade{from{opacity:0}}
@keyframes m-modal-in{from{opacity:0;scale:.98}}

/* Cards: arrive on first load / load more (TT card-arrive: opacity 0, translateY 4px). JS sets --mi (0..11) per batch */
.card.m-rise{animation:m-rise .26s var(--m-ease) calc(var(--mi,0)*22ms) backwards}
@keyframes m-rise{from{opacity:0;translate:0 8px}}

/* Route enter (TT page-arrive: opacity 0, translateY 12px) */
#page.m-page{animation:none}
@keyframes m-page{from{opacity:0;translate:0 8px}}

/* Query-bar chips (TT t-chip-in: .15s, scale .92 + 3px, 28ms stagger). Only chips JS marks as new */
.chip.m-chip{animation:m-chip .15s cubic-bezier(.34,1.45,.64,1) calc(var(--mi,0)*28ms) backwards}
@keyframes m-chip{from{opacity:0;scale:.92;translate:0 3px}}

/* Header total ticks when the number changes (JS restarts the class) */
.m-tick{animation:m-tick .26s var(--m-ease)}
@keyframes m-tick{from{opacity:.35;translate:0 3px}}

@media (prefers-reduced-motion:reduce){
  .sortm-menu,.qpop,.pop.m-in,.scrim,.drawer,.card.m-rise,#page.m-page,.chip.m-chip,.m-tick,.tabs [aria-selected=true]::after{animation:none!important}
  .view.pin .chev,.sortm-btn .chev{transition:none}
}

/* ===== Loading + transition layer (TrendTrack benchmark 2026-10-22 §2-3) ===== */
.sk{background:var(--skeleton-fill)}
.mx-rsk{display:grid;gap:14px;align-content:start}
.mx-rsk .sk{border-radius:8px}
.mx-sk-hd{display:flex;align-items:center;gap:12px}
.mx-sk-bar{height:40px;border-radius:99px!important;flex:1;max-width:560px}
.mx-sk-btn{height:36px;width:112px;flex:none}
.mx-sk-title{height:26px;width:220px}
.mx-sk-pills{display:flex;gap:8px;overflow:hidden}
.mx-sk-pill{height:30px;width:var(--w,92px);flex:none;border-radius:99px!important}
.mx-sk-tabs{display:flex;gap:10px;border-bottom:1px solid var(--r-line);padding-bottom:10px}
.mx-sk-tab{height:18px;width:var(--w,88px)}
.mx-sk-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px}
.mx-sk-tile{height:88px;border-radius:12px!important}
.mx-sk-panel{border:1px solid var(--r-line);border-radius:12px;padding:16px;background:var(--r-panel);display:grid;gap:12px;align-content:start}
.mx-sk-grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:12px}
.mx-sk-hbars{display:grid;gap:10px}
.mx-sk-hbars .sk{height:12px;width:var(--w,70%)}
.mx-sk-chart{display:flex;align-items:flex-end;gap:8px;height:150px}
.mx-sk-chart .sk{flex:1;height:var(--h,50%);border-radius:4px 4px 0 0}
.mx-sk-area{display:block;height:150px;border-radius:0!important;clip-path:polygon(0 78%,12% 60%,25% 68%,38% 42%,52% 54%,66% 28%,80% 40%,100% 16%,100% 100%,0 100%)}
.mx-rsk .grid{margin:0}

/* busy grid: keep height, show skeleton cards over the stale ones */
.grid.mx-busy{position:relative}
.grid.mx-busy>:not(.mx-ovl){opacity:.3;pointer-events:none}
.mx-ovl{position:absolute;left:0;right:0;top:0;height:min(100%,1500px);z-index:2;overflow:hidden;background:var(--r-canvas);pointer-events:none;align-content:start}
#res[aria-busy=true]:not(.grid):not(:has(.sk)){opacity:.5;pointer-events:none}

/* sliding active indicator (JS adds .mx-slide + <i.mx-ind>; without it the static active styles stay) */
.views,.seg,.an-tabs,.tabs{position:relative}
.mx-ind{position:absolute;left:0;top:0;width:0;pointer-events:none;z-index:0}
.mx-slide>:not(.mx-ind){position:relative;z-index:1}
.mx-slide[data-mx=line]>.mx-ind{top:auto;bottom:0;height:2px;background:var(--r-act);border-radius:2px 2px 0 0}
.mx-slide[data-mx=line]>[aria-selected=true],.mx-slide[data-mx=line]>[aria-pressed=true],.mx-slide[data-mx=line]>[aria-current=page]{border-bottom-color:transparent!important}
.tabs.mx-slide [aria-selected=true]::after{display:none}
.mx-slide[data-mx=pill]>.mx-ind{background:var(--r-panel);box-shadow:var(--sh);border-radius:6px}
.views.mx-slide[data-mx=pill]>.mx-ind{background:var(--r-act-soft);box-shadow:inset 0 0 0 1px var(--r-act-line);border-radius:99px}
.mx-slide[data-mx=pill]>[aria-selected=true],.mx-slide[data-mx=pill]>[aria-pressed=true],.mx-slide[data-mx=pill]>[aria-current=page]{background:transparent!important;box-shadow:none!important;border-color:transparent!important}

/* popover close ghost */
.mx-out{pointer-events:none}

/* search submit hint (TT "Start search ↵") */
.mx-kbd{flex:none;margin:0 12px 0 6px;padding:2px 6px;border:1px solid var(--r-line-2);border-radius:5px;font:600 11px/1.2 var(--font-mono,ui-monospace,monospace);color:var(--r-ink-3);background:var(--r-well);opacity:0;transition:opacity var(--dur-base) var(--ease-smooth);pointer-events:none}
.qb-field:focus-within .mx-kbd{opacity:1}
.btn kbd.mx-kbd{opacity:.8;margin:0 -4px 0 2px;background:transparent;border-color:currentColor}

@media (prefers-reduced-motion:no-preference){
  .sk{animation:mx-pulse 2s cubic-bezier(.4,0,.6,1) infinite}
  @keyframes mx-pulse{50%{opacity:.5}}
  .mx-in{animation:mx-in .2s var(--ease-smooth) calc(var(--mi,0)*18ms) backwards}
  @keyframes mx-in{from{opacity:0;translate:0 4px}}
  .grid.mx-busy>:not(.mx-ovl){transition:opacity var(--dur-base) var(--ease-smooth)}
  .mx-ovl{animation:mx-fade .15s var(--ease-smooth)}
  .mx-ind{transition:transform var(--dur-slow) var(--ease-smooth),width var(--dur-slow) var(--ease-smooth),height var(--dur-slow) var(--ease-smooth)}
  .mx-ind.mx-nt{transition:none}
  .mx-out{animation:mx-out var(--dur-fast) var(--ease-smooth) forwards!important}
  @keyframes mx-out{to{opacity:0}}
  /* charts: line draws, area/dots fade in, bars grow */
  .pt-svg.mx-draw .pt-ln{stroke-dasharray:var(--len);stroke-dashoffset:var(--len);animation:mx-draw .6s var(--ease-smooth) forwards}
  .pt-svg.mx-draw path:not(.pt-ln){animation:mx-fade .4s var(--ease-smooth) .25s backwards}
  .pt-svg.mx-draw .pt-dot,.pt-svg.mx-draw .pt-pl{animation:mx-fade .3s var(--ease-smooth) .5s backwards}
  @keyframes mx-draw{to{stroke-dashoffset:0}}
  .pt-cols.mx-bars i,.vbars.mx-bars i,.spark.mx-bars i,.mx-bars .rt-bar{transform-origin:50% 100%;transform-box:fill-box;animation:mx-grow-y .4s var(--ease-smooth) calc(var(--bi,0)*20ms) backwards}
  .pt-bars.mx-bars i,.pt-hbars.mx-bars .pt-track i,.pt-stack.mx-bars i,.pt-lift.mx-bars .pt-bars i,.pt-cov.mx-bars .pt-stack i{transform-origin:0 50%;animation:mx-grow-x .4s var(--ease-smooth) calc(var(--bi,0)*20ms) backwards}
  @keyframes mx-grow-y{from{scale:1 0}}
  @keyframes mx-grow-x{from{scale:0 1}}
}
@media (prefers-reduced-motion:reduce){
  .sk{animation:none}
  .mx-in,.mx-ovl,.mx-out,.mx-bars i,.mx-bars .rt-bar{animation:none!important}
  .mx-ind{transition:none}
}
.pt-mt{justify-self:start;margin-bottom:4px}
.pt-mbody{display:grid;gap:8px;min-width:0}
