/* Shared motion and interaction layer.
   Loaded after every page stylesheet, so it only refines entrance, hover,
   press and feedback behaviour that those files already own. Everything in
   here is decorative: without this file (or without motion.js) the pages keep
   their original appearance and stay fully usable. */

:root{
  --motion-ease:cubic-bezier(.22,.68,.16,1);
  --motion-ease-out:cubic-bezier(.16,1,.3,1);
  --motion-ease-soft:cubic-bezier(.4,0,.2,1);
  --motion-accent:19,184,207;
}

/* ---------- Entrance choreography ---------- */

@keyframes motion-rise{
  from{opacity:0;transform:translate3d(0,var(--motion-rise,12px),0) scale(.996)}
  to{opacity:1;transform:none}
}

.dashboard .dash-grid>.practice-card{
  --motion-rise:9px;
  animation:motion-rise .7s var(--motion-ease-out) both;
  animation-delay:.1s;
}
.dashboard .summary-column>*{
  --motion-rise:9px;
  animation:motion-rise .62s var(--motion-ease-out) both;
}
.dashboard .summary-column>*:nth-child(1){animation-delay:.18s}
.dashboard .summary-column>*:nth-child(2){animation-delay:.26s}

/* Content pages cascade from the hero downwards instead of arriving at once. */
.page-shell>*{
  animation:site-rise-in .58s var(--motion-ease-out) both;
  animation-delay:calc(.06s + var(--motion-step,0)*.07s);
}
.page-shell>*:nth-child(1){--motion-step:0}
.page-shell>*:nth-child(2){--motion-step:1}
.page-shell>*:nth-child(3){--motion-step:2}
.page-shell>*:nth-child(4){--motion-step:3}
.page-shell>*:nth-child(n+5){--motion-step:4}

@media(prefers-reduced-motion:reduce){
  .dashboard .dash-grid>.practice-card,
  .dashboard .summary-column>*,
  .page-shell>*{animation:none!important;opacity:1!important;transform:none!important}
}

/* ---------- Pointer spotlight on cards ---------- */

.motion-host{position:relative}
.motion-sheen{
  position:absolute;
  inset:0;
  z-index:3;
  padding:1px;
  border-radius:inherit;
  pointer-events:none;
  opacity:0;
  background:radial-gradient(190px circle at var(--motion-x,50%) var(--motion-y,0%),rgba(var(--motion-accent),.5),rgba(var(--motion-accent),0) 62%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  transition:opacity .4s var(--motion-ease-soft);
}
.motion-host:hover>.motion-sheen,
.motion-host:focus-within>.motion-sheen{opacity:1}

/* Filled variant for high-emphasis buttons: the glow follows the cursor
   inside the button instead of hugging its border. */
.motion-sheen-fill{
  padding:0;
  background:radial-gradient(150px circle at var(--motion-x,50%) var(--motion-y,50%),var(--motion-fill,rgba(var(--motion-accent),.15)),transparent 62%);
  -webkit-mask:none;
  mask:none;
  -webkit-mask-composite:source-over;
  mask-composite:add;
  transition:opacity .32s var(--motion-ease-soft);
}
.challenge-button>.motion-sheen-fill,
#dailyStartButton>.motion-sheen-fill,
.tool-button.primary>.motion-sheen-fill,
.article-button.primary>.motion-sheen-fill,
.auth-submit>.motion-sheen-fill{--motion-fill:rgba(255,255,255,.26)}

/* ---------- Press ripple ---------- */

@keyframes motion-ripple{
  from{transform:scale(.16);opacity:.5}
  to{transform:scale(1);opacity:0}
}
/* The ripple needs a positioned ancestor. Only add the containing block when
   the host is static: forcing position:relative onto an absolutely positioned
   control (the auth dialog's close button) would move the control itself. */
.motion-ripple-host{position:relative;overflow:hidden}
.motion-ripple-clip{overflow:hidden}
.motion-ripple{
  position:absolute;
  left:0;
  top:0;
  border-radius:50%;
  pointer-events:none;
  translate:-50% -50%;
  background:radial-gradient(circle,rgba(var(--motion-ripple-color,var(--motion-accent)),.5),rgba(var(--motion-ripple-color,var(--motion-accent)),0) 70%);
  animation:motion-ripple .58s var(--motion-ease-out) forwards;
}
.challenge-button,#dailyStartButton,.segmented:not(.light) button,
.tool-button.primary,.article-button.primary,.auth-submit,
.nav-primary .nav-item,#game button{--motion-ripple-color:255,255,255}

/* ---------- Sliding pill for segmented controls ---------- */

.motion-pill-static{position:relative}
.motion-pill>button,.motion-pill>a{position:relative;z-index:1}
.motion-pill.is-ready>button.active,
.motion-pill.is-ready>a.active{
  background:transparent!important;
  border-color:transparent!important;
  box-shadow:none!important;
}
.motion-pill-indicator{
  position:absolute;
  left:0;
  top:0;
  z-index:0;
  box-sizing:border-box;
  pointer-events:none;
  border-radius:var(--motion-pill-radius,8px);
  border:1px solid var(--motion-pill-border,transparent);
  background:var(--motion-pill-bg,#fff);
  box-shadow:var(--motion-pill-shadow,0 1px 5px rgba(20,28,40,.09));
  opacity:0;
  transition:transform .34s var(--motion-ease-out),width .34s var(--motion-ease-out),height .34s var(--motion-ease-out),border-radius .3s ease,opacity .25s ease;
  will-change:transform,width,height;
}
.motion-pill-indicator.is-ready{opacity:1}

.nav-primary{
  --motion-pill-bg:#13b8cf;
  --motion-pill-shadow:0 4px 12px rgba(19,184,207,.24);
}
.performance-duration-toggle{
  --motion-pill-bg:#13b8cf;
  --motion-pill-shadow:0 2px 6px rgba(19,184,207,.22);
}
.segmented.light{--motion-pill-bg:#fff;--motion-pill-shadow:0 1px 5px rgba(20,28,40,.08)}
.segmented:not(.light){--motion-pill-bg:#30363e;--motion-pill-shadow:none}
.record-filters{--motion-pill-bg:#edf8fa;--motion-pill-shadow:none}
.leaderboard-tabs{--motion-pill-bg:#e9f7f9;--motion-pill-shadow:none}
.leaderboard-duration-tabs,
.leaderboard-mode-tabs{--motion-pill-bg:#e9f7f9;--motion-pill-border:#13b8cf;--motion-pill-shadow:none}
.auth-tabs{--motion-pill-bg:#fff;--motion-pill-shadow:0 1px 5px rgba(22,35,48,.1)}

/* Duration, target size and moving-target count are drawn as individual
   outlined chips rather than a shared track, and the button styles mark the
   selection with nothing more than a cyan outline and cyan label. With the
   pill covering the chip that outline is hidden, so the pill has to carry the
   whole selected state: accent fill, accent shadow, white label. */
.practice-card .segmented.light,
.practice-card .target-size-options,
.practice-card .moving-count-options{
  --motion-pill-bg:#13b8cf;
  --motion-pill-shadow:0 4px 12px rgba(19,184,207,.26);
}
.practice-card .motion-pill.is-ready>button.active{color:#fff!important}

/* ---------- Page furniture ---------- */

/* The sticky header and its scrolled state live in assets/site-nav.css. */
.motion-progress{
  position:fixed;
  left:0;
  top:0;
  z-index:70;
  width:100%;
  height:2px;
  pointer-events:none;
  opacity:0;
  transform:scaleX(0);
  transform-origin:0 50%;
  background:linear-gradient(90deg,#13b8cf,#5de1ee);
  transition:opacity .3s ease;
}
.motion-progress.is-active{opacity:1}

/* ---------- Micro-interactions ---------- */

.challenge-button svg{transition:transform .42s var(--motion-ease)}
#startButton:hover svg{transform:rotate(90deg) scale(1.08)}
.daily-challenge-heading button svg,
.section-icon{transition:transform .34s var(--motion-ease)}
.daily-challenge-heading button:hover svg{transform:rotate(-180deg)}
.daily-challenge-panel:hover .section-icon,
.dash-card:hover .section-icon{transform:scale(1.06)}

.practice-card .mode-strip .scenario .mode-icon{transition:transform .34s var(--motion-ease),background-color .24s ease}
.practice-card .mode-strip .scenario:hover .mode-icon{transform:translateY(-2px) scale(1.06)}
.practice-card .mode-strip .scenario>b{transition:background-color .24s ease,color .24s ease,transform .24s var(--motion-ease)}
.practice-card .mode-strip .scenario:hover>b{transform:translateX(2px)}

.daily-target>strong,
.performance-stat-row strong,
.record-summary strong{transition:color .3s ease}
.daily-challenge:hover .daily-target>strong{color:#0b93a7}

.page-close-button{transition:transform .3s var(--motion-ease),border-color .2s ease,color .2s ease,background-color .2s ease}

/* ---------- Focus visibility ---------- */

a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
.switch:focus-visible{
  outline:2px solid rgba(var(--motion-accent),.55);
  outline-offset:2px;
}
#game a:focus-visible,
#game button:focus-visible{outline-color:rgba(255,255,255,.5)}

/* ---------- Scroll reveal ---------- */

.motion-reveal{
  opacity:0;
  transform:translate3d(0,18px,0);
  transition:opacity .72s var(--motion-ease-out),transform .72s var(--motion-ease-out);
  transition-delay:var(--motion-delay,0ms);
}
.motion-reveal.is-visible{opacity:1;transform:none}

/* ---------- Leaderboard ---------- */

@keyframes motion-row-in{
  from{opacity:0;transform:translate3d(0,10px,0)}
  to{opacity:1;transform:none}
}
.leaderboard-table tbody tr.motion-row-in{
  animation:motion-row-in .45s var(--motion-ease-out) both;
  animation-delay:calc(var(--motion-i,0)*40ms);
}
.leaderboard-table tbody tr{transition:background-color .22s var(--motion-ease-soft),transform .26s var(--motion-ease),box-shadow .26s var(--motion-ease-soft)}
.leaderboard-table tbody tr:hover{
  transform:translateX(3px);
  box-shadow:inset 2px 0 0 rgba(var(--motion-accent),.55);
}

@media(prefers-reduced-motion:reduce){
  .motion-sheen,
  .motion-ripple,
  .motion-pill-indicator,
  .motion-progress{transition:none!important;animation:none!important}
  .motion-reveal{opacity:1!important;transform:none!important;transition:none!important}
  .leaderboard-table tbody tr.motion-row-in{animation:none!important;opacity:1!important;transform:none!important}
  .leaderboard-table tbody tr:hover{transform:none}
  .motion-pill-indicator{transition:none!important}
}
