/* glad UI motion: how people marks move, ported from the Design canvas's glad-motion-1.css. Load after themes.css.
   Motion says what is happening, never who someone is. Everyone shares the same moves:
     idle        a blink every 6 to 9 s and a slow drift of the topper; 40 px and up alone (.mk-live), never in the
                 graph or a list
     pointing    the mark lifts, the eyes look up, the topper reacts; 40 px and up alone, like idle
     new         a decision just landed; plays once (.is-new)
     working     an agent is mid-turn; loops until its turn ends (.is-working)
     clash       two answers to one question disagree; plays once (.is-clash)
   Each topper and pair of eyes performs a move its own way, each person runs on their own clock (ph-0..11, from
   marks.js), and each theme gives the moves its own texture. Classes come from marks.js. */

/* ================================================================ texture per theme */

.mark { --mk-ease: cubic-bezier(.4, 0, .2, 1); --mk-spring: cubic-bezier(.2, .8, .2, 1); --mk-idle: ease-in-out; --mk-rip-c: var(--accent);
  transition: transform 220ms var(--mk-spring); }
.th-datasheet .mark { --mk-ease: steps(4, end); --mk-spring: steps(3, end); --mk-idle: steps(3, end); }          /* a plotter: no easing */
.th-graphite .mark { --mk-ease: cubic-bezier(.4, 0, .2, 1); --mk-spring: cubic-bezier(.22, .8, .24, 1); }       /* soft, nothing bounces */
.th-hud .mark { --mk-ease: cubic-bezier(.6, 0, .4, 1); --mk-spring: cubic-bezier(.2, .9, .3, 1); }              /* light, quick to settle */
.th-porcelain .mark { --mk-ease: cubic-bezier(.45, 0, .2, 1); --mk-spring: cubic-bezier(.34, 1.56, .64, 1); transform-origin: 50% 90%; } /* a spring */

/* ================================================================ each person's own clock */

.mark.ph-0  { --mk-d: 0s;    --mk-blink: 6.2s; --mk-drift: 5.1s; }
.mark.ph-1  { --mk-d: -1.7s; --mk-blink: 7.4s; --mk-drift: 6.3s; }
.mark.ph-2  { --mk-d: -3.1s; --mk-blink: 8.1s; --mk-drift: 4.7s; }
.mark.ph-3  { --mk-d: -0.9s; --mk-blink: 6.8s; --mk-drift: 5.9s; }
.mark.ph-4  { --mk-d: -4.4s; --mk-blink: 7.9s; --mk-drift: 5.4s; }
.mark.ph-5  { --mk-d: -2.6s; --mk-blink: 6.5s; --mk-drift: 6.8s; }
.mark.ph-6  { --mk-d: -5.2s; --mk-blink: 8.6s; --mk-drift: 4.9s; }
.mark.ph-7  { --mk-d: -3.8s; --mk-blink: 7.1s; --mk-drift: 6.1s; }
.mark.ph-8  { --mk-d: -1.2s; --mk-blink: 8.3s; --mk-drift: 5.6s; }
.mark.ph-9  { --mk-d: -6.1s; --mk-blink: 6.9s; --mk-drift: 6.6s; }
.mark.ph-10 { --mk-d: -2.2s; --mk-blink: 7.7s; --mk-drift: 5.0s; }
.mark.ph-11 { --mk-d: -4.9s; --mk-blink: 9.0s; --mk-drift: 6.0s; }

/* ================================================================ pivots */

/* eyes, the diamond and the ring turn on themselves; paired toppers (ears, horns) turn on their own base;
   one-piece toppers turn where they meet the head */
.mark .mk-eye, .mark .mk-tag, .mark .mk-rip, .mark .tp-bear { transform-box: fill-box; transform-origin: 50% 50%; }
.mark .tp-cat, .mark .tp-horns { transform-box: fill-box; transform-origin: 50% 100%; }
.mark .tp-antenna, .mark .tp-sprout, .mark .tp-tuft, .mark .tp-halo, .mark .tp-bun { transform-box: view-box; transform-origin: 16px 11px; }
.mark .mk-rip { fill: none; stroke: var(--mk-rip-c); stroke-width: 1.2; opacity: 0; }

/* ================================================================ idle · 40 px and up */

@keyframes mk-blink { 0%, 92%, 96%, 100% { transform: scaleY(1); } 94% { transform: scaleY(.1); } }
@keyframes mk-sway { from { transform: rotate(-5deg); } to { transform: rotate(5deg); } }
@keyframes mk-ruffle { from { transform: skewX(-5deg); } to { transform: skewX(5deg); } }
@keyframes mk-float { from { transform: translateY(0); } to { transform: translateY(-1.2px); } }
@keyframes mk-twitch-l { 0%, 86%, 92%, 100% { transform: rotate(0); } 89% { transform: rotate(-14deg); } }
@keyframes mk-twitch-r { 0%, 88%, 94%, 100% { transform: rotate(0); } 91% { transform: rotate(14deg); } }
@keyframes mk-flex { 0%, 84%, 92%, 100% { transform: scale(1); } 88% { transform: scale(1.14); } }
@keyframes mk-bob { 0%, 80%, 90%, 100% { transform: translateY(0); } 85% { transform: translateY(-1.4px); } }

.mark.mk-live .mk-eye { animation: mk-blink var(--mk-blink) linear var(--mk-d) infinite; }
.mark.mk-live .tp-antenna { animation: mk-sway var(--mk-drift) var(--mk-idle) var(--mk-d) infinite alternate; }
.mark.mk-live .tp-sprout { animation: mk-sway calc(var(--mk-drift) * .8) var(--mk-idle) var(--mk-d) infinite alternate; }
.mark.mk-live .tp-tuft { animation: mk-ruffle var(--mk-drift) var(--mk-idle) var(--mk-d) infinite alternate; }
.mark.mk-live .tp-halo { animation: mk-float calc(var(--mk-drift) * .6) var(--mk-idle) var(--mk-d) infinite alternate; }
.mark.mk-live .tp-cat.side-l { animation: mk-twitch-l var(--mk-blink) linear var(--mk-d) infinite; }
.mark.mk-live .tp-cat.side-r { animation: mk-twitch-r var(--mk-blink) linear var(--mk-d) infinite; }
.mark.mk-live .tp-bear { animation: mk-flex calc(var(--mk-blink) * 1.3) linear var(--mk-d) infinite; }
.mark.mk-live .tp-bun { animation: mk-bob calc(var(--mk-blink) * 1.1) linear var(--mk-d) infinite; }
/* horns stay put when idle: they only move when you point at them */

/* ================================================================ pointing at a mark */

@keyframes mk-look { to { transform: translateY(-1px); } }
@keyframes mk-boing { 0% { transform: rotate(0); } 20% { transform: rotate(-16deg); } 45% { transform: rotate(11deg); } 65% { transform: rotate(-6deg); } 82% { transform: rotate(3deg); } 100% { transform: rotate(0); } }
@keyframes mk-perk { 0% { transform: scaleY(1); } 40% { transform: scaleY(1.28); } 100% { transform: scaleY(1.12); } }
@keyframes mk-wiggle { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-12deg); } 40% { transform: rotate(10deg); } 60% { transform: rotate(-8deg); } 80% { transform: rotate(5deg); } }
@keyframes mk-shuffle { 0%, 100% { transform: skewX(0); } 25% { transform: skewX(-14deg); } 55% { transform: skewX(10deg); } 80% { transform: skewX(-4deg); } }
@keyframes mk-spring { 0% { transform: scaleY(1); } 30% { transform: scaleY(1.35); } 55% { transform: scaleY(.88); } 78% { transform: scaleY(1.06); } 100% { transform: scaleY(1); } }
@keyframes mk-lift { 0% { transform: translateY(0) scaleX(1); } 50% { transform: translateY(-2.4px) scaleX(1.18); } 100% { transform: translateY(-1.6px) scaleX(1.08); } }
@keyframes mk-tilt-l { 0%, 100% { transform: rotate(0); } 40% { transform: rotate(-14deg); } }
@keyframes mk-tilt-r { 0%, 100% { transform: rotate(0); } 40% { transform: rotate(14deg); } }
@keyframes mk-hop { 0%, 100% { transform: translateY(0); } 30% { transform: translateY(-3.2px); } 55% { transform: translateY(0); } 72% { transform: translateY(-1.2px); } }

:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) { transform: translateY(-2px); }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .mk-eye { animation: mk-look 300ms var(--mk-spring) forwards; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-antenna { animation: mk-boing 820ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-cat { animation: mk-perk 420ms var(--mk-spring) forwards; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-bear { animation: mk-wiggle 640ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-tuft { animation: mk-shuffle 620ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-sprout { animation: mk-spring 700ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-halo { animation: mk-lift 520ms var(--mk-spring) forwards; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-horns.side-l { animation: mk-tilt-l 600ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-horns.side-r { animation: mk-tilt-r 600ms var(--mk-ease) both; }
:is(.mark.mk-live:hover, .mk-host:hover .mark.mk-live) .tp-bun { animation: mk-hop 620ms var(--mk-ease) both; }

/* ================================================================ a new decision lands · plays once */

@keyframes mk-pop { 0% { transform: scale(.4); opacity: 0; } 55% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes mk-ripple { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.7); } }
.mark.is-new { animation: mk-pop 520ms var(--mk-spring) both; }
.mark.is-new .mk-rip { animation: mk-ripple 900ms ease-out 140ms both; }

/* datasheet: it prints in, line by line, and its outline registers in orange once */
@keyframes mk-print { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes mk-register { 0% { stroke: var(--accent); } 100% { stroke: var(--mk-line); } }
.th-datasheet .mark.is-new { animation: mk-print 560ms steps(7, end) both; }
.th-datasheet .mark.is-new .mk-rip { animation: none; }
.th-datasheet .mark.is-new .mk-head { animation: mk-register 900ms steps(2, end) 560ms both; }

/* graphite: it rises into place; a soft ring spreads */
@keyframes mk-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.th-graphite .mark.is-new { animation: mk-rise 640ms var(--mk-spring) both; }

/* hud: the outline draws itself, the mark flickers on, a ring of light spreads */
@keyframes mk-draw { from { stroke-dashoffset: 120; } to { stroke-dashoffset: 0; } }
@keyframes mk-fill-in { from { fill-opacity: 0; } to { fill-opacity: 1; } }
@keyframes mk-flicker { 0% { opacity: 0; } 12% { opacity: .9; } 18% { opacity: .2; } 30% { opacity: 1; } 38% { opacity: .5; } 50%, 100% { opacity: 1; } }
.th-hud .mark.is-new { animation: mk-flicker 720ms linear both; }
.th-hud .mark.is-new .mb { stroke-dasharray: 120; animation: mk-draw 650ms cubic-bezier(.6, 0, .4, 1) both, mk-fill-in 300ms linear 450ms both; }

/* porcelain: it pops, squashes and settles */
@keyframes mk-squash { 0% { transform: scale(.3); opacity: 0; } 45% { transform: scale(1.14, .9); opacity: 1; } 68% { transform: scale(.95, 1.06); } 85% { transform: scale(1.02, .99); } 100% { transform: scale(1); opacity: 1; } }
.th-porcelain .mark.is-new { animation: mk-squash 660ms cubic-bezier(.3, .7, .4, 1) both; }

/* ================================================================ an agent is working · loops until it replies */

@keyframes mk-march { to { stroke-dashoffset: -8; } }
@keyframes mk-scan { 0%, 100% { transform: translateX(-1.4px); } 50% { transform: translateX(1.4px); } }
@keyframes mk-beat { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.3); } }
.mark.is-working .mb { animation: mk-march 900ms linear infinite; }
.mark.is-working .mk-eye { animation: mk-scan 1.6s ease-in-out infinite; }
.mark.is-working .mk-tag { animation: mk-beat 1.2s ease-in-out infinite; }
.th-datasheet .mark.is-working .mb { animation-timing-function: steps(2, end); }
.th-datasheet .mark.is-working .mk-eye { animation-timing-function: steps(3, end); }
.th-hud .mark.is-working { filter: drop-shadow(0 0 4px rgba(255, 181, 71, .9)); }

/* ================================================================ a clash opens · plays once */

@keyframes mk-shake { 0%, 100% { transform: translateX(0); } 15% { transform: translateX(-3px) rotate(-4deg); } 30% { transform: translateX(3px) rotate(4deg); } 45% { transform: translateX(-2px) rotate(-2deg); } 60% { transform: translateX(2px) rotate(2deg); } 75% { transform: translateX(-1px); } }
@keyframes mk-frown { 0%, 100% { transform: scaleY(1); } 30%, 70% { transform: scaleY(.45); } }
.mark.is-clash { animation: mk-shake 540ms var(--mk-ease) both; }
.mark.is-clash .mk-eye { animation: mk-frown 540ms linear both; }
.th-hud .mark.is-clash { filter: drop-shadow(0 0 5px rgba(255, 90, 78, .9)); }

/* ================================================================ people who asked for less motion get none */

@media (prefers-reduced-motion: reduce) {
  .mark, .mark * { animation: none !important; transition: none !important; }
  .mark.mk-live:hover, .mk-host:hover .mark.mk-live { transform: none; }
}
