/*
 * angebote.css — COD-Embed Stufe B
 *
 * Enthaelt alle .angebot-*, .angebote-* Styles fuer das Angebote-Widget.
 * Basis: cod_angebote_card_css() + cod_angebote_widget_theme_overrides_css()
 * aus includes/angebote/cod-angebote-directory.php (Stand 2026-06).
 *
 * Die --cod-* Tokens kommen aus embed-design.css (wird vorher geladen)
 * bzw. aus dem Live-Tokens-Endpunkt. Keine hartcodierten Hex-Farben
 * ausserhalb der Fallback-Werte in var().
 *
 * Umscopung: Layout-Wrapper (.angebote-embed-wrap, .angebote-grid) sind im
 * generierten HTML vorhanden. Karten-Selektoren (.angebot-card) brauchen
 * kein zusaetzliches Scoping, weil die Klassen eindeutig genug sind.
 */

/* ── Wrapper ─────────────────────────────────────────────────────────────── */

.angebote-embed-wrap {
    margin-top: 24px;
}

/* Linke/rechte Kante mit dem Partner-Karussell ausrichten ("Flucht"): dessen Karte
   sitzt um den Buehnen-Innenabstand (stagePadding) eingerueckt — Desktop 24 / Tablet
   18 / Mobil 10px. Dieselbe Einrueckung bekommt das Angebote-Grid, damit Partner- und
   Angebote-Karten dieselbe linke Kante haben. */
.cod-embed-angebote-wrap {
    padding-left: 10px;
    padding-right: 10px;
}
@media (min-width: 768px) {
    .cod-embed-angebote-wrap { padding-left: 18px; padding-right: 18px; }
}
@media (min-width: 1025px) {
    .cod-embed-angebote-wrap { padding-left: 24px; padding-right: 24px; }
}

/* ── Grid ────────────────────────────────────────────────────────────────── */
/*
 * Kartenbreite spiegelt die Partner-Karussell-Konfiguration (Owl Carousel):
 *
 *   Breakpoint   items  margin  stagePadding   -> Karte nimmt 1/items der
 *                                                 Stage (= Wrapper minus
 *                                                 2×stagePadding) minus
 *                                                 anteiligen Margin ein.
 *
 *   Mobil  (<768px):   1 Item,  margin=12px, stage=10px  -> 1 Spalte, Gap 12px
 *   Tablet (768-1024): 2 Items, margin=28px, stage=18px  -> 2 Spalten, Gap 28px
 *   Desktop (>=1025px):3 Items, margin=36px, stage=24px  -> 3 Spalten, Gap 36px
 *
 * HINWEIS: Variable-calc-Methode (flex: calc(100%/var(--cols)...)) wird NICHT
 * verwendet (hat das Design zuvor zerschossen). Feste Media-Query-Werte.
 *
 * Der aeussere Wrapper (.cod-embed-angebote-wrap) hat padding = stagePadding
 * je Breakpoint (10/18/24px), sodass die Karten-Linksfluchten mit den
 * Partner-Karten uebereinstimmen.
 */

.angebote-grid {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    /* Mobil: Halber Gap (6px) als negativer Ausgleich, damit Aussen-Padding
       nicht doppelt zaehlt. Gap zwischen Karten = margin*2 = 12px. */
    margin: -6px;
}

.angebote-grid > .angebot-card {
    /* Mobil: 1 Spalte, je Karte 6px Rand -> Gap = 12px (Partner margin_xs=12). */
    flex: 0 0 calc(100% - 12px);
    /* Seit 05.08.2026 dieselbe Breite wie die Partner-Karte darüber. Vorher
       füllte die Angebote-Karte einfach ihre Rasterspalte und war deshalb
       mobil 24 px und auf dem Tablet 60 px breiter — gemessen 296 gegen 272
       bei 360 px, 360 gegen 300 bei 768 px. Zwei Karten übereinander, zwei
       verschiedene Breiten: genau der Fall aus Abschnitt 20 des Bauplans.

       Die Partner-Karte bezieht ihre Breite aus drei Stufen
       (widget-partner-karusell.php). Nachgemessen, was davon bei der KARTE
       ankommt — nicht beim Owl-Element, das 44 px mehr hat:
         bis  600 px   Owl-Element 100vw - 44, Karte darin 22 px Rand je Seite
                       -> also 100vw - 88
         bis 1024 px   max-width 300px
         darüber       max-width 360px
       Genau diese drei Stufen stehen hier. Ändert sich die Zahl im
       Partner-Widget, gehört sie hier mitgezogen — sonst laufen die beiden
       Karten wieder auseinander, und man sieht es nur im Wechsel der Bereiche. */
    max-width: min(calc(100% - 12px), calc(100vw - 88px));
    /* In der Spalte MITTIG. Seit die Karte gedeckelt ist, ist sie schmaler als
       ihre Rasterspalte - ohne diese Zeile klebt sie links, und die gesparte
       Breite landet komplett rechts. Gemessen am 05.08.2026 bei 360 px direkt
       nach dem Deckeln: Mitte 168 statt 180, also 12 px zu weit links, während
       die Partner-Karte darüber korrekt auf 180 sass. Kriterium 13 erlaubt 1 px. */
    justify-self: center;
    margin: 6px;
}

@media (min-width: 600px) {
    /* Ab 600px 2 Spalten (vorher erst 768px): dazwischen wurde die Karte volle
       Breite und durch das 3:2-Titelbild viel zu hoch. Je Karte 14px Rand ->
       Gap = 28px (Partner margin_sm=28). Das Wrapper-Padding bleibt bewusst bei
       768px, weil es die Karussell-Einrückung der Partner-Karten spiegelt. */
    .angebote-grid {
        margin: -14px;
    }
    .angebote-grid > .angebot-card {
        flex: 0 0 calc(50% - 28px);
        /* Deckel auf die Partner-Kartenbreite dieser Stufe. ABSOLUT, nicht als
           Prozent: Das Widget rendert als RASTER, und ein Prozentwert bezieht
           sich dort auf die SPALTE, nicht auf den Container. Am 05.08.2026
           gemessen, was min(33.333% - 24px, 360px) im Raster ergibt: 33,333 %
           von 360 px Spalte = 120, minus 24 = 96 px Karte. Absolut umgeht das. */
        max-width: 300px;
        margin: 14px;
    }
}

@media (min-width: 1025px) {
    /* Desktop: 3 Spalten, je Karte 12px Rand -> Gap = 24px. Owl rechnet die
       Item-Breite (stagePadding-Peek) so, dass 36px Gap die Karte ~8px zu
       schmal macht; 24px Gap trifft die Partner-Kartenbreite exakt. */
    .angebote-grid {
        margin: -12px;
    }
    .angebote-grid > .angebot-card {
        flex: 0 0 calc(33.333% - 24px);
        /* Absolut, siehe Begründung eine Stufe darüber. */
        max-width: 360px;
        margin: 12px;
    }
}

/* Sentinel (Inline Scroll-Observer-Anker) */
.angebote-embed-sentinel {
    width: 100%;
    height: 1px;
}

/* ── Karte ───────────────────────────────────────────────────────────────── */

.angebot-card.cod-card {
    display: flex;
    flex-direction: column;
    /* Feste Karten-Höhe (4:5) wie beim Partner -> alle Karten gleich hoch.
       Inhalt verteilt sich (Buttons unten), Überlauf wird abgeschnitten. */
    aspect-ratio: 4 / 5;

    /* ALLE festen Abstände der Karte stehen hier, und jeder skaliert mit ihr.
       Warum das keine Kosmetik ist (gemessen am 06.08.2026):
       Die Karte trägt 4:5, das Bild darüber 4:3. Beides geht nur auf, wenn der
       Block unter dem Bild GENAU 500 Promille der Kartenbreite hoch ist -
       1,25·B minus 0,75·B. Alles darüber nimmt sich das Bild, denn nur es kann
       nachgeben (flex-shrink).
       Die Schriften folgten der Karte längst (--cod-card-ui-scale), diese
       Abstände nicht. Bei einer 300er Karte wogen dieselben 14/16/8/40 px
       anteilig ein Fünftel mehr als bei 360 - und genau dieses Fünftel fehlte
       dem Bild:
           768 px   Karte 300 x 375   Bild 182,4   Bild/Karte 0,49
          1440 px   Karte 360 x 450   Bild 265     Bild/Karte 0,59
       Ein Wert hier ist deshalb IMMER die Desktop-Zahl mal Skalierung. Wer
       einen festen px-Wert in die Karte schreibt, verstellt das Verhältnis auf
       jedem Gerät, dessen Karte nicht 360 px breit ist - ohne dass irgendwo
       etwas kaputt aussieht. */
    --cod-angebot-rand: calc(16px * var(--cod-card-ui-scale, 1));
    --cod-angebot-luft: calc(8px * var(--cod-card-ui-scale, 1));
    --cod-angebot-fuss: calc(14px * var(--cod-card-ui-scale, 1));

    padding: 0 0 var(--cod-angebot-fuss) 0;
    overflow: hidden;
    height: auto;
    box-sizing: border-box;
    border-radius: var(--cod-card-radius, 5px);
    border: 1px solid var(--cod-border, rgba(31, 65, 102, .12));
    box-shadow: var(--cod-shadow-card, 0 14px 32px rgba(21, 58, 99, .10));
}

/* Breiteste zulässige Karte. Sie liegt auf der Partner-Kartenbreite (360 px),
   damit beide Bereiche auf der Startseite gleich wirken - die umgebenden
   Container sind ohnehin identisch breit (gemessen bei 1920 px: l 112 - r 1808
   für beide). Ohne diese Grenze zog eine einzelne Angebote-Karte ihre ganze
   Rasterspalte auf und war dort 525 px breit.
   Gelesen wird der Wert in codEmbedAngeboteApplyGrid(). */
.cod-embed-angebote-wrap {
    --cod-card-max-width: 360px;
}

/* Aufgeklappt darf die Karte wachsen (Entscheidung 01.08.2026).
   Das feste 4:5 gilt nur im RUHEZUSTAND - daraus entstehen die Sharing-Bilder,
   die brauchen alle dasselbe Format. Sobald Beschreibung oder Buchung offen
   sind, wird das Verhältnis ausgesetzt: sonst schneidet overflow:hidden genau
   den Text weg, den der Tipp sichtbar machen sollte (gemessen am 01.08.2026 bei
   360 px: Inhalt 541 px in einer 370 px hohen Karte, der komplette
   "Termin buchen"-Knopf des Panels unsichtbar).

   Die Klasse setzt updateRowStateFor() in cod-angebote-directory.php bereits -
   sie ist wahr, solange .angebot-desc.open ODER .angebote-booking-inline.open
   in der Karte steckt. Kein :has() (in Firefox < 121 ungültig), kein neues JS.
   overflow bleibt hidden, damit die Rundung sauber bleibt; abgeschnitten wird
   nichts mehr, weil die Karte jetzt mitwächst. */
.angebot-card.cod-card.angebote-row-open {
    aspect-ratio: auto;
}

/* ── Bild-Bereich ────────────────────────────────────────────────────────── */

.angebot-image-wrap {
    position: relative;
    overflow: hidden;
    /* Das Standardformat der Plattform: 1,426 (365/256, praktisch 10:7) - seit
       dem 13.08.2026 dasselbe wie bei Academy, Gewinnspiel und Event. Fixiert,
       damit nichts springt, bevor das Bild geladen ist.

       Vorher stand hier 4/3 "wie beim Partner-Bild". Gemessen kamen aber 1,358
       heraus (360x265), weil die Karte eine feste Gesamt-Proportion hat und das
       Bild staucht - und zugeschnitten wurde auf 3:2. Ein Angebotsbild wurde
       also ZWEIMAL beschnitten, einmal beim Speichern und einmal beim Anzeigen,
       und keine der drei Zahlen kannte die andere. */
    /* DIE ZAHL STEHT HIER DIREKT, NICHT ALS var(--cod-card-ratio, ...) - das war am
       13.08.2026 ein Live-Schaden von wenigen Minuten: Das Token ist global auf
       'auto' gesetzt. var() nimmt dann diesen Wert und den Rueckfall NIE, die
       Huelle kollabiert auf Hoehe 0 und das Bild verschwindet. Ein Rueckfallwert
       greift nur, wenn die Variable GAR NICHT gesetzt ist - nicht, wenn sie auf
       etwas Unbrauchbares gesetzt ist. */
    aspect-ratio: 365 / 256;
    /* flex-shrink: 0 wurde am 06.08.2026 versucht und ZURUECKGENOMMEN.
       Es loeste zwar das Bild (ueberall 300 x 225 statt 182,4 gegen 205,1) und
       damit Anbietername, Titel und Ort - aber im Angebote-Bereich ragte der
       Inhalt danach unten aus der Karte: letzte Zeile bei 377 px in einer
       375 px hohen Karte. Bei overflow: hidden heisst das abgeschnittene
       Knoepfe - schlimmer als der urspruengliche Fehler.
       Der richtige Weg ist deshalb umgekehrt: erst die TEXTHOEHE konstant
       machen (Titel auf feste Zeilenzahl begrenzen), dann haelt das Bild sein
       4:3 von selbst, ohne dass etwas anstoesst. */
    max-height: none;
}

.angebot-image-wrap img.angebot-main-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
    transform: none;
    transition: none;
}

/* ── Provider-Chip ───────────────────────────────────────────────────────── */

/* Fläche und Schrift der beiden Chips auf dem Bild (Anbieter unten links,
   Kategorie oben links) kommen aus derselben Kette. Sie stand fest im CSS und
   war damit die einzige Stelle der Karte, an die der Betreiber nicht
   herankommt. Letztes Glied bleibt der bisherige Wert - ohne Dashboard-Angabe
   sieht es unverändert aus. */
.angebot-provider-chip {
    position: absolute;
    /* Mit der Karte skaliert, wie es die Partner-Karte für ihre Bild-Auflagen
       längst tut (partner-card.css). Diese Auflagen ändern die Kartenhöhe
       nicht - sie liegen im Bild -, verstellen aber genauso das Verhältnis,
       das man SIEHT: Der Chip mass auf der 272er Karte 118 Promille ihrer
       Breite und auf der 360er nur 89. */
    left: calc(16px * var(--cod-card-ui-scale, 1));
    bottom: calc(16px * var(--cod-card-ui-scale, 1));

    /* Seit 06.08.2026 auf dem gemeinsamen Info-Chip (Etappe 7):
       .cod-info-chip --bild --medien --aktion. Von hier kommt nur noch, was
       NUR hier gilt.

       DIE SKALIERUNG IST DER GRUND, WARUM DAS NICHT EINFACH WEGFÄLLT: Der Chip
       wächst und schrumpft mit der Karte - gemessen am 06.08.2026 von 105 x 24
       bei 360 px bis 141 x 32 bei 1440 px. Der Baustein kennt die
       Kartenskalierung nicht; hier bekommt er sie in seine eigenen Token
       hineingerechnet.

       --cod-chip-pad-x-basis liegt auf der KARTE (weiter unten) und trägt den
       unskalierten Dashboard-Wert. Ohne diesen Umweg müsste man ihn hier fest
       eintragen und der Chip folgte dem Betreiber nicht mehr.

       Senkrecht und links bleibt 0: Der Chip ist genau so hoch wie das Bild
       darin, dadurch deckt sich die linke Halbkugel des Kreises mit der
       Rundung der Pille. Am 02.08.2026 gemessen - mit Innenabstand war er
       12 px zu hoch. --medien bringt genau das mit. */
    --cod-chip-pad-x: calc(var(--cod-chip-pad-x-basis, 10px) * var(--cod-card-ui-scale, 1));
    --cod-chip-medien-size: calc(32px * var(--cod-card-ui-scale, 1));

    /* Untergrenze 9 statt 11 px (06.08.2026): Bei 11 griff sie auf der 272er
       Karte (13 x 0,756 = 9,83) und machte den Anbieternamen dort anteilig
       grösser als am Desktop - 48 gegen 43 Promille der Kartenbreite. Die
       Regel dahinter steht beim Titel: Eine Untergrenze gehört UNTER den
       kleinsten Wert, den die Skala auf der schmalsten Karte erzeugt, sonst
       ist sie keine Notbremse mehr, sondern eine zweite Grösse.
       Bleibt hier, weil auch die Schrift mit der Karte skaliert - der Baustein
       erbt sie sonst aus der Umgebung und der Name wäre auf der schmalen Karte
       zu gross. */
    font-size: max(var(--cod-card-min-font, 13px), calc(13px * var(--cod-card-ui-scale, 1)));
    font-weight: 400;
    line-height: 1.2;
    -webkit-backdrop-filter: blur(4px);backdrop-filter: blur(4px);
    text-decoration: none;
    box-shadow: var(--cod-shadow-action, 0 10px 24px rgba(21, 58, 99, .16));
}

/* Der unskalierte Dashboard-Wert, damit der Chip ihn oben multiplizieren kann.
   Muss auf der KARTE stehen und nicht am Chip selbst: Eine Custom Property
   kann sich nicht auf ihren eigenen Namen beziehen. */
.angebot-card {
    --cod-chip-pad-x-basis: var(--cod-chip-pad-x, 10px);
}

/* Hover der Bild-Chips (Branding & Design -> Info-Chips 2). Nur der
   Anbieter-Chip bekommt ihn: Er ist ein <a> und führt zum Anbieter. Die
   Kategorie ist ein reines Etikett ohne Klick — ein Hover dort würde
   Klickbarkeit vortäuschen, die es nicht gibt.
   Ohne Einstellung passiert nichts: Rückfallwert ist der Ruhezustand. */
.angebot-provider-chip:hover,
.angebot-provider-chip:focus-visible {
    background: var(--cod-chip-hover-bg, var(--cod-chip-bg, rgba(0, 0, 0, .55)));
    color: var(--cod-chip-hover-color, var(--cod-chip-color, #fff));
}

/* Die eigene Bild-Regel ist entfallen (06.08.2026): Rundung, Zuschnitt und
   der weisse Ring kommen jetzt aus .cod-info-chip--medien, die Grösse über
   --cod-chip-medien-size oben. */

/* Der Chip ist jetzt nur noch so hoch wie der Kreis (32 px) und damit auf Touch
   unter der Mindestgrösse. Die Fläche wird aufgerechnet, ohne ihn zu vergrössern.
   position: absolute steht bereits am Chip - der Anker ist vorhanden und wird
   hier NICHT angefasst; eine Sammelregel mit position:relative hat an dieser
   Karte schon einmal den Teilen-Knopf aus dem Bild gerissen. */
@media (pointer: coarse) {
    .angebot-provider-chip::after {
        content: "";
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 100%;
        height: 100%;
        min-height: 44px;
        border-radius: 999px;
    }
}

.angebot-provider-name {
    white-space: nowrap;
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--cod-chip-color, #fff) !important;
}

/* ── Share-FAB ───────────────────────────────────────────────────────────── */

.angebot-share-fab {
    position: absolute;
    /* Mit der Karte skaliert - die Partner-Karte verankert ihre Bild-Knöpfe
       seit jeher so (partner-card.css Zeile 93/94). Die Trefferfläche bleibt
       davon unberührt: Sie entsteht weiter unten über ein Pseudo-Element mit
       min-height 44px und nicht aus dieser Grösse. */
    right: calc(10px * var(--cod-card-ui-scale, 1));
    bottom: calc(10px * var(--cod-card-ui-scale, 1));
    width: calc(var(--cod-angebot-share-box-size, 40px) * var(--cod-card-ui-scale, 1));
    height: calc(var(--cod-angebot-share-box-size, 40px) * var(--cod-card-ui-scale, 1));
    border-radius: var(--cod-button-radius, 8px);
    background: var(--cod-angebot-share-bg, var(--cod-cta2, #2b86c5));
    opacity: var(--cod-angebot-share-opacity, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--cod-shadow-action, 0 10px 24px rgba(21, 58, 99, .16));
    cursor: pointer;
    border: 0;
    padding: 0 !important;
    /* overflow:visible damit das Tooltip-Popup nicht abgeschnitten wird;
       das Icon-img wird separat per clip-path auf die FAB-Box begrenzt. */
    overflow: visible;
}

/* Icon-Bild innerhalb der FAB auf die Box clippen,
   damit es trotz overflow:visible nicht aus der runden FAB herausragt. */
.angebot-share-fab img {
    clip-path: none;
    overflow: hidden;
    border-radius: inherit;
}

.angebot-share-fab:hover,
.angebot-share-fab:focus {
    background: var(--cod-angebot-share-bg, var(--cod-cta2, #2b86c5));
    box-shadow: var(--cod-shadow-action-hover, 0 14px 28px rgba(21, 58, 99, .18));
    transform: translateY(-1px);
}

.angebot-share-fab img {
    /* Das Sinnbild folgt seiner Box - sonst sässe auf einer geschrumpften
       Fläche ein unveränderter Glyph und würde sie ausfüllen. */
    width: calc(var(--cod-angebot-share-glyph-size, 22px) * var(--cod-card-ui-scale, 1)) !important;
    height: calc(var(--cod-angebot-share-glyph-size, 22px) * var(--cod-card-ui-scale, 1)) !important;
    max-width: none !important;
    max-height: none !important;
    display: block;
    filter: brightness(0) invert(1);
    object-fit: contain;
    flex: 0 0 calc(var(--cod-angebot-share-glyph-size, 22px) * var(--cod-card-ui-scale, 1));
}

/* ── Karten-Inhalt ───────────────────────────────────────────────────────── */

.angebot-content {
    padding: var(--cod-angebot-luft) 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
}

.angebote-grid .angebot-card .cod-title,
.angebot-card .cod-title {
    margin: var(--cod-angebot-luft) var(--cod-angebot-rand) !important;
    padding: 0 !important;
    text-align: left;
    /* Feste Zeilenzahl seit 06.08.2026 — und der Grund ist nicht Optik.
       Die Karte hat eine feste Hoehe (aspect-ratio 4/5). Das Bild darueber
       bekommt den Platz, der nach dem Text uebrig bleibt, weil flex-shrink
       standardmaessig 1 ist. Ein zweizeiliger Titel an einem Ort und ein
       einzeiliger am anderen ergab deshalb zwei verschieden hohe Bilder
       (gemessen bei 768 px: 182,4 gegen 205,1 px) - und alles darunter war um
       76 Promille verschoben.
       Mit fester Zeilenzahl ist der Textblock ueberall gleich hoch, und das
       Bild haelt sein Verhaeltnis von selbst. Der umgekehrte Weg
       (flex-shrink: 0 auf dem Bild) wurde versucht und zurueckgenommen: Dann
       ragte der Text unten aus der Karte. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-indent: 0 !important;
    font-family: var(--cod-font-card-title, var(--e-global-typography-dbdb71b-font-family, var(--e-global-typography-44ebb6b-font-family, system-ui, sans-serif)));
    /* Schriftmass folgt der KARTE, nicht dem Fenster: --cod-card-ui-scale kommt
       aus der gemessenen Kartenbreite (cod-partner-card-scale.js). Der frühere
       @media-Sprung bei 767px hing an der Fensterbreite und lag beim Tablet
       daneben - 820px Fenster heisst zwei Spalten, also eine schmalere Karte als
       bei 390px, die Schrift wuchs dort aber statt zu schrumpfen.
       Die Untergrenze lag bis zum 06.08.2026 bei 15 px und war damit HÖHER als
       die kleinste Stufe selbst: "Winzig" sind 16 px, auf einer 272er Karte
       also 16 x 0,756 = 12,1 - angehoben auf 15. "Klein" ergibt dort 15,12.
       Beide Stufen lagen 0,12 px auseinander, der Regler wirkte wie kaputt
       (vom Betreiber genau so gemeldet). Gemessen in Promille der Kartenbreite:
           Stufe        360    390    768   1440
           Winzig        55     50     50     44   <- wanderte
           Klein         56     56     56     56
           Mittel        67     67     67     67
       Nur Winzig fiel heraus, und zwar allein wegen dieser Zahl. Mit 12 px
       bleiben alle sieben Stufen bis hinunter zur 272er Karte verhältnistreu;
       ein Restschutz gegen die Schrumpf-Schleife der Nachführung bleibt. Wer
       sie wieder anhebt, nimmt dem Betreiber die unterste Stufe - ohne dass
       irgendwo ein Fehler sichtbar wird. */
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-font-card-title-size, var(--e-global-typography-dbdb71b-font-size, 1.05rem)) * var(--cod-card-ui-scale, 1)));
    font-weight: var(--e-global-typography-dbdb71b-font-weight, 700);
    line-height: var(--e-global-typography-dbdb71b-line-height, 1.2);
    color: var(--cod-name-color, var(--cod-title-color, var(--cod-color-text, #4d4d4d)));
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Zwei Zeilen fest: darunter kappt line-clamp mit "…". Die Karte hat ein
       festes Verhältnis, deshalb darf der Titel nie eine dritte Zeile nehmen. */
    min-height: calc(1.2em * 2);
    max-height: calc(1.2em * 2);
    width: auto;
    max-width: calc(100% - 2 * var(--cod-angebot-rand));
    word-wrap: break-word;
    position: static;
    float: none;
}

/* Anbieterkennzeichnung (cod_anbieter_line_html der Zentrale). Sie hatte als
   einziger Text der Kachel gar keine eigene Grössenangabe und bekam ihre 16 px
   vom Theme-Reset (hello-elementor, "button { font-size: 1rem }"). Damit stand
   sie auf jeder Breite gleich gross und fiel als einzige aus dem Verhältnis:
   59 Promille der Kartenbreite bei 360 px gegen 44 bei 1440.
   Der Grundwert ist bewusst 16px - genau der bisherige Wert. Am Desktop ändert
   sich dadurch NICHTS; die Zeile schrumpft nur noch im selben Mass wie die
   Karte, statt stehenzubleiben. Das ist wichtig, weil es eine Pflichtangabe
   ist: Sie darf mitskalieren, aber nicht gegenüber den anderen Texten kleiner
   werden - mit 44 Promille liegt sie jetzt exakt auf der Ortszeile.
   Nur innerhalb der Kachel, damit dieselbe Zeile im Partner-Popup und in den
   Belegen unberührt bleibt. */
.angebot-card .cod-anbieter-link {
    font-size: max(var(--cod-card-min-font, 13px), calc(16px * var(--cod-card-ui-scale, 1)));
}

/* ── Standort-Zeile ──────────────────────────────────────────────────────── */

.angebot-location-meta {
    margin: 0 var(--cod-angebot-rand) calc(4px * var(--cod-card-ui-scale, 1));
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: calc(2px * var(--cod-card-ui-scale, 1));
    min-height: calc(36px * var(--cod-card-ui-scale, 1));
    /* Bezugsrahmen für die Touch-Fläche des Standort-Knopfes weiter unten.
       Sie MUSS hier hängen und nicht am Knopf: Zeile und Wert klemmen beide
       ihren Text ab (overflow: hidden, sonst gäbe es keine Ellipse), und ein
       Kasten beschneidet eine absolut gesetzte Box nur dann, wenn er zwischen
       ihr und ihrem Bezugsrahmen liegt. Von hier aus liegen beide darunter -
       die Fläche kommt durch, die Ellipse bleibt. */
    position: relative;
}

.angebot-location-name {
    width: 100%;
    font-size: max(var(--cod-card-min-font, 13px), calc(13px * var(--cod-card-ui-scale, 1)));
    line-height: 1.25;
    color: var(--cod-location-color, var(--cod-meta, #5a7a99));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.angebot-distance-line {
    width: 100%;
    font-size: max(var(--cod-card-min-font, 13px), calc(13px * var(--cod-card-ui-scale, 1)));
    line-height: 1.25;
    color: var(--cod-location-color, var(--cod-meta, #5a7a99));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.angebot-distance-value {
    display: inline-block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.angebote-location-btn {
    appearance: none;
    -webkit-appearance: none;
    background: transparent !important;
    background-image: none !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
    /* --cod-location-link-color / --cod-font-angebot-loclink werden vom Elementor-Widget gesetzt;
       Fallback auf --cod-color-accent-blue (bisheriger Wert) -> unveraenderte Optik. */
    color: var(--cod-location-link-color, var(--cod-color-accent-blue, #2b86c5)) !important;
    font-family: var(--cod-font-angebot-loclink, inherit);
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-location-link-size, 13px) * var(--cod-card-ui-scale, 1)));
    text-decoration: underline !important;
    cursor: pointer;
    display: inline !important;
    line-height: 1.25;
    text-align: left;
    border-radius: 0 !important;
    min-height: auto !important;
}

.angebote-location-btn:hover,
.angebote-location-btn:focus,
.angebote-location-btn:active {
    background: transparent !important;
    color: var(--cod-location-link-hover-color, var(--cod-location-link-color, var(--cod-color-accent-blue, #2b86c5))) !important;
    box-shadow: none !important;
    outline: none;
}

/* ── Aktionen-Zeile ──────────────────────────────────────────────────────── */

.angebot-actions,
.angebot-desc-actions {
    position: relative;
    z-index: 20;
}

.angebot-actions {
    /* Buttons ans untere Karten-Ende schieben (feste Karten-Hoehe -> wie beim Partner,
       gleicher Abstand zur Unterkante ueber das Karten-Padding unten). */
    margin-top: auto;
    margin-bottom: 0 !important;
    padding: 0 var(--cod-angebot-rand);
    display: flex;
    gap: var(--cod-angebot-rand);
    align-items: stretch;
    /* Beide Buttons IMMER nebeneinander (kein Umbruch auch bei schmaler Karte). */
    flex-wrap: nowrap;
    justify-content: flex-start;
    text-align: left;
}
/* Buttons teilen sich die Reihe gleichmaessig + duerfen schrumpfen, damit sie
   nebeneinander passen. */
.angebot-actions > .cod-cta {
    flex: 1 1 0;
    min-width: 0;
}

/* Primär-Button "Mehr erfahren" — grün via --cod-btn-angebot-bg (= --cod-cta) */
/* Vollstaendige Theme-Override-Schicht aus cod_angebote_widget_theme_overrides_css() */
.angebot-actions .cod-cta,
.angebot-desc-actions .cod-cta,
.angebote-booking-fallback .cod-cta {
    appearance: none;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--cod-angebot-luft, 8px);
    box-sizing: border-box;
    white-space: nowrap;
    padding: 0 var(--cod-angebot-rand, 16px);
    /* Token-gesteuerte Farbe (gruen = --cod-btn-angebot-bg -> --cod-cta -> #51B36F) */
    background: var(--cod-btn-angebot-bg, var(--cod-cta, #51B36F));
    color: var(--cod-btn-angebot-color, #fff) !important;
    border: var(--cod-btn-angebot-border-width, 0px) solid var(--cod-btn-angebot-border-color, transparent);
    /* Mittleres Glied ergänzt (02.08.2026): Ohne --cod-button-radius erreichte die
       Rundung aus dem Betreiber-Dashboard diese Buttons gar nicht - der Regler war
       gesetzt, wirkte aber nur auf die Partner-Karte. Ein fester Wert ist als
       LETZTES Glied erlaubt, nie als einziges. */
    border-radius: var(--cod-btn-angebot-border-radius, var(--cod-button-radius, 6px));
    font-family: var(--cod-font-btn-angebot, inherit);
    /* Mit der Karte skaliert - siehe Titel. Untergrenze 12px, sonst ist die
       Beschriftung auf schmalen Karten nicht mehr lesbar. */
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-font-btn-angebot-size, 14px) * var(--cod-card-ui-scale, 1)));
    font-weight: var(--cod-font-btn-angebot-weight, 700);
    /* Feste Höhe wie beim Partner-Button (statt vertikalem Padding), damit
       die Button-Höhe 1:1 mit den Partner-Karten übereinstimmt.
       Mit der Karte skaliert seit 06.08.2026 - und erst dadurch stimmt die
       Zusage im Satz darüber wirklich: Der Partner-Knopf rechnet längst
       calc(... * --cod-card-ui-scale) (partner-card.css), der Angebote-Knopf
       stand als einziger fest. Auf einer 300er Karte war er damit anteilig
       133 statt 111 Promille hoch und nahm dem Bild 6,7 px.
       Die Trefferfläche bleibt davon unberührt - die entsteht unten im
       Touch-Block über ein Pseudo-Element und nicht aus dieser Höhe. */
    height: calc(var(--cod-btn-angebot-height, 40px) * var(--cod-card-ui-scale, 1));
    min-height: calc(var(--cod-btn-angebot-height, 40px) * var(--cod-card-ui-scale, 1));
    box-shadow: 0 var(--cod-btn-angebot-shadow, 0px) calc(var(--cod-btn-angebot-shadow, 0px) * 2) var(--cod-shadow-color, rgba(31, 65, 102, .12));
    opacity: var(--cod-btn-angebot-opacity, 1);
    transition: all var(--cod-btn-angebot-transition, 160ms) var(--cod-btn-angebot-ease, ease);
}

.angebot-actions .cod-cta:hover,
.angebot-desc-actions .cod-cta:hover,
.angebote-booking-fallback .cod-cta:hover,
.angebot-actions .cod-cta:focus,
.angebot-desc-actions .cod-cta:focus,
.angebote-booking-fallback .cod-cta:focus {
    color: var(--cod-btn-angebot-hover-color, #fff) !important;
    background: var(--cod-btn-angebot-hover-bg, var(--cod-btn-angebot-bg, var(--cod-cta, #51B36F)));
    border-color: var(--cod-btn-angebot-hover-border-color, var(--cod-btn-angebot-border-color, transparent));
    transform: translateY(var(--cod-btn-angebot-hover-translate, 0px)) scale(var(--cod-btn-angebot-hover-scale, 1));
    opacity: var(--cod-btn-angebot-hover-opacity, 1);
}

.angebot-actions .cod-cta:active,
.angebot-desc-actions .cod-cta:active,
.angebote-booking-fallback .cod-cta:active {
    color: var(--cod-btn-angebot-active-color, #fff) !important;
    background: var(--cod-btn-angebot-active-bg, var(--cod-btn-angebot-bg, var(--cod-cta, #51B36F)));
    border-color: var(--cod-btn-angebot-active-border-color, var(--cod-btn-angebot-border-color, transparent));
    transform: translateY(var(--cod-btn-angebot-active-translate, 0px)) scale(var(--cod-btn-angebot-active-scale, 1));
    opacity: var(--cod-btn-angebot-active-opacity, 1);
}

/* Secondary-Button "Termin buchen" — blau via --cod-btn-event-bg (= --cod-cta2) */
.angebot-actions .cod-cta.secondary,
.angebot-desc-actions .cod-cta.secondary,
.angebote-booking-fallback .cod-cta.secondary {
    background: var(--cod-btn-event-bg, var(--cod-cta2, #2b86c5));
    color: var(--cod-btn-event-color, #fff) !important;
    border: var(--cod-btn-event-border-width, 0px) solid var(--cod-btn-event-border-color, transparent);
    /* Mittleres Glied ergänzt - Begründung beim Angebot-Button darüber. */
    border-radius: var(--cod-btn-event-border-radius, var(--cod-button-radius, 6px));
    font-family: var(--cod-font-btn-event, inherit);
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-font-btn-event-size, 14px) * var(--cod-card-ui-scale, 1)));
    font-weight: var(--cod-font-btn-event-weight, 700);
    /* Mit der Karte skaliert wie der Knopf darüber - diese Regel steht SPÄTER
       in der Datei und hat die dortige Skalierung sonst still wieder
       ausgehebelt. Gemessen am 06.08.2026 bei 768 px: erster Knopf 33,3 px,
       zweiter 40 px - und weil die Reihe sich am höheren ausrichtet
       (align-items: stretch), blieb die ganze Knopfreihe bei 40 und das Bild
       entsprechend kleiner. Die Reparatur am ersten Knopf allein war deshalb
       messbar wirkungslos.
       Der Partner-Knopf rechnet mit derselben Variablen längst so
       (partner-card.css) - erst damit sind beide Karten wirklich gleich. */
    height: calc(var(--cod-btn-event-height, 40px) * var(--cod-card-ui-scale, 1));
    min-height: calc(var(--cod-btn-event-height, 40px) * var(--cod-card-ui-scale, 1));
    box-shadow: 0 var(--cod-btn-event-shadow, 0px) calc(var(--cod-btn-event-shadow, 0px) * 2) var(--cod-shadow-color, rgba(31, 65, 102, .12));
    opacity: var(--cod-btn-event-opacity, 1);
    transition: all var(--cod-btn-event-transition, 160ms) var(--cod-btn-event-ease, ease);
}

.angebot-actions .cod-cta.secondary:hover,
.angebot-desc-actions .cod-cta.secondary:hover,
.angebote-booking-fallback .cod-cta.secondary:hover,
.angebot-actions .cod-cta.secondary:focus,
.angebot-desc-actions .cod-cta.secondary:focus,
.angebote-booking-fallback .cod-cta.secondary:focus {
    color: var(--cod-btn-event-hover-color, #fff) !important;
    background: var(--cod-btn-event-hover-bg, var(--cod-btn-event-bg, var(--cod-cta2, #2b86c5)));
    border-color: var(--cod-btn-event-hover-border-color, var(--cod-btn-event-border-color, transparent));
    transform: translateY(var(--cod-btn-event-hover-translate, 0px)) scale(var(--cod-btn-event-hover-scale, 1));
    opacity: var(--cod-btn-event-hover-opacity, 1);
}

.angebot-actions .cod-cta.secondary:active,
.angebot-desc-actions .cod-cta.secondary:active,
.angebote-booking-fallback .cod-cta.secondary:active {
    color: var(--cod-btn-event-active-color, #fff) !important;
    background: var(--cod-btn-event-active-bg, var(--cod-btn-event-bg, var(--cod-cta2, #2b86c5)));
    border-color: var(--cod-btn-event-active-border-color, var(--cod-btn-event-border-color, transparent));
    transform: translateY(var(--cod-btn-event-active-translate, 0px)) scale(var(--cod-btn-event-active-scale, 1));
    opacity: var(--cod-btn-event-active-opacity, 1);
}

.angebot-actions .cod-cta span,
.angebot-desc-actions .cod-cta span,
.angebote-booking-fallback .cod-cta span {
    white-space: nowrap;
}

/* Farbe des geöffneten Knopfes ("Weniger anzeigen" / "Schließen").
   #F7A715 ist KEINE Statusfarbe im Sinne von Fehler/Erfolg, sondern eine
   Zustandsfarbe - sie gehört damit ans Dashboard. Die Kette ist hier geöffnet,
   der bisherige Wert bleibt letztes Glied: Solange niemand etwas setzt, sieht
   es genau aus wie vorher. */
.angebot-actions .cod-cta.is-close,
.angebot-desc-actions .cod-cta.is-close {
    background: var(--cod-btn-angebot-open-bg, var(--cod-color-accent-orange, #F7A715)) !important;
}

/* Der Innenabstand darf am Fenster hängen (er bestimmt keine Textgrösse),
   die SCHRIFT nicht - die stand hier fest auf 14px und hat damit die
   Skalierung wieder ausgehebelt. Sie kommt jetzt aus der Grundregel. */
@media (max-width: 767px) {
    .angebot-actions .cod-cta,
    .angebot-actions .cod-cta.secondary {
        padding: 0 12px;
        /* min-width:0, NICHT auto: Bei einem Flex-Element heisst "auto"
           "niemals schmaler als der eigene Text". Die Knöpfe konnten deshalb
           nicht schrumpfen und liefen aus der Karte - gemessen am 01.08.2026
           im aufgeklappten Zustand bei 360 px: "Termin buchen" endete 39 px
           hinter dem Kartenrand und wurde von overflow:hidden gekappt.
           Diese Regel steht nach .angebot-actions > .cod-cta { min-width: 0 }
           und hat sie ausgehebelt. */
        min-width: 0;
        line-height: 1.2;
    }
}

/* ── Beschreibungs-Panel ─────────────────────────────────────────────────── */

.angebot-desc {
    padding: 12px 16px 12px;
    margin-top: 20px;
    display: none;
    border-top: 1px solid rgba(0, 0, 0, .06);
}

.angebot-desc.open {
    display: block;
}

.angebote-desc-content {
    font-size: max(var(--cod-card-min-font, 13px), calc(15px * var(--cod-card-ui-scale, 1)));
    line-height: 1.5;
    color: var(--cod-text, #4d4d4d);
    margin-top: 6px;
    margin-bottom: 6px;
}

.angebote-desc-content p {
    margin: 0 0 8px;
}

.angebote-desc-content a {
    color: var(--cod-color-accent-blue, #2b86c5);
    text-decoration: underline;
}

.angebot-desc-actions {
    margin-top: 10px;
    display: flex;
    justify-content: flex-start;
}

/* ── Buchungs-Inline ─────────────────────────────────────────────────────── */

.angebote-booking-inline {
    padding: 0 16px 16px;
    border-top: 1px solid rgba(0, 0, 0, .06);
    display: none;
    margin-top: 0;
}

.angebote-booking-fallback {
    padding: 16px 0 4px 0;
}

.angebote-booking-fallback p {
    margin: 0 0 12px 0;
    font-size: 14px;
    line-height: 1.45;
    color: var(--cod-text, #4d4d4d);
}

/* ── Theme-Overrides (Widget-Builder-Variablen) ──────────────────────────── */
/* Entspricht cod_angebote_widget_theme_overrides_css() — vollstaendige Schicht */

/* Karte */
.angebot-card.cod-card {
    background: var(--cod-card-bg, #fff);
    border-radius: var(--cod-card-border-radius-top-left, var(--cod-card-radius, 5px))
                   var(--cod-card-border-radius-top-right, var(--cod-card-radius, 5px))
                   var(--cod-card-border-radius-bottom-right, var(--cod-card-radius, 5px))
                   var(--cod-card-border-radius-bottom-left, var(--cod-card-radius, 5px));
    border: var(--cod-card-border-width, 1px) solid var(--cod-card-border-color, var(--cod-border, rgba(31, 65, 102, .12)));
    box-shadow: var(--cod-shadow-card);
    opacity: var(--cod-card-opacity, 1);
    transition: all var(--cod-card-transition, 300ms) var(--cod-card-ease, ease);
}

.angebot-card.cod-card:hover {
    box-shadow: var(--cod-shadow-card-hover);
    transform: translateY(var(--cod-card-hover-translate, 0px));
}

.angebot-card.cod-card:active {
    box-shadow: var(--cod-shadow-card);
    transform: translateY(var(--cod-card-active-translate, 0px)) scale(var(--cod-card-active-scale, 1));
    opacity: var(--cod-card-active-opacity, 1);
}

/* Bild */
.angebot-image-wrap {
    border-radius: var(--cod-card-border-radius-top-left, var(--cod-card-radius, 5px))
                   var(--cod-card-border-radius-top-right, var(--cod-card-radius, 5px))
                   var(--cod-card-image-radius-bottom-right, var(--cod-card-border-radius-bottom-right, var(--cod-card-radius, 5px)))
                   var(--cod-card-image-radius-bottom-left, var(--cod-card-border-radius-bottom-left, var(--cod-card-radius, 5px)));
}

.angebot-image-wrap img.angebot-main-image {
    border-radius: inherit;
}

/* Share-FAB (Override — eigene Variablen + hoehere Spezifitaet .cod-cta.secondary.angebot-share-fab,
   schlaegt die globale .cod-cta.secondary-Button-Farbe (events.css, 0,2,0). Gradient als Fallback =
   bisheriges Standard-Aussehen; sobald das Control --cod-angebot-share-bg setzt, greift die Farbe. */
.cod-cta.secondary.angebot-share-fab {
    background: var(--cod-angebot-share-bg, linear-gradient(135deg, var(--cod-cta2, #2b86c5) 0%, var(--cod-cta, #51B36F) 100%)) !important;
    opacity: var(--cod-angebot-share-opacity, 1);
    /* Mit der Karte skaliert wie die Grundregel weiter oben. Diese Fassung hat
       die höhere Spezifität und stand am 06.08.2026 als einzige noch fest -
       die Skalierung oben war dadurch messbar wirkungslos (Knopf 42 px auf
       JEDER Breite, also 154 Promille der 272er Karte gegen 117 der 360er).
       Die min-height ist dabei die eigentliche Klemme: Sie hielt die Box auch
       dann auf 42, als height längst kleiner rechnete. */
    width: calc(var(--cod-angebot-share-box-size, 40px) * var(--cod-card-ui-scale, 1));
    height: calc(var(--cod-angebot-share-box-size, 40px) * var(--cod-card-ui-scale, 1));
    min-height: calc(var(--cod-angebot-share-box-size, 40px) * var(--cod-card-ui-scale, 1));
    border-radius: 8px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, .14);
    /* overflow:visible damit das Tooltip-Popup nicht abgeschnitten wird. */
    overflow: visible !important;
}

.cod-cta.secondary.angebot-share-fab:hover,
.cod-cta.secondary.angebot-share-fab:focus-visible {
    background: var(--cod-angebot-share-bg, linear-gradient(135deg, var(--cod-cta2, #2b86c5) 0%, var(--cod-cta, #51B36F) 100%)) !important;
    transform: translateY(-1px);
    box-shadow: none !important;
    /* Identischer Hover-Ring wie Partner-Share-Button (partner-card.css ~L108-115). */
    outline: var(--cod-title-icon-hover-ring-width, 3px) solid var(--cod-title-icon-hover-ring, rgba(53,152,219,.65));
    outline-offset: var(--cod-title-icon-hover-gap, 2px);
}

.angebot-share-fab img {
    /* Zweite Fassung des Sinnbilds - dieselbe Klemme wie bei der Box darüber:
       Ohne die Skalierung hier bleibt der Glyph fest und füllt die
       geschrumpfte Fläche aus. */
    width: calc(var(--cod-angebot-share-glyph-size, 20px) * var(--cod-card-ui-scale, 1)) !important;
    height: calc(var(--cod-angebot-share-glyph-size, 20px) * var(--cod-card-ui-scale, 1)) !important;
    min-width: calc(var(--cod-angebot-share-glyph-size, 20px) * var(--cod-card-ui-scale, 1)) !important;
    min-height: calc(var(--cod-angebot-share-glyph-size, 20px) * var(--cod-card-ui-scale, 1)) !important;
}

/* ── Tooltip "Teile dieses Angebot" (identisches Design wie .partner-loc-tooltip
   aus partner-card.css; FAB sitzt bottom:10px/right:10px => Blase oben-rechts) ── */
.angebot-share-fab .partner-loc-tooltip {
    position:   absolute;
    /* Rechtsbuendig ankern (wie Action-Stack in partner-card.css ~L436),
       damit die Blase nicht ueber den rechten Kartenrand laeuft. */
    left:       auto;
    right:      0;
    bottom:     calc(100% + 8px);
    transform:  translateX(0);
    background: var(--cod-color-secondary, rgba(34,34,34,.96));
    color:      var(--cod-text-on-dark, #fff);
    font-size:  13px;
    line-height: 1.35;
    padding:    8px 10px;
    border-radius: 8px;
    white-space: normal;
    width:      max-content;
    max-width:  220px;
    text-align: center;
    opacity:    0;
    visibility: hidden;
    pointer-events: auto;
    cursor:     pointer;
    transition: opacity .18s ease, visibility .18s ease, transform .18s ease;
    z-index:    20;
    box-shadow: var(--cod-shadow-md);
}

/* Pfeil zeigt nach UNTEN (FAB liegt unterhalb der Blase). */
.angebot-share-fab .partner-loc-tooltip::after {
    content:   "";
    position:  absolute;
    /* Rechts ausgerichtet wie partnerActionStack-Variante (~L441-444). */
    left:      auto;
    right:     16px;
    top:       100%;
    transform: translateX(0);
    border:    6px solid transparent;
    border-top-color: var(--cod-color-secondary, rgba(34,34,34,.96));
}

/* Unsichtbare Bruecke zwischen Blase und FAB (verhindert Hover-Verlust beim
   Wandern mit der Maus von der FAB in die Blase — identisch zu partner-card.css). */
.angebot-share-fab .partner-loc-tooltip::before {
    content:  "";
    position: absolute;
    left:     -6px;
    right:    -6px;
    top:      100%;
    height:   18px;
}

/* Tooltip sichtbar bei Hover/Focus auf der FAB. */
.cod-cta.secondary.angebot-share-fab:hover .partner-loc-tooltip,
.cod-cta.secondary.angebot-share-fab:focus-visible .partner-loc-tooltip,
.angebot-share-fab:hover .partner-loc-tooltip,
.angebot-share-fab:focus-visible .partner-loc-tooltip {
    opacity:    1;
    visibility: visible;
    transform:  translateX(0) translateY(-2px);
}

/* Titel — vollstaendige Token-Schicht (Schriftgroesse, Farbe, Decoration, States) */
.angebote-grid .angebot-card .cod-title,
.angebot-card .cod-title {
    font-family: var(--cod-font-card-title, var(--e-global-typography-dbdb71b-font-family, var(--e-global-typography-44ebb6b-font-family, system-ui, sans-serif)));
    /* Skalierung MUSS auch hier stehen: Diese Schicht kommt später in der Datei
       und gewinnt bei gleicher Spezifität gegen die Grundregel weiter oben.
       Das !important ist leider nötig - gemessen am 01.08.2026 setzen sowohl das
       Theme (Zeile 1850) als auch events.css (Zeile 241) ein
       ".cod-card .cod-title { font-size: 0.875rem !important }", das jede
       Angebote-Regel ohne !important schlägt. Der früher hier stehende
       767px-Media-Block hat nur deshalb gewirkt, weil er ebenfalls !important
       trug; ohne Ersatz fiel der Titel auf 14px zurück. */
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-font-card-title-size, var(--e-global-typography-dbdb71b-font-size, 1.05rem)) * var(--cod-card-ui-scale, 1))) !important;
    font-weight: var(--e-global-typography-dbdb71b-font-weight, 700);
    line-height: var(--e-global-typography-dbdb71b-line-height, 1.2);
    color: var(--cod-name-color, var(--cod-title-color, var(--cod-color-text, #4d4d4d)));
    background: var(--cod-name-bg, transparent);
    padding: var(--cod-name-pad, 0) !important;
    border: var(--cod-name-border-width, 0px) solid var(--cod-name-border-color, transparent);
    border-radius: var(--cod-name-border-radius, 0px);
    box-shadow: 0 var(--cod-name-shadow, 0px) var(--cod-name-shadow, 0px) var(--cod-name-shadow-color, var(--cod-shadow-color, rgba(31, 65, 102, .12)));
    opacity: var(--cod-name-opacity, 1);
    transition: all var(--cod-name-transition, 300ms) var(--cod-name-ease, ease);
    text-transform: var(--cod-name-text-transform, none);
}

.angebote-grid .angebot-card .cod-title:hover,
.angebot-card .cod-title:hover {
    color: var(--cod-name-hover-color, currentColor);
    background: var(--cod-name-hover-bg, var(--cod-name-bg, transparent));
    transform: translateY(var(--cod-name-hover-translate, 0px)) scale(var(--cod-name-hover-scale, 1));
    opacity: var(--cod-name-hover-opacity, 1);
}

.angebote-grid .angebot-card .cod-title:active,
.angebot-card .cod-title:active {
    color: var(--cod-name-active-color, currentColor);
    background: var(--cod-name-active-bg, var(--cod-name-bg, transparent));
    transform: translateY(var(--cod-name-active-translate, 0px)) scale(var(--cod-name-active-scale, 1));
    opacity: var(--cod-name-active-opacity, 1);
}

/* Location-Meta — vollstaendige Token-Schicht */
.angebot-location-meta {
    padding: var(--cod-location-pad, 0);
    background: var(--cod-location-bg, transparent);
    border: var(--cod-location-border-width, 0px) solid var(--cod-location-border-color, transparent);
    border-radius: var(--cod-location-border-radius, 0px);
    box-shadow: 0 var(--cod-location-shadow, 0px) var(--cod-location-shadow, 0px) var(--cod-shadow-color, rgba(31, 65, 102, .12));
    opacity: var(--cod-location-opacity, 1);
    transition: all var(--cod-location-transition, 300ms) var(--cod-location-ease, ease);
}

/* Diese Regel steht NACH den Grundregeln und gewinnt bei gleicher Spezifität -
   gemessen am 01.08.2026: Standort- und Entfernungszeile blieben bei 20px,
   obwohl die Grundregel oben bereits skaliert. Deshalb muss die Skalierung
   hier stehen, sonst ist sie wirkungslos. */
.angebot-location-name,
.angebot-distance-line,
.angebote-location-btn {
    font-family: var(--cod-font-card-location, inherit);
    font-size: max(var(--cod-card-min-font, 13px), calc(var(--cod-font-card-location-size, 13px) * var(--cod-card-ui-scale, 1)));
    color: var(--cod-location-color, var(--cod-meta, #5a7a99));
}

/* Entfernungs-/Standort-Link: eigene Schriftart via --cod-font-angebot-loclink
   (vom Elementor-Widget gesetzt); Fallback auf den Ort-Wert -> unveraenderte Optik. */
.angebote-location-btn {
    font-family: var(--cod-font-angebot-loclink, var(--cod-font-card-location, inherit));
}

.angebot-location-meta:hover {
    color: var(--cod-location-hover-color, currentColor);
    background: var(--cod-location-hover-bg, var(--cod-location-bg, transparent));
    transform: translateY(var(--cod-location-hover-translate, 0px)) scale(var(--cod-location-hover-scale, 1));
    opacity: var(--cod-location-hover-opacity, 1);
}

.angebot-location-meta:active {
    color: var(--cod-location-active-color, currentColor);
    background: var(--cod-location-active-bg, var(--cod-location-bg, transparent));
    transform: translateY(var(--cod-location-active-translate, 0px)) scale(var(--cod-location-active-scale, 1));
    opacity: var(--cod-location-active-opacity, 1);
}

/* ── Kategorie-Filter-Leiste (übergeordnet, zwischen Überschrift und Kacheln) ── */
/* Unten 32 statt 20 (07.08.2026): Gemessen sass die Leiste schief - oben 32 px
   zur Ueberschrift, unten nur 20 px zu den Karten. Der obere Abstand kommt von
   der Ueberschrift und laesst sich hier nicht setzen, also zieht der untere
   nach. Zwilling: Inline-CSS in cod-angebote-directory.php. */
.angebote-cat-filter{display:none;flex-wrap:wrap;justify-content:center;gap:8px;margin:0 0 32px 0}
.angebote-cat-filter.is-visible{display:flex}
.angebote-cat-btn{border-radius:var(--cod-pill-radius,999px);border:1px solid var(--cod-border,rgba(31,65,102,.15));padding:10px 16px;font-size:14px;font-weight:700;cursor:pointer;background:var(--cod-soft,#f2f6fa);color:var(--cod-title-color,#1f4166);box-shadow:none;transition:background .2s ease,transform .15s ease,box-shadow .15s ease;white-space:nowrap}
.angebote-cat-btn:hover,.angebote-cat-btn:focus{background:var(--cod-cta,#51B36F);color:#fff;transform:translateY(-1px)}
.angebote-cat-btn.active{background:var(--cod-cta,#51B36F);color:#fff;border-color:transparent;transform:translateY(-1px)}
@media (max-width:480px){.angebote-cat-btn{flex:1 1 calc(50% - 8px);text-align:center}}

/* ── Kategorie-Tag oben links im Bild + Fallback-Badge ohne Bild ── */
/* Lage, Polsterung und Deckel skalieren mit der Karte - wie beim Anbieter-Chip
   darunter und wie bei den Bild-Auflagen der Partner-Karte.
   Die Schrift-Untergrenze steht bei 9 px und nicht mehr bei 10: Bei 10 griff
   sie auf der 272er Karte (12 x 0,756 = 9,07) und machte das Etikett dort
   anteilig grösser als am Desktop - 72 gegen 68 Promille. */
.angebot-category-tag{position:absolute;top:calc(12px * var(--cod-card-ui-scale, 1));left:calc(12px * var(--cod-card-ui-scale, 1));z-index:3;display:inline-block;padding:calc(5px * var(--cod-card-ui-scale, 1)) calc(11px * var(--cod-card-ui-scale, 1));border-radius:999px;font-size:max(var(--cod-card-min-font, 13px), calc(12px * var(--cod-card-ui-scale, 1)));font-weight:700;line-height:1.2;background:var(--cod-chip-bg, rgba(0,0,0,.55));color:var(--cod-chip-color, #fff);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);max-width:calc(100% - 70px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.angebot-category-badge{display:inline-block;align-self:flex-start;margin:10px 16px 0 16px;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:700;line-height:1.2;background:var(--cod-soft,#eef4fa);color:var(--cod-title-color,#1f4166);border:1px solid var(--cod-border,rgba(31,65,102,.12))}

/* ── Produkt-Preiszeile ── */
.angebot-price-line{margin:2px 16px 4px;font-size:14px;font-weight:800;color:var(--cod-title-color,#1f4166)}
.angebot-price-line .angebot-price-member{font-weight:600;font-size:12.5px;color:var(--cod-meta,#5a7a99)}

/* ── Betreiber-Shop: Inline-Bestellformular ── */
.angebote-order-inline{margin:0 16px 14px;padding:14px;border:1px solid var(--cod-border,rgba(31,65,102,.15));border-radius:12px;background:var(--cod-soft,#f7fafc)}
.angebot-order-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.angebot-order-grid label{display:flex;flex-direction:column;gap:4px;font-size:13px;color:var(--cod-meta,#5a7a99)}
.angebot-order-grid label.full{grid-column:1 / -1}
.angebot-order-grid input,.angebot-order-grid select{padding:9px 10px;border:1px solid var(--cod-border,#d7dce2);border-radius:8px;font-size:14px;background:#fff;color:#1f2733}
.angebot-order-summary{margin:10px 0 2px;font-weight:800;font-size:14px;color:var(--cod-title-color,#1f4166)}
.angebot-order-vat{margin:0 0 8px;font-size:12px;color:var(--cod-meta,#5a7a99)}
.angebot-order-check{display:flex;gap:8px;align-items:flex-start;font-size:12.5px;color:var(--cod-meta,#5a7a99);margin:4px 0}
.angebot-order-check input{margin-top:2px}
.angebot-order-msg{margin:8px 0;padding:9px 12px;border-radius:8px;background:#fff1f2;color:#b42318;font-size:13px;font-weight:600}
.angebot-order-submit{margin-top:10px}
.angebot-order-btn.is-soldout{opacity:.55;cursor:not-allowed}
.angebot-order-hp{position:absolute;left:-9999px;opacity:0;height:0;width:0}
.angebot-order-banner{margin:0 0 16px;padding:12px 16px;border-radius:10px;background:#fff1f2;color:#b42318;font-weight:700}
.angebot-order-banner.is-ok{background:#e8f8ef;color:#166534}
@media (max-width:520px){.angebot-order-grid{grid-template-columns:1fr}}

/* ── Trefferflaechen fuer Touch (Bauplan, Abschnitt 8) ────────────────────────
   Mindestens 44x44px, ohne das sichtbare Element zu vergroessern: Die Flaeche
   entsteht ueber ein absolut positioniertes Pseudo-Element.

   min-width/min-height statt fester inset-Angabe - gemessen am 01.08.2026 misst
   dasselbe Symbol je nach Fensterbreite unterschiedlich viel (Knoepfe 124x40 bis
   167x40, Symbole 42x42, die Standort-Zeile nur 181x25). Ein starrer Wert traefe
   mal 44 und mal daneben; min-* rechnet immer bis auf die Vorgabe hoch.

   Waagerecht wird nichts aufgeweitet, wo Elemente nebeneinander stehen - sonst
   ueberlappen sich die Flaechen und der falsche Knopf reagiert. */
@media (pointer: coarse) {
    /* NIE pauschal position:relative setzen - wer schon absolut sitzt, wird
       dadurch aus seiner Verankerung gerissen. Genau das ist am 01.08.2026
       passiert: Die Teilen-Fläche ist absolut im Bild verankert
       (right:10px; bottom:10px). Mit position:relative wurden daraus
       Verschiebungen im Textfluss, und der Knopf stand 10 px LINKS ausserhalb
       der Karte, halb im Inhaltsbereich (gemessen: Knopf l 10 - r 52 bei einer
       Karte l 20 - r 316). Deshalb ist die Teilen-Fläche hier ausgenommen. */
    /* Der Standort-Knopf steht hier bewusst NICHT mehr mit drin (06.08.2026):
       Seine Fläche hängt jetzt an der Meta-Zeile, und dafür muss er selbst
       unpositioniert bleiben - sonst wäre ER der Bezugsrahmen und die beiden
       overflow:hidden darüber schnitten die Fläche wieder ab. Begründung
       vollständig weiter unten. */
    .cod-embed-angebote-wrap .cod-cta:not(.angebot-share-fab) {
        position: relative;
        /* z-index am ELEMENT, nicht nur am Pseudo-Element: Ohne eigenen
           Stapelplatz bleibt die aufgeweitete Fläche unter dem Nachbarn, der
           im Textfluss darüber steht. Gemessen: Der obere Prüfpunkt der
           Standort-Zeile landete auf .angebot-location-name. */
        z-index: 2;
    }

    /* Symbole: allseitig auf 44x44 aufrechnen (sie stehen frei).
       z-index über dem Inhaltsblock, der im Dokument nach dem Bild kommt -
       ohne ihn verschluckt er die Ränder der Fläche (Fehlerklasse D:
       44x44 gemessen, aber nur 2 von 5 Tippproben kamen an). */
    .cod-embed-angebote-wrap .angebot-share-fab::after {
        content: "";
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 100%;
        height: 100%;
        min-width: 44px;
        min-height: 44px;
        z-index: 2;
    }

    /* Trefferfläche des Standort-Knopfes.
       VORGESCHICHTE: Die Entfernungszeile kappt ihren Text mit overflow:hidden
       und beschnitt damit die Fläche des Knopfes darin auf 32 px. Die Abhilfe
       war, der Zeile auf Touch selbst 44 px Höhe zu geben - erst nur im
       Angebote-Bereich, seit dem 06.08.2026 auch im Partner-Panel, wo sie
       vorher ganz gefehlt hatte.

       Noch am selben Tag ZURÜCKGEBAUT, aus einem Grund, der
       mit Trefferflächen nichts zu tun hat: Die 44 px waren echte Layout-Höhe.
       mit Trefferflächen nichts zu tun hat: Die 44 px waren echte Layout-Höhe.
       Auf Touch war der Block unter dem Bild damit 22,7 px höher als mit der
       Maus, und weil die Karte 4:5 fest trägt, holte sich das Bild die
       Differenz. Gemessen an DERSELBEN Breite:
           768 px Touch   Bild 182,4   Bild/Karte 0,486
           768 px Maus    Bild 205,1   Bild/Karte 0,547
       Ein Finger-Ziel ist unsichtbar - es darf das sichtbare Verhältnis der
       Karte nicht verstellen. Die Fläche wird deshalb AUFGERECHNET statt
       reserviert, so wie es der Bauplan für kleine Ziele vorschreibt.

       Zwei Dinge daran sind teuer gemessen und dürfen nicht zurückgedreht
       werden:
         1. Die Fläche wächst nach OBEN (bottom: 0), nie mittig. Mittig
            aufgeweitet reicht sie in die Knopfreihe darunter, und die gewinnt
            mit ihrem z-index: 20 - abgetastet blieben dann 32 statt 44 px.
            Oberhalb liegt nur Text, den darf sie überlagern.
         2. Bezugsrahmen ist .angebot-location-meta, NICHT der Knopf. Zeile
            und Wert klemmen beide ihren Text ab; ein Kasten beschneidet eine
            absolut gesetzte Box aber nur, wenn er zwischen ihr und ihrem
            Bezugsrahmen liegt. Von der Meta-Zeile aus liegen beide darunter -
            Fläche kommt an, Ellipse bleibt erhalten. Der frühere Weg
            (Bezugsrahmen = Knopf) zwang dazu, beiden das overflow zu nehmen,
            und dann hatte "Entfernung 14 km von ..." keine drei Punkte mehr.
       Nicht an den Wrapper gebunden, damit es im aufgeklappten Partner-Panel
       genauso gilt - dort fehlte die Fläche vorher ganz. */
    .angebot-card .angebote-trigger-location::after {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 44px;
        z-index: 2;
    }

    /* Knöpfe: nur senkrecht aufweiten - waagerecht sind sie ohnehin breit
       genug und stehen teils nebeneinander.
       Die Standort-Zeile stand hier bis zum 06.08.2026 mit drin und ist
       herausgenommen: Diese Regel steht NACH ihrer eigenen und hätte sie
       stillschweigend wieder auf "mittig" zurückgedreht - genau die Fassung,
       die abgetastet nur 32 statt 44 px liefert, weil die Knopfreihe darunter
       die untere Hälfte an sich zieht. */
    .cod-embed-angebote-wrap .cod-cta:not(.angebot-share-fab)::after {
        content: "";
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 100%;
        height: 100%;
        min-height: 44px;
        z-index: 2;
    }
}

/* Breiten-Deckel (07.08.2026, Vorgabe des Betreibers: "Desktop geht mir
   das auch zu breit, 2 Zeilen darf es schon sein").
   Gemessen ohne Deckel: 1648 px bei 1920er Fenster - alle neun Knoepfe in
   EINER sehr breiten Zeile, waehrend die Karten darunter mittig und
   schmal stehen. Mit dem Deckel bricht die Reihe auf zwei Zeilen um und
   bleibt unter der Breite der Nachbar-Widgets (Partner 1696, Events 1900).
   Absolut angegeben, nicht in Prozent: In einem Flex-/Raster-Zusammenhang
   bezieht sich Prozent auf die Spalte, nicht auf den Container - diese
   Falle steht im Widget-Bauplan. */
.angebote-cat-filter{
  max-width:900px;
  margin-left:auto;
  margin-right:auto;
}

/* ── Kategorien-Aufklapper ────────────────────────────────────────────
   Zugeklappt ist nur "Alle N Kategorien" zu sehen. Der Zustand haengt an
   .is-collapsed am Rahmen und kommt schon so vom Server. */
.angebote-cat-filter.is-collapsed > .angebote-cat-btn:not(.angebote-cat-btn--toggle){display:none}
.angebote-cat-filter.is-collapsed .angebote-cat-btn--close{display:none}
.angebote-cat-filter:not(.is-collapsed) .angebote-cat-btn--open{display:none}
/* Weniger als zwei Kategorien: Zuklappen spart nichts, beide Knoepfe weg. */
.angebote-cat-filter.cod-cat-ohne-aufklapper > .angebote-cat-btn--toggle{display:none}

.angebote-cat-btn--toggle{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.45em;
}

/* Derselbe Pfeil wie in der Partner-Karte: das Zeichen "\203A", gedreht.
   Vergroessert ueber scale statt font-size - eine groessere Schrift
   wuerde die Zeilenhoehe und damit den ganzen Knopf wachsen lassen, und
   er stuende neben den anderen zu hoch. */
.angebote-cat-btn--toggle::after{
  content:"\203A";
  display:block;
  width:1em;
  height:1em;
  line-height:1;
  text-align:center;
  font-weight:900;
  transform:rotate(90deg) scale(1.6);
}
.angebote-cat-btn--close::after{transform:rotate(-90deg) scale(1.6)}

/* Der Knopf ist mit 43 px knapp unter der Mindestgroesse. Aufgerechnet
   ueber min-height statt ueber ein festes inset, damit es bei jeder
   Schriftgroesse stimmt. ::before, weil ::after den Pfeil traegt. */
@media (pointer: coarse){
  .angebote-cat-btn--toggle{position:relative}
  .angebote-cat-btn--toggle::before{
    content:"";
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%,-50%);
    width:100%;
    height:100%;
    min-width:44px;
    min-height:44px;
    z-index:0;
  }
}

/* Trefferflaeche 44 px auf Beruehrgeraeten. Die Knoepfe sind mit der Karte
   skaliert nur 33,5 px hoch - optisch gewollt, fuer den Finger zu wenig. Die
   Flaeche wird deshalb unsichtbar aufgeweitet, das Aussehen bleibt unveraendert.
   Uebernommen aus der Gewinnspiel-Karte, samt der dort teuer gelernten Regel:
   z-index gehoert ans ELEMENT, nicht nur ans Pseudo-Element - sonst bleibt die
   aufgeweitete Flaeche unter dem Nachbarn, der im Textfluss danach kommt. */
@media (pointer: coarse) {
  .angebot-card .cod-cta,
  .angebote-grid .cod-cta{position:relative;z-index:2}
  .angebot-card .cod-cta::after,
  .angebote-grid .cod-cta::after{
    content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
    width:100%;height:100%;min-height:44px;z-index:2}
}
