/*
Theme Name: Commacross 2026
Theme URI: https://www.commacross.de
Author: Commacross GmbH
Description: Block-Theme für Commacross GmbH — Messe, Event, Medien, KI-Services. Alle Tokens aus dem Design-System-Sheet, 17 Block-Patterns.
Requires at least: 6.5
Tested up to: 6.8
Requires PHP: 8.0
Version: 4.12.0
License: GNU General Public License v2 or later
Text Domain: commacross
Tags: full-site-editing, block-patterns, business, custom-colors, custom-logo, wide-blocks
*/

/* Schriften — woff2-Dateien in assets/fonts/ ablegen (siehe assets/fonts/README.txt) */
@font-face { font-family: "Lato"; font-style: normal; font-weight: 400; font-display: swap; src: url("assets/fonts/lato-400.woff2") format("woff2"); }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 700; font-display: swap; src: url("assets/fonts/lato-700.woff2") format("woff2"); }
@font-face { font-family: "Lato"; font-style: italic; font-weight: 400; font-display: swap; src: url("assets/fonts/lato-400-italic.woff2") format("woff2"); }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 300; font-display: swap; src: url("assets/fonts/lato-300.woff2") format("woff2"); }

:root {
  --cc-transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);
  /* Höhe der fixierten Menüleiste. Wird dem Header als min-height aufgeprägt
     UND als Platzhalter oben auf Seiten ohne Bild/Video-Header verwendet —
     dadurch können beide Werte nicht auseinanderlaufen. */
  --cc-header-height: 76px;
}

body { text-wrap: pretty; }

/* main und post-content spannen über die ganze Breite — die Blöcke darin
   regeln ihre Breite selbst über alignwide / contentSize */
main.wp-block-group.alignfull > .entry-content.wp-block-post-content.alignfull,
main.wp-block-group.alignfull { max-width: none; }

/* Kein globaler Block-Gap zwischen Header/Main/Footer auf Root-Ebene.
   Ohne Klasse im Selektor waere die Spezifitaet null und WordPress' eigene
   Regle ":where(.wp-site-blocks) > *" wuerde als spaeter eingebundener
   globaler Stil gewinnen — der Reset waere wirkungslos. */
.wp-site-blocks > * { margin-block-start: 0; }

/* Menüleiste immer oben fixiert, unabhängig vom Scroll-Stand.
   Bewusst am <header>-Wrapper des Template-Teils angesetzt und nicht nur an
   .cc-header-fixed: Liefert WordPress eine im Site-Editor angepasste
   Header-Version aus der Datenbank aus, fehlt dort unsere Klasse — der
   <header>-Wrapper ist aber in jedem Fall vorhanden. */
header.wp-block-template-part,
.cc-header-fixed { position: fixed; top: 0; left: 0; right: 0; z-index: 100; }
header.wp-block-template-part { display: flex; align-items: center; }
header.wp-block-template-part > * { width: 100%; }
/* Wenn beide Ebenen greifen, fixiert nur der Wrapper */
header.wp-block-template-part .cc-header-fixed { position: static; }

/* Logo: width und height im Markup reservieren den Platz, damit die Kopfzeile
   beim Laden nicht springt. Die Hoehe ist dort auf ganze Pixel gerundet und
   weicht deshalb um bis zu einem Pixel vom SVG-Verhaeltnis ab — height:auto
   laesst fuer die Darstellung das echte Verhaeltnis der Datei gelten. */
header.wp-block-template-part .custom-logo { height: auto; }

/* Firmenname neben dem Logo ausblenden. Im Theme ist der site-title-Block
   entfernt; diese Regel fängt die alte DB-Version ab, die ihn noch enthält. */
header.wp-block-template-part .wp-block-site-title { display: none; }

/* Seiten OHNE Bild/Video-Header: Platz für die fixierte Menüleiste, sonst
   läge der Seitenanfang darunter. Seiten MIT .cc-hero bleiben bündig an der
   Oberkante (kein Margin/Padding), der Header schwebt dort über dem Medium. */
main.wp-block-group.alignfull:not(:has(.cc-hero)) { padding-top: var(--cc-header-height); }

/* Radius: ausschließlich pill für Buttons — alle Flächen bleiben kantig */
:where(.wp-block-group, .wp-block-column, .wp-block-image img, .wp-block-cover, .wp-block-post-featured-image img, input, textarea, select) { border-radius: 0; }

/* Fokus-Ring: auf Weiß und base-dark orange, auf oranger Fläche dunkelblau */
:where(a, button, input, textarea, select, summary, .wp-block-button__link):focus-visible {
  outline: 2px solid var(--wp--preset--color--brand-primary);
  outline-offset: 2px;
}
.has-brand-primary-background-color :where(a, button, .wp-block-button__link):focus-visible {
  outline-color: var(--wp--preset--color--base-dark);
}

/* Kicker */
.cc-kicker { text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; color: var(--wp--preset--color--brand-ink); }
.has-base-dark-background-color .cc-kicker,
.has-text-inverse-color .cc-kicker { color: var(--wp--preset--color--brand-primary); }

/* Orange Akzentlinie unter Überschriften */
.cc-rule { display: block; width: 210px; height: 2px; background: var(--wp--preset--color--brand-primary); border: 0; margin: var(--wp--preset--spacing--2-xs) 0; }
.cc-rule.is-centered { margin-inline: auto; }
.cc-rule.is-short { width: 72px; margin-top: 10px; }

/* USP-Liste mit orangem Chevron */
.cc-usp { list-style: none; padding-left: 0; }
.cc-usp li { position: relative; padding-left: 1.6em; }
.cc-usp li::before {
  content: ""; position: absolute; left: 0; top: 0.55em; width: 0.42em; height: 0.42em;
  border-right: 2.4px solid var(--wp--preset--color--brand-primary);
  border-top: 2.4px solid var(--wp--preset--color--brand-primary);
  transform: rotate(45deg);
}

/* Karten — Schatten aus den theme.json-Presets "card"/"card-hover", Rahmen aus
   dem Farb-Preset border-subtle. Bewusst hier und nicht als Inline-Style im
   Blockmarkup: so folgt jede Karte automatisch einer Farbänderung im
   Design-System. is-style-cc-card ist der im Editor wählbare Block-Style
   (functions.php), .cc-card die in den Patterns gesetzte Klasse. */
.cc-card,
.wp-block-group.is-style-cc-card {
  box-shadow: var(--wp--preset--shadow--card);
  border: 1px solid var(--wp--preset--color--border-subtle);
  transition: box-shadow var(--cc-transition), transform var(--cc-transition);
  height: 100%;
}
.cc-card:hover,
.wp-block-group.is-style-cc-card:hover { box-shadow: var(--wp--preset--shadow--card-hover); transform: translateY(-2px); }

/* Inhaltskasten um die Einbettung in Muster 02 (z. B. KI-Avatar-Demo).
   Seit 4.10.3 ohne Rahmen: Die Linie lag als Kasten um jeden iFrame und
   wirkte wie ein Fremdkörper. Die Klasse bleibt bestehen, damit bereits
   eingefügte Abschnitte weiter erkannt werden und sich später wieder
   gestalten lassen. */
.cc-panel { border: 0; }

/* "Beitrag lesen" als eigener Button unterhalb der Karte */
.cc-card-cta {
  display: inline-block; margin-top: var(--wp--preset--spacing--2-xs);
  background: var(--wp--preset--color--brand-primary); color: var(--wp--preset--color--text-inverse);
  font-weight: 700; text-decoration: none; border-radius: 999px;
  padding: 13px 26px; transition: background var(--cc-transition);
}
.cc-card-cta:hover { background: var(--wp--preset--color--brand-primary-hover); color: var(--wp--preset--color--text-inverse); }

/* Query-Pagination: keine Seitenzahlen, nur schlanke Vor-/Zurück-Pfeile */
.cc-pagination .wp-block-query-pagination-previous,
.cc-pagination .wp-block-query-pagination-next {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 20px; border: 1px solid var(--wp--preset--color--border-subtle);
  border-radius: 999px; font-weight: 700; text-decoration: none;
  color: var(--wp--preset--color--base-dark); transition: background var(--cc-transition), color var(--cc-transition), border-color var(--cc-transition);
}
.cc-pagination .wp-block-query-pagination-previous:hover,
.cc-pagination .wp-block-query-pagination-next:hover {
  background: var(--wp--preset--color--base-dark); color: #fff; border-color: var(--wp--preset--color--base-dark);
}

/* Blog-Übersicht (index/archive): "Weiter"-Link dient nur assets/js/infinite-scroll.js als URL-Quelle */
.cc-infinite-next { display: none; }

/* Blog-Startseite: Kategorie-Filter (assets/js/blog-filter.js) */
.cc-blog-filter { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: var(--wp--preset--spacing--sm); }
.cc-blog-filter__btn {
  display: inline-flex; align-items: center; border: 0; border-radius: 999px; cursor: pointer;
  padding: 10px 22px; font-weight: 700; font-family: inherit; font-size: var(--wp--preset--font-size--sm);
  background: var(--wp--preset--color--base-dark); color: #fff; transition: background var(--cc-transition);
}
.cc-blog-filter__btn:hover { background: var(--wp--preset--color--base-dark-soft); }
.cc-blog-filter__btn.is-active,
.cc-blog-filter__btn.is-active:hover { background: var(--wp--preset--color--brand-primary); }

/* "Referenzen & Blog": horizontale Karten-Slideshow statt Pagination (assets/js/blog-carousel.js) */
.cc-blog-carousel .wp-block-post-template {
  display: flex; gap: var(--wp--preset--spacing--xs); overflow-x: auto;
  scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: 2px;
}
.cc-blog-carousel .wp-block-post-template::-webkit-scrollbar { display: none; }
.cc-blog-carousel .wp-block-post-template > * {
  flex: 0 0 calc((100% - 2 * var(--wp--preset--spacing--xs)) / 3); scroll-snap-align: start;
  /* Der Block läuft im Flow-Layout, deshalb setzt WordPress jedem Kind außer
     dem ersten margin-block-start. In der waagerechten Reihe wirkt das als
     Abstand nach oben — die erste Karte stünde dadurch höher als die übrigen.
     Der seitliche Abstand kommt hier ausschließlich aus gap. */
  margin: 0;
}
/* Karten gleich hoch (Flex-Stretch der Reihe) + "Beitrag lesen" unten rechts in der Karte */
.cc-blog-carousel .cc-card { display: flex; flex-direction: column; }
.cc-blog-carousel .cc-card .cc-card-cta {
  align-self: flex-end; margin: auto var(--wp--preset--spacing--xs) var(--wp--preset--spacing--xs) 0;
}
@media (max-width: 960px) {
  .cc-blog-carousel .wp-block-post-template > * { flex-basis: calc((100% - var(--wp--preset--spacing--xs)) / 2); }
}
@media (max-width: 600px) {
  .cc-blog-carousel .wp-block-post-template > * { flex-basis: 85%; }
}
.cc-blog-carousel__nav { display: flex; justify-content: flex-end; gap: 4px; margin-top: var(--wp--preset--spacing--sm); }
.cc-blog-carousel__arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border: 0; border-radius: 999px;
  background: transparent; color: #A7ACB8; cursor: pointer;
  transition: background var(--cc-transition), color var(--cc-transition);
}
.cc-blog-carousel__arrow:hover { background: var(--wp--preset--color--base-light-soft); color: var(--wp--preset--color--base-dark); }
.cc-blog-carousel__arrow:disabled { opacity: .35; cursor: default; }

/* Beiträge sliden animiert beim Blättern (siehe assets/js/query-slide.js) */
@keyframes cc-slide-in-next { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: translateX(0); } }
@keyframes cc-slide-in-prev { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: translateX(0); } }
.wp-block-post-template.cc-slide-next { animation: cc-slide-in-next 320ms cubic-bezier(0.4, 0, 0.2, 1); }
.wp-block-post-template.cc-slide-prev { animation: cc-slide-in-prev 320ms cubic-bezier(0.4, 0, 0.2, 1); }

/* Bild/Video-Header (Pattern 01 Startseite, Pattern 05c Blogbeitrag).
   Beide identisch aufgebaut: Gruppe .cc-hero als Bühne, darin das Medium
   .cc-hero__bg absolut über die ganze Fläche und die weiße Textbox auf der
   Unterkante. Bewusst KEIN core/cover — dessen save()-Markup (Hintergrund-
   Span) lässt sich in einem Pattern nicht zuverlässig von Hand schreiben. */
.cc-hero {
  position: relative; display: grid; align-items: end; justify-items: center;
  min-height: 100vh; overflow: hidden; padding-bottom: 0 !important;
}
/* Ohne Hintergrund: Grau steht ausschließlich in .cc-hero__bg--empty, sonst
   läge es hinter einem freigestellten Header-Bild. */
.cc-hero__bg {
  position: absolute !important; inset: 0 !important; margin: 0 !important;
  width: 100% !important; max-width: none !important;
}
/* img und video gleichermaßen — der Medienblock im Hero ist austauschbar */
.cc-hero__bg img,
.cc-hero__bg video {
  display: block; width: 100% !important; height: 100% !important;
  max-width: none !important; object-fit: cover !important;
}
/* Header-Video bleibt unsichtbar, bis das erste Bild geladen ist (Klasse
   .is-ready aus assets/js/hero-video.js). Sonst blitzt vorher der Video-
   Platzhalter des Browsers vollflächig auf. Den Start-Button, den Safari
   zeigt, wenn Autoplay blockiert ist (Stromsparmodus), gleich mit weg. */
.cc-hero__bg video { opacity: 0; transition: opacity 400ms ease; }
.cc-hero__bg video.is-ready { opacity: 1; }
.cc-hero__bg video::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
.cc-hero__bg video::-webkit-media-controls { display: none !important; }
/* Oben leicht durchscheinend, ab 40 % der Höhe deckend — wie auf der
   bisherigen Website. Das Header-Bild schimmert so an der Oberkante der Box
   durch, der Text darunter steht auf reinem Weiß und bleibt voll lesbar.
   Werte 1:1 übernommen (dort: .headerContainer). Bewusst OHNE
   background-color darunter: Der Verlauf läge sonst auf Weiß, und von der
   Transparenz bliebe nichts übrig. */
.cc-hero__box {
  position: relative; z-index: 1;
  background: linear-gradient(180deg, rgba(249, 249, 250, 0.85) 0%, var(--wp--preset--color--base-light) 40%, var(--wp--preset--color--base-light) 100%);
  width: 100%; max-width: 1100px; margin-inline: auto; text-align: center;
}
/* Textbreite unabhängig von der (breiteren) Box — eigene Klasse statt
   WordPress' contentSize-Layout-Mechanik, die hier unzuverlässig durchschlägt. */
.cc-hero__box-text { max-width: 780px; margin-inline: auto; }

/* Buttons in zentrierten Bereichen mittig setzen (ohne Layout-Attribut im Markup) */
.cc-hero__box .wp-block-buttons,
.has-text-align-center + .wp-block-buttons,
.cc-center .wp-block-buttons { justify-content: center; }

/* Akkordeon */
.wp-block-details { border: 1px solid var(--wp--preset--color--border-subtle); background: #fff; padding-inline: var(--wp--preset--spacing--xs); }
.wp-block-details summary { font-weight: 700; list-style: none; cursor: pointer; padding-block: var(--wp--preset--spacing--xs); display: flex; justify-content: space-between; align-items: center; gap: var(--wp--preset--spacing--xs); }
.wp-block-details summary::-webkit-details-marker { display: none; }
.wp-block-details summary::after {
  content: ""; flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--wp--preset--color--brand-primary) no-repeat center;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none"><path d="M2 4l4 4 4-4" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  transition: transform var(--cc-transition);
}
.wp-block-details[open] summary::after { transform: rotate(180deg); }

/* Akkordeon animiert auf- und zufahren */
.wp-block-details[data-cc-anim] > .cc-details__inner {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--cc-transition), opacity var(--cc-transition);
}
.wp-block-details[data-cc-anim][open] > .cc-details__inner { grid-template-rows: 1fr; opacity: 1; }
.wp-block-details[data-cc-anim].is-closing > .cc-details__inner { grid-template-rows: 0fr; opacity: 0; }
.wp-block-details[data-cc-anim] > .cc-details__inner > div { min-height: 0; overflow: hidden; }

/* Auto-Slideshow (Block 03, Variante Slideshow) */
.cc-slideshow { display: flex; gap: var(--wp--preset--spacing--2-xs); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.cc-slideshow::-webkit-scrollbar { display: none; }
.cc-slideshow > * { flex: 0 0 100%; scroll-snap-align: start; margin: 0; }
.cc-slideshow__dots { display: flex; gap: 8px; justify-content: center; margin-top: var(--wp--preset--spacing--2-xs); }
.cc-slideshow__dot { width: 9px; height: 9px; border-radius: 50%; border: 0; padding: 0; cursor: pointer; background: var(--wp--preset--color--border-subtle); }
.cc-slideshow__dot[aria-current="true"] { background: var(--wp--preset--color--brand-primary); }

/* Blog-Detail: 1/4 Sidebar links, 3/4 Inhalt rechts */
.cc-blog-detail > .wp-block-column:first-child { position: sticky; top: var(--wp--preset--spacing--md); align-self: start; }
@media (max-width: 781px) { .cc-blog-detail > .wp-block-column:first-child { position: static; } }

/* Bildplatzhalter (Video/iFrame-Hinweistexte), solange keine Medien gesetzt sind */
.cc-placeholder { background: var(--wp--preset--color--base-light-soft); display: grid; place-items: center; color: #A7ACB8; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.8125rem; }
.cc-ratio-16-9 { aspect-ratio: 16 / 9; }
.cc-ratio-16-10 { aspect-ratio: 16 / 10; }
.cc-ratio-4-3 { aspect-ratio: 4 / 3; }
.cc-ratio-3-2 { aspect-ratio: 3 / 2; }
.cc-ratio-3-4 { aspect-ratio: 3 / 4; }
.cc-ratio-9-16 { aspect-ratio: 9 / 16; }
.cc-ratio-21-9 { aspect-ratio: 21 / 9; }

/* Einbettung (commacross/embed-frame, Muster 02): Der iFrame füllt die Fläche,
   das Seitenverhältnis kommt von der cc-ratio-Klasse am Rahmen. Absolut
   positioniert statt height:100%, damit auch Anbieter mit eigener height-Angabe
   im iFrame-Tag sauber sitzen.

   margin-inline: auto statt margin: 0 — der Block bringt eine eigene
   Breiteneinstellung mit (max-width in Prozent, siehe inc/embed-frame-block.php).
   Ein pauschales margin: 0 würde den schmaleren Rahmen links kleben lassen
   statt ihn zu zentrieren, und stünde zugleich der Ausrichtung „breit“ /
   „volle Breite“ im Weg. Die senkrechten Abstände bleiben bei 0: die geben
   die Muster über blockGap vor. */
.cc-embed { position: relative; margin-block: 0; margin-inline: auto; background: var(--wp--preset--color--base-light-soft); }
.cc-embed > iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }

/* Bild-/Video-Slots: core/image bzw. core/video direkt im Seitenverhältnis */
.wp-block-image[class*="cc-ratio-"], .wp-block-video[class*="cc-ratio-"] { margin: 0; }
.wp-block-image[class*="cc-ratio-"] img, .wp-block-video[class*="cc-ratio-"] video { width: 100%; height: 100%; object-fit: cover; }

/* Grau markiert ausschließlich die LEERE Fläche — sonst läge es hinter jedem
   freigestellten Bild (Logos, PNG/SVG mit Transparenz, WebP) als hellgrauer
   Kasten. :has() prüft, ob das Bild eine Quelle hat; ein leerer Bildblock ist
   in den Mustern <figure …><img alt=""/></figure>, also ein img OHNE src. */
.wp-block-image[class*="cc-ratio-"]:not(:has(img[src])),
.wp-block-video[class*="cc-ratio-"]:not(:has(video[src])) { background: var(--wp--preset--color--base-light-soft); }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; animation-duration: 1ms !important; scroll-behavior: auto !important; }
}

/* Kachelraster für Branchen (15) — 3 Spalten, ab Tablet 2, mobil 1 */
.cc-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--wp--preset--spacing--xs); }
/* Der Block läuft im Flow-Layout, deshalb setzt WordPress jedem Kind außer dem
   ersten margin-block-start. Im Raster stünde die erste Kachel dadurch höher
   als die übrigen. Der Abstand kommt hier ausschließlich aus gap.
   Der Selektor braucht ZWEI Klassen: WordPress' Regel
   ":root :where(.is-layout-flow) > *" hat dieselbe Spezifität wie ein
   einzelnes ".cc-grid-3 > *" — und wird als globaler Stil nach dem
   Theme-Stylesheet eingebunden, gewinnt bei Gleichstand also. */
.wp-block-group.cc-grid-3 > * { margin: 0; }
@media (max-width: 960px) { .cc-grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .cc-grid-3 { grid-template-columns: 1fr; } }

/* Kundenstimmen (14): ein Zitat je Ansicht im Slider.
   --cc-slide-interval steuert die Wechselzeit (assets/js/slideshow.js liest
   den Wert aus) — bewusst über CSS statt über ein Block-Attribut, damit im
   gespeicherten Markup nichts steht, was die Blockvalidierung nicht kennt. */
.cc-quotes { --cc-slide-interval: 6000; align-items: stretch; }
.cc-quote {
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--wp--preset--spacing--sm) var(--wp--preset--spacing--xs);
  text-align: center;
}
.cc-quote .wp-block-post-content > p:first-child::before,
.cc-quote > p:first-child::before { content: "„"; }
.cc-quote .wp-block-post-content > p:last-child::after,
.cc-quote > p:first-child::after { content: "“"; }
/* Englische Seiten: “…” statt „…“. Greift über das lang-Attribut am <html>,
   das inc/multilang.php auf der englischen Fassung auf en-US setzt. */
.cc-quote:lang(en) .wp-block-post-content > p:first-child::before,
.cc-quote:lang(en) > p:first-child::before { content: "“"; }
.cc-quote:lang(en) .wp-block-post-content > p:last-child::after,
.cc-quote:lang(en) > p:first-child::after { content: "”"; }
.cc-quote .wp-block-post-content { text-align: center; font-size: var(--wp--preset--font-size--lg); }
.cc-quote__org { margin-top: var(--wp--preset--spacing--3-xs); text-align: center; font-size: var(--wp--preset--font-size--sm); }
/* Der Query-Loop erzeugt die Slideshow-Spur — die Kinder sind <li>-Wrapper. */
.cc-quotes.wp-block-post-template { list-style: none; margin: 0; padding: 0; }
.cc-quotes.wp-block-post-template > * { margin: 0; }

/* Sprungziele nicht unter die fixierte Menüleiste rutschen lassen —
   betrifft Anker-Links und den Skip-Link, den WordPress für Block-Themes
   selbst ausgibt. */
:where(h1, h2, h3, h4, :target) { scroll-margin-top: calc(var(--cc-header-height) + var(--wp--preset--spacing--xs)); }
/* Anker-Links auf derselben Seite (z. B. Menüpunkt "#kundenstimmen") gleiten
   zum Ziel statt zu springen. Bei prefers-reduced-motion nimmt die Regel
   weiter oben das zurück. Modal-Links sind nicht betroffen — modal.js fängt
   sie ab, bevor der Browser scrollt. */
html { scroll-behavior: smooth; }

/* Skip-Link von WordPress über der fixierten Leiste halten */
.skip-link:focus { z-index: 1000; }

/* Leerer Medien-Slot: graue Fläche, damit ein unbefüllter Header sichtbar
   unbefüllt ist statt unsichtbar. */
.cc-hero__bg--empty { background: var(--wp--preset--color--base-light-soft); }

/* Filterleiste: Hinweis, wenn eine Auswahl nichts übrig lässt */
.cc-blog-filter__empty { flex-basis: 100%; text-align: center; margin: var(--wp--preset--spacing--xs) 0 0; color: #6b7280; }
.cc-blog-filter__empty[hidden] { display: none; }

/* Sprachumschalter — wird rechts neben den Kontakt-Button gehängt
   (inc/multilang.php), damit er unabhängig vom Kopfbereich-Template greift. */
.cc-lang-switch {
  font-size: var(--wp--preset--font-size--sm); font-weight: 700;
  display: flex; align-items: center; flex: none;
  margin-left: var(--wp--preset--spacing--xs);
}
/* Rückfall, falls der Kopfbereich keinen Button enthält: rechtsbündig ans Ende */
.cc-lang-switch--loose { position: absolute; right: var(--wp--preset--spacing--sm); top: 50%; transform: translateY(-50%); margin-left: 0; }
.cc-lang-switch:empty { display: none; }
.cc-lang-switch a { color: currentColor; text-decoration: none; text-transform: uppercase; letter-spacing: 0.06em; }
.cc-lang-switch a:hover { color: var(--wp--preset--color--brand-primary); }

/* Sprachumschalter: Liste kommt aus dem Shortcode in inc/multilang.php */
.cc-lang-switch__list { list-style: none; margin: 0; padding: 0; display: flex; gap: 10px; }
.cc-lang-switch__list a[aria-current="true"] { color: var(--wp--preset--color--brand-primary); }

/* ---------------------------------------------------------------------------
   Modal (Pattern 16). Geöffnet wird über einen normalen Link auf den
   HTML-Anker des Blocks — siehe assets/js/modal.js. Ohne JavaScript bleibt
   das Fenster ausgeblendet und der Link springt lediglich ins Leere; kein
   Inhalt geht verloren, weil er im Dokument steht.
   --------------------------------------------------------------------------- */
.cc-modal[hidden] { display: none; }
.cc-modal {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: var(--wp--preset--spacing--sm);
  background: rgba(16, 21, 34, 0.6);
  opacity: 0; transition: opacity var(--cc-transition);
  overflow-y: auto;
}
.cc-modal.is-open { opacity: 1; }
.cc-modal__dialog {
  position: relative;
  /* Innenabstand hier, damit auch die aus dem Inhaltstyp "Modals" erzeugten
     Fenster richtig sitzen — Muster 16 bringt seinen eigenen Wert per
     Inline-Style mit und bleibt davon unberuehrt (derselbe Wert, damit beide
     Wege gleich aussehen). */
  padding: var(--wp--preset--spacing--sm);
  background: var(--wp--preset--color--base-light);

  /* Format 16:9 statt Inhaltsbreite.

     Die Breite wird aus der verfuegbaren Hoehe abgeleitet, nicht umgekehrt.
     Andersherum waere das Fenster auf flachen Bildschirmen hoeher als das
     Sichtfeld, die max-height wuerde greifen und genau das Verhaeltnis
     kaputtmachen, um das es hier geht. */
  --cc-modal-gap: calc(2 * var(--wp--preset--spacing--sm));
  --cc-modal-max-block: calc(100vh - var(--cc-modal-gap));
  /* dvh beruecksichtigt die ein- und ausfahrende Adressleiste auf Mobilgeraeten. */
  --cc-modal-max-block: calc(100dvh - var(--cc-modal-gap));
  --cc-modal-max-width: 1320px;

  width: min(100%, calc(var(--cc-modal-max-block) * 16 / 9), var(--cc-modal-max-width));
  aspect-ratio: 16 / 9;
  max-height: var(--cc-modal-max-block);
  overflow-y: auto;

  box-shadow: var(--wp--preset--shadow--card-hover);
  transform: translateY(8px); transition: transform var(--cc-transition);
}
/* Fenster aus dem Inhaltstyp "Modals": gescrollt wird der Inhalt, nicht das
   Fenster — sonst wandert der Schliessen-Button mit nach oben aus dem Bild.
   Muster 16 bringt keinen __body mit und behaelt sein bisheriges Verhalten. */
.cc-modal__dialog:has(> .cc-modal__body) { overflow: hidden; }
.cc-modal__body { height: 100%; overflow-y: auto; }
/* Modal-Inhalte nutzen immer die volle Fensterbreite — das Fenster selbst
   begrenzt bereits. Statt jede Ebene einzeln aufzuheben, werden die beiden
   Breitenstufen des Themes innerhalb des Modals auf 100 % gesetzt: Jede
   Gruppe mit "Inhaltsbreite" (auch verschachtelt) liest genau diese Variablen
   und wird dadurch ebenfalls voll breit. Die Fensterbreite oben haengt deshalb
   nicht mehr an --wp--style--global--wide-size, sondern steht als fester Wert.
   .cc-modal-canvas ist die Vorschau eines Modals (templates/single-cc_modal.html). */
.cc-modal,
.cc-modal-canvas {
  --wp--style--global--content-size: 100%;
  --wp--style--global--wide-size: 100%;
}
.cc-modal__body > * { max-width: none; }
/* Muster 16 bringt am Fenster eine feste Inhaltsbreite (720 px) mit — in
   bereits angelegten Seiten steht sie im gespeicherten Markup. Die dafuer
   erzeugte Regel hat eine Klasse Spezifitaet, diese hier zwei. */
.cc-modal__dialog.is-layout-constrained > * { max-width: none; }
/* Auf schmalen Bildschirmen ergibt 16:9 keinen Sinn — daraus wuerde ein
   flacher Streifen, in dem jeder Inhalt scrollen muesste. */
@media (max-width: 781px) {
  .cc-modal__dialog { width: 100%; aspect-ratio: auto; }
  .cc-modal__dialog:has(> .cc-modal__body) { overflow-y: auto; }
  .cc-modal__body { height: auto; overflow: visible; }
}
.cc-modal.is-open .cc-modal__dialog { transform: translateY(0); }
.cc-modal__close {
  position: absolute; top: 8px; right: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0;
  border: 0; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--wp--preset--color--base-dark);
  transition: background var(--cc-transition);
}
.cc-modal__close:hover { background: var(--wp--preset--color--base-light-soft); }
/* Der Schalter liegt ueber dem Inhalt. Ausweichen muss ihm nur das ERSTE
   Element — in aller Regel eine Ueberschrift, die auf schmalen Bildschirmen
   sonst unter das Kreuz liefe. assets/js/modal.js setzt den Schalter als erstes
   Kind des Dialogs, "close + *" trifft damit genau das erste Inhaltselement;
   .cc-modal__body ist ausgenommen, weil dort der zentrierte Inhalt sonst
   verrutschen wuerde — dessen erstes Kind bekommt den Platz stattdessen. */
.cc-modal__close + *:not(.cc-modal__body),
.cc-modal__body > *:first-child { padding-right: 40px; }
/* Seite hinter dem Fenster nicht mitscrollen */
html.cc-modal-open { overflow: hidden; }
/* Vorschau eines Modals: Fenster auf abgedunkelter Flaeche, gleiche Breite und
   gleicher Innenabstand wie im Overlay. */
.cc-modal-canvas {
  padding: var(--wp--preset--spacing--sm);
  background: var(--wp--preset--color--base-light);
  box-shadow: var(--wp--preset--shadow--card-hover);
}

/* ---------------------------------------------------------------------------
   Icons — Inline-SVG aus inc/icons.php, übernehmen über currentColor
   automatisch die Textfarbe ihrer Umgebung.
   --------------------------------------------------------------------------- */
/* Symbole tragen die Akzentfarbe. Auf oranger Flaeche waeren sie unsichtbar,
   dort wird auf die Inversfarbe gewechselt. */
.cc-icon { display: inline-block; vertical-align: middle; width: 1em; height: 1em; color: var(--wp--preset--color--brand-primary); }
.has-brand-primary-background-color .cc-icon { color: var(--wp--preset--color--text-inverse); }
.cc-icon--sm { width: 1.25rem; height: 1.25rem; }
.cc-icon--md { width: 2rem; height: 2rem; }
.cc-icon--lg { width: 3rem; height: 3rem; }

.cc-icon-block { display: flex; }
.cc-icon-block.is-align-center { justify-content: center; }
.cc-icon-block.is-align-right { justify-content: flex-end; }

/* Menüpunkte: Icon vor der Beschriftung */
.cc-icon--nav { width: 1em; height: 1em; margin-right: 0.5em; flex: none; }
.wp-block-navigation-item__content { display: inline-flex; align-items: center; }

/* ---------------------------------------------------------------------------
   Hauptmenü mit Dropdowns — nach dem Vorbild der bisherigen Website.

   WordPress gibt Untermenüs 200 px Breite vor; alles Längere
   („Medientechnik & Inszenierung“) bricht dann um. Die alte Website ließ
   Einträge nie umbrechen, sondern das Menü so breit werden wie der längste
   Eintrag. Das leistet white-space: nowrap allein: Ein absolut positioniertes
   Element wird von sich aus so breit wie sein Inhalt, sobald der nicht mehr
   umbrechen darf.

   Alles gilt nur für die aufgeklappte Desktop-Leiste. Das mobile Menü
   (.is-menu-open) bleibt wie es ist, die Footer-Navigationen haben keinen
   responsiven Container und sind damit ebenfalls nicht betroffen.
   --------------------------------------------------------------------------- */
@media (min-width: 600px) {
  /* Menüpunkte oberster Ebene: orange Fläche beim Überfahren — auch solange
     das Untermenü offen ist, damit sichtbar bleibt, wozu es gehört. */
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
    padding: 0.3rem 0.75rem;
    border-radius: 0.5rem;
    transition: background var(--cc-transition), color var(--cc-transition);
  }
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item:hover > .wp-block-navigation-item__content,
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .wp-block-navigation-item:focus-within > .wp-block-navigation-item__content {
    background: var(--wp--preset--color--brand-primary);
    color: var(--wp--preset--color--text-inverse);
  }

  /* Untermenü: dunkle, abgerundete Fläche, mittig unter dem Menüpunkt. Die
     zusätzliche Klasse vorn hebt die Spezifität über die Regel des Kerns
     (left: -1px), unabhängig von der Ladereihenfolge der Stylesheets. */
  .wp-block-navigation .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__container > .has-child > .wp-block-navigation__submenu-container {
    left: 50%;
    transform: translateX(-50%);
    padding: 0.75rem 1.5rem;
    border: 0;
    border-radius: 0.5rem;
    background: var(--wp--preset--color--base-dark);
    box-shadow: 0 12px 28px rgba(16, 21, 34, 0.28);
  }

  /* Einträge nie umbrechen. */
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
    white-space: nowrap;
    padding: 0.5rem 0.25rem;
    transition: color var(--cc-transition);
  }
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible {
    color: var(--wp--preset--color--brand-primary);
  }

  /* Symbole wie bisher in Orange, mit etwas mehr Luft zum Text. */
  .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .cc-icon--nav {
    color: var(--wp--preset--color--brand-primary);
    margin-right: 0.75em;
  }
}

/* Medien-Slot "Bild, Video oder Symbol" (commacross/tile-media) */
.cc-tile-media { display: grid; place-items: center; overflow: hidden; }
.cc-tile-media > img, .cc-tile-media > video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Video auf schwarzem Grund: Bedienelemente und Letterboxing sind darauf gebaut. */
.cc-tile-media.is-video { background: #000; }
/* Grau nur noch hinter der LEEREN Fläche — hinter Bild wie Symbol wäre es bei
   Transparenz (freigestellte Logos, PNG/SVG) als hellgrauer Kasten sichtbar. */
.cc-tile-media.is-empty { background: var(--wp--preset--color--base-light-soft); }
.cc-tile-media.is-icon .cc-icon { width: 38%; height: auto; max-height: 60%; }
/* Hochformate (3:4, 9:16) nie höher als das Sichtfeld: In einer halben Spalte
   wäre ein 9:16-Video sonst rund 1100 px hoch und nur scrollend zu sehen.
   Begrenzt wird über die BREITE — eine max-height allein würde das
   Seitenverhältnis brechen und das Video beschneiden. Die Fläche rückt dabei
   in die Mitte der Spalte. */
.cc-tile-media.cc-ratio-3-4 { width: min(100%, calc(85svh * 3 / 4)); margin-inline: auto; }
.cc-tile-media.cc-ratio-9-16 { width: min(100%, calc(85svh * 9 / 16)); margin-inline: auto; }
/* "Original": Format kommt aus der Datei selbst, nichts wird beschnitten.
   Solange nichts gewählt ist, braucht die leere Fläche trotzdem eine Höhe. */
.cc-tile-media.cc-ratio-auto > img,
.cc-tile-media.cc-ratio-auto > video { width: auto; max-width: 100%; height: auto; max-height: 85svh; object-fit: contain; }
.cc-tile-media.cc-ratio-auto.is-video { background: none; }
.cc-tile-media.cc-ratio-auto.is-empty { aspect-ratio: 16 / 9; }

/* Sterne-Bewertung (commacross/star-grid)
   ---------------------------------------
   EIN Raster für alles: Beschriftungen und Sternenreihen sind Geschwister,
   keine verschachtelten Kästen. Je Feld zwei Spalten — die Beschriftung nimmt
   den Rest der Breite, die Sternenspalte ist max-content und damit bei stets
   fünf gleich breiten Sternen überall exakt gleich breit. Dadurch stehen die
   Sterne in jeder Zeile deckungsgleich untereinander, egal wie lang die
   Beschriftung daneben ausfällt. */
.cc-stars {
  display: grid;
  align-items: center;
  column-gap: var(--wp--preset--spacing--sm);
  row-gap: var(--wp--preset--spacing--xs);
  padding: var(--wp--preset--spacing--sm);
  background: var(--wp--preset--color--base-light-soft);
}
.cc-stars.is-cols-1 { grid-template-columns: minmax(0, 1fr) max-content; }
.cc-stars.is-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr) max-content); }
.cc-stars.is-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr) max-content); }
.cc-stars__label { font-weight: 700; }
/* nowrap: Die fünf Sterne bleiben unter allen Umständen in einer Zeile. */
.cc-stars__rating { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.cc-stars .cc-star { display: inline-block; width: 1.5rem; height: 1.5rem; flex: none; color: var(--wp--preset--color--border-subtle); }
.cc-stars .cc-star.is-on { color: var(--wp--preset--color--brand-primary); }
/* Ersatzausgabe, falls die Icon-Daten fehlen */
.cc-stars__value { font-weight: 700; color: var(--wp--preset--color--brand-primary); }
/* Zwei Spalten nebeneinander werden auf dem Telefon zu schmal für Wort plus
   fünf Sterne — dort steht immer ein Feld je Zeile. */
@media (max-width: 781px) {
  .cc-stars[class*="is-cols-"] { grid-template-columns: minmax(0, 1fr) max-content; }
}

/* ---------------------------------------------------------------------------
   Anfrage-Assistent (Pattern 17). Formular aus Contact Form 7, Symbol-Reiter
   aus inc/contact-form.php. Bewusst ohne JavaScript: Die Reiter sind echte
   <input type="radio"> in einem <label>, die Auswahl läuft über :checked.
   Damit funktionieren Tastatur (Pfeiltasten), Screenreader und das Absenden
   ohne eine einzige Zeile Skript — und nichts kann kaputtgehen, wenn ein
   Cache- oder Optimierungs-Plugin Skripte zusammenlegt.
   --------------------------------------------------------------------------- */

/* Nur für Screenreader — Beschriftungen, die im Original als Platzhalter im
   Feld stehen. Ein Platzhalter allein ist kein zugänglicher Feldname: Er
   verschwindet beim Tippen und wird nicht von jeder Vorlesehilfe angesagt. */
.screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}

/* Formular auf Lesebreite halten, auch wenn der Abschnitt breiter läuft */
.cc-anfrage-section .wpcf7 { max-width: 780px; margin-inline: auto; }

/* Reiterreihe — vier Spalten, ab Tablet-Breite zwei, damit die Beschriftungen
   nicht umbrechen müssen. */
.cc-anfrage {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: var(--wp--preset--spacing--sm);
}
@media (max-width: 600px) {
  .cc-anfrage { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.cc-anfrage__item { position: relative; display: block; cursor: pointer; }

/* Der Radiobutton bleibt im Dokument (Tastatur, Screenreader, Formularversand)
   und wird nur unsichtbar gemacht. display:none oder visibility:hidden würden
   ihn aus der Tab-Reihenfolge nehmen. */
.cc-anfrage__input {
  position: absolute; width: 1px; height: 1px; margin: 0; padding: 0;
  opacity: 0; pointer-events: none;
}

.cc-anfrage__tab {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--wp--preset--spacing--2-xs);
  min-height: 150px; height: 100%;
  text-align: center; text-transform: uppercase; letter-spacing: 0.06em;
  font-size: var(--wp--preset--font-size--sm); font-weight: 700; line-height: 1.3;
  transition: color var(--cc-transition);
}

/* Markierung des gewählten Reiters: halbbreiter Strich mittig unter dem Text,
   wie im bisherigen Auftritt. Als Pseudo-Element und nicht als border-bottom,
   weil ein Rahmen über die ganze Spaltenbreite liefe. */
.cc-anfrage__tab::after {
  content: ""; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 50%; height: 2px; background: transparent;
  transition: background var(--cc-transition);
}

/* Zwei Klassen im Selektor, damit die Regel die Grundfarbe aus .cc-icon
   (orange) sicher schlägt — das Symbol soll die Farbe seines Reiters tragen. */
.cc-anfrage .cc-anfrage__icon { width: 52px; height: 52px; color: inherit; }

.cc-anfrage__item:hover .cc-anfrage__tab { color: var(--wp--preset--color--brand-primary); }
.cc-anfrage__input:checked + .cc-anfrage__tab { color: var(--wp--preset--color--brand-primary); }
.cc-anfrage__input:checked + .cc-anfrage__tab::after { background: var(--wp--preset--color--brand-primary); }
/* Der Fokusring gehört sichtbar an den Reiter, nicht an das versteckte Feld */
.cc-anfrage__input:focus-visible + .cc-anfrage__tab {
  outline: 2px solid var(--wp--preset--color--brand-primary); outline-offset: -2px;
}

/* Eingabefelder auf dunklem Grund. Contact Form 7 bringt keine eigene
   Feldgestaltung mit, deshalb hier vollständig. */
.cc-anfrage-section input[type="text"],
.cc-anfrage-section input[type="email"],
.cc-anfrage-section input[type="tel"],
.cc-anfrage-section input[type="url"],
.cc-anfrage-section input[type="number"],
.cc-anfrage-section select,
.cc-anfrage-section textarea {
  display: block; width: 100%;
  padding: 12px 16px;
  font: inherit; font-size: var(--wp--preset--font-size--base);
  color: var(--wp--preset--color--text-inverse);
  background: transparent;
  border: 1px solid var(--wp--preset--color--border-inverse);
  transition: border-color var(--cc-transition);
}
.cc-anfrage-section textarea { min-height: 140px; resize: vertical; }
.cc-anfrage-section ::placeholder { color: rgba(255, 255, 255, 0.55); opacity: 1; }
.cc-anfrage-section :is(input, select, textarea):focus { border-color: var(--wp--preset--color--brand-primary); }

/* Contact Form 7 setzt jedes Feld in einen <p>. Der Abstand kommt von hier,
   damit die Vorlage im Plugin ohne eigenes Markup auskommt. */
.cc-anfrage-section .wpcf7-form p { margin-block: 0 var(--wp--preset--spacing--2-xs); }
.cc-anfrage-section .wpcf7-form-control-wrap { display: block; }

/* Zwei Felder nebeneinander — Klasse in der Formularvorlage vergeben */
.cc-anfrage-section .cc-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--wp--preset--spacing--2-xs); }
@media (max-width: 600px) { .cc-anfrage-section .cc-form-row { grid-template-columns: 1fr; } }

/* Datenschutzhinweis unter den Feldern. Der Elementname steht bewusst mit im
   Selektor: Sonst hätte die allgemeine Absatzregel oben (zwei Klassen plus
   Element) die höhere Spezifität und der Abstand käme nicht an. */
.cc-anfrage-section p.cc-form-terms {
  font-size: var(--wp--preset--font-size--sm); line-height: 1.45;
  color: rgba(255, 255, 255, 0.65);
  margin-block: var(--wp--preset--spacing--xs);
}
.cc-anfrage-section p.cc-form-terms a { color: var(--wp--preset--color--brand-primary); }

/* Absende-Button wie jeder andere Button des Themes */
.cc-anfrage-section .wpcf7-submit {
  display: inline-block; cursor: pointer;
  padding: 13px 26px; border: 0; border-radius: 999px;
  font: inherit; font-size: var(--wp--preset--font-size--base); font-weight: 700;
  background: var(--wp--preset--color--brand-primary); color: var(--wp--preset--color--text-inverse);
  transition: background var(--cc-transition);
}
.cc-anfrage-section .wpcf7-submit:hover { background: var(--wp--preset--color--brand-primary-hover); }
.cc-anfrage-section .wpcf7-submit:disabled { opacity: .5; cursor: default; }

/* Meldungen des Plugins auf dunklem Grund lesbar halten. Die Randfarbe je
   Zustand kommt von Contact Form 7 selbst und bleibt unangetastet. */
.cc-anfrage-section .wpcf7-not-valid-tip { color: #FFB280; font-size: var(--wp--preset--font-size--sm); }
.cc-anfrage-section .wpcf7-response-output { margin: var(--wp--preset--spacing--xs) 0 0; padding: 12px 16px; }
.cc-anfrage-section .wpcf7-spinner { background-color: rgba(255, 255, 255, 0.5); }

/* Hinweis, wenn das Formular fehlt — sichtbar nur für angemeldete Bearbeitende
   (siehe inc/contact-form.php). */
.cc-anfrage-hint {
  padding: var(--wp--preset--spacing--xs);
  border: 1px dashed var(--wp--preset--color--brand-primary);
  font-size: var(--wp--preset--font-size--sm);
}
