/* blankton.ch — Kundendesign dieser Installation.

Das ist die EINE Design-Datei dieser Website. Sie enthaelt alles, was das Aussehen
der oeffentlichen Seiten bestimmt, und sie ist die Datei, die der Design-Editor der
Engine anzeigt und schreibt ("Website-Design" in der Sidebar; savecss.php schreibt
unabhaengig von jeder Einstellung immer hart nach css/styles.css). Genau deshalb
darf es keine zweite Kundendatei geben, die diese hier ueberstimmt: bis September
2026 lag die Seiten-Optik in einer eigenen css/blankton-shared.css, die NACH dieser
Datei geladen wurde — jede Aenderung im Backend waere dadurch wirkungslos geblieben,
ohne erkennbaren Grund. Die Datei ist aufgeloest und ihr Inhalt steht hier in
Abschnitt 2.

Kein Engine-Update fasst diese Datei an.

Aufbau:

  1. BASIS — box-sizing, html/:root, body. Gilt fuer alles.
  2. SEITEN-OPTIK — Nav, Seiten-Header, Footer, Back-to-Top, Rechtstext-Seiten,
     Miet-/Verkaufstabellen, Webcam. Das ist blankton.ch. Wer am Aussehen der
     Website arbeitet, arbeitet fast immer hier. Steht deshalb weit oben.
  3. STARTER-SCHALE — Topbar, Header/Logo, mainnav, Sections, Footer aus dem
     KAI-Starter-Paket. Auf den sechs echten Seiten wird davon nichts verwendet;
     die einzige Seite, die noch so gebaut ist, ist 404.html.
  4. ENGINE-FEATURES — Optik der zuschaltbaren Bausteine: TinyMCE-Formate,
     404-Seite, Cookie-Banner, Popup, Lightbox, Referenzfelder, Kalender, News,
     Preisliste, Menuekarten, Kategorie-Karten, Kontaktformular, Galerie.
     cms/css/system.css liefert dazu nur Struktur und Mechanik — ohne diesen
     Abschnitt sieht ein eingeschaltetes Feature unformatiert aus. Der Abschnitt
     bleibt vollstaendig, auch wo ein Feature (noch) nicht benutzt wird: wer eines
     einschaltet und es sieht kaputt aus, findet die Ursache nicht. Bitte nicht
     "aufraeumen".
  5. EDITIERMODUS — was im Backend anders aussehen muss als im Frontend.

Nicht hier drin, absichtlich: die Effekt-Bausteine in css/ (hero-parallax,
text-reveal, sticky-header, scroll-reveal, cursor-dot). Das ist eine eigenstaendige,
als Ganzes aktualisierbare Sammlung, kein Kundendesign — Ausnahme ist die eine
body.editing-Regel in Abschnitt 5, die bewusst hier steht und nicht dort.

Ebenfalls nicht hier drin: seiteneigene Optik (der grosse Parallax-Hero der
Startseite z.B.) — die bleibt im <style>-Block der jeweiligen HTML-Datei. */


/* ===========================================================================
   1. BASIS
   =========================================================================== */

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Aktueller Standard ist eher 17-18px Basis statt der alten 16px – die ganze Seite
     nutzt rem-Einheiten, daher skaliert diese eine Zeile Fliesstext, Überschriften und
     Abstände proportional gemeinsam hoch, ohne jede einzelne font-size anzufassen. */
  font-size: 112.5%; /* 18px bei Standard-Browsereinstellung */
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

:root {
  /* Content-Breite nach gängigem modernem Standard (~1200-1320px sind üblich). */
  --site-content-width: 1280px;

  /* AKZENTFARBE DER SEITE. Traegt drei Rollen: Linkfarbe (Footer, Rechtstexte,
     Preislisten-Verzeichnis, Schlussblock), Strichfarbe der Kontakt-Icons und Flaeche des
     Button-Links im Verkauf-Schlussblock. Bewusst nach der ROLLE benannt und nicht nach dem
     Ton – wird die Marke je umgefaerbt, stimmt der Name weiter. Praefix --site- wie
     --site-content-width darueber; die Engine vergibt ausschliesslich --cms-* (siehe
     cms/css/system.css und cms.css), eine Kollision ist damit ausgeschlossen.

     Zum Wert: bis September 2026 stand hier #14879e. Auf hellem Grund verfehlte das den
     Richtwert 4,5 : 1 fuer Fliesstext deutlich – 4,21 auf Weiss, 3,69 auf dem Footer-Grau
     #f0f0f0 und 3,31 auf dem Subfooter-Grau #e4e4e4. Das Subfooter-Grau ist der duenkelste
     Grund, auf dem die Farbe ueberhaupt steht, und gibt den Wert deshalb vor.

     #106e81 haelt Farbton und Saettigung des Originals exakt fest (190,0° / 77,5%) und
     senkt allein die Helligkeit von 34,9% auf 28,5%. Es ist der hellste Wert auf dieser
     Achse, der auf allen drei Gruenden mit Reserve ueber die Marke kommt: 5,88 / 5,16 /
     4,63. Der buchstaeblich naechste Wert waere #117083 gewesen, der trifft die Marke aber
     mit 4,501 erst auf der dritten Nachkommastelle – zu knapp fuer antialiaste Schrift auf
     einem realen Grund.

     Der Hover-Wert gehoert dazu und muss mitwandern: #0f6a7d, der fruehere Hover, laege nur
     einen Helligkeitspunkt unter der heutigen Basis und waere nicht mehr zu unterscheiden.
     #0c515f haelt denselben Abstand, den die Gestaltung immer hatte (7,5 Helligkeitspunkte
     unter der Basis), auf demselben Farbton. */
  --site-accent: #106e81;
  --site-accent-hover: #0c515f;
}

/* Zusammengefuehrt aus den beiden frueheren body-Regeln. Uebernommen sind die
   blankTon-Werte, weil sie das Aussehen der sechs echten Seiten bestimmen.

   Die "line-height: 1.6" der Starter-Fassung ist hier bewusst NICHT mehr drin:
   blankton.ch ist ohne sie gebaut, global gesetzt kostete sie allein auf der
   Startseite 112px Dokumenthoehe. Sie ist nicht verloren, sondern in Abschnitt 3
   auf .wrap gewandert — den Container, in dem auf den Starter-Seiten jeder Text
   sitzt und den keine der sechs blankTon-Seiten benutzt. */
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* Heller Default, da die meisten Unterseiten (Vermietung, Verkauf, Impressum, AGB,
     Webcam) helle Inhaltsflaechen haben. Die Startseite ueberschreibt das in ihrem
     eigenen <style>-Block auf das dunkle Theme. */
  background: #fff;
  color: #111;
}


/* ===========================================================================
   2. SEITEN-OPTIK — blankton.ch
   ===========================================================================
   Bis September 2026 eine eigene Datei css/blankton-shared.css, unveraendert
   uebernommen (nur die Basis-Regeln daraus stehen jetzt in Abschnitt 1). Wird von
   allen sechs Seiten benutzt und enthaelt nur, was auf allen identisch ist.

   Die Navigation nutzt sticky-header.js aus der Effektsammlung als Mechanik. Die
   frueher noetige Ladereihenfolge-Regel ("blankton-shared.css MUSS nach
   sticky-header.css kommen, sonst bleibt die Nav sticky statt fixed") gilt
   weiterhin — jetzt fuer diese Datei: css/styles.css laedt in allen sechs Seiten
   nach den Effekt-Bausteinen. Wer die <link>-Reihenfolge im <head> umstellt,
   bricht die Nav.
   =========================================================================== */

/*
  Hauptnavigation – nutzt sticky-header.js als Mechanik (Scroll-Schwelle + Richtung), Optik
  hier fest: position:fixed + halbtransparenter Verlauf, damit sie auf JEDER Seite über dem
  jeweiligen Hero-Bild schwebt (grosser Parallax-Hero auf Home, kompakter Bild-Header auf
  den Unterseiten) statt eigenen Platz zu beanspruchen. Sanftes Fade (Opacity + Versatz)
  zusätzlich zum Slide der Basis-Regel, statt des harten 100%-Slides.
*/
.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 10;
  background: linear-gradient(to bottom, rgba(10, 6, 4, 0.55) 0%, rgba(10, 6, 4, 0) 100%);
  --header-transition-duration: 0.45s;
  --header-transition-easing: ease-out;
  transition: transform var(--header-transition-duration) var(--header-transition-easing),
              opacity var(--header-transition-duration) var(--header-transition-easing);
}
.site-nav.is-hidden {
  transform: translateY(-100%);
  opacity: 0;
}
.site-nav-inner {
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 1.1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.site-nav-logo {
  display: inline-flex;
  line-height: 0;
}
.site-nav-logo img {
  height: 26px;
  width: auto;
  display: block;
}
.site-nav-links {
  list-style: none;
  display: flex;
  gap: 2rem;
  margin: 0;
  padding: 0;
}
.site-nav-links a {
  color: #eee;
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.9;
  transition: opacity 0.2s ease;
}
.site-nav-links a:hover,
.site-nav-links a:focus-visible {
  opacity: 1;
}

/*
  Untermenue «Leistungen» — Desktop-Leiste.
  Der Elternpunkt bleibt ein gewoehnlicher Link; der Aufklapper ist ein eigener kleiner
  Umschalter daneben (Begruendung steht im Markup). Aufgeklappt wird in drei Faellen:
  :hover fuer die Maus, :focus-within fuer die Tastatur — beide greifen auch ohne
  JavaScript — und .is-open, das js/blankton-shared.js beim Tipp auf den Umschalter setzt.

  .is-forced-closed steht bewusst als LETZTE Regel und hat exakt dieselbe Spezifitaet wie
  die drei Oeffnen-Faelle (je 0,4,0). Nur dadurch schlaegt sie :focus-within, wenn Escape
  oder ein zweiter Tipp auf den Umschalter schliesst, waehrend der Fokus noch im Menue
  liegt — ohne sie bliebe das Menue in genau diesem Fall haengen.
*/
.site-nav-item.has-submenu {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.site-nav-submenu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  background: none;
  color: #eee;
  opacity: 0.9;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Pfeil rein aus Rahmen gezeichnet, kein Icon-Asset - gleiche Machart wie beim
   Starter-Dropdown in Abschnitt 3. */
.site-nav-submenu-toggle::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid currentColor;
  transition: transform 0.2s ease;
}
.site-nav-item.has-submenu.is-open > .site-nav-submenu-toggle::after {
  transform: rotate(180deg);
}
.site-nav-submenu {
  position: absolute;
  top: calc(100% + 1.1rem);
  left: -1.1rem;
  min-width: 11rem;
  list-style: none;
  margin: 0;
  padding: 0.35rem 0;
  background: rgba(10, 6, 4, 0.92);
  border-radius: 0 0 3px 3px;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
}
/* Hover-Bruecke: fuellt den Abstand zwischen Elternpunkt und Klappmenue unsichtbar auf.
   Sie haengt am <ul> und gehoert damit zum <li> - die Maus verlaesst den Hover-Bereich
   beim Hinunterfahren also nie. Ohne sie schloesse sich das Menue auf halbem Weg. */
.site-nav-submenu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -1.1rem;
  height: 1.1rem;
}
.site-nav-submenu a {
  display: block;
  padding: 0.5rem 1.1rem;
  white-space: nowrap;
}
.site-nav-item.has-submenu:hover > .site-nav-submenu,
.site-nav-item.has-submenu:focus-within > .site-nav-submenu,
.site-nav-item.has-submenu.is-open > .site-nav-submenu {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}
.site-nav-item.has-submenu.is-forced-closed > .site-nav-submenu {
  visibility: hidden;
  opacity: 0;
}

/*
  Burger-Button: nur < 768px sichtbar (dieselbe Schwelle wie der Mobile-Fallback weiter
  unten). Die drei Balken morphen per transform/opacity zu einem X, wenn .is-menu-open
  auf dem Header sitzt – kein separates Icon-Asset nötig.
*/
.site-nav-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.site-nav-burger-line {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: #eee;
  transition: transform 0.3s ease, opacity 0.2s ease;
}
.site-nav.is-menu-open .site-nav-burger-line:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.site-nav.is-menu-open .site-nav-burger-line:nth-child(2) {
  opacity: 0;
}
.site-nav.is-menu-open .site-nav-burger-line:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/*
  Mobile-Menü-Panel: klappt unterhalb der Nav-Leiste auf. grid-template-rows 0fr→1fr
  animiert die Höhe sauber ohne Magic-Number/max-height-Schätzung; overflow:hidden auf
  dem Grid-Kind sorgt dafür, dass der Inhalt beim Zuklappen sauber abgeschnitten wird.
*/
.site-nav-mobile {
  display: none;
}

@media (max-width: 768px) {
  .site-nav-links {
    display: none;
  }
  .site-nav-burger {
    display: flex;
  }
  .site-nav-mobile {
    display: grid;
    grid-template-rows: 0fr;
    background: rgba(10, 6, 4, 0.92);
    transition: grid-template-rows 0.35s ease;
  }
  .site-nav.is-menu-open .site-nav-mobile {
    grid-template-rows: 1fr;
  }
  .site-nav-mobile-links {
    overflow: hidden;
    min-height: 0;
    list-style: none;
    margin: 0;
    padding: 0 1.5rem;
  }
  .site-nav-mobile-links a {
    display: block;
    padding: 0.85rem 0;
    color: #eee;
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
  /* Die Trennlinie sass frueher auf dem <a>. Sie liegt jetzt auf dem <li> der obersten
     Ebene: gleiche Stelle, gleiche Breite, gleiches Bild - aber die eingerueckten
     Untermenue-Zeilen bekommen dadurch keine eigene Linie. */
  .site-nav-mobile-links > li {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
  }
  .site-nav-mobile-links > li:first-child {
    border-top: 0;
  }

  /* Untermenue «Leistungen» - Mobile-Panel. Zeile aus Link und Umschalter, darunter das
     eingerueckte Klappmenue. Der Umschalter ist 44px breit/hoch (Fingerziel) und passt
     damit in die vorhandene Zeilenhoehe, ohne sie zu strecken. */
  .site-nav-mobile-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }
  .site-nav-mobile-row > a {
    flex: 1 1 auto;
  }
  .site-nav-mobile-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    margin-right: -0.6rem;
    padding: 0;
    border: 0;
    background: none;
    color: #eee;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .site-nav-mobile-toggle::after {
    content: "";
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid currentColor;
    transition: transform 0.3s ease;
  }
  .site-nav-mobile-item.is-open > .site-nav-mobile-row > .site-nav-mobile-toggle::after {
    transform: rotate(180deg);
  }
  /* Dieselbe Hoehen-Mechanik wie beim Panel selbst (0fr auf 1fr), siehe den Kommentar
     dort und im Markup. */
  .site-nav-mobile-sub {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.3s ease;
  }
  .site-nav-mobile-item.is-open > .site-nav-mobile-sub {
    grid-template-rows: 1fr;
  }
  .site-nav-mobile-sublinks {
    overflow: hidden;
    min-height: 0;
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .site-nav-mobile-sublinks a {
    padding: 0.7rem 0 0.7rem 1.25rem;
    font-size: 0.85rem;
    opacity: 0.85;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav-burger-line {
    transition: none;
  }
  .site-nav-mobile {
    transition: none;
  }
  .site-nav-submenu,
  .site-nav-submenu-toggle::after,
  .site-nav-mobile-toggle::after,
  .site-nav-mobile-sub {
    transition: none;
  }
}

/*
  Kompakter Seiten-Header für Unterseiten (Vermietung/Verkauf/Impressum/AGB/Webcam):
  Bild + Titel, im Gegensatz zum grossen Fixed-Parallax-Hero der Startseite bewusst simpel
  – kein eigener scroll-effects-Baustein nötig, reines statisches <img>.
*/
.page-hero {
  overflow: hidden;
}
.page-hero img {
  display: block;
  width: 100%;
  height: clamp(220px, 42vw, 460px);
  object-fit: cover;
  object-position: center;
}
.page-hero-title {
  background: #fff;
  color: #111;
  text-align: center;
  padding: 4rem 1.5rem 3rem;
}
/* Das Netz gegen zu lange Titel. Ein einzelnes langes Wort ohne Bindestrich hat keine
   Umbruchgelegenheit und schiebt sonst die ganze Seite seitlich hinaus – datenschutz.html
   lief so von Anfang an auf 443px Dokumentbreite, bei jeder Fensterbreite unter 470px.

   Es braucht beide Zeilen, keine allein reicht:

   hyphens ist plattformabhaengig. Die Seite ist lang="de", trotzdem trennt ein Browser nur,
   wenn er die deutschen Trennmuster mitbringt – nachgemessen: Chromium unter Linux tut das
   nicht (auch nicht als echtes Fenster, nur ohne Wortliste), Chrome und Safari auf macOS
   schon. Als alleinige Absicherung also unbrauchbar.

   overflow-wrap allein wiederum bricht stumpf nach Platz, ohne Bindestrich: aus
   «Datenschutzerklärung» wuerde «Datenschutzerklä / rung». Deshalb break-word und nicht
   anywhere – break-word greift erst, wenn ein Wort auch allein auf einer Zeile nicht passt,
   und ruehrt bestehende Umbrueche nicht an (ueber alle acht Seiten pixelweise geprueft).

   Der schoene Umbruch kommt darum weiterhin aus weichen Trennstellen im Markup (&shy;,
   siehe datenschutz.html); diese Regel ist nur die Rueckfallebene, damit kein kuenftiger
   Titel die Seite wieder seitlich wegschiebt. */
.page-hero-title h1 {
  font-size: clamp(2.2rem, 6vw, 3.5rem);
  font-weight: 800;
  margin: 0 0 0.75rem;
  hyphens: auto;
  overflow-wrap: break-word;
}
.page-hero-title p {
  color: #555;
  font-size: 1.05rem;
  max-width: 620px;
  margin: 0 auto;
}

/*
  Preis-/Artikel-Liste (Vermietung, Verkauf): eine Kategorie = Überschrift + Tabelle
  (Beschreibung/Typ | CHF). Mehrere .rental-category-Blöcke lassen sich beliebig
  untereinander stapeln, jede mit eigener .rental-table.
*/
.rental-list {
  padding: 1rem 1.5rem 5rem;
}
.rental-list .section-inner {
  max-width: 900px;
  margin: 0 auto;
}
.rental-category {
  margin-top: 3rem;
}
.rental-category h2 {
  font-size: 1.6rem;
  font-weight: 400;
  color: #666;
  margin: 0 0 1rem;
}
.rental-table {
  width: 100%;
  border-collapse: collapse;
}
.rental-table th,
.rental-table td {
  text-align: left;
  padding: 0.9rem 1rem;
}
.rental-table th:last-child,
.rental-table td:last-child {
  text-align: right;
}
.rental-table thead th {
  background: #d6d6d6;
  color: #222;
  font-weight: 700;
  font-size: 0.95rem;
}
.rental-table tbody tr {
  border-bottom: 1px solid #eaeaea;
}
.rental-table tbody tr:last-child {
  border-bottom: none;
}
/*
  Fusstext unter den Listen (Mindestbestellwert, MWST-Hinweis, Stand) – redaktionell
  über kai_edit_text änderbar, deshalb ein div mit <p> darin. Die Optik ist bewusst
  zurückhaltend: der Block ist Beiwerk zur Tabelle, keine eigene Aussage.
*/
.rental-footnote {
  margin-top: 3rem;
  color: #666;
  font-size: 0.95rem;
}
.rental-footnote p {
  margin: 0;
  line-height: 1.7;
}

/*
  Schlussblock unter der Verkaufsliste (verkauf.html): zwei gleich breite Spalten auf
  Desktop, untereinander sobald der Platz eng wird. Die Umbruchbreite ist bewusst keine
  Geräteschwelle, sondern der Punkt, an dem zwei Spalten in der 900px breiten
  .section-inner zu schmal werden. Schriftgrössen und Farben wie im übrigen Seitentext,
  nicht wie im WordPress-Original.
*/
.sales-outro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem 3rem;
  margin-top: 4rem;
  padding-top: 3rem;
  border-top: 1px solid #eaeaea;
}
@media (max-width: 720px) {
  .sales-outro {
    grid-template-columns: 1fr;
  }
}
/* Wie .rental-category h2 und .pricelist-category-title, eine Stufe kleiner – der Block
   ist Beiwerk zur Liste, keine weitere Kategorie. */
.sales-outro-col h2 {
  font-size: 1.3rem;
  font-weight: 400;
  color: #666;
  margin: 0 0 0.75rem;
}
.sales-outro-col p {
  margin: 0 0 0.75rem;
  line-height: 1.7;
}
.sales-outro-col p:last-child {
  margin-bottom: 0;
}
/* Mail-Zeile wie .legal-contact-line auf impressum.html: Icon und Text auf einer Linie,
   das Icon in der Linkfarbe dieser Website. Das Icon liegt hier INNERHALB des <a>
   (company-data-Marker, siehe verkauf.html), deshalb greift der flex-Container auf dem
   Link selbst und nicht auf dem Absatz. */
.sales-outro-contact {
  margin-top: 1rem;
}
.sales-outro-contact a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--site-accent);
  text-decoration: none;
  transition: color 0.2s ease;
}
.sales-outro-contact a:hover,
.sales-outro-contact a:focus-visible {
  color: var(--site-accent-hover);
  text-decoration: underline;
}
.sales-outro-contact svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.sales-outro-action {
  margin-top: 1.25rem;
}
/* Gescopte Umfaerbung statt .btn-link selbst zu aendern: .btn-link ist auch ein
   TinyMCE-Editorformat ("Button-Link", siehe cms/settings.php style_formats) und
   potenziell schon in echtem Seiteninhalt verwendet – eine globale Farbaenderung waere
   eine unbeabsichtigte Nebenwirkung fuer jede Seite, die das Format nutzt. Hier die
   Akzentfarbe der Seite (--site-accent, siehe :root) statt des generischen Standard-Blaus –
   dieselbe Farbe, die die Links tragen, hier als Flaeche mit weisser Schrift darauf.
   (Bis September 2026 stand dieselbe Begruendung auch bei .error-404 .btn-link; diese
   Regel ist mit dem Umbau der Fehlerseite weggefallen.) */
.sales-outro .btn-link {
  background: var(--site-accent);
}
.sales-outro .btn-link:hover,
.sales-outro .btn-link:focus-visible {
  background: var(--site-accent-hover);
}

/*
  Rechtstext-Seiten (Impressum, AGB): Default einspaltig (schmale Lesebreite). Mit
  Modifier-Klasse .legal-content--two-col zweispaltig (Impressum) – jede .legal-col
  ist ein eigener, unabhängig gefüllter Textblock (kein interleaved Grid-Autoflow).
*/
.legal-content {
  padding: 1rem 1.5rem 5rem;
}
.legal-content .section-inner {
  max-width: 760px;
  margin: 0 auto;
}
/* Zweispaltig bewusst NICHT wie die einspaltige Variante als schmaler, zentrierter
   900px-Block – dadurch stand die linke Spalte sichtbar eingerückt gegenüber dem
   Logo. Stattdessen dasselbe Box-Modell wie .site-nav-inner: volle
   --site-content-width, Padding direkt auf demselben Element statt auf dem
   Eltern-<section> – so landet die linke Spalte exakt auf derselben Flucht wie
   das Logo in der Nav. */
.legal-content.legal-content--two-col {
  padding-left: 0;
  padding-right: 0;
}
.legal-content.legal-content--two-col .section-inner {
  max-width: var(--site-content-width);
  padding: 0 1.5rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 3rem;
}
/* Beide Spalten zentriert. */
.legal-content.legal-content--two-col .legal-col {
  text-align: center;
}
@media (max-width: 640px) {
  .legal-content.legal-content--two-col .section-inner {
    grid-template-columns: 1fr;
  }
}
.legal-col h2 {
  font-size: 1.15rem;
  margin: 2.25rem 0 0.6rem;
}
/* Erste Überschrift OHNE oberen Abstand – bei allen Spalten, nicht nur der linken,
   sonst startet z.B. bei Impressum die rechte Spalte ("Handelsregister:") sichtbar
   tiefer als die linke ("Verantwortlich für den Inhalt:") statt auf gleicher Höhe. */
.legal-col h2:first-child,
.legal-content:not(.legal-content--two-col) h2:first-child {
  margin-top: 0;
}
.legal-col p,
.legal-content p {
  margin: 0 0 1rem;
  line-height: 1.6;
  color: #333;
}
.legal-contact-line {
  /* inline-flex statt flex: als Block würde die Zeile immer die volle Spaltenbreite
     einnehmen und intern linksbündig bleiben (justify-content-Default), egal was
     text-align auf dem Vorfahren sagt – als Inline-Element folgt sie dagegen ganz
     normal dem text-align:center der Spalte, wie der Rest des Texts. */
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.legal-contact-line svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--site-accent);
}
.legal-col a,
.legal-content a {
  color: var(--site-accent);
  text-decoration: none;
  transition: color 0.2s ease;
}
.legal-col a:hover,
.legal-col a:focus-visible,
.legal-content a:hover,
.legal-content a:focus-visible {
  color: var(--site-accent-hover);
}

/*
  Webcam-Seite: zweispaltig, Player (breiter) links + Meteo-Kasten (schmaler, ca. 35%)
  rechts, per fr-Einheiten statt Prozent (verrechnet sich automatisch korrekt mit dem
  gap). Unter 900px eine Spalte, Meteo-Kasten unter den Player gestapelt. Radius/Grauton
  des Kastens bewusst an den Iframe selbst angelehnt (der bringt sein eigenes
  border-radius:12px per Inline-Style mit, siehe Kunden-Markup) statt neu erfunden.
*/
.webcam-layout {
  padding: 1rem 1.5rem 5rem;
}
.webcam-layout .section-inner {
  max-width: var(--site-content-width);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 65fr 35fr;
  gap: 2rem;
  align-items: start;
}
@media (max-width: 900px) {
  .webcam-layout .section-inner {
    grid-template-columns: 1fr;
  }
}
.webcam-player iframe {
  width: 100%;
}
.webcam-sidebar {
  background: #f0f0f0;
  border-radius: 12px;
  padding: 1.5rem;
}
.webcam-sidebar iframe {
  width: 100%;
}

/*
  Footer – hell, 3 Spalten (Kontakt/Über Uns/Menü) + Bottom-Bar mit Copyright + Credit.
  Farben/Icons nach Referenz-Screenshot der Originalseite.
*/
.site-footer {
  /* position+z-index nötig, da <footer> (anders als <section>) keine eigene
     Stacking-Order von einer generischen section-Regel erbt – auf der Startseite würde
     sonst der fixierte Hero-Hintergrund den Footer trotz normaler Dokumentreihenfolge
     überdecken. Auf Unterseiten schadet es nicht, hier trotzdem gesetzt zu lassen. */
  position: relative;
  z-index: 1;
  background: #f0f0f0;
  color: #333;
  /* Bewusst KEIN horizontales Padding hier – sonst rückt die Bottom-Bar (die die volle
     Footer-Breite ausfüllen soll) seitlich ein und zeigt einen Rand des Seitenhintergrunds.
     Das Padding sitzt stattdessen konsequent auf den -inner-Elementen, damit Kontakt-
     Formular oben, Footer-Spalten und Copyright-Zeile alle exakt dieselbe linke/rechte
     Kante haben. */
  padding: 4.5rem 0 0;
}
.site-footer-inner {
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 0 1.5rem 3rem;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
}
@media (max-width: 640px) {
  .site-footer-inner {
    grid-template-columns: 1fr;
    gap: 2.25rem;
  }
}
.footer-col h3 {
  font-size: 1.05rem;
  margin: 0 0 1.1rem;
  color: #111;
}
.footer-col address {
  font-style: normal;
  line-height: 1.6;
}
.footer-col address strong {
  display: block;
  color: #111;
}
.footer-contact-line {
  margin: 0.9rem 0 0;
}
/* Icon liegt INNERHALB des <a> (nicht daneben) – Klickfläche/Cursor:pointer gilt
   dadurch auch über dem Icon, nicht nur über dem Text (wie beim netzdienst-Link
   unten in der Bottom-Bar). */
.footer-contact-line a {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.footer-contact-line svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--site-accent);
}
.footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.footer-col a {
  color: var(--site-accent);
  text-decoration: none;
  transition: color 0.2s ease;
}
.footer-col a:hover,
.footer-col a:focus-visible {
  color: var(--site-accent-hover);
}

.site-footer-bottom {
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  background: #e4e4e4;
}
.site-footer-bottom-inner {
  max-width: var(--site-content-width);
  margin: 0 auto;
  padding: 1.1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-size: 0.82rem;
  color: #666;
}
/*
  Die Copyright-Zeile ist seit September 2026 ein Link aufs Impressum. Im Ruhezustand soll
  sie aussehen wie vorher – Farbe (#666) und Grösse erbt sie von .site-footer-bottom-inner;
  die Browser-Voreinstellung für Links (Blau, unterstrichen) wäre hier ein Fremdkörper und
  würde die ganze Zeile herausschreien. Erst beim Darüberfahren gibt sie sich als Link zu
  erkennen, in derselben Farbe wie .footer-credit daneben.
*/
.footer-copyright a {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}
.footer-copyright a:hover,
.footer-copyright a:focus-visible {
  color: var(--site-accent);
  text-decoration: underline;
}

.footer-credit {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--site-accent);
  text-decoration: none;
  transition: color 0.2s ease;
}
.footer-credit svg {
  width: 16px;
  height: 16px;
}
.footer-credit:hover,
.footer-credit:focus-visible {
  color: var(--site-accent-hover);
}

/*
  Rakete ist immer sichtbar (kein Fade-In) und "steigt" per kurzer Animation, sobald sie
  in den Viewport kommt – wiederholbar bei jedem Rein-/Rausscrollen, nicht nur beim
  ersten Laden. Trigger per IntersectionObserver in blankton-shared.js, der die Klasse
  is-rising bei jedem erneuten Eintritt entfernt+neu setzt (per rAF verzögert, sonst
  startet die CSS-Animation in Firefox/Brave beim zweiten Mal nicht neu).
*/
.footer-credit svg.is-rising {
  animation: footer-rocket-launch 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes footer-rocket-launch {
  0% { transform: translateY(14px) rotate(-10deg) scale(0.85); }
  60% { transform: translateY(-13px) rotate(5deg) scale(1.1); }
  100% { transform: translateY(0) rotate(0deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .footer-credit svg.is-rising {
    animation: none;
  }
}

/*
  Back-to-Top-Button: fixiert unten rechts, erscheint erst nach etwas Scroll-Distanz
  (sonst stört er auf der Startansicht), reiner Klick-Scroll ohne Scroll-Bezug im Sinne
  von "Effekt" – deshalb bespoke wie Burger-Menü, nicht Teil der scroll-effects-Bausteine.
*/
.back-to-top {
  position: fixed;
  right: 1.5rem;
  bottom: 6rem; /* Bottom-Bar des Footers ist ~78px hoch (Copyright + netzdienst-Link) –
                   Button sonst als fixed-Element darüber, würde den Link verdecken */
  z-index: 20;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #1a1a1a;
  border: none;
  border-radius: 6px;
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease, background-color 0.2s ease;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover,
.back-to-top:focus-visible {
  background: #333;
}
.back-to-top svg {
  width: 20px;
  height: 20px;
}
@media (prefers-reduced-motion: reduce) {
  .back-to-top {
    transition: opacity 0.15s ease;
  }
}

/*
  Cursor-Dot (Effekt 7): Grösse leicht an die blankTon-Optik angepasst. Farbe bewusst
  NICHT auf die Markenfarbe (Gelb) gesetzt – mix-blend-mode: difference kontrastiert
  ohnehin automatisch mit dem Untergrund; ein reines Weiss liefert dabei über allen
  Bildern/Farben der Seite die zuverlässigste Sichtbarkeit.
*/
.cursor-dot {
  --cursor-dot-size: 12px;
  --cursor-dot-active-size: 48px;
}

/* ===========================================================================
   3. STARTER-SCHALE
   ===========================================================================
   Topbar, Header/Logo, mainnav, Sections und Footer aus dem KAI-Starter-Paket.
   Keine der sechs blankTon-Seiten benutzt dieses Markup; die einzige Seite, die
   noch so gebaut ist, ist 404.html. Bleibt erhalten, damit 404.html nicht
   unformatiert dasteht und eine kuenftige Seite aus der Starter-Vorlage sofort
   sitzt.

   Zwei der Regeln hier waren Element-Selektoren ohne Einschraenkung (header,
   footer) und griffen dadurch auf das blankTon-Markup durch — siehe die
   Kommentare an Ort und Stelle.
   =========================================================================== */

/* line-height stand frueher global auf body und griff dadurch auch auf die sechs
   blankTon-Seiten durch (+112px Dokumenthoehe allein auf der Startseite). Hier ist sie
   genau dort, wo sie hingehoert: auf den Seiten der Starter-Schale sitzt jeder Text in
   einem .wrap, und keine der sechs blankTon-Seiten benutzt diese Klasse. */
.wrap {
	line-height: 1.6;
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 24px;
}

/* TOP BAR (Firmendaten-Beispiel 1) */

.topbar {
	background: #2f5d50;
	color: #eaf3f0;
	font-size: 13px;
	padding: 6px 0;
}

.topbar .wrap {
	display: flex;
	gap: 24px;
	flex-wrap: wrap;
}

.topbar a.company-data {
	color: #eaf3f0;
	text-decoration: none;
}

.topbar a.company-data:hover {
	text-decoration: underline;
}

/* HEADER / NAV */

/* :not(.site-nav) eingegrenzt: als blosses "header" traf diese Regel auch
   <header class="site-nav sticky-header"> der sechs blankTon-Seiten und machte die Nav
   66px -> 105px hoch samt heller Unterkante. Element-Selektor (0,0,1) verliert nicht
   gegen .site-nav (0,1,0), solange .site-nav padding/border gar nicht erst setzt — die
   Reihenfolge im Stylesheet half hier also nichts, nur die Eingrenzung. */
header:not(.site-nav) {
	border-bottom: 1px solid #eee;
	padding: 18px 0;
}

header .wrap {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
}

.logo {
	font-size: 22px;
	font-weight: 700;
	letter-spacing: 0.5px;
	color: #2b2b2b;
	text-decoration: none;
}

/* Nur oberhalb des Mobile-Breakpoints (siehe @media (max-width: 720px) weiter unten) -
bewusst NICHT unbedingt gesetzt: dieselbe Selektor-Spezifitaet wie die
Sichtbarkeits-Mechanik in system.css (nav.mainnav ul.mainnav-list) wuerde sonst bei
gleichem Spezifitaetswert allein durch die spaetere Ladereihenfolge von styles.css
gewinnen und "display:flex" auch auf schmalen Viewports erzwingen - der Button liesse
sich dann zwar anklicken, das Panel bliebe aber unsichtbar bzw. (wie hier) immer offen. */
@media (min-width: 721px) {
	nav.mainnav ul.mainnav-list {
		display: flex;
		align-items: center;
		gap: 28px;
	}
}

nav.mainnav a,
nav.mainnav .mainnav-toggle {
	color: #555;
	text-decoration: none;
	font-size: 15px;
	padding: 6px 0;
	border-bottom: 2px solid transparent;
	cursor: pointer;
}

/* .mainnav-toggle ist jetzt ein eigenstaendiger <button> NEBEN dem Label-Link (nicht mehr
der Link selbst, siehe menu.js renderItem()) - reine Browser-Button-Defaults (Rahmen/
Hintergrund/Schrift) zuruecksetzen, damit er wie zuvor als reiner Pfeil erscheint. */
nav.mainnav .mainnav-toggle {
	background: transparent;
	border-top: none;
	border-left: none;
	border-right: none;
	font-family: inherit;
	padding: 6px 4px;
}

nav.mainnav a:hover,
nav.mainnav a.active,
nav.mainnav .mainnav-toggle:hover {
	color: #2b2b2b;
	border-bottom-color: #2f5d50;
}

/* Kleiner Pfeil als Hinweis auf ein Untermenue - reines CSS, kein zusaetzliches Icon-Markup.
Der Button selbst hat keinen Text mehr (nur noch dieses Pseudo-Element), daher kein
margin-left mehr noetig (frueher: Abstand zum vorangehenden Label-Text im selben Element). */
nav.mainnav .mainnav-item.has-dropdown > .mainnav-toggle:after {
	content: '▾';
	display: inline-block;
	font-size: 11px;
}

nav.mainnav ul.mainnav-dropdown {
	background: #fff;
	border: 1px solid #eee;
	border-radius: 6px;
	box-shadow: 0 10px 24px rgba(0,0,0,0.09);
	padding: 8px 0;
	margin-top: 10px;
}

/* Unsichtbare Bruecke ueber die 10px Luecke aus margin-top oben (siehe system.css:
das Dropdown klappt per :hover auf .mainnav-item.has-dropdown auf/zu - :hover bleibt nur
aktiv, solange die Maus ueber .mainnav-item selbst oder einem seiner Nachfahren steht).
Ohne diese Bruecke verlaesst die Maus beim geraden Herunterbewegen vom Hauptmenuepunkt
zu einem Untermenuepunkt kurzzeitig JEDE hoverbare Flaeche (weder mehr ueber Label/Pfeil
noch schon ueber dem sichtbaren Dropdown-Kasten) - :hover faellt weg, das Dropdown klappt
per CSS sofort wieder zu, BEVOR der Klick auf den Untermenuepunkt ueberhaupt registriert
werden kann. Nur der explizite Klick auf den Pfeil-Button (setzt .is_open statisch, siehe
menu.js) blieb davon unberuehrt, weil er nicht von :hover abhaengt. Die Bruecke ist als
Nachfahre von .mainnav-dropdown selbst Teil von dessen Hover-Kette, transparent und
veraendert daher nichts am sichtbaren Erscheinungsbild. */
nav.mainnav ul.mainnav-dropdown:before {
	content: '';
	position: absolute;
	top: -10px;
	left: 0;
	right: 0;
	height: 10px;
}

nav.mainnav ul.mainnav-dropdown a {
	display: block;
	padding: 9px 20px;
	border-bottom: none;
	white-space: nowrap;
	font-size: 14px;
}

nav.mainnav ul.mainnav-dropdown a:hover,
nav.mainnav ul.mainnav-dropdown a.active {
	background: #f7f7f5;
	color: #2f5d50;
}

/* Klassisches 3-Balken-Icon, per JS als drei <span> ins Burger-Button-Markup gesetzt
(cms/js/menu.js). display bewusst NICHT hier gesetzt (nur Groesse/Anordnung) - ob der
Button ueberhaupt sichtbar ist (display:none auf breiten, display:flex auf schmalen
Viewports), steuert allein system.css; wuerde hier zusaetzlich ein unbedingtes
display:flex stehen, ueberschriebe das (spaeter geladen) dessen display:none auf dem
Desktop, der Button bliebe faelschlich immer sichtbar. */
.mainnav-burger {
	width: 26px;
	height: 20px;
	flex-direction: column;
	justify-content: space-between;
}
.mainnav-burger span {
	display: block;
	height: 2px;
	background: #2b2b2b;
	border-radius: 1px;
}

/* SECTIONS */

section { padding: 50px 0; }
section.alt { background: #f7f7f5; }
h2 { font-size: 26px; margin: 0 0 24px; }

/* FOOTER (Firmendaten-Beispiel 3) */

/* :not(.site-footer) eingegrenzt, gleicher Grund wie bei header:not(.site-nav) oben:
   als blosses "footer" setzte diese Regel dem blankTon-Footer eine helle Oberkante auf
   und schrumpfte seine Schrift von 18px auf 13px. footer .wrap braucht keine Eingrenzung,
   .wrap kommt im blankTon-Markup nicht vor. Die beiden a.company-data-Regeln dagegen
   schon: seit die Kontaktdaten im Footer aus dem Kontaktdaten-Panel kommen, tragen die
   beiden Footer-Links dort die Klasse .company-data, und "footer a.company-data" (0,1,2)
   schlaegt ".footer-col a" (0,1,1) — der Link stand dadurch in #666 statt im
   blankTon-Petrol. Deshalb gleich eingegrenzt wie die Regel darueber. */
footer:not(.site-footer) {
	border-top: 1px solid #eee;
	padding: 30px 0;
	color: #666;
	font-size: 13px;
}
footer .wrap {
	display: flex;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px;
}
footer:not(.site-footer) a.company-data { color: #666; text-decoration: none; }
footer:not(.site-footer) a.company-data:hover { text-decoration: underline; }

/* ===========================================================================
   4. ENGINE-FEATURES
   ===========================================================================
   Optik der zuschaltbaren Engine-Bausteine. Struktur und Mechanik dazu stehen in
   cms/css/system.css und den Skripten unter cms/js/ — ohne diesen Abschnitt sieht
   ein eingeschaltetes Feature unformatiert aus. Vollstaendig erhalten, auch wo ein
   Feature hier nie benutzt wird; ungenutzte Regeln kosten Kilobyte, ein fehlender
   Block kostet eine Fehlersuche. Bitte nicht "aufraeumen".
   =========================================================================== */

/* GALLERY */

.gallery_item img { width: 100%; border-radius: 6px; display: block; object-fit: cover; object-position: center; }

/* .kai_lightbox_image (cms/js/lightbox.js) is a general, reusable "fixed-size thumbnail with a
   click-to-enlarge lightbox" pattern (see the CMS's own "Hilfe" panel), always paired with
   .kai_edit_image data-type="thumb_and_big_image" and explicit width/height attributes -
   a fixed-dimension image box by definition. Every current use of it (team.html/
   ueber-uns.html's member photos, gallery_item.html) happens to also sit inside .card or
   .gallery_item, both already covered above - so this rule doesn't change how any existing
   page renders today. Added anyway as its own direct, explicit rule (same fix as
   fix/image-object-fit-cover, 2026-08-12, applied here) rather than relying on that
   incidental ancestor coverage - a standalone .kai_lightbox_image outside of either wrapper
   (a single portrait/photo, not in a grid) would otherwise still get the browser's default
   object-fit: fill and distort any image that doesn't already exactly match its box. */
.kai_lightbox_image { object-fit: cover; object-position: center; }

/* TINYMCE-FORMATE (Optik - Konfiguration in cms/settings.php $tinymcedivoptions style_formats)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (die Editor-Formate
"Zitat"/"Info-Box"/"Warnung"/"Button-Link" im TinyMCE-Dropdown setzen ausschliesslich diese
Klassen - hier komplett frei anpassbar, es gibt keine Struktur-/Mechanik-Gegenrolle in
cms/css/system.css, da diese Formate rein statischer Content sind, keine JS-Mechanik haben):
- .quote: Zitat-Block (Randfarbe, Kursivschrift, Textfarbe).
- .infobox / .infobox-info / .infobox-warning: Hervorhebungs-Box, Basis-Look in .infobox,
  Farbvarianten in den beiden Zusatzklassen (info = neutral, warning = Warnhinweis).
- .btn-link: Button-artig gestylter Link im Fliesstext (z.B. ein "Jetzt anrufen"-CTA). */

.quote {
	margin: 20px 0;
	padding: 4px 20px;
	border-left: 4px solid #4a6fa5;
	font-style: italic;
	color: #666;
}

.infobox {
	margin: 20px 0;
	padding: 16px 20px;
	border-radius: 6px;
	border-left: 4px solid #888;
	background: #f7f7f5;
}

.infobox-info {
	background: #eef3fa;
	border-left-color: #4a6fa5;
}

.infobox-warning {
	background: #fdf3e0;
	border-left-color: #d99a2b;
}

.btn-link {
	display: inline-block;
	padding: 10px 22px;
	border-radius: 6px;
	background: #4a6fa5;
	color: #fff;
	text-decoration: none;
	transition: background-color 0.15s ease;
}

.btn-link:hover {
	background: #3c5c8a;
}

/* 404-SEITE (404.html, ueber .htaccess/ErrorDocument ausgeliefert - siehe dort)

Seit September 2026 nach dem Vorbild von blankton.ch/404 gebaut: ein kurzer Clip als
Flaeche, der Text mittig darueber. Die frueheren Starter-Regeln (.error-404-code fuer eine
grosse "404"-Zahl, .error-404 .btn-link fuer den gefuellten Knopf) sind mit der
Starter-Schale weggefallen - beide Klassen kommen in dieser Installation nicht mehr vor. */

.error-404 {
	position: relative;
	min-height: 72vh;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	text-align: center;
	/* Grundton des Standbilds - steht da, solange poster und Clip noch nicht geladen sind,
	   damit die Flaeche nie schwarz aufblitzt. */
	background: #eceeef;
}

/* Der Clip fuellt die Flaeche formattreu: object-fit "cover" schneidet ueber- stehende
   Raender ab, statt das Bild zu verzerren - wichtig auf schmalen Fenstern, wo ein
   16:9-Clip sonst gestaucht wuerde. */
.error-404-video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
}

.error-404-inner {
	position: relative;
	z-index: 1;
	padding: 7rem 1.5rem 4rem; /* oben mehr, die Nav liegt fixiert darueber */
	max-width: 40rem;
}

/* Weicher weisser Schleier NUR hinter dem Text, nicht ueber dem ganzen Clip: im Video
   zieht ein dunkel gekleideter Fahrer durch die Bildmitte, gemessen bis hinunter auf
   reines Schwarz im Textband - #111 darauf ergaebe 1.11:1 und waere unlesbar. Ein Schleier
   ueber der ganzen Flaeche haette das Bild flach gewaschen; diese Ellipse laesst die
   Raender frei und bringt den Text auf ueber 15:1, auch im dunkelsten Einzelbild.
   Liegt hinter dem Text (z-index -1 innerhalb von .error-404-inner) und faengt keine
   Klicks ab (pointer-events: none). */
.error-404-inner::before {
	content: "";
	position: absolute;
	inset: -6rem -5rem;
	z-index: -1;
	pointer-events: none;
	background: radial-gradient(ellipse 50% 45% at center,
		rgba(255, 255, 255, 0.72) 0%,
		rgba(255, 255, 255, 0.70) 70%,
		rgba(255, 255, 255, 0) 100%);
}

.error-404 h1 {
	font-size: clamp(2rem, 5vw, 2.6rem);
	font-weight: 700;
	color: #111;
	margin: 0 0 1.2rem;
}

/* 1.4rem = 25px bei der 18px-Basis: damit zaehlt die Zeile als grosse Schrift und der
   Kontrast-Massstab 3:1 statt 4.5:1 gilt - der Schleier oben liegt ohnehin weit darueber. */
.error-404 .kai_edit_text p {
	font-size: 1.4rem;
	line-height: 1.45;
	color: #111;
	margin: 0;
}

.error-404-action {
	margin: 2rem 0 0;
}

/* Wie im Original: nur Rahmen, keine Fuellung, keine abgerundeten Ecken. currentColor
   haelt Rahmen und Schrift automatisch zusammen. */
.error-404-btn {
	display: inline-block;
	padding: 0.75rem 1.5rem;
	border: 2px solid currentColor;
	color: #111;
	background: none;
	text-decoration: none;
	font-size: 1.05rem;
	transition: color 0.2s ease, background-color 0.2s ease;
}

.error-404-btn:hover,
.error-404-btn:focus-visible {
	background: #111;
	color: #fff;
}

@media (max-width: 640px) {
	.error-404 {
		min-height: 80vh;
	}
	.error-404-inner {
		padding: 6rem 1.25rem 3rem;
	}
	/* Auf schmalen Fenstern schrumpft der Textblock, der Schleier muss dann anders
	   sitzen: gemessen ueber reinem Schwarz kaeme er sonst auf 3.2:1 herunter, so auf
	   14.4:1. */
	.error-404-inner::before {
		inset: -5rem -3rem;
		background: radial-gradient(ellipse 70% 50% at center,
			rgba(255, 255, 255, 0.72) 0%,
			rgba(255, 255, 255, 0.70) 70%,
			rgba(255, 255, 255, 0) 100%);
	}
}

/* COOKIE-CONSENT-BANNER (Optik - Struktur/Mechanik in cms/css/system.css, js/cookieconsent.js) */

.cookieconsent_accept, .cookieconsent_embed_accept {
	background: #2f5d50;
}
.cookieconsent_accept:hover, .cookieconsent_embed_accept:hover {
	background: #244a3f;
}
.cookieconsent_reject:hover {
	border-color: #999;
	color: #333;
}

/* POPUP (Optik - Struktur/Mechanik in cms/css/system.css, js/popup.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (siehe cms/css/
system.css fuer die Struktur/Mechanik dieser Klassen - dort bewusst NICHT ueberschreiben,
Aenderungen gehoeren hierher):
- .popup_overlay: Hintergrund/Abdunkelung hinter dem Dialog (z.B. andere Farbe/Deckkraft).
- .popup_dialog: Look der Dialog-Box selbst (Hintergrundfarbe, Eckenradius, Innenabstand,
  text-align fuer zentrierten statt linksbuendigen Inhalt).
- .popup_close: Farbe des Schliessen-Buttons (Normal-/Hover-Zustand).
- .popup_image: Abstand/Eckenradius des optionalen Bildes.
- .popup_text: Typografie des Textinhalts (Schriftgroesse, Zeilenabstand, Farbe). */

.popup_overlay {
	background: rgba(20,20,20,0.75);
}
.popup_dialog {
	background: #fff;
	border-radius: 6px;
	padding: 40px 30px 30px;
}
.popup_close {
	background: transparent;
	color: #666;
}
.popup_close:hover {
	color: #111;
}
.popup_image {
	margin: 0 0 20px;
	border-radius: 4px;
}
.popup_text {
	font-size: 16px;
	line-height: 1.5;
	color: #333;
}
.popup_text p { margin: 0 0 14px; }
.popup_text p:last-child { margin-bottom: 0; }

/* LIGHTBOX (Optik - Struktur/Mechanik in cms/css/system.css, js/lightbox.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (siehe cms/css/
system.css fuer die Struktur/Mechanik dieser Klassen - dort bewusst NICHT ueberschreiben,
Aenderungen gehoeren hierher):
- .lightbox_overlay: Abdunkelung hinter dem Grossbild (Farbe/Deckkraft).
- .lightbox_img: Eckenradius des Grossbilds.
- .lightbox_caption: Typografie der Bildunterschrift (Farbe, Schriftgroesse, Abstand nach
  oben). Der Text kommt aus dem alt-Attribut des Thumbnails, das der Dateimanager aus der
  gespeicherten Dateibeschreibung setzt (siehe lightbox.js).
- .lightbox_close / .lightbox_prev / .lightbox_next: Look der drei Bedienknoepfe -
  Hintergrund, Textfarbe, Schriftgroesse des Symbols, Eckenradius, Hover-Zustand. Ihre
  Groesse (44 bzw. 52 px) und ihre Position stehen bewusst NICHT hier, sondern in
  system.css: das ist die Trefferflaeche fuer den Finger, nicht Gestaltung.
- .lightbox_fields / .lightbox_field / .lightbox_field_label / .lightbox_field_value:
  die beschrifteten Felder eines Referenz-Eintrags unter der Bildunterschrift (siehe
  cse/referenz_item.html und renderFields() in js/lightbox.js) - Spaltenaufteilung,
  Typografie, Abstaende. Die Beschriftungen selbst stehen als data-label in der Vorlage,
  nicht hier und nicht im Skript.
Nicht hier, aber von hier aus ueberschreibbar: die Zentrierung der Bildunterschrift
(text-align auf .lightbox_figure) steht in system.css, weil eine linksbuendige Unterschrift
unter einem zentrierten Bild nach Fehler aussieht - system.css wird zuerst geladen. */

.lightbox_overlay {
	background: rgba(20,20,20,0.92);
}

.lightbox_img {
	border-radius: 4px;
}

.lightbox_caption {
	color: #eee;
	font-size: 14px;
	margin-top: 12px;
}

.lightbox_close, .lightbox_prev, .lightbox_next {
	background: rgba(255,255,255,0.1);
	color: #fff;
}

.lightbox_close { font-size: 32px; border-radius: 50%; }
.lightbox_prev, .lightbox_next { font-size: 34px; border-radius: 50%; }

.lightbox_close:hover, .lightbox_prev:hover, .lightbox_next:hover { background: rgba(255,255,255,0.25); }

.lightbox_fields {
	margin-top: 14px;
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 4px 14px;
	font-size: 14px;
	line-height: 1.45;
}

.lightbox_field {
	display: contents;
}

.lightbox_field_label {
	color: #999;
}

.lightbox_field_value {
	color: #eee;
}

/* REFERENZ-FELDER AUF DER SEITE (Struktur/Mechanik: cse/referenz_item.html,
js/lightbox.js, body.editing wird von cms.js gesetzt)

Die vier Felder eines Referenz-Eintrags gehoeren zum Grossbild, nicht zur Uebersicht: fuer
Besucher stehen sie deshalb im Markup, aber nicht im Bild. Sichtbar werden sie nur im
Bearbeitungsmodus, damit die Redaktion sie direkt am Eintrag pflegen kann - dasselbe
Zwei-Regel-Muster wie .cms_pagemetadescription_bar in cms/css/cms.css, nur hier statt dort,
weil cms.css auf einer Kundenseite gar nicht geladen wird.

Umgeschaltet wird ausschliesslich die SICHTBARKEIT, nie die Existenz: save.php ordnet die
gespeicherten Werte rein ueber die Position im Dokument zu, ein weggelassenes Feld wuerde
alle folgenden Werte um eins verschieben.

Vorgesehene Customization-Hooks: Abstaende und Typografie der Felder im Bearbeitungsmodus
sowie die Beschriftung ueber ::before - der Text dafuer kommt aus data-label in der
Vorlage. */

.kai_refitem_fields {
	display: none;
}

body.editing .kai_refitem_fields {
	display: block;
	margin-top: 10px;
}

body.editing .kai_refitem_field {
	font-size: 14px;
	line-height: 1.5;
	min-height: 1.5em;
}

body.editing .kai_refitem_field:before {
	content: attr(data-label) ": ";
	color: #999;
}

@media (max-width: 720px) {
	/* .mainnav-list ist auf schmalen Viewports das aufklappbare Burger-Panel (Sichtbarkeit/
	Positionierung: system.css) - hier nur die Optik dieses Panels. */
	nav.mainnav ul.mainnav-list {
		background: #fff;
		border: 1px solid #eee;
		border-radius: 6px;
		box-shadow: 0 10px 24px rgba(0,0,0,0.09);
		padding: 8px 0;
		margin-top: 10px;
		min-width: 200px;
		gap: 0;
	}
	nav.mainnav ul.mainnav-list a,
	nav.mainnav ul.mainnav-list .mainnav-toggle {
		display: block;
		padding: 10px 20px;
		border-bottom: none;
	}
	nav.mainnav ul.mainnav-list a:hover,
	nav.mainnav ul.mainnav-list a.active,
	nav.mainnav ul.mainnav-list .mainnav-toggle:hover {
		background: #f7f7f5;
		border-bottom: none;
	}
	/* Elternpunkt mit eigenem Link (a) UND Ausklapp-Button (.mainnav-toggle) sind zwei
	getrennte Geschwister-Elemente im selben <li> (siehe menu.js) - ohne diese Regel wuerde
	obiges "display:block" beide untereinander stapeln (der Button dann als eigene,
	fast leere Zeile nur mit dem Pfeil). Per flex-wrap in eine Zeile nebeneinander, das
	Dropdown (flex-basis:100%) faellt dabei automatisch in die naechste Zeile.
	list-style:none/margin:0 gleichen aus, dass dieses <li> jetzt selbst der Flex-
	Container ist statt nur eines seiner Kind-Links. */
	nav.mainnav ul.mainnav-list li.mainnav-item.has-dropdown {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		list-style: none;
		margin: 0;
	}
	nav.mainnav ul.mainnav-list li.mainnav-item.has-dropdown > a {
		flex: 1 1 auto;
	}
	nav.mainnav ul.mainnav-list li.mainnav-item.has-dropdown > .mainnav-toggle {
		flex: 0 0 auto;
		padding: 10px 20px;
	}
	nav.mainnav ul.mainnav-list li.mainnav-item.has-dropdown > ul.mainnav-dropdown {
		flex-basis: 100%;
	}

	/* Untermenue stapelt sich eingerueckt UNTER seinem Ausloeser (position:static kommt
	aus system.css) statt schwebend danebenzuklappen - passt zur bereits senkrechten
	Burger-Liste. */
	nav.mainnav ul.mainnav-dropdown {
		box-shadow: none;
		border: none;
		margin: 0;
		padding-left: 14px;
		display: none;
	}
	nav.mainnav li.mainnav-item.has-dropdown.is_open > ul.mainnav-dropdown {
		display: block;
	}
	nav.mainnav ul.mainnav-dropdown a {
		padding: 9px 20px 9px 14px;
	}
}

/* TERMINE/KALENDER (Optik - Struktur/Mechanik in cms/css/system.css, js/calendar.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (siehe cms/css/
system.css fuer die Struktur/Mechanik dieser Klassen - dort bewusst NICHT ueberschreiben,
Aenderungen gehoeren hierher):
- .calendar-widget: Breite/Aussenabstand des gesamten Widgets.
- .calendar-view-button, .calendar-filter (+ .is_active-Varianten): Look der Liste/Monat-
  Umschalter und Kategorie-Filter-Pills (Farben, Rahmen, Radius).
- .calendar-list-item + Sub-Klassen (.calendar-list-date/-day/-time/-title/-location/
  -description): Look eines einzelnen Termin-Eintrags in der Listenansicht (Farben,
  Abstaende, Typografie, text-align fuer zentrierten statt linksbuendigen Inhalt).
- .calendar-dot: Farbe/Groesse der Kategorie-Farbpunkte.
- .calendar-grid-*: Look der Monatsansicht (Raster-Zellen, Wochentags-Kopfzeile, aktiver/
  heutiger Tag). */

.calendar-widget {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 24px;
}

.calendar-toolbar {
	gap: 16px;
}

.calendar-view-button {
	font-size: 13px;
	color: #555;
	padding: 7px 16px;
	border: 1px solid #ddd;
}
.calendar-view-button:first-child { border-radius: 20px 0 0 20px; }
.calendar-view-button:last-child { border-radius: 0 20px 20px 0; margin-left: -1px; }

.calendar-view-button.is_active {
	background: #2f5d50;
	color: #fff;
	border-color: #2f5d50;
}

.calendar-filter {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
	color: #555;
	padding: 6px 14px;
	margin: 0 8px 8px 0;
	border: 1px solid #ddd;
	border-radius: 20px;
}

.calendar-filter.is_active {
	background: #f7f7f5;
	color: #2b2b2b;
	border-color: #2b2b2b;
}

.calendar-filter .calendar-dot {
	width: 9px;
	height: 9px;
}

.calendar-body {
	margin-top: 24px;
}

.calendar-empty {
	color: #999;
	font-size: 14px;
}

.calendar-month-heading {
	font-size: 18px;
	margin: 28px 0 14px;
	color: #2b2b2b;
}
.calendar-month-group:first-child .calendar-month-heading {
	margin-top: 0;
}

.calendar-list-item {
	gap: 20px;
	padding: 14px 0;
	border-bottom: 1px solid #eee;
}

.calendar-list-date {
	width: 130px;
	flex-shrink: 0;
}

.calendar-list-day {
	font-size: 13px;
	color: #666;
}

.calendar-list-time {
	font-size: 13px;
	color: #999;
}

.calendar-dot {
	width: 10px;
	height: 10px;
	margin-right: 4px;
	flex-shrink: 0;
}

.calendar-list-title {
	font-size: 16px;
	font-weight: 700;
	color: #2b2b2b;
}

.calendar-list-location {
	font-size: 13px;
	color: #666;
	margin-top: 2px;
}

.calendar-list-description {
	font-size: 14px;
	color: #555;
	margin-top: 6px;
}
.calendar-list-description p:first-child { margin-top: 0; }
.calendar-list-description p:last-child { margin-bottom: 0; }

/* Monatsansicht */

.calendar-grid-header {
	margin-bottom: 16px;
}

.calendar-grid-title {
	font-size: 18px;
	font-weight: 700;
	color: #2b2b2b;
}

.calendar-grid-nav {
	font-size: 22px;
	color: #555;
	padding: 4px 12px;
}
.calendar-grid-nav:hover { color: #2f5d50; }

.calendar-grid-weekdays {
	font-size: 12px;
	color: #999;
	text-align: center;
	margin-bottom: 6px;
}

.calendar-grid-day {
	aspect-ratio: 1;
	border-radius: 8px;
	gap: 4px;
	padding: 6px 0;
}

.calendar-grid-day.has_events:hover {
	background: #f7f7f5;
}

.calendar-grid-daynum {
	font-size: 14px;
	color: #2b2b2b;
}

.calendar-grid-day.is_today .calendar-grid-daynum {
	color: #fff;
	background: #2f5d50;
	border-radius: 50%;
	width: 22px;
	height: 22px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.calendar-grid-day.is_selected {
	background: #f0efe9;
}

.calendar-grid-dots {
	gap: 3px;
}

.calendar-grid-dot {
	width: 6px;
	height: 6px;
}

.calendar-grid-dayevents {
	margin-top: 20px;
	border-top: 1px solid #eee;
	padding-top: 10px;
}

@media (max-width: 720px) {
	.calendar-list-item {
		flex-direction: column;
		gap: 4px;
	}
	.calendar-list-date {
		width: auto;
		display: flex;
		gap: 10px;
	}
}

/* NEWS/AKTUELLES (Optik - Struktur/Mechanik in cms/css/system.css, js/content-items.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (siehe cms/css/
system.css fuer die Struktur/Mechanik dieser Klassen - dort bewusst NICHT ueberschreiben,
Aenderungen gehoeren hierher):
- .content-items-widget: Breite/Aussenabstand des Grids, Abstand zwischen den Karten.
- .content-items-card-image: Look des Karten-Vorschaubilds (Seitenverhaeltnis, Radius,
  Abstand, Platzhalter-Hintergrund).
- .content-items-card-date, .content-items-card-title, .content-items-card-teaser: Look/
  Typografie der Karten-Textelemente (Farben, Groessen, text-align fuer zentrierten statt
  linksbuendigen Inhalt).
- .content-items-empty: Look des "Noch keine Eintraege"-Hinweistexts. */

.content-items-widget {
	max-width: 1100px;
	margin: 0 auto;
	padding: 0 24px;
	gap: 28px;
}

.content-items-empty {
	color: #999;
	font-size: 14px;
}

.content-items-card-image {
	aspect-ratio: 16 / 9;
	border-radius: 4px;
	margin-bottom: 14px;
	background: #f0efe9;
}

/* .kai_contentitem_image (singular) is the detail page's own hero image (see
cse/_template_content_item.html) - distinct from .content-items-card-image (plural) above,
which is only the small teaser-card thumbnail on the overview page. Had no rule at all until
now (unlike every other image slot here), so it rendered unconstrained at its raw
width/height HTML attributes - same width:100%/max-height/object-fit treatment as .hero img,
since it plays the identical "full-width banner image at the top of a page" role. */
.kai_contentitem_image {
	width: 100%;
	max-height: 420px;
	object-fit: cover;
	object-position: center;
	display: block;
	margin-bottom: 24px;
}

.content-items-card-date {
	font-size: 13px;
	color: #999;
}

.content-items-card-title {
	font-size: 18px;
	font-weight: 700;
	color: #2b2b2b;
	margin: 6px 0 8px;
}

.content-items-card-teaser {
	font-size: 14px;
	color: #555;
}

.content-items-card:hover .content-items-card-title {
	color: #2f5d50;
}

/* PREISLISTE (Optik - Struktur/Mechanik in cms/css/system.css, js/pricelist.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design (siehe cms/css/
system.css fuer die Struktur/Mechanik dieser Klassen - dort bewusst NICHT ueberschreiben,
Aenderungen gehoeren hierher):
- .pricelist-widget: Breite/Aussenabstand des gesamten Widgets.
- .pricelist-toc: Look des Inhaltsverzeichnisses (Ausrichtung/Abstaende der Links, z.B.
  horizontale Pills statt vertikaler Liste).
- .pricelist-category-title: Look der Kategorie-Ueberschriften.
- .pricelist-table (+ .pricelist-th- und .pricelist-td-Klassen): Look der Tabelle (Rahmen,
  Zebra-Streifen, Ausrichtung der Preis-Spalte, text-align fuer zentrierten statt
  linksbuendigen Inhalt).
- .pricelist-empty: Look des "noch keine Eintraege"-Hinweistexts.

Die Werte unten bilden die frueher handgepflegte .rental-table dieser Website nach:
graue Kopfzeile, 18px-Schriftbasis, ruhige Zeilentrennung. Beibehalten aus der
Engine-Optik sind Zebra-Streifen und Hover, beide aber deutlicher als die sehr
zurueckhaltenden Engine-Werte (#fafaf8/#f7f7f5), die auf weissem Grund kaum sichtbar
waren. .rental-table selbst steht weiter oben im Abschnitt "Preis-/Artikel-Liste" und
bleibt als Vorlage und fuer verkauf.html erhalten.

ACHTUNG Kommentarende: Die Klassennamen oben stehen bewusst ohne Stern-Platzhalter. Ein
Stern direkt vor einem Schraegstrich beendet einen CSS-Kommentar - genau das passierte
hier bis September 2026 in der Zeile ueber .pricelist-table. Der Rest dieses Kopfes wurde
dadurch als Regelwerk geparst und riss die erste Regel darunter mit: .pricelist-widget kam
nie an (im Browser gemessen, max-width "none" statt der deklarierten "1100px"). */

/* Das Widget sitzt auf dieser Website in .rental-list .section-inner, das Breite und
   Aussenabstand schon setzt (max-width 900px). Eine eigene Breite plus Innenabstand
   wuerde die Tabellen gegenueber dem uebrigen Seiteninhalt einruecken. */
.pricelist-widget {
	max-width: none;
	margin: 0;
	padding: 0;
}

/* Inhaltsverzeichnis wie im WordPress-Original: einspaltige Liste, jede Zeile mit einem
   Pfeil davor, kein Kasten darum, Schrift in der Seitengroesse. Der Pfeil ist ein
   ::before-Zeichen und kein Icon - die Engine rendert nur <ul><li><a>, und ein Zeichen
   braucht weder zusaetzliches Markup noch eine Icon-Datei. Linkfarbe wie in Fuss- und
   Rechtstexten dieser Website, also die Akzentfarbe --site-accent (siehe :root, dort auch
   die Begruendung des Wertes; bis September 2026 stand hier #14879e, das dem Ton des
   WordPress-Originals #0a81a9 noch naeher kam, aber den Kontrastrichtwert verfehlte). Der
   Abstand nach unten kommt aus dem margin-top der ersten .pricelist-category, die beiden
   Werte fallen zusammen. */
.pricelist-toc {
	display: flex;
	flex-direction: column;
	gap: 0.55rem;
	margin: 3rem 0 0;
	padding: 0;
	background: none;
}
.pricelist-toc li {
	display: flex;
	align-items: baseline;
	gap: 0.6rem;
}
.pricelist-toc li::before {
	content: "\2192";
	color: #222;
	flex-shrink: 0;
}
.pricelist-toc a {
	color: var(--site-accent);
	text-decoration: none;
	font-size: inherit;
	transition: color 0.2s ease;
}
.pricelist-toc a:hover,
.pricelist-toc a:focus-visible {
	color: var(--site-accent-hover);
	text-decoration: underline;
}

/* Abstand zwischen den Kategorien wie frueher zwischen den .rental-category-Bloecken:
   oben 3rem, unten nichts - so bleibt der Rhythmus auch dann gleich, wenn zwei Widgets
   (Vermietung und Mietfaktoren) untereinander stehen. */
.pricelist-category {
	margin-top: 3rem;
	margin-bottom: 0;
}

/* Wie .rental-category h2 - die Engine rendert die Kategorie-Ueberschrift als <h3>, das
   Aussehen soll davon unberuehrt bleiben. */
.pricelist-category-title {
	font-size: 1.6rem;
	font-weight: 400;
	color: #666;
	margin: 0 0 1rem;
	padding-top: 8px; /* etwas Puffer ueber dem Anker-Sprungziel, damit die Ueberschrift beim Anspringen nicht direkt am oberen Rand klebt */
}

.pricelist-table {
	font-size: inherit; /* erbt die 18px-Basis der Seite, wie .rental-table - kein fester Wert */
}
.pricelist-table th, .pricelist-table td {
	padding: 0.9rem 1rem;
	text-align: left;
}
.pricelist-table thead th {
	background: #d6d6d6;
	color: #222;
	font-weight: 700;
	font-size: 0.95rem;
}
/* Trennlinie auf der Zeile statt auf den Zellen - nur so laesst sich die letzte Zeile
   ueber :last-child wieder ausnehmen, genau wie bei .rental-table. */
.pricelist-table tbody tr {
	border-bottom: 1px solid #eaeaea;
	transition: background-color 0.15s ease; /* wie btn-link/.category-card */
}
.pricelist-table tbody tr:last-child {
	border-bottom: none;
}
/* Zebra-Streifen + Hover: nth-child zaehlt pro <tbody>, und jede Kategorie hat ihre eigene
<table>/<tbody> (siehe renderCategoryHtml() in pricelist.js/renderPricelistCategoryHtml() in
pricelisthelper.php) - das Muster faengt dadurch bei jeder Kategorie automatisch wieder bei
Zeile 1 an, statt kategorieuebergreifend durchzulaufen. Die Engine-Werte (#fafaf8 Zebra,
#f7f7f5 Hover) sind auf dem weissen Grund dieser Seite praktisch unsichtbar - beide Toene
liegen unter 3 % Helligkeitsunterschied zu Weiss. Deshalb hier deutlicher: Zebra #f2f2f0,
Hover #e6e6e1. Der Hover bleibt merklich heller als die Kopfzeile (#d6d6d6), damit die
Zeile hervortritt, ohne mit ihr zu konkurrieren. */
.pricelist-table tbody tr:nth-child(even) {
	background: #f2f2f0;
}
.pricelist-table tbody tr:hover {
	background: #e6e6e1;
}
/* Praefix ".pricelist-table" ist hier notwendig, nicht nur Stil: ohne ihn hat diese Regel
weniger Spezifitaet (0,1,0) als ".pricelist-table th, .pricelist-table td" oben (0,1,1, Klasse
+ Element) und wird von dessen "text-align: left" ueberschrieben, unabhaengig von der
Reihenfolge im Stylesheet - genau das war vorher der Fall (per getComputedStyle() bestaetigter,
bereits laenger bestehender Bug: die Preis-Spalte war trotz dieser Regel nie tatsaechlich
rechtsbuendig). */
.pricelist-table .pricelist-th-price, .pricelist-table .pricelist-td-price {
	text-align: right;
	white-space: nowrap;
}
/* Dritte Spalte "Anzahl" - nur bei Listen, die sie eingeschaltet haben (hier verkauf.html,
   nicht vermietung.html). Rechtsbuendig wie die Preisspalte, damit die Zahlen beider
   Spalten untereinander stehen; im Original war es ebenso. Der ".pricelist-table"-Praefix
   ist auch hier notwendig und nicht Stil - siehe den Kommentar ueber der Preisspalte.
   Die feste Breite haelt die Spalte schmal, damit die Beschreibung den Platz bekommt;
   ohne sie verteilt der Browser die Breite nach Inhalt und die Zahlenspalten wandern
   bei kurzen Beschreibungen nach links. */
.pricelist-table .pricelist-th-quantity, .pricelist-table .pricelist-td-quantity {
	text-align: right;
	white-space: nowrap;
	width: 6rem;
}
/* Drei Spalten brauchen mehr Platz, als 0.9rem/1rem Polster auf einem Telefon uebrig
   lassen: gemessen ragte die Tabelle bei 390px Fensterbreite bis 445px hinaus, die Seite
   liess sich also seitlich schieben. Deshalb schmaleres seitliches Polster, freie Breite
   der Anzahl-Spalte und eine Umbrucherlaubnis innerhalb langer Beschreibungen, sobald es
   eng wird. Der :has()-Selektor grenzt alles drei auf Listen MIT Anzahl-Spalte ein - die
   zweispaltigen Tabellen auf vermietung.html passen auch schmal und bleiben unveraendert.
   Unterhalb von etwa 350px Fensterbreite reicht auch das nicht mehr; dort bleibt ein
   schmaler seitlicher Ueberhang, der kein heute uebliches Geraet betrifft. */
@media (max-width: 640px) {
	.pricelist-table:has(.pricelist-th-quantity) th,
	.pricelist-table:has(.pricelist-th-quantity) td {
		padding-left: 0.5rem;
		padding-right: 0.5rem;
	}
	.pricelist-table:has(.pricelist-th-quantity) .pricelist-th-quantity,
	.pricelist-table:has(.pricelist-th-quantity) .pricelist-td-quantity {
		width: auto;
	}
	/* hyphens zuerst: der Browser trennt dann an Silbengrenzen mit Bindestrich (die Seite
	   ist lang="de", Chrome/Safari/Firefox bringen die Trennmuster mit). overflow-wrap
	   bleibt als Notnagel darunter, falls ein Wort auch getrennt nicht passt - sonst
	   entsteht wieder ein Ueberhang. */
	.pricelist-table:has(.pricelist-th-quantity) .pricelist-td-description {
		hyphens: auto;
		overflow-wrap: anywhere;
	}
}
/* Keine Hervorhebung der Beschreibungsspalte - .rental-table hatte sie nicht, und mit der
   grauen Kopfzeile darueber wirkt eine zweite fette Spalte unruhig. */
.pricelist-td-description {
	font-weight: inherit;
}
.pricelist-td-note {
	color: #666;
	font-size: 14px;
}

.pricelist-empty {
	color: #999;
	font-size: 14px;
}

/* MENÜKARTEN (Optik - Struktur/Mechanik: kai_section_wrap-Mechanismus in cms.js) */
.menu_grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 24px;
}

.menu_item {
  position: relative;
   padding-top: 56px;
}

.menu_item_badge {
  position: absolute;
  top: 0;
  left: 0;
  background: #1a1a1a;
  color: #fff;
  font-size: 12px;
  padding: 1px 14px;
  border-radius: 4px;
}

.menu_item_badge:empty {
  display: none;
}

.menu_item_head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  border-bottom: 1px dashed #999;
  padding-bottom: 6px;
  margin-bottom: 10px;
}

.menu_item_title {
  margin: 0;
  font-size: 18px;
}

.menu_item_price {
  white-space: nowrap;
  font-size: 14px;
  color: #666;
}

.menu_item_desc {
  color: #555;
  margin-bottom: 10px;
}

.menu_item_image {
  border-radius: 4px;
  object-fit: cover;
  object-position: center;
}

.menu_item_image[src$="spacer-lightgrey.jpg"] {
  display: none;
}

/* KATEGORIE-KARTEN (Optik - Struktur/Mechanik: kai_section_wrap-Mechanismus,
siehe cms/js/cms.js und Hilfe-Sektion im CMS)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design:
- .category-cards-wrap: Grid-Layout der Kartenuebersicht (Spaltenzahl, Abstand).
- .category-card: Look der einzelnen Karte (Hintergrund, Rahmen, Eckenradius).
- .category-card .kai_edit_text p: Innenabstand des Kartentexts.
- .category-card .kai_edit_text i: Icon-Groesse/-Farbe.
- .category-card .kai_edit_text a: Verlinkung als block-level Flaeche - macht die ganze
  Karte klickbar, wenn Icon+Text beim Verlinken gemeinsam markiert wurden (siehe
  Kommentar in cse/category_card.html). Falls nur der Text verlinkt wird, bleibt nur
  dieser klickbar - das Card-Padding sorgt optisch trotzdem fuer eine grosszuegige
  Klickflaeche. */

.category-cards-wrap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 20px;
}

.category-card {
  border-radius: 8px;
  background: #f7f7f5;
  overflow: hidden;
}

.category-card .kai_edit_text p {
  margin: 0;
}

.category-card .kai_edit_text i {
  font-size: 32px;
  color: #2f5d50;
  display: block;
  margin-bottom: 12px;
}

.category-card .kai_edit_text a {
  display: block;
  padding: 28px 16px;
  text-align: center;
  color: #2b2b2b;
  text-decoration: none;
  font-weight: 600;
  transition: background 0.15s ease;
}

.category-card .kai_edit_text a:hover {
  background: #ececea;
}

/* KONTAKTFORMULAR (Optik - Struktur/Mechanik in cms/css/system.css, js/contactform.js)

Vorgesehene Customization-Hooks fuer individuelles Kunden-Design:
- .contact-form: Breite/Abstand des Formulars als Ganzes.
- .contact-form-field: Abstand zwischen den einzelnen Feldern.
- .contact-form label: Beschriftungs-Optik.
- .contact-form input, .contact-form textarea: Eingabefeld-Optik (Rahmen, Radius, Fokus).
- .contact-form button: Absende-Button.
- .contact-form-message.success / .contact-form-message.error: Rueckmeldung nach dem
  Absenden (die Klasse wird von contactform.js je nach Ergebnis gesetzt). */

.contact-form {
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.contact-form-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.contact-form-field-checkbox {
  flex-direction: row;
  align-items: flex-start;
  gap: 8px;
}

.contact-form label {
  font-weight: 600;
  font-size: 14px;
}

.contact-form input,
.contact-form textarea {
  padding: 8px 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font: inherit;
}

.contact-form textarea {
  min-height: 120px;
  resize: vertical;
}

.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: #2f5d50;
}

/* :not(.kontakt-form) eingegrenzt, gleicher Grund wie bei header:not(.site-nav) und
   footer:not(.site-footer) weiter oben: das blankTon-Formular traegt beide Klassen,
   .contact-form als Einbaupunkt der Engine und .kontakt-form fuer die Optik dieser
   Seite. Die uebrigen Regeln dieses Blocks kollidieren nicht - sie haben dieselbe
   Spezifitaet wie ihr .kontakt-form-Gegenstueck im <style>-Block von index.html, das
   spaeter geladen wird und die Gleichstaende deshalb gewinnt. Diese vier hier nicht:
   ".contact-form button" (0,1,1) schlaegt ".kontakt-submit" (0,1,0) unabhaengig von
   der Reihenfolge - der Absende-Button stand dadurch gruen und gefuellt statt als
   heller Umriss. Und die beiden Meldungsfarben (dunkelgruen/dunkelrot) sind auf dem
   dunklen Hintergrund der Kontaktsektion praktisch unlesbar. */
.contact-form:not(.kontakt-form) button {
  align-self: flex-start;
  padding: 10px 24px;
  border: none;
  border-radius: 4px;
  background: #2f5d50;
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}

.contact-form:not(.kontakt-form) button:disabled {
  opacity: 0.6;
  cursor: default;
}

.contact-form-message {
  font-size: 14px;
}

.contact-form:not(.kontakt-form) .contact-form-message.success {
  color: #2f5d50;
}

.contact-form:not(.kontakt-form) .contact-form-message.error {
  color: #c0392b;
}

/* ---------------------------------------------------------------------------
   Kontaktformular blankton.ch - was die Starter-Schale oben fuer diese Seite
   nicht leisten kann. Steht bewusst HIER und nicht im <style>-Block von
   index.html: savecss.php schreibt beim Design-Editor immer nach css/styles.css,
   die Redaktion soll diese Werte also erreichen koennen.

   Die Datenschutz-Checkbox ist neu (Einheit 8) und uebernimmt die Bildsprache der
   Textfelder: gleicher Fuellton, gleiche Rahmenfarbe, gleiches Fokusverhalten.
   appearance:none, weil die Systemdarstellung einer Checkbox auf dem dunklen
   Hintergrund als weisser Kasten steht und den Rest des Formulars erschlaegt.
   --------------------------------------------------------------------------- */
.kontakt-form .contact-form-field-checkbox label {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  font-weight: 400;
  font-size: 0.85rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
}

/* Der Link zur Datenschutzerklaerung hatte als einziger sichtbare Link der Seite gar keine
   Autoren-Farbregel und stand damit auf den Browser-Vorgaben: unbesucht #0000EE, besucht
   #551A8B - auf dem dunklen Hintergrundbild der Kontaktsektion 1,72:1 bzw. 1,47:1 und
   damit praktisch unlesbar.

   Eine einzige Farbregel raeumt beide Zustaende weg: Autoren-Regeln schlagen die
   UA-Regeln a:link/a:visited unabhaengig von der Spezifitaet, der besuchte Zustand erbt
   dieselbe Farbe. Ein eigener :visited-Block waere doppelt gemoppelt - und ohnehin wenig
   wert, weil Browser aus Datenschutzgruenden nur Farben darauf zulassen. Genau deshalb
   hatte KEIN anderer Link der Seite dieses Problem: sie alle haben eine Farbregel.

   #fff wie .kontakt-address a im selben dunklen Abschnitt. Die Unterstreichung bleibt -
   sie ist es, die den Link im Fliesstext in rgba(255,255,255,0.7) erkennbar macht. Hover
   und Fokus bekommen bewusst keine eigene Regel, der Link verhaelt sich darin wie
   bisher. */
.kontakt-form .contact-form-field-checkbox a {
  color: #fff;
}

.kontakt-form .contact-form-field-checkbox input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0.15rem 0 0;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.08);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.kontakt-form .contact-form-field-checkbox input[type="checkbox"]::before {
  content: "";
  width: 0.5rem;
  height: 0.26rem;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg) translate(1px, -2px);
  opacity: 0;
  transition: opacity 0.15s ease;
}

.kontakt-form .contact-form-field-checkbox input[type="checkbox"]:checked {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.65);
}

.kontakt-form .contact-form-field-checkbox input[type="checkbox"]:checked::before {
  opacity: 1;
}

.kontakt-form .contact-form-field-checkbox input[type="checkbox"]:focus-visible {
  outline: none;
  border-color: #fff;
  background: rgba(255, 255, 255, 0.12);
}

/* Rueckmeldung nach dem Absenden. contactform.js haengt das div selbst ans Formular,
   es wird also das letzte Flex-Kind und erbt den 0.9rem-Abstand von .kontakt-form. */
.kontakt-form .contact-form-message {
  font-size: 0.9rem;
  line-height: 1.5;
}

.kontakt-form .contact-form-message.success {
  color: #6fd3e3;
}

.kontakt-form .contact-form-message.error {
  color: #ff9a90;
}

.kontakt-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

/* ===========================================================================
   5. EDITIERMODUS
   =========================================================================== */
/* ===========================================================================
   EDITIERMODUS – Effekte neutralisieren
   ===========================================================================
   Die Engine setzt body.editing, sobald edit() laeuft (cms/js/cms.js:1352) und
   entfernt sie beim Speichern/Abbrechen (cms/js/cms.js:1948). Muster wie bei
   .cms_pagemetadescription_bar in cms/css/cms.css:474 – mit dem Unterschied,
   dass die Regel HIER stehen muss und nicht dort: cms.css wird nur im
   Editiermodus geladen, gehoert aber der Engine und wird bei jedem Update
   ersetzt.

   Bewusst NICHT in css/scroll-reveal.css: die Effektsammlung soll unveraendert
   bleiben, damit sie spaeter als Ganzes aktualisiert werden kann. Ein
   installationsspezifischer Sonderfall gehoert in die Kundendatei.

   Spezifitaet: body.editing .reveal-on-scroll ist (0,2,0) gegen (0,1,0) von
   .reveal-on-scroll in scroll-reveal.css – die Regel gewinnt unabhaengig von
   der Ladereihenfolge der beiden Dateien. !important ist deshalb nicht noetig
   und waere hier auch falsch: die Werte muessen weiterhin ueberschreibbar
   bleiben.
   =========================================================================== */

/* scroll-reveal: .reveal-on-scroll traegt opacity:0 unbedingt, sichtbar wird
   das Element erst, wenn scroll-reveal.js .is-revealed setzt. Alle acht
   Elemente der Startseite tragen zusaetzlich data-reveal-repeat, blenden beim
   Weiterscrollen also wieder aus – im Editiermodus waere praktisch der gesamte
   Inhalt unterhalb des Heros unsichtbar und nicht anklickbar. */
body.editing .reveal-on-scroll {
	opacity: 1;
	transform: none;
	transition: none;
}
