/* Kletterfigur, der Nach-oben-Knopf. Markup: includes/footer.php, Steuerung: climber.js.
   Dauern und Fußhöhe stehen nur hier; climber.js liest sie per getComputedStyle. */

@layer components {

    .climber {
        --fuss: 0.94;               /* Füße bei 94 % der Höhe */
        --dauer-klettern: 800;      /* ms: über die Kante ans Seil und zurück */
        --dauer-landen: 1300;       /* ms: Seil los, landen, hüpfen */
        --dauer-zur-mail: 1400;     /* ms: unten zur E-Mail gehen */
        --dauer-wiederrauf: 1800;   /* ms: „Na gut, wieder rauf!“ */
        --dauer-jubel: 2400;        /* ms: Klick auf die E-Mail-Adresse */
        --sticker-rand: 2px;        /* heller Rand auf Flammrot, wie ausgeschnitten */

        position: fixed; right: 18px; bottom: 20px; z-index: 85;
        width: 84px; display: block; color: var(--ink);
        transform-origin: 50% calc(var(--fuss) * 100%);   /* skaliert um die Füße */
    }
    .climber.is-aktiv {
        right: auto; bottom: auto;
        left: var(--x, 0px); top: var(--y, 0px); scale: var(--s, 1); opacity: var(--o, 1);
    }
    .climber.is-oben { z-index: 95; }   /* läuft auf der Kopfleiste, also darüber */
    /* Dort liegt er über Menü, Schalter und Burger: Klicks gehen durch ihn hindurch. */
    .climber.is-oben { pointer-events: none; }

    /* Wie schnell die Figur je Phase ihre Position wechselt. */
    .climber.is-aktiv    { transition: opacity .3s, scale .4s; }
    .climber.is-oben     { transition: left .2s linear, top calc(var(--dauer-klettern) * 1ms) ease-in-out, opacity .3s, scale .4s; }
    .climber.is-klettert { transition: top calc(var(--dauer-klettern) * 1ms) ease-in-out, scale calc(var(--dauer-klettern) * 1ms) ease-in-out; }
    .climber.am-seil:not(.is-klettert) { transition: top .25s linear, left .6s ease-in-out, scale .3s; }
    .climber.is-gelandet { transition: top .45s cubic-bezier(.5, 0, 1, .5), left .45s; }
    .climber.is-unten.is-geht { transition: left calc(var(--dauer-zur-mail) * 1ms) linear, top calc(var(--dauer-zur-mail) * 1ms) linear; }

    .climber-rope {
        position: absolute; left: 50%; bottom: calc(100% - 10px);
        width: 3px; height: 100vh; margin-left: -1.5px; background: var(--ink);
        pointer-events: none; opacity: 0; transition: opacity .2s;
    }
    .climber.am-seil .climber-rope { opacity: 1; }

    /* ---- Figur ---- */
    .climber-fig { display: block; width: 100%; height: auto; overflow: visible; transform-origin: 50% 5%; transition: scale .2s; }
    .climber .fig-limb-o { fill: none; stroke: var(--hard); stroke-width: 12; stroke-linecap: round; }
    .climber .fig-sleeve { fill: none; stroke: var(--flame); stroke-width: 8; stroke-linecap: round; }
    .climber .fig-leg    { fill: none; stroke: var(--fig-jeans); stroke-width: 8; stroke-linecap: round; }
    .climber .fig-shoe   { fill: var(--hard); }
    .climber .fig-hoodie { fill: var(--flame); stroke: var(--hard); stroke-width: 2.2; stroke-linejoin: round; }
    .climber .fig-pocket { fill: none; stroke: var(--hard); stroke-width: 1.4; stroke-linejoin: round; opacity: .6; }
    .climber .fig-string { fill: none; stroke: var(--bone); stroke-width: 1.6; stroke-linecap: round; }
    .climber .fig-skin   { fill: var(--fig-skin); stroke: var(--hard); stroke-width: 2.2; }
    .climber .fig-beard  { fill: var(--hard); stroke: var(--hard); stroke-width: 2.2; stroke-linejoin: round; }
    .climber .fig-mouth  { fill: none; stroke: var(--bone); stroke-width: 1.6; stroke-linecap: round; }
    .climber .fig-ring   { fill: none; stroke: var(--bone); stroke-width: 1; }
    .climber .fig-beanie { fill: var(--hard); }
    .climber .fig-rib    { fill: none; stroke: var(--bone); stroke-opacity: .2; stroke-width: 1.1; }
    .climber .mark-eye   { stroke-width: 1.2; }
    .climber .pupil      { fill: var(--hard); }
    .climber .fig-grin   { fill: var(--bone); stroke: var(--hard); stroke-width: 1.2; opacity: 0; }
    .climber .fig-oh     { fill: var(--hard); stroke: var(--bone); stroke-width: 1.2; opacity: 0; }
    .climber .mark-eyes  { transition: scale .15s; }   /* transform-box/-origin: style.css (.mark-eyes) */

    .climber .fig-hat, .climber .fig-leg-l, .climber .fig-leg-r { transform-box: fill-box; transition: translate .25s var(--ease-pop), rotate .25s var(--ease-pop); }
    .climber .fig-hat   { transform-origin: 80% 100%; }
    .climber .fig-leg-l, .climber .fig-leg-r { transform-origin: 50% 0; }

    /* Zwei Haltungen: Arme unten (laufen, zeigen) oder oben am Seil (.am-seil). */
    .climber .fig-arms-walk { opacity: 1; }
    .climber .fig-arms-hang { opacity: 0; }
    .climber.am-seil .fig-arms-walk { opacity: 0; }
    .climber.am-seil .fig-arms-hang { opacity: 1; }
    .climber .fig-arm-l, .climber .fig-arm-r { transform-box: fill-box; transform-origin: 50% 0; transition: rotate .3s; }

    /* ---- Zubehör: Stirnlampe (nachts, im Dunkelmodus), Werkzeug, Brille ---- */
    .climber .fig-lampe, .climber .fig-werkzeug, .climber .fig-brille { opacity: 0; transition: opacity .25s; }
    .climber .fig-lampe-licht { fill: var(--acid); opacity: .35; }
    .climber .fig-lampe-kopf  { fill: var(--acid); stroke: var(--hard); stroke-width: 1.2; }
    .climber.ist-nacht .fig-lampe { opacity: 1; }
    :root[data-theme="dark"] .climber .fig-lampe { opacity: 1; }
    @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .climber .fig-lampe { opacity: 1; } }
    .climber .fig-werkzeug { fill: var(--bone); stroke: var(--hard); stroke-width: 1.4; stroke-linejoin: round; }
    .climber .fig-brille   { fill: none; stroke: var(--hard); stroke-width: 1.6; }
    .climber[data-geste="werkzeug"] .fig-werkzeug,
    .climber[data-geste="brille"] .fig-brille { opacity: 1; }

    /* ---- Sprechblasen ---- */
    .climber-bubble {
        position: absolute; right: calc(100% + 10px); top: 34%;
        padding: 8px 14px; border-radius: 50%;
        background: var(--acid); color: var(--hard); border: 3px solid var(--hard);
        filter: drop-shadow(calc(var(--shadow) * .4) calc(var(--shadow) * .4) 0 var(--hard));
        font-size: 14px; font-weight: 800; letter-spacing: -.02em; white-space: nowrap;
        opacity: 0; scale: .4; transform-origin: 100% 50%; pointer-events: none;
        transition: opacity .15s, scale .3s var(--ease-pop);
    }
    .climber-bubble--sektion { top: 24%; }
    .climber-bubble--panik   { top: 18%; }
    .climber-bubble--rauf    { top: 16%; }
    .climber-bubble--unten,
    .climber-bubble--direkt  { top: 12%; }
    .climber-bubble--leerlauf{ top: 20%; }
    .climber-bubble--hoch    { top: 28%; }
    /* Start: rechts neben der Figur; die Figur ist dabei auf 0,6 verkleinert, die Blase gleicht mit 1,6 aus. */
    .climber-bubble--start   { right: auto; left: calc(100% + 8px); top: 30%; transform-origin: 0 50%; }
    /* Unten: rechts neben dem Kopf, dort ist Fläche frei (links steht der Kontakttext). */
    .climber-bubble--schreib,
    .climber-bubble--jubel   { right: auto; left: 72%; top: -30px; transform-origin: 0 100%; }

    /* Wer spricht wann – eine Blase zur Zeit, Reihenfolge nach Vorrang (spätere Regeln gewinnen). */
    .climber.spricht .climber-bubble--sektion                   { opacity: 1; scale: 1; }
    .climber.is-oben .climber-bubble--start                     { opacity: 1; scale: 1.6; }
    .climber.is-gelandet:not(.is-direkt) .climber-bubble--unten { opacity: 1; scale: 1; }
    .climber.is-gelandet.is-direkt .climber-bubble--direkt      { opacity: 1; scale: 1; }
    .climber.is-zeigt .climber-bubble--schreib                  { opacity: 1; scale: 1; }
    .climber.is-wiederrauf .climber-bubble--rauf                { opacity: 1; scale: 1; }
    .climber.is-leerlauf .climber-bubble--leerlauf              { opacity: 1; scale: 1; }
    .climber.faehrt-hoch .climber-bubble--hoch                  { opacity: 1; scale: 1; }
    .climber.is-panisch .climber-bubble--panik                  { opacity: 1; scale: 1; }

    /* Vorrang: Panik > Aufzug > Leerlauf > Wieder-rauf > Rest; Sektionssatz nur am Seil. */
    .climber:is(.is-oben, .is-klettert, .is-unten, .is-wiederrauf, .is-leerlauf, .faehrt-hoch, .is-panisch) .climber-bubble--sektion,
    .climber:is(.is-leerlauf, .faehrt-hoch, .is-panisch) :is(.climber-bubble--unten, .climber-bubble--direkt, .climber-bubble--schreib, .climber-bubble--rauf, .climber-bubble--start),
    .climber:is(.faehrt-hoch, .is-panisch) .climber-bubble--leerlauf,
    .climber.is-panisch .climber-bubble--hoch { opacity: 0; }

    /* Jubel nach dem Klick auf die E-Mail-Adresse schlägt alles außer dem Überfahren. */
    .climber.is-jubelt .climber-bubble--jubel { opacity: 1; scale: 1; }
    .climber.is-jubelt .climber-bubble:not(.climber-bubble--jubel) { opacity: 0; }

    /* Überfahren: nur die eigene Blase, Mütze lüpfen. */
    .climber:hover .climber-fig, .climber:focus-visible .climber-fig { scale: 1.12; }
    .climber:hover .fig-hat, .climber:focus-visible .fig-hat { translate: 0 -7px; rotate: -18deg; }
    .climber:is(:hover, :focus-visible) .climber-bubble--hover { opacity: 1; scale: 1; }
    .climber:is(:hover, :focus-visible) .climber-bubble:not(.climber-bubble--hover) { opacity: 0; }

    /* ---- Zustände ---- */
    .climber.is-zeigt .fig-arm-l { rotate: 80deg; }
    .climber.is-zeigt-runter .fig-arm-l { rotate: 35deg; }       /* Handy: steht oben auf der Schaltfläche */
    .climber.is-zeigt-runter :is(.climber-bubble--schreib, .climber-bubble--jubel) { left: auto; right: 100%; top: calc(var(--fuss) * 100% - 40px); transform-origin: 100% 50%; }
    .climber.is-unten .fig-grin { opacity: 1; }
    .climber.is-unten .fig-mouth { opacity: 0; }
    .climber:is(.is-panisch, .is-leerlauf) .fig-oh { opacity: 1; }
    .climber:is(.is-panisch, .is-leerlauf) :is(.fig-mouth, .fig-grin) { opacity: 0; }
    .climber.is-panisch .mark-eyes { scale: 1.5; }
    .climber.is-jubelt .fig-grin { opacity: 1; }
    .climber.is-jubelt :is(.fig-mouth, .fig-oh) { opacity: 0; }
    .climber.is-jubelt .fig-arm-l { rotate: 150deg; }   /* beide Arme hoch */
    .climber.is-jubelt .fig-arm-r { rotate: -150deg; }

    /* Unten im flammroten Kontaktblock (nur Startseite) verschwände der Hoodie im
       Hintergrund. Ein heller Rand wie bei einem ausgeschnittenen Sticker plus
       Blockschatten hebt ihn ab. Der Lichtkegel der Stirnlampe bekäme denselben
       Rand – unten im Hellen braucht er ihn ohnehin nicht. */
    :root:has(.reach-sec) .climber.is-unten .climber-fig {
        filter: drop-shadow(var(--sticker-rand) 0 0 var(--bone)) drop-shadow(calc(var(--sticker-rand) * -1) 0 0 var(--bone))
                drop-shadow(0 var(--sticker-rand) 0 var(--bone)) drop-shadow(0 calc(var(--sticker-rand) * -1) 0 var(--bone))
                drop-shadow(calc(var(--shadow) * .3) calc(var(--shadow) * .3) 0 var(--hard));
    }
    :root:has(.reach-sec) .climber.is-unten .fig-lampe-licht { visibility: hidden; }
}

@layer motion {
    @media (prefers-reduced-motion: no-preference) {
        .climber.am-seil .climber-fig { animation: swing 2.8s ease-in-out infinite; }
        .climber.is-klettert .climber-fig { animation: ueber-kante calc(var(--dauer-klettern) * 1ms) ease-in-out both; }
        .climber:is(:hover, :focus-visible) .climber-fig { animation: zappeln .35s ease-in-out infinite; }
        /* Gehen: Schritte auf Zeit – oben auf der Kopfleiste nur, solange gescrollt wird. */
        .climber.is-geht .fig-leg-l { animation: schritt .5s ease-in-out infinite; }
        .climber.is-geht .fig-leg-r { animation: schritt .5s ease-in-out infinite reverse; }
        .climber.is-geht .fig-arm-l { animation: schritt .5s ease-in-out infinite reverse; }
        .climber.is-geht .fig-arm-r { animation: schritt .5s ease-in-out infinite; }
        .climber.is-oben:not(.is-laeuft) :is(.fig-leg-l, .fig-leg-r, .fig-arm-l, .fig-arm-r) { animation: none; }
        /* Am Seil strampeln, solange gescrollt wird; beim Aufzug baumeln die Beine. */
        .climber.am-seil.is-laeuft .fig-leg-l { animation: strampeln .38s ease-in-out infinite; }
        .climber.am-seil.is-laeuft .fig-leg-r { animation: strampeln .38s ease-in-out infinite reverse; }
        .climber.faehrt-hoch .climber-fig { animation: swing .9s ease-in-out infinite; }
        .climber.is-gelandet .climber-fig { animation: freude .3s ease-in-out 4 alternate; }
        .climber.is-zeigt .fig-arm-r { animation: winken .5s ease-in-out infinite alternate; }
        .climber.is-jubelt .climber-fig { animation: freude .22s ease-in-out infinite alternate; }
        .climber.is-jubelt .fig-arm-l { animation: jubel-l .22s ease-in-out infinite alternate; }
        .climber.is-jubelt .fig-arm-r { animation: jubel-r .22s ease-in-out infinite alternate; }
        .climber.is-panisch .climber-fig { animation: zappeln .18s ease-in-out infinite; }
        .climber:is(:hover, :focus-visible) .fig-leg-l { animation: strampeln .3s ease-in-out infinite; }
        .climber:is(:hover, :focus-visible) .fig-leg-r { animation: strampeln .3s ease-in-out infinite reverse; }
        /* Abends gähnt er ab und zu, im Leerlauf sofort. */
        .climber.ist-abend .fig-oh { animation: gaehnen 14s 6s infinite; }
        .climber.is-leerlauf .fig-oh { animation: none; }
        .climber.is-leerlauf .climber-fig { animation: freude .8s ease-in-out 3 alternate; }
        .climber .fig-lampe-licht { animation: flackern 3s ease-in-out infinite; }
    }

    @keyframes ueber-kante {
        0%   { rotate: 0deg; translate: 0 0; }
        40%  { rotate: 28deg; translate: 6px 10px; }
        100% { rotate: 0deg; translate: 0 0; }
    }
    @keyframes winken    { from { rotate: -150deg; } to { rotate: -110deg; } }
    @keyframes jubel-l   { from { rotate: 140deg; } to { rotate: 165deg; } }
    @keyframes jubel-r   { from { rotate: -140deg; } to { rotate: -165deg; } }
    @keyframes schritt   { 0%, 100% { rotate: -24deg; } 50% { rotate: 24deg; } }
    @keyframes freude    { from { translate: 0 0; rotate: -4deg; } to { translate: 0 -12px; rotate: 4deg; } }
    @keyframes zappeln   { 0%, 100% { rotate: -9deg; } 50% { rotate: 9deg; } }
    @keyframes strampeln { 0%, 100% { rotate: -22deg; } 50% { rotate: 18deg; } }
    @keyframes swing     { 0%, 100% { rotate: -5deg; } 50% { rotate: 5deg; } }
    @keyframes gaehnen   { 0%, 88%, 100% { opacity: 0; } 90%, 97% { opacity: 1; } }
    @keyframes flackern  { 0%, 100% { opacity: .35; } 50% { opacity: .2; } }
}

/* ---- Schmale Fenster ---- */
@layer components {
    @media (max-width: 900px) {
        .climber { width: 62px; }
        .climber-bubble { font-size: 12px; }
        /* Blase unter die Figur (rechte, leere Hälfte des Telefon-Knopfs) statt über den Absatz. */
        .climber.is-zeigt:not(.is-zeigt-runter) :is(.climber-bubble--schreib, .climber-bubble--jubel) { top: calc(100% + 4px); left: auto; right: 0; transform-origin: 100% 0; }
    }
}

@media print {
    .climber { display: none !important; }
}
