/* =====================================================================
   heroStage — code-driven, responsive homepage hero (images + video).
   Fixes the legacy "keyhole" crop: object-fit:cover + object-position:left
   on art-directed <picture> sources, with a CSS gradient scrim (never baked
   into the asset). Full-bleed inside the centered .container.main-container.
   Desktop ratio 12:5, mobile 4:5. All timing/controls in js/heroStage.js.
   ===================================================================== */

/* --- full-bleed wrapper (breaks out of the max-1200 container; .overflow-container clips x-scroll) --- */
.hero-stage {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-bottom: 0;   /* the reference-logo band now sits directly under the hero */
    background: #0c1a30;
}

/* --- the stage: fixed aspect, everything stacks inside --- */
.hero {
    position: relative;
    width: 100%;
    aspect-ratio: 12 / 5;          /* desktop cinematic */
    max-height: 760px;
    overflow: hidden;
    isolation: isolate;
    background: #0c1a30;
    touch-action: pan-y;           /* let the page scroll vertically; horizontal swipes are ours (reliable on mobile) */
}

.hero-track { position: absolute; inset: 0; }

/* --- slides crossfade-stacked --- */
.hero-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    z-index: 0;
    pointer-events: none;
    transition: opacity .8s ease;
}
.hero-slide.is-active {
    opacity: 1;
    z-index: 1;
    pointer-events: auto;
}

/* --- media layer (image or video), anchored by focal point --- */
.hero-media,
.hero-img,
.hero-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: var(--focal, left center);
    z-index: 1;
}

/* dev/local only: a designer preset overlay laid ON TOP of the composed slide for visual checking.
   The overlay PNG is semi-transparent (~20% zones) -> the image + scrim + text stay readable
   through it, while the guide itself stays fully readable everywhere (incl. the scrim side).
   Crops exactly like the media (same object-position) so the zones stay aligned on mobile too. */
.hero-preview-overlay {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--focal, left center);
    z-index: 4;            /* above media (z1) + scrim (z2) + content (z3), BELOW controls/dots (z5) */
    pointer-events: none;
}

/* --- scrim: gradient that ENDS in the slide's solid color, fills any width --- */
.hero-scrim {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
}
.hero-scrim.side-right {
    background: linear-gradient(90deg,
        rgba(var(--scrim-rgb, 12,26,48), 0) 0%,
        rgba(var(--scrim-rgb, 12,26,48), 0) 28%,
        rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 55%,
        rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 100%);
}
.hero-scrim.side-left {
    background: linear-gradient(270deg,
        rgba(var(--scrim-rgb, 12,26,48), 0) 0%,
        rgba(var(--scrim-rgb, 12,26,48), 0) 28%,
        rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 55%,
        rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 100%);
}

/* --- text/CTA overlay --- */
.hero-content {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(24px, 4.5vw, 84px);
    pointer-events: none;          /* only interactive children re-enable */
}
.hero-content > * { pointer-events: auto; }

.hero-text { max-width: min(48%, 620px); }   /* 560->620 (2026-07-10): "Additive Fertigung in" muss in EINE Zeile passen, sonst Waise "in" (der 48%-Deckel schützt schmale Viewports) */
/* fit-style.css setzt hyphens:auto DIREKT auf p/h2/a -> die Elemente selbst treffen
   (Wurzel-Vererbung reicht nicht); fixt Brüche wie "Detailauflö-sung" im Subhead (2026-07-10) */
.hero-text, .hero-text :is(p, h1, h2, h3, a) { hyphens: manual; }
.hero-slide.text-right .hero-content { align-items: flex-end; }
.hero-slide.text-right .hero-text   { text-align: left; }
.hero-slide.text-left  .hero-content { align-items: flex-start; }

/* themes: text color over the scrim */
.hero-slide.theme-dark  { color: #ffffff; }
.hero-slide.theme-light { color: var(--fitblue); }

.hero-eyebrow {
    font-size: clamp(12px, 1.1vw, 15px);
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--fityellow);
    margin: 0 0 10px;
}
.hero-slide.theme-light .hero-eyebrow { color: var(--fitblue); }   /* yellow-on-white = poor contrast */
.hero-headline {
    color: inherit;            /* beat the site's global h2 color rule (class > element specificity) */
    font-size: clamp(30px, 4.4vw, 64px);
    font-weight: 800;
    line-height: 1.03;
    letter-spacing: -.01em;
    margin: 0 0 14px;
    text-shadow: 0 2px 18px rgba(6,14,28,.35);
    text-wrap: balance;        /* wie .fit-heading: gleichmäßige Zeilen statt lang/kurz, wenn ein <br>-Segment zusätzlich umbricht (2026-07-10) */
}
.hero-slide.theme-light .hero-headline { text-shadow: none; }
.hero-subhead {
    color: inherit;            /* beat the site's global p color rule */
    font-size: clamp(15px, 1.5vw, 21px);
    line-height: 1.4;
    margin: 0 0 22px;
    opacity: .94;
}

/* CTAs */
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; }
.hero-cta {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    font-weight: 700;
    font-size: clamp(13px, 1.1vw, 16px);
    padding: .7em 1.25em;
    border-radius: 0;   /* eckig wie Nav-CTA/ctaBand — war 2px, der einzige nicht-eckige Button der Seite (2026-07-10) */
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.hero-cta:hover { transform: translateY(-1px); }
.hero-cta.primary {
    background: var(--fityellow);
    color: #16284a;
    box-shadow: 0 6px 20px rgba(252,186,0,.28);
}
.hero-cta.primary:hover { box-shadow: 0 10px 26px rgba(252,186,0,.4); }
.hero-cta.secondary {
    background: transparent;
    color: inherit;
    border: 2px solid currentColor;
}
.hero-cta.secondary:hover { background: rgba(255,255,255,.12); }

/* --- extra element (e.g. the KuZu animated bubble iframe) --- */
.hero-extra { z-index: 3; pointer-events: auto; }
.hero-extra-kuzu {
    position: absolute;
    z-index: 3;
    right: clamp(24px, 5vw, 90px);
    top: 50%;
    transform: translateY(-50%);
    width: clamp(170px, 17vw, 230px);
    aspect-ratio: 1 / 1;
}
.hero-extra-kuzu iframe { width: 100%; height: 100%; border: 0; background: transparent; }

/* --- persistent corner badge (e.g. "Azubis wanted"), outside the crossfade --- */
.hero-badge {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 6;
    max-width: clamp(120px, 13vw, 168px);
    line-height: 0;
    transition: transform .2s ease;
}
.hero-badge:hover { transform: scale(1.03); }
.hero-badge img { width: 100%; height: auto; display: block; }

/* --- controls (grouped indicators; prev/next arrows removed) ---
   Each indicator is ONE theme. A theme with several slides shows a SEGMENTED bar
   (one .hero-dot__seg per slide). The <button> itself is a large transparent hit
   target (generous padding) while the visible bar stays slim — much easier to hit
   than the old 4px-tall dot. */
.hero-indicators {
    position: absolute;
    left: 0; right: 0; bottom: clamp(2px, 0.8vw, 10px);
    z-index: 5;
    display: flex; justify-content: center; align-items: center; gap: 2px;
}
.hero-dot {
    --g: 3px;                          /* gap between a theme's stacked sub-slide segments */
    /* segment widths per slide-count as  inactive / active(=swollen). The active sub-slide stays
       wider (swells) so the whole indicator grows on activation; the multi base widths are small
       enough that the resulting ACTIVE indicator is only ~+15% (2) / +25% (3) wider than a single. */
    --s1i: 30px; --s1a: 42px;          /* 1 slide */
    --s2i: 15px; --s2a: 30px;          /* 2 slides */
    --s3i: 12px; --s3a: 22px;          /* 3 slides (max) */
    display: inline-flex;
    align-items: center;
    gap: var(--g);
    margin: 0; padding: 16px 5px;      /* big transparent hit area (the bar stays 4px tall) */
    border: 0; background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.hero-dot__seg {
    display: block;
    height: 4px; border-radius: 2px;
    background: rgba(255,255,255,.4);
    transition: width .2s ease, background-color .2s ease;
}
.hero-dot--n1 .hero-dot__seg           { width: var(--s1i); }
.hero-dot--n1 .hero-dot__seg.is-active { width: var(--s1a); }   /* single swells when active */
.hero-dot--n2 .hero-dot__seg           { width: var(--s2i); }
.hero-dot--n2 .hero-dot__seg.is-active { width: var(--s2a); }
.hero-dot--n3 .hero-dot__seg           { width: var(--s3i); }
.hero-dot--n3 .hero-dot__seg.is-active { width: var(--s3a); }
.hero-dot:hover .hero-dot__seg:not(.is-active) { background: rgba(255,255,255,.7); }  /* hover brightens only the grey segments … */
.hero-dot__seg.is-active               { background: var(--fityellow); }   /* … the active sub-slide keeps its yellow (even on hover) */

.hero-visually-hidden {
    position: absolute !important; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* =====================  TABLET (768-1099px)  =====================
   Das 12:5-Kinoformat ist in diesem Fenster zu FLACH für den gestapelten
   Textblock: bei ~780px ist die Stage nur ~326px hoch, die MSLA-Slide
   (3-zeilige Headline + 2 gewrappte CTAs) lief in die Indikator-Zeile
   (Nutzer-Screenshot 2026-07-10, gemessen: CTA-Unterkante auf Dot-Höhe).
   -> höheres Format, breitere Textspalte (weniger Zeilen), und die
   Indikator-Zeile bleibt per padding-bottom immer frei. */
@media (min-width: 768px) and (max-width: 1099px) {
    .hero { aspect-ratio: 16 / 9; }
    /* 54% statt 60% (Nutzer 2026-07-10): die 60%-Box wurde von der längsten Zeile
       (Subhead) aufgespannt — die kürzeren Zeilen hingen an der LINKEN Boxkante und
       die Rechts-Verankerung der text-right-Slides wirkte verloren ("Schrift nach
       links gerutscht"). Schmalere Box = mehr Umbrüche, aber kompakt am Anker;
       die nötige Höhe liefert das 16/9-Format (CTAs dürfen stapeln). */
    .hero-text { max-width: min(54%, 620px); }
    .hero-content { padding-bottom: 64px; }   /* > Dot-Zone (~48px) -> CTAs können nie kollidieren */
    /* Rechts-Anker auch OPTISCH (Nutzer-Screenshot 869px, artarch1): die Box wird vom
       max-width-Umbruch aufgespannt, kürzere Zeilen enden an Wortgrenzen -> rechts blieb
       Flatterluft, der Text wirkte mittig. Rechtsbündige Ausrichtung legt jede Zeile an
       die Ankerkante; links verankerte Slides sind über die Boxkante bereits bündig.
       Desktop (>=1100) bleibt bewusst linksbündig (abgenommener Stand). */
    .hero-slide.text-right .hero-text { text-align: right; }
    .hero-slide.text-right .hero-ctas { justify-content: flex-end; }
}

/* =====================  MOBILE (< 768px)  ===================== */
@media (max-width: 767px) {
    .hero { aspect-ratio: 4 / 5; max-height: 82vh; }

    /* vertical scrim -> solid text band at the bottom */
    .hero-scrim.side-right,
    .hero-scrim.side-left {
        background: linear-gradient(180deg,
            rgba(var(--scrim-rgb, 12,26,48), 0) 0%,
            rgba(var(--scrim-rgb, 12,26,48), 0) 40%,
            rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 66%,
            rgba(var(--scrim-rgb, 12,26,48), var(--scrim-opacity, .96)) 100%);
    }

    .hero-content {
        justify-content: flex-end;
        padding: 22px 20px 56px;
    }
    .hero-slide.text-right .hero-content,
    .hero-slide.text-left  .hero-content { align-items: stretch; }
    .hero-text { max-width: none; text-align: left; }

    /* KuZu bubble: tuck into the upper area so it doesn't fight the text band */
    .hero-extra-kuzu {
        right: 16px; top: 18px; transform: none;
        width: clamp(116px, 34vw, 150px);
    }

    .hero-badge { max-width: 108px; }
    .hero-indicators { bottom: 4px; }
    .hero-dot {                                      /* >=44px touch target; smaller bars on mobile */
        padding: 20px 5px;
        --s1i: 22px; --s1a: 30px;
        --s2i: 10px; --s2a: 22px;
        --s3i: 8px;  --s3a: 15px;
    }
}

/* =====================  media-left video slide (content on black, e.g. WAAM)  =====================
   The clip is cropped to just the motif — the rest of the original frame was pure black. We drop that
   black from the file and let the slide's black background fill the remainder, fading the clip's right
   edge into it (forgiving of a not-perfectly-black crop edge). Desktop only; mobile keeps the poster
   cover + bottom scrim band. */
.hero-slide.media-left { background: #000; }
@media (min-width: 768px) {
    /* keep the media box full-frame, but render the narrow clip CONTAINED + left-anchored, so it sits
       at full height on the left and the rest of the box is transparent -> the black slide bg shows.
       The clip's crop edge is already near-black, so it blends into the bg with no visible seam. */
    .hero-slide.media-left .hero-img,
    .hero-slide.media-left .hero-video {
        object-fit: contain;
        object-position: left center;
    }
    .hero-slide.media-left .hero-scrim { display: none; }   /* pure-black bg already gives full text contrast */
}

/* hide the CSS scrim on a slide whose IMAGE already ends in solid black (e.g. whiteout) so the text
   sits on the baked pure-black. Desktop only — the mobile 4:5 crop shows the motif, so it keeps its
   bottom scrim band for legibility. */
@media (min-width: 768px) {
    .hero-slide.no-scrim .hero-scrim { display: none; }
}

/* =====================  SLIDE-TEXT-REVEAL (Nutzer 2026-07-10)  =====================
   Eyebrow/Headline/Subhead/CTAs steigen beim Aktivwerden einer Slide gestaffelt ein
   (gleiches Expo-Easing wie der Seiten-Scroll-Reveal), das Motiv schärft sich aus
   einem leichten Blur ("der Hintergrund darf ruhig blurren" — Nutzer).

   Gating (gleicher FOUC-/A11y-Vertrag wie reveal.css):
   - Verstecken NUR unter html.has-reveal (Inline-Gate in home/index.phtml:
     JS + IntersectionObserver + KEIN reduced-motion) -> ohne JS / bei
     reduced-motion ist alles sofort sichtbar und statisch.
   - .hero.is-run kommt von einem Inline-Doppel-rAF DIREKT nach dem Hero-Markup
     (heroStage.render.php) — der Zustandswechsel NACH dem ersten Paint lässt die
     Transition auch beim Seiten-Load spielen (Slide 1 trägt is-active schon im
     Server-HTML, ohne den Kick gäbe es beim Load keine Animation).
   - html.reveal-safety (3s-Fallback aus index.phtml) stellt alles zwangsweise
     sichtbar, falls Skripte hängen — Block muss NACH den Hide-Regeln stehen. */
html.has-reveal .hero-slide .hero-eyebrow,
html.has-reveal .hero-slide .hero-headline,
html.has-reveal .hero-slide .hero-subhead,
html.has-reveal .hero-slide .hero-ctas {
    opacity: 0;
    transform: translateY(26px);
    /* schneller, delaylose Rückweg: die abgehende Slide räumt unterm Crossfade auf */
    transition: opacity .25s ease, transform .25s ease;
}
html.has-reveal .hero.is-run .hero-slide.is-active .hero-eyebrow,
html.has-reveal .hero.is-run .hero-slide.is-active .hero-headline,
html.has-reveal .hero.is-run .hero-slide.is-active .hero-subhead,
html.has-reveal .hero.is-run .hero-slide.is-active .hero-ctas {
    opacity: 1;
    transform: none;
    transition: opacity .9s cubic-bezier(.16, 1, .3, 1), transform .9s cubic-bezier(.16, 1, .3, 1);
}
/* Staffelung (Regler): Eyebrow -> Headline -> Subhead -> CTAs */
html.has-reveal .hero.is-run .hero-slide.is-active .hero-eyebrow  { transition-delay: .10s; }
html.has-reveal .hero.is-run .hero-slide.is-active .hero-headline { transition-delay: .22s; }
html.has-reveal .hero.is-run .hero-slide.is-active .hero-subhead  { transition-delay: .34s; }
html.has-reveal .hero.is-run .hero-slide.is-active .hero-ctas     { transition-delay: .46s; }

/* Motiv: leicht unscharf -> scharf (nur Bild/Video; die programmatische KuZu-Slide
   hat kein Motiv-Element und animiert ohnehin selbst) */
html.has-reveal .hero-slide .hero-img,
html.has-reveal .hero-slide .hero-video {
    filter: blur(10px);
    transition: filter .4s ease;
}
html.has-reveal .hero.is-run .hero-slide.is-active .hero-img,
html.has-reveal .hero.is-run .hero-slide.is-active .hero-video {
    filter: blur(0);
    transition: filter 1.1s cubic-bezier(.16, 1, .3, 1) .05s;
}

/* Not-Restore: falls das is-run-Script nie lief (Skripte hängen), zeigt der
   3s-Safety-Marker alles — MUSS der letzte Block dieses Abschnitts bleiben. */
html.reveal-safety .hero-slide .hero-eyebrow,
html.reveal-safety .hero-slide .hero-headline,
html.reveal-safety .hero-slide .hero-subhead,
html.reveal-safety .hero-slide .hero-ctas {
    opacity: 1;
    transform: none;
}
html.reveal-safety .hero-slide .hero-img,
html.reveal-safety .hero-slide .hero-video { filter: none; }

/* =====================  REDUCED MOTION  ===================== */
@media (prefers-reduced-motion: reduce) {
    .hero-slide { transition: none; }
    .hero-cta, .hero-dot__seg, .hero-badge { transition: none; }
}
