/* ═══════════════════════════════════════════════
   ICE STREAMS SYSTEMS: illustration motion
   One vocabulary for every animated illustration on the site (the home
   page story and the service page diagrams). Elements carry an entrance
   kind (m-pop, m-type, m-draw ...) and a start time (d12 = 1.2 s). Nothing
   moves until the scene is running (.m-on): the home story turns it on for
   the current step, and figs.js turns it on when a diagram scrolls into
   view, then replays it gently on a loop. Only opacity, transform, clip
   and stroke offsets animate. With reduced motion every illustration rests
   in its finished state.
═══════════════════════════════════════════════ */
.m-svg { display: block; width: 100%; height: auto; overflow: visible; }
.m-svg text { font-kerning: normal; }
.m-stage { transition: opacity .9s ease; }
.m-fadeout .m-stage { opacity: 0; }
/* armed but not yet running: entrances wait hidden */
.m-armed:not(.m-on) .m-a:not(.m-out) { opacity: 0; }
.m-armed:not(.m-on) .m-was { opacity: 1; }

.m-on .m-a { animation-duration: .8s; animation-timing-function: cubic-bezier(.2,.75,.25,1); animation-fill-mode: both; transform-box: fill-box; }
.m-on .m-pop { animation-name: m-pop; transform-origin: center; }
.m-on .m-fade { animation-name: m-fade; animation-duration: 1.1s; animation-timing-function: ease; }
.m-on .m-rise { animation-name: m-rise; animation-duration: 1.2s; }
.m-on .m-type { animation-name: m-type; animation-duration: 1.2s; animation-timing-function: steps(30, jump-none); }
.m-on .m-type.ts { animation-duration: .6s; animation-timing-function: steps(14, jump-none); }
.m-on .m-type.tl { animation-duration: 1.9s; animation-timing-function: steps(44, jump-none); }
.m-on .m-draw { stroke-dasharray: 100; animation-name: m-draw; animation-duration: .9s; animation-timing-function: ease-out; }
.m-on .m-draw.slow { animation-duration: 2.2s; animation-timing-function: ease-in-out; }
.m-on .m-gx { animation-name: m-gx; transform-origin: left center; animation-duration: 1.1s; }
.m-on .m-gy { animation-name: m-gy; transform-origin: center bottom; animation-duration: 1.1s; }
.m-on .m-out { animation-name: m-out; animation-duration: .7s; animation-timing-function: ease; }
.m-on .m-stamp { animation-name: m-stamp; transform-origin: center; animation-duration: .55s; animation-timing-function: cubic-bezier(.3,1.4,.5,1); }
.m-on .m-press { animation-name: m-press; transform-origin: center; animation-duration: .5s; }
.m-on .m-hl { animation-name: m-hl; animation-duration: 2.2s; animation-timing-function: ease; }
.m-on .m-slide { animation-name: m-slide; animation-duration: 1s; }
.m-on .m-zoom { animation-name: m-zoom; transform-origin: center; animation-duration: 1.2s; }
@keyframes m-pop   { from { opacity: 0; transform: translateY(7px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes m-fade  { from { opacity: 0; } to { opacity: 1; } }
@keyframes m-rise  { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes m-type  { from { clip-path: inset(-20% 100% -20% 0); } to { clip-path: inset(-20% 0 -20% 0); } }
@keyframes m-draw  { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes m-gx    { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes m-gy    { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes m-out   { from { opacity: 1; } to { opacity: 0; } }
@keyframes m-stamp { from { opacity: 0; transform: scale(1.9) rotate(-8deg); } to { opacity: 1; transform: rotate(-8deg); } }
@keyframes m-press { 0% { transform: none; } 45% { transform: scale(.9); } 100% { transform: none; } }
@keyframes m-hl    { 0% { opacity: 0; } 18% { opacity: 1; } 100% { opacity: 0; } }
@keyframes m-slide { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: none; } }
@keyframes m-zoom  { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: none; } }

/* looping details: these idle gently once a scene has played in */
.m-on .m-blink { animation: m-blink 1.05s steps(1) infinite; }
.m-on .m-breathe { animation: m-breathe 3.2s ease-in-out infinite; }
.m-on .m-flow { stroke-dasharray: 3 7; animation: m-flow 1.4s linear infinite; }
.m-on .m-flow.slow { animation-duration: 2.6s; }
.m-on .m-spin { transform-box: fill-box; transform-origin: center; animation: m-spin 2.4s linear infinite; }
.m-on .m-dots circle { animation: m-dot 1.2s ease-in-out infinite; }
.m-on .m-dots circle:nth-child(2) { animation-delay: .18s; } .m-on .m-dots circle:nth-child(3) { animation-delay: .36s; }
@keyframes m-blink { 50% { opacity: 0; } }
@keyframes m-breathe { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes m-flow { to { stroke-dashoffset: -20; } }
@keyframes m-spin { to { transform: rotate(360deg); } }
@keyframes m-dot { 0%, 100% { opacity: .25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-1.5px); } }

/* the home story pauses with its controls */
.story.paused .m-on, .story.paused .m-on * { animation-play-state: paused !important; }

/* start times, in tenths of a second */
.m-on .d0{animation-delay:0.0s}.m-on .d1{animation-delay:0.1s}.m-on .d2{animation-delay:0.2s}.m-on .d3{animation-delay:0.3s}.m-on .d4{animation-delay:0.4s}.m-on .d5{animation-delay:0.5s}.m-on .d6{animation-delay:0.6s}.m-on .d7{animation-delay:0.7s}.m-on .d8{animation-delay:0.8s}.m-on .d9{animation-delay:0.9s}.m-on .d10{animation-delay:1.0s}.m-on .d11{animation-delay:1.1s}.m-on .d12{animation-delay:1.2s}.m-on .d13{animation-delay:1.3s}.m-on .d14{animation-delay:1.4s}.m-on .d15{animation-delay:1.5s}.m-on .d16{animation-delay:1.6s}.m-on .d17{animation-delay:1.7s}.m-on .d18{animation-delay:1.8s}.m-on .d19{animation-delay:1.9s}.m-on .d20{animation-delay:2.0s}.m-on .d21{animation-delay:2.1s}.m-on .d22{animation-delay:2.2s}.m-on .d23{animation-delay:2.3s}.m-on .d24{animation-delay:2.4s}.m-on .d25{animation-delay:2.5s}.m-on .d26{animation-delay:2.6s}.m-on .d27{animation-delay:2.7s}.m-on .d28{animation-delay:2.8s}.m-on .d29{animation-delay:2.9s}.m-on .d30{animation-delay:3.0s}.m-on .d31{animation-delay:3.1s}.m-on .d32{animation-delay:3.2s}.m-on .d33{animation-delay:3.3s}.m-on .d34{animation-delay:3.4s}.m-on .d35{animation-delay:3.5s}.m-on .d36{animation-delay:3.6s}.m-on .d37{animation-delay:3.7s}.m-on .d38{animation-delay:3.8s}.m-on .d39{animation-delay:3.9s}.m-on .d40{animation-delay:4.0s}.m-on .d41{animation-delay:4.1s}.m-on .d42{animation-delay:4.2s}.m-on .d43{animation-delay:4.3s}.m-on .d44{animation-delay:4.4s}.m-on .d45{animation-delay:4.5s}.m-on .d46{animation-delay:4.6s}.m-on .d47{animation-delay:4.7s}.m-on .d48{animation-delay:4.8s}.m-on .d49{animation-delay:4.9s}.m-on .d50{animation-delay:5.0s}.m-on .d51{animation-delay:5.1s}.m-on .d52{animation-delay:5.2s}.m-on .d53{animation-delay:5.3s}.m-on .d54{animation-delay:5.4s}.m-on .d55{animation-delay:5.5s}.m-on .d56{animation-delay:5.6s}.m-on .d57{animation-delay:5.7s}.m-on .d58{animation-delay:5.8s}.m-on .d59{animation-delay:5.9s}.m-on .d60{animation-delay:6.0s}.m-on .d61{animation-delay:6.1s}.m-on .d62{animation-delay:6.2s}.m-on .d63{animation-delay:6.3s}.m-on .d64{animation-delay:6.4s}.m-on .d65{animation-delay:6.5s}.m-on .d66{animation-delay:6.6s}.m-on .d67{animation-delay:6.7s}.m-on .d68{animation-delay:6.8s}.m-on .d69{animation-delay:6.9s}.m-on .d70{animation-delay:7.0s}.m-on .d71{animation-delay:7.1s}.m-on .d72{animation-delay:7.2s}.m-on .d73{animation-delay:7.3s}.m-on .d74{animation-delay:7.4s}.m-on .d75{animation-delay:7.5s}.m-on .d76{animation-delay:7.6s}.m-on .d77{animation-delay:7.7s}.m-on .d78{animation-delay:7.8s}.m-on .d79{animation-delay:7.9s}.m-on .d80{animation-delay:8.0s}.m-on .d81{animation-delay:8.1s}.m-on .d82{animation-delay:8.2s}.m-on .d83{animation-delay:8.3s}.m-on .d84{animation-delay:8.4s}.m-on .d85{animation-delay:8.5s}.m-on .d86{animation-delay:8.6s}.m-on .d87{animation-delay:8.7s}.m-on .d88{animation-delay:8.8s}.m-on .d89{animation-delay:8.9s}.m-on .d90{animation-delay:9.0s}.m-on .d91{animation-delay:9.1s}.m-on .d92{animation-delay:9.2s}.m-on .d93{animation-delay:9.3s}.m-on .d94{animation-delay:9.4s}.m-on .d95{animation-delay:9.5s}.m-on .d96{animation-delay:9.6s}.m-on .d97{animation-delay:9.7s}.m-on .d98{animation-delay:9.8s}.m-on .d99{animation-delay:9.9s}.m-on .d100{animation-delay:10.0s}.m-on .d101{animation-delay:10.1s}.m-on .d102{animation-delay:10.2s}.m-on .d103{animation-delay:10.3s}.m-on .d104{animation-delay:10.4s}.m-on .d105{animation-delay:10.5s}.m-on .d106{animation-delay:10.6s}.m-on .d107{animation-delay:10.7s}.m-on .d108{animation-delay:10.8s}.m-on .d109{animation-delay:10.9s}.m-on .d110{animation-delay:11.0s}.m-on .d111{animation-delay:11.1s}.m-on .d112{animation-delay:11.2s}.m-on .d113{animation-delay:11.3s}.m-on .d114{animation-delay:11.4s}.m-on .d115{animation-delay:11.5s}.m-on .d116{animation-delay:11.6s}.m-on .d117{animation-delay:11.7s}.m-on .d118{animation-delay:11.8s}.m-on .d119{animation-delay:11.9s}.m-on .d120{animation-delay:12.0s}.m-on .d121{animation-delay:12.1s}.m-on .d122{animation-delay:12.2s}.m-on .d123{animation-delay:12.3s}.m-on .d124{animation-delay:12.4s}.m-on .d125{animation-delay:12.5s}.m-on .d126{animation-delay:12.6s}.m-on .d127{animation-delay:12.7s}.m-on .d128{animation-delay:12.8s}.m-on .d129{animation-delay:12.9s}.m-on .d130{animation-delay:13.0s}.m-on .d131{animation-delay:13.1s}.m-on .d132{animation-delay:13.2s}.m-on .d133{animation-delay:13.3s}.m-on .d134{animation-delay:13.4s}.m-on .d135{animation-delay:13.5s}.m-on .d136{animation-delay:13.6s}.m-on .d137{animation-delay:13.7s}.m-on .d138{animation-delay:13.8s}.m-on .d139{animation-delay:13.9s}.m-on .d140{animation-delay:14.0s}.m-on .d141{animation-delay:14.1s}.m-on .d142{animation-delay:14.2s}.m-on .d143{animation-delay:14.3s}.m-on .d144{animation-delay:14.4s}.m-on .d145{animation-delay:14.5s}.m-on .d146{animation-delay:14.6s}.m-on .d147{animation-delay:14.7s}.m-on .d148{animation-delay:14.8s}.m-on .d149{animation-delay:14.9s}.m-on .d150{animation-delay:15.0s}.m-on .d151{animation-delay:15.1s}.m-on .d152{animation-delay:15.2s}.m-on .d153{animation-delay:15.3s}.m-on .d154{animation-delay:15.4s}.m-on .d155{animation-delay:15.5s}.m-on .d156{animation-delay:15.6s}.m-on .d157{animation-delay:15.7s}.m-on .d158{animation-delay:15.8s}.m-on .d159{animation-delay:15.9s}.m-on .d160{animation-delay:16.0s}

/* story scene 4: the owner's cursor visits the price, the holiday toggle, then Publish */
.m-on .mv-cur4 { animation: mv-cur4 6.2s cubic-bezier(.45,.05,.25,1) .6s both; }
@keyframes mv-cur4 {
  0%   { transform: translate(200px, 270px); opacity: 0; }
  8%   { opacity: 1; }
  28%  { transform: translate(292px, 100px); }
  44%  { transform: translate(292px, 100px); }
  58%  { transform: translate(286px, 212px); }
  68%  { transform: translate(286px, 212px); }
  82%  { transform: translate(276px, 260px); }
  100% { transform: translate(276px, 260px); opacity: 1; }
}
.m-on .mv-knob { transform-box: fill-box; animation: mv-knob .5s cubic-bezier(.3,.8,.3,1) 3.6s both; }
@keyframes mv-knob { from { transform: none; } to { transform: translateX(16px); } }

/* service diagrams: frame and caption */
.m-fig .m-svg { max-height: 360px; }
.m-fig figcaption { margin-top: 12px; font-size: 1rem; line-height: 1.5; color: var(--dim); max-width: 70ch; }
.m-fig figcaption b { color: var(--ice); font-weight: 600; }

/* hosting: the request goes out to the edge, the answer comes back */
.m-on .mv-req { animation: mv-req 2.6s cubic-bezier(.5,0,.4,1) 1.2s both; }
@keyframes mv-req { 0% { transform: translate(184px, 104px); opacity: 0; } 10% { opacity: 1; } 70% { transform: translate(262px, 100px); opacity: 1; } 100% { transform: translate(300px, 96px); opacity: 0; } }
.m-on .mv-res { animation: mv-res 1.6s cubic-bezier(.5,0,.4,1) 4.4s both; }
@keyframes mv-res { 0% { transform: translate(262px, 100px); opacity: 0; } 12% { opacity: 1; } 88% { transform: translate(184px, 104px); opacity: 1; } 100% { transform: translate(176px, 104px); opacity: 0; } }

/* web apps: the new request travels the board, collecting its status as it goes */
.m-on .mv-card { animation: mv-card 8s cubic-bezier(.55,0,.35,1) .6s both; }
@keyframes mv-card {
  0%   { transform: translate(0, -24px); opacity: 0; }
  6%   { transform: none; opacity: 1; }
  24%  { transform: none; }
  33%  { transform: translate(152px, 0); }
  50%  { transform: translate(152px, 0); }
  59%  { transform: translate(304px, 0); }
  76%  { transform: translate(304px, 0); }
  85%  { transform: translate(456px, 0); }
  100% { transform: translate(456px, 0); opacity: 1; }
}
.m-on .mv-tag1 { animation: mv-tag1 8s cubic-bezier(.55,0,.35,1) .6s both; }
@keyframes mv-tag1 { 0%, 26% { transform: translate(250px, 112px); opacity: 0; } 34% { transform: translate(250px, 112px); opacity: 1; } 50% { transform: translate(250px, 112px); } 59% { transform: translate(402px, 112px); } 76% { transform: translate(402px, 112px); opacity: 1; } 85%, 100% { transform: translate(554px, 112px); opacity: 0; } }
.m-on .mv-tag2 { animation: mv-tag2 8s cubic-bezier(.55,0,.35,1) .6s both; }
@keyframes mv-tag2 { 0%, 52% { transform: translate(452px, 90px); opacity: 0; } 60% { transform: translate(452px, 90px); opacity: 1; } 76% { transform: translate(452px, 90px); } 85%, 100% { transform: translate(604px, 90px); opacity: 1; } }
.m-on .mv-tag3 { animation: mv-tag3 8s ease .6s both; }
@keyframes mv-tag3 { 0%, 86% { transform: translate(568px, 106px); opacity: 0; } 94%, 100% { transform: translate(568px, 106px); opacity: 1; } }

/* owner dashboard: a finger taps the price, the notice switch, then Save */
.m-on .mv-tap { animation: mv-tap 5s cubic-bezier(.45,.05,.25,1) .4s both; }
@keyframes mv-tap { 0% { transform: translate(120px, 250px); opacity: 0; } 10% { opacity: 1; } 28%, 42% { transform: translate(150px, 82px); } 62%, 72% { transform: translate(146px, 172px); } 88%, 100% { transform: translate(112px, 228px); opacity: 1; } }
.m-on .mv-knob2 { transform-box: fill-box; animation: mv-knob2 .5s cubic-bezier(.3,.8,.3,1) 3.6s both; }
@keyframes mv-knob2 { from { transform: none; } to { transform: translateX(13px); } }

/* networking: an allowed packet leaves for the internet, a guest packet is stopped */
.m-on .mv-ok { animation: mv-ok 2.4s cubic-bezier(.5,0,.5,1) 2.2s both; }
@keyframes mv-ok { 0% { transform: translate(172px, 66px); opacity: 0; } 8% { opacity: 1; } 45% { transform: translate(238px, 78px); } 60% { transform: translate(320px, 60px); } 92% { transform: translate(320px, 40px); opacity: 1; } 100% { transform: translate(320px, 36px); opacity: 0; } }
.m-on .mv-bad { animation: mv-bad 1.8s cubic-bezier(.5,0,.5,1) 3.4s both; }
@keyframes mv-bad { 0% { transform: translate(468px, 66px); opacity: 0; } 10% { opacity: 1; } 70% { transform: translate(426px, 80px); opacity: 1; } 82% { transform: translate(440px, 76px); } 100% { transform: translate(452px, 72px); opacity: 0; } }

/* process automation: the scan beam passes down the page */
.m-on .mv-scan { animation: mv-scan 2.2s ease-in-out .9s both; }
@keyframes mv-scan { 0% { transform: translateY(18px); opacity: 0; } 8% { opacity: 1; } 92% { transform: translateY(236px); opacity: 1; } 100% { transform: translateY(240px); opacity: 0; } }
.m-armed:not(.m-on) .mv-scan, .m-armed:not(.m-on) [class*="mv-"] { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .mv-scan, .mv-req, .mv-res, .mv-ok, .mv-bad, .mv-tap, .mv-cur4, .mv-tag1 { display: none; }
  .mv-card { transform: translate(456px, 0); } .mv-tag2 { transform: translate(604px, 90px); } .mv-tag3 { transform: translate(568px, 106px); }
  .mv-knob, .mv-knob2 { transform: translateX(14px); }
}

@media (prefers-reduced-motion: reduce) {
  .m-on .m-a, .m-on .m-blink, .m-on .m-breathe, .m-on .m-flow, .m-on .m-spin, .m-on .m-dots circle, .m-on [class*="mv-"] { animation: none !important; }
  .m-armed:not(.m-on) .m-a { opacity: 1; }
  .m-was { display: none; }
}
