/* snapshot-overrides.css
 *
 * Targeted fixes for Webflow elements that don't behave correctly outside
 * Webflow's own hosting — typically because their visual state is driven by
 * ix2 scroll/hover interactions that occasionally desync in the snapshot.
 *
 * Loaded after cyreen-legacy.css so these rules win.
 */

/* ---------------------------------------------------------------------------
 * Case study detail pages
 * --------------------------------------------------------------------------- */

/* Case study detail sections (.section_advertising / .section_discount /
 * .section_ton-relevanz / etc.) are `display: flex` by default in
 * cyreen-legacy.css. That makes their child .div-block-575 a flex item that
 * shrinks to content width instead of filling — the visible "everything
 * cluttered on the left" symptom. Force vertical stack layout.
 *
 * Excludes `.press-release` because /de/pressemitteilung relies on
 * `.section_advertising.padding-global` being `display: flex` for its
 * two press-list columns to sit side-by-side. */
section[class*='section_'][class*='advertising']:not(.press-release),
section[class*='section_'][class*='discount']:not(.press-release),
section[class*='section_'][class*='ton-relevanz']:not(.press-release),
section[class*='section_'][class*='kontakte']:not(.press-release),
section[class*='section_'][class*='wetter']:not(.press-release),
section[class*='section_'][class*='zeit']:not(.press-release),
section[class*='section_'][class*='langzeit']:not(.press-release),
section[class*='section_'][class*='a-b']:not(.press-release),
section.section_advertising:not(.press-release),
section.section_discount:not(.press-release) {
  display: block !important;
}

/* `.div-block-575` is the centered max-1200px wrapper; force full width so
 * it actually centers visibly. */
.div-block-575 {
  width: 100% !important;
  max-width: 1200px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* `.div-block-573` is the main content area inside .div-block-575. */
.div-block-573 {
  width: 100%;
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}

/* `.text-block-134` is the sticky "⭠ ZURÜCK" button.
 *
 * The real bug: cyreen-legacy.css sets
 *     .text-block-134:hover { margin-left: 75px; }
 * combined with `transition: all .2s` — so on hover the element slides 75px
 * to the right. The cursor, parked at the left edge, then sits OUTSIDE the
 * element → hover ends → it slides back → cursor now over it → hover starts
 * → infinite flicker.
 *
 * Kill both the hover slide and the base transition. Also force a stable
 * visible state in case ix2 (Webflow's interaction engine) initialises it
 * at opacity:0 and never fires the fade-in. */
.text-block-134 {
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
  transition: none !important;
}
.text-block-134:hover {
  margin-left: 0 !important; /* cancel the 75px slide that causes the flicker */
  transform: none !important;
}

/* Toolbar thread YLEqm0uHhuSJ: the "⭠ ZURÜCK" link (.link-23) renders as a
 * filled maroon pill (background + border-radius:999px + padding) — a "box"
 * that should not be there. Restore the plain text link. */
.link-23,
.link-23:hover {
  background-color: transparent !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  border-radius: 0 !important;
}

/* Toolbar thread u2UV13uHdERN: add breathing room below the back link so it
 * does not collide with the Zusammenfassung block on the case-study pages. */
.text-block-134 {
  margin-bottom: 1.5rem !important;
}

/* ---------------------------------------------------------------------------
 * In-store retail media — partner logo row
 * --------------------------------------------------------------------------- */

/* Toolbar thread lFArRq7I9fbc: the four logos sat in a Webflow grid with
 * per-logo grid-area placement plus 3 empty cells, so the visible spacing
 * came out lopsided. On desktop, lay them out in four equal columns with each
 * logo centred in its slot (kept to >=992px so the Webflow mobile/tablet
 * stacking is untouched). NOTE: a small residual offset remains on logos whose
 * source PNG carries asymmetric transparent padding — that needs an asset
 * re-export, not CSS. */
@media screen and (min-width: 992px) {
  .section_case-studies .div-block-554 {
    display: grid !important;
    grid-template-columns: repeat(4, 1fr) !important;
    justify-items: center !important;
    align-items: center !important;
    gap: 24px;
  }
  .section_case-studies .div-block-554 > *:not(.link-block-29) {
    display: none !important;
  }
  .section_case-studies .div-block-554 > .link-block-29 {
    grid-column: auto !important;
    grid-row: auto !important;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
  }
}

/* ---------------------------------------------------------------------------
 * C.A.P. data-cycle (.scroll-track) — make the bullet texts visible
 * --------------------------------------------------------------------------- */

/* Toolbar thread CrSiQd1eXuHf: the four data-cycle bullets (Datenerfassung,
 * Datenanalyse, Datenmuster, Datentargeting) start at opacity:0 + translateY
 * (the intended reveal), but Webflow's IX2 holds them at opacity:0 forever and
 * never animates them in, so the text is invisible. A small script on the
 * c-a-p page adds `.cyr-reveal` to each bullet in turn once the section scrolls
 * into view; the `!important` here beats IX2's inline opacity, and the base
 * transition makes it a fade + slide-up. */
.cap-optimization_text-1,
.cap-optimization_text-2,
.cap-optimization_text-3,
.cap-optimization_text-4 {
  transition:
    opacity 0.6s ease,
    transform 0.6s ease;
}
.cap-optimization_text-1.cyr-reveal,
.cap-optimization_text-2.cyr-reveal,
.cap-optimization_text-3.cyr-reveal,
.cap-optimization_text-4.cyr-reveal {
  opacity: 1 !important;
  transform: none !important;
}
.cap-optimization_redline {
  height: 100% !important;
}

/* Reduced-motion: show everything at once, no animation. */
@media (prefers-reduced-motion: reduce) {
  .cap-optimization_text-1,
  .cap-optimization_text-2,
  .cap-optimization_text-3,
  .cap-optimization_text-4 {
    opacity: 1 !important;
    transform: none !important;
  }
  .cap-optimization_redline {
    height: 100% !important;
  }
}

/* ---------------------------------------------------------------------------
 * Case-studies-2 — "für FMCG Marken" / "für Wissenschaftler" boxes
 * --------------------------------------------------------------------------- */

/* Toolbar threads 5LPmTjfKtuBv / O-9UBUDvHBod: the two boxes were clustered in
 * the centre. Spread them so each sits more centrally in its half of the page,
 * and centre the heading + the call-to-action button in each box. */
.div-block-595 {
  width: 100% !important;
  max-width: 1040px;
  margin-left: auto;
  margin-right: auto;
  justify-content: space-around !important;
}
.div-block-264,
.div-block-269 {
  text-align: center !important;
  align-items: center !important;
}

/* ---------------------------------------------------------------------------
 * Case-studies-2 slider — align title + logo with the paragraph
 * --------------------------------------------------------------------------- */

/* Toolbar threads fYjcpM8Yo_PT / PvTn3-vcJkwc / pOfH567fcNnh: in the case-study
 * slider each slide's title + logo sat in a full-width floated column with
 * centred content, so they did not line up with the paragraph below and
 * landed differently per slide. Force every slide column (title AND
 * paragraph) to the same centred 707 px block so the whole slide stacks
 * vertically the same way on DE and EN.
 *
 * DE case-studies-2 columns: .columns-213 (title) + .column-234 (paragraph).
 * EN case-studies columns:   .columns-204 (title) + .column-134 (paragraph).
 *
 * All four get the same treatment. Without applying to both columns of a
 * row the second col floats next to the first and the slide reads as a
 * two-column layout instead of a stack. */
.cs-slide .columns-213,
.cs-slide .column-234,
.cs-slide .columns-204,
.cs-slide .column-134 {
  float: none !important;
  width: 707px !important;
  max-width: 100%;
  margin-left: auto !important;
  margin-right: auto !important;
  padding-left: 0 !important;
  justify-content: flex-start !important;
}

/* ---------------------------------------------------------------------------
 * Two-column section grids — align the right description with the heading
 * --------------------------------------------------------------------------- */

/* Toolbar threads SwEkBPoMOcn_ / a-umN8FuHHiI / TppFGWxnOOie (Davide's
 * reference image): in the topline + heading / description sections the
 * right-hand description should line up with the <h2> heading, NOT with the
 * small red topline above it. The grid top-aligns both columns at the topline,
 * so push the description down by the topline's footprint (24px height + 4px
 * gap) to sit level with the heading. Desktop only — on mobile the columns
 * stack. :has(.topline) leaves topline-less grids untouched. */
@media screen and (min-width: 992px) {
  .basic-grid:has(.topline) > .content-wrap:nth-child(2) {
    margin-top: 28px;
  }
}

/* ---------------------------------------------------------------------------
 * CAP Explorer — section toplines
 * --------------------------------------------------------------------------- */

/* Toolbar thread MeyDfmdREq0u: the section toplines (the small eyebrow over
 * each heading, e.g. "KAMPAGNEN-MANAGEMENT") render dark grey under the
 * active-grey-black section theme, but they should be brand red like the rest
 * of the site. Restore the red. */
.section_campaigns .topline,
.section_infrastructure .topline,
.section_retail .topline {
  color: var(--brand_colors--red_active) !important;
}

/* ---------------------------------------------------------------------------
 * C.A.P. CTA section background (de/c-a-p, en/c-a-p, en/home)
 * --------------------------------------------------------------------------- */

/* Toolbar thread CDYN6EJvwHm4: swap the old "Gemüse" stock photo for the new
 * C.A.P. Screen image, and self-host it (it used to hot-link the Webflow CDN).
 * Show the required image credit subtly in the corner. */
.section_cta-cap {
  background-image: url('/cap-screen-kaese.jpg') !important;
  position: relative;
}
.cap-image-credit {
  position: absolute;
  right: 0.75rem;
  bottom: 0.5rem;
  z-index: 2;
  font-size: 0.6rem;
  line-height: 1.2;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.75);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * Footer (every page)
 * --------------------------------------------------------------------------- */

/* Toolbar thread gSleTT18WEvq: the Kontakt + Social links sit in <li> items
 * that pick up 1.25rem (20px), but the address <p class="footer_address">
 * is 1rem (16px) — so the address looks smaller than the other two columns.
 * Webflow already drops BOTH to .9rem at max-width:479px, so they only
 * diverge above that. Bump the address to 1.25rem above 479px to match;
 * below it Webflow's own .9rem rule keeps them equal. */
@media screen and (min-width: 480px) {
  .footer_address {
    font-size: 1.25rem;
    line-height: 1.5;
  }
}

/* ---------------------------------------------------------------------------
 * General — neutralise ix2 initial-state hides on elements that have a
 * `data-w-id` but never actually animate visible. Keeps content readable on
 * the rare page where Webflow's interactions JS doesn't run as expected.
 * --------------------------------------------------------------------------- */
[data-w-id]:not(.lottie-animation-2):not(.lottie-animation-4):not(.lottie-animation-5):not(
    .lottie-animation-6
  ):not(.lottie-animation-7):not(.lottie-animation-9):not(.lottie-animation-10):not(
    .lottie-animation-14
  ) {
  /* Don't force here — let Webflow's ix2 win normally. But ensure
   * nothing is permanently hidden if the interaction JS fails to fire. */
}

/* ---------------------------------------------------------------------------
 * Homepage team grid — black & white portraits per Davide's feedback.
 * No hover colour restore — Davide explicitly wants them to stay b&w.
 *
 * Plus one targeted fix for Werner's portrait: his source photo has more
 * whitespace above the head than the others, so the Webflow default
 * object-fit: fill renders the whitespace as a visible white edge.
 * Switch to object-fit: cover (anchored to the head area) so all four
 * portraits crop the same way. The card variant (.div-block-583-special)
 * already provides the light-grey card background + correct role text
 * styling for the dark section context — no other overrides needed.
 * --------------------------------------------------------------------------- */
.section_home-team .image-84 {
  filter: grayscale(1) contrast(1.02);
  object-fit: cover;
  object-position: center top;
}
/* Founder cards: the portrait was a fixed 250px in normal flow, so when the
 * grid stretched a row taller (e.g. a 2-line role in one language made the
 * tallest card, EN especially) a shorter card like Benedict's left a grey gap
 * BELOW the photo. Make the card a flex column and let the portrait grow to the
 * card bottom, so the photo always fills the card regardless of role length or
 * language. object-fit: cover keeps the framing. */
.section_home-team .div-block-583-special {
  display: flex;
  flex-direction: column;
}
.section_home-team .image-84 {
  flex: 1 0 250px;
  min-height: 250px;
}
/* Hotspot-aware crops are now delivered by the Sanity CDN at the right
   size + face-centred via imageUrl(... { width, height }) — see
   src/lib/sanity.ts and the components in src/components/sanity/.
   That removes the need for per-portrait CSS scale tricks, because the
   image already arrives correctly framed. Marketing can fine-tune each
   face by adjusting the hotspot in Studio. */

/* ---------------------------------------------------------------------------
 * Case study detail pages — 'Zurück' button positioning.
 * It was previously pinned (sticky) to the top, but toolbar thread
 * k1_tBmLCgD3Q asks for the opposite: the back arrow should scroll along with
 * the content, not stay stuck at the top. Make it static. (The pill/box on
 * .link-23 is intentionally gone too — thread YLEqm0uHhuSJ wants a plain text
 * link, handled above.)
 * --------------------------------------------------------------------------- */
.text-block-134 {
  position: static !important;
  margin-top: 1.5rem !important;
  width: max-content;
}

/* ---------------------------------------------------------------------------
 * Legal pages (/agb-media, /datenschutz, /imprint) — H2 word spacing.
 * Davide noted the headings on /agb-media render with words too tightly
 * packed. Open it up for readability across all .w-richtext legal blocks.
 * --------------------------------------------------------------------------- */
.rich-text-datenschutz h2,
.rich-text-datenschutz h3 {
  word-spacing: 0.12em;
  letter-spacing: 0.005em;
}
.rich-text-datenschutz h2 {
  margin-top: 2.25rem;
  margin-bottom: 0.75rem;
  line-height: 1.3;
}

/* ---------------------------------------------------------------------------
 * Generic IX2 fallback: any [data-w-id] that Webflow's runtime left at
 * opacity:0 should still fade in when the user scrolls past it. Pure CSS
 * fallback via the .cyr-revealed class added by Navbar.astro's catch-all
 * IntersectionObserver below.
 * --------------------------------------------------------------------------- */
[data-w-id].cyr-revealed {
  opacity: 1 !important;
  transform: none !important;
  transition:
    opacity 0.6s ease,
    transform 0.6s ease;
}

/* ---------------------------------------------------------------------------
 * Big-data 'Conversion Rates' graph on the homepage — turn the two static
 * 2.25rem-tall labels into actual bars whose heights show the 375 % delta
 * (Ohne C.A.P. 0.20% vs Mit C.A.P. 0.75%). Webflow IX2 was supposed to
 * animate this; we re-implement with CSS that fires when JS adds the
 * .cyr-graph-animated class on the .graph parent (Navbar.astro IO below).
 * --------------------------------------------------------------------------- */
.graph .graph-1,
.graph .graph-2 {
  transition:
    height 1.2s cubic-bezier(0.45, 0.05, 0.55, 0.95),
    background-color 0.4s ease;
}
.graph.cyr-graph-animated .graph-1 {
  height: 5rem !important; /* 0.20% baseline */
}
.graph.cyr-graph-animated .graph-2 {
  height: 16rem !important; /* 0.75% — visually ~3.2× taller; works within the 25rem .graph container */
}

/* ---------------------------------------------------------------------------
 * Homepage testimonials — Xiaotong feedback: round logo and blockquote
 * sit too close together. Add breathing room.
 * --------------------------------------------------------------------------- */
.section_home-testimonials .div-block-226-1 blockquote {
  margin-top: 1.25rem;
}
.section_home-testimonials .div-block-226-1 {
  gap: 1rem;
}

/* ---------------------------------------------------------------------------
 * Homepage references — ensure the marquee CSS animation runs even when
 * Webflow IX2 doesn't trigger it. The .references_logos-moving-right and
 * .references_logos-moving-left elements are pre-set up as marquees but
 * sometimes start paused on static export.
 * --------------------------------------------------------------------------- */
.references_logos-moving-right,
.references_logos-moving-left {
  animation-play-state: running !important;
}
@keyframes references-marquee-right {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}
@keyframes references-marquee-left {
  from {
    transform: translateX(-50%);
  }
  to {
    transform: translateX(0);
  }
}
.references_logos-moving-right {
  animation: references-marquee-right 60s linear infinite;
}
.references_logos-moving-left {
  animation: references-marquee-left 60s linear infinite;
}

/* ---------------------------------------------------------------------------
 * Homepage testimonials slider — working prev/next navigation.
 *
 * Webflow's native w-slider for .section_home-testimonials does not initialise
 * correctly in the snapshot: all five quote slides end up stacked at
 * translateX(0) with a single nav dot, and neither arrow advances. A small
 * script on en/home (see en/home.astro) takes the slider over once the page has
 * loaded: it strips Webflow's dead handlers, rebuilds one dot per slide, and
 * wires both arrows to step prev/next with wrap-around. These rules drive the
 * visible state only after that script adds `.cyr-carousel-ready`, so the DE
 * home (no script yet) and any other snapshot are left untouched.
 * --------------------------------------------------------------------------- */
/* These rules are keyed on `.cyr-carousel-ready` (added by
 * public/testimonials-carousel.js to each taken-over slider section), so they
 * cover ALL sliders the script drives: the home testimonials (DE + EN), the
 * /de/c-a-p .section_cap-testimonials, and the retail .section_benefits. Pages
 * without the script keep Webflow's untouched markup. */
/* Fixed-height carousel: stack every slide absolutely inside the mask and
 * cross-fade between them, so the mask keeps ONE constant height across all
 * slides. The script sets that height (= tallest slide) via inline style, and
 * re-measures on resize. This stops the arrows from jumping and the section (and
 * everything below it) from reflowing when the slide changes. */
.cyr-carousel-ready .w-slider-mask {
  display: grid !important;
}
.cyr-carousel-ready .w-slide {
  grid-area: 1 / 1 / 2 / 2; /* stack every slide in one grid cell so the mask auto-sizes to the TALLEST slide -> constant height, no reflow */
  display: flex;
  flex-direction: column;
  justify-content: center; /* centre each slide's content in the (tallest-slide) cell so the prev/next arrows line up with the logo, not the empty space below it (thread bW1eadPGfEE9) */
  width: 100%;
  opacity: 0 !important;
  visibility: hidden !important;
  transition: opacity 0.35s ease;
}
.cyr-carousel-ready .w-slide.cyr-slide-active {
  opacity: 1 !important;
  visibility: visible !important;
}
@media (prefers-reduced-motion: reduce) {
  .cyr-carousel-ready .w-slide {
    transition: none;
  }
}
/* Centre the logo in its full-height column so the prev/next arrows (which sit
 * at the slide's vertical centre) line up with the logo on every slide,
 * regardless of logo height. Home testimonials only (thread bW1eadPGfEE9). */
.cyr-carousel-ready .slider_slide-logo-wrapper {
  align-self: center; /* centre the (shorter) logo column within the grid row, which is sized by the taller quote column */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Hide Webflow's font-icon glyph and draw a clean chevron on each arrow, so the
 * left arrow is exactly as visible as the right and both stay symmetric. */
.cyr-carousel-ready .w-icon-slider-left,
.cyr-carousel-ready .w-icon-slider-right {
  display: none !important;
}
.cyr-carousel-ready .w-slider-arrow-left,
.cyr-carousel-ready .w-slider-arrow-right {
  display: flex !important; /* always visible: the navigation + swipe affordance, mobile AND desktop, on every carousel */
  align-items: center; /* vertically centre the chevron */
  justify-content: center;
  overflow: visible; /* cancel webflow.css overflow:hidden that clipped the rotated chevron's corner */
  cursor: pointer;
  z-index: 2;
  /* Sit in a bottom control band, flanking the dot row (‹ ••• ›), so the arrows
   * never overlap the full-width quote text ("Pfeile im Text") and every
   * carousel looks identical. Positioned from the slider centre so the layout is
   * independent of slide/section width. */
  top: auto;
  bottom: 0;
  left: 50%;
  right: auto;
  width: 2.5rem;
  height: 2.75rem;
}
.cyr-carousel-ready .w-slider-arrow-left {
  margin-left: -6rem; /* left of the centred dots */
}
.cyr-carousel-ready .w-slider-arrow-right {
  margin-left: 3.5rem; /* right of the centred dots */
}
.cyr-carousel-ready .w-slider-arrow-left::after,
.cyr-carousel-ready .w-slider-arrow-right::after {
  content: '';
  width: 16px;
  height: 16px;
  border: solid var(--brand_colors--red_active, #f04b55);
  border-width: 0;
}
.cyr-carousel-ready .w-slider-arrow-left::after {
  border-bottom-width: 3px;
  border-left-width: 3px;
  transform: rotate(45deg); /* chevron pointing left */
}
.cyr-carousel-ready .w-slider-arrow-right::after {
  border-top-width: 3px;
  border-right-width: 3px;
  transform: rotate(45deg); /* chevron pointing right */
}
/* Uniform control band at the bottom of every taken-over carousel: reserve space
 * below the slides so the dot row + arrows sit BELOW the quote (never over it)
 * and every carousel is identical (thread: "alle Carousels gleich" + "Indikator
 * dass man swipen kann"). Replaces the old per-carousel dot offsets and the
 * mobile arrow-hide. */
.cyr-carousel-ready .w-slider {
  padding-bottom: 3.25rem;
}
.cyr-carousel-ready .w-slider-nav {
  display: flex !important; /* centre the dots; also reveals the retail (.section_benefits) dots that base Webflow CSS hid */
  align-items: center;
  justify-content: center;
  top: auto;
  bottom: 0;
  height: 2.75rem;
  padding: 0;
}

/* ---------------------------------------------------------------------------
 * /de/c-a-p — Coca-Cola bottle drop (toolbar thread kiz4_VbjjBM2).
 * The `.bottle` img in .section_contact-quality should drop DOWN through the
 * funnel and out the bottom spout on scroll (the original Webflow IX2 effect,
 * which never fires here). Earlier threads (HnDiwEldlIij + PPKW1v_myEvb) asked
 * to remove the bottle only because it sat statically at the TOP; a real
 * scroll-triggered drop satisfies both — it is no longer a static stray.
 *
 * This is only the REST state (above the funnel mouth, hidden). The drop itself
 * is run by the Web Animations API from the script on c-a-p.astro: a leftover
 * Webflow IX2 transition on this element overrode CSS classes AND inline
 * !important, so a WAAPI animation (which composites independently of the
 * cascade, fill:forwards) is the reliable way to move it. Reduced-motion rests
 * it at the spout with no motion.
 * --------------------------------------------------------------------------- */
/* `.bottle` (exact class) exists only on /de/c-a-p + /en/c-a-p, so this is not
 * section-scoped — it must cover both, where the funnel section is named
 * differently (DE section_contact-quality, EN section-36). The retail pages use
 * a different class (.image-bottle-screen) and are untouched. */
.bottle {
  display: block;
  opacity: 0;
  transform: translateY(-110px); /* rest: above the funnel mouth — tuned live */
  will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
  .bottle {
    opacity: 1;
    transform: translateY(240px); /* rest at the spout, no motion */
  }
}

/* ---------------------------------------------------------------------------
 * /de/handel/in-store-retail-media — "Conversion Rates" chart percentages
 * (toolbar thread MmwKq_-7pUBU: "here there is no percentage"). The bar labels
 * (197%, +13%, +17%, +20%) are IX2 elements that start at opacity:0 and rely on
 * a scroll animation that does not fire reliably in the snapshot, so the numbers
 * stay invisible. Force them visible (same approach as the homepage graph fix).
 * --------------------------------------------------------------------------- */
.case-studies_chart-wrapper .mid-precent-2,
.case-studies_chart-wrapper .handel {
  opacity: 1 !important;
  transform: none !important;
}

/* ---------------------------------------------------------------------------
 * /de/c-a-p — optimization icon grid hover (toolbar thread HxtR8Hshxut9).
 * Lift + slight scale the six icons on hover; reduced-motion stays static.
 * Same selectors exist on en/c-a-p, so one block covers both.
 * --------------------------------------------------------------------------- */
.optimization_grid-icon {
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.optimization_grid-item:hover .optimization_grid-icon {
  transform: translateY(-6px) scale(1.08);
}
@media (prefers-reduced-motion: reduce) {
  .optimization_grid-icon {
    transition: none;
  }
  .optimization_grid-item:hover .optimization_grid-icon {
    transform: none;
  }
}

/* ---------------------------------------------------------------------------
 * Home big-data graph (toolbar thread UGk4E4CbAX2N).
 * Reuse the SAME arrow as the /c-a-p "Optimierung" chart for consistency:
 * .counting-arrow is a square box with a red top+left border and
 * border-top-left-radius:100% (a clean quarter-circle arc), plus the
 * .optimization_chart-arrowhead chevron at its top-right. The prior override
 * squashed it into a tall rectangle, distorting the arc; keep it SQUARE here.
 * The "x375%" number sits above the arc at the chart-number size (1.5rem).
 * --------------------------------------------------------------------------- */
.section_big-data .graph .counting {
  top: auto;
  bottom: 60%;
  left: 14%;
  font-size: 1.5rem;
}
.section_big-data .graph .counting-arrow {
  border-top-left-radius: 100%;
  width: 3.5rem;
  height: 3.5rem;
  top: auto;
  bottom: 38%;
  left: 15%;
}
.section_big-data .graph .graph-1 .graph-text-bottom {
  top: 0.8rem;
}

/* ---------------------------------------------------------------------------
 * Case-study pages — metadata line spacing (toolbar thread FZlujjbbNqr6).
 * The 4-line <br> metadata blocks use line-height 14px on 14px text (ratio 1),
 * so the lines touch. Open the leading (unitless, so it also scales at the
 * 10px mobile size). These four classes appear only on case-study pages, DE+EN.
 * --------------------------------------------------------------------------- */
.paragraph-27,
.paragraph-28,
.paragraph-29,
.paragraph-30 {
  line-height: 1.7;
}

/* ---------------------------------------------------------------------------
 * .section_cta-cap background crop (toolbar thread VGCTNGC_28PA).
 * The fixed screen-photo was centre-cropped (background-position 50% +
 * attachment fixed), so the C.A.P. screen (upper-left of the photo) was cut off
 * and shifted while scrolling. Anchor the crop to the element and raise it so
 * the screen stays in view. Applies to the CTA on en/home, the newly ported DE
 * home CTA, and /de/c-a-p + /en/c-a-p (same section, kept consistent).
 * --------------------------------------------------------------------------- */
.section_cta-cap {
  /* Parallax scroll (fixed attachment) per Davide's request. The band is tall so
   * the C.A.P. screen (upper-right in the new photos) stays in frame across the
   * scroll. Threads VGCTNGC_28PA, svmoE2b4CRNi, 9zUdjK30UmQs. */
  background-attachment: fixed !important;
  background-size: cover !important;
  background-position: 50% 16% !important;
  padding-top: 6.5rem !important;
  padding-bottom: 6.5rem !important;
}
/* Per-page CTA photo (threads Veiv05eG_Kei home / mVjRaj_6kg9- c-a-p). Each CTA
 * shows its own C.A.P.-screen store photo instead of the shared one. In both new
 * photos the screen sits in the upper-right, so the crop is shifted right. */
.section_cta-cap.cta-photo-putzmittel {
  background-image: url('/cap-screen-putzmittel.jpg') !important;
  background-position: 72% 22% !important;
}
.section_cta-cap.cta-photo-sommergetraenk {
  background-image: url('/cap-screen-sommergetraenk.jpg') !important;
  background-position: 76% 14% !important;
}
/* Home CTA card: more transparent so the store photo shows through, matching the
 * /de/c-a-p card look, but kept centred (thread Veiv05eG_Kei). */
.cta-photo-putzmittel .cta_contact-card {
  background-color: rgba(255, 255, 255, 0.72) !important;
}

/* ---------------------------------------------------------------------------
 * Team office map — desaturate the OpenStreetMap tiles to a monochrome look that
 * matches Cyreen's black/white CI (toolbar thread iNAjTGb1pnAo). Filter the
 * whole tile pane rather than each tile so there are no seams between tiles.
 * Applies on /de/team and /en/team (both use the same Leaflet container).
 * --------------------------------------------------------------------------- */
.leaflet-tile-pane {
  filter: grayscale(1) contrast(1.05) brightness(1.03);
}
/* Leaflet's default container background is a mid grey (#ddd) that shows as a
 * visible strip wherever tiles have not yet reached. Use a near-white tone that
 * matches the desaturated map so any uncovered sliver blends in; the JS also
 * calls invalidateSize() so tiles fill the container in the first place. */
.leaflet-container {
  background: #f0f0f0;
}
/* The default Leaflet marker is blue, which fights the monochrome map. Shift it
 * to Cyreen red so the pin reads as brand colour against the grey tiles. */
.leaflet-marker-pane img {
  filter: hue-rotate(140deg) saturate(1.4) brightness(0.95);
}

/* ---------------------------------------------------------------------------
 * Rounded corners (Cyreen CI). The CTA contact card and the home big-data card
 * already use 24px; bring every other content card and the form fields up to the
 * same radius so the whole site is consistent (Davide). Full-bleed sections, the
 * map, pill buttons, the round testimonial logo and chart bars stay square.
 * --------------------------------------------------------------------------- */
/* Team + advisory cards. overflow:hidden clips the edge-to-edge portrait
 * (.image-84 / .image-advisor) to the rounded corner so no square corner shows. */
.div-block-583-special,
.card-front {
  border-radius: 24px;
  overflow: hidden;
}
/* The advisory flip card's outer container (.card-advisor) has a dark background
 * with square corners that show behind the rounded front. Round it too (thread
 * KYSJ9FNryq4m). No overflow:hidden here, that would clip the 3D flip. */
.card-advisor {
  border-radius: 24px;
}
/* Case-study cards: maroon summary + info bands and the grey chart panel (the
 * panel class differs per case study, hence several). */
.div-block-315,
.div-block-311,
.div-block-316,
.div-block-108,
/* Case-studies overview tiles + grey box */
.div-block-64,
.div-block-651,
/* /de/c-a-p optimization description box */
.optimization_chart-decription {
  border-radius: 24px;
}
/* Case-study visual images: round the two top corners so each visual reads with
 * a soft top edge like the rest of the CI, bottom kept square (thread
 * joYrjgKycWGE). The image sits edge-to-edge at the top of its panel, so 24px
 * lines up with the panel corner. */
.div-block-108 .w-embed img,
.div-block-314 .w-embed img {
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
}
/* div-block-108 is already a rounded card; div-block-314 was square, so round
 * its top to match the image and avoid a square nub behind the rounded corner. */
.div-block-314 {
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
}
/* Contact-form fields: a lighter radius so a short field does not read as a pill. */
.w-input {
  border-radius: 12px;
}
/* Conversion-rate bars: round the two top corners to match the card radius, so
 * the bars read as part of the rounded CI (thread Ta7xcRlyTr_r). Bars grow from
 * the baseline, so only the top is rounded. */
/* Home big-data card bars keep the full 24px (Davide liked that card). */
.big-data_card-right .graph-1,
.big-data_card-right .graph-2 {
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
}
/* Case-study CR chart bars: dialed back ~20% (24px -> 19px) so the rounding reads
 * softer. Top corners only, the rest of each bar is unchanged. Covers every
 * case-study CR chart bar (thread 00CeCJKSB4Ru). */
.div-block-163,
.div-block-167,
.div-block-169,
.div-block-318,
.div-block-319 {
  border-top-left-radius: 19px;
  border-top-right-radius: 19px;
}
/* Case-study chart tooltips (thread 00CeCJKSB4Ru). Each bar group becomes
 * focusable + hoverable; a small dark card explains the two bars and the uplift.
 * Behaviour is wired up by /case-study-tooltips.js, which reads the values and
 * range label already in the DOM. */
.cap-chart-group {
  cursor: help;
  outline: none;
}
.cap-chart-group:focus-visible {
  outline: 2px solid #f04b55;
  outline-offset: 3px;
  border-radius: 6px;
}
.cap-chart-tooltip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 9999;
  box-sizing: border-box;
  width: max-content;
  max-width: 260px;
  padding: 12px 14px;
  border-radius: 12px;
  background: #1c1c1c;
  color: #fff;
  font-family: 'Graphik 400', sans-serif;
  font-size: 13px;
  line-height: 1.45;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease;
}
.cap-chart-tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.cap-chart-tooltip strong {
  display: block;
  margin-bottom: 4px;
  color: #f04b55;
  font-size: 14px;
  font-weight: 600;
}
.cap-chart-tooltip span {
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  .cap-chart-tooltip {
    transition: none;
    transform: none;
  }
}
/* Tiles that carry a C.A.P. pattern or icon must clip it to the rounded corner:
 * the case-studies-2 tiles (.div-block-64, thread EDzZf4bf7XWR) and the "weitere
 * Cases" navigation tiles on the case-study pages (.div-block-444, thread
 * CeZGUX7tr4Nh). The latter were still square. */
.div-block-64,
.div-block-444 {
  border-radius: 24px;
  overflow: hidden;
}
/* Case-study "weitere Cases" slider (.slider-5) tweaks. */
/* Arrows: the button spans the full slider height, so the icon centres on empty
 * space below the tiles. Lift it so it sits level with the tile block (thread
 * GMgmYjPmzPbP). Applies on every case-study page. */
.slider-5 .w-slider-arrow-left,
.slider-5 .w-slider-arrow-right {
  bottom: 98px;
}
/* Gap between the icon tile and its text: the tile sits left-aligned in a
 * half-width column, leaving a wide gap. Make the entry a flex row so the tile
 * column shrinks to the tile and the text takes the rest (thread ebOB0XoRO_V5). */
.slider-5 .columns-80 {
  display: flex;
  align-items: center;
}
.slider-5 .columns-80 > .w-col:first-child {
  flex: 0 0 auto;
  width: auto;
}
.slider-5 .columns-80 > .w-col:last-child {
  flex: 1;
  min-width: 0;
}

/* Team and advisory cards lift slightly on hover for a bit of interactivity
 * (Davide, thread UDwwBg0LBAVq). The lift shadow sits outside the box so
 * overflow:hidden does not clip it. */
.div-block-583-special,
.card-advisor {
  transition:
    transform 0.25s ease,
    box-shadow 0.25s ease;
}
.div-block-583-special:hover,
.card-advisor:hover {
  transform: translateY(-6px);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.3);
}
@media (prefers-reduced-motion: reduce) {
  .div-block-583-special,
  .card-advisor {
    transition: none;
  }
  .div-block-583-special:hover,
  .card-advisor:hover {
    transform: none;
  }
}

/* Home big-data card body text. Justifying it (thread dXl2CQ8Mundm) stretched
 * the words into wide rivers of whitespace on this narrow column, so it is back
 * to left-aligned for even word spacing (thread swWLfbVM3NGn, "zu viel abstand").
 * text-wrap:balance stays so the line breaks are even and "C.A.P." does not
 * stack at a line end. */
/* Blocksatz for both paragraphs (thread TU2M3786jjHE, follow-up). `text-wrap`
 * left at its default so justify has room to stretch words evenly across the
 * full column width. */
.big-data_card-left p {
  text-align: justify;
}

/* /de/c-a-p (+ /en/c-a-p) contact card. On DESKTOP, lay it out like the approved
 * home CTA so the Ingo cutout sits in the bottom-right corner instead of floating
 * over the heading (feedback: Ingo stand mitten über dem Text). The card becomes
 * the positioning context for the global absolute .cta_contact-person; heading +
 * buttons stay left and width-capped so nothing runs under Ingo. On mobile the
 * card stays centred and Ingo stacks below (global <=767px rule). */
.section_cta-cap .contact-card_cap {
  text-align: center;
  position: relative;
  overflow: hidden;
}
@media screen and (min-width: 768px) {
  .section_cta-cap .contact-card_cap {
    /* Match the home CTA card exactly (720px wide, 48px padding, min-height 24rem,
       content capped ~52%) so Ingo sits in the corner without the card looking
       oversized. Webflow pins this card at 528px, which was too small (Ingo
       overlapped); full-width was too big — 720px is the home size. */
    width: 100%;
    max-width: 720px;
    min-height: 24rem; /* same as the home card (heading is now short) */
    padding: 48px;
    text-align: left;
    align-items: flex-start;
    justify-content: flex-start;
    margin-left: -2.5rem; /* nudge the card a bit further left (Davide) */
  }
  .section_cta-cap .contact-card_cap > *:not(.cta_contact-person) {
    max-width: 52%;
  }
}

/* ---------------------------------------------------------------------------
 * Weather case study — conversion-rate chart bar thickness (Davide). The first
 * temperature bucket (15-19°C) rendered with narrower bars than the other three
 * because its column did not stretch to fill its grid cell and its white bar
 * carried a fixed 37px width. Make every bar-pair column fill its grid cell and
 * give the white 15-19 bar the same proportional width as the rest, so all four
 * buckets have identical bar thickness. Applies on /de + /en (section_weather).
 * --------------------------------------------------------------------------- */
.section_weather .div-block-320 > .div-block-160 {
  width: 100%;
}
.section_weather .div-block-163 {
  width: 45%;
}

/* ---------------------------------------------------------------------------
 * Footer legal row (toolbar threads 2_yCpN6fY11e, KQyophrhi6JT, m6YbVWoXHhSl).
 * Shared Footer component -> applies on every page.
 * - Address text matches the phone-number size (was 20px vs the phone's 16px).
 * - "(c) {year}" centred in its (equal-width) grid column.
 * - "BY CYREEN" right-aligned in its column.
 * --------------------------------------------------------------------------- */
.section_footer .footer_address {
  font-size: 16px;
}
/* ...and the rest of the contact block matches it (thread QB3-0WHfA1-h): the
 * column titles, the phone/fax/email/social links and the list items were still
 * 14.4px while the address was 16px. Keep the whole block one size. */
.section_footer .footer_contact-grid .footer_col-title,
.section_footer .footer_contact-grid .footer_contact-link,
.section_footer .footer_contact-grid .footer_list-item {
  font-size: 16px;
}
.section_footer .footer_legal-grid-col:nth-child(2) {
  justify-self: center;
  text-align: center;
}
.section_footer .footer_legal-grid-col:last-child {
  justify-self: end;
  text-align: right;
}

/* ---------------------------------------------------------------------------
 * /de/case-studies-2 — VU Amsterdam logo (thread 3C6BlN9R8VMY). Its source PNG
 * is opaque white while the other three logos are transparent grey, so a white
 * box shows on the grey section. CSS stopgap: multiply blends the white into the
 * section background and grayscale desaturates the logo. Also broaden the
 * 4-equal-column logo-row layout to this page so the logo is evenly spaced.
 * --------------------------------------------------------------------------- */
.section_cases .div-block-554 .image-154 {
  /* VU logo: white background now stripped in the asset, so the multiply blend
   * (old white-box stopgap) is gone; grayscale keeps the row monochrome. */
  filter: grayscale(1);
}
@media screen and (min-width: 992px) {
  .section_cases .div-block-554 {
    display: grid !important;
    grid-template-columns: repeat(4, 1fr) !important;
    justify-items: center !important;
    align-items: center !important;
    gap: 24px;
  }
  .section_cases .div-block-554 > .link-block-29 {
    grid-column: auto !important;
    grid-row: auto !important;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
  }
}

/* ---------------------------------------------------------------------------
 * /de/team + /en/team portraits (threads wc_r77n6ZhVx, 3ZTFIsrhzmT-,
 * poFmTAyfbGLH, plus the six "picture not aligned with box" threads on en/team).
 * The base .image-84 pins width:250px + object-fit:fill + a stray left:-26px and
 * margins, so on any card that is not exactly 250px the portrait sits offset and
 * distorted. Reset those, let it fill the flex card, and crop from the top so the
 * face stays framed. Grayscale so every portrait (founders included) reads as one
 * consistent black-and-white set, like the homepage founder cutouts.
 * --------------------------------------------------------------------------- */
#cyreen-team .div-block-583-special,
#cyreen-advisory .div-block-583-special {
  display: flex;
  flex-direction: column;
}
/* Advisory (#cyreen-advisory) shares the exact team treatment so the two grids
   look identical: flex-column card, top-anchored square portrait, and the same
   grayscale so every portrait reads as one consistent black-and-white set. */
#cyreen-team .image-84,
#cyreen-advisory .image-84 {
  flex: 1 0 auto;
  min-height: 250px;
  width: 100%;
  margin: 0;
  left: 0;
  object-fit: cover;
  object-position: center top;
  filter: grayscale(1) contrast(1.02);
}

/* Mobile: each card in these Webflow grids is placed on an explicit 2-D grid
   position (per-child #w-node grid-row/grid-column). On a 1-column phone layout
   those placements scatter the items across empty row tracks, leaving a dead
   ~190px gap after the last card before the next grid (the "gap between Werner
   und Anik"). Switch the grid to a plain flex column so children just stack,
   ignoring their desktop grid placement; keep the cards centered at 250px. */
@media screen and (max-width: 991px) {
  #cyreen-team .grid-7,
  #cyreen-advisory .grid-7 {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: 40px !important; /* generous spacing so stacked cards never crowd (feedback: "Abstand zu gering") */
  }
  /* Each desktop row is its own .grid-7; on a phone they stack with no space
     between grids, so the last card of one grid touched the first of the next
     (the Werner<->Anik 0px gap). Add the same 40px between consecutive grids. */
  #cyreen-team .grid-7 + .grid-7,
  #cyreen-advisory .grid-7 + .grid-7 {
    margin-top: 40px !important;
  }
}

/* ---------------------------------------------------------------------------
 * /de/pressemitteilung (.section_hero-v2-3) + /en/press-release
 * (.section_hero-v2-4) hero (threads smBH2hZQ9W21, pEhhYX3eOw_D)
 * Two fixes to make these page-unique heroes match every other page's header:
 * 1) Vertical: top-align the content (align-items: flex-start) so the heading
 *    sits ~160px from the top, not mid-section.
 * 2) Horizontal: the hero column uses justify-content: flex-end, so the content
 *    box is pushed to the right. On every other page a wide subtitle fills the
 *    box (632px max-width) and the heading lands flush-left; this page has no
 *    subtitle, so its short box got shoved right and the heading sat indented.
 *    Force the box to fill its max-width so the H1 lands at the same top-left
 *    spot as every other page header.
 * The EN press hero (.section_hero-v2-4) is structurally identical to the DE
 * one but never received these rules, so its title sat higher and indented.
 * Applying the same rules to both makes EN match DE (thread pEhhYX3eOw_D). */
.section_hero-v2-3 .hero-v2_grid-col,
.section_hero-v2-4 .hero-v2_grid-col {
  align-items: flex-start;
}
.section_hero-v2-3 .hero-v2_content-wrap,
.section_hero-v2-4 .hero-v2_content-wrap {
  width: 100%;
  /* Match the vertical push applied to .section_hero-v2 (thread hkccvdjNniz6)
   * so the H1 sits at the same height as every other page header
   * (threads jhdXJ6CleARJ, pEhhYX3eOw_D). */
  padding-top: 12rem;
}
@media (max-width: 767px) {
  .section_hero-v2-3 .hero-v2_content-wrap,
  .section_hero-v2-4 .hero-v2_content-wrap {
    padding-top: 4rem;
  }
}

/* ---------------------------------------------------------------------------
 * .section_hero-v2 hero position (thread hkccvdjNniz6)
 * On the live Webflow original the H1 sits ~5rem lower than in our Astro
 * rehost. Webflow's IX2 scroll-in animation ends at that lower position; the
 * rehost never runs the IX2, so the H1 sits at its markup-default (higher).
 * Compensate by pushing the content wrapper down. Not applied to the
 * -v2-3 variant (that has its own top-left alignment above).
 * --------------------------------------------------------------------------- */
.section_hero-v2 .hero-v2_content-wrap {
  padding-top: 12rem;
}
@media (max-width: 767px) {
  .section_hero-v2 .hero-v2_content-wrap {
    padding-top: 4rem;
  }
}

/* ---------------------------------------------------------------------------
 * /de/pressemitteilung press links (thread i2ad94UImGr2)
 * Show each publication's own logo (favicon) before the link so readers see
 * where it leads (Davide's preference over a generic glyph). The favicons are
 * DOWNLOADED into public/press-logos/ and served locally — never hotlinked
 * (CLAUDE.md). One rule per domain, matched on the link href. Refresh a logo by
 * re-downloading its file; add a domain by adding a file + a rule below.
 * --------------------------------------------------------------------------- */
.press-list .text-block-188 {
  display: inline-flex;
  /* Centre the logo on the whole title so multi-line links do not leave it stuck
   * at the top (thread MnsYQfTS4EP8). */
  align-items: center;
  gap: 0.5em;
}
.press-list .text-block-188::before {
  content: '';
  flex: 0 0 auto;
  width: 1.05em;
  height: 1.05em;
  background: center / contain no-repeat;
  border-radius: 2px;
}
.press-list a[href*='fruchthandel.de'] .text-block-188::before {
  background-image: url('/press-logos/fruchthandel.de.png');
}
.press-list a[href*='gfm-nachrichten.de'] .text-block-188::before {
  background-image: url('/press-logos/gfm-nachrichten.de.png');
}
.press-list a[href*='invidis.de'] .text-block-188::before {
  background-image: url('/press-logos/invidis.de.png');
}
.press-list a[href*='invidis.com'] .text-block-188::before {
  background-image: url('/press-logos/invidis.com.png');
}
.press-list a[href*='rtgroup.de'] .text-block-188::before {
  background-image: url('/press-logos/rtgroup.de.png');
}
.press-list a[href*='gs1-germany.de'] .text-block-188::before {
  background-image: url('/press-logos/gs1-germany.de.png');
}
.press-list a[href*='startupvalley.news'] .text-block-188::before {
  background-image: url('/press-logos/startupvalley.news.png');
}
.press-list a[href*='maresmedia.se'] .text-block-188::before {
  background-image: url('/press-logos/maresmedia.se.png');
}
.press-list a[href*='hessian.ai'] .text-block-188::before {
  background-image: url('/press-logos/hessian.ai.png');
}
.press-list a[href*='idooh.media'] .text-block-188::before {
  background-image: url('/press-logos/idooh.media.png');
}
.press-list a[href*='lebensmittelzeitung.net'] .text-block-188::before {
  background-image: url('/press-logos/lebensmittelzeitung.net.png');
}
.press-list a[href*='hamburg040.com'] .text-block-188::before {
  background-image: url('/press-logos/hamburg040.com.png');
}
.press-list a[href*='openpr.de'] .text-block-188::before {
  background-image: url('/press-logos/openpr.de.png');
}
.press-list a[href*='einzelhandel.de'] .text-block-188::before {
  background-image: url('/press-logos/einzelhandel.de.png');
}
.press-list a[href*='meedia.de'] .text-block-188::before {
  background-image: url('/press-logos/meedia.de.png');
}
.press-list a[href*='horizont.net'] .text-block-188::before {
  background-image: url('/press-logos/horizont.net.png');
}
.press-list a[href*='station-frankfurt.de'] .text-block-188::before {
  background-image: url('/press-logos/station-frankfurt.de.png');
}

/* ---------------------------------------------------------------------------
 * /en/case-studies — St. Gallen logo (thread 8fVKTUbETkfm)
 * Davide asked for the ENG logo asset, cropped, in black-and-white. Until
 * a swapped asset is available, apply grayscale + light contrast so the logo
 * reads as monochrome. Scoped to the EN page via html[lang="en"] so the DE
 * case-studies-2 (which shares the same class) stays in original colour.
 * TODO: replace /images/st.gallen.png with the ENG-language, tighter-cropped
 * asset when supplied. */
html[lang^='en'] #case-studies .div-block-554 .image-156 {
  filter: grayscale(1) contrast(1.02);
}

/* ---------------------------------------------------------------------------
 * /en/case-studies — Barilla / Journal-of-Marketing slider wrapper rounded
 * (thread pOfH567fcNnh). DE case-studies-2 uses .div-block-651.cs-slider-main
 * as the outer wrapper (already rounded via the .div-block-651 rule above);
 * EN case-studies uses .div-block-276.cs-slider-main for the same visual
 * element. Target the shared modifier .cs-slider-main so both branches round
 * identically without a page-specific selector. */
.cs-slider-main {
  border-radius: 24px;
  overflow: hidden;
}

/* ---------------------------------------------------------------------------
 * /en/team + /de/team — philosophy statements aligned with the hero H1
 * (threads WrWD5PbS98Vm, 7VdZFkxo2_2P)
 *
 * Both languages now use the same .section_team-philosophy markup, so neither
 * needs an alignment patch. The .team-mission_content-wrap mirrors the hero
 * exactly (same 2-col grid, same 632px box pushed to the right edge of its
 * 846px column, inner .padding-global), so the copy lines up with the hero H1
 * on its own. Adding padding here double-indents the text by 32px; do not.
 *
 * EN used to carry the legacy .hero.head._1234 > .div-block-270 shell, which
 * was absolutely positioned with a 7vh left margin and had to be pinned to the
 * content-box edge by hand at three breakpoints. That shell also fixed the
 * section to 100vh with overflow:hidden, so the copy was clipped whenever the
 * effective viewport got shorter (browser zoom, short laptop windows) — at a
 * 1267x613 viewport #page1inspiration overflowed by 24px and lost its last
 * line plus the scroll button. The markup was migrated to the DE structure
 * instead (17.08.2026) and those rules are deleted with it. */

/* Philosophy body copy: the site-wide p default is font-size: 1rem with
 * text-align: justify. On this ~560px column 16px read too small and the
 * justification stretched the word spacing visibly. Scoped bump to 18px with
 * a left edge; the global p default stays untouched. */
.section_team-philosophy .team-mission_content-wrap p {
  font-size: 1.125rem;
  line-height: 1.6;
  text-align: left;
}

/* CTA contact-person block (thread _DXkkGtVu2W2): photo + name for Ingo Marx,
 * the demo-booking contact, shown on the homepage CTA card between the heading
 * and the button group. Card background is white (.cta_contact-card), so text
 * stays default dark. Used on both DE (HomeCtaSection.astro) and EN
 * (en/home.html, not yet componentized) homepages with matching markup. */
/* CTA card layout (feedback: make Ingo much bigger, put him in the bottom-right
   corner, relocate the buttons). Heading + buttons sit on the left; Ingo is a
   large portrait anchored to the bottom-right corner of the card. */
.cta_contact-card {
  position: relative;
  text-align: left;
  min-height: 24rem;
  overflow: hidden;
  align-items: flex-start; /* left-align the content instead of centering it */
  justify-content: flex-start; /* heading + buttons sit near the top, not centered */
}
.cta_content {
  max-width: 52%;
  margin-right: auto;
}
.cta_content .cta_heading {
  text-align: left;
}
.cta_content .button-group {
  justify-content: flex-start;
}
/* Ingo as a frameless background-removed cutout in the bottom-right corner,
   leaning into the card; the "Ihr Ansprechpartner / Ingo Marx / Media Sales"
   caption sits to his left. */
.cta_contact-person {
  position: absolute;
  right: 0;
  bottom: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  align-items: flex-end;
  gap: 0.75rem;
}
.cta_contact-avatar {
  width: auto;
  height: 22rem;
  object-fit: contain;
  object-position: bottom;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  align-self: flex-end;
}
.cta_contact-info {
  text-align: right;
  padding-bottom: 1.25rem;
  line-height: 1.25;
}
.cta_contact-eyebrow {
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #1e1e28; /* ink — the grey read too faint over the busy card photo */
  font-weight: 600;
}
.cta_contact-name {
  font-size: 1.3rem;
  font-weight: 600;
}
.cta_contact-role {
  font-size: 0.9rem;
  color: #2d2d37;
}

/* Phones: stack it — heading + buttons centered, Ingo (cutout) centered below
   the caption so nothing overlaps. */
@media screen and (max-width: 767px) {
  .cta_contact-card {
    min-height: 0;
  }
  .cta_content {
    max-width: 100%;
    text-align: center;
  }
  .cta_content .cta_heading {
    text-align: center;
  }
  .cta_content .button-group {
    justify-content: center;
  }
  .cta_contact-person {
    position: static;
    flex-direction: column;
    align-items: center;
    width: 100%;
    margin-top: 1.5rem;
    order: 3; /* Ingo always below the heading + buttons (title + buttons on top) */
  }
  .cta_contact-info {
    text-align: center;
    padding-bottom: 0;
    order: 2;
  }
  .cta_contact-avatar {
    height: 13rem;
    order: 1;
  }
}

/* ---------------------------------------------------------------------------
 * Homepage Sanity sections — mobile: stack the two-column "heading | text"
 * grid instead of leaving the body text in a cramped right column.
 *
 * The rebuilt Astro components (HomeCap, HomeBigData, TeamSection,
 * Testimonials) reuse Webflow's .w-layout-grid.basic-grid, which stays a
 * 2-column grid on phones (heading left, body squeezed into ~120px on the
 * right, justified — the "text not aligned / spread out" symptom). Collapse it
 * to a single column below the desktop breakpoint so heading and text stack
 * full-width. Scoped to these homepage sections so the Webflow snapshot pages
 * (which also use .basic-grid) are untouched. */
@media screen and (max-width: 991px) {
  .section_cap .basic-grid,
  .section_big-data .basic-grid,
  .section_home-testimonials .basic-grid,
  .section_home-team .basic-grid {
    grid-template-columns: 1fr !important;
  }
}

/* ---------------------------------------------------------------------------
 * Team member cards (.div-block-583-special) — mobile portrait fix.
 * On desktop each card is a 250x336 box with a static 250x250 square portrait
 * (.image-84) below the name. A Webflow mobile rule re-positions .image-84 to
 * position:absolute (250x250, top:-115) inside a collapsed 250x135 card, so the
 * top 115px of the portrait (the head) is clipped by overflow:hidden ("heads
 * are cut off" on the phone). This hits BOTH the homepage founder grid
 * (.section_home-team) AND the /de/team + /en/team grids, so the rule targets
 * the card class directly rather than a section scope. Restore the static
 * square portrait, top-anchored so the face always shows, card grows to fit. */
@media screen and (max-width: 991px) {
  .section_home-team .div-block-583-special {
    width: 100%;
  }
  .div-block-583-special {
    height: auto;
  }
  .div-block-583-special .image-84 {
    position: static;
    inset: auto;
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    object-position: 50% 0%;
    transform: none;
  }
}

/* ---------------------------------------------------------------------------
 * CTA band photo (.section_cta-cap, "Möchten Sie eine Kampagne...") — mobile.
 * The section uses a full-bleed C.A.P.-screen photo with
 * background-attachment: fixed. On phones fixed backgrounds are sized to the
 * whole viewport/document, which blows the photo up and pixelates it ("viel zu
 * gross / schlechte Qualität"). Switch to scroll on mobile so the photo is
 * sized to the section, and trim the band height so it does not dominate. */
@media screen and (max-width: 991px) {
  .section_cta-cap,
  .section_cta-cap.cta-photo-putzmittel {
    background-attachment: scroll !important;
    background-position: center !important;
  }
}

/* ---------------------------------------------------------------------------
 * Site-wide: kill background-attachment:fixed on mobile. Fixed backgrounds are
 * sized to the whole viewport on phones (iOS ignores fixed entirely), which
 * blows the image up and pixelates it. Every remaining Webflow section that
 * uses fixed (.hero-pattern hero banner, .div-block-256 case-study /
 * retail-media banners) switches to scroll below the tablet breakpoint.
 * .section_cta-cap is handled in its own block above. */
@media screen and (max-width: 991px) {
  .hero-pattern,
  .div-block-256,
  .div-block-256._123._321-copy {
    background-attachment: scroll !important;
    background-position: center !important;
  }
}

/* ---------------------------------------------------------------------------
 * Team page — Senior Advisor cards (toolbar yG1b0Bx5vGc1). Davide: the advisory
 * card background must be dark grey (the same #2D2D37 as the "Impulse von
 * Experten" heading), as on the original Webflow site, NOT the light team-card
 * grey. The section stays on its original lighter grey (#62626E) so the dark
 * cards contrast against it. The role text goes light for legibility on the dark
 * card; the name is already brand red. Applies on all breakpoints incl. mobile. */
#cyreen-advisory {
  background-color: #62626e;
}
#cyreen-advisory .div-block-583-special {
  background-color: #2d2d37;
}
#cyreen-advisory .department_team {
  color: #d6d6d6;
}

/* ---------------------------------------------------------------------------
 * Homepage: the body paragraphs in the CAP / Big-Data / Testimonials / Team
 * sections are text-align:justify. On a narrow phone column that opens ugly
 * word gaps ("rivers"). Left-align them on mobile for clean, readable lines.
 * Desktop (wider columns) keeps the Webflow justify. */
@media screen and (max-width: 991px) {
  .section_cap p,
  .section_big-data p,
  .section_home-testimonials p,
  .section_home-testimonials blockquote,
  .section_home-team p {
    text-align: left !important;
  }
}

/* ---------------------------------------------------------------------------
 * Button interaction feedback (feedback: "keine farbliche Interaktion", the
 * KONTAKT button felt dead). The base only nudged the outline button's border
 * from bright to muted red on :hover, with no fill and no :active — so touch
 * devices (no hover) showed nothing at all. Give every .button a clear colour
 * response: the solid button darkens, the outline (KONTAKT) button fills solid
 * red with white text. :active is included so a tap on mobile also reacts.
 * --------------------------------------------------------------------------- */
/* IMPORTANT: kill the transition. On these Webflow snapshots the base
 * `.button { transition: all .15s }` leaves a perpetually-running CSSTransition
 * that pins background/color and overrides even inline !important (see gotchas),
 * so the hover/active colours below never painted. With no transition the state
 * snaps in instantly and reliably — exactly the visible feedback that was
 * missing. */
.button {
  transition: none !important;
}
.button:hover {
  background-color: var(--brand_colors--red_muted, #af3241);
  border-color: var(--brand_colors--red_muted, #af3241);
  color: #fff;
}
.button:active {
  background-color: var(--brand_colors--red_dark, #6e2332);
  border-color: var(--brand_colors--red_dark, #6e2332);
  color: #fff;
  transform: translateY(1px);
}
/* Outline button (KONTAKT): fill solid on hover AND press so it visibly reacts,
 * including on touch. Beats the base .is-outline:hover (lower specificity). */
.button.is-outline:hover {
  background-color: var(--brand_colors--red_active, #f04b55);
  border-color: var(--brand_colors--red_active, #f04b55);
  color: #fff;
}
.button.is-outline:active {
  background-color: var(--brand_colors--red_muted, #af3241);
  border-color: var(--brand_colors--red_muted, #af3241);
  color: #fff;
  transform: translateY(1px);
}

/* The Ingo CTA cutout is purely decorative. Its rectangular PNG has transparent
 * margins that extend over the buttons, so a click on KONTAKT landed on the
 * transparent image and SELECTED it (blue highlight) instead of activating the
 * button (feedback: "das Bild wird blau, der Button ist nicht auswählbar"). Make
 * the image + its figure ignore pointer and selection so clicks pass straight
 * through to the buttons and the image can never be selected or dragged. */
.cta_contact-person,
.cta_contact-avatar {
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none; /* also suppress the iOS long-press image menu/selection */
}

/* ---------------------------------------------------------------------------
 * Mobile polish (feedback: buttons too small, team gap too large, logos tiny).
 * --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  /* Bigger tap targets: Webflow buttons render ~36px tall / 12.8px font on
     phones. Grow font + padding for comfortable touch (nav CTA uses a separate
     class and is untouched). */
  .button,
  .w-button,
  .contact {
    font-size: 0.95rem !important;
    padding-top: 0.7rem !important;
    padding-bottom: 0.7rem !important;
    padding-left: 1.1rem !important;
    padding-right: 1.1rem !important;
    white-space: nowrap; /* keep labels on one line (e.g. "DEMO BUCHEN") */
  }

  /* CTA card: the two buttons don't both fit on one phone row once enlarged, so
     "DEMO BUCHEN" was wrapping. Stack them full-width instead — cleaner CTA. */
  .cta_contact-card .button-group {
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
  }
  .cta_contact-card .button-group .button {
    width: 100%;
    max-width: 18rem;
    justify-content: center;
  }

  /* Homepage team grid has the same phantom-row gap as /de/team (~192px dead
     space after the last founder). Stack it as a flex column. */
  .section_home-team .grid-7 {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    gap: 16px !important;
  }

  /* Partner reference logos render ~50px on phones — too small to read.
     Enlarge them, aspect ratio preserved. */
  .section_references .references_client-logo {
    width: auto !important;
    height: auto !important;
    max-height: 4.25rem !important;
    max-width: 6.5rem !important;
  }
}

/* ---------------------------------------------------------------------------
 * Homepage testimonials slider — mobile polish (feedback: "sieht noch nicht
 * gut aus"). The prev/next arrows are full-height (~530px) clickable strips
 * whose chevron sits at the vertical centre, right over the quote text; each
 * slide is centre-aligned in the tallest-slide cell, leaving a big empty gap
 * above short slides; and the logo is tiny inside a large circle.
 * --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  /* (Arrows are no longer hidden on mobile — they now sit in the uniform bottom
   * control band with the dots, below the quote, same as every other carousel.) */
  /* Top-align the slide so short quotes don't leave a big empty gap above it. */
  .section_home-testimonials.cyr-carousel-ready .w-slide {
    justify-content: flex-start !important;
  }
  /* Logo hugs its circle better (was a small logo in a large circle). */
  .section_home-testimonials .slider_slide-logo-wrapper {
    width: 80px !important;
    height: 80px !important;
  }
  .section_home-testimonials .slider_slide-logo-wrapper img {
    width: auto !important;
    height: auto !important;
    max-width: 58px !important;
    max-height: 46px !important;
  }
}

/* ---------------------------------------------------------------------------
 * Native mobile navbar (Navbar.astro .cyr-mnav). Replaces the Webflow hamburger
 * on phones — the Webflow runtime mis-binds the snapshot navbar so the
 * C.A.P./Handel sub-menus never opened. This menu is fully self-owned: a JS
 * panel toggle + native <details> accordions the runtime cannot touch. Shown
 * only <=991px; desktop keeps the Webflow nav untouched.
 * --------------------------------------------------------------------------- */
.cyr-mnav,
.cyr-mnav-panel {
  display: none;
}
@media screen and (max-width: 991px) {
  .cyr-mnav {
    display: block;
  }
  .cyr-mnav-panel {
    display: block;
  }
  header[navbar='component'] .navbar_primary_component {
    display: none !important;
  }
  /* Keep the DEMO BUCHEN CTA clear of the burger (they overlapped). */
  .navbar_primary_cta {
    margin-right: 3.25rem !important;
  }

  .cyr-mnav-burger {
    position: absolute;
    top: 50%;
    right: 1.5rem;
    transform: translateY(-50%);
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    padding: 0;
    background: transparent;
    border: 0;
    color: #fff;
    cursor: pointer;
    z-index: 60;
  }
  .cyr-mnav-burger span {
    display: block;
    width: 26px;
    height: 2px;
    background: currentColor;
    transition:
      transform 0.25s ease,
      opacity 0.2s ease;
  }
  .cyr-mnav-burger.is-open span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }
  .cyr-mnav-burger.is-open span:nth-child(2) {
    opacity: 0;
  }
  .cyr-mnav-burger.is-open span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }

  .cyr-mnav-panel {
    position: fixed;
    left: 0;
    right: 0;
    top: 5.5rem;
    bottom: 0;
    background: #af3241;
    transform: translateX(100%);
    opacity: 0;
    visibility: hidden;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    z-index: 55;
  }
  /* No transition: on this fixed element (page-wrapper / backdrop context) a
     transition on any property gets stuck at its start value, leaving the panel
     invisible. Snap instead — reliable. */
  .cyr-mnav-panel.is-open {
    transform: translateX(0);
    opacity: 1;
    visibility: visible;
  }
  .cyr-mnav-inner {
    display: flex;
    flex-direction: column;
    padding: 1.25rem 1.5rem 3rem;
  }
  .cyr-mnav-list {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .cyr-mnav-item {
    border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  }
  .cyr-mnav-link,
  .cyr-mnav-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 0;
    color: #fff;
    font-size: 1.35rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    list-style: none;
  }
  .cyr-mnav-summary::-webkit-details-marker {
    display: none;
  }
  .cyr-mnav-chevron {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
    transition: transform 0.2s ease;
  }
  .cyr-mnav-acc[open] .cyr-mnav-chevron {
    transform: rotateX(180deg);
  }
  .cyr-mnav-sublist {
    list-style: none;
    margin: 0;
    padding: 0 0 0.75rem;
  }
  .cyr-mnav-sublink {
    display: block;
    padding: 0.55rem 0 0.55rem 1rem;
    color: rgba(255, 255, 255, 0.88);
    font-size: 1.1rem;
    text-decoration: none;
  }
  .cyr-mnav-cta {
    margin-top: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.9rem 1.75rem;
    background: #fff;
    color: #af3241;
    border-radius: 999px;
    font-weight: 600;
    text-decoration: none;
  }
}

/* ---------------------------------------------------------------------------
 * Case-study "Forschungskooperation" forms (.cs-sliders) — take them out of the
 * carousel on phones/tablets. A swipe-to-find slider of two contact forms is
 * poor mobile UX; show both forms stacked instead. Desktop keeps the slider.
 * --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .cs-sliders {
    height: auto !important;
    overflow: visible !important;
  }
  .cs-sliders .w-slider-mask {
    height: auto !important;
    white-space: normal !important;
  }
  .cs-sliders .cs-slide,
  .cs-sliders .w-slide {
    position: relative !important;
    width: 100% !important;
    transform: none !important;
    display: block !important;
    margin-bottom: 2rem;
  }
  .cs-sliders .w-slider-arrow-left,
  .cs-sliders .w-slider-arrow-right,
  .cs-sliders .w-slider-nav {
    display: none !important;
  }
}

/* ---------------------------------------------------------------------------
 * Carousel arrows unclickable on desktop: the dot-nav container (.w-slider-nav)
 * is a wide box that overlaps the prev/next arrows and swallows their clicks
 * (seen on the C.A.P. testimonials slider, where nav + arrows share the bottom
 * row). Let clicks pass through the nav's empty space to the arrows below, and
 * keep the dots themselves clickable. Applies to every taken-over slider.
 * --------------------------------------------------------------------------- */
.cyr-carousel-ready .w-slider-nav {
  pointer-events: none;
}
.cyr-carousel-ready .w-slider-dot {
  pointer-events: auto;
}

/* ---------------------------------------------------------------------------
 * Case-study campaign-info labels (thread mkHvLfXxAKfP): the "Product Category /
 * Brand / Campaign Period / Impressions" labels rendered in Graphik 400. Other
 * case studies show them semibold, so make them Graphik Semibold (Graphik 600)
 * consistently wherever the .paragraph-27 label block is used. */
.paragraph-27 {
  font-family: 'Graphik 600', sans-serif !important;
  font-weight: 600 !important;
}

/* Case-study chart legend (threads IF0MQSCxEo8v, bjS9L9421Vz0): the red/grey
 * swatch sat slightly off the label baseline. Centre the swatch on the text and
 * flatten the line box so box and text line up. */
.cap-ref-leg {
  line-height: 1;
}
.cap-ref-leg .cap-ref-swatch {
  align-self: center;
  position: relative;
  top: 0;
}

/* ---------------------------------------------------------------------------
 * Light Box banner on /de/handel/in-store-retail-media (thread qtIhdo2Je9UV),
 * placed right after the "Supermarkt 2.0 / Wir denken Handel" section. Full
 * container width, rounded, generous vertical spacing. Asset is downsized and
 * served locally (public/images/lightbox-banner.webp), never hotlinked. */
.section_lightbox-banner {
  padding-top: 4rem;
  padding-bottom: 4rem;
}
.section_lightbox-banner .lightbox-banner_img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
}
@media screen and (max-width: 767px) {
  .section_lightbox-banner {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }
  .section_lightbox-banner .lightbox-banner_img {
    border-radius: 8px;
  }
}

/* ---------------------------------------------------------------------------
 * IoT Ökosystem diagram (thread mPEI3Nc482km, "cards overlap / packed too
 * tightly on mobile"). The section ships three purpose-built SVGs: a vertical
 * phone layout, a compact tablet layout and the wide desktop one. The base only
 * showed the vertical phone SVG at ≤479px; from 480–767px it showed the compact
 * tablet layout, which reads as cramped on a phone. Show the vertical phone SVG
 * across the whole mobile range (≤767) and cap its width so it stays the same
 * sensible, centred size as on a small phone. */
@media screen and (max-width: 767px) {
  .section_data .svg-images .tablet-landscape_image {
    display: none !important;
  }
  .section_data .svg-images .mobile {
    display: block !important;
    text-align: center;
    /* Base .mobile has 20px side padding, leaving a 295px box that the 328px
     * phone SVG overflowed to the right (thread mPEI3Nc482km). Drop the inner
     * padding so the illustration fits and centres within the normal gutters. */
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  .section_data .svg-images .mobile img {
    max-width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

/* ---------------------------------------------------------------------------
 * Mobile de-justify (feedback: text "weirdly aligned" on phones). Same reason
 * as the homepage block above (lines ~1485): the global base `p{text-align:
 * justify}` opens ugly word-gap rivers on narrow columns. The homepage fix is
 * scoped to homepage sections only, so these pages still justified. Left-align
 * the affected copy on mobile; desktop keeps the Webflow justify.
 *
 * 1) FAQ answers on /de/c-a-p and /de/cap-explorer (shared .faq-page accordion).
 *    The accordion inline <style> only sets font-size, so answers fell through
 *    to the global justify.
 * 2) The explanatory side-text columns on /de/cap-explorer (the two-column
 *    basic-grid sections: Kampagnen-Management, Infrastruktur, Retail).
 * --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .faq-page .accordion-content p,
  .faq-page .accordion-content li {
    text-align: left !important;
  }
  /* All two-column side-text paragraphs (comment sections under the headings)
   * across the snapshot pages, e.g. c-a-p #instore-advert, cap-explorer
   * Kampagnen/Infrastruktur/Retail, retail-media. Thread NIxkdao4hX0m asked to
   * de-justify all of these plus the Q&A boxes on mobile. */
  .content-wrap p {
    text-align: left !important;
  }
}

/* ---------------------------------------------------------------------------
 * "Vorteile für den Handel" benefits card on /de/handel/in-store-retail-media
 * (feedback: "this part should be aligned in the middle" — the green-check grid).
 * The card (.div-block-500) is centred, but the base CSS leaves the two-column
 * item grid (.div-block-499) starting flush-left (justify-content:start), so the
 * green-icon items hug the left edge with empty space on the right. Centre the
 * grid content within the card on mobile.
 * --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .section_benefits .div-block-500 {
    text-align: center;
  }
  .section_benefits .div-block-499 {
    justify-content: center !important;
    justify-items: center !important;
  }
  /* Each item's inner box (.div-block-498) is 90% wide but sat flush-left, so
   * the green check icon centred at ~65px in a 145px item instead of at 73px.
   * Centre the inner box so the dots sit dead-centre over their label
   * (thread 1jfKdPtfIyhD: "the green dots are not centered"). */
  .section_benefits .div-block-498 {
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

/* ---------------------------------------------------------------------------
 * University / research-partner logos (threads zSUQTrv6njwO retail-media,
 * jwinA4VhRPzn case-studies-2). Feedback: make the four logos the same visual
 * size and put them on one centerline; Babson a touch smaller. The source PNGs
 * have very different aspect ratios, so we normalise by a common render HEIGHT:
 * each logo sits in an equal cell, object-fit:contain, capped to one max-height
 * so they share a height and baseline. Babson (emblem, reads heavier) gets a
 * slightly lower cap per the feedback. VU's white background is stripped in the
 * asset itself; the grayscale on VU (block above) stays. */
.section_case-studies .div-block-554 .link-block-29,
.section_cases .div-block-554 .link-block-29 {
  width: 100% !important;
  display: flex;
  align-items: center;
  justify-content: center;
}
.section_case-studies .div-block-554 .link-block-29 img,
.section_cases .div-block-554 .link-block-29 img {
  width: auto !important;
  height: auto !important;
  max-width: 100% !important;
  /* Base Webflow CSS absolutely-positions some logos (e.g. St. Gallen is
   * position:absolute; inset:0 0 0 auto = right-anchored), so they escaped the
   * flex centering and sat pinned right. Force static so justify-content:center
   * centres every logo (threads 1H3TZueKtBYD, jwinA4VhRPzn). */
  position: static !important;
  /* Common height. Kept low enough that even the ultra-wide EBS wordmark
   * (409x37) reaches it inside its column, so all four share one height. */
  max-height: 30px !important;
  object-fit: contain;
}
/* Mobile: stack one logo per row across the full width, so the wide EBS/Kedge
 * wordmarks also reach the common height instead of being squeezed shorter in
 * a narrow 2-column cell. Base grid pins fixed 120px columns, so override it. */
@media screen and (max-width: 991px) {
  .section_case-studies .div-block-554,
  .section_cases .div-block-554 {
    display: grid !important;
    grid-template-columns: 1fr !important;
    grid-row-gap: 26px !important;
    width: 100% !important;
    max-width: none !important;
    justify-items: center !important;
    align-items: center !important;
  }
}

/* ---------------------------------------------------------------------------
 * Case studies: breathing room between the copy and the figure below it
 * (thread HAYUtAgorbW7, "more space between the points and graphics").
 *
 * The content wrapper alternates a copy block (.div-block-576, the summary
 * list, a rich-text block) with a figure block, and the spacing between them
 * was too tight in two different ways:
 *
 *   - .div-block-108 / .div-block-314 (grey figure cards) and
 *     .div-block-311 / .div-block-603 / .div-block-624 (red panels) carry
 *     `margin: 50px auto 150px`. Measured on werbewirkung: 50px above the
 *     figure but 150px below it, so the copy sat almost on top of its figure
 *     while the gap to the NEXT case was three times larger.
 *   - .div-block-316 (the chart cards on the weather / daypart / long-term
 *     pages) has `margin-top: 0`, so there the copy touched the figure.
 *
 * Both get 90px. Deliberately still below the 150px below a figure: the copy
 * and its figure belong together, and that larger gap has to stay the stronger
 * break between one case and the next. Do not equalise them.
 *
 * Note the wrapper differs by language, which is easy to miss: the 8 DE pages
 * and /en/case-studies/advertising-impact use .div-block-573, the other 7 EN
 * pages use .div-block-305. Both are listed, otherwise the fix silently covers
 * only part of the case studies.
 * --------------------------------------------------------------------------- */
:is(.div-block-573, .div-block-305)
  > :is(
    .div-block-108,
    .div-block-314,
    .div-block-316,
    .div-block-311,
    .div-block-603,
    .div-block-624
  ) {
  /* !important because the Webflow base sets these margins through several
     three-class variants, some in vh: .div-block-316._900 uses
     `margin: 5vh 7vh 60px` and ._900._266 `margin-top: 5vh`, which computed to
     36px on a 720px-tall window and left one figure per page tighter than the
     rest. The whole point here is one consistent gap on every case study, so
     this deliberately outranks all of them. */
  margin-top: 90px !important;
}

/* ---------------------------------------------------------------------------
 * Homepage hero (.section_hero-v2) — design-loop run 2026-08-18, piece 1.
 * Brief, system and craft critics failed the hero on all seven mechanisms in
 * knowledge-hub/cyreen-web/design-loop/bar-homepage-hero.md. The markup fixes
 * (topline, two actions) are in HomeHeroSection.astro. These are the CSS ones:
 * committed ground, legibility, action styling, heading letter-spacing.

/* Committed ground. The right column carried a diagonal pattern and nothing
 * else, so half of the above-the-fold frame did no work. It now carries the
 * approved C.A.P. store photo. The CTA band already uses cap-screen-putzmittel,
 * so the hero takes cap-screen-kaese and the page never shows one photo twice.
 * Desktop only: below 992px the column is a narrow sliver where a photo would
 * read worse than the pattern, and mobile cannot be screenshot on this machine,
 * so mobile keeps today's pattern until it can be seen. */
@media screen and (min-width: 992px) {
  .section_hero-v2.is-home-hero .hero-v2_grid-col.is-pattern {
    background-image: url('/cap-screen-kaese.jpg') !important;
    /* Scaled past cover on the vertical axis so the burned-in photographer
     * credit along the bottom of the source file is cropped out rather than
     * half-cut. The CTA band crops it the same way. */
    background-size: auto 122% !important;
    background-position: 34% 0% !important;
    background-repeat: no-repeat !important;
  }
}

/* NOTE: these rules use the Webflow variable namespace, not the @theme
 * --color-cyreen-* tokens. The snapshot pages never load global.css, so the
 * @theme vars are out of scope here and var() silently fell back to the
 * inherited colour (#2d2d37, 3.8:1), which failed the contrast it was meant
 * to fix. Same palette, different names, verified in the rendered DOM.
 *
 * Legibility. The subline was red_muted on red_active at 1.7:1 and the old
 * scroll pill put red_active on red_muted, also 1.7:1. Ink on red_active is
 * 4.6:1, which clears AA. .topline defaults to red_active, invisible on this
 * background, so it is coloured here as well.
 *
 * 2026-08-27, Davide: use red_dark instead of ink, to match the other heroes.
 * .subheadline_hero already resolves to red_dark on the case-study heroes via
 * the Webflow variant class, so this makes the home hero the same colour the
 * rest of the site already ships, and answers toolbar thread JemyVpbsOby_.
 * Contrast is the trade: red_dark #6e2332 on red_active #f04b55 is 3.0:1,
 * against 4.6:1 for ink. The 24px/600 subline clears AA large text at 3.0:1.
 * The 16px topline and the outline-button label do NOT clear AA at their size,
 * which is a known and accepted regression, flagged to Davide. */
.section_hero-v2.is-home-hero .subheadline_hero,
.section_hero-v2.is-home-hero .topline {
  color: var(--text_colors--red_dark) !important;
}

/* The documented eyebrow tracking is 0.08em. It lives in global.css, which the
 * snapshot pages never load, so .topline rendered at 0 here. Both critics caught
 * it independently, one by measuring and one by looking. */
.section_hero-v2.is-home-hero .topline {
  letter-spacing: 0.08em !important;
}

/* Actions. The hero had none, only a scroll cue. It now carries the same
 * filled-plus-outline pair as the CTA band. On the red field the filled pill
 * inverts to white with a red_muted label (6.3:1) and the outline pill inks its
 * border and label (4.6:1). .button-group centres by default, which is wrong
 * for the left-aligned hero column. */
.section_hero-v2.is-home-hero .button-group {
  justify-content: flex-start !important;
  flex-wrap: wrap;
}
.section_hero-v2.is-home-hero .button {
  background-color: #fff !important;
  border-color: #fff !important;
  color: var(--text_colors--red_muted) !important;
}

/* The primary has to out-mass the outline pill, whose near-black 2px border is
 * the highest-contrast edge in the row. Shortening the secondary label closed
 * most of the gap; this padding closes the rest. Scoped away from .is-outline,
 * which also carries .button and would otherwise grow by the same amount. */
.section_hero-v2.is-home-hero .button:not(.is-outline) {
  padding-left: 1.5rem !important;
  padding-right: 1.5rem !important;
}
.section_hero-v2.is-home-hero .button.is-outline {
  background-color: #0000 !important;
  border-color: var(--text_colors--red_dark) !important;
  color: var(--text_colors--red_dark) !important;
}
.section_hero-v2.is-home-hero .button:hover {
  background-color: var(--background_colors--grey_light) !important;
  border-color: var(--background_colors--grey_light) !important;
}
.section_hero-v2.is-home-hero .button.is-outline:hover {
  background-color: var(--text_colors--red_dark) !important;
  border-color: var(--text_colors--red_dark) !important;
  color: #fff !important;
}

/* Heading. global.css sets -0.01em and 1.05 on headings, but the Webflow h1
 * rule was winning, so the hero H1 rendered at normal spacing and 1.2 leading
 * and read looser than every section headline below it. */
.section_hero-v2.is-home-hero h1 {
  letter-spacing: -0.01em !important;
  line-height: 1.05 !important;
}

/* Homepage hero on mobile. The design-loop hero adds a topline and a second
 * action, and both are vertical cost on a narrow screen: measured at 375x812
 * the section came to 858px against an 812px viewport, so the 100svh hero no
 * longer held on one screen and pushed the pattern band out of frame. The two
 * pills cannot sit side by side either (180px + 171px + gap > 375px), so they
 * stack, which is correct but costs another ~64px.
 *
 * The actions are the point of the redesign, so they stay. The topline is the
 * cheapest 48px to give back: it is a supporting line, and on mobile the H1
 * carries the same message one line later. Desktop keeps it. */
@media screen and (max-width: 991px) {
  .section_hero-v2.is-home-hero .topline {
    display: none;
  }
  /* Second action off on mobile too. The two pills cannot share a row at this
   * width (180px + 171px + gap > 375px), so the outline one costs a further
   * ~64px stacked. Measured heights of the mobile hero: 858px with everything,
   * 810px without the topline, 746px without both. The old hero was ~698px, and
   * that slack is what made it feel right on a phone, which is the read Davide
   * had. The primary "Demo buchen" stays, so mobile keeps the conversion action
   * rather than the old scroll cue. Desktop keeps both. */
  .section_hero-v2.is-home-hero .button.is-outline {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * /de/pressemitteilung + /en/press-release press timeline
 * Single vertical spine, newest first, with a marker where the year changes.
 * Replaces the two hand-balanced snapshot columns; rendered by
 * src/components/PressTimeline.astro from src/lib/press-articles.ts.
 * Hover keeps the interaction language of the old list: the row fills dark red
 * and the text goes white.
 * The publisher logo comes from the --press-logo custom property set inline per
 * item, so a new outlet needs only public/press-logos/<host>.png and no rule.
 * --------------------------------------------------------------------------- */
.press-tl {
  width: 100%;
  max-width: 860px;
  /* The parent .new_2x-columns is a centring flexbox built for two columns. */
  margin: 0 auto;
}
.press-tl__head {
  margin-bottom: 2.5rem;
}
/* Eyebrow per the design system: Apercu Mono, uppercase, 0.08em tracking. */
.press-tl__eyebrow {
  margin: 0 0 0.5rem;
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #62626e;
}
.press-tl__heading {
  margin: 0;
  font-family: 'Graphik 600', sans-serif;
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: #1e1e28;
}
@media screen and (max-width: 767px) {
  .press-tl__heading {
    font-size: 1.75rem;
  }
}
.press-tl__group + .press-tl__group {
  margin-top: 2.5rem;
}
.press-tl__year {
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 13px;
  letter-spacing: 0.12em;
  color: #62626e;
  margin: 0 0 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #e6e6e6;
}
.press-tl__list {
  list-style: none;
  margin: 0;
  padding: 0 0 0 1.25rem;
  /* The spine itself. */
  border-left: 1px solid #e6e6e6;
}
.press-tl__item {
  position: relative;
}
/* The dot on the spine. Sits on the border of .press-tl__list. */
.press-tl__item::before {
  content: '';
  position: absolute;
  top: 1.35rem;
  left: calc(-1.25rem - 4px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: #aaa;
  transition: background-color 0.3s ease;
  z-index: 1;
}
.press-tl__item:hover::before,
.press-tl__item:focus-within::before {
  background-color: #af3241;
}
.press-tl__link {
  display: block;
  padding: 0.85rem 1rem;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  transition:
    background-color 0.3s ease,
    color 0.3s ease;
}
.press-tl__link:hover,
.press-tl__link:focus-visible {
  background-color: #af3241;
}
.press-tl__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 12px;
  color: #62626e;
  transition: color 0.3s ease;
}
.press-tl__outlet {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
}
.press-tl__outlet::before {
  content: '';
  flex: 0 0 auto;
  width: 1.05em;
  height: 1.05em;
  border-radius: 2px;
  background: var(--press-logo) center / contain no-repeat;
}
.press-tl__date::before {
  /* Drawn, not a character. A CSS hex escape here once wrote a real NUL
   * byte into this file and rendered as a replacement glyph. */
  content: '';
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background-color: currentColor;
  opacity: 0.5;
  vertical-align: middle;
  margin-right: 0.55em;
}
.press-tl__archived {
  padding: 0.1em 0.45em;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: help;
}
.press-tl__title {
  display: block;
  margin-top: 0.3rem;
  font-family: 'Graphik 400', sans-serif;
  font-size: 15px;
  line-height: 1.4;
  color: #1e1e28;
  transition: color 0.3s ease;
}
.press-tl__link:hover .press-tl__title,
.press-tl__link:focus-visible .press-tl__title,
.press-tl__link:hover .press-tl__meta,
.press-tl__link:focus-visible .press-tl__meta {
  color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .press-tl__item::before,
  .press-tl__link,
  .press-tl__meta,
  .press-tl__title {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * Homepage big-data card: the numbers that sit ON the grey panel
 * .big-data_card is grey_neutral #62626e. The three figures above the bars
 * (x375%, and the two conversion rates) inherited grey_ultra-dark #1e1e28,
 * which is 2.75:1 on that panel and fails AA even as large text. White is
 * 6.0:1. The labels INSIDE the bars stay ink: they sit on the white and the
 * red bar, where ink is the readable choice (Davide, 2026-08-21).
 * The arrow keeps its own red border colours, it does not inherit.
 * --------------------------------------------------------------------------- */
.big-data_card .counting {
  color: #fff;
}
.big-data_card .graph-text-bottom-light {
  color: #fff;
}

/* ---------------------------------------------------------------------------
 * Case-study chart card: hug the content instead of a fixed height.
 * Reported by Davide 2026-08-27: "die Box ist unten auch sehr gross", a wide
 * band of empty grey below the Werbekontakte row.
 *
 * Cause. Webflow gives .div-block-316._900._123._321 a fixed height (525px on
 * ._900, then 600px on the three-class variant) and centres its content. The
 * DOM charts that replaced the Chart.js canvases are shorter than the canvases
 * were, so the card keeps its old height and the surplus shows as dead space
 * under the info table.
 *
 * Scope. :has(.cap-uplift) restricts this to cards that actually hold one of
 * our DOM charts, so the Webflow cards elsewhere keep their authored height.
 * The :has() also raises specificity above the four-class Webflow rule, so this
 * wins wherever it is placed in the cascade.
 * --------------------------------------------------------------------------- */
.div-block-316:has(.cap-uplift) {
  height: auto;
}

/* ---------------------------------------------------------------------------
 * "Aktuelles von Cyreen" — curated LinkedIn cards below the press timeline.
 * Component: src/components/SocialPosts.astro, data: src/lib/social-posts.ts.
 *
 * Visually distinct from the timeline above it on purpose. The press page is
 * third-party coverage and that is where its credibility comes from; our own
 * posts must not read as if a publication wrote them. Hence cards on a light
 * panel rather than the dated spine, and a quieter type scale.
 * --------------------------------------------------------------------------- */
/* Position. The press wrapper .new_2x-columns is `display: flex` with a row
   direction, so dropping a second child next to <PressTimeline /> put the cards
   in a second COLUMN beside the timeline instead of below it (reported by
   Davide, 2026-08-27, with a screenshot). Letting that flex row wrap and giving
   this section a full basis puts it back on its own line under the timeline.
   .press-relese-main is the press page's own marker class on the same element,
   so nothing else on the site is touched. */
.press-relese-main {
  flex-wrap: wrap;
}
.cyr-social {
  flex: 0 0 100%;
  width: 100%;
  max-width: 100%;
  margin-top: 5rem;
  padding-top: 3rem;
  border-top: 1px solid #e6e6e6;
}
.cyr-social__head {
  margin-bottom: 2rem;
}
.cyr-social__eyebrow {
  margin: 0 0 0.5rem;
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #62626e;
}
.cyr-social__heading {
  margin: 0;
  font-family: 'Graphik 600', sans-serif;
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: #1e1e28;
}
.cyr-social__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.cyr-social__item {
  display: flex;
}
/* The card needs a drawn edge, not just a fill. #f5f5f5 on the white page is
   1.09:1, so the card boundary was all but invisible (Davide, 2026-08-27).
   Ink at 22% composites to about #ceced0, a 1.57:1 hairline: clearly a line,
   still quiet enough not to turn the grid into a table. */
.cyr-social__card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  background: #f5f5f5;
  border: 1px solid rgba(30, 30, 40, 0.22);
  border-radius: 12px;
  overflow: hidden;
  color: inherit;
  transition:
    transform 0.25s ease,
    box-shadow 0.25s ease,
    border-color 0.25s ease;
}
.cyr-social__card:hover,
.cyr-social__card:focus-within {
  transform: translateY(-3px);
  border-color: rgba(30, 30, 40, 0.38);
  box-shadow: 0 12px 30px rgba(30, 30, 40, 0.12);
}
/* Same problem one level in: the 27.08 poster is a near-white motion graphic,
   so on the #f5f5f5 card it had no bottom edge and bled into the copy. This
   hairline is a step stronger than the card's, because it separates two light
   surfaces rather than sitting against the page. The placeholder is darker
   again, so a slow image still reads as a frame and not as empty card. */
.cyr-social__media {
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #d4d4d9;
  border-bottom: 1px solid rgba(30, 30, 40, 0.3);
}
.cyr-social__media img,
.cyr-social__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Above the CTA's stretched hit area, so the player controls stay clickable
   instead of the whole card swallowing the press. */
.cyr-social__media--video {
  position: relative;
  z-index: 2;
}
.cyr-social__media--video video {
  background: #1e1e28;
}
.cyr-social__body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.5rem;
}
.cyr-social__date {
  font-family: 'Apercu Mono', 'Courier New', monospace;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: #62626e;
}
/* Left-aligned on every viewport, not just mobile. The Webflow base sets
   `p { text-align: justify }` globally, and both paragraphs in this block are
   <p>, so the card copy rendered as Blocksatz with word-gap rivers (Ciril,
   thread SwXGt0K5og04; confirmed by Davide as "sieht aus wie Blocksatz").
   The de-justify rules further down only cover mobile and deliberately leave
   Webflow's justify on desktop, which is why this block needs its own rule.
   It has to sit on the paragraphs themselves: a bare `p` selector beats an
   inherited value from .cyr-social, however specific that ancestor rule is. */
.cyr-social__eyebrow,
.cyr-social__text {
  text-align: left;
}
.cyr-social__text {
  font-family: 'Graphik 400', sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: #1e1e28;
}
/* Pushed to the bottom so cards of unequal text length still line their CTA up. */
/* The only anchor in the card. ::after stretches it over the whole card so the
   card still reads as one click target, without nesting interactive elements. */
.cyr-social__cta {
  margin-top: auto;
  padding-top: 0.4rem;
  font-family: 'Graphik 600', sans-serif;
  font-size: 14px;
  color: #af3241;
  text-decoration: none;
}
.cyr-social__cta::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}
.cyr-social__cta:focus-visible {
  outline: 2px solid #af3241;
  outline-offset: 3px;
}
.cyr-social__card:hover .cyr-social__cta {
  color: #6e2332;
}
.cyr-social__follow {
  display: inline-block;
  margin-top: 2rem;
  font-family: 'Graphik 600', sans-serif;
  font-size: 15px;
  color: #af3241;
  text-decoration: none;
}
.cyr-social__follow:hover {
  color: #6e2332;
  text-decoration: underline;
}
@media (prefers-reduced-motion: reduce) {
  .cyr-social__card {
    transition: none;
  }
  .cyr-social__card:hover,
  .cyr-social__card:focus-within {
    transform: none;
  }
}
@media screen and (max-width: 991px) {
  .cyr-social__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media screen and (max-width: 767px) {
  .cyr-social__grid {
    grid-template-columns: 1fr;
  }
  .cyr-social__heading {
    font-size: 1.75rem;
  }
}

/* ---------------------------------------------------------------------------
 * EN homepage CTA card — Ingo overlapped the heading.
 *
 * The rules above are written against the DE markup, where HomeCtaSection.astro
 * wraps heading and buttons in .cta_content and that wrapper is capped at 52%
 * so nothing runs under the absolutely positioned portrait. en/home.html is
 * still the raw snapshot and has no .cta_content: the heading is a bare div and
 * the buttons sit in .margin-top.margin-custom1. So the cap never applied, the
 * centred heading ran the full width of the card, and Ingo landed on top of it
 * (reported by Davide 2026-08-27 on both DEV and PROD).
 *
 * Fixed by capping the card's children directly rather than the named wrapper,
 * the same shape as the /de/c-a-p rule above. Structure-independent, so it holds
 * whether or not the page is ever componentised, and it changes nothing on DE
 * where .cta_content is already 52%.
 *
 * Scoped with :has(.cta_contact-person) so it can only ever touch a card that
 * actually holds the portrait. The EN page used to carry a second, portrait-less
 * .cta_contact-card, the "Interested?" one, which an unscoped version of this
 * rule squeezed for no reason. That section has since been deleted from the
 * snapshot because the German homepage never had it, but the guard stays: it
 * costs nothing and states what the rule is actually about.
 * --------------------------------------------------------------------------- */
@media screen and (min-width: 768px) {
  .cta_contact-card:has(.cta_contact-person) > *:not(.cta_contact-person) {
    max-width: 52%;
  }
  /* The snapshot centres this heading; the card is a left-aligned layout. */
  .cta_contact-card:has(.cta_contact-person) > * > .text-align-center {
    text-align: left;
  }
  .cta_contact-card:has(.cta_contact-person) > * > .button-group {
    justify-content: flex-start;
  }
}
@media screen and (max-width: 767px) {
  /* Mobile stacks and centres, matching the .cta_content rules for DE. */
  .cta_contact-card:has(.cta_contact-person) > *:not(.cta_contact-person) {
    max-width: 100%;
    text-align: center;
  }
  .cta_contact-card:has(.cta_contact-person) > * > .button-group {
    justify-content: center;
  }
}
