/*
 * The machine — the hero, and its motion.
 *
 * A conveyor ring in anodised navy and polished chrome with amber light in
 * every seam a machine would actually have one, and floating inside it on
 * nothing at all, an obsidian slab carrying three stations: money, a vault,
 * goods. It is a loop on purpose — the only shape that can honestly repeat for
 * ever without a seam.
 *
 * Four things are worth knowing before editing.
 *
 *   The cargo follows a real CSS motion path, so it curves with the ellipse
 *   rather than being translated in straight lines. One animation, twelve
 *   phases: the negative delays are constant, so the spacing is as true on the
 *   thousandth lap as the first. A second animation of the same length scales
 *   each piece — largest at the front of the ring, smallest at the back — and
 *   because it shares the delay it can never drift out of step with the path.
 *
 *   The medal over the vault is not three-dimensional. A disc turning about a
 *   vertical axis projects to its face scaled horizontally by cos, and its rim
 *   by |sin|. So the face, the blank reverse and the milled rim are three flat
 *   shapes sharing one clock, and the result is a real turning coin — edge and
 *   all — with no 3D context, no backface tricks and nothing to go wrong in an
 *   old browser. The keyframes at the bottom of this file are that cosine,
 *   sampled every fortieth of a turn, and the rank medals use them too.
 *
 *   The amber runs on its own short clocks — the sockets chase, the groove
 *   breathes, the vault opens on a long cycle. A machine where every last
 *   thing is synchronised reads as a cartoon.
 *
 *   Nothing is filled behind any of it. The background is the page.
 */

.fac{position:relative}
.fac-panel{position:relative}
.rg-svg{display:block;width:100%;height:auto;overflow:visible}

.kg-mface,.kg-mback,.kg-mrim,.kg-medal{transform-origin:457.9px 281.0px}
.kg-mshadow{transform-origin:458px 349px}
.kg-cargo,.kg-rider,.kg-sheen,.kg-medal,.kg-mface,.kg-mback,.kg-mrim,.kg-mshadow,
.kg-sock,.kg-rail,.kg-well,.kg-halo,.kg-petal,.kg-blk-lift,.kg-joint,.kg-groove{
  transform-box:view-box}
.kg-rider-in{transform-box:fill-box;transform-origin:center}
.kg-rider{
  offset-path:path('M 704.5,372 A 252.5,126 0 1 1 199.5,372 A 252.5,126 0 1 1 704.5,372');
  offset-rotate:0deg;animation:kgRide 22s linear infinite;
  animation-delay:calc(var(--i) * -1.8333s);will-change:offset-distance}
@keyframes kgRide{from{offset-distance:0%}to{offset-distance:100%}}
.kg-rider-in{animation:kgDepth 22s linear infinite;animation-delay:calc(var(--i) * -1.8333s)}
@keyframes kgDepth{
  0%{transform:scale(.95);opacity:.95}
  25%{transform:scale(1.14);opacity:1}
  50%{transform:scale(.95);opacity:.95}
  75%{transform:scale(.78);opacity:.7}
  100%{transform:scale(.95);opacity:.95}
}
.kg-sheen{animation:kgSheen 7s linear infinite}
@keyframes kgSheen{from{stroke-dashoffset:0}to{stroke-dashoffset:calc(var(--len) * -1)}}
.kg-sock{animation:kgChase 3s linear infinite;animation-delay:calc(var(--i) * -.1875s)}
@keyframes kgChase{0%{opacity:.35}10%{opacity:1}34%{opacity:.35}100%{opacity:.35}}
.kg-rail{animation:kgChase 1.7s linear infinite;animation-delay:calc(var(--i) * .18s)}
.kg-groove{animation:kgBreathe 9s ease-in-out infinite}
@keyframes kgBreathe{0%,100%{opacity:.6}50%{opacity:.95}}

/* the vault: eight petals drawing back and shutting again */
.kg-petal{transform-origin:center;animation:kgPetal 18s cubic-bezier(.45,0,.25,1) infinite;
  animation-delay:calc(var(--i) * .04s)}
@keyframes kgPetal{
  0%,34%{transform:translate(0,0)}
  46%,62%{transform:translate(var(--dx),var(--dy))}
  74%,100%{transform:translate(0,0)}
}
.kg-well{animation:kgWell 18s ease-in-out infinite;transform-origin:center}
@keyframes kgWell{0%,30%{opacity:.55}48%,60%{opacity:1}76%,100%{opacity:.55}}
.kg-halo{transform-origin:center;animation:kgHalo 18s ease-in-out infinite}
@keyframes kgHalo{0%,30%{opacity:.5;transform:scale(.88)}50%{opacity:1;transform:scale(1.1)}76%,100%{opacity:.5;transform:scale(.88)}}
.kg-joint{animation:kgBreathe 5.5s ease-in-out infinite}

/* one block still hanging above its slot */
.kg-blk-lift{animation:kgLift 6.5s ease-in-out infinite}
@keyframes kgLift{0%,100%{transform:translateY(-22px)}50%{transform:translateY(-6px)}}

/* the medal over the well, turning on its own axis */
.kg-mface{animation:medFace 9s linear infinite}
.kg-mback{animation:medBack 9s linear infinite}
.kg-mrim{animation:medRim 9s linear infinite}
.kg-mshadow{animation:medRim 9s linear infinite;opacity:.5}
.kg-medal{animation:kgHover 7.5s ease-in-out infinite}
@keyframes kgHover{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}

.fac.is-idle .rg-svg,.fac.is-idle .rg-svg *{animation-play-state:paused}

@media(prefers-reduced-motion:reduce){
  .rg-svg,.rg-svg *{animation:none!important}
  /* left standing: the cargo spread round the deck, the vault shut, the medal
     facing you, the loose block still hanging where it hangs */
  .kg-rider{offset-distance:calc(var(--i) * 8.3333%)}
  .kg-petal{transform:translate(0,0)}
  .kg-mface{transform:scaleX(1);opacity:1}
  .kg-mback{opacity:0}
  .kg-mrim{transform:scaleX(.02)}
  .kg-mshadow{transform:scaleX(.9);opacity:.4}
  .kg-blk-lift{transform:translateY(-14px)}
  .kg-sheen{opacity:.3}
  .kg-sock,.kg-rail{opacity:.75}
}

/* ============================================================
   The trade, built as a structure.

   One course of blocks for each stage a trade has actually reached — agreed,
   paid, shipped, checked, released. Courses that have not been earned are
   drawn as an empty dashed outline, never as a solid block: a trade that has
   not been paid for must not look like one that nearly has.

   It builds once, when the page opens, from the bottom up.
   ============================================================ */

.tw{--tw-fall:.66s;position:relative;flex:0 0 auto;width:230px}
.tw svg{display:block;width:100%;height:auto;overflow:visible}
.tw-course{opacity:0}
.tw[data-stage="1"] .tw-course[data-c="0"],
.tw[data-stage="2"] .tw-course[data-c="0"],
.tw[data-stage="2"] .tw-course[data-c="1"],
.tw[data-stage="3"] .tw-course[data-c="0"],
.tw[data-stage="3"] .tw-course[data-c="1"],
.tw[data-stage="3"] .tw-course[data-c="2"],
.tw[data-stage="4"] .tw-course[data-c="0"],
.tw[data-stage="4"] .tw-course[data-c="1"],
.tw[data-stage="4"] .tw-course[data-c="2"],
.tw[data-stage="4"] .tw-course[data-c="3"],
.tw[data-stage="5"] .tw-course{opacity:1}

.tw-blk{transform-box:view-box;transform-origin:center;
  animation:twDrop var(--tw-fall) cubic-bezier(.3,1.22,.5,1) both;
  animation-delay:calc(var(--c) * .3s + var(--k) * .085s + .15s)}
@keyframes twDrop{
  0%  {transform:translate(0,-84px);opacity:0}
  30% {opacity:1}
  76% {transform:translate(0,3px);opacity:1}
  100%{transform:translate(0,0);opacity:1}
}
/* The ghost of a course still to come: an outline with nothing inside it. */
.tw-ghost{opacity:0;transition:opacity .4s}
.tw[data-stage="0"] .tw-ghost[data-c="0"],
.tw[data-stage="0"] .tw-ghost[data-c="1"],.tw[data-stage="1"] .tw-ghost[data-c="1"],
.tw[data-stage="0"] .tw-ghost[data-c="2"],.tw[data-stage="1"] .tw-ghost[data-c="2"],
.tw[data-stage="2"] .tw-ghost[data-c="2"],
.tw[data-stage="0"] .tw-ghost[data-c="3"],.tw[data-stage="1"] .tw-ghost[data-c="3"],
.tw[data-stage="2"] .tw-ghost[data-c="3"],.tw[data-stage="3"] .tw-ghost[data-c="3"],
.tw[data-stage="0"] .tw-ghost[data-c="4"],.tw[data-stage="1"] .tw-ghost[data-c="4"],
.tw[data-stage="2"] .tw-ghost[data-c="4"],.tw[data-stage="3"] .tw-ghost[data-c="4"],
.tw[data-stage="4"] .tw-ghost[data-c="4"]{opacity:.5}

/* Every seam is dark but the newest one, which is where the trade actually is. */
.tw-seam{opacity:0;transition:opacity .4s}
.tw[data-stage="1"] .tw-course[data-c="0"] .tw-seam,
.tw[data-stage="2"] .tw-course[data-c="1"] .tw-seam,
.tw[data-stage="3"] .tw-course[data-c="2"] .tw-seam,
.tw[data-stage="4"] .tw-course[data-c="3"] .tw-seam,
.tw[data-stage="5"] .tw-course[data-c="4"] .tw-seam{opacity:.9;
  animation:twSeam 3.4s ease-in-out infinite;animation-delay:calc(var(--c) * .3s + 1.1s)}
@keyframes twSeam{0%,100%{opacity:.45}50%{opacity:1}}

.tw-cap{opacity:0;transform-box:view-box;transform-origin:center}
.tw[data-stage="5"] .tw-cap{opacity:1;animation:twCap .7s cubic-bezier(.3,1.3,.5,1) 1.75s both}
@keyframes twCap{
  0%  {transform:translate(0,-64px);opacity:0}
  40% {opacity:1}
  80% {transform:translate(0,2px)}
  100%{transform:translate(0,0);opacity:1}
}

/* A frozen trade is a frozen structure: the warmth goes out of it and it stops
   breathing. Nothing is removed — what happened still happened. */
.tw[data-frozen] .tw-seam{animation:none!important;opacity:.3;filter:grayscale(1)}
.tw[data-frozen] svg{filter:grayscale(.85) brightness(.82)}

@media(prefers-reduced-motion:reduce){
  .tw-blk,.tw-cap{animation:none!important;transform:none;opacity:1}
  .tw-seam{animation:none!important}
}


/* The cosine of one turn, sampled. Shared by the hero medal and the rank
   medals in the rewards section — one coin, two places. */
@keyframes medFace{
  0.0%{transform:scaleX(1.0000);opacity:1}
  2.5%{transform:scaleX(0.9877);opacity:1}
  5.0%{transform:scaleX(0.9511);opacity:1}
  7.5%{transform:scaleX(0.8910);opacity:1}
  10.0%{transform:scaleX(0.8090);opacity:1}
  12.5%{transform:scaleX(0.7071);opacity:1}
  15.0%{transform:scaleX(0.5878);opacity:1}
  17.5%{transform:scaleX(0.4540);opacity:1}
  20.0%{transform:scaleX(0.3090);opacity:1}
  22.5%{transform:scaleX(0.1564);opacity:1}
  25.0%{transform:scaleX(0.0008);opacity:1}
  27.5%{transform:scaleX(0.0008);opacity:0}
  30.0%{transform:scaleX(0.0008);opacity:0}
  32.5%{transform:scaleX(0.0008);opacity:0}
  35.0%{transform:scaleX(0.0008);opacity:0}
  37.5%{transform:scaleX(0.0008);opacity:0}
  40.0%{transform:scaleX(0.0008);opacity:0}
  42.5%{transform:scaleX(0.0008);opacity:0}
  45.0%{transform:scaleX(0.0008);opacity:0}
  47.5%{transform:scaleX(0.0008);opacity:0}
  50.0%{transform:scaleX(0.0008);opacity:0}
  52.5%{transform:scaleX(0.0008);opacity:0}
  55.0%{transform:scaleX(0.0008);opacity:0}
  57.5%{transform:scaleX(0.0008);opacity:0}
  60.0%{transform:scaleX(0.0008);opacity:0}
  62.5%{transform:scaleX(0.0008);opacity:0}
  65.0%{transform:scaleX(0.0008);opacity:0}
  67.5%{transform:scaleX(0.0008);opacity:0}
  70.0%{transform:scaleX(0.0008);opacity:0}
  72.5%{transform:scaleX(0.0008);opacity:0}
  75.0%{transform:scaleX(0.0008);opacity:0}
  77.5%{transform:scaleX(0.1564);opacity:1}
  80.0%{transform:scaleX(0.3090);opacity:1}
  82.5%{transform:scaleX(0.4540);opacity:1}
  85.0%{transform:scaleX(0.5878);opacity:1}
  87.5%{transform:scaleX(0.7071);opacity:1}
  90.0%{transform:scaleX(0.8090);opacity:1}
  92.5%{transform:scaleX(0.8910);opacity:1}
  95.0%{transform:scaleX(0.9511);opacity:1}
  97.5%{transform:scaleX(0.9877);opacity:1}
  100.0%{transform:scaleX(1.0000);opacity:1}
}
@keyframes medBack{
  0.0%{transform:scaleX(0.0008);opacity:0}
  2.5%{transform:scaleX(0.0008);opacity:0}
  5.0%{transform:scaleX(0.0008);opacity:0}
  7.5%{transform:scaleX(0.0008);opacity:0}
  10.0%{transform:scaleX(0.0008);opacity:0}
  12.5%{transform:scaleX(0.0008);opacity:0}
  15.0%{transform:scaleX(0.0008);opacity:0}
  17.5%{transform:scaleX(0.0008);opacity:0}
  20.0%{transform:scaleX(0.0008);opacity:0}
  22.5%{transform:scaleX(0.0008);opacity:0}
  25.0%{transform:scaleX(0.0008);opacity:0}
  27.5%{transform:scaleX(0.1564);opacity:1}
  30.0%{transform:scaleX(0.3090);opacity:1}
  32.5%{transform:scaleX(0.4540);opacity:1}
  35.0%{transform:scaleX(0.5878);opacity:1}
  37.5%{transform:scaleX(0.7071);opacity:1}
  40.0%{transform:scaleX(0.8090);opacity:1}
  42.5%{transform:scaleX(0.8910);opacity:1}
  45.0%{transform:scaleX(0.9511);opacity:1}
  47.5%{transform:scaleX(0.9877);opacity:1}
  50.0%{transform:scaleX(1.0000);opacity:1}
  52.5%{transform:scaleX(0.9877);opacity:1}
  55.0%{transform:scaleX(0.9511);opacity:1}
  57.5%{transform:scaleX(0.8910);opacity:1}
  60.0%{transform:scaleX(0.8090);opacity:1}
  62.5%{transform:scaleX(0.7071);opacity:1}
  65.0%{transform:scaleX(0.5878);opacity:1}
  67.5%{transform:scaleX(0.4540);opacity:1}
  70.0%{transform:scaleX(0.3090);opacity:1}
  72.5%{transform:scaleX(0.1564);opacity:1}
  75.0%{transform:scaleX(0.0008);opacity:1}
  77.5%{transform:scaleX(0.0008);opacity:0}
  80.0%{transform:scaleX(0.0008);opacity:0}
  82.5%{transform:scaleX(0.0008);opacity:0}
  85.0%{transform:scaleX(0.0008);opacity:0}
  87.5%{transform:scaleX(0.0008);opacity:0}
  90.0%{transform:scaleX(0.0008);opacity:0}
  92.5%{transform:scaleX(0.0008);opacity:0}
  95.0%{transform:scaleX(0.0008);opacity:0}
  97.5%{transform:scaleX(0.0008);opacity:0}
  100.0%{transform:scaleX(0.0008);opacity:0}
}
@keyframes medRim{
  0.0%{transform:scaleX(0.0008)}
  2.5%{transform:scaleX(0.1564)}
  5.0%{transform:scaleX(0.3090)}
  7.5%{transform:scaleX(0.4540)}
  10.0%{transform:scaleX(0.5878)}
  12.5%{transform:scaleX(0.7071)}
  15.0%{transform:scaleX(0.8090)}
  17.5%{transform:scaleX(0.8910)}
  20.0%{transform:scaleX(0.9511)}
  22.5%{transform:scaleX(0.9877)}
  25.0%{transform:scaleX(1.0000)}
  27.5%{transform:scaleX(0.9877)}
  30.0%{transform:scaleX(0.9511)}
  32.5%{transform:scaleX(0.8910)}
  35.0%{transform:scaleX(0.8090)}
  37.5%{transform:scaleX(0.7071)}
  40.0%{transform:scaleX(0.5878)}
  42.5%{transform:scaleX(0.4540)}
  45.0%{transform:scaleX(0.3090)}
  47.5%{transform:scaleX(0.1564)}
  50.0%{transform:scaleX(0.0008)}
  52.5%{transform:scaleX(0.1564)}
  55.0%{transform:scaleX(0.3090)}
  57.5%{transform:scaleX(0.4540)}
  60.0%{transform:scaleX(0.5878)}
  62.5%{transform:scaleX(0.7071)}
  65.0%{transform:scaleX(0.8090)}
  67.5%{transform:scaleX(0.8910)}
  70.0%{transform:scaleX(0.9511)}
  72.5%{transform:scaleX(0.9877)}
  75.0%{transform:scaleX(1.0000)}
  77.5%{transform:scaleX(0.9877)}
  80.0%{transform:scaleX(0.9511)}
  82.5%{transform:scaleX(0.8910)}
  85.0%{transform:scaleX(0.8090)}
  87.5%{transform:scaleX(0.7071)}
  90.0%{transform:scaleX(0.5878)}
  92.5%{transform:scaleX(0.4540)}
  95.0%{transform:scaleX(0.3090)}
  97.5%{transform:scaleX(0.1564)}
  100.0%{transform:scaleX(0.0008)}
}
