/* ==========================================================================
   Components – wiederverwendbare UI-Bausteine
   Buttons · Slider · Seiten-Intro · Galerie-Grid · Lightbox · Formular · Karten
   ========================================================================== */

/* --- Buttons ------------------------------------------------------------- */
.btn {
    display: inline-block;
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--c-ink);
    padding: 0.95em 2.2em;
    border: 1px solid var(--c-ink);
    border-radius: var(--radius);
    background: transparent;
    cursor: pointer;
    transition: background var(--t-base), color var(--t-base), border-color var(--t-base);
}

.btn:hover {
    background: var(--c-ink);
    color: var(--c-bg);
}

.btn--accent {
    border-color: var(--c-accent);
    color: var(--c-white);
    background: var(--c-accent);
}

.btn--accent:hover {
    background: var(--c-accent-deep);
    border-color: var(--c-accent-deep);
    color: var(--c-white);
}

.btn--light {
    border-color: var(--c-white);
    color: var(--c-white);
}

.btn--light:hover {
    background: var(--c-white);
    color: var(--c-ink);
}

/* --- Galerie-CTA (editoriale Anfrage-Einheit unter Galerien) ------------- */
.gallery-cta {
    margin-top: var(--sp-6);
    padding-top: var(--sp-5);
    text-align: center;
}

/* kurze, mittige Akzentlinie als dezenter Auftakt */
.gallery-cta::before {
    content: "";
    display: block;
    width: 48px;
    height: 1px;
    margin: 0 auto var(--sp-4);
    background: var(--c-accent);
}

/* Übergang Galerie → Einladungskarte: kurze, mittige Einleitung im
   Serifen-Stil. Führt den Blick weiter und füllt den Abstand gestaltet,
   statt eine leere Lücke zu lassen. */
.gallery-bridge {
    margin-top: var(--sp-7);
    text-align: center;
}

.gallery-bridge__eyebrow {
    margin-bottom: 0;
}

/* Einleitung übernimmt den Abstand – Karte rückt näher heran. */
.gallery-bridge + .gallery-cta--framed {
    margin-top: var(--sp-4);
}

/* Karten-Variante: breites Querbild oben, Text darunter – ruhige
   „Einladungskarte“. */
.gallery-cta--framed {
    display: block;
    padding-top: 0;
    margin-top: var(--sp-7);
    text-align: center;
    background: var(--c-bg-light);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-soft);
    overflow: hidden;
}

/* Akzentlinie entfällt in der Karte – sie sitzt im Textteil (siehe __body). */
.gallery-cta--framed::before {
    content: none;
}

.gallery-cta__media {
    overflow: hidden;
}

/* Querformat: breites Bild oben als Blickfang. */
.gallery-cta__media img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
}

.gallery-cta__body {
    padding: var(--sp-5);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Feine Akzentlinie über dem Titel – wie in der zentrierten Variante,
   hier aber links ausgerichtet. */
.gallery-cta__body::before {
    content: "";
    display: block;
    width: 48px;
    height: 1px;
    margin: 0 auto var(--sp-3);
    background: var(--c-accent);
}

.gallery-cta__title {
    font-family: var(--font-head);
    font-style: italic;
    font-size: var(--fs-lg);
    font-weight: 500;
    line-height: 1.2;
    color: var(--c-ink);
    margin-bottom: var(--sp-2);
}

.gallery-cta__text {
    max-width: 40ch;
    margin: 0 auto var(--sp-2);
    color: var(--c-ink-soft);
}

/* Text-Link mit feiner, animierter Unterstreichung – elegant & dezent */
.gallery-cta__link {
    display: inline-block;
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--c-accent);
    padding-bottom: 12px;
    background-image: linear-gradient(var(--c-accent), var(--c-accent));
    background-size: 100% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size var(--t-base), color var(--t-base);
}

.gallery-cta__link:hover {
    color: var(--c-accent-deep);
    background-size: 0% 1px;
    background-position: 100% 100%;
}

/* Auf dem Desktop kompakter: schmaler und mittig, statt die volle
   Container-Breite zu füllen – die Karte schließt sauber ab. */
@media (min-width: 701px) {
    .gallery-cta--framed {
        max-width: 640px;
        margin-inline: auto;
    }
    .gallery-cta__body {
        padding: var(--sp-5) var(--sp-6);
    }
}

/* Mobil: etwas weniger Abstand nach oben. */
@media (max-width: 700px) {
    .gallery-cta--framed {
        margin-top: var(--sp-6);
    }
    .gallery-cta__body {
        padding: var(--sp-4);
    }
}

/* --- Startseiten-Slider (Hero) ------------------------------------------- */
.hero {
    position: relative;
    /* --hero-offset wird per JS auf die ECHTE Header-Höhe gesetzt (Fallback:
       --header-h), damit der Hero exakt den Rest des ersten Viewports füllt.
       dvh = stabile Viewport-Höhe auch auf Mobil (Browser-Leisten korrekt). */
    height: calc(100vh - var(--hero-offset, var(--header-h)));
    height: calc(100dvh - var(--hero-offset, var(--header-h)));
    min-height: 520px;
    overflow: hidden;
    background: var(--c-bg-deep);
}

.hero__slides {
    position: absolute;
    inset: 0;
}

.hero__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    z-index: 1;
    transition: opacity 1.6s var(--ease);
    /* Eigene GPU-Ebene → der Crossfade läuft flüssig, ohne Ruckeln. */
    will-change: opacity;
    transform: translateZ(0);
    backface-visibility: hidden;
}

/* Sauberer Crossfade ohne Abdunkeln: das neue Bild blendet OBEN ein (is-active),
   das vorherige bleibt darunter deckend liegen (is-leaving), bis es verdeckt ist.
   So scheint nie der dunkle Hintergrund durch zwei halbtransparente Bilder. */
.hero__slide.is-leaving {
    opacity: 1;
    z-index: 2;
}

.hero__slide.is-active {
    opacity: 1;
    z-index: 3;
}

.hero__slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.04);
}

/* Sehr langsamer Ken-Burns-Zoom – als Animation, damit er auch beim
   ersten (schon beim Laden aktiven) Slide sofort startet.
   Wichtig: Der Zoom läuft auch auf dem ausblendenden Bild (is-leaving) NAHTLOS
   weiter – derselbe Animationslauf, kein Reset. So springt das alte Bild nicht
   auf Originalgröße zurück, während es noch sichtbar ist. Zurückgesetzt wird es
   erst, wenn es nicht mehr is-leaving ist – dann liegt es längst verdeckt. */
.hero__slide.is-active img,
.hero__slide.is-leaving img {
    animation: hero-kenburns 7s ease-out forwards;
    will-change: transform;
}

@keyframes hero-kenburns {
    from { transform: scale(1.04); }
    to   { transform: scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
    .hero__slide.is-active img,
    .hero__slide.is-leaving img { animation: none; transform: scale(1.04); }
}

.hero__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(20,20,18,0.15) 0%, rgba(20,20,18,0.42) 100%);
    z-index: 4;
}

.hero__content {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--sp-3);
    padding-inline: var(--sp-3);
    color: var(--c-white);
}

.hero__title {
    color: var(--c-white);
    font-size: var(--fs-2xl);
    font-weight: 400;
    max-width: 16ch;
}

.hero__subtitle {
    font-size: var(--fs-xs);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: rgba(255,255,255,0.85);
}

/* Kurzer Satz über dem Button – wechselt sanft mit dem Slider (siehe slider.js).
   Kein eigener Abstand: der Flex-Gap von .hero__content sorgt für denselben
   Abstand zum großen Text wie beim Wort darüber. */
.hero__caption {
    font-size: var(--fs-sm);
    font-style: italic;
    color: rgba(255,255,255,0.92);
    /* Einblenden dauert genauso lange wie das Bild (1.6s). */
    transition: opacity 1.6s var(--ease);
    /* Sprüche immer einzeilig – kein Umbruch, kein Absatz. */
    white-space: nowrap;
    /* Platz für eine Zeile bleibt reserviert, auch wenn kein Spruch da ist –
       so springt der Button nicht, wenn ein Slide ohne Text kommt. */
    min-height: 1.4em;
}

.hero__caption.is-fading {
    opacity: 0;
    /* Aus- und Einblenden dauern beide 1.6s – exakt so lang wie der Bildwechsel
       (siehe transition oben). Der Spruch faded also im selben Tempo wie sein Bild. */
}

/* Dezenter Pfeil nach unten statt Button – führt sanft zu den Portfolio-Vorschauen. */
.hero__scroll {
    margin-top: var(--sp-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.6);
    color: var(--c-white);
    transition: border-color .3s var(--ease), background-color .3s var(--ease);
    animation: hero-scroll-bounce 2.8s ease-in-out infinite;
}

.hero__scroll:hover {
    border-color: var(--c-white);
    background-color: rgba(255,255,255,0.12);
}

/* Chevron aus zwei gedrehten Linien – zeigt nach unten. */
.hero__scroll-chevron {
    width: 12px;
    height: 12px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
}

@keyframes hero-scroll-bounce {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(6px); }
}

@media (prefers-reduced-motion: reduce) {
    .hero__scroll { animation: none; }
}

/* Slider-Steuerung (Punkte) */
.hero__dots {
    position: absolute;
    bottom: var(--sp-4);
    left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    display: flex;
    gap: var(--sp-1);
}

.hero__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    border: 1px solid var(--c-white);
    background: transparent;
    cursor: pointer;
    padding: 0;
    transition: background var(--t-fast);
}

.hero__dot.is-active {
    background: var(--c-white);
}

/* --- Seiten-Intro (Galerie-/Inhaltsseiten) ------------------------------- */
.page-intro {
    text-align: center;
    padding-block: var(--sp-6) var(--sp-4);
}

.page-intro__title {
    margin-bottom: var(--sp-2);
}

.page-intro__desc {
    margin-inline: auto;
    max-width: 56ch;
    color: var(--c-ink-soft);
}

/* --- Galerie-Einschub (Text-Kachel mitten im Mosaik) --------------------- */
/* Der Textblock sitzt als eigene Kachel im Spalten-Mosaik; die Bilder fließen
   oben, unten und seitlich darum herum. */
.gallery-interlude {
    text-align: center;
}

.gallery-interlude__title {
    /* Alle Einschub-Titel gleich groß & gleich skalierend – egal ob als h1
       (SEO-Haupttitel „Euer schönster Tag") oder h2 ausgezeichnet. */
    font-size: var(--fs-xl);
    margin-bottom: var(--sp-2);
}

.gallery-interlude__desc {
    margin-inline: auto;
    max-width: 40ch;
    color: var(--c-ink-soft);
}

/* --- Galerie-Grid -------------------------------------------------------- */
.gallery {
    margin-bottom: var(--sp-6);
}

.gallery__heading {
    text-align: center;
    margin-bottom: var(--sp-4);
}

.gallery__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-2);
}

.gallery__item {
    position: relative;
    display: block;
    overflow: hidden;
    background: var(--c-bg-deep);
    aspect-ratio: 4 / 5;
    cursor: zoom-in;
}

.gallery__item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--t-slow);
}

.gallery__item:hover img {
    transform: scale(1.05);
}

/* Teaser-Label (nur auf verlinkten Kacheln, z. B. Startseite) */
.gallery__item-label {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-head);
    font-size: var(--fs-lg);
    letter-spacing: 0.04em;
    color: var(--c-white);
    background: rgba(20, 20, 18, 0.28);
    opacity: 1;
    transition: background var(--t-base);
}

.gallery__item:hover .gallery__item-label {
    background: rgba(20, 20, 18, 0.45);
}

/* --- Startseite: Portfolio-Teaser (organische Blob-Cluster) -------------- */
/* Der Farbumbruch zum getönten Instagram-Bereich liegt an der Kante zwischen
   diesen beiden Sektionen. Damit er GENAU MITTIG zwischen den Teasern und dem
   Instagram-Inhalt sitzt, ist der Abstand hier unten gleich groß wie der
   Innenabstand oben im Instagram-Bereich (#instagram, siehe unten). */
#portfolio-teaser {
    padding-bottom: calc(var(--sp-7) + var(--sp-5));
}

#instagram {
    padding-top: calc(var(--sp-7) + var(--sp-5));
}

/* Basis-Layout (immer sichtbar): zentrierte Reihe. Dient zugleich als
   Fallback, falls der Browser keine Trigonometrie in CSS kann. */
.portfolio-teasers {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--sp-5);
}

.portfolio-teaser {
    display: block;
    text-decoration: none;
    color: inherit;
    width: 220px;
    max-width: 30%;
}

/* Kreisförmige Anordnung – nur wenn cos()/sin() unterstützt werden.
   Die Teaser sitzen auf einer quadratischen Bühne und werden je nach Winkel
   (aus Index --i und Gesamtzahl --total) nach außen versetzt. Ohne Support
   bleibt das sichtbare Reihen-Layout oben bestehen. */
@supports (width: calc(cos(30deg) * 1px)) {
    .portfolio-teasers {
        --stage: min(840px, 92vw);            /* Durchmesser der Bühne */
        --radius: calc(var(--stage) * 0.39);  /* Abstand der Teaser zur Mitte */
        --item: calc(var(--stage) * 0.42);    /* Breite eines Teasers */
        display: block;
        position: relative;
        width: var(--stage);
        aspect-ratio: 1 / 1;
        margin-inline: auto;
    }

    .portfolio-teaser {
        --angle: calc(360deg / var(--total) * var(--i) - 90deg); /* Start oben */
        position: absolute;
        top: 50%;
        left: 50%;
        width: var(--item);
        max-width: none;
        /* In die Mitte rücken und entlang des Winkels nach außen versetzen. */
        transform:
            translate(-50%, -50%)
            translate(calc(cos(var(--angle)) * var(--radius)),
                      calc(sin(var(--angle)) * var(--radius)));
    }
}

/* Quadratische Bühne, in der die drei Blobs überlappend sitzen. */
.portfolio-teaser__cluster {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    transition: transform var(--t-slow);
}

.portfolio-teaser__blob {
    position: absolute;
    overflow: hidden;
    background: var(--c-bg-deep);
    width: 62%;
    aspect-ratio: 1 / 1;
    transition: box-shadow var(--t-base);
    /* Nur die organische Kontur dreht/morpht sich – das Bild bleibt still.
       Dauer & Phase je Form individuell (siehe unten). */
    animation: blob-morph 18s ease-in-out infinite;
    will-change: border-radius;
}

/* Die border-radius-Kontur wandert langsam um die Form -> wirkt wie eine
   sanfte Eigendrehung der organischen Form, ohne das Bild zu bewegen. */
@keyframes blob-morph {
    0%, 100% { border-radius: 63% 37% 58% 42% / 60% 40% 60% 40%; }
    25%      { border-radius: 42% 58% 63% 37% / 42% 60% 40% 58%; }
    50%      { border-radius: 37% 63% 42% 58% / 40% 42% 60% 58%; }
    75%      { border-radius: 58% 42% 37% 63% / 58% 40% 42% 60%; }
}

.portfolio-teaser__blob img {
    /* Bild füllt die volle Form. Da die Kontur immer innerhalb des Quadrats
       liegt, ist die Form in jeder Morph-Position komplett gefüllt. */
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Drei verschiedene organische Formen, überlappend zu einer Rundform.
   Unterschiedliche Dauer/Verzögerung -> die Formen drehen nie synchron. */
.portfolio-teaser__blob--1 {
    top: 0;
    left: 0;
    z-index: 1;
    border-radius: 63% 37% 58% 42% / 60% 40% 60% 40%;
    animation-duration: 16s;
}

.portfolio-teaser__blob--2 {
    top: 6%;
    right: 0;
    z-index: 2;
    border-radius: 38% 62% 45% 55% / 55% 42% 58% 45%;
    animation-duration: 20s;
    animation-delay: -6s;
}

.portfolio-teaser__blob--3 {
    bottom: 0;
    left: 19%;
    z-index: 3;
    border-radius: 52% 48% 40% 60% / 45% 55% 48% 52%;
    animation-duration: 18s;
    animation-delay: -11s;
}

/* Beim Hover zoomt der gesamte Cluster sanft (statt der einzelnen Bilder,
   damit die laufende Dreh-Animation nicht überschrieben wird) und die Blobs
   heben sich per Schatten hervor. */
.portfolio-teaser:hover .portfolio-teaser__cluster {
    transform: scale(1.04);
}

.portfolio-teaser:hover .portfolio-teaser__blob {
    box-shadow: 0 14px 40px rgba(20, 20, 18, 0.25);
}

/* Titel unter dem Cluster. */
.portfolio-teaser__label {
    display: block;
    margin-top: var(--sp-3);
    text-align: center;
    font-family: var(--font-head);
    font-size: var(--fs-lg);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--c-ink);
    transition: color var(--t-base);
}

.portfolio-teaser:hover .portfolio-teaser__label {
    color: var(--c-accent);
}

/* --- Mosaik (Bilder im Originalformat, justierte Reihen / Spalten) -------
   Die erste Reihe einer Galerie bleibt das beschnittene .gallery__grid,
   alle weiteren Bilder erscheinen hier im Originalformat. mosaic.js setzt
   je nach data-mosaic-mode die Maße ("justified") bzw. baut Spalten auf
   ("columns"). */
.gallery__mosaic {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
    --mosaic-row-h: 300px;   /* angestrebte Reihenhöhe (von mosaic.js gesetzt) */
}

/* Einzelnes Mosaik-Bild – Container; Maße kommen je Modus. */
.gallery__mosaic-item {
    position: relative;
    display: block;
    overflow: hidden;
    background: var(--c-bg-deep);
    cursor: zoom-in;
}

.gallery__mosaic-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--t-slow);
}

.gallery__mosaic-item:hover img {
    transform: scale(1.05);
}

/* Spalten-Modus: feste Spaltenzahl, jedes Bild im Originalformat. mosaic.js
   verteilt die Bilder auf .mosaic-col und füllt die kürzeste Spalte zuerst. */
.gallery__mosaic[data-mosaic-mode="columns"] {
    --mosaic-cols: 3;
    align-items: flex-start;
}

.mosaic-col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.gallery__mosaic[data-mosaic-mode="columns"] .gallery__mosaic-item {
    width: 100%;
    aspect-ratio: var(--ar, 1.5);
}

.gallery__mosaic[data-mosaic-mode="columns"] .gallery__mosaic-item img {
    height: auto;
}

/* Text-Kachel im Mosaik: keine feste Bildproportion (Höhe = Textinhalt),
   nicht klickbar, ruhige Fläche statt Foto. */
.gallery__mosaic-item--text,
.gallery__mosaic[data-mosaic-mode="columns"] .gallery__mosaic-item--text {
    aspect-ratio: auto;
    height: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: visible;
    background: transparent;
    cursor: default;
    padding: var(--sp-5) var(--sp-3);
}

/* Ausgeglichenes letztes Bild einer kürzeren Spalte: füllt die per JS gesetzte
   Höhe komplett aus (Überschuss wird durch object-fit: cover beschnitten),
   damit alle Spalten unten bündig abschließen. */
.gallery__mosaic[data-mosaic-mode="columns"] .gallery__mosaic-item.is-stretched img {
    height: 100%;
}

/* --- Lightbox ------------------------------------------------------------ */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: var(--c-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-base), visibility var(--t-base);
}

.lightbox.is-open {
    opacity: 1;
    visibility: visible;
}

.lightbox__img {
    max-width: 92vw;
    max-height: 88vh;
    object-fit: contain;
    box-shadow: var(--shadow-soft);
    /* Sanft und fließend: Bild zoomt beim Öffnen weich ein statt hart zu
       erscheinen. */
    opacity: 0;
    transform: scale(0.94);
    transition: opacity var(--t-base), transform var(--t-base);
}

.lightbox.is-open .lightbox__img {
    opacity: 1;
    transform: scale(1);
}

.lightbox__btn {
    position: absolute;
    background: transparent;
    border: 0;
    color: var(--c-white);
    cursor: pointer;
    font-size: 2.4rem;
    line-height: 1;
    padding: var(--sp-2);
    opacity: 0.8;
    transition: opacity var(--t-fast);
}

.lightbox__btn:hover { opacity: 1; }
.lightbox__close { top: var(--sp-2); right: var(--sp-2); }
.lightbox__prev  { left: var(--sp-1); top: 50%; transform: translateY(-50%); }
.lightbox__next  { right: var(--sp-1); top: 50%; transform: translateY(-50%); }

/* --- Kontaktformular ----------------------------------------------------- */
.form {
    max-width: var(--container-text);
    margin-inline: auto;
}

.form__row {
    margin-bottom: var(--sp-3);
}

.form__row--split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-3);
}

.form__label {
    display: block;
    font-size: var(--fs-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--c-accent);
    margin-bottom: var(--sp-1);
}

.form__input,
.form__select,
.form__textarea {
    width: 100%;
    font-family: var(--font-body);
    font-size: var(--fs-base);
    color: var(--c-ink);
    background: var(--c-white);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    padding: 0.85em 1em;
    transition: border-color var(--t-fast);
}

.form__input:focus,
.form__select:focus,
.form__textarea:focus {
    outline: none;
    border-color: var(--c-accent);
}

.form__textarea {
    min-height: 180px;
    resize: vertical;
}

/* Honeypot-Feld (Spam-Falle) – visuell entfernt */
.form__hp {
    position: absolute;
    left: -9999px;
    opacity: 0;
    height: 0;
    width: 0;
    overflow: hidden;
}

.form__consent {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
    font-size: var(--fs-sm);
}

.form__consent input { margin-top: 0.3em; }

.form__error {
    display: block;
    margin-top: var(--sp-1);
    font-size: var(--fs-xs);
    color: #9a3412;
}

.form__feedback {
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius);
    margin-bottom: var(--sp-3);
}

.form__feedback--ok {
    background: color-mix(in srgb, var(--c-accent) 18%, var(--c-bg));
    color: var(--c-accent-deep);
    border: 1px solid var(--c-accent);
}

.form__feedback--error {
    background: #f7e7e3;
    color: #9a3412;
    border: 1px solid #d98b76;
}

/* --- Inhalts-Layout (Über mich, Recht) ----------------------------------- */
.prose h2 { margin-block: var(--sp-4) var(--sp-2); }
.prose h3 { margin-block: var(--sp-3) var(--sp-1); }
.prose p  { margin-bottom: var(--sp-2); }
.prose ul { margin: 0 0 var(--sp-2) var(--sp-3); }

.split {
    display: grid;
    /* Schmale Fotospalte (bündig links), breite Textspalte – das Foto bleibt
       dezent, ohne dass eine tote Fläche zwischen Foto und Text entsteht. */
    grid-template-columns: minmax(400px, 580px) 1fr;
    gap: var(--sp-5);
    /* Text vertikal mittig neben dem Foto ausrichten. */
    align-items: center;
}

/* Über-mich-Foto (Einzelbild)
   Das Bild wird in seinem NATÜRLICHEN Seitenverhältnis gezeigt – kein
   erzwungenes 4/5 und kein cover-Crop. So zoomt nichts hinein und der weiße
   Rahmen umschließt exakt das ganze Foto. */
.about__photo img {
    display: block;
    width: 100%;        /* füllt die schmale Spalte (max. 360px) */
    height: auto;       /* Höhe folgt dem echten Seitenverhältnis */
    border-radius: var(--radius);
    /* Eleganter weißer Rahmen (Passepartout-Look) mit dezentem Schatten */
    border: 10px solid #fff;
    box-shadow: 0 18px 45px rgba(0, 0, 0, 0.12);
}

/* Über-mich-Foto: mehrere Bilder, die sich am SELBEN Platz überblenden
   (statt untereinander zu stehen). Steuerung der Ein-/Ausblendung: about-fade.js */
.about__photo--fade .about__slides {
    position: relative;            /* Bezugsrahmen für die gestapelten Bilder */
    width: 100%;                   /* füllt die schmale Spalte, wie das Einzelbild */
    aspect-ratio: 4 / 5;
    border-radius: var(--radius);
    overflow: hidden;
    /* Gleicher weißer Rahmen wie beim Einzelbild */
    border: 10px solid #fff;
    box-shadow: 0 18px 45px rgba(0, 0, 0, 0.12);
}
.about__slide {
    position: absolute;           /* alle Bilder exakt deckungsgleich */
    inset: 0;
    will-change: opacity;
}
.about__photo--fade img {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;           /* überschreibt die 4/5-Regel des Einzelbilds */
    object-fit: cover;
    border-radius: 0;             /* Rundung übernimmt der Container */
    box-shadow: none;
}

/* CTA-Band */
.cta-band {
    background: var(--c-bg-deep);
    text-align: center;
    padding-block: var(--sp-6);
    margin-top: var(--sp-6);
}

/* Folgt das CTA-Band direkt auf einen getönten Bereich (z. B. Instagram auf der
   Startseite), entfällt der Außenabstand – sonst blitzt dazwischen ein beiger
   Streifen durch. Die beiden Flächen gehen so sauber ineinander über. */
.section--tint + .cta-band {
    margin-top: 0;
}

.cta-band__title { margin-bottom: var(--sp-3); }

/* --- Ablauf / Prozess-Schritte („So läuft's ab“) ------------------------- */
.steps {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-4);
    margin-top: 3.5rem; /* Abstand zwischen Überschrift und Schritten */
}

/* Sanfter Hover: die Schritte sind normal dezent gedämpft (dunkler); der
   Schritt, über den man fährt, wird heller und wächst leicht – so sieht man,
   auf welchem Schritt man gerade ist. */
.step {
    opacity: 0.62; /* Grundzustand: etwas zurückgenommen */
    transition: transform 0.35s ease, opacity 0.35s ease;
}

.step:hover {
    opacity: 1; /* aktiver Schritt hebt sich hell hervor */
    transform: scale(1.06);
}

.step__no {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    border: 1px solid var(--c-accent);
    color: var(--c-accent-deep);
    font-family: var(--font-head);
    font-size: var(--fs-lg);
    line-height: 1;                    /* enge Zeilenhöhe: Ziffer sitzt mittig */
    font-feature-settings: "lnum" 1;   /* Versalziffern (gleiche Höhe) */
    margin-bottom: var(--sp-2);
    transition: background 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}

/* Beim Hover füllt sich die Ziffer und wird dadurch klar hervorgehoben. */
.step:hover .step__no {
    background: var(--c-accent);
    color: #fff;
    border-color: var(--c-accent);
}

.step h3 {
    margin: 0 0 var(--sp-1);
    transition: color 0.35s ease;
}

.step:hover h3 { color: var(--c-accent-deep); }

.step p {
    margin: 0;
    color: var(--c-ink-soft);
    font-size: var(--fs-sm);
}

/* --- Timeline: „Ein Tag mit mir“ (Ablauf des Hochzeitstags) ---------------
   Vertikale Zeitleiste mit Punkten – ergänzt den 4-Schritte-Plan um den
   konkreten Tagesablauf. */
.timeline {
    max-width: var(--container-text);
    margin-inline: auto;
    position: relative;
    padding-left: var(--sp-4);
}
.timeline::before {
    content: "";
    position: absolute;
    left: 7px;
    top: 6px;
    bottom: 6px;
    width: 2px;
    background: var(--c-line);
}
.timeline__item { position: relative; padding: 0 0 var(--sp-4) var(--sp-4); }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__item::before {
    content: "";
    position: absolute;
    left: 0;
    top: 6px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--c-bg);
    border: 2px solid var(--c-accent);
}
.timeline__time {
    font-size: var(--fs-xs);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--c-accent-deep);
}
.timeline__item h3 { margin: 0.2rem 0 0.2rem; font-size: var(--fs-md); }
.timeline__item p  { margin: 0; color: var(--c-ink-soft); font-size: var(--fs-sm); }

/* --- Werte-Karten: „So arbeite ich“ (was Besucher bekommen) --------------- */
.values {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-4);
    margin-top: 3.5rem;
}
.value {
    text-align: center;
    padding: var(--sp-4);
    background: var(--c-white);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.value:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .08);
}
.value:hover .value__icon {
    transform: scale(1.08);
}
.value__icon {
    width: 26px;
    height: 26px;
    margin: 0 auto var(--sp-2);
    color: var(--c-accent-deep);
    transition: transform .3s ease;
}
.value__icon svg { width: 100%; height: 100%; }
.value h3 { margin: 0 0 var(--sp-1); font-size: var(--fs-md); }
.value p  { margin: 0; color: var(--c-ink-soft); font-size: var(--fs-sm); }
@media (max-width: 720px) {
    .values { grid-template-columns: 1fr; }
}


/* Getönte Sektion: helles Creme über die volle Breite – hebt den Bereich
   dezent und freundlich vom beigen Seitenhintergrund ab. */
.section--tint {
    background: var(--c-bg-light);
}

/* --- Gerissenes Papierstück als Sektions-Trenner („Idee B") ------------------
   Wo sich die Hintergrundfarbe ändert (Beige → Creme bzw. Creme → tiefes Beige
   des CTA-Bands), liegt ein echtes gerissenes Papierstück über der Naht – wie
   bei emelyundsophie.de mit einer echten Rissgrafik, nur in deiner Farbwelt
   (echtes Pergament, CC0). Das Bild ist ein heller Streifen mit OBERER und
   UNTERER Reißkante; oben und unten transparent, sodass beide Nachbarfarben
   durch die gerissenen Kanten scheinen und keiner der Übergänge eine gerade
   Linie ist. Der Streifen straddelt die Naht (halb darüber, halb darunter);
   seine opake Mitte verdeckt die harte Farbkante. Ein Bild bedient jeden
   Übergang. Reine CSS-Lösung, keine HTML-Änderung nötig. */
.section--tint,
.cta-band {
    position: relative;
}

.section--tint::before,
.cta-band::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(100% - 30px);    /* Streifenmitte auf die Naht → straddelt */
    height: 60px;
    background: url(/assets/img/torn-band.png) no-repeat left bottom / 100% 100%;
    pointer-events: none;
    z-index: 1;
}

/* Folgen zwei gleichfarbige getönte Sektionen aufeinander (z. B. Instagram →
   FAQ auf der Startseite), gibt es keinen Farbwechsel – dann entfällt der
   Trenner, damit kein Streifen ohne Farbwechsel erscheint. */
.section--tint + .section--tint::before {
    content: none;
}

/* --- Instagram-Feed-Teaser -------------------------------------------------
   Bilder werden in ihrem Originalformat gezeigt (kein quadratischer Zuschnitt),
   so wie ein Beitrag im Instagram-Feed aussieht. */
.ig-grid {
    /* Flexbox statt festem Raster: So zählt immer nur die tatsächliche
       Bildanzahl – jede (auch unvollständige) Reihe wird automatisch mittig
       zentriert, egal ob 4, 5 oder 6 Bilder. */
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    gap: var(--sp-1);
    margin-top: 3.5rem;
    --ig-tile: 160px;
}

.ig-grid__item {
    position: relative;
    display: block;
    flex: 0 0 var(--ig-tile);
    overflow: hidden;
    border-radius: var(--radius);
    margin: 0;
    /* Ganze Kachel wächst beim Hover – transform-origin bleibt mittig,
       Schatten hebt das Bild sanft ab. Weicher, längerer Verlauf mit
       sanftem Ein-/Ausgang statt ruckartigem Springen. */
    transform: scale(1);
    transition: transform 0.6s cubic-bezier(0.34, 1.2, 0.42, 1),
                box-shadow 0.6s ease;
    /* Eigene GPU-Ebene → das Skalieren des großen Bildes läuft flüssig,
       ohne Ruckeln beim Neuzeichnen. */
    will-change: transform;
    backface-visibility: hidden;
    transform-origin: center;
}

/* Beim Überfahren wächst die komplette Kachel und legt sich über die
   Nachbarn (z-index), statt nur das Bild innerhalb des Rahmens zu zoomen. */
.ig-grid__item:hover {
    transform: scale(1.28);
    z-index: 2;
    box-shadow: 0 1.6rem 3rem rgba(0, 0, 0, 0.26);
}

/* Kleines Play-Symbol für Video-Beiträge (Reels). */
.ig-grid__badge {
    position: absolute;
    top: var(--sp-1);
    right: var(--sp-1);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    font-size: 0.7rem;
    color: #fff;
    background: rgba(0, 0, 0, 0.45);
    border-radius: 50%;
    pointer-events: none;
}

.ig-grid img {
    display: block;
    width: 100%;
    height: auto;
}

/* --- Responsive ---------------------------------------------------------- */

/* Große Monitore ab 1920px (Full HD und größer): Bei nur 3 Spalten und voller
   Seitenbreite werden die Mosaik-Bilder zu groß -> ab hier 4 Spalten. Alles
   darunter (MacBook, Tablets, Handy) bleibt unverändert bei 3 (bzw. 2/1)
   Spalten. Nur der Spalten-Modus wird angefasst – mosaic.js packt die Bilder
   lückenlos in die kürzeste Spalte und gleicht die Unterkanten an, daher
   entstehen KEINE weißen Leerräume. Die beschnittene 3er-Reihe darüber bleibt
   bewusst als Featured-Highlight. */
@media (min-width: 1920px) {
    .gallery__mosaic[data-mosaic-mode="columns"] { --mosaic-cols: 4; }
}

/* Erste Reihe 4-spaltig: Die Klasse wird von mosaic.js NUR gesetzt, wenn ab
   1920px tatsächlich ein 4. Bild (data-hero-swing) hineingeschoben wurde – so
   bleibt bei Galerien ohne 5. Bild keine leere Rasterzelle. */
.gallery__grid--four { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 820px) {
    .gallery__grid { grid-template-columns: repeat(2, 1fr); }
    /* Kreis bleibt – Bühne kleiner halten, da die Teaser ~10% über die
       Bühne hinausragen; mit 82vw bleibt klarer Abstand zum Rand. */
    .portfolio-teasers { --stage: min(560px, 82vw); }
    .gallery__mosaic { --mosaic-row-h: 220px; }
    .gallery__mosaic[data-mosaic-mode="columns"] { --mosaic-cols: 2; }
    .split { grid-template-columns: 1fr; }
    .steps { grid-template-columns: repeat(2, 1fr); }
    /* Einspaltig: Foto wieder dezent begrenzen und mittig setzen, sonst füllt
       es die volle Breite. Gilt für Einzelbild und Fade-Slideshow. */
    .about__photo img,
    .about__photo--fade .about__slides {
        max-width: 580px;
        margin-inline: auto;
    }
    .form__row--split { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
    .gallery__grid { grid-template-columns: 1fr; }
    .steps { grid-template-columns: 1fr; }
    /* Auf dem Handy 3 Kacheln pro Reihe – Breite füllt den Platz aus,
       bleibt aber über justify-content: center mittig. */
    .ig-grid { --ig-tile: calc((100% - 2 * var(--sp-1)) / 3); }
    .gallery__mosaic { --mosaic-row-h: 160px; }
    .gallery__mosaic[data-mosaic-mode="columns"] { --mosaic-cols: 1; }

    /* Auf dem Handy keinen Kreis: Die kreisförmige Anordnung lässt die
       Teaser über die Bühne hinausragen und damit über den Viewport-Rand
       (horizontales Scrollen / Rauszoomen). Stattdessen sauber gestapelt.
       Überschreibt die @supports-Kreis-Regel per Quellreihenfolge. */
    .portfolio-teasers {
        display: flex;
        flex-direction: column;
        align-items: center;
        position: static;
        width: auto;
        aspect-ratio: auto;
        gap: var(--sp-6);
    }

    .portfolio-teaser {
        position: static;
        transform: none;
        width: min(320px, 80vw);
        max-width: none;
    }
}

/* --- FAQ (Akkordeon, ohne JS via <details>) ------------------------------ */
.faq {
    max-width: var(--container-text);
    margin-inline: auto;
    margin-top: 3.5rem; /* Abstand zwischen Überschrift und Fragen */
}

.faq__item {
    border-bottom: 1px solid var(--c-line);
}

.faq__q {
    list-style: none;
    cursor: pointer;
    padding: var(--sp-3) 0;
    font-family: var(--font-head);
    font-size: var(--fs-md);
    color: var(--c-ink);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-3);
}

/* Marker (Standard-Dreieck) ausblenden und eigenes +/– setzen */
.faq__q::-webkit-details-marker { display: none; }

.faq__q::after {
    content: '+';
    font-family: var(--font-body);
    font-size: 1.4em;
    line-height: 1;
    color: var(--c-accent-deep);
    transition: transform var(--dur, 0.25s) ease;
}

.faq__item[open] .faq__q::after {
    content: '–';
}

.faq__a {
    margin: 0;
    padding: 0 0 var(--sp-3);
    color: var(--c-ink-soft);
    line-height: 1.7;
}

/* ==========================================================================
   Journal / Blog – Übersicht, Karten, Artikel
   ========================================================================== */

/* Kategorie-Filter */
.journal-filter {
    display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3);
    justify-content: center; margin-bottom: var(--sp-5);
}
.journal-filter__item {
    text-decoration: none; color: var(--c-ink-soft);
    font-size: var(--fs-sm); letter-spacing: 0.02em;
    padding-bottom: 2px; border-bottom: 1px solid transparent;
    transition: color var(--t-fast), border-color var(--t-fast);
}
.journal-filter__item:hover { color: var(--c-ink); }
.journal-filter__item.is-active { color: var(--c-ink); border-bottom-color: var(--c-accent); }

/* Beitrags-Raster */
.journal-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--sp-4); margin-bottom: var(--sp-6);
}
.journal-card { background: var(--c-bg-light); border: 1px solid var(--c-line); border-radius: var(--radius); overflow: hidden; }
.journal-card__link { display: block; text-decoration: none; color: inherit; height: 100%; }
.journal-card__media { aspect-ratio: 3 / 2; background: var(--c-bg-deep); overflow: hidden; }
.journal-card__media img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    transition: transform var(--t-base);
}
.journal-card__link:hover .journal-card__media img { transform: scale(1.04); }
.journal-card__media.is-empty { display: block; }
.journal-card__body { padding: var(--sp-3); }
.journal-card__meta { font-size: var(--fs-xs); letter-spacing: var(--ls-wide); text-transform: uppercase; color: var(--c-accent-deep); margin: 0 0 var(--sp-1); }
.journal-card__cat { font-weight: 700; }
.journal-card__title { font-family: var(--font-head); font-size: var(--fs-md); line-height: var(--lh-tight); margin: 0 0 var(--sp-1); }
.journal-card__excerpt { font-size: var(--fs-sm); color: var(--c-ink-soft); margin: 0 0 var(--sp-2); }
.journal-card__more { font-size: var(--fs-sm); color: var(--c-accent-deep); }

.journal-empty { text-align: center; color: var(--c-ink-soft); padding: var(--sp-6) 0; }

/* Einzelbeitrag */
.journal-article { padding-bottom: var(--sp-5); }
.journal-article__head { text-align: center; padding-top: var(--sp-4); }
.journal-article__title { font-family: var(--font-head); font-size: var(--fs-xl); line-height: var(--lh-tight); margin: var(--sp-1) 0; }
.journal-article__lead { font-size: var(--fs-md); color: var(--c-ink-soft); }
.journal-article__head .eyebrow a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--c-line); }

.journal-article__cover {
    max-width: var(--container); margin: var(--sp-4) auto var(--sp-5);
    aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--radius);
}
.journal-article__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.journal-article__body > * { margin-bottom: var(--sp-3); }
.journal-block--text { line-height: var(--lh-base); }
.journal-block--heading { font-family: var(--font-head); line-height: var(--lh-tight); margin-top: var(--sp-4); }
.journal-block--image { margin: var(--sp-4) 0; }
.journal-block--image a { display: block; }
.journal-block--image img { width: 100%; border-radius: var(--radius); display: block; }
.journal-block--image figcaption { font-size: var(--fs-sm); color: var(--c-ink-soft); text-align: center; margin-top: var(--sp-1); }
.journal-block--quote {
    border-left: 3px solid var(--c-accent); padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
    margin: var(--sp-4) 0; font-family: var(--font-head); font-size: var(--fs-md); color: var(--c-ink);
}
.journal-block--quote cite { display: block; font-family: var(--font-body); font-size: var(--fs-sm); font-style: normal; color: var(--c-ink-soft); margin-top: var(--sp-1); }
.journal-block--gallery { margin: var(--sp-4) 0; }

.journal-article__tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.journal-tag { font-size: var(--fs-sm); color: var(--c-accent-deep); text-decoration: none; }
.journal-tag:hover { text-decoration: underline; }
.journal-article__foot { margin-top: var(--sp-5); text-align: center; }

/* ==========================================================================
   Vorher/Nachher-Vergleich (wiederverwendbares Modul)
   Hinweis: aktuell NICHT auf der Seite eingebunden – nur bereitgehalten.
   Aktivierung: render_before_after() aufrufen + before-after.js laden.
   ========================================================================== */
.before-after { margin: var(--sp-4) 0; }
.before-after__stage {
    position: relative; width: 100%; overflow: hidden; border-radius: var(--radius);
    user-select: none; touch-action: pan-y; line-height: 0;
}
.before-after__img { display: block; width: 100%; height: auto; }
.before-after__img--before { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.before-after__clip { position: absolute; inset: 0; width: 50%; overflow: hidden; }
.before-after__badge {
    position: absolute; bottom: var(--sp-2); padding: 2px 10px; border-radius: 999px;
    font-size: var(--fs-xs); letter-spacing: 0.04em; text-transform: uppercase;
    background: rgba(20,20,18,0.6); color: #fff; pointer-events: none;
}
.before-after__badge--before { left: var(--sp-2); }
.before-after__badge--after { right: var(--sp-2); }
.before-after__range {
    position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
    opacity: 0; cursor: ew-resize;
}
.before-after__handle {
    position: absolute; top: 0; bottom: 0; left: 50%; width: 2px;
    background: #fff; transform: translateX(-50%); pointer-events: none;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.25);
}
.before-after__handle::after {
    content: '⟷'; position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%); width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    background: #fff; color: #1a1a1a; border-radius: 50%; font-size: 14px;
    box-shadow: var(--shadow-soft);
}
.before-after figcaption { font-size: var(--fs-sm); color: var(--c-ink-soft); text-align: center; margin-top: var(--sp-1); }

/* --- Wortband (dezentes Endlos-Laufband unter dem Hero) ------------------ */
.wordband {
    overflow: hidden;
    border-bottom: 1px solid var(--c-line);
    padding-block: var(--sp-3);
    background: var(--c-bg);
}
.wordband__track {
    display: flex;
    width: max-content;
    animation: wordband 60s linear infinite;
}
.wordband__track span {
    font-family: var(--font-head);
    font-weight: 400;
    font-size: var(--fs-md);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--c-ink);
    white-space: nowrap;
    margin-inline: var(--sp-4);
}
.wordband__track span::after {
    content: "·";
    margin-left: var(--sp-4);
    color: var(--c-accent);
}
.wordband:hover .wordband__track { animation-play-state: paused; }
@keyframes wordband {
    to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
    .wordband__track { animation: none; justify-content: center; width: 100%; }
}
