/* ─────────────────────────────────────────────────────────────────────────
   Ergänzende Styles (nach style.css geladen).
   ───────────────────────────────────────────────────────────────────────── */

/* Feature-Kacheln der Startseite (Label + Icon + Text + Link) */
.featurecard {
  text-align: center;
}
/* Die kleine Versalzeile ganz oben in einer Box («PRODUKTE», «ÜBER UNS»,
   «PREMIUM PRODUKTE»).

   Es gibt sie in zwei Ausführungen, und genau das war das Problem: In den
   Feature-Kacheln der Startseite ist es ein <h6 class="featurecard-eyebrow">,
   in den Textblöcken ein blankes <h6> aus dem Rich-Text. Wer nur die erste
   anfasst, ändert die Hälfte - die Zeile über «Wir leben Qualität» blieb
   deshalb klein, obwohl die über den Icons schon korrigiert war.

   Beide stehen jetzt auf 1.4rem = 14px. Vorher 12px bzw. 13px: für gesperrte
   Versalien zu wenig, und uneinheitlich obendrein. */
.featurecard .featurecard-eyebrow,
.textblock .payload-richtext h6,
.textblock .payload-richtext .h6,
.textblock .payload-richtext .dachzeile,
.textblock h6,
.textblock .dachzeile {
  font-size: 1.4rem;
}
.featurecard .featurecard-eyebrow {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  margin: 0 0 2rem 0;
  opacity: 0.85;
}
/* Der Satz IST der Titel der Kachel und trägt jetzt auch die Auszeichnung
   dafür. Bewusst kleiner als die Abschnittstitel der Seite (4.5rem): Drei
   Kacheln nebeneinander haben je rund ein Drittel der Breite, dieselbe Grösse
   würde dort in vier Zeilen umbrechen. */
.featurecard .featurecard-titel {
  /* Genau die h2-Grösse des Themes (3rem). Damit stehen die Kacheltitel auf
     derselben Stufe wie «Wir leben Qualität», «PIYA Premium Beef» und «Wir sind
     Piya» – einheitlich über die ganze Seite statt jede Box mit eigener Grösse. */
  font-size: 3rem;
  line-height: 1.22;
  margin: 0 0 2.8rem 0;
  max-width: none;
}
@media only screen and (max-width: 1023px) {
  .featurecard .featurecard-titel {
    font-size: 2.6rem;
  }
}
@media only screen and (max-width: 639px) {
  .featurecard .featurecard-titel {
    font-size: 2.4rem;
  }
}
.featurecard-icon {
  display: block;
  width: 4.4rem;
  height: 4.4rem;
  margin: 0 auto 1.6rem auto;
}
.featurecard p {
  margin: 0 0 1.6rem 0;
}
.featurecard .button {
  margin-top: 0.6rem;
}

/* Google-Maps im Footer.

   Das Platzhalterbild des Themes (theme/img/map.webp) zeigt noch die alte
   Adresse und bleibt deshalb aus. Statt des vorherigen flachen Schwarz steht
   hier ein dezentes Grau mit einem angedeuteten Raster: Solange Google lädt,
   sieht man eine ruhige Fläche und kein schwarzes Loch. Das iframe kommt jetzt
   direkt aus dem Server-Rendering (siehe FooterMap.tsx) und legt sich darüber,
   sobald es geladen ist. */
#mymap {
  background-image: none !important;
  background-color: #1b1e21 !important;
}
/* Das Kartenbild blendet auf, statt hineinzuspringen. */
#mymap iframe {
  opacity: 0;
  transition: opacity 0.5s ease;
}
#mymap.karte-da iframe {
  opacity: 1;
}
/* Ohne JavaScript feuert `onLoad` nicht – dann ist die Karte sofort sichtbar,
   statt für immer durchsichtig zu bleiben. Sichtbarkeit gewinnt. */
.no-js #mymap iframe {
  opacity: 1;
}

/* Produkt-Filter: einzelne Buttons nicht auf volle Zeilenbreite strecken */
#product-filter .filterbtn {
  flex-grow: 0;
}

/* Anker-Sprungziele nicht hinter dem fixen Header verstecken */
.ankerlink {
  scroll-margin-top: 9rem;
}

/* Kontaktformular (zweispaltig: Intro links, Formular rechts) */
.kontaktformular-block h2,
.kontaktformular-block .h2 {
  margin-bottom: 2.6rem;
}
.kontakt-form .kf-field {
  margin-bottom: 2rem;
}
.kontakt-form .kf-label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 1.15rem;
  margin-bottom: 0.7rem;
  opacity: 0.75;
}
.kontakt-form .kf-row {
  display: flex;
  gap: 1.6rem;
}
.kontakt-form .kf-row > * {
  flex: 1;
  min-width: 0;
}
.kontakt-form .text-input {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.28);
  padding: 0.6rem 0;
  font-size: 1.5rem;
  color: inherit;
  font-family: inherit;
}
.kontakt-form textarea.text-input {
  border: 1px solid rgba(0, 0, 0, 0.28);
  padding: 0.9rem 1rem;
  resize: vertical;
}
.kontakt-form .text-input:focus {
  outline: none;
  border-color: rgba(0, 0, 0, 0.6);
}
.kontakt-form .kf-actions {
  margin-top: 1.4rem;
  display: flex;
  align-items: center;
  gap: 1.4rem;
}
/* Der Spinner ist weg (der Knopf zeigt den Zustand selbst). Falls je wieder
   ein kleines Bild in ein Formular soll: Das Theme hat eine pauschale Regel

     img { max-width: 100%; width: 100%; height: auto }

   und die schlägt die `width`/`height`-Angaben AM ELEMENT. Ein 41px-Symbol
   wurde damit auf die volle Spaltenbreite gezogen - rund 570px, ein riesiger
   schwarzer Pfeil neben dem Absenden-Knopf. Wer hier ein Symbol einsetzt,
   gibt ihm die Grösse im CSS, nicht als Attribut. */
.kf-message {
  font-size: 1.5rem;
}
.kf-message.error {
  color: #a33;
}

/* Cookie-Banner */
/* ── Cookie-Hinweis ────────────────────────────────────────────────────────
   Vorher ein schwarzes Band über die ganze Breite: Es erbte `text-align:
   center`, der Absatz war 600px breit, die Knöpfe passten nicht mehr daneben
   und rutschten darunter. Aus der geplanten einen Zeile wurden zwei zentrierte,
   die Knöpfe hatten keine Umrandung geerbt und sahen wie blosser Text aus -
   schwarz auf schwarzem Grund, quer über der Schlagzeile.

   Jetzt eine abgesetzte Karte unten links: eigener Grund, feine Umrandung,
   Schatten. Sie verdeckt den Inhalt nur dort, wo sie steht, und sieht aus wie
   ein Teil dieser Seite - dieselben Knöpfe wie überall sonst. */
#cookie-banner {
  position: fixed;
  left: 2.4rem;
  bottom: 2.4rem;
  z-index: 9999;
  width: calc(100% - 4.8rem);
  max-width: 46rem;
  background: #141414;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 1.2rem 3.6rem rgba(0, 0, 0, 0.55);
  padding: 2.4rem 2.6rem;
  /* Der Seitengrund zentriert fast alles - hier soll der Text links stehen. */
  text-align: left;
}
#cookie-banner .cookie-inner {
  display: block;
  max-width: none;
  margin: 0;
}
#cookie-banner p {
  margin: 0 0 2rem 0;
  font-size: 1.3rem;
  line-height: 1.65;
  max-width: none;
  color: rgba(255, 255, 255, 0.85);
  text-align: left;
}
#cookie-banner a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 0.25em;
}
#cookie-banner .cookie-actions {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}
/* Eigene Knöpfe statt der Theme-Klasse: Die trägt auf dunklem Grund keine
   sichtbare Umrandung, und «Annehmen» soll die deutlichere Wahl sein. */
#cookie-banner .cookie-actions .button {
  margin: 0;
  cursor: pointer;
  flex: 1 1 auto;
  min-width: 12rem;
  padding: 1.1rem 1.8rem;
  font-size: 1.2rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.2;
  border: 1px solid #fff;
  border-radius: 0;
  transition: background-color 0.2s ease, color 0.2s ease;
}
#cookie-banner .cookie-accept {
  background: #fff;
  color: #000;
}
#cookie-banner .cookie-accept:hover {
  background: rgba(255, 255, 255, 0.82);
}
#cookie-banner .cookie-decline {
  background: transparent;
  color: #fff;
}
#cookie-banner .cookie-decline:hover {
  background: rgba(255, 255, 255, 0.14);
}
#cookie-banner .button:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}
@media (max-width: 639px) {
  #cookie-banner {
    left: 1.2rem;
    right: 1.2rem;
    bottom: 1.2rem;
    width: auto;
    max-width: none;
    padding: 2rem 2rem;
  }
}

/* Produkt-Detailseite ohne Bild: „Foto folgt“-Platzhalter statt weisser Fläche */
.produkt-bild-placeholder {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  background: #111;
}
.produkt-bild-placeholder::after {
  content: "Foto folgt";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 1.8rem;
  letter-spacing: 0.05em;
}

/* Produkt-Kacheln ohne Bild: „Foto folgt“-Platzhalter (wie Original) */
.term-product.no-image,
.product-teaser.no-image {
  position: relative;
}
.term-product.no-image .inner::after,
.product-teaser.no-image::after {
  content: "Foto folgt";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 1.6rem;
  letter-spacing: 0.05em;
  pointer-events: none;
}

/* ── Barrierefreiheit ─────────────────────────────────────────────────────── */

/* Sprunglink: nur sichtbar, wenn er per Tastatur fokussiert wird (WCAG 2.4.1). */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10000;
  padding: 0.75rem 1.25rem;
  background: #ffffff;
  color: #000000;
  text-decoration: none;
  font-weight: 700;
}
.skip-link:focus,
.skip-link:focus-visible {
  left: 0;
  outline: 3px solid #000000;
  outline-offset: 2px;
}

/* Der Sprungziel-Container darf keinen eigenen Fokusrahmen zeichnen. */
#inhalt:focus {
  outline: none;
}

/* Deutlich sichtbarer Tastatur-Fokus auf dunklem wie hellem Grund. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 2px;
}
.color-white a:focus-visible,
#site-header a:focus-visible,
#nav-modal a:focus-visible {
  outline-color: #ffffff;
}
body:not(.schwarz) a:focus-visible,
.hellgrau a:focus-visible,
.hellbraun a:focus-visible {
  outline-color: #000000;
}

/* Auf hellem Grund gilt das auch für Formularfelder und Knöpfe.

   Die Regel darüber kannte nur `a`. Ein Eingabefeld im Newsletter-Block
   (`.hellgrau`, #d2d6d0) bekam darum den weissen Rahmen der Grundregel –
   auf hellgrauem Grund ein weisser Kasten statt einer sichtbaren Markierung.
   Genau das Gegenteil dessen, wofür ein Fokusrahmen da ist.

   Der Rahmen bleibt 3px stark; nur die Farbe folgt dem Untergrund. */
.hellgrau :is(input, textarea, select, button):focus-visible,
.hellbraun :is(input, textarea, select, button):focus-visible,
.kontakt-form :is(input, textarea, select, button):focus-visible,
#newsletter-container :is(input, textarea, select, button):focus-visible {
  outline-color: #000000;
}

/* Knopf im Ladezustand: abgeschaltet, aber lesbar. */
input[type='submit']:disabled,
button:disabled {
  opacity: 0.55;
  cursor: progress;
}

/* Hamburger-Button ist ein interaktives Element – Fokus muss sichtbar sein. */
#hamburger-button:focus-visible {
  outline: 3px solid #ffffff;
  outline-offset: 4px;
}

/* Nutzer mit reduzierter Bewegungspräferenz respektieren. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Produkt-Detailseite
   ───────────────────────────────────────────────────────────────────────── */

/* Kopfbereich rechts (Kategorie-Pfad, Typ-Icons, Artikelnummer, Eckdaten). */
.right-details {
  text-align: left;
}
/* Vier Pixel zwischen Pfadzeile und Titel waren zu wenig: Sobald der Pfad
   umbricht - «Kebab & Co. › ORIGIN Premium Döner Produkte» tut das schon unter
   1200px - klebte «PRODUKTE» am Kopf des Titels. Die Pfadzeile bekommt Raum
   nach unten, der Titel den passenden Abstand nach oben. */
.right-details h1 {
  margin-top: 1.2rem;
}
.right-details .product-categories {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 1.15rem;
  line-height: 1.6;
  opacity: 0.7;
}
.right-details .product-categories a {
  color: inherit;
}
.right-details .type-articul {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.6rem;
  margin: 1.6rem 0 2.8rem 0;
}
.right-details .type-articul .item {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 1.35rem;
}
.right-details .type-articul .item img {
  width: 2.6rem;
  height: 2.6rem;
  object-fit: contain;
}
.right-details .type-articul .wall {
  width: 1px;
  align-self: stretch;
  background: currentColor;
  opacity: 0.25;
}

/* Eckdaten-Liste (Einheit / Zutaten / Herkunft / Verpackungseinheit). */
.table-contents {
  margin: 0 0 3.2rem 0;
  border-top: 1px solid rgba(0, 0, 0, 0.15);
}
.color-white .table-contents,
.schwarz .table-contents {
  border-top-color: rgba(255, 255, 255, 0.25);
}
.table-contents .unit {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 2rem;
  padding: 1.2rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.color-white .table-contents .unit,
.schwarz .table-contents .unit {
  border-bottom-color: rgba(255, 255, 255, 0.25);
}
.table-contents .label {
  /* Nicht `0 0 14rem`: Damit durfte das Label nicht schrumpfen. Zwischen 640
     und 1023px steht die Eckdaten-Spalte neben dem Produktbild und ist dort
     nur ~268px breit – abzüglich 140px Label und 20px Abstand blieben dem Wert
     108px, und Bezeichnung und Wert schoben sich ineinander. */
  flex: 1 1 12rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 1.15rem;
  line-height: 1.9;
  opacity: 0.7;
}
.table-contents .data {
  flex: 1 1 20rem;
  min-width: 0;
}
.table-contents .data p:last-child {
  margin-bottom: 0;
}

/* ── Produktespezifikation ───────────────────────────────────────────────── */
.produkt-spezifikation {
  text-align: left;
  padding: 0 0 8rem 0;
}
/* Das Theme zentriert Überschriften global (`margin: 0 auto` + `max-width: 80rem`).
   Im Spezifikationsblock sollen sie bündig zur Tabellenspalte stehen. */
.produkt-spezifikation h2,
.produkt-spezifikation h3,
.produkt-spezifikation .h2,
.produkt-spezifikation .h3,
.produkt-spezifikation p {
  text-align: left;
}
.produkt-spezifikation h2,
.produkt-spezifikation h3,
.produkt-spezifikation .h2,
.produkt-spezifikation .h3 {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}
.produkt-spezifikation .spec-title {
  margin-bottom: 2.4rem;
}
.produkt-spezifikation table {
  width: 100%;
  /* Ohne `fixed` gilt Auto-Layout, und die Prozentbreiten weiter unten sind
     bloss Wünsche: Die Min-Content-Breite langer Wörter wie
     «Verpackungseinheit» gewinnt und drückt die Nachbarspalte zusammen. */
  table-layout: fixed;
  border-collapse: collapse;
  margin: 0 0 1.6rem 0;
  font-size: 1.45rem;
}
.produkt-spezifikation caption {
  text-align: left;
}
.spec-table th,
.spec-table td {
  text-align: left;
  vertical-align: top;
  padding: 1rem 1.4rem 1rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
  font-weight: normal;
  hyphens: none;
  /* Trennung ist bewusst aus (Fachbegriffe sollen nicht zerschnitten werden),
     aber ein zu langes Wort muss trotzdem umbrechen dürfen, statt die Zelle zu
     sprengen. */
  overflow-wrap: break-word;
}
.spec-table thead th {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 1.1rem;
  opacity: 0.7;
  border-bottom-width: 2px;
}
.spec-table-pairs th[scope='row'],
.spec-table-nutrition th[scope='row'] {
  width: 34%;
  opacity: 0.75;
}
.spec-table-nutrition .spec-num {
  text-align: right;
  width: 20%;
  font-variant-numeric: tabular-nums;
}
.spec-table-nutrition .spec-unit {
  width: 20%;
  opacity: 0.75;
}
/* Allergene stehen als kurze Aussage («Enthält: …»), nicht als Ja/Nein-Tabelle. */
.spec-allergen-line {
  margin: 0 0 0.6rem 0;
  font-size: 1.45rem;
  line-height: 1.65;
}
.spec-allergen-traces {
  opacity: 0.75;
}
/* Verkaufstext über den Abschnitten. */
.spec-positionierung {
  font-size: 1.8rem;
  line-height: 1.5;
  margin: 0 0 2.8rem 0;
  max-width: 62ch;
}
.spec-prose p {
  font-size: 1.45rem;
  line-height: 1.65;
  margin: 0 0 0.6rem 0;
  max-width: 72ch;
}

/* Breite Tabellen scrollen in sich – die Seite selbst nie horizontal. */
.spec-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.spec-scroll > table {
  min-width: 46rem;
}

/* ── Kachelwand der Produktangaben ──────────────────────────────────────────
   Sechs beschriftete Felder statt einer Endlosliste. Die geöffnete Kachel legt
   sich über die ganze Zeile: So kann - anders als bei einem schwebenden Fenster
   - nichts hinter dem Fussbereich verschwinden.
   Immer noch ein natives <details>: ohne JavaScript bedienbar. */
/* EINE SPALTE, KEIN RASTER – und das ist die dritte Fassung.

   Fassung 1 war ein Dreierraster, in dem sich die geöffnete Kachel über die
   Zeile legte und ihre Nachbarn überdeckte.
   Fassung 2 schickte die geöffnete Kachel ans Ende des Rasters. Damit war
   zwar nichts mehr überdeckt, aber die Kachel, die man ANGEKLICKT hatte,
   verschwand von ihrem Platz und tauchte unten wieder auf – die übrigen
   rutschten dabei unter dem Cursor weg, und in der letzten Zeile blieb ein
   leeres Feld stehen. Das sah kaputt aus, und es war es auch.

   Fassung 3 verzichtet auf das Raster. Sechs Zeilen untereinander: Was man
   antippt, klappt an seinem Platz auf, nichts springt, nirgends ein Loch,
   auf dem Telefon wie am Schirm dasselbe Verhalten. Der Inhalt – eine breite
   Tabelle aus Merkmal und Wert – war ohnehin immer über die volle Breite
   gesetzt; die Kachelwand war nur die Navigation davor.

   Immer noch ein natives <details>: ohne JavaScript bedienbar. */
.spec-kacheln {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px;
  margin: 0 0 3.6rem 0;
}
.spec-kachel {
  background: #f4f4f4;
  min-width: 0;
}
.spec-kachel[open] {
  background: #eeeeec;
}
.spec-kachel-kopf {
  list-style: none;
  cursor: pointer;
  /* Zeile statt Spalte: Symbol links, Beschriftung daneben. Sechs solcher
     Zeilen brauchen zusammen etwa so viel Platz wie das frühere Dreierraster,
     und der Inhalt klappt an seinem Platz auf, statt ans Ende zu springen. */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 1.6rem;
  min-height: 0;
  padding: 2.2rem 2.6rem;
  text-align: left;
  transition: background-color 0.2s ease;
}
.spec-kachel-kopf::-webkit-details-marker {
  display: none;
}
.spec-kachel-kopf:hover {
  background: #eeeeec;
}
.spec-kachel-kopf:focus-visible {
  outline: 2px solid #000;
  outline-offset: -2px;
}
.spec-kachel-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.8rem;
  height: 4.8rem;
  border: 1px solid rgba(0, 0, 0, 0.28);
  border-radius: 50%;
  /* Markenfarbe, abgedunkelt – siehe den Block zu `.hellbraun` weiter unten. */
  color: #7b6a6a;
  flex: 0 0 auto;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.spec-kachel-icon svg {
  width: 2.4rem;
  height: 2.4rem;
}
.spec-kachel-kopf:hover .spec-kachel-icon {
  color: #000;
  border-color: rgba(0, 0, 0, 0.55);
}
.spec-kachel-titel {
  font-size: 2.1rem;
  line-height: 1.2;
  letter-spacing: 0.01em;
}
/* Geöffnet wird die Kachel zur Kopfzeile: Symbol klein nach links, Titel
   daneben, Schliessen-Kreuz rechts. */
.spec-kachel[open] > .spec-kachel-kopf {
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: 1.6rem;
  min-height: 0;
  padding: 2.4rem 6rem 2rem 2.8rem;
  text-align: left;
  position: relative;
}
.spec-kachel[open] .spec-kachel-icon {
  width: 4.4rem;
  height: 4.4rem;
  color: #000;
}
.spec-kachel[open] .spec-kachel-icon svg {
  width: 2.2rem;
  height: 2.2rem;
}
.spec-kachel[open] > .spec-kachel-kopf::before,
.spec-kachel[open] > .spec-kachel-kopf::after {
  content: '';
  position: absolute;
  right: 2.6rem;
  top: 50%;
  width: 1.6rem;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}
.spec-kachel[open] > .spec-kachel-kopf::before {
  transform: rotate(45deg);
}
.spec-kachel[open] > .spec-kachel-kopf::after {
  transform: rotate(-45deg);
}
.spec-kachel-inhalt {
  padding: 0 2.8rem 3rem 2.8rem;
}
/* Zubereitung je Gerät nebeneinander - «Ich habe eine Fritteuse, wie lange?» */
.spec-zubereitung {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(24rem, 1fr));
  gap: 2.4rem 3.2rem;
}
.spec-zubereitung h4,
.spec-zubereitung .h4 {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 1.2rem;
  margin: 0 0 0.6rem 0;
  text-align: left;
  max-width: none;
}
.spec-zubereitung p {
  margin: 0;
  font-size: 1.45rem;
  line-height: 1.65;
}
/* Kennzahl-Zeile unter dem Produkttitel. */
.produkt-kennzeile {
  font-size: 1.4rem;
  letter-spacing: 0.06em;
  opacity: 0.8;
  margin: 0.8rem 0 0 0;
}

/* Die Wand steht seit dem Umbau auf EINER Spalte – die früheren Umbrüche bei
   1023px und 639px sind damit hinfällig. Übrig bleibt, was auf dem Telefon
   wirklich enger werden muss: Polsterung und Schriftgrad. */
@media (max-width: 639px) {
  .spec-kachel-kopf {
    padding: 2rem 2.2rem;
    gap: 1.4rem;
  }
  .spec-kachel-icon {
    width: 4.4rem;
    height: 4.4rem;
  }
  .spec-kachel-titel {
    font-size: 1.8rem;
  }
  .spec-kachel[open] > .spec-kachel-kopf {
    padding: 2rem 5rem 1.6rem 2.2rem;
  }
  .spec-kachel-inhalt {
    padding: 0 2.2rem 2.4rem 2.2rem;
  }
}
.spec-lead {
  font-size: 1.45rem;
  line-height: 1.65;
  margin: 0 0 2rem 0;
  max-width: 72ch;
}
.spec-note {
  font-size: 1.2rem;
  opacity: 0.7;
  margin: 0.6rem 0 1.6rem 0;
}
.spec-head {
  margin-bottom: 2.8rem;
}

/* Auszeichnungen (vegan, halal, koscher …) – im Produktkopf und im Angabenblock */
.right-details .spec-badges {
  margin: 1.6rem 0 0 0;
}
.spec-badges {
  list-style: none;
  margin: 0 0 2.4rem 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.spec-badges li {
  border: 1px solid currentColor;
  border-radius: 2rem;
  padding: 0.5rem 1.4rem;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.spec-legal {
  margin-top: 2.8rem;
  font-size: 1.2rem;
  line-height: 1.7;
  opacity: 0.65;
}

/* Auf dunklem Grund (Farb-Utility-Klassen des Themes) Linien aufhellen. */
.color-white .spec-table th,
.color-white .spec-table td {
  border-color: rgba(255, 255, 255, 0.25);
}

/* Bis 1023px, nicht bis 639px.
   Das Raster des Themes stellt schon ab 640px (`medium-*`) auf zwei Spalten um.
   Der Umbruch hier endete aber eine Stufe früher, sodass genau im Band
   640–1023px – Tablets im Hochformat, schmale Fenster – niemand zuständig war:
   zwei Spalten nebeneinander, aber ohne die Regeln, die sie dort lesbar halten. */
@media only screen and (max-width: 1023px) {
  .spec-table-pairs th[scope='row'],
  .spec-table-nutrition th[scope='row'] {
    width: 46%;
  }
  .table-contents .label {
    flex-basis: 100%;
  }
  /* Kurzer Datenblock neben hohem Bild: oben bündig statt mittig schwebend. */
  .entry-content {
    align-items: flex-start;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Blog und Stelleninserate
   ───────────────────────────────────────────────────────────────────────── */

/* Der schwarze Body scheint sonst durch und schwarze Schrift wird unsichtbar.
   Das Theme gibt Detailseiten über `#post` eine weisse Lesefläche – die
   Übersichtsseiten von Blog und Stellen bekommen dieselbe. */
#blog-archive,
#jobs-archive {
  margin-top: 5.8rem;
  background-color: #fff;
}
@media only screen and (min-width: 640px) {
  #blog-archive,
  #jobs-archive {
    margin-top: 9.1rem;
  }
}
.blog-intro {
  padding-top: 6rem;
  text-align: left;
}
@media only screen and (min-width: 640px) {
  .blog-intro {
    padding-top: 9rem;
  }
}
.blog-intro h1,
#blog-archive h1,
#jobs-archive h1 {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
  text-align: left;
}
.blog-lead {
  font-size: 1.8rem;
  line-height: 1.5;
  max-width: 62ch;
  margin: 0 0 2rem 0;
  text-align: left;
}
.blog-empty,
.jobs-empty {
  text-align: left;
  margin-bottom: 8rem;
}

/* Leere Übersicht: der Abstand war für eine LISTE gedacht.

   Zwischen dem Einleitungssatz und der Meldung «Zurzeit sind keine Beiträge
   veröffentlicht.» standen 120px – 40px Abstand unter dem Lead plus 80px
   unter dem Einleitungsblock. Vor einer Liste von Beiträgen ist das richtig,
   vor einem einzelnen Satz sieht es aus, als fehle etwas.

   Gemessen am 16.09.2026 auf /blog und /jobs, 1440px. */
#blog-archive.ist-leer .blog-intro,
#jobs-archive.ist-leer .blog-intro {
  margin-bottom: 2.4rem;
}
#blog-archive.ist-leer .blog-lead,
#jobs-archive.ist-leer .blog-lead {
  margin-bottom: 0;
}

/* Schnelles Auf- und Zuklappen des Menüs markierte die halbe Seite blau.

   Zwei Klicks kurz hintereinander sind für den Browser ein Doppelklick, drei
   ein Dreifachklick – und der markiert Text. Weil der Knopf über dem
   Seiteninhalt liegt, lief die Markierung quer über Bild und Text: alles
   blau, bis man irgendwohin klickte.

   Bedienelemente sind kein Text zum Kopieren. */
#site-header,
#top-bar,
#menu-toggle,
.menu-toggle,
#site-header button,
#site-header .hamburger {
  -webkit-user-select: none;
  user-select: none;
}
.jobs-empty .button {
  margin-top: 1.6rem;
}

/* ── Beitragsliste ───────────────────────────────────────────────────────── */
.blog-list {
  list-style: none;
  margin: 0 0 8rem 0;
  padding: 0;
  display: grid;
  gap: 3.2rem;
  grid-template-columns: 1fr;
}
@media only screen and (min-width: 640px) {
  .blog-list {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media only screen and (min-width: 1024px) {
  .blog-list {
    grid-template-columns: repeat(3, 1fr);
  }
}
.blog-card-link {
  display: flex;
  flex-direction: column;
  height: 100%;
  color: inherit;
  text-decoration: none;
}
.blog-card-media {
  display: block;
  aspect-ratio: 3 / 2;
  background-size: cover;
  background-position: center;
  background-color: #3f2b2b;
  margin-bottom: 1.6rem;
}
.blog-card-media.no-image {
  background-color: #5f6672;
}
.blog-card-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 0.8rem;
}
.blog-card-date {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 1.15rem;
  opacity: 0.7;
}
.blog-card-title {
  font-size: 2.2rem;
  line-height: 1.2;
  font-weight: 700;
}
.blog-card-lead {
  font-size: 1.45rem;
  line-height: 1.6;
}
.blog-card-more {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 1.15rem;
  border-bottom: 1px solid currentColor;
  padding-bottom: 0.2rem;
  margin-top: 0.4rem;
}
.blog-card-link:hover .blog-card-title {
  text-decoration: underline;
}

/* ── Beitrag / Stelleninserat ────────────────────────────────────────────── */
.blog-body {
  text-align: left;
  padding-bottom: 8rem;
}
.blog-single .entry-content,
.job-single .entry-content {
  align-items: flex-start;
}
.blog-body h1 {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
  text-align: left;
}
.blog-meta {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 1.15rem;
  opacity: 0.7;
  margin: 2.4rem 0 0.8rem 0;
  text-align: left;
}
.blog-prose {
  max-width: 68ch;
}
.blog-prose h2,
.blog-prose h3,
.blog-prose h4,
.blog-prose .h2,
.blog-prose .h3,
.blog-prose .h4 {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
  text-align: left;
  margin-top: 3.2rem;
  margin-bottom: 1.2rem;
}
.blog-prose h3,
.blog-prose .h3 {
  font-size: 2rem;
}
.blog-prose p,
.blog-prose li {
  font-size: 1.6rem;
  line-height: 1.7;
  text-align: left;
}
.blog-prose p {
  margin-bottom: 1.6rem;
}
.blog-prose ul,
.blog-prose ol {
  margin: 0 0 1.6rem 0;
  padding-left: 2.2rem;
}
.blog-prose li {
  margin-bottom: 0.6rem;
  list-style: disc;
}
.blog-prose ol li {
  list-style: decimal;
}
.blog-prose a {
  color: inherit;
  text-decoration: underline;
}
.blog-prose img {
  max-width: 100%;
  height: auto;
  margin: 2.4rem 0;
}

/* ── Stellenliste ────────────────────────────────────────────────────────── */
.jobs-list {
  list-style: none;
  margin: 0 0 4rem 0;
  padding: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.18);
}
.job-item {
  border-bottom: 1px solid rgba(0, 0, 0, 0.18);
}
.job-item a {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 2.4rem 0;
  color: inherit;
  text-decoration: none;
  text-align: left;
}
.job-item a:hover .job-title {
  text-decoration: underline;
}
.job-title {
  font-size: 2.2rem;
  line-height: 1.2;
  font-weight: 700;
}
.job-facts {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 1.15rem;
  opacity: 0.7;
}
.job-lead {
  font-size: 1.45rem;
  line-height: 1.6;
  max-width: 68ch;
}
.jobs-contact {
  text-align: left;
  margin-bottom: 8rem;
  font-size: 1.45rem;
}
.job-facts-table {
  margin: 2.4rem 0 3.2rem 0;
  max-width: 52rem;
}
.job-download {
  margin: 2.4rem 0 0 0;
  text-align: left;
}
.job-download a {
  color: inherit;
}
.job-apply {
  margin: 3.2rem 0 0 0;
  text-align: left;
}

/* Kategorieseiten: der Kategoriename ist die Seitenüberschrift (H1).
   Das Theme zentriert H1 global und begrenzt die Breite – hier bündig. */
.category-products .category-title {
  font-size: 3rem;
  line-height: 1.15;
  margin: 0 auto 3.2rem auto;
  max-width: none;
}

/* Die Spaltenklassen des Themes greifen erst ab 1024px (large) bzw. 1600px
   (xlarge). Darunter läuft der Inhalt über die volle Breite – dann braucht er
   seitliche Luft, sonst klebt der Text am Rand. */
.produkt-spezifikation > .columns,
#blog-archive .columns,
#jobs-archive .columns,
.blog-body {
  padding-left: 2rem;
  padding-right: 2rem;
}
@media only screen and (min-width: 1024px) {
  .produkt-spezifikation > .columns,
  #blog-archive .columns,
  #jobs-archive .columns,
  .blog-body {
    padding-left: 0;
    padding-right: 0;
  }
}
/* Lange Stellen-/Beitragstitel dürfen umbrechen statt die Zeile zu sprengen. */
.blog-body h1 {
  font-size: 3.6rem;
  line-height: 1.1;
  overflow-wrap: break-word;
}
@media only screen and (min-width: 640px) {
  .blog-body h1 {
    font-size: 4.5rem;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Bewegung
   Zurückhaltend und einheitlich: ein Einblenden beim Scrollen, ein sanfter
   Zoom auf Bildkacheln, ein weiches Öffnen der Akkordeons. Mehr nicht – die
   Bilder sollen wirken, nicht die Effekte.
   ───────────────────────────────────────────────────────────────────────── */

/* Erst wenn das Skript läuft, wird überhaupt etwas versteckt (siehe Reveal.tsx).
   Ohne JavaScript bleibt jeder Inhalt sichtbar. */
/* UMGEDREHT (08.09.2026).
   Vorher versteckte diese Regel JEDES [data-reveal], sobald das Skript
   `reveal-on` gesetzt hatte, und deckte es erst wieder auf, wenn der
   Beobachter auslöste. Löste der für ein Element nie aus, blieb der Inhalt
   dauerhaft unsichtbar - im HTML vollständig vorhanden, auf dem Schirm weg.
   Genau so standen die Blogübersicht und Teile der Produktseite leer.

   Jetzt versteckt das CSS nur noch, was das Skript ausdrücklich mit
   `will-reveal` markiert - also ausschliesslich Elemente, die es auch
   beobachtet. Was ausserhalb dieses Wegs liegt, bleibt sichtbar. Der
   Grundzustand ist Sichtbarkeit; die Animation ist die Ausnahme. */
[data-reveal].will-reveal {
  opacity: 0;
  /* War 1.8rem. Auf einem 800px hohen Farbband ist ein Versatz von 18px gut
     sichtbar - zusammen mit dem Aufblenden wirkte das wie ein Ruck. */
  transform: translateY(1rem);
}
[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  /* War 0.75s. Zusammen mit dem zu spaten Auslosen dauerte das Aufblenden
     langer, als man zum Vorbeiscrollen braucht. */
  transition:
    opacity 0.45s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* Kacheln in einer Reihe leicht versetzt – wirkt wie ein Schwenk statt wie ein
   Sprung. Nur die ersten Elemente, danach greift der Scroll-Trigger ohnehin. */
.blog-list > [data-reveal]:nth-child(2).is-revealed,
.term-products > [data-reveal]:nth-child(2).is-revealed,
.jobs-list > [data-reveal]:nth-child(2).is-revealed {
  transition-delay: 0.09s;
}
.blog-list > [data-reveal]:nth-child(3).is-revealed,
.term-products > [data-reveal]:nth-child(3).is-revealed,
.jobs-list > [data-reveal]:nth-child(3).is-revealed {
  transition-delay: 0.18s;
}
.blog-list > [data-reveal]:nth-child(n + 4).is-revealed,
.term-products > [data-reveal]:nth-child(n + 4).is-revealed {
  transition-delay: 0.27s;
}

/* Bildkacheln: langsamer Zoom beim Hovern – „cinematic", nicht verspielt. */
.blog-card-media,
.term-product,
.product-teaser .background-image {
  transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.blog-card-link:hover .blog-card-media,
.term-product:hover,
.product-teaser:hover .background-image {
  transform: scale(1.035);
}
/* Der Zoom darf nicht aus der Kachel laufen. */
.blog-card,
.product-item,
.product-teaser {
  overflow: hidden;
}
.term-products .product-item {
  overflow: hidden;
}

/* Kacheln: weiches Aufklappen statt Sprung. Browser ohne `::details-content`
   klappen einfach hart auf - der Inhalt ist in beiden Fällen da. */
.spec-kachel::details-content {
  block-size: 0;
  overflow: hidden;
  transition:
    block-size 0.4s cubic-bezier(0.22, 0.61, 0.36, 1),
    content-visibility 0.4s allow-discrete;
}
.spec-kachel[open]::details-content {
  block-size: auto;
}

/* Buttons und Links: spürbar, aber ruhig. */
.button,
.blog-card-more,
.job-item a {
  transition:
    background-color 0.3s ease,
    color 0.3s ease,
    opacity 0.3s ease;
}
.job-item a:hover {
  opacity: 0.7;
}

/* Wer reduzierte Bewegung wünscht, bekommt gar keine – auch keinen Zoom. */
@media (prefers-reduced-motion: reduce) {
  [data-reveal].will-reveal {
    opacity: 1;
    transform: none;
  }
  .blog-card-link:hover .blog-card-media,
  .term-product:hover,
  .product-teaser:hover .background-image {
    transform: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Detailschliff
   ───────────────────────────────────────────────────────────────────────── */

/* Das Produktbild klebte direkt unter der schwarzen Kopfleiste – oben Luft. */
.produkte.type-produkte .entry-content {
  padding-top: 4rem;
}
@media only screen and (min-width: 640px) {
  .produkte.type-produkte .entry-content {
    padding-top: 7rem;
  }
}

/* Beitragskacheln: gleich lange Anrisse, damit das Raster ruhig wirkt. */
.blog-card-lead {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-card-body {
  flex: 1 1 auto;
}
/* «Weiterlesen» sitzt unten bündig, auch wenn der Anriss kürzer ist. */
.blog-card-more {
  margin-top: auto;
  padding-top: 1.2rem;
}

/* Stellenübersicht: die Luft zwischen Lead und Liste war zu gross. */
#jobs-archive .blog-lead,
#blog-archive .blog-lead {
  margin-bottom: 4rem;
}

/* Eckdaten-Tabelle: Werte nicht umbrechen lassen, wo es unnötig ist. */
.table-contents .data {
  overflow-wrap: break-word;
}

/* ── Häufige Fragen (FAQ-Block) ──────────────────────────────────────────────
   Aufklappen macht der Browser über <details>/<summary>. Kein JavaScript, keine
   ARIA-Attribute von Hand – Tastatur, Screenreader und die Browser-Suche
   (Strg+F öffnet geschlossene Abschnitte selbst) funktionieren dadurch von
   allein. Das Dreieck des Browsers wird ersetzt, nicht ergänzt. */
.faq,
.faq h2,
.faq h3,
.faq .h2,
.faq .h3,
.faq p,
.faq li,
.faq .faq-frage,
.faq .faq-antwort {
  /* Das Theme zentriert Überschriften und Absätze direkt auf dem Element.
     Eine Regel am Container erbt sich dagegen nicht durch - sie muss die
     Kinder ausdrücklich nennen, sonst steht das FAQ zentriert da. */
  text-align: left;
}
.faq {
  max-width: 84rem;
  margin: 0 auto;
  /* Der seitliche Abstand muss hier fest sein, nicht in Prozent.

     `.box-padding` setzt `padding: 7.8rem 20%`, und Prozentangaben beim
     Innenabstand rechnen gegen die Breite des ELTERNELEMENTS - das ist die
     Zeile über die volle Fensterbreite, nicht dieser 84rem breite Block. Auf
     einem 1920px-Bildschirm ergab das 384px Abstand je Seite bei 840px
     Gesamtbreite: 72px Platz für den Text, jede Antwort brach nach jedem
     einzelnen Wort um. Je breiter der Bildschirm, desto schmaler das FAQ. */
  padding-left: 3rem;
  padding-right: 3rem;
}
@media only screen and (max-width: 639px) {
  .faq {
    padding-left: 2rem;
    padding-right: 2rem;
  }
}
.faq-titel {
  margin: 0 0 1.2rem 0;
  font-size: 3rem;
  line-height: 1.15;
  max-width: none;
}
.faq-einleitung {
  max-width: 62rem;
  margin: 0 0 3.6rem 0;
  font-size: 1.55rem;
  line-height: 1.6;
  opacity: 0.75;
}
.faq-liste {
  border-top: 1px solid rgba(0, 0, 0, 0.15);
}
.color-white .faq-liste,
.schwarz .faq-liste {
  border-top-color: rgba(255, 255, 255, 0.25);
}
.faq-eintrag {
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.color-white .faq-eintrag,
.schwarz .faq-eintrag {
  border-bottom-color: rgba(255, 255, 255, 0.25);
}
.faq-frage {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding: 2rem 0;
  cursor: pointer;
  font-size: 1.9rem;
  line-height: 1.4;
  /* Ohne das zeigt Safari zusätzlich sein eigenes Dreieck. */
  list-style: none;
}
.faq-frage::-webkit-details-marker {
  display: none;
}
.faq-frage:hover .faq-frage-text {
  opacity: 0.7;
}
.faq-frage-text {
  transition: opacity 0.2s ease;
}
/* Plus, das beim Aufklappen zum Minus wird – aus zwei Strichen gebaut, damit
   keine Schriftart und kein Bild nötig ist. */
.faq-zeichen {
  position: relative;
  flex: 0 0 1.6rem;
  height: 1.6rem;
  align-self: center;
}
.faq-zeichen::before,
.faq-zeichen::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1px;
  background: currentColor;
  transition: transform 0.25s ease;
}
.faq-zeichen::after {
  transform: rotate(90deg);
}
.faq-eintrag[open] .faq-zeichen::after {
  transform: rotate(0deg);
}
.faq-antwort {
  padding: 0 0 2.6rem 0;
  max-width: 68rem;
  font-size: 1.55rem;
  line-height: 1.7;
  opacity: 0.85;
}
.faq-antwort > :last-child {
  margin-bottom: 0;
}
/* Auf schmalen Schirmen darf die Frage mehrzeilig werden, das Zeichen bleibt
   oben bündig – sonst rutscht es bei dreizeiligen Fragen in die Mitte. */
@media only screen and (max-width: 639px) {
  .faq-frage {
    font-size: 1.6rem;
    gap: 1.2rem;
  }
  .faq-zeichen {
    align-self: flex-start;
    margin-top: 0.4rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .faq-zeichen::before,
  .faq-zeichen::after,
  .faq-frage-text {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Kategorieseiten (/kategorien/…)

   Für .category-products, .term-products, .term-product, .product-item und
   .headings gab es bisher NUR Dekoration (Hover-Zoom, overflow) und kein
   einziges Layout: kein Raster, keine Grössen, keine Farben. Die Folge war
   eine praktisch leere Seite – die Überschrift schwarz auf schwarz, die
   Unterkategorien als blaue Standard-Browserlinks, und die Produktkacheln
   0 × 0 Pixel gross, also mehrere hundert Pixel schwarze Leere statt der
   Produktliste.
   ───────────────────────────────────────────────────────────────────────── */
.category-products {
  background: #000;
  color: #fff;
  padding: 6rem 5% 8rem 5%;
  text-align: left;
}
/* Alles hier drin erbt die Schriftfarbe – sonst zeichnet der Browser seine
   eigenen Linkfarben (blau auf schwarz). */
.category-products a {
  color: inherit;
  text-decoration: none;
}
.category-products .category-title {
  color: inherit;
}

/* Das Raster. `auto-fill` statt fester Spaltenzahl: Die Kacheln ordnen sich
   nach verfügbarer Breite, vom Handy bis zum grossen Schirm, ohne eigenen
   Breakpoint je Stufe. */
.term-products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(28rem, 1fr));
  gap: 2rem;
  align-items: stretch;
}
@media only screen and (max-width: 639px) {
  .term-products {
    grid-template-columns: 1fr;
    gap: 1.6rem;
  }
  .category-products {
    padding: 4rem 5% 6rem 5%;
  }
}

/* Die Kachel selbst. `aspect-ratio` gibt ihr überhaupt erst eine Höhe – das
   Hintergrundbild allein streckt nichts auf. */
.term-product {
  display: block;
  position: relative;
  aspect-ratio: 4 / 5;
  background-color: #111;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  overflow: hidden;
}
.term-product .inner {
  display: flex;
  align-items: flex-end;
  height: 100%;
  padding: 2.4rem;
}
.term-product .inner h4,
.term-product .inner .h4 {
  margin: 0;
  font-size: 2rem;
  line-height: 1.25;
  color: #fff;
}

/* Eine Kachel mit `aspect-ratio` darf sich nicht in der Höhe strecken lassen.

   Im Raster stehen zwei Kachelarten nebeneinander: Warengruppen (Titel IM
   Bild) und Produkte (Titel UNTER dem Bild). Die Produktkachel ist dadurch
   rund 60px höher – und eine Rasterzeile ist so hoch wie ihr höchstes Kind.

   Die Warengruppenkacheln werden auf diese Zeilenhöhe gestreckt. Weil sie
   `aspect-ratio: 4 / 5` tragen, rechnet der Browser daraus die BREITE zurück:
   473px Höhe ergeben 378px Breite – in einer Spalte von 329px. Jede Kachel
   ragte also 48px in ihre rechte Nachbarin, und die letzte über den Rand
   hinaus. Auf /kategorien/vegi-und-vegan traf es «PIYA Plant Kebab»: Bild
   rechts aus dem Raster gelaufen, Beschriftung von `overflow: hidden`
   abgeschnitten.

   Sichtbar wird es nur, wenn beide Arten in DERSELBEN Zeile landen – bei
   1920px (fünf Spalten) und bei 1280px/1024px in der zweiten Zeile. Bei
   1440px steht die Produktkachel allein in Zeile zwei, dort stimmte alles.
   Genau deshalb fiel es bei den früheren Durchgängen nicht auf.

   `align-self: start` nimmt die Höhe aus der Gleichung: Der Browser rechnet
   wieder von der Spaltenbreite zur Höhe statt umgekehrt. Gemessen über sechs
   Breiten – Kachelbreite gleich Spaltenbreite, kein Überstand. */
.term-products > .term-product {
  align-self: start;
}


/* Zurück-Link über der Überschrift.
   BackLink trägt die Theme-Klasse `color-black` – auf hellen Seiten richtig,
   auf dem schwarzen Grund dieser Seite unsichtbar. Der Kontext sticht sie
   darum hier, und nur hier. */
.category-products .back,
.category-products .back.color-black {
  display: inline-block;
  margin-bottom: 1.6rem;
  color: #fff;
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  opacity: 0.7;
}
.category-products .back:hover {
  opacity: 1;
}
/* Der Pfeil davor ist eine Grafik in Schwarz (`pfeil_links.svg`, #11110F).
   Auf dieser Seite steht er auf schwarzem Grund und war schlicht nicht da -
   die Beschriftung schwebte ohne Zeichen davor. Umkehren macht ihn weiss,
   ohne eine zweite Datei zu brauchen. */
.category-products .back::before {
  filter: invert(1);
}

/* ── Bilder, die ihre Fläche füllen sollen ───────────────────────────────────
   Das Theme meint `.background-image` als Hintergrund: absolut positioniert,
   hinter dem Text. In zwei Fällen greift diese Absicht nicht, und das Bild
   steht als gewöhnliches Element im Inhaltsfluss:

   1. Produktkacheln – dort schnürt die Polsterung der Kachel (bis 6rem) das
      Bild ein: schwarze Ränder ringsum, und das rote «NEU»-Band hing im
      leeren Rand statt in der Bildecke.
   2. Der Kopfbereich eines Blogbeitrags – `.entry-header` ist nur
      `padding-top: 9rem` hoch, das Bild darin aber 960px. Es ragte über den
      Header hinaus und legte sich über Titel und Fliesstext: Auf dem Desktop
      sah man das Bild und danach direkt die Fusszeile.

   Nur `object-fit` zu setzen reicht nicht – ein Element im Inhaltsfluss bleibt
   im Inhaltsbereich. Es muss aus dem Fluss heraus, dann trägt es die Polsterung
   nicht mehr mit und der Text liegt wieder darüber. */
.product-teaser,
.term-product,
/* Kopfbereiche und Bildblöcke: Der Behälter muss den Bezugspunkt stellen,
   damit das Bild darin absolut liegen kann. `#page-header` bringt das schon
   mit, die Bildblöcke im Seiteninhalt nicht. */
[data-responsive-background-image] {
  position: relative;
}
.product-teaser > .background-image,
.term-product > .background-image,
.blog-single #page-header .background-image,
/* Das <img> IST das Bild - nicht ein CSS-Hintergrund daneben.

   Vorher stand beides da: ein `background-image` auf dem Behälter (sichtbar)
   und ein `<img>` mit `srcset` (per Theme-CSS `display: none`). Geladen wurde
   trotzdem beides, sobald die beiden auf verschiedene Dateien zeigten - auf
   fünf von sieben gemessenen Seiten, 1,4 MB von 6,0 MB auf dem Desktop. Der
   Besucher sah davon die Hälfte nie.

   Jetzt trägt das <img> das Bild. Damit greift auch `srcset`/`sizes`: Auf dem
   Telefon kommt die kleinere Fassung statt des Originals. `cover` und die
   zentrierte Ausrichtung entsprechen dem, was `background-size: cover` und
   `background-position: 50% 50%` vorher taten - an allen 28 Kopfbereichen
   nachgemessen. */
[data-responsive-background-image] > .background-image {
  /* Das Theme versteckt dieses <img> und zeigt es NUR bei abgeschaltetem
     JavaScript (`.no-js [data-responsive-background-image] .background-image`).
     Es rechnete mit einem eigenen Skript, das daraus den Hintergrund setzt -
     das gibt es hier nicht. Also zeigen wir das Bild selbst. */
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  /* Das Theme zentriert über `left:50%` + `translateX(-50%)`; mit inset-0
     wäre das eine zweite, widersprüchliche Zentrierung. */
  transform: none;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}
/* Beschriftung, Knopf und «NEU»-Band gehören über das Bild. Ohne das
   verschwanden sie hinter dem jetzt flächendeckenden Bild.

   `.product-overlay` ist ausdrücklich ausgenommen. Das Theme legt ihn als
   `position: absolute` mit `top/right/bottom/left: 2.5rem` an - ein Kasten, der
   die Kachel mit 25px Rand ausfüllt, auf jeder Kachel gleich. Meine Regel machte
   daraus `position: relative`: Damit wirken `right` und `bottom` nicht mehr,
   `top`/`left` verschieben ihn bloss, und seine Höhe richtet sich plötzlich nach
   der Textlänge. Sichtbar wurde das beim Überfahren - ein schwarzer Kasten, der
   irgendwo in der Kachel schwebte und bei jedem Produkt anders hoch war
   (gemessen: 327px gegen 354px bei gleich grossen Kacheln). */
.product-teaser > *:not(.background-image):not(.product-overlay),
.product-teaser::before,
.term-product > .inner {
  position: relative;
  z-index: 1;
}
.product-teaser > .product-overlay {
  z-index: 1;
}

/* Kopfbereich des Blogbeitrags: Seitenverhältnis statt fester Höhe.

   Feste 46rem ergaben auf 1440px ein Band von 3,13:1. Die Blogbilder sind
   3:2 – `cover` schnitt also knapp die Hälfte der Bildhöhe weg. Beim Bild
   «PIYA Premium Beef» fielen dabei der Schriftzug «PREMIUM BEEF» und
   «SWISS MADE» heraus, beim Kebab der Teller samt Schatten: In der Übersicht
   war das Motiv vollständig, im Beitrag wirkte es zu nah herangeholt.

   2,35:1 zeigt alle drei Motive ganz (nachgestellt am 14.09.2026) und ist
   zugleich das Verhältnis der Kategorie-Kopfbilder – die Kopfbereiche der
   Seite sehen damit gleich aus. Auf 1440px sind das 612px statt 460px.

   Auf schmalen Schirmen bleibt es bei einer festen Höhe: 2,35:1 wären auf
   390px gerade 166px – ein Streifen, kein Kopfbild. */
.blog-single #page-header {
  position: relative;
  height: auto;
  aspect-ratio: 2.35 / 1;
  padding-top: 0;
  overflow: hidden;
}
@media only screen and (max-width: 1023px) {
  .blog-single #page-header {
    aspect-ratio: auto;
    height: 32rem;
  }
}
@media only screen and (max-width: 639px) {
  .blog-single #page-header {
    aspect-ratio: auto;
    height: 22rem;
  }
}

/* Antworten im FAQ: die Absätze kommen aus dem Rich-Text und behalten sonst
   die Theme-Grösse von 2rem - dadurch stand die Antwort grösser da als ihre
   Frage. */
.faq-antwort,
.faq-antwort p,
.faq-antwort li {
  font-size: 1.55rem;
  line-height: 1.7;
}

/* «Ähnliche Produkte» klebte an den Farbboxen darüber - die Überschrift sass
   ohne Abstand direkt auf deren Unterkante. */
.entry-footer {
  margin-top: 6rem;
}
.entry-footer > .h1 {
  margin-bottom: 3.2rem;
}
@media only screen and (max-width: 639px) {
  .entry-footer {
    margin-top: 4rem;
  }
}

/* Schwarzer Streifen links und rechts neben den Produktkacheln.

   `.product-teaser-container` ist im Theme schwarz hinterlegt, und die Kacheln
   tragen ab 640px je 7.5px Aussenabstand (`#post .product-teaser`). Zwischen
   zwei Kacheln ergibt das die gewollte schwarze Fuge - vor der ersten und nach
   der letzten Kachel aber einen 8 Pixel breiten schwarzen Balken über die volle
   Kachelhöhe. Er sah aus wie ein abgeschnittener Rand und schob die rote
   NEU-Ecke sichtbar nach innen. Aussen also keinen Abstand. */
.product-teaser-container > .product-teaser:first-child,
#post .product-teaser-container > .product-teaser:first-child {
  margin-left: 0;
}
.product-teaser-container > .product-teaser:last-child,
#post .product-teaser-container > .product-teaser:last-child {
  margin-right: 0;
}

/* Lesbarkeit der Kacheltitel auf hellen Bildstellen.

   Titel und Einheit stehen weiss oben in der Kachel, direkt auf dem Foto. Bei
   den meisten Produktbildern ist dort dunkler Hintergrund – bei «Platin»,
   «Star» oder «Gold» beginnt aber genau dort das helle Fleisch bzw. die rote
   Tomate, und der Titel verlor seinen Kontrast.

   Ein Verlauf von oben, der nach 45 % der Höhe vollständig verschwunden ist:
   Er verdunkelt nur den Streifen hinter der Schrift, das Produktfoto selbst
   bleibt unangetastet. Dieselbe Technik nutzt das Theme bereits bei den
   Kategorie-Kacheln, dort von unten. */
.product-teaser::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 45%;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 100%);
  pointer-events: none;
  z-index: 0;
}
/* Kacheln ohne Foto tragen bereits einen eigenen ::after-Platzhalter
   («Foto folgt»); dort ist der Verlauf weder nötig noch erwünscht. */
.product-teaser.no-image::after {
  background: none;
  height: auto;
}

/* Kategorie-Karte im Produktarchiv auf dem Telefon.

   Die Karte trägt nur den Namen der Oberkategorie und dient als Trenner im
   Raster. Auf dem Desktop steht sie neben Produktkacheln und teilt deren Höhe -
   das ist gewollt. Auf dem Telefon liegt sie über die volle Breite allein in
   ihrer Zeile und war trotzdem 460 Pixel hoch: elf Zeichen Text in einem
   schwarzen Block, den man erst wegscrollen musste, um die Produkte zu sehen.
   Dort also nur so hoch wie ihr Inhalt. */
@media only screen and (max-width: 639px) {
  .product-teaser.product-category {
    height: auto;
    min-height: 0;
    padding: 3.6rem 2rem;
  }
}

/* Knöpfe in Textblöcken waren auf dem Desktop unsichtbar.

   Das Theme blendet sie grundsätzlich aus und zeigt sie erst, wenn die Maus
   über den ganzen Block fährt:

     .textblock .button          { opacity: 0 }
     .textblock:hover .button    { opacity: 1 }

   Sichtbar war der Knopf nur unter `@media (hover:none) and (max-width:1024px)`,
   also auf Telefon und Tablet. Auf jedem Desktop mit Maus blieb damit JEDER
   Handlungsaufruf verborgen, bis man zufällig darüberfuhr - «Mehr zu Piya
   erfahren», «Mehr zu one tree planted», «Zum Engagement» und alle weiteren.
   Wer nicht mit der Maus über die Box fuhr, sah nie, dass es dort weitergeht.

   Ein Knopf, den man erst finden muss, ist kein Knopf. Er ist jetzt immer da;
   die Rückmeldung beim Überfahren übernimmt weiterhin `.button:hover`. */
.textblock .button,
.textblock .post-edit-link {
  opacity: 1;
}

/* Textblock, der NUR aus einem Knopf besteht.

   In der Redaktion steht der Knopf manchmal in einer eigenen Zeile statt im
   Textblock darüber (so kommt «Mehr zu Piya erfahren» auf /ueber-uns aus der
   Migration). Beide Zeilen tragen dann `.box-padding` mit bis zu 7.8rem
   Innenabstand: 78px unten am Text, 78px oben am Knopf. Zusammen mit dem
   Absatzabstand klafften dort rund 190 Pixel Leere, und der Knopf sah aus, als
   gehöre er nicht mehr dazu.

   Enthält ein Textblock ausser dem Knopf nichts, braucht er oben keinen eigenen
   Abstand - der des vorangehenden Blocks genügt. */
.textblock:has(> .button:only-child) {
  padding-top: 0;
}

/* ── Produktarchiv: Sachfilter, Kennzahlen, Listenansicht ─────────────────────
   Das Raster verkauft, die Liste bestellt. Beide Ansichten arbeiten auf
   denselben Daten; umgeschaltet wird ohne Seitenwechsel.
   Merkmale und Achsen kommen aus src/lib/produktmerkmale.ts.
   ───────────────────────────────────────────────────────────────────────── */

/* Nur für Screenreader – im Theme gab es dafür bisher keine Klasse. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Kennzahl-Zeile unter dem Produktnamen: «Spiess · Kalb · Schweizer Herkunft».
   Bewusst auch auf dem Telefon sichtbar (das alte `only-desktop` ist weg):
   Genau dort zählt jede Angabe, die man nicht antippen muss. */
.produkt-kennzahl {
  font-size: 1.25rem;
  letter-spacing: 0.04em;
  opacity: 0.85;
  margin: 0.4rem 0 0 0;
}

/* Werkzeugleiste unter den Kategorie-Knöpfen – gleiche Bandfarbe, damit
   Kategorien und Sachfilter als EIN Block gelesen werden. */
.produkt-werkzeugleiste-zeile > .columns {
  padding-bottom: 3.2rem;
}
.produkt-werkzeugleiste {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1.6rem;
  border-top: 1px solid rgba(0, 0, 0, 0.15);
  padding-top: 2.4rem;
}
/* Raster statt Flexbox.
   Als Flexbox wuchs das letzte Feld einer Zeile auf die ganze Restbreite: «Ohne
   Allergen» stand 927px breit unter vier 200px-Feldern. Im Raster behält jedes
   Feld seine Spaltenbreite, egal wie viele in der Zeile stehen. */
.produkt-filterfelder {
  display: grid;
  grid-template-columns: 1.4fr repeat(4, 1fr);
  gap: 1.2rem 1.6rem;
  flex: 1 1 auto;
  min-width: 0;
}
.produkt-filterfeld {
  display: block;
  position: relative;
  min-width: 0;
  text-align: left;
}
.produkt-filterfeld-label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 1.05rem;
  opacity: 0.7;
  margin-bottom: 0.5rem;
}
.produkt-filterfeld select {
  /* `appearance: none` nimmt den Systempfeil weg; der Ersatz unten ist reines
     CSS und braucht damit weder eine Grafik noch eine Lockerung der CSP. */
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  background: #fff;
  color: #000;
  border: 1px solid rgba(0, 0, 0, 0.28);
  border-radius: 0;
  padding: 1.1rem 3.4rem 1.1rem 1.4rem;
  font-family: inherit;
  font-size: 1.4rem;
  line-height: 1.2;
  cursor: pointer;
  /* Ohne diese Zeile sprengt eine lange Option («Alle Zubereitungsarten») auf
     schmalen Schirmen die Spalte, statt sie zu füllen. */
  text-overflow: ellipsis;
}
.produkt-filterfeld select:focus-visible {
  outline: 2px solid #000;
  outline-offset: 2px;
}
/* Suchfeld: gleiche Anmutung wie die Ausklapplisten, nur ohne Pfeil.
   `type="search"` bringt in Chrome ein eigenes Löschkreuz mit - das darf
   bleiben, es ist genau die Geste, die man dort erwartet. */
.produkt-suchfeld {
  /* Die Suche ist das Feld, in das getippt wird – sie bekommt die breiteste
     Spalte (siehe `grid-template-columns` oben). */
  grid-column: span 1;
}
.produkt-suchfeld input {
  /* Ohne diese Zeile rechnet der Browser Polsterung und Rahmen ZUSÄTZLICH zu
     den 100 %: Das Feld wurde 30px breiter als seine Spalte und schob sich
     unter die Ausklappliste daneben. Das Theme setzt `border-box` für
     `select`, für `input` aber nicht. */
  box-sizing: border-box;
  width: 100%;
  background: #fff;
  color: #000;
  border: 1px solid rgba(0, 0, 0, 0.28);
  border-radius: 0;
  padding: 1.1rem 1.4rem;
  font-family: inherit;
  font-size: 1.4rem;
  line-height: 1.2;
  -webkit-appearance: none;
  appearance: none;
}
.produkt-suchfeld input::placeholder {
  color: rgba(0, 0, 0, 0.45);
}
.produkt-suchfeld input:focus-visible {
  outline: 2px solid #000;
  outline-offset: 2px;
}
/* Der Pfeil gehört nur zu den Ausklapplisten. */
.produkt-suchfeld::after {
  display: none;
}

.produkt-filterfeld::after {
  content: '';
  position: absolute;
  right: 1.5rem;
  bottom: 1.7rem;
  width: 0.8rem;
  height: 0.8rem;
  border-right: 2px solid rgba(0, 0, 0, 0.55);
  border-bottom: 2px solid rgba(0, 0, 0, 0.55);
  transform: rotate(45deg);
  pointer-events: none;
}

/* Raster ⇄ Liste */
.produkt-ansichtswahl {
  display: flex;
  gap: 0.6rem;
  flex: 0 0 auto;
}
.produkt-ansicht-knopf {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.4rem;
  height: 4.4rem;
  background: transparent;
  border: 1px solid rgba(0, 0, 0, 0.28);
  color: rgba(0, 0, 0, 0.55);
  cursor: pointer;
  padding: 0;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.produkt-ansicht-knopf:hover {
  color: #000;
  border-color: rgba(0, 0, 0, 0.55);
}
.produkt-ansicht-knopf.active {
  background: #000;
  border-color: #000;
  color: #fff;
}
.produkt-ansicht-knopf:focus-visible {
  outline: 2px solid #000;
  outline-offset: 2px;
}
/* Beide Symbole sind gezeichnet, nicht geladen: ein Punktraster aus
   Schlagschatten und drei Linien. Spart zwei Anfragen und färbt sich über
   `currentColor` von selbst mit. */
.produkt-ansicht-icon {
  display: block;
}
/* Die Schlagschatten wachsen nur nach rechts und unten: Der sichtbare Block
   ist 15 px breit, das Element selbst 3 px. Ohne Ausgleich sässe das Raster
   um seine halbe Breite versetzt in der Schaltfläche. */
.produkt-ansicht-icon-raster {
  width: 3px;
  height: 3px;
  margin: -6px 0 0 -6px;
  background: currentColor;
  box-shadow:
    0 0 0 0 currentColor,
    6px 0 0 0 currentColor,
    12px 0 0 0 currentColor,
    0 6px 0 0 currentColor,
    6px 6px 0 0 currentColor,
    12px 6px 0 0 currentColor,
    0 12px 0 0 currentColor,
    6px 12px 0 0 currentColor,
    12px 12px 0 0 currentColor;
}
.produkt-ansicht-icon-liste {
  width: 15px;
  height: 2px;
  margin-top: -5px;
  background: currentColor;
  box-shadow:
    0 5px 0 0 currentColor,
    0 10px 0 0 currentColor;
}

/* Zähler, Fussnote, Zurücksetzen */
.produkt-werkzeugfuss {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.8rem 2rem;
  margin-top: 1.4rem;
  text-align: left;
}
.produkt-zaehler,
.produkt-fussnote {
  margin: 0;
  font-size: 1.25rem;
  text-align: left;
}
.produkt-zaehler strong {
  font-weight: bold;
}
.produkt-fussnote {
  opacity: 0.7;
  flex: 1 1 28rem;
}
.produkt-zuruecksetzen {
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  font-size: 1.25rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: inherit;
  cursor: pointer;
  border-bottom: 1px solid currentColor;
}

/* ── Listenansicht ──────────────────────────────────────────────────────── */
/* Dieselbe Bandfarbe wie die Filterleiste darüber: Filter und Ergebnis sollen
   als ein Block gelesen werden, und die Farbe steht damit fest, statt vom
   Umfeld abzuhängen (die Schatten unten rechnen mit ihr). */
.produkt-liste-zeile {
  background: #d2d6d0;
  color: #000;
}
.produkt-liste-zeile > .columns {
  padding-top: 4rem;
  padding-bottom: 6rem;
}
/* Breite Tabellen scrollen in sich – die Seite selbst nie horizontal.
   Die beiden Schatten an den Rändern verschwinden am jeweiligen Anschlag und
   sagen so, dass rechts noch Spalten stehen. Ohne sie sieht die abgeschnittene
   Tabelle auf dem Telefon einfach aus wie eine Tabelle mit drei Spalten. */
.produkt-liste-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background:
    linear-gradient(to right, #d2d6d0 30%, rgba(210, 214, 208, 0)) left center / 3rem 100% no-repeat
      local,
    linear-gradient(to left, #d2d6d0 30%, rgba(210, 214, 208, 0)) right center / 3rem 100% no-repeat
      local,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0)) left center /
      1.2rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0)) right center /
      1.2rem 100% no-repeat scroll;
}
.produkt-liste {
  width: 100%;
  min-width: 68rem;
  border-collapse: collapse;
  text-align: left;
  font-size: 1.4rem;
}
.produkt-liste th,
.produkt-liste td {
  text-align: left;
  vertical-align: middle;
  padding: 1.2rem 1.6rem 1.2rem 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
  font-weight: normal;
  hyphens: none;
  overflow-wrap: break-word;
}
.produkt-liste thead th {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 1.05rem;
  opacity: 0.7;
  border-bottom-width: 2px;
  white-space: nowrap;
}
.produkt-liste tbody tr:hover {
  background: rgba(0, 0, 0, 0.03);
}
.produkt-liste-bild {
  width: 8.4rem;
  padding-right: 1.6rem;
}
.produkt-liste-bild img {
  display: block;
  width: 7.2rem;
  height: 5.4rem;
  object-fit: cover;
}
.produkt-liste tbody th[scope='row'] {
  min-width: 20rem;
}
.produkt-liste tbody th[scope='row'] a {
  display: inline-block;
  font-size: 1.55rem;
  border-bottom: 1px solid transparent;
}
.produkt-liste tbody th[scope='row'] a:hover {
  border-bottom-color: currentColor;
}
.produkt-liste-kategorie {
  display: block;
  font-size: 1.15rem;
  opacity: 0.6;
  margin-top: 0.2rem;
}
.produkt-liste-neu {
  display: inline-block;
  margin-left: 0.8rem;
  padding: 0.2rem 0.6rem;
  background: #000;
  color: #fff;
  font-size: 1rem;
  letter-spacing: 0.12em;
  vertical-align: 0.2rem;
}
.produkt-liste-nummer {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.produkt-liste-merkmale {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.produkt-liste-merkmale li {
  border: 1px solid rgba(0, 0, 0, 0.3);
  padding: 0.15rem 0.7rem;
  font-size: 1.1rem;
  white-space: nowrap;
}

/* Eine Zeile mit fünf Feldern braucht Platz. Darunter wird umbrochen - erst
   auf drei, dann auf zwei, zuletzt auf eine Spalte. Die Suche nimmt dabei
   jeweils die ganze Zeile, weil sie den längsten Inhalt trägt. */
@media (max-width: 1199px) {
  .produkt-filterfelder {
    grid-template-columns: repeat(3, 1fr);
  }
  .produkt-suchfeld {
    grid-column: 1 / -1;
  }
}
@media (max-width: 767px) {
  .produkt-filterfelder {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 639px) {
  .produkt-werkzeugleiste {
    gap: 1.4rem;
  }
  .produkt-filterfelder {
    grid-template-columns: 1fr;
  }
  .produkt-ansichtswahl {
    width: 100%;
    justify-content: flex-start;
  }
}

/* Rücksprung auf der Produktseite: «Zurück zur Übersicht» über dem Bild.
   Anders als auf der Kategorieseite steht er hier auf weissem Grund - die
   Theme-Klasse `color-black` stimmt also, es braucht nur die Versalzeile und
   den Abstand. */
.produkt-zurueck-zeile {
  padding-top: 3.2rem;
}
.produkt-zurueck-zeile .back {
  display: inline-block;
  padding: 0;
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  opacity: 0.65;
}
.produkt-zurueck-zeile .back:hover {
  opacity: 1;
}

/* Letzte Kachel einer Reihe: nicht heimlich auf die doppelte Breite wachsen.
   Das Theme deckelt die Kachelbreite erst ab 1024px (`max-width: 33.333%`).
   Darunter steht nur `width: 50%` – zusammen mit `flex-grow: 1` des Rasters
   wächst eine allein stehende Kachel damit auf die volle Zeilenbreite.
   Folge: Der Browser hat nach `sizes` eine 320px-Datei geholt und zog sie auf
   390px auf – genau eine Kachel je Seite war sichtbar unscharf, und welche,
   wechselte mit dem Filter. Derselbe Deckel wie oben löst es. */
@media only screen and (max-width: 1023px) {
  .product-teaser:not(.product-category) {
    max-width: 50%;
  }
}

/* ── Bildblöcke auf dem Telefon ───────────────────────────────────────────────

   Ein Bildblock steht neben einem Textblock: zwei Spalten, `medium-12`. Das
   Bild liegt darin absolut (`position: absolute`), damit es die Spalte
   formatfüllend ausfüllt – die Höhe holt sich die Spalte vom Text daneben.

   Unter 640px stapeln sich die Spalten. Der Text steht dann oben, das Bild
   darunter – nur hat die Bildspalte jetzt nichts mehr, woher sie eine Höhe
   nehmen könnte: Ihr einziger Inhalt liegt ausserhalb des Flusses. Die Spalte
   fällt auf 0 Pixel zusammen, und das Foto ist auf dem Telefon SCHLICHT NICHT
   DA. Gemessen auf der Startseite (2 Bilder) und «Über uns» (2 Bilder).

   Das ist kein Fehler dieser Umsetzung – piya.ch macht es genauso. Das Skript
   des alten Themes (`custom.js`, `responsiveBgImg`) schreibt nur das Bild als
   Hintergrund auf den Behälter und setzt ebenfalls keine Höhe. Auf dem Telefon
   fehlten die Fotos dort also seit jeher; weil ein Loch von 0 Pixeln nichts
   anzeigt, fällt es beim Durchblättern nicht auf.

   Ein Seitenverhältnis gibt der Spalte die fehlende Höhe. 3:2 ist das Format,
   in dem die Fotos vorliegen (1024×683, 1920×1280) – so wird nichts
   beschnitten, was auf dem Desktop zu sehen ist.

   Nur bis 639px: Ab `medium` stehen die Spalten wieder nebeneinander, dort
   bestimmt weiterhin der Text die Höhe. */
@media only screen and (max-width: 639px) {
  .columns > [data-responsive-background-image] {
    width: 100%;
    aspect-ratio: 3 / 2;
  }
}

/* ── Fussbereich: Grau war zu dunkel für Schwarz ────────────────────────────

   Das Theme setzt die Unterpunkte im Fussbereich (Impressum, Datenschutz,
   Deklaration, Geschichte, Engagement …) und den Kontaktblock auf #616161.
   Auf schwarzem Grund ergibt das ein Kontrastverhältnis von 3,39:1. Die
   Richtlinie für Fliesstext verlangt 4,5:1 – gemessen, nicht geschätzt, an
   zehn Elementen auf jeder Seite.

   Wer bei Tageslicht auf ein Telefon schaut, liest solche Zeilen nicht mehr;
   es sind ausgerechnet die, die rechtlich dastehen müssen. #7a7a7a bringt
   4,89:1 und bleibt trotzdem erkennbar zweitrangig – heller als das Theme,
   dunkler als der Fliesstext daneben. */
.footermenu-gray,
#footer-navigation .dropdown .menu-item a,
#footer-navigation .submenu-item a,
#footer-contact {
  color: #7a7a7a;
}

/* ── Markenfarbe «hellbraun»: aufgehellte Schrift braucht dunkleren Grund ────

   Das Theme setzt `.hellbraun` auf #958282. Weisse Schrift darauf erreicht
   3,62:1 – verlangt sind 4,5:1 für Fliesstext. Betroffen sind das Feld «Wir
   fördern Leidenschaft», der Zeitstrahl («Anno 1992») und die Knöpfe darin.

   #7b6a6a hält denselben Farbton (Rot zu Grün/Blau bleibt 1,16) und kommt auf
   5,11:1. Bewusst dieser Wert und nicht der knappste, der gerade durchkommt:
   Die Schwesterfarbe `.oliv` (#5f7261) liegt bei 5,16:1 – die beiden
   mitteltonigen Flächen der Seite lesen sich damit gleich gut. */
.hellbraun {
  background-color: #7b6a6a;
}

/* Dieselbe Farbe trägt der Ring um die Symbole der Produktangaben – dort auf
   Weiss, also als Vordergrund. Mitgezogen (oben bei `.spec-kachel-icon`),
   damit die Marke eine Farbe bleibt und nicht zwei; auf Weiss steigt der
   Kontrast dabei von 3,62:1 auf 5,11:1. */

/* ── Google-Maps: Platzhalter, solange niemand zugestimmt hat ────────────────

   Sobald das iframe im Dokument steht, holt der Browser es von Google – und
   Google kennt die IP-Adresse des Besuchers, ohne dass der gefragt wurde.
   Deshalb steht dort erst ein Kästchen mit dem Grund und einem Knopf (siehe
   FooterMap.tsx).

   `#mymap` hält seine Höhe über `padding-top: 65.25%`; der Inhalt muss darin
   also absolut liegen, sonst schöbe er den Kasten auseinander. */
.karte-platzhalter-inhalt {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  padding: 2rem;
  text-align: center;
}
.karte-platzhalter-titel {
  margin: 0;
  color: #fff;
  font-size: 1.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.karte-platzhalter-text {
  margin: 0;
  max-width: 42rem;
  color: #c4c4c4; /* 7,0:1 auf #23262a */
  font-size: 1.4rem;
  line-height: 1.6;
}
.karte-platzhalter-text a {
  color: #fff;
  text-decoration: underline;
}
/* Wie im Cookie-Hinweis: Die Theme-Klasse `.button` trägt auf dunklem Grund
   keine sichtbare Umrandung. */
.karte-platzhalter .button {
  margin: 0;
  cursor: pointer;
  padding: 1.1rem 2.2rem;
  font-size: 1.2rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.2;
  border: 1px solid #fff;
  border-radius: 0;
  background: #fff;
  color: #000;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.karte-platzhalter .button:hover {
  background: rgba(255, 255, 255, 0.82);
}
.karte-platzhalter .button:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}
@media (max-width: 639px) {
  .karte-platzhalter-inhalt {
    gap: 1.1rem;
    padding: 1.4rem;
  }
  .karte-platzhalter-text {
    font-size: 1.3rem;
  }
}

/* ---------------------------------------------------------------------------
   Cookie-Einstellungen im Fussbereich

   Der Widerruf der Einwilligung steht neben Impressum und
   Datenschutzerklaerung. Technisch ist es ein <button> (es oeffnet etwas, es
   fuehrt nirgendwohin) — es soll aber wie die Links daneben aussehen, sonst
   springt es aus der Zeile. Darum die Knopf-Voreinstellungen zuruecksetzen und
   die Schrift vom Elternelement erben.
--------------------------------------------------------------------------- */
#footer-secondary-navigation .cookie-einstellungen-link {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  text-align: left;
  cursor: pointer;
}
#footer-secondary-navigation .cookie-einstellungen-link:hover,
#footer-secondary-navigation .cookie-einstellungen-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* ── Überschriftenklassen: Gliederung ändern, Aussehen behalten ───────────────

   `src/lib/ueberschriften.ts` hängt Überschriften migrierter Blöcke um, damit
   die Gliederung stimmt (kein Sprung von h1 auf h6, kein Abschnittstitel als
   h3 direkt unter der h1). Damit dabei NICHTS anders aussieht, trägt jede
   umgehängte Überschrift die Klasse ihrer alten Ebene – aus `<h3>` wird
   `<h2 class="h3">`.

   Die Werte sind die des Themes, Eins zu eins aus `style.css` übernommen (dort
   stehen sie an den Tags h2…h6). `.h1` bringt das Theme bereits selbst mit.
   Wer im Theme eine Überschriftengrösse ändert, ändert sie hier mit. */
.h2 {
  font-size: 3rem;
  line-height: 1.111;
  margin: 0 auto 1em auto;
  font-weight: 700;
  max-width: 80rem;
}
.h3 {
  font-size: 3rem;
  line-height: 1.66;
  margin: 0 auto 4.7rem auto;
  max-width: 80rem;
  font-weight: 400;
}
.h4 {
  font-size: 3rem;
  line-height: 1.2;
  font-weight: 700;
  margin-bottom: 4.7rem;
}
.h5 {
  font-size: 2.5rem;
  line-height: 1.12;
  margin-bottom: 4.7rem;
}
/* Dachzeile und `.h6` sind dasselbe: die kleine Zeile in Versalien über dem
   Titel. Nur ist die Dachzeile jetzt ein Absatz und keine Überschrift mehr. */
.h6,
.dachzeile {
  font-size: 1.3rem;
  line-height: 1.23;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 2.75em;
}
@media only screen and (min-width: 1024px) {
  .h2 {
    font-size: 4.5rem;
    line-height: 1.111;
    margin: 0 auto 6rem auto;
    font-weight: 400;
  }
  .h3 {
    font-size: 4rem;
    line-height: 1.35;
  }
}

/* ── Kacheltitel: h3 wie h2 ───────────────────────────────────────────────────

   Das Theme gestaltet den Titel einer Produktkachel als `.product-teaser h2,
   .product-teaser h4` – zwei Ebenen, aber nicht h3. Seit 15.09.2026 ist der
   Kacheltitel h3: Die Kachel steht unter der Warengruppe bzw. unter «Ähnliche
   Produkte», und die sind h2. Ohne diese Zeile fiele der Titel auf die
   Vorgabegrösse des Browsers zurück und wäre plötzlich kleiner als die
   Kennzahl darunter. Die Werte stammen aus dem Theme (2.2rem, ab 640px 3rem). */
.product-teaser h3 {
  position: relative;
  z-index: 2;
  margin-bottom: 0.5rem;
  font-size: 2.2rem;
}
@media only screen and (min-width: 640px) {
  .product-teaser h3 {
    font-size: 3rem;
  }
}

/* ── «Ähnliche Produkte»: Kacheln hatten das falsche Format ──────────────────

   Das Theme gibt jeder Produktkachel eine feste Höhe von 55rem. Im Archiv
   liegen vier nebeneinander, jede misst dort 400×550 – Verhältnis 0,73, und
   genau so sind die Produktfotos aufgenommen (576×788, ebenfalls 0,73). Es
   wird also praktisch nichts beschnitten: 99 % des Bildes sind zu sehen.

   Unter «Ähnliche Produkte» liegen nur ZWEI nebeneinander. Bei gleicher Höhe
   wurde jede 578 breit (1600px-Schirm) bzw. 618 (1280px) – Verhältnis 1,05
   bis 1,12, also querformatig. `object-fit: cover` schneidet dann oben und
   unten weg: gemessen blieben 70 % bzw. 65 % des Fotos übrig. Das ist der
   «reingezoomte» Eindruck – der Dönerspiess war gekappt, die Schale
   angeschnitten.

   Statt fester Höhe jetzt dasselbe Seitenverhältnis wie im Archiv. Die
   Kacheln dürfen bis 48rem wachsen und stehen mittig in der Zeile.

   ACHTUNG, SPEZIFITÄT: Das Theme setzt Breite, Höhe und Ausrichtung unter
   `#post .product-teaser…` – mit einer ID. Eine Regel aus zwei Klassen
   (`.entry-footer .product-teaser`) verliert dagegen, egal wie weit hinten sie
   steht. Die Ausrichtung blieb deshalb im ersten Anlauf links, und die beiden
   Kacheln klebten mit einem breiten schwarzen Streifen daneben. Darum hier
   ebenfalls mit `#post`. */
#post .entry-footer .product-teaser-container {
  /* Das Theme stellt die Kacheln auf «nicht umbrechen» und schiebt sie nach
     links. Beides ist hier falsch: «Ähnliche Produkte» zeigt je nach
     Warengruppe eine, zwei oder DREI Kacheln – drei ohne Umbruch ergaben auf
     dem Telefon 110 Pixel breite Streifen. */
  flex-wrap: wrap;
  justify-content: center;
}
#post .entry-footer .product-teaser {
  /* Grundbreite 28rem: Drei Kacheln passen damit ab 1024px in eine Zeile und
     wachsen auf die Zeilenbreite; darunter bricht die dritte um. Der Deckel
     bei 48rem verhindert, dass zwei Kacheln ins Riesenhafte wachsen. */
  flex: 1 1 28rem;
  max-width: 48rem;
  height: auto;
  aspect-ratio: 400 / 550;
}
/* Der schwarze Streifen soll so breit sein wie sein Inhalt.

   Der Deckel oben verhindert richtigerweise, dass eine allein stehende Kachel
   über die ganze Zeile wächst – im Hochformat 400/550 wäre sie sonst über
   900px hoch. Bei ZWEI Kacheln liess er aber 218px schwarze Fläche je Seite
   übrig: Streifen 1410px breit, Inhalt 975px. Das liest sich als Loch, nicht
   als Gestaltung.

   Der Deckel gehört also auch an den Streifen, nicht nur an die Kachel.
   99rem sind zwei Kacheln à 48rem plus Abstand. Auf piya.ch nachgemessen:
   218px Leerraum je Seite → 8px, Kachelbreite unverändert 480px, unter
   1024px alles wie zuvor. */
@media (min-width: 1024px) {
  #post .entry-footer .product-teaser-container {
    max-width: 99rem;
    margin-inline: auto;
  }
}
@media (max-width: 1023px) {
  /* Tablet: Hier bricht die dritte Kachel in die zweite Zeile. Ohne Deckel
     wüchse sie dort auf die vollen 48rem und stünde 25 % grösser da als die
     beiden darüber. Halbe Zeilenbreite hält alle drei gleich gross. */
  #post .entry-footer .product-teaser {
    max-width: 50%;
  }
}
@media (max-width: 639px) {
  /* Auf dem Telefon wie im Archiv: zwei Kacheln je Zeile, halbe Breite. Eine
     dritte rutscht darunter und bleibt gleich breit – nicht doppelt so gross. */
  #post .entry-footer .product-teaser {
    flex: 1 1 40%;
  }
}
