/* Moments (js/moments.js): what the interface marks when something happens.
 *
 * Each is set off by an event and over in about a second, and moves only
 * transforms and opacity (docs/speed.md). The endless ones (the star's points
 * while something waits) run only while it waits. Under Reduced motion each
 * has a still form: the base rule in base.css takes every animation to its end.
 */

/* -- the star's points, lighting in turn ----------------------------------- */
/* A point is bright as the light reaches it and dims behind it, so the light
   goes round like the hand of a sundial. At rest, and under Reduced motion,
   every point is whole. */
@keyframes star-point { 0% { opacity: 1; } 55%, 100% { opacity: 0.24; } }

/* -- the avatar -------------------------------------------------------------- */
/* The spark sits straight on the page; on a light one its heart is gold. */
html:not(.dark) .star-mark .heart { fill: var(--star-gold); }

/* -- the loader -------------------------------------------------------------- */
/* The four-pointed spark in gold, a deeper gold on light pages. It waits a
   moment before it shows, so a quick load never flashes it. On a filled button
   it takes the button's own text colour. */
.icon.star-loader {
  display: inline-flex;
  flex: none;
  width: 1em;
  height: 1em;
  color: var(--star-gold);
  animation: loader-wait 1ms linear 280ms both;
}
.btn.primary .icon.star-loader, .mz-capsule .send .icon.star-loader { color: inherit; }
.star-loader svg { width: 100%; height: 100%; display: block; overflow: visible; }
.star-loader .pt, .star-loader .heart { fill: currentColor; }
.star-loader .pt {
  animation: star-ray 0.96s linear infinite;
  animation-delay: calc((var(--i) - 4) * 0.24s);
}
/* A loader's resting rays stay clear enough to read as the spark at 13 px. */
@keyframes star-ray { 0% { opacity: 1; } 55%, 100% { opacity: 0.4; } }
@keyframes loader-wait { from { opacity: 0; } to { opacity: 1; } }

/* -- done, said with tiles ----------------------------------------------------- */
.confirm-chip {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 4px;
  height: 4px;
  border-radius: 1px;
  pointer-events: none;
  opacity: 0;
}

/* -- a paragraph settling --------------------------------------------------- */
/* Begun while an answer is written: it rises 4px from a little faint. A block
   with no words to ink in (code, a table, maths, a picture) fades in itself,
   from fainter and a little slower (js/chat.js settleNew). */
.body > .settle { animation: block-settle 180ms var(--ease-out) both; }
.body > .settle.whole { animation: block-whole 360ms var(--ease-out) both; }
@keyframes block-settle { from { opacity: 0.55; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes block-whole { from { opacity: 0.15; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* -- words coming in ---------------------------------------------------------- */
/* Words being written fade in a few at a time, each few a step after the
   ones before (js/chat.js inkWords), so the newest trail off to the right in
   one continuous fade; then they are plain text again. */
#view-chat span.ink { animation: ink-in 640ms cubic-bezier(0.25, 0.1, 0.25, 1) both; }
@keyframes ink-in { from { opacity: 0; } to { opacity: 1; } }

/* -- words taken back ----------------------------------------------------------- */
/* Words already shown that the answer takes back (an opening written again
   after a step, a draft replaced) stay where they stood, faded, while the work
   that replaces them goes on; once new words come they lift out of the flow,
   so the new words take their place, and fade away (js/chat.js withdraw). */
#view-chat .withdrawing { position: relative; }
#view-chat .withdrawing > .withdrawn { pointer-events: none; user-select: none; }
#view-chat .withdrawing > .withdrawn.waiting { animation: words-wait var(--dur-slow) var(--ease) both; }
#view-chat .withdrawing > .withdrawn.leaving {
  position: absolute;
  left: 0;
  right: 0;
  animation: withdraw 320ms var(--ease) both;
}
#view-chat .withdrawing > .withdrawn.leaving.waited { animation-name: withdraw-waited; }
@keyframes words-wait { from { opacity: 1; } to { opacity: 0.4; } }
/* Words taken back and then written again brighten where they stood. */
#view-chat .words-back { animation: words-back var(--dur-slow) var(--ease) both; }
@keyframes words-back { from { opacity: 0.4; } to { opacity: 1; } }
@keyframes withdraw { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-6px); } }
@keyframes withdraw-waited { from { opacity: 0.4; transform: none; } to { opacity: 0; transform: translateY(-6px); } }

/* -- dusk in one frame -------------------------------------------------------- */
.theme-toggle .icon.turning { animation: theme-turn 420ms var(--ease-spring) both; }
@keyframes theme-turn { from { opacity: 0.4; transform: rotate(-90deg) scale(0.6); } to { opacity: 1; transform: none; } }

/* -- the Star Window setting -------------------------------------------------- */
/* Its tiles from the centre out, then the star turning into place. */
.logo-set svg { width: 100%; height: 100%; display: block; }
.logo-set .tile, .logo-set .star { transform-box: fill-box; transform-origin: center; }
.logo-set .tile { animation: logo-tile 620ms var(--ease-out) both; }
.logo-set .star { animation: logo-star 700ms var(--ease-spring) 640ms both; }
@keyframes logo-tile { from { opacity: 0.12; transform: scale(0.3) rotate(-10deg); } to { opacity: 1; transform: none; } }
@keyframes logo-star { from { opacity: 0.3; transform: scale(0.55) rotate(-22.5deg); } to { opacity: 1; transform: none; } }
