/* =====================================================================
   Motion layer — loading states, page and chart entrances, micro-interactions.
   Loaded after ux.css. motion.js adds body.mo-enter for a moment after each navigation (and after the first
   load), tags "Loading…" placeholders with .mo-loading and drives the #mo-bar progress bar.
   Only transform and opacity animate; everything stops under prefers-reduced-motion.
   ===================================================================== */
:root{
  --mo-ease:cubic-bezier(.2,.8,.2,1);
  --mo-spring:cubic-bezier(.34,1.56,.64,1);
  --mo-shine:rgba(255,255,255,.65); --mo-skel:var(--stone); --mo-shine-bar:#FCFBFA;
  --mo-glow-a:rgba(131,157,249,.30); --mo-glow-b:rgba(194,211,255,.42);
}
@media (prefers-color-scheme:dark){:root{
  --mo-shine:rgba(131,157,249,.22); --mo-skel:#173A7A; --mo-shine-bar:#2E58A8;
  --mo-glow-a:rgba(53,49,207,.38); --mo-glow-b:rgba(78,96,231,.20);
}}

@keyframes mo-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes mo-fade{from{opacity:0}to{opacity:1}}
@keyframes mo-pop{from{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:none}}
@keyframes mo-slide{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:none}}
@keyframes mo-grow-x{from{transform:scaleX(0)}to{transform:none}}
@keyframes mo-grow-y{from{transform:scaleY(0)}to{transform:none}}
@keyframes mo-draw{to{stroke-dashoffset:0}}
@keyframes mo-spin{to{transform:rotate(360deg)}}
@keyframes mo-shimmer{from{background-position:180% 0}to{background-position:-80% 0}}
@keyframes mo-breathe{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes mo-aurora{0%{transform:translate3d(0,0,0) rotate(0deg) scale(1)}50%{transform:translate3d(4%,-3%,0) rotate(8deg) scale(1.08)}100%{transform:translate3d(-3%,4%,0) rotate(-6deg) scale(1.02)}}
@keyframes mo-pulse-ring{0%{box-shadow:0 0 0 0 rgba(53,49,207,.35)}100%{box-shadow:0 0 0 10px rgba(53,49,207,0)}}

/* ---------- 1. Progress bar while the CRM talks to the server ---------- */
#mo-bar{position:fixed;top:0;left:0;right:0;height:3px;z-index:120;pointer-events:none;transform:scaleX(0);transform-origin:0 50%;opacity:0;
  background:linear-gradient(90deg,var(--indigo),var(--peri) 55%,var(--sky));box-shadow:0 0 10px rgba(78,96,231,.55);
  transition:transform .45s var(--mo-ease),opacity .25s}
#mo-bar.on{opacity:1}
#mo-bar.done{opacity:0;transition:transform .18s ease-out,opacity .4s .15s}

/* ---------- 2. Loading placeholders ---------- */
/* Inline: a small ring and a soft shimmer across the words */
.mo-loading{display:flex;align-items:center;justify-content:center;gap:10px;color:var(--muted);
  background:linear-gradient(100deg,var(--muted) 30%,var(--mo-shine) 50%,var(--muted) 70%) 0 0/250% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  animation:mo-shimmer 1.8s linear infinite}
.mo-loading::before{content:"";flex:none;width:16px;height:16px;border-radius:50%;-webkit-text-fill-color:initial;
  background:conic-gradient(from 90deg,transparent 0 20%,var(--accent) 100%);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2px));mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 2px));
  animation:mo-spin .8s linear infinite}
/* Block placeholders (a card or panel waiting for data): three skeleton lines above the words */
.empty.mo-loading,.card .mo-loading:only-child,.cb>.mo-loading:only-child{flex-direction:column;gap:14px;padding:22px 18px;min-height:120px}
.empty.mo-loading::after,.card .mo-loading:only-child::after,.cb>.mo-loading:only-child::after{content:"";order:-1;width:min(320px,80%);height:44px;-webkit-text-fill-color:initial;
  /* the mask cuts three bars; only the shimmer behind them moves */
  align-self:center;background:linear-gradient(100deg,var(--mo-skel) 30%,var(--mo-shine-bar) 50%,var(--mo-skel) 70%) 0 0/250% 100%;
  -webkit-mask:linear-gradient(#000,#000) 0 0/100% 10px no-repeat,linear-gradient(#000,#000) 0 17px/82% 10px no-repeat,linear-gradient(#000,#000) 0 34px/58% 10px no-repeat;
  mask:linear-gradient(#000,#000) 0 0/100% 10px no-repeat,linear-gradient(#000,#000) 0 17px/82% 10px no-repeat,linear-gradient(#000,#000) 0 34px/58% 10px no-repeat;
  animation:mo-shimmer 1.6s linear infinite}
.empty.mo-loading::before,.card .mo-loading:only-child::before,.cb>.mo-loading:only-child::before{display:none}
/* Whole page waiting (first paint, and while the pipeline loads after sign-in): a larger ring, centred */
#view>.mo-loading:only-child{min-height:62vh;flex-direction:column;gap:18px;font-size:13px;letter-spacing:.02em;padding:0;background-color:transparent;animation:mo-shimmer 1.8s linear infinite,mo-fade .5s var(--mo-ease) both}
#view>.mo-loading:only-child::before{display:block;width:46px;height:46px;
  background:conic-gradient(from 90deg,transparent 0 15%,var(--sky) 45%,var(--accent) 100%);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 3.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 3.5px));
  animation:mo-spin .9s linear infinite}
#view>.mo-loading:only-child::after{display:none}
/* The AI coach box keeps its own spinner, made a little calmer */
.ai-load{animation:mo-breathe 1.6s ease-in-out infinite}

/* ---------- 3. Page entrance (only for a moment after navigating, never on in-place edits) ---------- */
body.mo-enter #cmd .eyebrow,body.mo-enter #cmd h1{animation:mo-rise .5s var(--mo-ease) both}
body.mo-enter #cmd h1{animation-delay:.04s}
body.mo-enter #cmd .stat{animation:mo-pop .5s var(--mo-ease) both}
body.mo-enter #cmd .stat:nth-child(2){animation-delay:.06s} body.mo-enter #cmd .stat:nth-child(3){animation-delay:.12s} body.mo-enter #cmd .stat:nth-child(4){animation-delay:.18s}
body.mo-enter #view .grid>*{animation:mo-rise .55s var(--mo-ease) both}
body.mo-enter #view .grid>:nth-child(2){animation-delay:.05s} body.mo-enter #view .grid>:nth-child(3){animation-delay:.1s}
body.mo-enter #view .grid>:nth-child(4){animation-delay:.15s} body.mo-enter #view .grid>:nth-child(5){animation-delay:.2s}
body.mo-enter #view .grid>:nth-child(n+6){animation-delay:.25s}
/* Board: columns slide up, then their cards drop in */
body.mo-enter #view .col{animation:mo-rise .5s var(--mo-ease) both}
body.mo-enter #view .col:nth-child(2){animation-delay:.04s} body.mo-enter #view .col:nth-child(3){animation-delay:.08s} body.mo-enter #view .col:nth-child(4){animation-delay:.12s}
body.mo-enter #view .col:nth-child(5){animation-delay:.16s} body.mo-enter #view .col:nth-child(n+6){animation-delay:.2s}
body.mo-enter #view .cards>.dcard{animation:mo-pop .45s var(--mo-ease) both;animation-delay:.18s}
body.mo-enter #view .cards>.dcard:nth-child(2){animation-delay:.24s} body.mo-enter #view .cards>.dcard:nth-child(n+3){animation-delay:.3s}
/* Lists and tables: rows arrive in a quick cascade (the first dozen; the rest simply appear) */
body.mo-enter #view li.tk,body.mo-enter #view .list>li{animation:mo-slide .4s var(--mo-ease) both}
body.mo-enter #view table.t tbody tr{animation:mo-fade .45s var(--mo-ease) both}
body.mo-enter #view li.tk:nth-child(2),body.mo-enter #view .list>li:nth-child(2),body.mo-enter #view table.t tbody tr:nth-child(2){animation-delay:.03s}
body.mo-enter #view li.tk:nth-child(3),body.mo-enter #view .list>li:nth-child(3),body.mo-enter #view table.t tbody tr:nth-child(3){animation-delay:.06s}
body.mo-enter #view li.tk:nth-child(4),body.mo-enter #view .list>li:nth-child(4),body.mo-enter #view table.t tbody tr:nth-child(4){animation-delay:.09s}
body.mo-enter #view li.tk:nth-child(5),body.mo-enter #view .list>li:nth-child(5),body.mo-enter #view table.t tbody tr:nth-child(5){animation-delay:.12s}
body.mo-enter #view li.tk:nth-child(6),body.mo-enter #view .list>li:nth-child(6),body.mo-enter #view table.t tbody tr:nth-child(6){animation-delay:.15s}
body.mo-enter #view li.tk:nth-child(n+7),body.mo-enter #view .list>li:nth-child(n+7),body.mo-enter #view table.t tbody tr:nth-child(n+7){animation-delay:.18s}
/* Health tiles and the stage path on a deal */
body.mo-enter #view .stat.drill{animation:mo-pop .45s var(--mo-ease) both}
body.mo-enter #view .path>.step{animation:mo-pop .4s var(--mo-ease) both}
body.mo-enter #view .path>.step:nth-child(2){animation-delay:.04s} body.mo-enter #view .path>.step:nth-child(3){animation-delay:.08s}
body.mo-enter #view .path>.step:nth-child(4){animation-delay:.12s} body.mo-enter #view .path>.step:nth-child(n+5){animation-delay:.16s}
/* Sidebar: the yellow marker grows into the newly selected item */
body.mo-enter .nav-i[aria-current=page]::before{transform-origin:50% 50%;animation:mo-grow-y .35s var(--mo-ease) both}
/* Record tabs: the underline sweeps in under the selected tab */
.rtabs a{transition:color .2s var(--mo-ease),border-color .25s var(--mo-ease)}

/* ---------- 4. Charts draw themselves in on arrival ---------- */
body.mo-enter #view .fnl .ft b,body.mo-enter #view .fnl .ft em,body.mo-enter #view .hbars .ht i{transform-origin:0 50%;animation:mo-grow-x .8s var(--mo-ease) both;animation-delay:.15s}
body.mo-enter #view .fnl .fr:nth-child(2) .ft *,body.mo-enter #view .hbars .hb:nth-child(2) .ht i{animation-delay:.2s}
body.mo-enter #view .fnl .fr:nth-child(3) .ft *,body.mo-enter #view .hbars .hb:nth-child(3) .ht i{animation-delay:.25s}
body.mo-enter #view .fnl .fr:nth-child(4) .ft *,body.mo-enter #view .hbars .hb:nth-child(4) .ht i{animation-delay:.3s}
body.mo-enter #view .fnl .fr:nth-child(n+5) .ft *,body.mo-enter #view .hbars .hb:nth-child(n+5) .ht i{animation-delay:.35s}
body.mo-enter #view svg[aria-label="Forecast by quarter"] rect,body.mo-enter #view svg[aria-label="Weekly pipeline trend"] rect{transform-box:fill-box;transform-origin:50% 100%;animation:mo-grow-y .75s var(--mo-ease) both;animation-delay:.15s}
body.mo-enter #view svg[viewBox="0 0 170 170"] path{stroke-dasharray:480;stroke-dashoffset:480;animation:mo-draw 1s var(--mo-ease) .15s forwards}
body.mo-enter #view svg[aria-label="Weekly pipeline trend"] polyline{stroke-dasharray:2400;stroke-dashoffset:2400;animation:mo-draw 1.1s var(--mo-ease) .35s forwards}
body.mo-enter #view svg[aria-label="Weekly pipeline trend"] circle{animation:mo-fade .4s ease .9s both}
body.mo-enter #view .viz svg[role=img]:not([aria-label="Forecast by quarter"]):not([aria-label="Weekly pipeline trend"]):not([viewBox="0 0 170 170"]){animation:mo-pop .6s var(--mo-ease) .1s both}

/* ---------- 5. Micro-interactions ---------- */
.btn.primary:hover:not(:disabled){box-shadow:0 6px 18px -6px rgba(53,49,207,.55)}
.dcard:active{cursor:grabbing;transform:scale(1.02) rotate(-.6deg);box-shadow:var(--shadow-hover)}
.col.over{animation:mo-fade .2s both;background:color-mix(in srgb,var(--accent) 7%,transparent)}
.col{transition:background .2s var(--mo-ease)}
.tk-check:active{transform:scale(.88)}
.tk-check:focus-visible{animation:mo-pulse-ring .6s ease-out}
tr.click,li.click,.hb{transition:background .15s var(--mo-ease)}
.nav-i svg{transition:transform .25s var(--mo-spring)}
.nav-i:hover svg{transform:scale(1.1)}
.fab{animation:mo-pop .55s var(--mo-spring) .35s both}
.fab span{display:inline-block;transition:transform .3s var(--mo-spring)}
.fab:hover span{transform:rotate(90deg)}
.modal-bg:not([hidden]){animation:mo-fade .22s ease-out both}
.toast{transition:opacity .25s,transform .45s var(--mo-spring)}
:focus-visible{transition:outline-offset .15s var(--mo-ease)}

/* ---------- 6. Look and feel ---------- */
/* A soft brand glow behind each page header (painted under the content, so it never covers anything) */
.main{background:
  radial-gradient(55% 340px at 88% -60px,var(--mo-glow-a),transparent 70%),
  radial-gradient(45% 300px at 18% -90px,var(--mo-glow-b),transparent 72%);background-repeat:no-repeat}
/* Slimmer scrollbars in the brand neutrals */
*{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px;border:3px solid transparent;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background-color:var(--muted)}
::-webkit-scrollbar-track{background:transparent}
/* Sign-in: a slow aurora behind the navy panel (kept to the right so the copy stays on plain navy), and the form rising in */
.login-hero{position:relative;overflow:hidden;isolation:isolate}
.login-hero::before{content:"";position:absolute;inset:-25% -35% -25% 25%;z-index:-1;pointer-events:none;filter:blur(40px);
  background:radial-gradient(32% 30% at 62% 28%,rgba(78,96,231,.58),transparent 70%),radial-gradient(28% 28% at 78% 64%,rgba(53,49,207,.65),transparent 70%),radial-gradient(22% 22% at 52% 88%,rgba(131,157,249,.3),transparent 70%);
  animation:mo-aurora 22s ease-in-out infinite alternate}
.login-hero>*{animation:mo-rise .7s var(--mo-ease) both}
.login-hero>:nth-child(2){animation-delay:.08s}.login-hero>:nth-child(3){animation-delay:.16s}
.login-hero .chev span{animation:mo-slide .5s var(--mo-ease) both}
.login-hero .chev span:nth-child(1){animation-delay:.3s}.login-hero .chev span:nth-child(2){animation-delay:.38s}
.login-hero .chev span:nth-child(3){animation-delay:.46s}.login-hero .chev span:nth-child(4){animation-delay:.54s}
.login-form form{animation:mo-rise .7s var(--mo-ease) .12s both}
.login-hero .eyebrow{color:var(--signal)}   /* brand cover: the "Tieto Banktech" eyebrow in Signal Yellow on navy */

/* ---------- 7. Reduced motion and print ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .mo-loading{-webkit-text-fill-color:currentColor;background:none}
  .login-hero::before{display:none}
}
@media print{#mo-bar{display:none}.main{background:none}}

/* ---------- Page changes: view transitions (app-shell.js render). The old page fades out under a still top bar
   while the new one arrives with the entrance animations above; a logo clicked in a list flies into the record's
   title (motion.js marks it, app-shell.js names the landing). Same-page repaints never animate. ---------- */
@media (prefers-reduced-motion:no-preference){
  .main{view-transition-name:page}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
  ::view-transition-old(page){animation:mo-vt-out .14s ease-in both}
  ::view-transition-new(page){animation:mo-vt-in .2s var(--mo-ease) .03s both}
  ::view-transition-group(rec-logo){animation-duration:.36s;animation-timing-function:var(--mo-ease)}
  ::view-transition-old(rec-logo),::view-transition-new(rec-logo){animation-duration:.36s}
}
@keyframes mo-vt-out{to{opacity:0}}
@keyframes mo-vt-in{from{opacity:0}}

/* ---------- Feedback where the work happens ---------- */
/* A tick on the field that was just saved (motion.js) */
.mo-tick{position:fixed;z-index:70;width:18px;height:18px;border-radius:50%;background:var(--ok,#1A7F4B);color:#fff;font-size:11px;font-weight:700;line-height:1;display:grid;place-items:center;pointer-events:none;box-shadow:0 2px 6px rgba(2,30,87,.18);animation:mo-tick 1.3s var(--mo-ease) both}
.mo-saved{box-shadow:0 0 0 3px rgba(26,127,75,.2)!important;transition:box-shadow .45s}
@keyframes mo-tick{0%{opacity:0;transform:scale(.4)}14%{opacity:1;transform:scale(1.15)}24%{transform:scale(1)}78%{opacity:1}100%{opacity:0;transform:scale(.92)}}
/* Completing a task: the check fills and pops before the list updates */
.tk-check.mo-ticked{background:var(--ok);border-color:var(--ok);animation:mo-check .45s var(--mo-spring) both}
.tk-check.mo-ticked::after{content:"";position:absolute;left:6px;top:2.5px;width:5px;height:9px;border:solid var(--on-ok,#fff);border-width:0 2px 2px 0;transform:rotate(45deg)}
.tk-check.big.mo-ticked::after{left:8.5px;top:4.5px;width:6px;height:11px}
@keyframes mo-check{0%{transform:scale(1)}35%{transform:scale(.78)}70%{transform:scale(1.16);box-shadow:0 0 0 6px rgba(26,127,75,.22)}100%{transform:scale(1);box-shadow:0 0 0 12px rgba(26,127,75,0)}}
