/* maximo.today — анимация знака «m.»
 *
 * Три состояния на чистом CSS, без зависимостей:
 *   .is-intro   — один проигрыш при загрузке (точка прилетает и садится)
 *   .is-bead    — цикл «аватар думает» (просвет бежит по аркам буквы)
 *   .is-pulse   — цикл «аватар думает», тихий вариант (точка дышит)
 *   .is-landed  — ответ пришёл (точка возвращается с перелётом)
 *
 * Разметка знака должна содержать классы .tile .letter .dot и ДОПОЛНИТЕЛЬНУЮ
 * окружность .bead — она нужна только для is-bead:
 *
 *   <svg class="mark" viewBox="0 0 120 120" aria-hidden="true">
 *     <rect class="tile" width="120" height="120" rx="30"/>
 *     <path class="letter" d="M 17.986 87.191 …"/>
 *     <circle class="dot" cx="95.591" cy="80.393" r="6.798"/>
 *     <circle class="bead" cx="0" cy="0" r="4.8"/>
 *   </svg>
 */

.mark {
  --mark-tile: #FAED00;
  --mark-ink: #0E0E0F;
  display: block;
}

/* инверсия: тёмная плитка, жёлтый знак. Бусина подхватывает цвет плитки сама */
.mark.is-inverse {
  --mark-tile: #0E0E0F;
  --mark-ink: #FAED00;
}

.mark .tile { fill: var(--mark-tile); }
.mark .letter,
.mark .dot { fill: var(--mark-ink); }

/* ВАЖНО: бусина — цвета ПЛИТКИ, а не буквы.
 * Она едет по осевой линии арок, то есть внутри чёрного штриха, и читается
 * как просвет, бегущий по букве. Если залить её цветом буквы, она станет
 * невидимой — чёрное по чёрному. Радиус 4.8 при толщине штриха 12.27
 * оставляет по краям ink и не даёт бусине выесть внешний контур. */
.mark .bead { fill: var(--mark-tile); opacity: 0; }

/* --- интро: точка прилетает ------------------------------------------- */
.mark.is-intro .tile   { animation: markTileIn .44s cubic-bezier(.2,.8,.3,1) both; }
.mark.is-intro .letter { animation: markLetterIn .40s cubic-bezier(.2,.8,.3,1) .10s both; }
.mark.is-intro .dot    { animation: markDotLand .52s cubic-bezier(.34,1.35,.5,1) .26s both; }

@keyframes markTileIn   { from { opacity: 0; transform: scale(.93); }
                          to   { opacity: 1; transform: scale(1); } }
@keyframes markLetterIn { from { opacity: 0; transform: translateY(5px); }
                          to   { opacity: 1; transform: none; } }
@keyframes markDotLand  { 0%   { opacity: 0; transform: translate(15px, -24px) scale(.5); }
                          60%  { opacity: 1; }
                          100% { opacity: 1; transform: none; } }

/* --- думает: просвет бежит по аркам ------------------------------------ */
.mark.is-bead .dot  { animation: markDotDim .3s ease both; }
.mark.is-bead .bead { animation: markBeadRun 1.5s cubic-bezier(.45,0,.55,1) infinite,
                                 markBeadFade 1.5s linear infinite; }

@keyframes markDotDim  { to { opacity: .22; } }
@keyframes markBeadFade { 0%, 100% { opacity: 0; } 12%, 88% { opacity: 1; } }

/* 21 опорный кадр — точки настоящих окружностей арок:
 * центры (36.3965 · 51.315) и (60.9430 · 51.315), радиус 12.2735.
 * Меньше кадров — и бусина начнёт срезать дугу по хорде. */
@keyframes markBeadRun {
  0%   { transform: translate(24.12px, 51.31px); }
  5%   { transform: translate(24.72px, 47.52px); }
  10%  { transform: translate(26.47px, 44.10px); }
  15%  { transform: translate(29.18px, 41.39px); }
  20%  { transform: translate(32.60px, 39.64px); }
  25%  { transform: translate(36.40px, 39.04px); }
  30%  { transform: translate(40.19px, 39.64px); }
  35%  { transform: translate(43.61px, 41.39px); }
  40%  { transform: translate(46.33px, 44.10px); }
  45%  { transform: translate(48.07px, 47.52px); }
  50%  { transform: translate(48.67px, 51.31px); }
  55%  { transform: translate(49.27px, 47.52px); }
  60%  { transform: translate(51.01px, 44.10px); }
  65%  { transform: translate(53.73px, 41.39px); }
  70%  { transform: translate(57.15px, 39.64px); }
  75%  { transform: translate(60.94px, 39.04px); }
  80%  { transform: translate(64.74px, 39.64px); }
  85%  { transform: translate(68.16px, 41.39px); }
  90%  { transform: translate(70.87px, 44.10px); }
  95%  { transform: translate(72.62px, 47.52px); }
  100% { transform: translate(73.22px, 51.31px); }
}

/* --- думает: тихий вариант --------------------------------------------- */
.mark.is-pulse .dot {
  transform-box: fill-box;
  transform-origin: center;
  animation: markDotPulse 1.15s ease-in-out infinite;
}
@keyframes markDotPulse { 0%, 100% { transform: scale(1); opacity: 1; }
                          50%      { transform: scale(1.42); opacity: .5; } }

/* --- ответ пришёл ------------------------------------------------------- */
.mark.is-landed .dot {
  transform-box: fill-box;
  transform-origin: center;
  animation: markDotPop .44s cubic-bezier(.3,1.5,.5,1) both;
}
@keyframes markDotPop { 0%   { transform: scale(.4); opacity: .3; }
                        100% { transform: scale(1); opacity: 1; } }

/* --- доступность -------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .mark *, .mark *::before, .mark *::after {
    animation: none !important;
  }
}
