/* Feinschliff: the small motions between the big chapters. Chapter heads build line by line, cards and photos settle as they
   arrive, pills slide, controls give under the finger, dialogs leave the way they came.
   - Additive and switchable: every rule hangs on html.fs, which a one-line script in the head sets before the first paint.
     index.html?feinschliff=0 shows the page without it.
   - Nothing changes at rest; only how states are entered and left. Only translate, scale and opacity move (the individual
     properties, so they compose with the transforms already in styles.css / motion.css). Hover colours, one focus ring and
     one glow on a prefilled field are the only paint-only changes.
   - Hidden starting states exist only on screens without reduced motion, and only for blocks that begin below the fold.
   - The approved scroll scenes (hero frame and zoom, statement fill, Vorgehen drawing, lift climb) are not touched. */
:root{
  --fs-ease:cubic-bezier(.22,1,.36,1);      /* interactions: hover, press release, pills, swaps (= --ease) */
  --fs-ease-in:cubic-bezier(.2,.75,.2,1);   /* entrances (= --motion-ease, like .reveal-in) */
  --fs-ease-out:cubic-bezier(.4,0,1,1);     /* exits only */
  --fs-step:90ms;                           /* one stagger step */
  --fs-rise-block:42px;                     /* blocks and cards, like .reveal-pending */
  --fs-rise:16px;                           /* lines that trail inside a block */
  --fs-block:.95s;
  --fs-trail:.8s;
  --fs-press-in:90ms;
  --fs-release:300ms;
  --fs-exit:220ms}
@media(max-width:600px){:root{--fs-rise-block:28px;--fs-rise:12px;--fs-block:.8s;--fs-trail:.7s}}
@keyframes fs-rise{from{opacity:0;translate:0 var(--fs-rise)}}
@keyframes fs-hero{from{opacity:0;translate:0 28px}}
@keyframes fs-drop{from{opacity:0;translate:0 -8px}}
@keyframes fs-lift{to{opacity:0;translate:0 -8px}}
@keyframes fs-settle{from{scale:1.05}}
@keyframes fs-float{from{translate:0 10px}}
@keyframes fs-fade-in{from{opacity:0}}
@keyframes fs-fade-out{to{opacity:0}}
@keyframes fs-sink{to{opacity:0;translate:0 16px;scale:.97}}
@keyframes fs-shrink{to{scale:.97}}


@media screen and (prefers-reduced-motion:no-preference){

/* 1 · Page load: the three hero lines rise one after another, then lead and actions, while the photo settles. Only the
   children move; .hero-copy and the photo's own transform stay with motion.js. */
.fs .motion-hero h1>span,.fs .hero-lead,.fs .hero-actions{animation:fs-hero 1.1s var(--fs-ease-in) backwards}
.fs .motion-hero h1>span:nth-child(2){animation-delay:.09s}
.fs .motion-hero h1>span:nth-child(3){animation-delay:.18s}
.fs .hero-lead{animation-delay:.3s}
.fs .hero-actions{animation-delay:.39s}
.fs .motion-hero .hero-photo{animation:fs-settle 2s var(--fs-ease) backwards}

/* 2 · Chapter heads and text blocks keep their reveal (script.js: .reveal-pending → .reveal-in); the first line rides it,
   every further line trails by one step with a small rise of its own. */
.fs :is(.frame-heading,.process-heading,.lift-outro,.fg-copy,.intro-columns).reveal-in>:nth-child(n+2){animation:fs-rise var(--fs-trail) var(--fs-ease-in) var(--fs-step) backwards}
.fs :is(.frame-heading,.process-heading,.lift-outro,.fg-copy,.intro-columns).reveal-in>:nth-child(3){animation-delay:calc(2*var(--fs-step))}
.fs :is(.frame-heading,.process-heading,.lift-outro,.fg-copy,.intro-columns).reveal-in>:nth-child(n+4){animation-delay:calc(3*var(--fs-step))}

/* 3 · Leistungen: the cards rise in turn (feinschliff.js marks them only when the rail starts below the fold) and their
   photos settle from a slight zoom. The card's hover lift keeps its own timing. */
/* Entering the waiting state never animates (it happens off screen at load); only leaving it does. */
.fs .service-card[data-fs] .card-photo img{transition:transform .8s var(--ease),scale 1.2s var(--fs-ease) var(--fs-d,0ms),opacity .5s var(--fs-ease)}
.fs .service-card[data-fs=wait]{opacity:0;translate:0 var(--fs-rise-block);transition:none}
.fs .service-card[data-fs=wait] .card-photo img{scale:1.05;transition:none}

/* Einblicke: while the strip rises (script.js), the photos actually in view settle left to right. */
.fs .shots.reveal-in .fs-settle img{animation:fs-settle 1.1s var(--fs-ease) calc(var(--fs-i,0) * var(--fs-step)) backwards}

/* Filme: when a film becomes the active one, its copy floats up into place as the card brightens. */
.fs.motion-ready .film-card.is-active .film-card-copy>*{animation:fs-float .7s var(--fs-ease-in) backwards}
.fs.motion-ready .film-card.is-active .film-card-copy>:nth-child(2){animation-delay:.06s}
.fs.motion-ready .film-card.is-active .film-card-copy>:nth-child(3){animation-delay:.12s}
.fs.motion-ready .film-card.is-active .film-card-copy>:nth-child(4){animation-delay:.18s}

/* Lazy photos that are still loading when reached fade in from their grey placeholder. */
html.fs img.fs-img-wait{opacity:0;transition:none}

/* 4 · Mobile menu: the panel drops in and its links follow; closing lifts it away (feinschliff.js keeps it shown 220 ms). */
@media(max-width:850px){
/* The panel is opaque before the links arrive, so no page text shows through them; only the links travel. */
.fs .header:not(.hdr) nav.open{animation:fs-fade-in .2s var(--fs-ease) backwards}
.fs .header:not(.hdr) nav.open>a{animation:fs-drop .45s var(--fs-ease) calc(60ms + var(--fs-i,0) * 35ms) backwards}
.fs .header:not(.hdr) nav>a:nth-child(2){--fs-i:1}
.fs .header:not(.hdr) nav>a:nth-child(3){--fs-i:2}
.fs .header:not(.hdr) nav>a:nth-child(4){--fs-i:3}
.fs .header:not(.hdr) nav>a:nth-child(5){--fs-i:4}
.fs .header:not(.hdr) nav>a:nth-child(6){--fs-i:5}
.fs.js .header:not(.hdr) nav.fs-leaving:not(.open){display:flex;pointer-events:none;box-shadow:0 20px 40px #071a2f30;animation:fs-lift var(--fs-exit) var(--fs-ease-out) forwards}
.fs .header:not(.hdr) .menu span{transition:transform .4s var(--fs-ease)}
}

/* 5 · Dialogs: the blurred backdrop fades with the panel, the content follows the panel in, and closing plays a short
   reverse (feinschliff.js holds the native close for those 220 ms). */
.fs :is(#detail-dialog,#inquiry-sheet)[open]::backdrop{animation:fs-fade-in .45s cubic-bezier(.2,.75,.2,1) backwards}
.fs .viewer[open]::backdrop{animation:fs-fade-in .28s cubic-bezier(.22,1,.36,1) backwards}
.fs #detail-dialog[open] .dialog-content>*{--fs-rise:12px;animation:fs-rise .6s var(--fs-ease-in) .06s backwards}
.fs #detail-dialog[open] .dialog-content>:nth-child(2){animation-delay:.12s}
.fs #detail-dialog[open] .dialog-content>:nth-child(n+3){animation-delay:.18s}
.fs .viewer[open] .viewer-bar{animation:fs-drop .5s var(--fs-ease) .08s backwards}
.fs .viewer[open] :is(.viewer-caption,.viewer-thumbs){--fs-rise:8px;animation:fs-rise .5s var(--fs-ease) .17s backwards}
.fs .viewer[open] .viewer-thumbs{animation-delay:.26s}
.fs :is(#detail-dialog,#inquiry-sheet).fs-closing{pointer-events:none;animation:fs-sink var(--fs-exit) var(--fs-ease-out) forwards}
.fs .viewer.fs-closing{pointer-events:none;animation:fs-fade-out var(--fs-exit) var(--fs-ease-out) forwards}
.fs .viewer.fs-closing .viewer-image{animation:fs-shrink var(--fs-exit) var(--fs-ease-out) forwards}
.fs :is(#detail-dialog,#inquiry-sheet,.viewer).fs-closing::backdrop{animation:fs-fade-out .22s cubic-bezier(.4,0,1,1) forwards}

/* 6 · Press: controls give a little under the finger and spring back (fast in, slower out). Tiles in swipe rails wait
   80 ms, so a swipe that starts on them never dips them. */
.fs :is(.button,.nav-cta,.round-button,.viewer-close,.viewer-arrow,.shot-arrow,.dialog-close,.compare-tabs button,.audience-tab,.film-select,.service-card,.shot-open,.lift-film,.menu):active,.fs .lift-film:active .lift-play{transition-duration:var(--fs-press-in)}
.fs :is(.button,.nav-cta):active{scale:.97}
.fs form .button:active{scale:.985}
.fs :is(.round-button,.viewer-arrow):not(:disabled):active,.fs :is(.viewer-close,.shot-arrow):active,.fs .lift-film:active .lift-play{scale:.92}
.fs :is(.dialog-close,.compare-tabs button,.audience-tab,.film-select):active{scale:.96}
.fs :is(.service-card,.shot-open):active{scale:.97;transition-delay:80ms}
}

@media screen and (prefers-reduced-motion:no-preference) and (max-width:860px){.fs .audience-tabs .audience-tab:active{scale:.985}}
@media screen and (prefers-reduced-motion:no-preference) and (max-width:850px){.fs .header:not(.hdr) .nav-cta:active{scale:.985}}
/* The site's reveal hides blocks below the fold; in print everything shows (motion.css' .reveal-pending outranks the
   print reset in styles.css). */
@media print{.fs .reveal-pending{opacity:1!important;transform:none!important}}
/* The global reduced-motion rule in styles.css does not reach ::backdrop. */
@media(prefers-reduced-motion:reduce){.fs :is(#detail-dialog,#inquiry-sheet,.viewer)::backdrop{animation:none!important}}


/* 7 · The transition lists these controls already have, with scale (and where needed opacity) added. Source rule in the
   comment: keep in sync if it changes there. */
.fs .button{transition:background .22s,transform .22s,scale var(--fs-release) var(--fs-ease)}                     /* styles.css .button */
.fs .header .nav-cta{transition:background .2s,scale var(--fs-release) var(--fs-ease)}                            /* motion.css .header .nav-cta */
.fs .round-button{transition:background .2s,color .2s,scale var(--fs-release) var(--fs-ease)}                     /* styles.css .round-button */
.fs .viewer-close,.fs .dialog-close{transition:background-color .2s,scale var(--fs-release) var(--fs-ease)}      /* styles.css .viewer-close; .dialog-close had none */
.fs .viewer-arrow{transition:background-color .2s,opacity .2s,scale var(--fs-release) var(--fs-ease)}            /* styles.css .viewer-arrow */
.fs .shot-arrow{transition:background-color .2s,color .2s,scale var(--fs-release) var(--fs-ease)}                /* styles.css .shot-arrow */
.fs .compare-tabs button{transition:background-color .25s,color .25s,box-shadow .25s,scale var(--fs-release) var(--fs-ease)} /* styles.css */
.fs .audience-tab{transition:color .3s,scale var(--fs-release) var(--fs-ease)}                                     /* styles.css .audience-tab */
.fs .film-select{transition:background .25s,color .25s,scale var(--fs-release) var(--fs-ease)}                    /* motion.css .film-select */
.fs .service-card{transition:transform .5s var(--ease),box-shadow .5s var(--ease),opacity var(--fs-block) var(--fs-ease-in) var(--fs-d,0ms),translate var(--fs-block) var(--fs-ease-in) var(--fs-d,0ms),scale var(--fs-release) var(--fs-ease)} /* styles.css .service-card */
.fs .shot-open img{transition:transform .8s var(--ease),opacity .5s var(--fs-ease)}                              /* styles.css .shot-open img */
.fs :is(.card-photo,.viewer-thumb) img{transition:opacity .5s var(--fs-ease)}
.fs :is(.shot-open,.lift-play,.menu){transition:scale var(--fs-release) var(--fs-ease)}
.fs :is(.text-link,.back-top,.footer-bottom a){transition:color .2s,opacity var(--fs-release) var(--fs-ease)}      /* color .2s as in styles.css / motion.css */
/* Text links dim while pressed (a state, so it also applies with reduced motion, instantly there). */
.fs :is(.text-link,.back-top,.footer-bottom a):active{opacity:.6;transition-duration:var(--fs-press-in)}


/* 8 · Hover (mouse only): arrows lean the way they point, quiet controls answer. */
.fs :is(.button,.nav-cta,.text-link.light,.back-top)>span:last-child,.fs .shot-arrow span,.fs :is(.gallery-controls,.viewer-stage) button>span{transition:translate .3s var(--fs-ease)}
.fs .gallery-controls button>span{display:inline-block}
@media(hover:hover) and (pointer:fine){
.fs :is(.button,.nav-cta):hover>span:last-child{translate:2px -2px}
.fs form .button:hover>span:last-child{translate:0 2px}
.fs .text-link.light:hover>span:last-child{translate:3px 0}
.fs .back-top:hover>span:last-child{translate:0 -3px}
.fs :is(.shot-prev,.gallery-prev:not(:disabled),.viewer-prev:not(:disabled)):hover span{translate:-2px 0}
.fs :is(.shot-next,.gallery-next:not(:disabled),.viewer-next:not(:disabled)):hover span{translate:2px 0}
.fs .lift-film:hover .lift-play{scale:1.08}
.fs .back-top:hover{color:#c9dcff}
.fs .footer-bottom a:hover{color:#fff}
.fs .dialog-close:hover{background:#e3e7ec}
.fs .compare-tabs button[aria-pressed=false]:hover{color:#0f1d2e}
.fs .film-select[aria-pressed=false]:hover{color:#fff}
.fs .ba:not(.is-dragging):hover .ba-handle{transform:translate(-50%,-50%) scale(1.05)}
}


/* 9 · Segmented controls: one pill slides to the chosen tab, like the Zielgruppen tab bar. At rest it looks exactly like
   the pressed button did. */
.fs .fs-seg-on{position:relative}
.fs .fs-seg-on>button{position:relative;z-index:1}
.fs .fs-seg{position:absolute;left:0;top:0;width:var(--seg-w,0);height:var(--seg-h,0);translate:var(--seg-x,0) var(--seg-y,0);border-radius:999px;pointer-events:none}
.fs .fs-seg-live .fs-seg{transition:translate .5s var(--ease),width .5s var(--ease)}
.fs .compare-tabs .fs-seg{background:#fff;box-shadow:0 1px 2px #071a2f1f,0 3px 10px #071a2f14}
.fs .compare-tabs.fs-seg-on button[aria-pressed=true]{background:transparent;box-shadow:none}
.fs .film-pills .fs-seg{background:#f1f5fc}
.fs .film-pills.fs-seg-on .film-select[aria-pressed=true]{background:transparent}


/* 10 · Form fields: the focus ring draws in from a wider offset. Film poster: shown under the video until it plays. */
.fs :is(input,select,textarea){transition:border-color .2s,outline-offset .3s var(--fs-ease)}
.fs :is(input,select,textarea):not(:focus){outline-offset:12px}
.fs .fs-poster{background-size:cover;background-repeat:no-repeat}
