/* ==========================================================================
   Echo Klub Rankweil — Stylesheet
   Akzentfarbe: --accent (pro Seite/Event via Blade gesetzt, pro Karte inline)
   ========================================================================== */

:root {
    --bg: #08080c;
    --bg-raised: #101018;
    --surface: #14141e;
    --line: rgba(255, 255, 255, 0.08);
    --text: #f4f4f6;
    --muted: #9a9aa8;
    /* --accent kommt aus dem Layout (Standard oder Event-Theme) */

    --font-display: 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-body: 'Segoe UI', system-ui, -apple-system, sans-serif;

    --pad: clamp(1.25rem, 4vw, 4rem);
    --radius: 14px;
}

*, *::before, *::after { box-sizing: border-box; }

html {
    background: var(--bg);
    color-scheme: dark;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    font-family: var(--font-body);
    /* Bewusst durchsichtig: den Grundton setzt html (oben). Ein eigener
       Hintergrund am body wuerde das Punktraster verdecken - das liegt als
       Kind mit negativem z-index darunter, und der body-Hintergrund wird im
       Malalgorithmus spaeter gezeichnet als solche Kinder. */
    background: transparent;
    color: var(--text);
    line-height: 1.55;
    overflow-x: hidden;
}

img { max-width: 100%; display: block; }

/* ==========================================================================
   Punkte im Hintergrund

   Ein Canvas ueber die volle Flaeche: einzelne Punkte tauchen auf, bleiben
   ein paar Sekunden und verschwinden wieder an anderer Stelle. Beim Scrollen
   ziehen sie Schweife hinter sich her - je schneller gescrollt wird, desto
   laenger. Gezeichnet wird in app.js; ohne JS bleibt schlicht der dunkle
   Grund stehen.
   ========================================================================== */

.bg-dots {
    position: fixed;
    inset: 0;
    z-index: -2;
    display: block;
    width: 100%;
    /* lvh = groesstmoegliche Viewporthoehe. Auf dem iPhone blendet Safari
       beim Scrollen die untere Leiste aus, dadurch waechst die Seitenhoehe -
       mit height:100% wuerde der Canvas dabei staendig neu vermessen und die
       Punkte sprangen. Mit lvh bleibt die Flaeche konstant. */
    height: 100%;
    height: 100lvh;
    pointer-events: none;
    background: var(--bg);
}


a { color: inherit; }

[x-cloak] { display: none !important; }

::selection { background: var(--accent); color: #fff; }

/* Honeypot-Feld unsichtbar, aber nicht display:none (Bots prüfen das) */
.hp-field {
    position: absolute !important;
    left: -9999px !important;
    width: 1px; height: 1px;
    overflow: hidden;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    padding: 0.8em 1.6em;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    letter-spacing: 0.02em;
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.btn:hover { transform: translateY(-2px); }

.btn--accent {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.btn--accent:hover { filter: brightness(1.15); }

.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }

/* ==========================================================================
   Navigation
   ========================================================================== */

.site-nav {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* iOS "Zum Home-Bildschirm": im Fullscreen laeuft der Inhalt sonst unter
       Statusleiste / Dynamic Island. Die Safe-Area-Insets schieben Logo und
       Nav darunter hervor. Im normalen Browser sind die Werte 0 -> kein Effekt. */
    padding-top: calc(1rem + env(safe-area-inset-top, 0px));
    padding-bottom: 1rem;
    padding-left: calc(var(--pad) + env(safe-area-inset-left, 0px));
    padding-right: calc(var(--pad) + env(safe-area-inset-right, 0px));
    background: linear-gradient(to bottom, rgba(8, 8, 12, 0.85), transparent);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.site-nav__logo {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
}

/* Die Marke ist hochkant und schmal - sie darf etwas hoeher stehen als der
   fruehere Schriftzug, sonst wirkt sie in der Leiste verloren. */
.site-nav__logo-img {
    height: 1.7rem;
    width: auto;
    display: block;
}

.site-nav__logo-dot {
    width: 0.5em; height: 0.5em;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 12px var(--accent);
}

.site-nav__links {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 3vw, 2.2rem);
}

.site-nav__links a {
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--muted);
    transition: color 0.2s ease;
}

.site-nav__links a:hover { color: var(--text); }

/* Fuenf Eintraege passen auf schmalen Schirmen nur knapp neben das Logo -
   enger setzen, nicht umbrechen lassen und im Notfall waagrecht schiebbar. */
@media (max-width: 640px) {
    .site-nav { gap: 0.75rem; }

    .site-nav__logo-img { height: 1.4rem; }

    .site-nav__links {
        gap: 0.65rem;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .site-nav__links::-webkit-scrollbar { display: none; }

    .site-nav__links a {
        font-size: 0.78rem;
        white-space: nowrap;
    }
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
    position: relative;
    /* lvh = "large viewport height" (Höhe OHNE die iOS-Adressleiste, also die
       größtmögliche). Damit ist der Hero nie kürzer als der sichtbare Bereich:
       mit eingeblendeter Safari-Leiste ragt er unten knapp drüber hinaus (kein
       Peek der Upcoming-Sektion), ohne Leiste passt er exakt. svh/dvh waren beim
       ersten Paint in Safari zu kurz und die nächste Sektion lugte hervor.
       vh als Fallback für Browser ohne lvh-Unterstützung (iOS < 15.4). */
    min-height: 100vh;
    min-height: 100lvh;
    display: grid;
    place-items: center;
    overflow: hidden;
    isolation: isolate;
    /* Eigener Grund, damit die Punkte aus dem Hintergrund nicht durch das
       halbtransparente Video schimmern. Der Hero soll fuer sich stehen. */
    background: var(--bg);
}

.hero__media { position: absolute; inset: 0; z-index: -1; }

.hero__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.5;
}

.hero__glow {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 80% 55% at 50% 110%, color-mix(in srgb, var(--accent) 45%, transparent), transparent 70%),
        radial-gradient(ellipse 60% 40% at 15% -10%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 70%),
        linear-gradient(to bottom, rgba(8,8,12,0.35), var(--bg) 96%);
}

/* Feines Korn über dem Hero, damit Verläufe nicht "billig" banden */
.hero__grain {
    position: absolute;
    inset: 0;
    opacity: 0.5;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.06'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

.hero__content {
    text-align: center;
    padding: 0 var(--pad);
}

/* Handy: Der Hero misst 100lvh — die Höhe OHNE Safari-Leisten, also die
   größtmögliche. Nur damit ist garantiert, dass die nächste Sektion in KEINEM
   Leistenzustand unten hervorlugt; mit svh tat sie das, sobald Safari die
   Leisten wegklappte und der Viewport wuchs.

   Dass der Hero damit unten über den Bildschirm hinausragt, ist kein Problem
   mehr: Durch diesen Rest muss niemand scrollen, der Hero-Snap überspringt ihn
   (siehe initHeroSnap in app.js).

   Das Boden-Padding in Höhe der Leisten (lvh − svh) schiebt den Inhalt in die
   Mitte des SICHTBAREN Bereichs — ohne säße er zu tief. Auf Desktop ist
   lvh == svh, das Padding also 0. */
@media (max-width: 760px) {
    .hero {
        padding-top: 0;
        padding-bottom: calc(100lvh - 100svh);
    }
}

.hero__wordmark {
    margin: 0;
    display: grid;
    line-height: 0.82;
}

.hero__echo {
    grid-area: 1 / 1;
    width: clamp(260px, 62vw, 760px);
    height: auto;
    justify-self: center;
    align-self: center;
}

/* Leises Atmen der Wortmarke: ein paar Pixel Drift, kaum als Bewegung zu
   benennen — das Logo steht nur nicht mehr tot da. Bewusst über die
   Einzel-Properties `translate`/`rotate`, damit GSAPs `transform` (Intro-Bounce,
   Scroll-Sog) unangetastet bleibt. Der Glow läuft synchron mit, sonst würde
   der Saum unter dem Logo wegrutschen. Start nach der Intro. */
[data-echo],
.hero__aura {
    animation: hero-float 9s ease-in-out 2s infinite;
}

@keyframes hero-float {
    0%   { translate: 0 0;       rotate: 0deg; }
    33%  { translate: -3px -5px; rotate: -0.22deg; }
    66%  { translate: 3px -2px;  rotate: 0.22deg; }
    100% { translate: 0 0;       rotate: 0deg; }
}

/* Geister-Ebenen dienen nur noch dem Glitch am Bounce-Peak (siehe unten),
   im Ruhezustand sind sie unsichtbar. */
.hero__echo--ghost,
.hero__echo--ghost2 {
    opacity: 0;
    pointer-events: none;
}

/* --- Lila Wander-Glow hinter dem Logo ---------------------------------- */

/* Vier Lichtpunkte ziehen unter der Wortmarke entlang. Die Maske
   schneidet sie auf die Logoform; weil das Logo-PNG darüber deckend weiß ist,
   sieht man vom Glow nur das, was der Blur über die Kanten hinausträgt — ein
   lila Saum, der am Logorand entlangwandert.

   Zwei Ebenen sind nötig, weil CSS `filter` VOR `mask` angewendet wird: innen
   maskieren, außen weichzeichnen. Andersherum würde der Glow an der Logokante
   hart abgeschnitten und nichts nach außen strahlen. */
.hero__aura {
    grid-area: 1 / 1;
    justify-self: center;
    align-self: center;
    position: relative;
    width: clamp(260px, 62vw, 760px);
    aspect-ratio: 2000 / 600;
    pointer-events: none;
    filter: blur(clamp(14px, 2.4vw, 30px)) saturate(1.4);
}

/* Die Einblendung sitzt auf der INNEREN Ebene, nicht auf .hero__aura: eine
   laufende CSS-Animation schlägt inline styles, und GSAP muss die Deckkraft
   der Aura beim Wegscrollen herunterfahren können. */
.hero__aura-inner {
    position: absolute;
    inset: 0;
    opacity: 0;
    -webkit-mask: url("../img/logo-white.png") center / contain no-repeat;
    mask: url("../img/logo-white.png") center / contain no-repeat;
    /* Erst einblenden, wenn die Logo-Intro durch ist. */
    animation: hero-aura-in 1.6s ease 1.5s forwards;
}

.hero__aura-inner::before,
.hero__aura-inner::after {
    content: "";
    position: absolute;
    inset: 0;
    background-repeat: no-repeat;
}

/* Je zwei Punkte pro Ebene: Beide Hintergrund-Layer teilen sich eine
   Animation (gleiche Dauer), laufen darin aber auf eigenen Bahnen. Zwei
   Ebenen mit unterschiedlicher Dauer ergeben vier Punkte, deren Muster sich
   nicht sichtbar wiederholt. */
.hero__aura-inner::before {
    background-image:
        radial-gradient(circle, #a44dff 0%, rgba(164, 77, 255, 0) 68%),
        radial-gradient(circle, #7d4dff 0%, rgba(125, 77, 255, 0) 68%);
    background-size: 46% 140%, 34% 120%;
    animation: hero-aura-a 7s ease-in-out infinite;
}

.hero__aura-inner::after {
    background-image:
        radial-gradient(circle, #e04dff 0%, rgba(224, 77, 255, 0) 68%),
        radial-gradient(circle, #c14dff 0%, rgba(193, 77, 255, 0) 68%);
    background-size: 38% 130%, 30% 115%;
    animation: hero-aura-b 9.5s ease-in-out infinite;
}

@keyframes hero-aura-in {
    to { opacity: 0.95; }
}

/* Gegenläufige Bahnen: eine Blase wandert links->rechts, die andere zurück,
   beide mit unterschiedlicher Dauer — dadurch wiederholt sich das Muster nicht
   sichtbar. */
@keyframes hero-aura-a {
    0%   { background-position: 0% 15%,   62% 90%; }
    50%  { background-position: 100% 85%, 18% 10%; }
    100% { background-position: 0% 15%,   62% 90%; }
}

@keyframes hero-aura-b {
    0%   { background-position: 100% 80%, 35% 5%; }
    50%  { background-position: 0% 20%,   85% 95%; }
    100% { background-position: 100% 80%, 35% 5%; }
}

/* Ohne Bewegung: ruhiger, stehender Glow statt Wanderung, Logo steht still. */
@media (prefers-reduced-motion: reduce) {
    [data-echo],
    .hero__aura { animation: none; }

    .hero__aura-inner {
        animation: none;
        opacity: 0.8;
    }

    .hero__aura-inner::before { animation: none; background-position: 20% 30%, 62% 90%; }
    .hero__aura-inner::after  { animation: none; background-position: 80% 70%, 35% 5%; }
}

/* Halbkreise-Klammern, die als Schallwelle nach außen laufen.
   Gleiche Canvas-Größe wie das Logo => die Bögen sitzen exakt auf den
   Logo-Klammern und wandern beim Hochskalieren nach links/rechts raus.
   Das Element im Markup ist nur Klon-Vorlage (opacity: 0) — sichtbar sind
   allein die Kopien: der einmalige Burst beim Start und die Wellen, die beim
   Runterscrollen aus dem Logo laufen. */
.hero__ring {
    grid-area: 1 / 1;
    width: clamp(260px, 62vw, 760px);
    height: auto;
    justify-self: center;
    align-self: center;
    opacity: 0;
    pointer-events: none;
    will-change: transform, opacity;
    filter: drop-shadow(0 0 14px color-mix(in srgb, var(--accent) 65%, transparent));
}

/* --- Start-Animation: Halbkreis-Ping + Glitch -------------------------- */

/* Ping am Bounce-Peak: hell und hart. */
.hero__ring--burst {
    filter: drop-shadow(0 0 18px color-mix(in srgb, var(--accent) 80%, #fff));
}

/* Scroll-Wellen: weicher und lila wie der Glow — sie gehören zum Abgang der
   Wortmarke, nicht zum Aufschlag. */
.hero__ring--scroll {
    filter: drop-shadow(0 0 22px rgba(164, 77, 255, 0.75));
}

/* Glitch am Bounce-Peak: Das Basis-Logo bleibt voll sichtbar (nur Mikro-
   Zittern), die beiden Geister-Ebenen zeigen 220 ms lang versetzte,
   rot/cyan gesäumte Streifen-Slices darüber. steps(1) hält jeden Frame
   hart und springt — kein Interpolieren, kein Blinken des Logos selbst.
   `translate`/`rotate` als eigene Properties, damit GSAPs `transform`
   (scale-Puls der Geister) nicht überschrieben wird. */
.hero__wordmark.is-glitching [data-echo] {
    animation: hero-glitch-base 0.22s steps(1) 1;
}

.hero__wordmark.is-glitching .hero__echo--ghost {
    animation: hero-glitch-a 0.22s steps(1) 1;
}

.hero__wordmark.is-glitching .hero__echo--ghost2 {
    animation: hero-glitch-b 0.22s steps(1) 1;
}

@keyframes hero-glitch-base {
    0%   { translate: 2px 0; }
    33%  { translate: -3px 1px; rotate: -0.4deg; }
    66%  { translate: 2px -1px; rotate: 0.3deg; }
    100% { translate: 0 0; rotate: 0deg; }
}

@keyframes hero-glitch-a {
    0%   { opacity: 0.85; clip-path: inset(6% 0 60% 0);  translate: -7px 0; filter: drop-shadow(-3px 0 rgba(255, 0, 84, 0.9)); }
    33%  { opacity: 0.85; clip-path: inset(36% 0 34% 0); translate: 6px 0;  filter: drop-shadow(-3px 0 rgba(255, 0, 84, 0.9)); }
    66%  { opacity: 0.85; clip-path: inset(64% 0 6% 0);  translate: -5px 0; filter: drop-shadow(-3px 0 rgba(255, 0, 84, 0.9)); }
    100% { opacity: 0.85; clip-path: inset(64% 0 6% 0);  translate: -5px 0; filter: drop-shadow(-3px 0 rgba(255, 0, 84, 0.9)); }
}

@keyframes hero-glitch-b {
    0%   { opacity: 0.85; clip-path: inset(52% 0 18% 0); translate: 7px 0;  filter: drop-shadow(3px 0 rgba(0, 216, 255, 0.9)); }
    33%  { opacity: 0.85; clip-path: inset(12% 0 58% 0); translate: -6px 0; filter: drop-shadow(3px 0 rgba(0, 216, 255, 0.9)); }
    66%  { opacity: 0.85; clip-path: inset(40% 0 28% 0); translate: 5px 0;  filter: drop-shadow(3px 0 rgba(0, 216, 255, 0.9)); }
    100% { opacity: 0.85; clip-path: inset(40% 0 28% 0); translate: 5px 0;  filter: drop-shadow(3px 0 rgba(0, 216, 255, 0.9)); }
}

.hero__sub {
    margin: 1.6rem 0 0;
    font-size: clamp(0.85rem, 2vw, 1.05rem);
    letter-spacing: 0.45em;
    text-transform: uppercase;
    color: var(--muted);
}

.hero__cta {
    display: inline-flex;
    align-items: center;
    gap: 0.7em;
    margin-top: 2.6rem;
    padding: 0.95em 2em;
    border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    font-weight: 800;
    font-size: 1.05rem;
    text-decoration: none;
    transition: background 0.25s ease, box-shadow 0.25s ease, gap 0.25s ease;
}

.hero__cta:hover {
    background: color-mix(in srgb, var(--accent) 24%, transparent);
    box-shadow: 0 0 40px color-mix(in srgb, var(--accent) 35%, transparent);
    gap: 1em;
}

.hero__cta-arrow { color: var(--accent); font-weight: 700; }

.hero__scroll {
    position: absolute;
    bottom: 2rem;
    left: 50%;
    translate: -50% 0;
    width: 2px;
    height: 56px;
    overflow: hidden;
}

.hero__scroll-line {
    display: block;
    width: 100%; height: 100%;
    background: linear-gradient(to bottom, transparent, var(--accent));
    animation: scroll-drip 1.8s ease-in-out infinite;
}

@keyframes scroll-drip {
    from { transform: translateY(-100%); }
    to { transform: translateY(100%); }
}

/* ==========================================================================
   Sektionen allgemein
   ========================================================================== */

section { padding: clamp(4rem, 10vw, 8rem) var(--pad); }

/* Handy: kompaktere vertikale Abstände zwischen den Sektionen — 64px oben und
   unten (= 128px Lücke) wirken auf dem Telefon zu weit auseinandergezogen. */
@media (max-width: 760px) {
    section { padding: 2.75rem var(--pad); }
}

/* ==========================================================================
   Panels — eine Sektion = ein Bildschirm

   Auf der Startseite ist jede Sektion (Hero, Upcoming, Archiv, Club, News,
   FAQ, Linktree) genau eine Bildschirmhöhe hoch, und EIN Wisch fährt von
   einer zur nächsten (siehe initPanelSnap in app.js). Es soll sich anfühlen
   wie durch Karten blättern, nicht wie eine lange Seite.

   Damit das aufgeht, muss der Inhalt jeder Sektion garantiert in eine
   Bildschirmhöhe passen. Deshalb wachsen Flyer, Club-Bilder und der
   Archiv-Stapel unten nicht mehr mit der BREITE, sondern mit der verfügbaren
   HÖHE (svh) — auf dem Handy ist die die knappe Größe, nicht die Breite.

   Passt eine Sektion doch mal nicht (aufgeklapptes FAQ mit Formular, viele
   News), wächst sie einfach weiter: min-height, nicht height. Der Snap merkt
   das und lässt bis zur Unterkante normal scrollen, bevor er weiterfährt.
   ========================================================================== */

.page-home [data-panel] {
    /* lvh = Höhe OHNE die iOS-Leisten, also die größtmögliche. Nur damit lugt
       in KEINEM Leistenzustand die nächste Sektion unten hervor. Dass der
       Rest dabei unter den Bildschirmrand rutscht, stört nicht: durch ihn muss
       niemand scrollen, der Snap überspringt ihn.
       vh als Fallback für Browser ohne lvh (iOS < 15.4). */
    min-height: 100vh;
    min-height: 100lvh;
}

/* Inhalt mittig im Panel. Der Hero bringt sein eigenes Grid mit. */
.page-home [data-panel]:not(.hero) {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Kopfraum für die fixierte Nav: die liegt über dem Sektionsanfang und
       würde den Titel sonst anschneiden. */
    padding-top: clamp(4.5rem, 10vh, 8rem);
    /* Kein Zuschlag für die Footer-Schublade: geschlossen ist sie unsichtbar,
       also darf der Linktree genau mittig stehen. */
    --pad-bottom: clamp(2.5rem, 6vh, 5rem);
    padding-bottom: var(--pad-bottom);
}

/* Die letzte Sektion (Linktree) rückt nach oben, sobald die Footer-Schublade
   mit dem Impressum aufgeht, und wieder zurück, wenn sie zugeht — geschoben
   wird in app.js (siehe lift()), hier steht nur die Überblendung.

   Bewegt werden die KINDER, nicht die Sektion selbst: deren Kante ist das Maß
   für den Panel-Snap, die muss stehen bleiben. Und geschoben wird über
   `translate` statt `transform`, weil auf `transform` die Einblende-Animation
   von GSAP sitzt. */
.page-home [data-panel][data-lift] > * {
    transition: translate 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
    .page-home [data-panel][data-lift] > * { transition: none; }
}

/* Handy: Das Panel misst 100lvh, sichtbar sind aber nur 100svh (Safari blendet
   Leisten ein). Das zusätzliche Boden-Padding in Höhe der Differenz schiebt
   den Inhalt in die Mitte des SICHTBAREN Bereichs — ohne säße alles zu tief.
   Auf Desktop ist lvh == svh, der Zuschlag also 0. */
@media (max-width: 760px) {
    .page-home [data-panel]:not(.hero) {
        padding-top: 4.75rem;
        --pad-bottom: calc(1.75rem + 100lvh - 100svh);
    }
}

/* --- Inhalte, die mit der Bildschirmhöhe skalieren ---------------------- */

/* Flyer im Upcoming-Slider: Breite aus der Höhe abgeleitet (3/4-Format),
   zusätzlich auf 62 % der Breite gedeckelt, damit auf sehr schmalen Geräten
   immer noch die nächste Karte anschneidet. */
.page-home [data-panel] .flyer-card {
    width: min(clamp(150px, 31svh, 380px), 62vw);
}

/* Club-Bänder: Die Bildbreite kommt aus der Bildschirmbreite — es sollen
   anderthalb Bilder nebeneinander stehen, also je Bild zwei Drittel der
   Breite abzüglich des Abstands. So ist auf dem Handy immer ein Bild ganz zu
   sehen und das nächste angeschnitten; man erkennt sofort, dass das Band
   weiterläuft.

   Der zweite Wert deckelt das auf breiten Schirmen: dort wären zwei Drittel
   der Breite riesig, und zwei Reihen passten nicht mehr auf einen Schirm.
   Gemessen wird dafür in svh (Bildschirmhöhe), denn eng ist auf dem Desktop
   die Höhe, nicht die Breite.

   Die Höhe folgt dem 3/2-Format — beschnitten wird nie, die Bilder sind immer
   ganz zu sehen. */
.page-home [data-panel] .club-shot img {
    width: min(63vw, 42svh);
    height: auto;
    aspect-ratio: 3 / 2;
}

/* Archiv-Stapel (3/4-Format, wird also 1,33x so hoch wie breit).
   Breite fest statt in Prozent: das Panel ist ein Flex-Container, darin hat
   der Link durch sein `margin: 0 auto` keine Streckbreite mehr — eine
   Prozentbreite waere dann kreisbezueglich und der Stapel schrumpfte auf
   Bildgroesse zusammen. */
.page-home [data-panel] .past-teaser__stack {
    width: min(320px, 34svh, 66vw);
    max-width: none;
}

/* News-Vorschaubilder dürfen das Panel nicht sprengen */
.page-home [data-panel] .news-card__media img { max-height: 30svh; }

/* Desktop: Presse-Karten flacher — drei Karten untereinander sprengen sonst
   die Bildschirmhöhe. Titel zweizeilig, Innenabstand aus der Höhe abgeleitet. */
@media (min-width: 641px) {
    .page-home [data-panel] .news-card__body {
        gap: 0.5rem;
        padding: clamp(0.8rem, 1.6vh, 1.4rem) clamp(1rem, 2vw, 1.5rem);
    }

    .page-home [data-panel] .news-card__title {
        -webkit-line-clamp: 2;
        font-size: clamp(1rem, 2vh, 1.4rem);
    }

    /* Die 170px Mindesthöhe des Vorschaubilds gab bisher die Kartenhöhe vor. */
    .page-home [data-panel] .news-card__media img { min-height: 0; }
}

/* Handy: Presse-Karten kompakter, damit auch zwei Reihen davon zusammen auf
   einen Schirm passen (flacheres Bild, engerer Text, Titel dreizeilig). */
@media (max-width: 640px) {
    .page-home [data-panel] .news__list { gap: 0.55rem; }

    .page-home [data-panel] .news-card__media img {
        aspect-ratio: 3 / 2;
        /* Deckel aus der Bildschirmhöhe: sonst wird die letzte, allein
           stehende Karte (breiter als eine Spalte) zu hoch und die Sektion
           passt nicht mehr auf einen Schirm. */
        max-height: 15svh;
    }

    .page-home [data-panel] .news-card__body {
        gap: 0.35rem;
        padding: 0.6rem 0.7rem 0.7rem;
    }

    .page-home [data-panel] .news-card__title { -webkit-line-clamp: 3; }
}

/* Kleine Schirme (Handy quer, ältere Geräte): Kopf- und Fußraum der Panels
   zurücknehmen, sonst bleibt für den Inhalt zu wenig übrig. */
@media (max-height: 720px) {
    .page-home [data-panel]:not(.hero) {
        padding-top: 4.25rem;
        --pad-bottom: calc(1.1rem + 100lvh - 100svh);
    }

    .page-home [data-panel] .flyer-card {
        width: min(clamp(150px, 29svh, 380px), 62vw);
    }
}

/* Bilder in den Panels: kein Langdruck-Menü, kein Markieren, kein Ziehen.
   Ein gehaltener Finger auf einem Flyer oder Club-Bild wurde vom System sonst
   als Ziehen gedeutet — die Geste gehörte dann dem Betriebssystem, und genau
   darüber ließ sich der Snap aushebeln. */
.page-home [data-panel] img,
.page-home [data-panel] .club-shot,
.page-home [data-panel] .flyer-card {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-user-drag: none;
}

/* Genre-Chips in EINER waagrecht schiebbaren Reihe statt umgebrochen: bei
   vielen Genres waren das sonst vier Zeilen (260 px) und die Sektion passte
   nicht mehr auf einen Schirm. */
.page-home [data-panel] .upcoming__filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 0.15rem;
}

.page-home [data-panel] .upcoming__filters::-webkit-scrollbar { display: none; }

.page-home [data-panel] .filter-chip { flex: 0 0 auto; }

/* Handy: FAQ und Linktree etwas enger setzen, damit alle Einträge zusammen
   auf einen Schirm gehen. */
@media (max-width: 760px) {
    .page-home [data-panel] .section-head { margin-bottom: 1.5rem; }

    .page-home [data-panel] .faq__question {
        padding: 1rem 2.5rem 1rem 0;
        font-size: 1.05rem;
    }

    .page-home [data-panel] .linktree__list { gap: 11px; }

    .page-home [data-panel] .linktree__link { padding: 15px 16px; font-size: 1rem; }
}

/* Ohne Snap (prefers-reduced-motion) bleibt die Seite eine normale, kurze
   Seite — volle Bildschirmhöhen wären dort nur unnötige Leere. */
@media (prefers-reduced-motion: reduce) {
    .page-home [data-panel] { min-height: 0; }
}

.section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
    margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.section-head__title {
    margin: 0 0 1.5rem;
    font-size: clamp(2.2rem, 6vw, 4.5rem);
    font-weight: 900;
    line-height: 0.95;
    letter-spacing: -0.01em;
    text-transform: uppercase;
}

.section-head .section-head__title { margin-bottom: 0; }

/* ==========================================================================
   Upcoming Slideshow
   ========================================================================== */

.upcoming { padding-right: 0; }

.upcoming .section-head { padding-right: var(--pad); }

.upcoming__controls { display: flex; gap: 0.6rem; }

.slider-btn {
    width: 3rem; height: 3rem;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    font-size: 1.1rem;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;
}

.slider-btn:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }

.slider-btn:disabled { opacity: 0.3; cursor: default; }

.upcoming__track {
    display: flex;
    gap: clamp(1rem, 2.5vw, 2rem);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding: 0.5rem var(--pad) 1.5rem 0;
    scrollbar-width: none;
    cursor: grab;
}

/* Während des Maus-Drags: Snap aus (sonst kämpft er gegen scrollLeft),
   nichts markieren, Karten nicht hovern */
.upcoming__track.is-dragging {
    cursor: grabbing;
    scroll-snap-type: none;
    user-select: none;
}

.upcoming__track.is-dragging .flyer-card {
    pointer-events: none;
}

.upcoming__track::-webkit-scrollbar { display: none; }

/* Handy: frei swipen statt an jeder Karte einrasten. Container auf `none`
   deaktiviert das Snappen komplett; Desktop behält den Snap, damit die
   Pfeil-Buttons sauber auf einer Karte landen. */
@media (max-width: 760px) {
    .upcoming__track { scroll-snap-type: none; }
}

.upcoming__empty { color: var(--muted); font-size: 1.1rem; }

/* --- Genre-Filter unter dem Slider ------------------------------------- */

.upcoming__filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding-right: var(--pad);
    margin-top: 0.4rem;
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1.1rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    /* Deckend, damit der Raster-Raum nicht durch die Knoepfe scheint. */
    background: var(--bg-raised);
    color: var(--muted);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1.2;
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

.filter-chip:hover {
    color: var(--text);
    border-color: var(--accent);
    background: var(--surface);
}

.filter-chip.is-active {
    color: var(--text);
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 22%, var(--bg-raised));
}

.filter-chip__count {
    font-size: 0.75rem;
    font-weight: 800;
    color: var(--muted);
}

.filter-chip.is-active .filter-chip__count { color: var(--accent); }

/* Ausgefilterte Karten müssen aus dem Flex-Fluss verschwinden — das
   hidden-Attribut allein reicht gegen `display: flex` des Tracks nicht. */
.upcoming__track .flyer-card[hidden] { display: none; }

.upcoming__nomatch {
    margin-top: 1.2rem;
    padding-right: var(--pad);
    color: var(--muted);
}

.flyer-card {
    flex: 0 0 auto;
    width: clamp(240px, 32vw, 380px);
    scroll-snap-align: start;
    text-decoration: none;
}

.flyer-card__img-wrap {
    position: relative;
    aspect-ratio: 3 / 4;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
    transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
}

.flyer-card:hover .flyer-card__img-wrap {
    transform: translateY(-8px) rotate(-1deg);
    box-shadow: 0 24px 60px -12px color-mix(in srgb, var(--accent) 55%, transparent);
}

.flyer-card__img { width: 100%; height: 100%; object-fit: cover; }

.flyer-card__meta {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.9rem 0.25rem 0;
}

.flyer-card__date {
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
}

.flyer-card__title { font-weight: 700; font-size: 1.05rem; }

/* ==========================================================================
   Der Club — laufende Bilderbaender

   Zwei Baender laufen gegenlaeufig als Endlosschleife. Jedes Band enthaelt
   seine Bilder doppelt; die Animation verschiebt es um genau die Haelfte,
   dann beginnt sie wieder bei null - dadurch ist der Uebergang unsichtbar.
   ========================================================================== */

/* Die Baender laufen ueber die volle Breite - der Innenabstand der Sektion
   wuerde sie sonst an beiden Seiten hart abschneiden. Nur die Ueberschrift
   behaelt ihn. */
.club { padding-left: 0; padding-right: 0; }

.club > .section-head {
    padding-inline: var(--pad);
    /* Enger als in den uebrigen Sektionen: der gewonnene Platz geht direkt in
       die Bildgroesse der Baender. */
    margin-bottom: clamp(1.6rem, 3.5vw, 2.6rem);
}

.club-marquee {
    display: flex;
    flex-direction: column;
    gap: clamp(0.8rem, 2vw, 1.4rem);
    /* Kein eigener Abstand nach oben: den Abstand zur Ueberschrift setzt
       `.club > .section-head` (margin-bottom). Zwei Abstaende uebereinander
       waren rund 100 px, die den Bildern fehlten. */
    margin-top: 0;
}

.club-marquee__row {
    overflow: hidden;
    /* An beiden Raendern weich auslaufen: dann wirkt es, als liefe das Band
       jenseits des Bildschirms weiter, statt an einer Kante zu enden. */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}

.club-marquee__track {
    display: flex;
    gap: clamp(0.8rem, 2vw, 1.4rem);
    width: max-content;
    animation: club-scroll 70s linear infinite;
}

.club-marquee__row--right .club-marquee__track {
    animation-direction: reverse;
    animation-duration: 85s;
    /* Negativer Verzug: das zweite Band startet mitten im Durchlauf, damit
       nicht beide gleichzeitig buendig am Rand beginnen. */
    animation-delay: -30s;
}

/* Die Baender laufen auch unter dem Zeiger weiter — angehalten wird nur,
   solange jemand wirklich wischt (siehe initClubMarquee in app.js). */

@keyframes club-scroll {
    from { transform: translate3d(0, 0, 0); }
    /* Halbe Strecke: das Band enthaelt alles zweimal. Die halbe Luecke gleicht
       den Abstand hinter dem letzten Bild aus. */
    to { transform: translate3d(calc(-50% - clamp(0.4rem, 1vw, 0.7rem)), 0, 0); }
}

.club-shot {
    flex: 0 0 auto;
    display: block;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
    cursor: zoom-in;
    line-height: 0;
    transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
}

.club-shot img {
    width: clamp(220px, 30vw, 420px);
    aspect-ratio: 3 / 2;
    object-fit: cover;
    opacity: 0.85;
    transition: opacity 0.35s ease;
}

.club-shot:hover { transform: translateY(-6px); box-shadow: 0 22px 50px -18px rgba(0,0,0,0.9); }
.club-shot:hover img { opacity: 1; }

.club-shot:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Wischbare Baender: sobald app.js die Fahrt uebernimmt (initClubMarquee),
   wird aus der Reihe ein waagrechter Scroller. Die Fahrt selbst laeuft dann
   ueber scrollLeft statt ueber die Keyframes — damit greift jeder Wisch und
   jedes Ziehen mit der Maus direkt in das laufende Band. */
.club-marquee__row.is-swipe {
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    overscroll-behavior-x: contain;
    cursor: grab;
    /* Der senkrechte Wisch gehoert weiter dem Panel-Snap. */
    touch-action: pan-x;
    scroll-behavior: auto;
}

.club-marquee__row.is-swipe::-webkit-scrollbar { display: none; }

.club-marquee__row.is-swipe .club-marquee__track { animation: none; }

.club-marquee__row.is-dragging { cursor: grabbing; }

/* Waehrend des Ziehens kein Aufstellen des Bildes unter dem Zeiger. */
.club-marquee__row.is-dragging .club-shot:hover {
    transform: none;
    box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
    /* Ohne Fahrt: die Baender werden zu normal scrollbaren Reihen. */
    .club-marquee__track { animation: none; }
    .club-marquee__row { overflow-x: auto; }
}

/* ==========================================================================
   Vollbild-Ansicht (Lightbox)
   ========================================================================== */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    padding: clamp(1rem, 4vw, 3rem);
}

.lightbox[hidden] { display: none; }

.lightbox__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(4, 4, 8, 0.94);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.lightbox__figure {
    position: relative;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    align-items: center;
    max-width: min(1200px, 92vw);
}

.lightbox__img {
    max-width: 100%;
    max-height: 76vh;
    border-radius: var(--radius);
    object-fit: contain;
}

.lightbox__caption {
    display: flex;
    gap: 1rem;
    align-items: baseline;
    color: var(--muted);
    font-size: 0.9rem;
    text-align: center;
}

.lightbox__count { font-weight: 700; letter-spacing: 0.08em; white-space: nowrap; }

.lightbox__btn {
    position: absolute;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: rgba(10, 10, 16, 0.8);
    color: var(--text);
    font-size: 1.2rem;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.lightbox__btn:hover { border-color: var(--accent); background: rgba(20, 20, 30, 0.95); }

.lightbox__btn--prev { left: clamp(0.5rem, 2vw, 2rem); top: 50%; transform: translateY(-50%); }
.lightbox__btn--next { right: clamp(0.5rem, 2vw, 2rem); top: 50%; transform: translateY(-50%); }
.lightbox__btn--close { top: clamp(0.5rem, 2vw, 2rem); right: clamp(0.5rem, 2vw, 2rem); }

@media (max-width: 640px) {
    .lightbox__btn--prev { left: 0.5rem; }
    .lightbox__btn--next { right: 0.5rem; }
}

/* ==========================================================================
   Past-Teaser (Stapelblatt)
   ========================================================================== */

/* Titel und Stapel, sonst nichts — der ganze Block ist der Link ins Archiv. */
.past-teaser__link {
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    grid-template-areas: "stack title";
    align-items: center;
    column-gap: clamp(2rem, 6vw, 5rem);
    text-decoration: none;
    max-width: 1100px;
    margin: 0 auto;
}

.past-teaser__title { grid-area: title; margin: 0; }

.past-teaser__stack {
    grid-area: stack;
    align-self: center;
    position: relative;
    aspect-ratio: 3 / 4;
    max-width: 340px;
    width: 100%;
    justify-self: center;
}

.past-teaser__sheet {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: var(--radius);
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.past-teaser__sheet:nth-child(1) { transform: rotate(-7deg) translate(-6%, 3%); filter: brightness(0.55); }
.past-teaser__sheet:nth-child(2) { transform: rotate(4deg) translate(5%, -1%); filter: brightness(0.75); }
.past-teaser__sheet:nth-child(3) { transform: rotate(-1.5deg); }

.past-teaser__link:hover .past-teaser__sheet:nth-child(1) { transform: rotate(-11deg) translate(-11%, 5%); }
.past-teaser__link:hover .past-teaser__sheet:nth-child(2) { transform: rotate(8deg) translate(10%, -3%); }
.past-teaser__link:hover .past-teaser__sheet:nth-child(3) { transform: rotate(0deg) translateY(-3%); }

.past-teaser__text p { color: var(--muted); font-size: 1.1rem; margin: 0 0 1.8rem; }

@media (max-width: 760px) {
    /* Titel ÜBER der Stapelvorschau, mit klarem Abstand (~1 cm) statt
       direkt auf den Flyern zu kleben. */
    .past-teaser__link {
        grid-template-columns: 1fr;
        grid-template-areas:
            "title"
            "stack";
        row-gap: 2.5rem;
        justify-items: center;
        text-align: center;
    }
    .past-teaser__stack { max-width: 240px; }
}

/* ==========================================================================
   Entry-Infos
   ========================================================================== */

.entry__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 1.2rem;
    margin: 0;
}

.entry__item {
    padding: 1.8rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg-raised);
    transition: border-color 0.25s ease, transform 0.25s ease;
}

.entry__item:hover { border-color: var(--accent); transform: translateY(-4px); }

.entry__item dt {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--accent);
    margin-bottom: 0.6rem;
}

.entry__item dd {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1.1;
}

.entry__hint {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.9rem;
    font-weight: 400;
    color: var(--muted);
    line-height: 1.5;
}

/* ==========================================================================
   Vermietung
   ========================================================================== */

.rental { max-width: 900px; margin: 0 auto; }

.rental__intro { color: var(--muted); font-size: 1.1rem; max-width: 34em; }

.rental__success {
    margin: 1.2rem 0;
    padding: 1rem 1.4rem;
    border-radius: var(--radius);
    border: 1px solid color-mix(in srgb, #22c55e 60%, transparent);
    background: color-mix(in srgb, #22c55e 12%, transparent);
    font-weight: 600;
}

.rental__toggle { margin: 0.8rem 0 0; }

.rental__form { margin-top: 2rem; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.2rem;
    margin-bottom: 1.6rem;
}

@media (max-width: 640px) {
    .form-grid { grid-template-columns: 1fr; }
}

.field { display: flex; flex-direction: column; gap: 0.4rem; }

.field--full { grid-column: 1 / -1; }

.field__label {
    font-size: 0.82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--muted);
}

.field input,
.field select,
.field textarea {
    font: inherit;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 0.85em 1em;
    transition: border-color 0.2s ease;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

.field textarea { resize: vertical; }

/* Kästchen-Felder aus dem Formular-Builder */
.field--check .field__check {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    cursor: pointer;
}

.field--check input {
    width: 1.15em;
    height: 1.15em;
    accent-color: var(--accent);
    flex: none;
}

.field__error { color: #f87171; font-size: 0.85rem; }

/* ==========================================================================
   FAQ
   ========================================================================== */

.faq { max-width: 900px; margin: 0 auto; }

.faq__item {
    border-bottom: 1px solid var(--line);
}

.faq__question {
    padding: 1.3rem 2.5rem 1.3rem 0;
    font-size: 1.15rem;
    font-weight: 700;
    cursor: pointer;
    list-style: none;
    position: relative;
}

.faq__question::-webkit-details-marker { display: none; }

.faq__question::after {
    content: '+';
    position: absolute;
    right: 0.5rem;
    top: 50%;
    translate: 0 -50%;
    font-size: 1.6rem;
    font-weight: 300;
    color: var(--accent);
    transition: rotate 0.25s ease;
}

.faq__item[open] .faq__question::after,
.faq__item.is-open .faq__question::after { rotate: 45deg; }

/* Aufklappen mit Fahrt: <details> selbst laesst sich nicht animieren, deshalb
   liegt der Inhalt in einem Wrapper, dessen Zeilenhoehe von 0fr auf 1fr faehrt
   (derselbe Kniff wie beim Kontakt-Akkordeon weiter unten). Das `open`-Attribut
   setzt und entfernt app.js (initFaqAccordion) passend zur Fahrt — nur so ist
   der Inhalt beim Zufahren ueberhaupt noch sichtbar.

   Ohne JS bleibt `[open]` allein massgeblich: dann steht der Rumpf sofort da. */
.faq__body {
    display: grid;
    grid-template-rows: 1fr;
}

.faq__body-inner {
    overflow: hidden;
    min-height: 0;
}

/* Erst wenn JS die Steuerung uebernommen hat, wird zugefahren. */
.faq__list.is-animated .faq__body {
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq__list.is-animated .faq__body-inner {
    opacity: 0;
    translate: 0 -6px;
    transition: opacity 0.28s ease, translate 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq__list.is-animated .faq__item.is-open .faq__body { grid-template-rows: 1fr; }

/* Beim Zufahren bleibt `open` bis zum Ende stehen — das Plus dreht sich aber
   sofort zurueck. */
.faq__list.is-animated .faq__item[open]:not(.is-open) .faq__question::after { rotate: 0deg; }

.faq__list.is-animated .faq__item.is-open .faq__body-inner {
    opacity: 1;
    translate: 0 0;
    transition-delay: 0.06s;
}

@media (prefers-reduced-motion: reduce) {
    .faq__list.is-animated .faq__body,
    .faq__list.is-animated .faq__body-inner { transition: none; }
}

.faq__answer { margin: 0 0 1.4rem; color: var(--muted); max-width: 60ch; }

/* ==========================================================================
   Event-Detailseite
   ========================================================================== */

.page-event main { padding-top: clamp(5rem, 12vh, 8rem); }

.event__hero {
    display: grid;
    grid-template-columns: minmax(280px, 420px) 1fr;
    gap: clamp(2rem, 6vw, 5rem);
    padding: 0 var(--pad);
    max-width: 1250px;
    margin: 0 auto;
}

@media (max-width: 820px) {
    .event__hero { grid-template-columns: 1fr; }
    .event__flyer-wrap { max-width: 380px; }
}

.event__flyer-wrap { position: relative; }

.event__flyer {
    border-radius: var(--radius);
    box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.8);
}

.event__flyer-glow {
    position: absolute;
    inset: -12%;
    z-index: -1;
    background: radial-gradient(ellipse at center, color-mix(in srgb, var(--accent) 30%, transparent), transparent 70%);
    filter: blur(30px);
}

.event__date {
    display: flex;
    align-items: center;
    gap: 0.8em;
    margin: 0 0 0.6rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-size: 0.95rem;
    color: var(--accent);
}

.event__past-badge {
    padding: 0.2em 0.8em;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--line);
    color: var(--muted);
    font-size: 0.75rem;
}

.event__title {
    margin: 0 0 1.2rem;
    font-size: clamp(2.6rem, 8vw, 5.5rem);
    font-weight: 900;
    line-height: 0.95;
    text-transform: uppercase;
}

.event__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0;
    margin: 0 0 1.8rem;
    list-style: none;
}

.event__tags li {
    padding: 0.35em 1em;
    border: 1px solid color-mix(in srgb, var(--accent) 50%, transparent);
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--accent);
}

.event__section-label {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--muted);
    margin: 0 0 0.5rem;
}

.event__lineup { margin-bottom: 1.8rem; }

.event__lineup ul { list-style: none; margin: 0; padding: 0; }

.event__lineup li {
    font-size: 1.4rem;
    font-weight: 800;
    line-height: 1.35;
}

.event__description { color: var(--muted); max-width: 50ch; margin: 0 0 1.8rem; }

.event__entry {
    display: flex;
    flex-wrap: wrap;
    gap: 1.8rem 2.5rem;
    margin: 0 0 2.2rem;
    padding: 1.4rem 0;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}

.event__entry dt {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--muted);
}

.event__entry dd { margin: 0.15rem 0 0; font-weight: 700; }

.event__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-items: center;
}

.share { display: flex; flex-wrap: wrap; gap: 0.7rem; }

.event__back { padding: 3rem var(--pad) 5rem; max-width: 1250px; margin: 0 auto; }

/* ==========================================================================
   Recap (Galerie + Aftermovie)
   ========================================================================== */

.recap { max-width: 1250px; margin: 0 auto; }

.recap__movie {
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
    margin-bottom: 2rem;
}

.recap__movie iframe { width: 100%; height: 100%; border: 0; }

.recap__movie-facade {
    width: 100%; height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    background:
        radial-gradient(ellipse at center, color-mix(in srgb, var(--accent) 22%, transparent), transparent 75%),
        var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    cursor: pointer;
}

.recap__movie-play {
    display: grid;
    place-items: center;
    width: 4.5rem; height: 4.5rem;
    border-radius: 50%;
    background: var(--accent);
    font-size: 1.4rem;
    color: #fff;
    padding-left: 0.3rem;
    transition: transform 0.25s ease;
}

.recap__movie-facade:hover .recap__movie-play { transform: scale(1.12); }

.recap__movie-label { font-weight: 700; }

.recap__movie-hint { font-size: 0.82rem; color: var(--muted); }

.recap__gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
}

.recap__photo {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius);
}

/* ==========================================================================
   Archiv
   ========================================================================== */

.page-archive main { padding-top: clamp(5rem, 12vh, 8rem); }

.archive__head { margin-bottom: clamp(1.5rem, 4vw, 2.5rem); }

/* Auf dem Handy muss der Kopf klein bleiben, sonst passen keine vier
   Regale mehr in den ersten Screen. */
@media (max-width: 760px) {
    .page-archive main { padding-top: 4.5rem; }
    .archive__head { margin-bottom: 1rem; }
    .archive__head .section-head__title { font-size: 1.9rem; }
}

.archive__empty { color: var(--muted); font-size: 1.1rem; }

/* --- Regale: pro Thema eine horizontal swipebare Reihe (Netflix-Prinzip) --- */

.archive .shelf { padding: 0; margin-bottom: clamp(1rem, 3vw, 2.6rem); }

.shelf__title {
    margin: 0 0 0.45rem;
    font-size: clamp(0.85rem, 2.4vw, 1.25rem);
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.shelf__track {
    display: flex;
    gap: clamp(0.6rem, 1.6vw, 1.1rem);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* Rechts über den Seitenrand hinaus laufen lassen: die angeschnittene
       Karte am Rand signalisiert "hier geht's weiter". */
    padding: 0 var(--pad) 0.4rem 0;
    margin-right: calc(var(--pad) * -1);
    scrollbar-width: none;
    cursor: grab;
}

.shelf__track::-webkit-scrollbar { display: none; }

.shelf__track.is-dragging {
    cursor: grabbing;
    scroll-snap-type: none;
    user-select: none;
}

.shelf__track.is-dragging .shelf-card { pointer-events: none; }

.shelf-card {
    position: relative;
    flex: 0 0 auto;
    width: clamp(96px, 26vw, 200px);
    aspect-ratio: 3 / 4;
    scroll-snap-align: start;
    text-decoration: none;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
}

.shelf-card__img {
    width: 100%; height: 100%;
    object-fit: cover;
    filter: saturate(0.4) brightness(0.7);
    transition: filter 0.35s ease, transform 0.35s ease;
}

.shelf-card:hover .shelf-card__img,
.shelf-card:focus-visible .shelf-card__img {
    filter: saturate(1) brightness(0.95);
    transform: scale(1.06);
}

.shelf-card__meta {
    position: absolute;
    inset: auto 0 0 0;
    padding: 2rem 0.7rem 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.92), transparent);
}

.shelf-card__date {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--accent);
}

.shelf-card__title {
    font-size: 0.82rem;
    font-weight: 800;
    line-height: 1.2;
    /* Lange Titel dürfen die Karte nicht sprengen */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Badges als Icon-Pillen oben rechts — kosten keine Zeilenhöhe */
.shelf-card__badges {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    display: flex;
    gap: 0.25rem;
}

.shelf-card__badges span {
    display: inline-flex;
    padding: 0.28em;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(4px);
    color: var(--text);
}

.shelf-card__badges svg { width: 0.85rem; height: 0.85rem; display: block; }

@media (min-width: 761px) {
    .shelf-card__date { font-size: 0.78rem; }
    .shelf-card__title { font-size: 1rem; }
    .shelf-card__meta { padding: 2.4rem 1rem 0.9rem; }
    .shelf-card__badges svg { width: 1rem; height: 1rem; }
}

/* ==========================================================================
   Legal
   ========================================================================== */

.page-legal main { padding-top: clamp(5rem, 12vh, 8rem); }

.legal { max-width: 760px; margin: 0 auto; }

.legal__body { color: var(--muted); }

.legal__body h2 { color: var(--text); margin-top: 2.2rem; }

.legal__todo {
    padding: 0.9rem 1.2rem;
    border-left: 3px solid var(--accent);
    background: var(--bg-raised);
    border-radius: 0 10px 10px 0;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
    border-top: 1px solid var(--line);
    padding: 3rem var(--pad) max(2rem, env(safe-area-inset-bottom));
}

.site-footer__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
}

.site-footer__wordmark {
    font-size: 2rem;
    font-weight: 900;
    letter-spacing: 0.15em;
}

.site-footer__brand p { color: var(--muted); font-size: 0.9rem; margin: 0.4rem 0 0; }

.site-footer__social,
.site-footer__legal {
    display: flex;
    gap: 1.4rem;
}

.site-footer__social a,
.site-footer__legal a {
    color: var(--muted);
    text-decoration: none;
    font-size: 0.92rem;
    transition: color 0.2s ease;
}

.site-footer__social a:hover,
.site-footer__legal a:hover { color: var(--accent); }

/* --- Startseite: der Footer ist eine Schublade --------------------------

   Am Linktree (letzte Sektion) blendet der naechste Wisch das Impressum von
   unten ein — die Sektion selbst bleibt stehen. Damit liegt unter den Panels
   kein frei scrollbarer Rest mehr, aus dem man aus dem Snap herausfallen
   koennte; ein Wisch nach oben blendet es wieder aus. Auf- und zugemacht wird
   sie in app.js (initPanelSnap).

   Geschlossen ist sie KOMPLETT weg — kein grauer Streifen, kein Text.

   WICHTIG — warum die Schublade NICHT `position: fixed` ist:
   Safari auf dem iPhone setzt fixierte Elemente beim ersten Seitenaufbau gegen
   einen anderen Viewport, als am Ende sichtbar ist (die Leisten sind noch nicht
   eingerechnet). Der Footer sass dadurch mal 90 px zu hoch und lugte unten
   hervor, bis das erste Scrollen Safari zum Neurechnen zwang.

   Deshalb haengt die Schublade ABSOLUT am unteren Ende des Dokuments (dafuer
   das `position: relative` am body weiter unten). Das Dokument endet mit der
   letzten Sektion, also sitzt sie genau an deren Unterkante — im selben
   Koordinatensystem wie die Panels. Da gibt es nichts, was Safari falsch
   verorten koennte.

   Der Zuschlag `100lvh - 100svh` im Boden-Abstand ist die Hoehe der
   iOS-Leisten: der Text sitzt damit ueber der Leiste und der graue Grund
   reicht trotzdem bis zur echten Unterkante. Auf Desktop ist er 0.
   -------------------------------------------------------------------- */
.page-home .site-footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    /* Deckend: die Schublade legt sich UEBER den Linktree. */
    background: var(--bg-raised);
    box-shadow: 0 -24px 60px rgba(0, 0, 0, 0.6);
    padding:
        1.6rem
        var(--pad)
        calc(max(1.4rem, env(safe-area-inset-bottom)) + 100lvh - 100svh);

    /* Zu: unsichtbar und unantastbar. Nicht bloss verschoben — wo Safari das
       Element parkt, spielt damit keine Rolle. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* Der Kasten selbst wird NICHT verschoben: eine Verschiebung zaehlt zur
       scrollbaren Flaeche und man koennte die 24 px hinter der letzten Sektion
       herunterscrollen — also genau wieder aus dem Snap ausbrechen. Bewegt
       wird der Inhalt, der Kasten schneidet ihn ab. */
    overflow: hidden;
    /* visibility erst NACH dem Ausblenden umschalten, sonst verschwindet die
       Schublade schlagartig statt weich. */
    transition:
        opacity 0.3s ease,
        visibility 0s linear 0.4s;
}

.page-home .site-footer.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    /* Beim Aufgehen sofort sichtbar schalten, dann einblenden. */
    transition:
        opacity 0.3s ease,
        visibility 0s;
}

/* Der Inhalt kommt von unten herein. */
.page-home .site-footer__inner {
    transform: translateY(24px);
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.page-home .site-footer.is-open .site-footer__inner { transform: none; }

/* Bezugsrahmen der Schublade: ohne das haengt sie am ersten Bildschirm statt
   am Ende des Dokuments (der Standardbezug ist viewportgross, nicht
   dokumentgross). */
body.page-home { position: relative; }

.page-home .site-footer__inner { gap: 1.1rem; }

.page-home .site-footer__wordmark { font-size: 1.5rem; }

/* Kurze Schirme: die aufgegangene Schublade schob sich sonst über die
   Unterkante des Kontakt-Buttons. Enger gesetzt bleibt der Linktree frei. */
@media (max-height: 700px) {
    .page-home .site-footer.is-open {
        padding: 1.1rem var(--pad) max(1rem, env(safe-area-inset-bottom));
    }

    .page-home .site-footer__inner { gap: 0.7rem; }

    .page-home .site-footer__wordmark { font-size: 1.25rem; }
}

/* Ohne JS und ohne Bewegung bleibt der Footer, wo er immer war — sonst wäre
   er nicht erreichbar (dann gibt es auch keine Panels, siehe oben). */
html.no-js .site-footer,
.page-home .site-footer[data-static],
.page-home .site-footer[data-static].is-open {
    position: static;
    padding: 1.6rem var(--pad) max(1.4rem, env(safe-area-inset-bottom));
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    overflow: visible;
    box-shadow: none;
    transition: none;
}

html.no-js .site-footer__inner,
.page-home .site-footer[data-static] .site-footer__inner {
    transform: none;
    transition: none;
}

@media (prefers-reduced-motion: reduce) {
    .page-home .site-footer {
        position: static;
        padding: 1.6rem var(--pad) max(1.4rem, env(safe-area-inset-bottom));
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        overflow: visible;
        box-shadow: none;
        transition: none;
    }

    .page-home .site-footer__inner {
        transform: none;
        transition: none;
    }
}

/* ==========================================================================
   Consent-Banner
   ========================================================================== */

.consent {
    position: fixed;
    z-index: 100;
    inset: auto 1rem max(1rem, env(safe-area-inset-bottom)) 1rem;
    display: flex;
    justify-content: center;
    pointer-events: none;
}

.consent__box {
    pointer-events: auto;
    max-width: 460px;
    padding: 1.4rem 1.6rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: rgba(16, 16, 24, 0.95);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}

.consent__title { margin: 0 0 0.4rem; font-weight: 800; }

.consent__text { margin: 0 0 1rem; font-size: 0.9rem; color: var(--muted); }

.consent__text a { color: var(--text); }

.consent__actions { display: flex; gap: 0.6rem; justify-content: flex-end; }

/* ==========================================================================
   News / Presse (über dem FAQ) — externe Beiträge, z. B. vol.at
   ========================================================================== */

.news { max-width: 960px; margin: 0 auto; }

.news__kicker {
    margin: 0;
    color: var(--muted);
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.news__list {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

/* Presse-Karte: Vorschaubild links, Quelle und Titel rechts. Bild, Titel und
   Favicon holt LinkPreview automatisch von der verlinkten Seite. */
.news-card {
    display: grid;
    grid-template-columns: minmax(0, 34%) 1fr;
    align-items: stretch;
    gap: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    text-decoration: none;
    overflow: hidden;
    transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

/* Ohne Vorschaubild bleibt nur die Textspalte. */
.news-card--flat { grid-template-columns: 1fr; }

.news-card:hover,
.news-card:focus-visible {
    border-color: var(--accent);
    transform: translateY(-3px);
    box-shadow: 0 18px 44px color-mix(in srgb, var(--accent) 22%, transparent);
}

.news-card__media {
    position: relative;
    overflow: hidden;
    background: var(--bg-raised);
    min-height: 100%;
}

.news-card__media img {
    width: 100%;
    height: 100%;
    min-height: 170px;
    object-fit: cover;
    transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
    opacity: 0.9;
}

.news-card:hover .news-card__media img { transform: scale(1.05); opacity: 1; }

.news-card__body {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    padding: clamp(1.1rem, 2.5vw, 1.7rem);
}

.news-card__source {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.news-card__favicon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--line);
    overflow: hidden;
    flex-shrink: 0;
}

.news-card__favicon img {
    width: 18px;
    height: 18px;
    object-fit: contain;
    border-radius: 3px;
}

.news-card__favicon svg { width: 16px; height: 16px; color: var(--muted); }

.news-card__host {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
}

.news-card__title {
    font-weight: 700;
    font-size: clamp(1.1rem, 2.4vw, 1.45rem);
    line-height: 1.25;
    /* Lange Titel hoechstens dreizeilig */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.news-card__more {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    margin-top: auto;
    padding-top: 0.3rem;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--accent);
}

.news-card__arrow { transition: transform 0.3s ease; }

.news-card:hover .news-card__arrow { transform: translateX(4px); }

/* Handy: zwei kompakte Karten nebeneinander, Bild ueber dem Text. */
@media (max-width: 640px) {
    .news__list {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.7rem;
    }

    .news-card { grid-template-columns: 1fr; }

    /* Ungerade Anzahl: die letzte Karte steht allein — mittig und etwas
       breiter als eine Spalte, aber nicht ueber die volle Breite. */
    .news__list > .news-card:last-child:nth-child(odd) {
        grid-column: 1 / -1;
        width: min(68%, 260px);
        justify-self: center;
    }

    .news-card__media img { min-height: 0; aspect-ratio: 4 / 3; }

    .news-card__body {
        gap: 0.45rem;
        padding: 0.75rem 0.8rem 0.9rem;
    }

    .news-card__source { gap: 0.4rem; }

    .news-card__favicon { width: 22px; height: 22px; border-radius: 7px; }

    .news-card__favicon img { width: 14px; height: 14px; }

    .news-card__favicon svg { width: 13px; height: 13px; }

    .news-card__host {
        font-size: 0.62rem;
        letter-spacing: 0.06em;
        /* Lange Hosts sonst zweizeilig */
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .news-card__title {
        font-size: 0.92rem;
        line-height: 1.3;
        -webkit-line-clamp: 4;
    }

    .news-card__more {
        padding-top: 0.1rem;
        font-size: 0.72rem;
    }
}

/* ==========================================================================
   Linktree (unter dem FAQ)
   ========================================================================== */

/* Ohne Foto-Panel steht der Titel sonst weit links neben der zentrierten
   Liste — Sektion auf Listenbreite begrenzen, dann sitzt beides bündig. */
.linktree {
    --linktree-contact: #ff0055;
    max-width: 560px;
    margin: 0 auto;
}

.linktree__layout { display: flex; justify-content: center; }

.linktree__list {
    display: flex;
    flex-direction: column;
    gap: 15px;
    width: 100%;
    max-width: 560px;
}

/* WICHTIG: Transitions explizit auflisten. Ein pauschales `transition: 0.3s`
   greift auch auf transform/opacity und kämpft dann mit den Inline-Styles,
   die GSAP pro Frame setzt — das war das Zittern beim Reinscrollen. */
.linktree__link {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 20px;
    background: rgba(255, 255, 255, 0.05);
    border-left: 4px solid var(--accent);
    color: var(--text);
    text-decoration: none;
    font-size: 1.2rem;
    text-transform: uppercase;
    font-weight: 700;
    transition: background 0.3s ease, color 0.3s ease, border-left-color 0.3s ease, transform 0.3s ease;
}

.linktree__link:hover { background: var(--accent); color: #fff; transform: translateX(10px); }

.linktree__icon {
    display: inline-flex;
    justify-content: center;
    width: 26px;
    transition: transform 0.3s ease;
}

.linktree__icon svg { width: 1.35em; height: 1.35em; }

.linktree__link:hover .linktree__icon { transform: scale(1.2) rotate(-6deg); }

.linktree__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Plattform-Farben beim Hover */
.linktree__link--youtube:hover { background: #ff0000; border-left-color: #ff0000; }
.linktree__link--tiktok:hover { background: #ff0050; border-left-color: #ff0050; }
.linktree__link--instagram:hover {
    background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888);
    border-left-color: #dc2743;
}

/* --- Kontakt-Akkordeon --- */
.linktree__contact { display: flex; flex-direction: column; }

.linktree__link--contact {
    width: 100%;
    justify-content: space-between;
    box-sizing: border-box;
    border: 0;
    border-left: 4px solid var(--linktree-contact);
    cursor: pointer;
    font-family: inherit;
    font-size: inherit;
    text-align: left;
}

.linktree__contact-label { display: flex; align-items: center; gap: 14px; }

.linktree__link--contact:hover { background: var(--linktree-contact); }

.linktree__chevron {
    display: inline-flex;
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.linktree__chevron svg { width: 1rem; height: 1rem; }

.linktree__link--contact.open .linktree__chevron { transform: rotate(180deg); }

/* Smoothes Aufklappen via grid-template-rows 0fr → 1fr */
.linktree__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.linktree__panel.open { grid-template-rows: 1fr; }

.linktree__panel-inner {
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.linktree__row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 6px 0 0;
    color: color-mix(in srgb, var(--text) 85%, transparent);
    text-decoration: none;
    font-size: 1rem;
    padding: 12px 16px;
    background: var(--surface);
    border-left: 4px solid color-mix(in srgb, var(--linktree-contact) 40%, transparent);
    transition: background 0.3s ease, color 0.3s ease, transform 0.3s ease;
}

.linktree__row .linktree__icon { width: 20px; color: var(--linktree-contact); }

.linktree__row .linktree__icon svg { width: 1.1em; height: 1.1em; }

a.linktree__row:hover {
    background: color-mix(in srgb, var(--linktree-contact) 15%, transparent);
    color: var(--text);
    transform: translateX(6px);
}

@media (max-width: 900px) {
    .linktree__link { padding: 14px 16px; font-size: 1.05rem; }
    .linktree__row { font-size: 0.9rem; padding: 10px 14px; }
}

/* ==========================================================================
   Motion-Hygiene
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==========================================================================
   Wartungsmodus

   .maintenance-bar: Erinnerung für Admins, die die Seite trotz Wartung sehen.
   .maintenance:     die Seite, die alle anderen Besucher stattdessen bekommen.
   ========================================================================== */

.maintenance-bar {
    position: fixed;
    z-index: 101;
    left: 50%;
    bottom: max(1rem, env(safe-area-inset-bottom));
    transform: translateX(-50%);
    width: max-content;
    max-width: calc(100% - 2rem);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem 1rem;
    padding: 0.6rem 1.1rem;
    border: 1px solid rgba(245, 158, 11, 0.5);
    border-radius: 999px;
    background: rgba(28, 20, 6, 0.92);
    backdrop-filter: blur(8px);
    color: #fcd34d;
    font-size: 0.85rem;
    line-height: 1.35;
    text-align: center;
}

.maintenance-bar a {
    color: inherit;
    font-weight: 700;
    white-space: nowrap;
}

.maintenance {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    padding: 2rem var(--pad);
    text-align: center;
    background: radial-gradient(ellipse at 50% 40%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 60%);
}

.maintenance__logo {
    height: clamp(4rem, 12vw, 6rem);
    width: auto;
}

.maintenance__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(2rem, 7vw, 3.5rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.05;
}

.maintenance__text {
    max-width: 34rem;
    margin: 0;
    color: var(--muted);
    font-size: 1.05rem;
}

.maintenance__link { margin-top: 0.5rem; }
