/* ============================================================================
   Coffee Festival Europe — MOTIVE · die Bewegtgrafik je Seite (Stand 03.09.2026)

   Die Sprache bleibt auf allen Seiten dieselbe: dieselbe Trennlinie, derselbe
   Kopf, dasselbe Tempo, dieselben Farben (Elfenbein-Strich, Ember als Akzent,
   der Zweitton der Seitengruppe als zweiter Akzent). Was sich unterscheidet,
   ist das MOTIV: ein gezeichnetes Bild zum Thema der Seite, das sich beim
   Eintreffen aufbaut und danach ruhig weiterlebt — der Standplan fuer die
   Ausstellerseiten, die Route fuer Anfahrt und Stadt, der Kreislauf fuer die
   Nachhaltigkeit, die Tageszeile fuer das Programm, die Wachstumskurve fuer
   Ueber uns. Welches Motiv wohin gehoert, steht in assets/js/motive.js.

   Bauart: reine SVG-Strichzeichnungen mit pathLength="1", damit jede Linie
   mit denselben zwei Werten (dasharray 1, dashoffset 1 -> 0) gezeichnet
   werden kann. Bewegt werden nur stroke-dashoffset, transform und opacity.
   Das Band startet, wenn es ins Bild kommt (.kx-on), und steht unter
   prefers-reduced-motion sofort im Endzustand — ohne Schleifen.
   ========================================================================== */

.mv{position:relative;padding-block:clamp(40px,6vh,84px)}
.mv .shell{display:grid;gap:clamp(20px,3vw,48px);align-items:center}
.mv__cap{display:flex;flex-direction:column;gap:.7rem}
.mv__k{font-family:var(--f-mono);font-size:var(--t-label);letter-spacing:.16em;text-transform:uppercase;color:var(--pt,var(--ember))}
.mv__t{font-family:var(--f-display);font-weight:750;font-stretch:108%;letter-spacing:-.025em;line-height:1.08;
  font-size:clamp(1.3rem,2.2vw,2rem);color:var(--ivory);text-wrap:balance;max-width:16ch}
.mv__l{width:clamp(40px,5vw,72px);height:1px;background:linear-gradient(90deg,var(--ember),transparent);
  transform:scaleX(0);transform-origin:left;transition:transform 1.2s var(--kx-out,cubic-bezier(.16,1,.3,1)) .2s}
.mv.kx-on .mv__l{transform:scaleX(1)}
.mv__cap > *{opacity:0;transform:translate3d(0,10px,0);transition:opacity .8s,transform 1s var(--kx-out,cubic-bezier(.16,1,.3,1))}
.mv.kx-on .mv__cap > *{opacity:1;transform:none}
.mv.kx-on .mv__cap > :nth-child(2){transition-delay:.1s}
.mv.kx-on .mv__cap > :nth-child(3){transition-delay:.2s}
.mv__art{width:100%;max-width:820px;justify-self:end}
.mv__art svg{width:100%;height:auto;display:block;overflow:visible}
/* der Filmstreifen zieht vorbei — er darf nicht aus seinem Kasten laufen */
.mv[data-mv="film"] .mv__art svg{overflow:hidden}
@media (min-width:900px){
  .mv .shell{grid-template-columns:minmax(0,4fr) minmax(0,8fr)}
}
@media (max-width:899px){
  .mv__art{max-width:560px;justify-self:stretch}
}

/* ---- Farben — die Sprache ------------------------------------------------- */
.mv svg{--s:rgba(244,238,228,.62);--s2:rgba(244,238,228,.22);--e:var(--ember);--p:var(--pt,var(--ember-lo))}
.mv .s{stroke:var(--s);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.mv .s2{stroke:var(--s2);fill:none;stroke-width:1;stroke-linecap:round}
.mv .e{stroke:var(--e);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.mv .p{stroke:var(--p);fill:none;stroke-width:1.5;stroke-linecap:round}
.mv .ef{fill:var(--e);stroke:none}
.mv .pf{fill:var(--p);stroke:none}
.mv .sf{fill:rgba(244,238,228,.08);stroke:none}
.mv .tx{font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;fill:rgba(244,238,228,.55)}
.mv .txe{fill:var(--e)}

/* ---- Bausteine der Bewegung ------------------------------------------------
   Jedes Element traegt eine Klasse und, wo gestaffelt, --i (0,1,2 ...).
   Alles wartet auf .kx-on am Band. */
.mv .d{stroke-dasharray:1;stroke-dashoffset:1}
.mv .pop{opacity:0;transform:scale(.6);transform-box:fill-box;transform-origin:center}
.mv .rise{opacity:0;transform:translateY(14px)}
.mv .grow{transform:scaleY(0);transform-box:fill-box;transform-origin:bottom}
.mv .wipe{transform:scaleX(0);transform-box:fill-box;transform-origin:left}
.mv .fade{opacity:0}

.mv.kx-on .d{animation:mvDraw 1.4s cubic-bezier(.33,1,.68,1) both;animation-delay:calc(var(--i,0) * 140ms + var(--b,0ms))}
.mv.kx-on .pop{animation:mvPop .7s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0) * 120ms + var(--b,300ms))}
.mv.kx-on .rise{animation:mvRise .9s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0) * 110ms + var(--b,200ms))}
.mv.kx-on .grow{animation:mvGrow 1s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0) * 110ms + var(--b,200ms))}
.mv.kx-on .wipe{animation:mvWipe 1s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0) * 110ms + var(--b,200ms))}
.mv.kx-on .fade{animation:mvFade .9s ease both;animation-delay:calc(var(--i,0) * 120ms + var(--b,400ms))}
@keyframes mvDraw{to{stroke-dashoffset:0}}
@keyframes mvPop{to{opacity:1;transform:none}}
@keyframes mvRise{to{opacity:1;transform:none}}
@keyframes mvGrow{to{transform:none}}
@keyframes mvWipe{to{transform:none}}
@keyframes mvFade{to{opacity:1}}

/* Schleifen — erst nach dem Aufbau, und nur solange Bewegung erlaubt ist */
.mv .spin{transform-box:fill-box;transform-origin:center}
.mv.kx-on .spin{animation:mvSpin var(--dur,22s) linear infinite;animation-delay:1.6s}
.mv.kx-on .spin--r{animation-direction:reverse}
@keyframes mvSpin{to{transform:rotate(360deg)}}
.mv .pulse{transform-box:fill-box;transform-origin:center;opacity:0}
.mv.kx-on .pulse{animation:mvPulse 2.8s ease-out infinite;animation-delay:calc(1.8s + var(--i,0) * .9s)}
@keyframes mvPulse{0%{opacity:.8;transform:scale(.3)}100%{opacity:0;transform:scale(1.6)}}
.mv .travel{offset-rotate:0deg;opacity:0}
.mv.kx-on .travel{animation:mvTravel var(--dur,9s) cubic-bezier(.45,0,.35,1) infinite;animation-delay:1.8s}
@keyframes mvTravel{0%{offset-distance:0%;opacity:0}6%{opacity:1}94%{opacity:1}100%{offset-distance:100%;opacity:0}}
.mv .blink{opacity:.25}
.mv.kx-on .blink{animation:mvBlink 1.6s ease-in-out infinite;animation-delay:calc(1.6s + var(--i,0) * .25s)}
@keyframes mvBlink{50%{opacity:1}}
.mv .float{transform-box:fill-box;transform-origin:center}
.mv.kx-on .float{animation:mvFloat var(--dur,5s) ease-in-out infinite alternate;animation-delay:calc(1.6s + var(--i,0) * .6s)}
@keyframes mvFloat{to{transform:translateY(-8px)}}
.mv .slide{transform-box:fill-box}
.mv.kx-on .slide{animation:mvSlide var(--dur,14s) cubic-bezier(.45,0,.55,1) infinite alternate;animation-delay:1.8s}
@keyframes mvSlide{to{transform:translateX(var(--dx,300px))}}
.mv .bounce{transform-box:fill-box;transform-origin:center bottom}
.mv.kx-on .bounce{animation:mvBounce 1.4s cubic-bezier(.3,0,.2,1) infinite;animation-delay:1.6s}
@keyframes mvBounce{0%,100%{transform:translateY(0) scale(1.06,.94)}45%{transform:translateY(-70px) scale(.96,1.06)}60%{transform:translateY(-70px) scale(.96,1.06)}}
.mv .shadow{transform-box:fill-box;transform-origin:center}
.mv.kx-on .shadow{animation:mvShadow 1.4s cubic-bezier(.3,0,.2,1) infinite;animation-delay:1.6s}
@keyframes mvShadow{0%,100%{transform:scaleX(1);opacity:.5}50%{transform:scaleX(.6);opacity:.2}}
.mv .strip{transform-box:fill-box}
.mv.kx-on .strip{animation:mvStrip 18s linear infinite;animation-delay:1.6s}
@keyframes mvStrip{to{transform:translateX(-170px)}}
.mv .ripple{transform-box:fill-box;transform-origin:center;opacity:0}
.mv.kx-on .ripple{animation:mvRipple 4.2s cubic-bezier(.2,.6,.3,1) infinite;animation-delay:calc(1.4s + var(--i,0) * 1.05s)}
@keyframes mvRipple{0%{opacity:0;transform:scale(.15)}12%{opacity:.9}100%{opacity:0;transform:scale(1)}}
.mv .swing{transform-box:fill-box;transform-origin:center top}
.mv.kx-on .swing{animation:mvSwing 3.2s ease-in-out infinite alternate;animation-delay:1.6s}
@keyframes mvSwing{from{transform:rotate(-4deg)}to{transform:rotate(4deg)}}

/* Dampf: zeichnet sich, verblasst, kommt wieder */
.mv .steam{stroke-dasharray:1;stroke-dashoffset:1;opacity:0}
.mv.kx-on .steam{animation:mvSteam 3.6s ease-in-out infinite;animation-delay:calc(1.4s + var(--i,0) * .5s)}
@keyframes mvSteam{0%{stroke-dashoffset:1;opacity:0}30%{opacity:.9}70%{stroke-dashoffset:0;opacity:.6}100%{stroke-dashoffset:0;opacity:0}}
/* Ringe, die sich nur bis zu ihrem Anteil zeichnen, tragen den Rest als
   Inline-Stil (stroke-dashoffset:.28 = 72 Prozent) */
.mv.kx-on .d[style*="stroke-dashoffset"]{animation-name:mvDrawTo}
@keyframes mvDrawTo{from{stroke-dashoffset:1}}
.mv .tx{font-size:11px}

/* ---- Ruhe ------------------------------------------------------------------ */
@media (prefers-reduced-motion:reduce){
  .mv .d{stroke-dashoffset:0}
  .mv .pop,.mv .rise,.mv .grow,.mv .wipe,.mv .fade{opacity:1;transform:none}
  .mv .d,.mv .pop,.mv .rise,.mv .grow,.mv .wipe,.mv .fade{animation:none!important}
  .mv .spin,.mv .pulse,.mv .travel,.mv .blink,.mv .float,.mv .slide,.mv .bounce,.mv .shadow,.mv .strip,.mv .ripple,.mv .swing,.mv .steam{animation:none!important}
  .mv .steam{stroke-dashoffset:0;opacity:.5}
  .mv .travel{opacity:1;offset-distance:60%}
  .mv .pulse{opacity:.4;transform:scale(1.2)}
  .mv .ripple{opacity:.35;transform:scale(.7)}
  .mv .blink{opacity:.7}
  .mv__l{transform:none}
  .mv__cap > *{opacity:1;transform:none}
}
