/* Hero intro: "Die Montage".
 *
 * WHY THE PICTURE SITS IN A FRAME AND NOT ACROSS THE FULL WIDTH
 *
 * danube-flats-01.jpg is portrait, 1316x1744. The subject runs from the
 * helicopter at 16% of the image height down to the foot of the tower at 88%.
 * A full-bleed hero on a wide desktop is roughly 1780x860, and `object-fit:
 * cover` there can only show 860 / (1780 / 0.755) = 30% of the image height.
 * That is the whole story of the "empty sky" hero: framed on the helicopter,
 * 30% of the height reaches y=0.42, which is precisely where the tower begins.
 * Nothing about the zoom or the anchor could fix it.
 *
 * So the sharp photograph gets .hero-photo: a 1.22:1 frame on the right whose
 * width follows the hero's height. That box sees 62% of the image height, which
 * is the helicopter, the cable, the mast and about two thirds of the tower.
 * On a phone the frame goes full width and, the box being nearly the image's own
 * shape, shows the picture practically whole.
 *
 * The rest of the width is .hero-backdrop, the same file blurred and dimmed, so
 * the hero still reads as one edge-to-edge image instead of a photo pasted onto
 * a panel. It costs no extra download.
 *
 * The camera move itself lives in /js/hero-montage.js, because it has to be
 * computed from the measured box: `object-fit: cover` fills whichever axis needs
 * it, so an `object-position` percentage moves the crop on a wide box and does
 * nothing at all on a narrow one.
 *
 * What stays here is the RESTING STATE and the copy timing. If the script never
 * runs, .hero-bg is a plain covered image, correctly framed, and every piece of
 * text is visible. Nothing is hidden by this file. */

.hero-inner .hero-title,
.hero-inner .hero-lead,
.hero-inner .hero-since { text-shadow: 0 2px 18px rgba(10, 12, 14, .75); }

/* Unscharfe Kopie hinter allem. Der Himmel im Original ist ohnehin fast ein
   Verlauf, deshalb geht die Kante zum scharfen Bild praktisch unsichtbar auf.
   Die Skalierung verdeckt den hellen Rand, den ein Weichzeichner am Bildrand
   sonst stehen laesst. */
/* Anmerkung 2 und 33, "Titelbild viel heller" — zum dritten Mal, und die
   ersten beiden Male am falschen Ort behoben.
   Gemessen am ausgelieferten Bild: das Foto rechts steht bei 75 % Leuchtdichte
   und der Himmel klippt im Rotkanal bereits bei 255, dort ist also nichts mehr
   zu holen. Dunkel war die TEXTSPALTE links mit 32 %: unscharfe Kopie auf 0,68
   abgedunkelt und darueber noch ein Verlauf mit 0,46. Genau die wird jetzt
   aufgehellt, auf gemessene 45 %.
   Weiter geht nicht: weisser Text auf 45 % ergibt 4,74:1, und ab 47 % faellt
   der Fliesstext unter die 4,5:1 der WCAG-AA. */
.hero-backdrop {
    transform: scale(1.16);
    filter: blur(34px) brightness(.88) saturate(.9);
}

.hero-photo {
    /* Weiche linke Kante: statt einer harten Naht laeuft das scharfe Bild in
       die unscharfe Kopie hinein. Die 20 % sind gemessen, nicht geraten: die
       Zeile "Familienbetrieb seit 1934" endet auf einem 1780er Bildschirm bei
       895 px, der Rahmen beginnt bei 716 px, und erst ab 20 % (947 px) liegt
       die ganze Textspalte auf der weichen Flaeche statt auf dem scharfen Foto.
       Weggeblendet wird dabei nur der Baukran am linken Bildrand; Hubschrauber,
       Mast und Turm stehen bei 44 bis 66 % der Bildbreite, weit rechts davon. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 20%);
    mask-image: linear-gradient(90deg, transparent 0, #000 20%);
}

.hero-bg {
    /* Resting frame for the no-JS case: helicopter high, tower below, not sky.
       The script sizes the element once and then only transforms it. */
    object-position: 55% 28%;
    /* Load-bearing: the script scales about the top-left, which is what makes
       its translate arithmetic independent of the element's own size. */
    transform-origin: 0 0;
    /* Keeps the scaled photograph on its own compositor layer, so the pan is
       a texture transform rather than a repaint of a 1316x1744 image. */
    backface-visibility: hidden;
    /* Die Aufnahme ist im Original sehr flau; etwas mehr Helligkeit und
       Kontrast bringt Turm und Hubschrauber vom Himmel weg. */
    filter: brightness(1.16) contrast(1.06) saturate(1.05);
}

/* The hero clips the oversized image, and telling the browser so lets it skip
   painting whatever falls outside. */
.hero-full { contain: paint; }

.hero-scrim {
    /* Zweimal "zu dunkel" vom Kunden. Der Verlauf ist jetzt sehr leicht: die
       Lesbarkeit traegt der Textschatten, und die linke Seite ist ohnehin schon
       die abgedunkelte unscharfe Kopie. Ueber der scharfen Aufnahme rechts
       liegt gar nichts mehr. */
    background: linear-gradient(90deg,
        rgba(30, 34, 38, .34) 0%,
        rgba(30, 34, 38, .13) 40%,
        rgba(30, 34, 38, 0) 59%);
    opacity: 1;
}

/* Only once the script is driving does the scrim have anything to reveal. */
.js-montage .hero-scrim { animation: hero-scrim 1.2s cubic-bezier(.65, 0, .35, 1) both; }

@keyframes hero-scrim {
    0% { opacity: .35; }
    100% { opacity: 1; }
}

.js-montage .hero-inner > * { animation: hero-copy .45s cubic-bezier(.22, .61, .36, 1) both; }
.js-montage .hero-inner > :nth-child(1) { animation-delay: .55s; }
.js-montage .hero-inner > :nth-child(2) { animation-delay: .68s; }
.js-montage .hero-inner > :nth-child(3) { animation-delay: .81s; }

@keyframes hero-copy {
    from { opacity: 0; transform: translateY(18px); }
    to { opacity: 1; transform: none; }
}

.js-montage .hero-seal { animation: hero-seal .5s cubic-bezier(.22, .61, .36, 1) 1s both; }

@keyframes hero-seal {
    from { opacity: 0; transform: scale(.7) rotate(-12deg); }
    to { opacity: 1; transform: none; }
}

/* Caption naming what the picture shows. A corner caption rather than a pointer
   line at the mast: the hero crops differently at every viewport width, so a
   pointer would drift off its target while a corner caption cannot. */
.hero-caption {
    position: absolute;
    left: 0;
    bottom: 0;
    z-index: 2;
    max-width: min(100%, 46rem);
    padding: var(--space-sm) var(--space-md);
    background: rgba(15, 17, 19, .74);
    border-left: 3px solid var(--accent);
    font-family: var(--font-mono);
    font-size: var(--step--1);
    letter-spacing: .06em;
    line-height: 1.6;
    color: var(--steel-100);
}
.js-montage .hero-caption { animation: hero-copy .45s cubic-bezier(.22, .61, .36, 1) 1.1s both; }
.hero-caption a { color: var(--accent); text-decoration: none; }
.hero-caption a:hover { text-decoration: underline; }
.hero-caption strong { color: var(--white); }

/* Reduced motion: the script applies the resting frame at once and never
   animates. These stop the copy and caption fades too. */
@media (prefers-reduced-motion: reduce) {
    .js-montage .hero-scrim,
    .js-montage .hero-inner > *,
    .js-montage .hero-seal,
    .js-montage .hero-caption {
        animation: none;
    }
}

@media (max-width: 720px) {
    /* Bounded so the hero cannot outgrow the viewport, which it did when the
       caption was in normal flow: 1101px tall on an 812px screen. */
    .hero-full { min-height: 72vh; max-height: 88vh; }

    /* Voll ueber die Breite: eine Telefonbox hat fast das Format des Bildes,
       hier sieht der Ausschnitt die Aufnahme nahezu vollstaendig. Der Rahmen
       waere schmaler als der Bildschirm und wuerde nur Platz verschenken. */
    .hero-photo {
        width: 100%;
        aspect-ratio: auto;
        -webkit-mask-image: none;
        mask-image: none;
    }

    /* Damit liegt die unscharfe Kopie vollstaendig hinter der scharfen und ist
       nie zu sehen. Ein 34-px-Weichzeichner ueber ein formatfuellendes Bild ist
       auf aelteren Telefonen teuer, also gar nicht erst zeichnen. */
    .hero-backdrop { display: none; }

    /* Das Siegel sass rechts oben auf gleicher Hoehe wie die Zeile
       "Familienbetrieb seit 1934". Bei 375 px blieben 8 px Abstand, bei 360 px
       und darunter ueberlappten beide. Die Zeile steht jetzt unten bei den
       Schaltflaechen, damit ist die Kollision baulich ausgeschlossen. */
    .hero-seal { width: 56px; height: 56px; top: var(--space-md); right: var(--space-md); }
    .hero-caption {
        right: 0;
        max-width: none;
        padding: .55rem var(--space-md);
        font-size: 0.6875rem;
        letter-spacing: .03em;
    }
}
