/* Preismonitoring — Oberfläche
   Ruhiges, dichtes Layout: Es geht um Zahlenvergleiche, nicht um Effekte.
   Teurer als der Wettbewerb ist rot, günstiger grün — das ist die einzige Farbe,
   die etwas bedeutet. */

:root {
  --papier: #fbfaf8;
  --flaeche: #ffffff;
  --linie: #e4e0d9;
  --text: #1c1917;
  --leise: #78716c;
  --akzent: #1c1917;
  --gut: #15803d;
  --schlecht: #b91c1c;
  --warnung: #a16207;
  --radius: 6px;
}

/* Dunkle Darstellung — zweimal deklariert, weil sie zwei Auslöser hat:
   die Einstellung des Betriebssystems und die Wahl in der Seitenleiste.
   CSS kann eine Regel nicht über eine Media Query hinweg teilen. */
:root[data-theme="dark"] {
  --papier: #1a1917;
    --flaeche: #232220;
    --linie: #383632;
    --text: #f5f3f0;
    --leise: #a8a29e;
    --akzent: #f5f3f0;
    --gut: #4ade80;
    --schlecht: #f87171;
    --warnung: #fbbf24;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --papier: #1a1917;
    --flaeche: #232220;
    --linie: #383632;
    --text: #f5f3f0;
    --leise: #a8a29e;
    --akzent: #f5f3f0;
    --gut: #4ade80;
    --schlecht: #f87171;
    --warnung: #fbbf24;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--papier);
  color: var(--text);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* --- Seitenleiste --------------------------------------------------------- */

.mit-seitenleiste {
  display: grid;
  grid-template-columns: var(--leiste-breite) 1fr;
  min-height: 100vh;
}

:root { --leiste-breite: 232px; }

.seitenleiste {
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding: 20px 14px 18px;
  background: var(--flaeche);
  border-right: 1px solid var(--linie);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.leiste-kopf { padding: 0 8px; }
.marke-logo {
  display: flex; align-items: center; gap: 9px;
  font-weight: 620; letter-spacing: -0.015em; font-size: 15px;
  text-decoration: none; color: var(--text);
}
.marke-zeichen {
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--akzent); color: var(--papier);
  font-size: 14px; line-height: 1;
}

.leiste-mandant { display: block; padding: 6px 8px; border-radius: 7px;
  text-decoration: none; color: inherit; position: relative; }
.leiste-mandant:hover { background: color-mix(in srgb, var(--linie) 45%, transparent); }
.leiste-mandant strong { display: block; font-size: 14px; margin-top: 2px; }
.leiste-mandant .wechseln { position: absolute; right: 8px; bottom: 7px;
  font-size: 11px; color: var(--leise); opacity: 0; transition: opacity 0.15s; }
.leiste-mandant:hover .wechseln { opacity: 1; }
.leiste-etikett {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--leise); padding: 0 8px 6px;
}
.leiste-nav .leiste-etikett { padding-left: 8px; }

.leiste-nav { display: flex; flex-direction: column; gap: 1px; }
.leiste-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 7px;
  text-decoration: none; color: var(--leise); font-size: 14px;
}
.leiste-nav a:hover { background: color-mix(in srgb, var(--linie) 45%, transparent);
  color: var(--text); }
.leiste-nav a.aktiv {
  background: color-mix(in srgb, var(--linie) 70%, transparent);
  color: var(--text); font-weight: 550;
}
.nav-zeichen { width: 18px; text-align: center; opacity: 0.75; font-size: 13px; }

.leiste-fuss { margin-top: auto; display: grid; gap: 8px; padding: 0 4px; }
.thema-knopf {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 10px 7px 34px; border-radius: 7px; border: 1px solid transparent;
  background: none; color: var(--leise); font: inherit; font-size: 13.5px;
  cursor: pointer; text-align: left;
}
/* Im Kontomenü steht das Symbol an derselben Stelle wie bei den Verweisen darüber. */
.kontomenue-inhalt .thema-knopf { padding-left: 10px; }
.thema-knopf:hover { background: color-mix(in srgb, var(--linie) 45%, transparent);
  color: var(--text); }
.thema-zeichen { width: 18px; text-align: center; font-size: 14px; }
.konto-zeile { display: flex; align-items: center; gap: 9px; padding: 0 4px; }
.konto-zeichen {
  display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; font-size: 12px; font-weight: 600;
  background: color-mix(in srgb, var(--linie) 70%, transparent); color: var(--text);
}
.konto-name { font-size: 13px; color: var(--leise); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.knopf.breit { width: 100%; text-align: center; }

/* Menü für schmale Fenster */
.menue-schalter, .menue-knopf, .menue-schatten { display: none; }

main {
  /* min-width: 0 ist in einem Grid nötig: Ohne das darf breiter Inhalt die Spalte
     aufblähen, und Tabellen schieben sich unter den rechten Fensterrand. */
  min-width: 0;
  width: 100%;
  padding: 30px 34px 80px;
}

/* Die Auswertung lebt von breiten Tabellen — sie bekommt den ganzen Platz. Fließtext
   und Formulare begrenzen sich dagegen selbst, damit die Zeilen lesbar bleiben. */
main > p,
main > section > p:not(.leer):not(.nebensache) { max-width: 76ch; }

h1 { font-size: 24px; margin: 0 0 4px; letter-spacing: -0.02em; }
h2 { font-size: 17px; margin: 32px 0 12px; letter-spacing: -0.01em; }
section h2:first-child { margin-top: 0; }
section { margin-top: 36px; }

.titelzeile { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
h1 { margin-bottom: 0; }
.brotkrumen { margin: 0 0 12px; font-size: 14px; }
.brotkrumen a { color: var(--leise); text-decoration: none; }
.brotkrumen a:hover { color: var(--text); }

/* Kennzahlen */
.kennzahlen { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 24px; }
.kennzahl {
  background: var(--flaeche); border: 1px solid var(--linie); border-radius: var(--radius);
  padding: 14px 18px; min-width: 150px; flex: 1 1 150px;
  /* Als Spalte, damit der Fuß unten andocken kann: Die Beschriftungen sind
     unterschiedlich lang, und ohne das säßen Balken und Prozentwert je nach Karte auf
     anderer Höhe. */
  display: flex; flex-direction: column;
}
/* Balken und Anteil stehen immer am unteren Rand, gleichgültig wie viele Zeilen die
   Beschriftung darüber braucht. */
.kennzahl-fuss { margin-top: auto; padding-top: 8px; }
/* Die Zahl darf nie umbrechen — "1.697" zwischen der 1 und der 6 getrennt liest sich
   wie zwei Werte. Die Karte wächst dafür lieber mit. */
.kennzahl .wert { display: block; font-size: 24px; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; white-space: nowrap; }
.kennzahl .etikett { display: block; color: var(--leise); font-size: 13px; margin-top: 2px; }
.kennzahl .balken.schmal { height: 5px; margin: 0 0 6px; }
.kennzahl .etikett.stark { color: var(--text); font-weight: 500; }
/* Jede Kennzahl ist eine Teilmenge der verglichenen Artikel. Der Balken zeigt, wie
   groß — eine 639 sagt wenig, "38 % der Vergleiche" sagt viel. */
.kennzahl .etikett.anteilswert { font-variant-numeric: tabular-nums; }
.kennzahl.schlecht .balken-fuellung { background: var(--schlecht); }
.kennzahl.gut .balken-fuellung { background: var(--gut); }
.kennzahl.gut .wert { color: var(--gut); }
.kennzahl.schlecht .wert { color: var(--schlecht); }

/* Karten (Mandantenliste) */
.karten { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.karte {
  display: block; text-decoration: none; color: inherit;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 18px 20px;
}
.karte:hover { border-color: var(--leise); }
.karte h2 { margin: 0; font-size: 18px; }
.karte .kuerzel { color: var(--leise); font-size: 13px; margin: 2px 0 14px; }
.karte dl { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; margin: 0; }
.karte dt { color: var(--leise); font-size: 12px; }
.karte dd { margin: 0; font-variant-numeric: tabular-nums; font-weight: 550; }

/* Filterzeile */
.filter { display: flex; align-items: center; gap: 10px; margin-bottom: 16px;
  flex-wrap: wrap; }
.filter .schalter {
  display: flex; align-items: center; gap: 7px; white-space: nowrap;
  padding: 8px 12px; border: 1px solid var(--linie); border-radius: var(--radius);
  background: var(--flaeche); font-size: 14px; color: var(--leise); cursor: pointer;
}
.filter .schalter input { width: auto; margin: 0; }
.filter .schalter:has(input:checked) { color: var(--text); border-color: var(--leise); }
input[type="search"], select {
  font: inherit; padding: 8px 11px; border: 1px solid var(--linie);
  border-radius: var(--radius); background: var(--flaeche); color: var(--text);
}
input[type="search"] { flex: 1 1 260px; }
input[type="search"]:focus, select:focus { outline: 2px solid var(--akzent); outline-offset: -1px; }

/* Tabellen */
/* Der Rahmen hält die Tabelle in ihrer Spalte: Wird sie breiter als der Platz,
   scrollt sie in sich, statt das Seitenlayout nach rechts zu sprengen. */
.tabellen-rahmen {
  min-width: 0; max-width: 100%; overflow-x: auto;
  background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius);
}
.liste { width: 100%; border-collapse: collapse; }
.liste th, .liste td { padding: 10px 14px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--linie); }
.liste thead th { font-size: 12px; font-weight: 600; color: var(--leise);
  text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }
.liste tbody tr:last-child td { border-bottom: none; }
.liste td:last-child, .liste th:last-child { padding-right: 16px; }
.liste tbody tr:hover { background: color-mix(in srgb, var(--linie) 35%, transparent); }
.liste tbody tr[onclick] { cursor: pointer; }
.liste .zahl { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.liste a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--linie); }
.liste a:hover { border-bottom-color: var(--text); }
.liste.klein td { padding: 6px 12px; font-size: 13px; }
.liste tr.verworfen { opacity: 0.45; }
.liste tr.inaktiv { opacity: 0.55; }
.liste tr.anhang td { padding: 0 14px; border-bottom: none; }
.liste tr.anhang:hover { background: none; }
.gekuerzt { display: block; max-width: 320px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* In einer Tabellenzelle ist der Hinweis nur Text — der Kasten der Seitenmeldung
   würde die Zeilenhöhe sprengen. */
td .nebensache.hinweis { display: block; max-width: 340px; white-space: normal;
  background: none; border: none; padding: 0; margin: 2px 0 0;
  color: var(--warnung); font-size: 12.5px; }

.gut { color: var(--gut); }
.schlecht { color: var(--schlecht); }
.nebensache { display: block; color: var(--leise); font-size: 12.5px; font-weight: 400; }
/* Steht die Klasse auf der Zelle selbst, darf sie das Tabellenlayout nicht aufheben:
   `display: block` nähme dem <td> die gemeinsame Zeilenhöhe seiner Zeile, und die
   Trennlinie bräche genau ab dieser Spalte ab. Sichtbar wurde das in der
   Quellentabelle des Handbuchs, wo die vorderen Zellen zweizeilig sind. */
td.nebensache, th.nebensache { display: table-cell; }
.marke + .nebensache { display: inline-block; margin-left: 6px; }
/* In Zahlenspalten steht der Zusatz daneben, in Textspalten darunter — sonst
   springen die Zeilenhöhen je nach Länge der Bezeichnung. */
td.zahl .nebensache { display: inline-block; margin-left: 6px; }
/* Auf der Änderungsseite gehört die Gültigkeitsdauer unter den alten Preis. */
.aenderungen td.zahl .nebensache { display: block; margin-left: 0; white-space: nowrap; }
.fuss { margin-top: 12px; }
.leer { color: var(--leise); padding: 20px 0; }
td.leer { text-align: center; }

/* Marken/Etiketten */
.marke {
  display: inline-block; padding: 2px 7px; margin: 0 3px 3px 0;
  max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  vertical-align: middle;
  font-size: 12px; border-radius: 4px;
  background: color-mix(in srgb, var(--linie) 60%, transparent); color: var(--leise);
}
.marke.sicher { color: var(--gut);
  background: color-mix(in srgb, var(--gut) 14%, transparent); }
.marke.unsicher { color: var(--warnung);
  background: color-mix(in srgb, var(--warnung) 16%, transparent); }
/* Ausverkauft: sichtbar, aber erkennbar ohne Gewicht für den Vergleich. */
.marke.leer { opacity: 0.5; text-decoration: line-through; }
.nebensache.ausverkauft { color: var(--leise); text-decoration: line-through;
  opacity: 0.8; }
tr.ausverkauft-zeile td { opacity: 0.6; }

/* Knöpfe */
.knopf {
  display: inline-block; font: inherit; font-size: 14px; font-weight: 500;
  padding: 8px 14px; border-radius: var(--radius); border: 1px solid var(--akzent);
  background: var(--akzent); color: var(--papier); cursor: pointer; text-decoration: none;
}
.knopf:hover { opacity: 0.85; }
.knopf.leise { background: var(--flaeche); color: var(--text); border-color: var(--linie); }
.knopf.klein { padding: 4px 10px; font-size: 13px; }
.aktionen { white-space: nowrap; }
.aktionen form { display: inline; }

/* Diagramm */
.verlauf { width: 100%; height: auto; background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius); padding: 8px; }
.verlauf .raster { stroke: var(--linie); stroke-width: 1; }
/* Jede Linie und jeder Punkt bringt sein Farbpaar als --hell/--dunkel mit; welche
   der beiden gilt, steht hier. Die Zuweisung muss am Element selbst geschehen:
   Eine Variable am Elternelement, die auf --hell verweist, würde dort aufgelöst —
   und dort gibt es das Farbpaar nicht. */
.verlauf .reihe-linie { stroke: var(--hell); }
.verlauf .reihe-punkt { fill: var(--hell); }
.verlauf .achse { fill: var(--leise); font-size: 11px;
  font-family: -apple-system, system-ui, sans-serif; }
:root[data-theme="dark"] .verlauf .reihe-linie { stroke: var(--dunkel); }
:root[data-theme="dark"] .verlauf .reihe-punkt { fill: var(--dunkel); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .verlauf .reihe-linie { stroke: var(--dunkel); }
  :root:not([data-theme="light"]) .verlauf .reihe-punkt { fill: var(--dunkel); }
}
.legende { list-style: none; display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  padding: 0; margin: 12px 0 0; font-size: 13px; color: var(--leise); }
.legende li { display: flex; align-items: center; gap: 6px; }

/* Die Legende ist zugleich die Auswahl — deshalb Knöpfe, keine bloße Aufzählung. */
.legendenchip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--leise);
  padding: 4px 11px; border-radius: 99px;
  border: 1px solid var(--linie); background: var(--flaeche);
  transition: border-color 0.12s, color 0.12s, opacity 0.12s;
}
.legendenchip:hover { color: var(--text); border-color: var(--akzent); }
.legendenchip.gewaehlt {
  color: var(--text); font-weight: 550; border-color: var(--akzent);
  background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
/* Ist etwas gewählt, treten die übrigen zurück — wie bei den Wettbewerber-Chips. */
.legende.gefiltert .legendenchip:not(.gewaehlt) { opacity: 0.45; }
.legende.gefiltert .legendenchip:not(.gewaehlt):hover { opacity: 1; }
.legende-zurueck {
  font: inherit; font-size: 12.5px; color: var(--leise); cursor: pointer;
  background: none; border: none; text-decoration: underline; padding: 4px 2px;
}
.legende-zurueck:hover { color: var(--text); }
/* Ausgeblendete Kurven im Diagramm. */
.reihe-linie.verborgen, .reihe-punkt.verborgen { display: none; }
.punkt, .anbieterpunkt {
  width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex: none;
  background: var(--hell);
}
.anbieterpunkt { width: 8px; height: 8px; margin-right: 7px; vertical-align: baseline; }
:root[data-theme="dark"] .punkt, :root[data-theme="dark"] .anbieterpunkt {
  background: var(--dunkel);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .punkt,
  :root:not([data-theme="light"]) .anbieterpunkt { background: var(--dunkel); }
}

/* Anbieter-Etiketten in der Übersicht — dieselbe Farbe wie die Linie im Diagramm. */
.marke.anbieter {
  color: var(--hell);
  background: color-mix(in srgb, var(--hell) 13%, transparent);
}
:root[data-theme="dark"] .marke.anbieter {
  color: var(--dunkel);
  background: color-mix(in srgb, var(--dunkel) 15%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .marke.anbieter {
    color: var(--dunkel);
    background: color-mix(in srgb, var(--dunkel) 15%, transparent);
  }
}
/* Ausverkauft oder unsicher schlägt die Anbieterfarbe: Die Aussage ist wichtiger
   als die Wiedererkennung. */
.marke.anbieter.unsicher { color: var(--warnung);
  background: color-mix(in srgb, var(--warnung) 16%, transparent); }
/* Ausverkauft schlägt beides: Ein ausverkaufter Anbieter sah bisher verschieden aus,
   je nachdem wie er zugeordnet wurde — sicher zugeordnet grau, über den Titel
   zugeordnet orange hinterlegt. Für den Leser ist beides dasselbe: zählt nicht.
   Dass die Zuordnung unsicher ist, sagt jetzt der gestrichelte Rand. */
.marke.anbieter.leer, .marke.anbieter.unsicher.leer {
  color: var(--leise); background: none;
}
.marke.anbieter.unsicher.leer {
  border: 1px dashed color-mix(in srgb, var(--warnung) 45%, transparent);
  padding: 0 4px;
}

/* Status und Prüfergebnis */
.status { background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: 18px; }
.status p { margin: 4px 0; }
.status .laeuft::after { content: " ⟳"; animation: dreh 1.4s linear infinite;
  display: inline-block; }
@keyframes dreh { to { transform: rotate(360deg); } }
.fehler { color: var(--schlecht); }
.hinweis { color: var(--warnung); font-size: 13px; margin: 4px 0; }
.pruefung { padding: 12px 0 16px; font-size: 14px; }
.pruefung p { margin: 4px 0; }

code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
  background: color-mix(in srgb, var(--linie) 45%, transparent);
  padding: 1px 5px; border-radius: 4px; }

/* Schmale Fenster: Die Leiste fährt über einen Schalter ein. */
@media (max-width: 860px) {
  .mit-seitenleiste { grid-template-columns: 1fr; }
  .seitenleiste {
    position: fixed; left: 0; top: 0; bottom: 0; width: 240px; z-index: 30;
    transform: translateX(-100%); transition: transform 0.22s ease;
  }
  .menue-schalter:checked ~ .seitenleiste { transform: translateX(0); }
  .menue-schalter:checked ~ .menue-schatten {
    display: block; position: fixed; inset: 0; z-index: 20;
    background: rgba(0, 0, 0, 0.35);
  }
  .menue-knopf {
    display: grid; place-items: center; position: fixed; top: 12px; left: 12px;
    z-index: 25; width: 38px; height: 38px; border-radius: 9px; cursor: pointer;
    background: var(--flaeche); border: 1px solid var(--linie); font-size: 17px;
  }
  main { padding: 64px 16px 60px; }
  .liste { display: block; overflow-x: auto; }
  body.mitte { display: grid; }
}

/* --- Anmeldung, Konto und Formulare --------------------------------------- */

body.mitte { display: grid; place-items: center; min-height: 100vh; }

.anmeldung {
  width: min(400px, 92vw); background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius);
  padding: 32px 30px; margin: 0;
}
.anmeldung h1 { font-size: 20px; margin-bottom: 20px; }
.anmeldung form { display: grid; gap: 14px; margin-top: 18px; }

label { display: block; font-size: 14px; }
label input, label select, label textarea {
  display: block; width: 100%; margin-top: 5px; font: inherit;
  padding: 8px 11px; border: 1px solid var(--linie); border-radius: var(--radius);
  background: var(--papier); color: var(--text);
}
label textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
label .nebensache { margin-top: 4px; }
label.kasten { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
label.kasten input { width: auto; margin: 0; }
label.kasten .nebensache { width: 100%; margin-left: 24px; }

.formular { display: grid; gap: 16px; max-width: 420px;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 20px 22px; }
.formular.breit { max-width: 620px; }
.formular button { justify-self: start; }
.artfelder { display: grid; gap: 16px; }
.artfelder[hidden] { display: none; }

.leise-link { color: var(--leise); text-decoration: none; font-size: 14px; }
.leise-link:hover { color: var(--text); }
form.inline { display: inline; }

/* Ein Etikett, das zugleich ein Knopf ist (Zugriff entziehen) */
.knopf-marke { border: none; cursor: pointer; font: inherit; font-size: 12px; }
.knopf-marke:hover { color: var(--schlecht); }

.hinweis { background: color-mix(in srgb, var(--warnung) 12%, transparent);
  border-left: 3px solid var(--warnung); padding: 10px 14px;
  border-radius: 0 var(--radius) var(--radius) 0; margin: 0 0 20px; }
.anmeldung .fehler { background: color-mix(in srgb, var(--schlecht) 12%, transparent);
  border-left: 3px solid var(--schlecht); padding: 10px 14px;
  border-radius: 0 var(--radius) var(--radius) 0; }

/* --- Laufender Import ----------------------------------------------------- */

.lauf { padding: 10px 0; border-bottom: 1px solid var(--linie); }
.lauf:last-of-type { border-bottom: none; }
.lauf.fertig { opacity: 0.75; }
.lauf-kopf { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.lauf-zustand { color: var(--leise); font-size: 14px; }
.lauf-zustand.fehler { color: var(--schlecht); }
.lauf .nebensache { display: inline; }

.balken { height: 6px; margin-top: 8px; border-radius: 3px;
  background: color-mix(in srgb, var(--linie) 70%, transparent); overflow: hidden; }
.balken-fuellung { height: 100%; background: var(--akzent);
  border-radius: 3px; transition: width 0.4s ease; }

.ergebnis { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--linie); }
.ergebnis h3 { font-size: 15px; margin: 0 0 10px; }
.ergebnis table { margin-bottom: 10px; }
.ergebnis p { margin: 0; }

/* --- Vergleichstabelle: sortieren und Spalten verstellen ------------------- */

/* Feste Spaltenbreiten — nur so lassen sie sich verlässlich ziehen. Dafür muss
   alles, was zu lang ist, sauber abgeschnitten werden statt die Nachbarspalte zu
   überschreiben. */
.liste.vergleich { table-layout: fixed; }
.liste.vergleich th, .liste.vergleich td { overflow: hidden; }
.liste.vergleich th a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%; }
.liste.vergleich td .nebensache { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* Der Anbieter steht unter dem Preis: Nebeneinander bliebe für den Namen kaum Platz. */
.liste.vergleich td.zahl .nebensache { display: block; margin-left: 0; }
.liste.vergleich .marke { max-width: 100%; }

th.sortierbar { position: relative; padding-right: 18px; }
th.sortierbar a {
  display: inline-flex; align-items: center; gap: 4px;
  color: inherit; text-decoration: none; border: none;
}
th.sortierbar a:hover { color: var(--text); }
th.sortiert a { color: var(--text); }
.pfeil { font-size: 11px; opacity: 0.8; }

/* Der Griff sitzt auf der Trennlinie zwischen zwei Spalten. */
.griff {
  position: absolute; top: 0; right: 0; width: 9px; height: 100%;
  cursor: col-resize; user-select: none;
}
.griff::after {
  content: ""; position: absolute; top: 25%; right: 4px;
  width: 1px; height: 50%; background: var(--linie);
}
.griff:hover::after { background: var(--leise); width: 2px; }
body.spalte-zieht { cursor: col-resize; user-select: none; }
body.spalte-zieht .liste tbody tr:hover { background: none; }

/* --- Quellenkarten -------------------------------------------------------- */

.quellkarten { display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }

/* Der eigene Katalog: eine Quelle, volle Breite, flach.
   Kopf, Zahlen und Knöpfe stehen nebeneinander statt untereinander — das spart die
   halbe Höhe, und die Wettbewerber darunter beginnen im sichtbaren Bereich. */
.quellkarten.eigenkatalog { grid-template-columns: 1fr; }
.eigenkatalog .quellkarte {
  /* Zwei Zeilen rechts: Zustand oben, Knöpfe darunter. Vorher schwebte der Zustand
     absolut positioniert über dem Raster und landete auf den Knöpfen — ein Element
     außerhalb des Flusses weiß nichts davon, was unter ihm liegt.
     Oben ausgerichtet, nicht mittig: Der Name gehört auf eine Höhe mit den Zahlen. */
  display: grid; align-items: start; gap: 8px 30px;
  grid-template-columns: minmax(190px, 1fr) minmax(0, 1fr) auto;
  grid-template-areas:
    "kopf zahlen zustand"
    "kopf zahlen aktionen";
  padding: 16px 20px 14px;
}
/* `display: contents` löst den Kopfbereich auf: Sein Innenleben — Name samt Untertitel
   und der Zustand — wird selbst zum Raster-Element. Ohne das bliebe der Zustand ein
   Kind des Kopfes und könnte seine Rasterzeile gar nicht erreichen; er landete unter
   dem Namen. Das Markup bleibt dabei unverändert, also auch das der Wettbewerber. */
.eigenkatalog .quellkopf { display: contents; }
/* Nur der Titelblock, nicht der Zustand: `> div` trifft beide Kinder, und weil dieser
   Selektor spezifischer ist als `.eigenkatalog .quellzustand`, landete der Zustand
   ebenfalls im Bereich "kopf" — direkt neben dem Namen statt oben rechts. */
.eigenkatalog .quellkopf > div:not(.quellzustand) { grid-area: kopf; padding-top: 1px; }
.eigenkatalog .quellkopf h3 { margin-bottom: 2px; }
/* Zustand und Zahnrad stehen rechts oben — in der eigenen Rasterzeile über den
   Knöpfen, nicht darüber schwebend. */
.eigenkatalog .quellzustand { grid-area: zustand; justify-self: end; margin: 0; }
/* Die Fakten als Kennzahlenreihe: Wert groß, Bezeichnung klein darunter — dasselbe
   Muster wie die Boxen auf der Übersichtsseite. Eine Aufzählung „Angebote: 2539“
   liest sich im Vorbeigehen schlechter als eine Zahl mit Beschriftung. */
.eigenkatalog .quellzahlen {
  grid-area: zahlen; display: flex; flex-wrap: wrap; gap: 4px 34px; margin: 0;
}
.eigenkatalog .quellzahlen > div {
  display: flex; flex-direction: column-reverse; margin: 0; min-width: 0;
}
.eigenkatalog .quellzahlen dt {
  font-size: 11.5px; color: var(--leise); font-weight: 400; margin-top: 1px;
  white-space: nowrap;
}
.eigenkatalog .quellzahlen dd {
  font-size: 18px; font-weight: 600; letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Die Zusätze in den Werten ("ein Feed liefert immer alles") gehören nicht in eine
   Kennzahl — sie stehen im Etikett darunter oder gar nicht. */
.eigenkatalog .quellzahlen dd .nebensache { display: none; }
.eigenkatalog .quellaktionen { grid-area: aktionen; justify-self: end; margin: 0; }
/* Fortschritt, Hinweise und Meldungen brauchen die ganze Zeile. */
.eigenkatalog .abdeckung,
.eigenkatalog .quellmeldung,
.eigenkatalog .automatik,
.eigenkatalog .hinweis { grid-column: 1 / -1; margin: 0; }
.eigenkatalog dialog { grid-column: 1 / -1; }

@media (max-width: 900px) {
  /* Schmal gestapelt wie jede andere Karte — nebeneinander wäre es unlesbar. */
  .eigenkatalog .quellkarte {
    grid-template-columns: 1fr;
    grid-template-areas: "kopf" "zustand" "zahlen" "aktionen";
  }
  .eigenkatalog .quellzustand,
  .eigenkatalog .quellaktionen { justify-self: start; }
}

.quellkarte {
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 18px 20px;
  display: flex; flex-direction: column; gap: 14px;
}
.quellkarte.still { opacity: 0.6; }
.quellkopf { display: flex; justify-content: space-between; align-items: flex-start;
  gap: 12px; }
.quellkopf h3 { margin: 0; font-size: 16px; letter-spacing: -0.01em; }
.quellkopf .nebensache { margin-top: 3px; }
/* Zustand links, Zahnrad rechts — und das Zahnrad am rechten Rand, gleich wie lang
   der Text davor ist. */
.quellzustand { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.quellzustand .quelle-zahnrad { margin-left: auto; }

.abdeckung { display: grid; gap: 6px; }
.abdeckung .balken { height: 7px; }
.abdeckung .nebensache { display: block; }

.quellzahlen { display: grid; gap: 10px 20px; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.quellzahlen dt { font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--leise); }
.quellzahlen dd { margin: 2px 0 0; font-size: 15px; font-variant-numeric: tabular-nums; }
.quellzahlen dd .nebensache { display: block; font-size: 12.5px; margin: 1px 0 0; }

.quellmeldung { border-left: 2px solid var(--linie); padding-left: 10px; margin: 0; }
.quellaktionen { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; }
.quellaktionen form { display: inline; }

/* --- Laufliste ------------------------------------------------------------ */

.liste.laeufe td { vertical-align: middle; }
/* Eine Zeile bleibt eine Zeile: Sonst wachsen einzelne Zellen und die Trennlinien
   der Spalten sitzen auf unterschiedlichen Höhen. */
.einzeilig { display: block; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }

/* Die Meldung steht unter dem Lauf über die volle Breite — als Fließtext in einer
   schmalen Spalte wäre sie unlesbar, und sie würde die Zeilenhöhe sprengen. */
.liste.laeufe tr.meldungszeile td { padding-top: 0; padding-bottom: 10px;
  border-bottom: 1px solid var(--linie); }
.liste.laeufe tr.meldungszeile:hover { background: none; }
.laufmeldung { display: block; color: var(--leise); font-size: 12.5px;
  border-left: 2px solid var(--linie); padding-left: 10px; }
.liste.laeufe tr:not(.meldungszeile) td { border-bottom: none; }
.liste.laeufe tr:not(.meldungszeile):not(:has(+ tr.meldungszeile)) td {
  border-bottom: 1px solid var(--linie); }
.liste.laeufe tr.zeile-fehler .laufmeldung { border-left-color: var(--schlecht); }

/* --- Laufender Import auf der Quellenseite -------------------------------- */

.quellkarte.arbeitet { border-color: var(--leise); }
.quellaktionen button[disabled] {
  opacity: 0.45; cursor: not-allowed;
  background: var(--flaeche); color: var(--leise); border-color: var(--linie);
}
.quellaktionen .nebensache { display: inline; align-self: center; }

.marke.arbeitet-marke { display: inline-flex; align-items: center; gap: 6px;
  color: var(--text); background: color-mix(in srgb, var(--linie) 70%, transparent); }

/* Ein kleiner Kreisel statt eines Textes: Er zeigt, dass gearbeitet wird, ohne
   den Platz einer weiteren Zeile zu brauchen. */
.kreisel {
  display: inline-block; width: 11px; height: 11px; flex: none;
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor; border-radius: 50%;
  animation: kreiseln 0.8s linear infinite;
}
.kreisel.gross { width: 15px; height: 15px; border-width: 2px; }
@keyframes kreiseln { to { transform: rotate(360deg); } }

.laufbanner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: 20px;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius);
}
.laufbanner.ruht { border-color: color-mix(in srgb, var(--gut) 40%, var(--linie)); }
.laufbanner .nebensache { display: inline; }
.laufbanner a { margin-left: auto; }

.quellmeldung.frisch { border-left-color: var(--akzent); color: var(--text); }

/* --- Einstellungen: Vorschau der Kennung ---------------------------------- */

.kennung-vorschau {
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 14px 18px; margin-bottom: 20px;
}
.kennung-vorschau code { display: block; margin-top: 6px; padding: 8px 10px;
  font-size: 13px; background: color-mix(in srgb, var(--linie) 35%, transparent);
  word-break: break-all; }
.kennung-vorschau .hinweis { margin: 12px 0 0; }

/* --- Seitenleiste ein- und ausklappen ------------------------------------- */

:root[data-leiste="schmal"] { --leiste-breite: 62px; }
.mit-seitenleiste { transition: grid-template-columns 0.18s ease; }
.seitenleiste { transition: padding 0.18s ease; }

.leiste-kopf { display: flex; align-items: center; justify-content: space-between;
  gap: 6px; }

.leiste-knopf {
  display: grid; place-items: center; width: 26px; height: 26px; flex: none;
  border: none; border-radius: 6px; background: none; color: var(--leise);
  cursor: pointer; padding: 0;
}
.leiste-knopf:hover { background: color-mix(in srgb, var(--linie) 50%, transparent);
  color: var(--text); }
/* Ein Winkel, der in die Richtung zeigt, in die es geht. */
.klapp-zeichen {
  display: block; width: 7px; height: 7px;
  border-left: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor;
  transform: rotate(45deg); margin-left: 3px;
  transition: transform 0.18s ease;
}
:root[data-leiste="schmal"] .klapp-zeichen { transform: rotate(-135deg); margin: 0 3px 0 0; }

/* Im schmalen Zustand bleiben nur die Symbole stehen. */
:root[data-leiste="schmal"] .nur-breit { display: none; }
:root[data-leiste="schmal"] .seitenleiste { padding-left: 8px; padding-right: 8px; }
:root[data-leiste="schmal"] .leiste-kopf { flex-direction: column; gap: 8px; }
:root[data-leiste="schmal"] .leiste-knopf { width: 100%; height: 22px; }
:root[data-leiste="schmal"] .marke-logo { justify-content: center; }
:root[data-leiste="schmal"] .leiste-nav a { justify-content: center; padding: 9px 0; }
:root[data-leiste="schmal"] .nav-zeichen { width: auto; font-size: 15px; }
:root[data-leiste="schmal"] .leiste-etikett { display: none; }
:root[data-leiste="schmal"] .konto-zeile { justify-content: center; }

:root[data-leiste="schmal"] .leiste-fuss { gap: 6px; }



/* --- Konto und Verwaltung ------------------------------------------------- */

.kontomenue { position: relative; }
.kontomenue > summary {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 7px; cursor: pointer;
  list-style: none; color: var(--leise); font-size: 13px;
}
.kontomenue > summary::-webkit-details-marker { display: none; }
.kontomenue > summary:hover { background: color-mix(in srgb, var(--linie) 45%, transparent);
  color: var(--text); }
.kontomenue[open] > summary { background: color-mix(in srgb, var(--linie) 55%, transparent);
  color: var(--text); }
.klapp-winkel {
  margin-left: auto; width: 7px; height: 7px; flex: none;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  opacity: 0.6; transition: transform 0.15s, opacity 0.15s;
}
.kontomenue[open] .klapp-winkel {
  transform: rotate(-135deg) translate(-2px, -2px); opacity: 1;
}

/* Das Menü klappt nach oben auf — es sitzt am unteren Rand der Leiste. */
.kontomenue-inhalt {
  display: grid; gap: 2px; padding: 6px 0 4px;
}
.kontomenue-inhalt a {
  display: block; padding: 7px 10px 7px 34px; border-radius: 7px;
  text-decoration: none; color: var(--leise); font-size: 13.5px;
}
.kontomenue-inhalt a:hover { background: color-mix(in srgb, var(--linie) 45%, transparent);
  color: var(--text); }
.kontomenue-inhalt a.aktiv { color: var(--text); font-weight: 550;
  background: color-mix(in srgb, var(--linie) 60%, transparent); }
.kontomenue-inhalt form { padding: 4px 4px 0; }

/* Eingeklappt: nur das Zahnrad, das Menü legt sich daneben. */
:root[data-leiste="schmal"] .kontomenue > summary { justify-content: center; padding: 9px 0; }
:root[data-leiste="schmal"] .klapp-winkel { display: none; }
:root[data-leiste="schmal"] .kontomenue[open] .kontomenue-inhalt {
  position: absolute; bottom: 0; left: calc(100% + 8px); z-index: 40;
  min-width: 170px; padding: 6px;
  background: var(--flaeche); border: 1px solid var(--linie);
  border-radius: var(--radius); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
}
:root[data-leiste="schmal"] .kontomenue-inhalt a { padding-left: 10px; }

/* Größenlauf
   Der Balken sitzt unter der Zahl und macht auf einen Blick sichtbar, ob ein Artikel
   noch voll bestückt ist. Ohne Zahl kein Balken — wo wir nichts wissen, zeigen wir
   nichts. */
.groessen { white-space: nowrap; }
.groessen .balken {
  display: block; height: 3px; margin-top: 3px; border-radius: 2px;
  background: var(--linie);
}
.groessen .balken::before {
  content: ""; display: block; height: 100%; width: var(--anteil, 0%);
  border-radius: 2px; background: var(--akzent);
}
/* Wenig Größen: der Balken warnt, statt Vollständigkeit vorzutäuschen. */
.groessen .balken.knapp::before { background: var(--warnung); }
.nebensache.restgroessen {
  color: var(--warnung); font-weight: 500;
  background: color-mix(in srgb, var(--warnung) 14%, transparent);
  border-radius: 4px; padding: 0 4px;
}
.groessenlauf { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.groessenlauf .groesse {
  font-size: 11px; padding: 1px 5px; border-radius: 4px;
  border: 1px solid var(--linie); color: var(--leise);
}
.groessenlauf .groesse.da { border-color: var(--akzent); color: var(--text); }

/* Handbuch
   Eine Seite zum Lesen: schmalere Zeilen als eine Tabelle, mehr Luft zwischen den
   Abschnitten. Das Verzeichnis oben springt per Anker, ohne JavaScript. */
.fliesstext { max-width: 68ch; line-height: 1.65; margin: 0 0 12px; }
.inhaltsverzeichnis {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 24px;
  padding-bottom: 14px; border-bottom: 1px solid var(--linie);
}
.inhaltsverzeichnis a {
  font-size: 13px; padding: 3px 10px; border-radius: 99px;
  border: 1px solid var(--linie); color: var(--leise); text-decoration: none;
}
.inhaltsverzeichnis a:hover { color: var(--text); border-color: var(--akzent); }
.schrittfolge { counter-reset: schritt; list-style: none; padding: 0; max-width: 68ch; }
.schrittfolge > li {
  counter-increment: schritt; position: relative;
  padding: 0 0 18px 42px; border-left: 1px solid var(--linie); margin-left: 13px;
}
.schrittfolge > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.schrittfolge > li::before {
  content: counter(schritt); position: absolute; left: -13px; top: 0;
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  font-size: 12px; font-weight: 600;
  background: var(--flaeche); border: 1px solid var(--linie); color: var(--leise);
}
.schrittfolge h3 { margin: 2px 0 4px; font-size: 15px; }
.schrittfolge p { margin: 0; line-height: 1.6; color: var(--leise); }
.erklaerung { max-width: 68ch; margin: 0; }
.erklaerung dt { font-weight: 600; margin-top: 12px; }
.erklaerung dd { margin: 3px 0 0; padding-left: 0; color: var(--leise); line-height: 1.6; }
.merkmale { max-width: 68ch; line-height: 1.65; padding-left: 20px; }
.merkmale li { margin-bottom: 6px; }
.frage {
  max-width: 68ch; border-bottom: 1px solid var(--linie); padding: 10px 0;
}
.frage summary { cursor: pointer; font-weight: 500; }
.frage summary:hover { color: var(--akzent); }
.frage p { margin: 8px 0 4px; color: var(--leise); line-height: 1.6; max-width: 66ch; }
.hilfe-abschnitt + .hilfe-abschnitt { margin-top: 32px; }

/* Wettbewerberauswahl
   Chips statt Mehrfachauswahlfeld: Die Prozentzahl gehört zum Namen, und die Farbe
   ist dieselbe wie im Diagramm und in der Tabelle. Ein <select multiple> könnte
   beides nicht zeigen. */
.anbieterwahl {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  width: 100%; margin-top: 4px;
}
.wahl-titel { margin-right: 2px; }
.anbieterchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 99px; cursor: pointer;
  border: 1px solid var(--linie); background: var(--flaeche);
  font-size: 12.5px; color: var(--leise); user-select: none;
  transition: border-color 0.12s, color 0.12s;
}
.anbieterchip input { position: absolute; opacity: 0; pointer-events: none; }
.anbieterchip::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--hell, var(--leise));
}
:root[data-theme="dark"] .anbieterchip::before { background: var(--dunkel, var(--leise)); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .anbieterchip::before { background: var(--dunkel, var(--leise)); }
}
.anbieterchip:hover { border-color: var(--akzent); color: var(--text); }

/* Gewählt heißt gefüllt: Ein Rahmen allein ist zu leise, wenn daneben sechs andere
   Chips stehen. Die Farbe kehrt sich um, ein Haken kommt dazu, der Chip hebt sich an.

   Entscheidend ist der Selektor: Er hängt am Zustand der Checkbox, nicht an einer
   Klasse aus der Antwort. Die Chipleiste liegt außerhalb von #tabelle, und HTMX
   tauscht nur die Tabelle aus — eine servergesetzte Klasse käme beim Anwählen nie an
   und bliebe beim Abwählen fälschlich stehen. Der Browser dagegen kennt den
   Checkbox-Zustand im selben Moment, in dem geklickt wird. */
.anbieterchip:has(input:checked) {
  background: var(--akzent); border-color: var(--akzent); color: var(--papier);
  font-weight: 560;
  box-shadow: 0 1px 6px color-mix(in srgb, var(--akzent) 35%, transparent);
}
.anbieterchip:has(input:checked):hover { color: var(--papier); opacity: 0.9; }
.anbieterchip:has(input:checked)::before { background: var(--papier); }
.anbieterchip:has(input:checked) .chip-wert { opacity: 0.85; }
.anbieterchip:has(input:checked) .chip-haken { display: inline; }
.chip-haken { display: none; font-size: 11px; margin-left: -1px; }

/* Sobald etwas gewählt ist, treten die übrigen zurück — dann ist auf einen Blick
   klar, dass die Tabelle gefiltert ist. */
.anbieterwahl:has(input:checked) .anbieterchip:not(:has(input:checked)) { opacity: 0.5; }
.anbieterwahl:has(input:checked) .anbieterchip:not(:has(input:checked)):hover { opacity: 1; }

/* Und eine Ansage in Worten, die kein Auge übersieht. Sie erscheint ebenfalls allein
   über den Checkbox-Zustand, also ohne Zutun des Servers. */
.wahl-hinweis { display: none; font-size: 12.5px; color: var(--leise); }
.anbieterwahl:has(input:checked) .wahl-hinweis { display: inline; }
.chip-wert { font-variant-numeric: tabular-nums; opacity: 0.75; }
.wahl-zuruecksetzen { cursor: pointer; text-decoration: underline; margin-left: 4px; }

/* Rückstand gegen einen Abverkauf: Die Zahl stimmt, aber sie soll nicht zu einer
   Preissenkung drängen, die sich nicht lohnt. Also ohne Warnfarbe. */
.liste td.gedaempft { color: var(--leise); }
.nebensache.massstab { color: var(--text); font-weight: 500; }

/* Suchfeld mit Löschknopf
   Der Knopf sitzt im Feld. Er erscheint nur, wenn etwas drinsteht — das erkennt CSS
   an :placeholder-shown, ohne dass JavaScript den Zustand pflegen müsste. */
.suchfeld { position: relative; display: flex; flex: 1 1 260px; }
.suchfeld input[type="search"] { flex: 1; padding-right: 32px; }
/* Das browsereigene Kreuz weicht dem eigenen, sonst stünden dort zwei. */
.suchfeld input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
.suche-loeschen {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: none; place-items: center; width: 20px; height: 20px; padding: 0;
  border: none; border-radius: 50%; background: none; cursor: pointer;
  color: var(--leise); font-size: 16px; line-height: 1;
}
.suche-loeschen:hover { background: color-mix(in srgb, var(--linie) 70%, transparent);
  color: var(--text); }
.suchfeld:has(input:not(:placeholder-shown)) .suche-loeschen { display: grid; }

/* "Unterbieten mich": Null ist die gute Nachricht und steht als Wort da — eine 0
   liest sich in einer Zahlenspalte wie ein fehlender Wert. */
.unterbieten .gut { color: var(--gut); font-weight: 500; }
.unterbieten .schlecht { color: var(--schlecht); font-weight: 600; }
.unterbieten .gedaempft { color: var(--leise); font-weight: 500; }

/* Selbsttätiger Betrieb: eine ruhige Zeile, kein Alarm. */
.quellkarte .automatik { margin: 10px 0 0; display: flex; gap: 6px; flex-wrap: wrap; }

/* Einstellungs-Layer je Quelle
   <dialog> bringt Hintergrund, Esc und Fokusführung mit; hier bleibt nur das Aussehen. */
.quelle-zahnrad {
  display: grid; place-items: center; flex: none;
  border: none; background: none; cursor: pointer; padding: 0;
  width: 24px; height: 24px; color: var(--leise); border-radius: 50%;
}
.quelle-zahnrad:hover { color: var(--text);
  background: color-mix(in srgb, var(--linie) 60%, transparent); }
dialog.einstellungen {
  border: 1px solid var(--linie); border-radius: var(--radius); padding: 20px 22px;
  background: var(--flaeche); color: var(--text);
  width: min(420px, calc(100vw - 32px));
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
  /* Der Layer selbst scrollt nie — weder senkrecht noch waagerecht. Er ist ein fester
     Rahmen; was darin zu lang wird, bekommt seinen eigenen Scrollbereich. Ohne die
     Höhenbegrenzung wächst ein <dialog> über den Bildschirm hinaus und nimmt das
     Scrollen selbst in die Hand. */
  max-height: min(86vh, 760px);
  overflow: clip;
}
/* `display` NUR im geöffneten Zustand setzen. Ein geschlossener <dialog> ist
   `display: none`; jede eigene display-Angabe hebelt das aus, und der Layer steht
   dauerhaft in der Seite — unschließbar, weil close() nur das open-Attribut entfernt. */
dialog.einstellungen[open] { display: flex; flex-direction: column; }
/* Das Kind (Formular oder Inhalt) darf schrumpfen, sonst drückt es den Rahmen auf. */
dialog.einstellungen > form,
dialog.einstellungen > .haendlerchips { min-height: 0; }
dialog.einstellungen > form {
  display: flex; flex-direction: column; flex: 1 1 auto; overflow: clip;
}
dialog.einstellungen::backdrop { background: rgba(0, 0, 0, 0.35); }
dialog.einstellungen h3 { margin: 0 0 2px; font-size: 16px; padding-right: 28px; }
/* Schließen oben rechts — der gewohnte Griff, zusätzlich zu Esc und dem Knopf unten. */
.dialog-x {
  position: absolute; top: 12px; right: 12px;
  display: grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: none; border-radius: 50%; background: none; cursor: pointer;
  color: var(--leise); font-size: 17px; line-height: 1;
}
.dialog-x:hover { color: var(--text);
  background: color-mix(in srgb, var(--linie) 70%, transparent); }
dialog.einstellungen > form > label {
  display: block; margin-top: 16px; font-size: 13.5px; font-weight: 500;
}
dialog.einstellungen label .nebensache { font-weight: 400; margin: 2px 0 5px; }
dialog.einstellungen input[type="number"],
dialog.einstellungen input[type="text"] {
  width: 100%; font: inherit; font-size: 14px; padding: 7px 10px;
  border: 1px solid var(--linie); border-radius: 6px;
  background: var(--papier); color: var(--text);
}
dialog.einstellungen label.schalter {
  display: flex; align-items: center; gap: 8px; margin-top: 14px;
}
dialog.einstellungen label.schalter input { width: auto; }
.dialog-knoepfe {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 22px;
  padding-top: 14px; border-top: 1px solid var(--linie);
  flex: none;            /* bleibt sichtbar, auch wenn der Inhalt scrollt */
}
/* Die Felder eines Einstellungsformulars scrollen, die Knöpfe stehen fest. */
.dialog-felder { flex: 1 1 auto; min-height: 0; overflow: hidden auto; }

/* everysize steht als ein Feld in der Reihe der Wettbewerber, mit einem Zahnrad für
   seine Händler — dasselbe Zeichen wie an den Quellkarten, dieselbe Bedeutung.
   Vierzig Chips in derselben Reihe wären keine Auswahl mehr, sondern eine Wand. */
/* Der everysize-Chip trägt sein Zahnrad innen. Die Hülle ist ein <span>, der Text
   darin ein <label> — der Knopf darf nicht im Label stehen. Nach außen sieht es aus
   wie jeder andere Chip, nur mit einem Zeichen mehr. */
.anbieterchip.sammel { padding-right: 4px; gap: 4px; }
.chip-klick { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.chip-zahnrad {
  display: grid; place-items: center; cursor: pointer;
  width: 19px; height: 19px; padding: 0;
  border: none; background: none; border-radius: 50%;
  color: inherit; opacity: 0.55;
}
/* Das SVG sitzt mittig im Knopf, weil sein Mittelpunkt die Mitte des viewBox ist —
   anders als beim Schriftzeichen, dessen Tinte je nach Font verrutscht. */
.zahnrad-zeichen { display: block; }
.chip-zahnrad:hover { opacity: 1; background: color-mix(in srgb, currentColor 16%, transparent); }
/* Sind einzelne Händler gewählt, ist das Zeichen dauerhaft kräftig. */
/* Teilmenge gewählt: gestrichelter Rahmen statt gefüllt — sichtbar anders als
   "alle einbezogen", damit niemand die Einschränkung übersieht. */
.anbieterchip.sammel.hat-auswahl {
  border-color: var(--akzent); border-style: dashed; color: var(--text);
  background: color-mix(in srgb, var(--akzent) 10%, transparent);
}
.anbieterchip.sammel.hat-auswahl .chip-zahnrad { opacity: 1; }
.anbieterchip.sammel.hat-auswahl .chip-wert { font-weight: 600; }

/* Im Layer stehen die Händler als Chips — dicht gesetzt, mit Suchfeld darüber. */
dialog.haendlerwahl { width: min(560px, calc(100vw - 32px)); }
/* Eine Zeile genügt. Der Selektor nennt bewusst auch das Element: Die globale Regel
   `input[type="search"]` ist spezifischer als eine Klasse allein und behielte sonst
   ihr größeres Polster und ihre Schriftgröße. */
/* Das Feld sitzt in einer eigenen Zeile. Der Dialog ist eine Flex-Spalte, und ein
   Suchfeld erbt aus der globalen Regel `flex: 1 1 260px` — in einer Spalte heißt
   "wachsen" in die Höhe, und das Feld wurde mehrere hundert Pixel hoch. Die Zeile
   darum nimmt ihm diese Möglichkeit, unabhängig davon, welche Regel gewinnt. */
.suchzeile { flex: none; margin-top: 14px; }
input[type="search"].haendlersuche {
  width: 100%; display: block; flex: none;
  padding: 5px 9px; font-size: 13px; line-height: 1.3;
}
.haendlerchips {
  /* Nur senkrecht scrollen. `overflow-y: auto` allein macht die waagerechte Achse
     ebenfalls scrollbar, und die vertikale Leiste stößt den Inhalt dann so weit an,
     dass eine zweite, sinnlose Leiste unten erscheint. */
  /* Der einzige Bereich, der scrollt — und nur senkrecht. */
  flex: 1 1 auto; min-height: 120px; overflow: hidden auto; margin-top: 10px;
  padding: 10px; align-content: flex-start;
  border: 1px solid var(--linie); border-radius: var(--radius);
  background: var(--papier);
}
.haendlerchips .anbieterchip { font-size: 12px; background: var(--flaeche); }
/* Was die Suche ausblendet. */
.anbieterchip.verborgen { display: none; }

/* Blätterleiste unter der Tabelle */
.blaetterleiste {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 12px; font-size: 13px;
}
.blaetterleiste .blaettern { display: flex; align-items: center; gap: 8px; }
.blaetterleiste .seitenzahl { font-variant-numeric: tabular-nums; }
/* Am Anfang und am Ende bleibt der Knopf stehen, statt zu verschwinden — sonst
   springt die Leiste beim Blättern. */
.knopf.aus { opacity: 0.4; cursor: default; }

/* Beispielblöcke im Handbuch: Adressen und Gewichte, die man lesen können soll. */
pre.beispiel {
  background: var(--papier); border: 1px solid var(--linie);
  border-radius: var(--radius); padding: 10px 14px; margin: 8px 0 14px;
  font-size: 12.5px; line-height: 1.7; overflow-x: auto; max-width: 68ch;
}
pre.beispiel strong { font-weight: 700; }

/* Der Verweis in den fremden Shop steht als Zeichen neben dem Namen — der Name selbst
   führt in den eigenen Vergleich. */
.fremdlink {
  border: none; color: var(--leise); text-decoration: none;
  font-size: 12px; margin-left: 5px;
}
.fremdlink:hover { color: var(--text); }

/* Herstellernummer kopieren
   Der Knopf steht neben der Nummer und bleibt zurückhaltend, bis man die Zeile
   berührt — er soll die Tabelle nicht mit Symbolen zupflastern. */
.artikelnummer { display: flex; align-items: center; gap: 5px; }
.kopieren {
  display: grid; place-items: center; flex: none;
  width: 18px; height: 18px; padding: 0; border: none; border-radius: 4px;
  background: none; color: var(--leise); cursor: pointer;
  opacity: 0; transition: opacity 0.12s, color 0.12s;
}
tr:hover .kopieren, .kopieren:focus-visible { opacity: 1; }
.kopieren:hover { color: var(--text);
  background: color-mix(in srgb, var(--linie) 70%, transparent); }
/* Rückmeldung: Ohne sie weiß niemand, ob der Klick gewirkt hat. */
.kopieren.geschafft { opacity: 1; color: var(--gut); }
.kopieren.geschafft .kopie-zeichen { display: none; }
.kopieren.geschafft::after { content: "✓"; font-size: 12px; font-weight: 700; }

/* Artikelzelle mit Thumbnail
   Der Flex-Kasten sitzt **in** der Zelle, nicht auf ihr: `display: flex` auf einem
   <td> nimmt ihm die gemeinsame Zeilenhöhe, und die Trennlinien der Tabelle stimmen
   nicht mehr überein. */
.artikelzelle > .zellinhalt { display: flex; align-items: center; gap: 10px; }
.artikeltext { min-width: 0; }
.thumb {
  width: 36px; height: 36px; flex: none; object-fit: contain;
  border-radius: 5px; background: var(--papier); border: 1px solid var(--linie);
}

/* Artikelbild auf der Detailseite */
.titelzeile.mit-bild { gap: 18px; align-items: flex-start; }
/* Neben dem Bild rücken Name und Kennungen zusammen: Der übliche Abstand einer
   Überschrift wirkt hier wie eine Lücke, weil das Bild daneben die Höhe vorgibt. */
.titelzeile.mit-bild h1 { margin-bottom: 0; line-height: 1.25; }
.titelzeile.mit-bild > div > .nebensache { margin-top: 3px; }
.artikelbild {
  width: 120px; height: 120px; flex: none; object-fit: contain;
  border-radius: var(--radius); background: var(--flaeche);
  border: 1px solid var(--linie); padding: 4px;
}
@media (max-width: 700px) { .artikelbild { width: 84px; height: 84px; } }

/* --- Gleich hohe Zeilen in der Vergleichsliste -----------------------------
 * Ein Artikel mit Abverkauf, Maßstab und ausverkauftem Tiefpreis trug vier
 * Nebenzeilen, sein Nachbar eine — die Liste las sich wie eine Treppe. Jede Zelle
 * trägt ihren Inhalt deshalb in einem Kasten von drei Zeilen Höhe: genug für
 * Wert, Anbieter und einen Hinweis, und zugleich die Obergrenze.
 *
 * Der Kasten liegt **in** der Zelle, nicht auf ihr: `display: flex` auf einem <td>
 * nimmt ihm die gemeinsame Zeilenhöhe und bricht die Trennlinien.
 */

/* Drei Chipreihen à 16 px plus zwei Fugen à 2 px — die Höhe ist genau so
   bemessen, dass eine vierte Reihe vollständig außerhalb beginnt und nicht
   angeschnitten am unteren Rand hängt. */
.liste.vergleich { --zeile: 52px; --chip: 16px; }
.liste.vergleich tbody td > .zellinhalt {
  height: var(--zeile); overflow: hidden;
  display: flex; flex-direction: column;
  /* Oben beginnen, nicht mittig: Sonst rutschte eine einzeilige Zelle gegenüber
     ihren Nachbarn nach unten — und die Liste wirkte unruhiger als vorher. */
  justify-content: flex-start; align-items: flex-start; gap: 1px;
}
.liste.vergleich tbody td.zahl > .zellinhalt { align-items: flex-end; }
/* Ohne Deckel wäre ein Kind so breit wie sein Text — in einer rechtsbündigen Spalte
   liefe es links aus der Zelle heraus, und der Anfang des Anbieternamens fehlte. */
.liste.vergleich tbody td > .zellinhalt > * { max-width: 100%; }
/* Links ausgerichtet, nicht zentriert: Sonst tanzen Bild und Titel je nach
   Titellänge von Zeile zu Zeile. */
.liste.vergleich .artikelzelle > .zellinhalt {
  flex-direction: row; justify-content: flex-start; align-items: center; gap: 10px;
}
.hauptwert { display: block; line-height: 1.3; }
/* Der Artikelname bleibt einzeilig: Zwei Zeilen Titel plus Nummer sprengen den
   Kasten, und wo abgeschnitten werden muss, ist das Ende des Namens der bessere
   Ort als die Herstellernummer darunter. Der volle Name steht im Tooltip. */
.artikeltext > a { display: block; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.liste.vergleich td .nebensache { line-height: 1.25; }
/* Die Hinweiszeile steht eine Stufe unter dem Anbieter: Sie erklärt den Preis
   darüber, statt selbst einer zu sein. */
.zusatzzeile { max-width: 100%; font-size: 11.5px; }

/* Die Anbieter brechen in Reihen um. Sie schrumpfen dabei nicht — ein Chip, von
   dem nur "eve…" übrig bleibt, sagt nichts; dann lieber einer weniger und der
   Zähler am Ende, der die übrigen im Tooltip trägt. */
.liste.vergleich .anbieterzelle > .zellinhalt {
  position: relative;
  flex-direction: row; flex-wrap: wrap; align-content: flex-start;
  align-items: flex-start; gap: 2px 3px;
}
.liste.vergleich .anbieterzelle .marke {
  /* Ohne das eigene Außenmaß der Marke: In einem Flex-Kasten kommt es zum gap
     hinzu, die Reihen rückten auf 20 px auseinander und die dritte wurde
     angeschnitten. */
  flex: none; max-width: 100%; margin: 0; font-size: 10.5px; padding: 0 5px;
  height: var(--chip); line-height: var(--chip);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Der Zähler sitzt fest in der unteren Ecke: Liefe er im Fluss mit, wäre er bei
   vielen Wettbewerbern das Erste, was aus dem Kasten fällt — dabei ist gerade dann
   am wichtigsten, dass da noch mehr sind. */
.liste.vergleich .anbieterzelle .mehr {
  position: absolute; right: 0; bottom: 0; margin: 0; padding-left: 4px;
  background: var(--flaeche);
}
.liste.vergleich tbody tr:hover .anbieterzelle .mehr {
  background: color-mix(in srgb, var(--linie) 35%, var(--flaeche));
}
/* Der Balken hat keine eigene Breite — in einer Spalte mit rechtsbündigem Inhalt
   fiele er sonst auf null zusammen. */
.liste.vergleich .groessen .balken { align-self: stretch; width: 100%; }

/* Wann ein Preis zuletzt bestätigt wurde — gedämpfter als der Anbietername, damit
   die Zeile nicht mit zwei gleich lauten Angaben konkurriert. */
.zeitzeile { font-size: 11px; opacity: 0.75; }
.liste.vergleich .zeitzeile { white-space: nowrap; }
