/* Memory Universe — motion layer. Loads on top of mu.css. One curve; linear for travel; accelerating for revocation. */
:root{--ease:cubic-bezier(.2,.7,.2,1);--ease-fast:cubic-bezier(.4,0,1,1)}
/* Nothing below applies unless the JS has confirmed motion is wanted. */
.mu-motion .mu-a{opacity:0;transform:translateY(12px);transition:opacity .34s var(--ease) var(--d,0s),transform .34s var(--ease) var(--d,0s)}
.mu-motion .mu-a.mu-in{opacity:1;transform:none}
/* the agent's state line and the governance record arrive after the human's words */
.mu-motion .mu-a .acting,.mu-motion .mu-a .stamps,.mu-motion .mu-a .pitem em{opacity:0;transition:opacity .2s var(--ease) var(--d2,0s)}
.mu-motion .mu-a.mu-in .acting,.mu-motion .mu-a.mu-in .stamps,.mu-motion .mu-a.mu-in .pitem em{opacity:1}
/* stamps scale in rather than fade, so a governance mark reads as being applied */
.mu-motion .mu-a .stamp{transform:scale(.94);transition:transform .18s var(--ease) var(--d2,0s)}
.mu-motion .mu-a.mu-in .stamp{transform:none}
/* terminals: real text, revealed by clip in discrete line steps — never injected characters */
.mu-motion .mu-clip{clip-path:inset(0 0 100% 0);transition:clip-path var(--dur,1.4s) linear var(--d,0s)}
.mu-motion .mu-clip.mu-in{clip-path:inset(0 0 0 0)}
.mu-motion .mu-clip.mu-fast{transition-timing-function:var(--ease-fast)}
/* the live caret: appears when the session has finished printing and sits waiting, as a real one does */
@keyframes mu-blink{0%,49%{opacity:1}50%,100%{opacity:0}}
.mu-motion .term-body{position:relative}
.mu-motion .term-caret{display:inline-block;width:.55em;height:1.05em;background:currentColor;vertical-align:-.18em;margin-left:.12em;opacity:0}
.mu-motion .mu-in .term-caret{animation:mu-blink 1.06s steps(1,end) infinite;animation-delay:var(--caret,0s)}
/* the private overlay's lit edge arrives last */
.mu-motion .overlay.mu-a{border-left-color:transparent;transition:opacity .3s var(--ease) var(--d,0s),transform .3s var(--ease) var(--d,0s),border-left-color .2s var(--ease) var(--d2,0s)}
.mu-motion .overlay.mu-a.mu-in{border-left-color:var(--priv-edge)}
/* M05 — foreground one private view; the shared record must not move */
@media (hover:hover){.mu-motion .mu-overlays:hover .overlay{opacity:.55;transition:opacity .16s var(--ease)}
.mu-motion .mu-overlays .overlay:hover,.mu-motion .mu-overlays .overlay:focus-within{opacity:1}}
/* M06 — the station line draws at constant velocity, so the gaps read as elapsed time */
.mu-motion .stations{border-top-color:transparent;background-image:linear-gradient(var(--ink),var(--ink));background-repeat:no-repeat;background-position:0 0;background-size:0 1px;transition:background-size 1.1s linear}
.mu-motion .stations.mu-in{background-size:100% 1px}
/* M01/M15 — the rail draws once, then its active node tracks the scene in view */
.mu-motion .rail:before{transform:scaleY(0);transform-origin:top;transition:transform .9s ease-out .2s}
.mu-motion.mu-ready .rail:before{transform:scaleY(1)}
.rail a.is-active:before{background:var(--ink);border-color:var(--ink)}
/* the always-on active label only clears the content column once the page margin is
   wide enough; below that the filled dot carries the active state and the label is
   still available on hover. */
@media (min-width:1660px){.rail a.is-active span{opacity:1}}
.mu-motion .rail a:before{transition:background .2s var(--ease),border-color .2s var(--ease)}
/* M16 — form error */
.input.mu-err{border-color:var(--revoke)}
@media (prefers-reduced-motion:reduce){
.mu-a,.mu-clip{opacity:1!important;transform:none!important;clip-path:none!important}
.term-caret{display:none!important}
.stations{background-size:100% 1px!important;border-top-color:var(--ink)!important}
.rail:before{transform:none!important}
}
