/* ===============================================================
   Gestaltung

   Die Seite beantwortet eine Frage nach einem Ort: was liegt hier an?
   Alles Sichtbare ordnet sich dem unter. Zahlen stehen in einer
   Schreibmaschinenschrift und rechtsbuendig untereinander, damit sich
   zwei Werte im Vorbeisehen vergleichen lassen; Flaechen sind kuehl und
   flach, Kanten rechtwinklig. Was hervorgehoben ist, ist es ueber eine
   Linie an der Seite, nicht ueber eine Farbflaeche — eine gefaerbte
   Kachel liest sich auf einer Seite mit Werbelinks wie Werbung.

   Ein heller Modus, bewusst. Ein dunkles Gegenstueck waere eine zweite
   Palette, die bei jeder Aenderung mitgepflegt werden muesste, und die
   Anbieterlogos sind ohnehin fuer hellen Grund gebaut.
   =============================================================== */

/* --- Schriften -------------------------------------------------
   Selbst gehostet, keine Verbindung zu Google. Das ist auf einer
   deutschen Seite die rechtlich saubere Variante und deckt sich mit
   dem, was die Datenschutzerklaerung zusagt.

   Die Rollen sind gegenueber der Vorlage vertauscht: Plex Sans traegt
   die Ueberschriften, Archivo den Fliesstext. Plex Mono ist hier keine
   Codeschrift, sondern die Zahlenschrift — Bandbreiten und Preise
   stehen darin, weil ihre Ziffern alle gleich breit sind.          */

@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}
@font-face {
  font-family: "Plex Sans";
  src: url("/assets/fonts/plexsans-var.woff2") format("woff2-variations");
  font-weight: 100 700;
  font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/assets/fonts/plexmono-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("/assets/fonts/plexmono-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

/* --- Werte -----------------------------------------------------

   Die Farben sind die der Seite, die seit 2015 unter dieser Domain
   steht: das Blau #2991d6 an Links, Knoepfen und der Marke, ein
   hellgrauer Streifen unter dem Kopf, ein dunkelgrauer Fuss. Wer die
   alte Seite kannte, erkennt die neue wieder — was sich geaendert hat,
   sind die Abstaende, die Schriften und das, was in den Kaesten steht.
                                                                   */

:root {
  /* Grundflaechen. Das #f7f7f7 ist der Titelstreifen der Altseite. */
  --grund: #ffffff;
  --flaeche: #f7f7f7;
  --flaeche-tief: #ededed;
  --linie: #e2e2e2;
  --linie-zart: #ededed;

  /* Schrift. Die Altseite setzte Fliesstext auf #626262 und
     Ueberschriften auf #444; hier steht beides eine Spur dunkler,
     damit auf kleinen Schirmen nichts verblasst. */
  --tinte: #3c3c3c;
  --grau: #6f6f6f;

  /* Handlungsfarbe: das Blau der Marke. Es steht an Links, Knoepfen,
     der Unterstreichung im Menue und den Kanten der Karten. */
  --leitung: #2991d6;
  --leitung-tief: #2275ac;
  --leitung-zart: #eaf5fc;
  --auf-leitung: #ffffff;

  /* Der Fuss. Eigene Werte, weil dort alles seitenverkehrt liegt:
     helle Schrift auf dunklem Grund, und das Blau muss aufgehellt
     werden, sonst faellt es in den Untergrund zurueck. */
  --fuss-grund: #545454;
  --fuss-schrift: #cfcfcf;
  --fuss-hell: #ffffff;
  --fuss-linie: rgb(255 255 255 / .12);
  --fuss-leitung: #6bb8e8;

  /* Faellt zurueck, wo keine Anbieterfarbe gesetzt ist */
  --marke: var(--leitung);

  --schrift-display: "Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --schrift-text: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --schrift-zahl: "Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --breite: 74rem;
  /* Leicht gerundet wie auf der Altseite — genug, dass Kanten nicht
     schneiden, zu wenig, als dass es auffiele. */
  --rundung: 3px;
  --rundung-gross: 4px;

  color-scheme: light;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--grund);
  color: var(--tinte);
  font-family: var(--schrift-text);
  font-size: 1.0125rem;
  line-height: 1.62;
  font-variant-numeric: tabular-nums lining-nums;
  -webkit-font-smoothing: antialiased;
}

/* --- Schriftbild ------------------------------------------------
   Die Ueberschriften stehen eng und ohne Zierde; die Groessensprünge
   zwischen h1, h2 und h3 sind klein. Eine Seite, die eine Sachfrage
   beantwortet, braucht keine Plakatschrift — sie braucht eine
   Gliederung, die man beim Ueberfliegen sieht. Dafuer sorgt hier die
   Linie ueber jeder h2, nicht der Schriftgrad.                    */

h1, h2, h3, .display {
  font-family: var(--schrift-display);
  font-weight: 600;
  letter-spacing: -.014em;
  line-height: 1.18;
  color: var(--tinte);
  text-wrap: balance;
}

h1 {
  font-size: clamp(1.75rem, 1.35rem + 1.7vw, 2.5rem);
  font-weight: 650;
  letter-spacing: -.022em;
  margin: 0 0 .7rem;
}

/* Die Linie ueber der h2 gliedert die Seite. Sie laeuft ueber die volle
   Spaltenbreite und trennt zwei Themen deutlicher, als ein groesserer
   Schriftgrad es koennte — haarfein und grau, damit sie neben dem
   hellen Blau der Seite nicht wie ein Balken wirkt. */
h2 {
  font-size: 1.45rem;
  margin: 3rem 0 1rem;
  padding-top: .85rem;
  border-top: 1px solid var(--linie);
}
h3 { font-size: 1.12rem; margin: 2rem 0 .4rem; }
/* In Karten und Listen bleibt die Linie weg — dort trennt schon der
   Kasten. */
.anbieter-karte h2, .weg h3, .faq-eintrag h3, .karte-titel,
.marken-liste h2, .marken-liste h3, .themen-karte h2,
.anbieter-titel h2 { border-top: 0; padding-top: 0; margin-top: 0; }

p { margin: 0 0 1rem; }

a { color: var(--leitung); text-underline-offset: .17em; text-decoration-thickness: 1px; }
a:hover { color: var(--leitung-tief); text-decoration-thickness: 2px; }

strong, b { font-weight: 600; }

/* Fließtext soll nicht über die ganze Bildschirmbreite laufen */
.mass { max-width: 64ch; }

/* --- Gerüst ----------------------------------------------------- */

.wrap { max-width: var(--breite); margin-inline: auto; padding-inline: 1.5rem; }

main { padding-block: 2.5rem 5rem; }

.skip-link {
  position: absolute; left: -9999px;
  background: var(--leitung); color: var(--auf-leitung);
  padding: .7rem 1.1rem; border-radius: 0 0 var(--rundung) 0;
  font-family: var(--schrift-zahl); font-size: .8rem;
}
.skip-link:focus { left: 0; top: 0; z-index: 20; }

:focus-visible { outline: 2px solid var(--leitung); outline-offset: 2px; border-radius: 2px; }

/* --- Kopfleiste --------------------------------------------------
   Weiss, schmal, ohne Kasten drumherum — wie auf der Altseite. Getrennt
   wird sie vom Inhalt nicht durch eine Linie, sondern durch den grauen
   Titelstreifen, der direkt darunter beginnt.                       */

.kopf {
  background: var(--grund);
  position: sticky; top: 0; z-index: 10;
}
@media (max-width: 56rem) {
  .kopf { position: static; }
}

.kopf-inhalt {
  display: flex; flex-wrap: wrap; gap: .5rem 2.25rem;
  align-items: center; justify-content: space-between;
  padding-block: 1.05rem;
}

/* --- Die Wortmarke -----------------------------------------------
   Drei Teile in einer Zeile, wie im Schriftzug der Altseite: "Internet"
   fett und dunkelblau, "anbieter" in Textfarbe, ".net" im Hausblau.
   Die Teile stehen in site.js (wortmarke) und nicht hier — der Name der
   Domain gehoert an eine Stelle, nicht an zwei.                     */

.logo {
  display: inline-block;
  text-decoration: none;
  font-family: var(--schrift-display);
  font-size: 1.5rem; font-weight: 400;
  letter-spacing: -.025em; line-height: 1;
  white-space: nowrap;
  color: var(--tinte);
}
.logo:hover { color: var(--tinte); }
.logo-stark { font-weight: 700; color: var(--leitung-tief); }
.logo-rest  { color: #2c2c2c; }
.logo-tld   { color: var(--leitung); }

/* --- Hauptnavigation ---------------------------------------------
   Gemischtschrift statt Versalien und ein blauer Strich, der beim
   Zeigen von links nach rechts auslaeuft — beides von der Altseite
   uebernommen. Der Strich sitzt am Element und braucht kein zweites.  */

.hauptnav > ul {
  display: flex; flex-wrap: wrap; gap: 0 1.7rem;
  list-style: none; margin: 0; padding: 0;
}
.hauptnav a {
  display: block; position: relative;
  padding: .5rem 0;
  font-family: var(--schrift-text); font-size: .95rem;
  color: var(--tinte); text-decoration: none;
}
.hauptnav > ul > li > a::after {
  content: ""; position: absolute;
  left: 0; right: 100%; bottom: .1rem; height: 2px;
  background: var(--leitung);
  transition: right .18s ease;
}
.hauptnav a:hover { color: var(--leitung); }
.hauptnav > ul > li > a:hover::after,
.hauptnav > ul > li > a[aria-current]::after,
.hauptnav > ul > li:focus-within > a::after { right: 0; }
.hauptnav > ul > li > a[aria-current] { color: var(--leitung); }

/* Untermenues. Sie klappen beim Zeigen und beim Tastaturfokus auf —
   :focus-within genuegt dafuer, ein Skript braucht es nicht. Der
   Pfeil sagt vorher an, dass da noch etwas kommt. */
.hauptnav .hat-kinder { position: relative; }
.hauptnav .hat-kinder > a::before {
  content: "▾"; float: right;
  margin-left: .35rem; font-size: .7em; line-height: 1.9;
  color: var(--grau);
}
.hauptnav .untermenue {
  position: absolute; left: -.85rem; top: 100%;
  display: none; min-width: 15rem;
  list-style: none; margin: 0; padding: .3rem;
  background: var(--grund);
  border: 1px solid var(--linie);
  box-shadow: 0 .5rem 1.4rem rgb(0 0 0 / .1);
  z-index: 30;
}
.hauptnav .hat-kinder:hover > .untermenue,
.hauptnav .hat-kinder:focus-within > .untermenue { display: block; }
.hauptnav .untermenue a {
  padding: .48rem .85rem;
  font-size: .92rem; color: var(--grau);
}
.hauptnav .untermenue a:hover,
.hauptnav .untermenue a[aria-current] {
  background: var(--flaeche); color: var(--leitung);
}

/* --- Menue auf schmalen Schirmen ----------------------------------
   Alles haengt an der Klasse "js" am <html>: laeuft kein JavaScript,
   greift keine dieser Regeln und die Navigation steht offen da. Ein
   Menue, das zu ist und sich nicht oeffnen laesst, gibt es damit
   nicht. Die Untermenues stehen dort eingerueckt und offen — ein
   Aufklappen im Aufklappen hilft auf einem Handy niemandem.        */

.menue-knopf { display: none; }

@media (max-width: 65rem) {
  .js .menue-knopf {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .45rem .8rem;
    background: var(--grund); color: var(--tinte);
    border: 1px solid var(--linie); border-radius: var(--rundung-gross);
    font-family: var(--schrift-text); font-size: .9rem;
    cursor: pointer;
  }
  .js .menue-knopf:hover { background: var(--flaeche); color: var(--leitung); }
  .js .menue-knopf[aria-expanded="true"] {
    background: var(--flaeche); border-color: var(--flaeche-tief);
  }

  /* Drei Striche aus einem Element: der mittlere ist der Rahmen selbst,
     die aeusseren sind ::before und ::after. Offen kippen sie zum Kreuz. */
  .js .menue-striche {
    position: relative; display: block;
    width: 1rem; height: 2px; background: currentColor; border-radius: 1px;
    transition: background-color .12s ease;
  }
  .js .menue-striche::before,
  .js .menue-striche::after {
    content: ""; position: absolute; left: 0;
    width: 1rem; height: 2px; background: currentColor; border-radius: 1px;
    transition: transform .16s ease;
  }
  .js .menue-striche::before { top: -.32rem; }
  .js .menue-striche::after { top: .32rem; }

  .js .menue-knopf[aria-expanded="true"] .menue-striche { background: transparent; }
  .js .menue-knopf[aria-expanded="true"] .menue-striche::before {
    transform: translateY(.32rem) rotate(45deg);
  }
  .js .menue-knopf[aria-expanded="true"] .menue-striche::after {
    transform: translateY(-.32rem) rotate(-45deg);
  }

  /* Die Liste legt sich unter die Leiste, ueber die volle Breite. */
  .js .hauptnav { flex-basis: 100%; display: none; }
  .js .hauptnav.offen { display: block; }
  .js .hauptnav > ul {
    flex-direction: column; gap: 0;
    margin-top: .5rem; padding-top: .4rem;
    border-top: 1px solid var(--linie);
  }
  /* Auf dem Handy wird getippt, nicht gezielt: grosszuegige Flaechen. */
  .js .hauptnav > ul > li > a { padding: .75rem .1rem; font-size: 1rem; }
  .js .hauptnav > ul > li > a::after { display: none; }
  .js .hauptnav .hat-kinder > a::before { display: none; }
  .js .hauptnav .untermenue {
    position: static; display: block;
    min-width: 0; border: 0; box-shadow: none; padding: 0 0 .5rem;
    background: none;
  }
  .js .hauptnav .untermenue a {
    padding: .5rem .1rem .5rem 1.1rem;
    border-left: 2px solid var(--linie);
  }
  .js .hauptnav .untermenue a:hover { background: none; }
}

@media (prefers-reduced-motion: reduce) {
  .menue-striche, .menue-striche::before, .menue-striche::after,
  .hauptnav > ul > li > a::after { transition: none; }
}

@media (max-width: 34rem) {
  .logo { font-size: 1.3rem; }
}
@media (max-width: 26rem) {
  .logo { font-size: 1.15rem; }
  .js .menue-knopf { padding: .45rem .6rem; }
  .js .menue-wort {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; border: 0;
  }
}

/* --- Titelstreifen ------------------------------------------------
   Der graue Balken zwischen Kopf und Inhalt: links die Ueberschrift
   der Seite, rechts der Weg dorthin. Auf der Altseite stand der Titel
   dort kursiv und blassgrau — hier steht er als das, was er ist, naemlich
   die <h1>, und liest sich entsprechend. Der weiche Schatten darunter
   ist dieselbe Trennung wie damals, nur ohne Bilddatei.            */

.titelstreifen {
  background: var(--flaeche);
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
  box-shadow: 0 3px 4px -3px rgb(0 0 0 / .13);
}
.titelstreifen-inhalt {
  display: flex; flex-wrap: wrap; gap: .3rem 2rem;
  align-items: baseline; justify-content: space-between;
  padding-block: 1.5rem;
}
.titelstreifen h1 {
  margin: 0;
  font-size: clamp(1.4rem, 1.15rem + 1.05vw, 1.95rem);
  font-weight: 600; letter-spacing: -.018em;
}

/* --- Brotkrumen ---------------------------------------------------
   Sie stehen im Titelstreifen rechts und tragen dort keine eigene
   Flaeche. Auf schmalen Schirmen rutschen sie unter den Titel.     */

.brotkrumen {
  margin: 0;
  font-size: .85rem; color: var(--grau);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}
.brotkrumen a { color: var(--grau); text-decoration: none; }
.brotkrumen a:hover { color: var(--leitung); text-decoration: underline; }
.brotkrumen .trenner { margin: 0 .4rem; opacity: .5; }

/* --- Fuss ---------------------------------------------------------
   Dunkelgrau, helle Schrift, blaue Verweise — der Fuss der Altseite.
   Er traegt jetzt mehr als zwei Zeilen: oben die Bereiche der Seite
   als Verzeichnis, darunter die Zusage, worauf die Zahlen beruhen,
   und ganz unten das Rechtliche.                                   */

.fuss {
  background: var(--fuss-grund);
  color: var(--fuss-schrift);
  font-size: .9rem;
}
.fuss a { color: var(--fuss-leitung); text-decoration: none; }
.fuss a:hover { color: var(--fuss-hell); text-decoration: underline; }

.fuss-spalten {
  display: grid; gap: 1.75rem 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  padding-block: 2.5rem 2rem;
}
.fuss-spalte h2 {
  margin: 0 0 .7rem;
  border-top: 0; padding-top: 0;
  font-size: .82rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--fuss-hell);
}
.fuss-spalte ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .38rem;
}
.fuss-versprechen { margin: 0; }
.fuss-versprechen strong { color: var(--fuss-hell); font-weight: 600; }

.fuss-schluss {
  display: flex; flex-wrap: wrap; gap: .5rem 1.75rem;
  align-items: baseline; justify-content: space-between;
  padding-block: 1.1rem 1.6rem;
  border-top: 1px solid var(--fuss-linie);
  font-size: .84rem;
}
.fuss-schluss p { margin: 0; }
.fuss-links {
  display: flex; flex-wrap: wrap; gap: .4rem 1.5rem;
  list-style: none; margin: 0; padding: 0;
}

/* --- Ortsseiten und DSL-Vergleich ------------------------------------ */

.anriss { font-size: 1.1rem; color: var(--grau); max-width: 62ch; }
.klein { color: var(--grau); font-size: .85rem; }
.quelle, .hinweis { color: var(--grau); font-size: .86rem; }
.ortsteile { color: var(--grau); }

.ort section,
.vergleich section { margin-block: 3rem; }

table { border-collapse: collapse; }
.tabelle-scroll { overflow-x: auto; }

/* Der Ortstext ist Fließtext und soll wie Fließtext gelesen werden:
   schmales Maß, etwas mehr Zeilenabstand als der Rest der Seite. */
.ortstext p { max-width: 62ch; line-height: 1.7; }
.ortstext p + p { margin-top: .9rem; }

.tarif-tabelle { width: 100%; font-size: .95rem; }
.tarif-tabelle th, .tarif-tabelle td {
  text-align: left; padding: .75rem .8rem; vertical-align: top;
  border-bottom: 1px solid var(--linie-zart);
}
.tarif-tabelle thead th {
  background: var(--flaeche);
  font-family: var(--schrift-zahl); font-size: .68rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau);
  border-bottom-color: var(--linie);
}
.tarif-tabelle tbody tr:last-child td { border-bottom: 0; }
.tarif-tabelle tbody tr:hover td,
.tarif-tabelle tbody tr:hover th { background: var(--flaeche); }
.tarif-tabelle-knopf { text-align: right; white-space: nowrap; }
.tarif-tabelle-knopf .knopf { padding: .35rem .8rem; font-size: .82rem; }

/* Eine Tabelle bricht nicht um. Auf schmalen Schirmen bekommt sie deshalb
   ihren eigenen Bildlauf, statt die Seite mitzureissen. */
.tabelle-rahmen { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tabelle-rahmen .tarif-tabelle { min-width: 40rem; }

/* Die dritte Darstellung der Anbieterseiten (anbieterZuschnitt.darstellung
   = "zeilen"): dieselbe Bauart wie die Vergleichsseite, nur ohne Filter. */
.anbieter-tarifzeilen { list-style: none; margin: 0; padding: 0; }
.anbieter-tarifzeile {
  display: grid; gap: .5rem 1.2rem;
  grid-template-columns: minmax(10rem, 1.6fr) 7rem 9rem auto;
  align-items: center;
  padding: .9rem 1.1rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund);
}
.anbieter-tarifzeile + .anbieter-tarifzeile { margin-top: .5rem; }
.anbieter-tarifzeile .tarif-name { margin: 0; font-size: 1.02rem; }
.anbieter-tarifzeile p { margin: 0; }
@media (max-width: 44rem) {
  .anbieter-tarifzeile {
    grid-template-columns: 1fr auto;
    grid-template-areas: "kopf kopf" "tempo preis" "knopf knopf";
  }
  .anbieter-tarifzeile > div { grid-area: kopf; }
  .anbieter-tarifzeile .tarif-tempo { grid-area: tempo; }
  .anbieter-tarifzeile .tarif-preis { grid-area: preis; }
  .anbieter-tarifzeile .knopf { grid-area: knopf; text-align: center; }
}
.tarif-tabelle .zahl { white-space: nowrap; font-family: var(--schrift-zahl); }
.tarif-tabelle .klein { display: block; }

/* Ein Tarif ohne Provision steht in der Tabelle, aber ohne Knopf. Die
   blassere Schrift sagt das, bevor jemand den Text liest: Hier ist nichts
   zu klicken. */
.ohne-angebot {
  display: inline-block; white-space: nowrap;
  font-size: .82rem; color: var(--grau);
}

.marke {
  display: inline-block; margin-left: .4rem; padding: .12rem .45rem;
  border-radius: var(--rundung); background: var(--leitung-zart);
  font-family: var(--schrift-zahl); font-size: .66rem; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--leitung-tief); vertical-align: middle;
}
.anschluss { display: block; color: var(--grau); font-size: .8rem; }

/* Der hervorgehobene Anbieter (aid in src/_data/hervorhebung.js). Er steht
   oben und bekommt einen ruhigen Tonwert plus Kante an der Vorderseite —
   sichtbar genug, um aufzufallen, zurückhaltend genug, dass die Tabelle
   eine Tabelle bleibt. Das Schild unter seinem Namen sagt, warum. */
/* Ortstext und Anbieterkarte teilen sich den Platz über der Tabelle: auf
   breiten Bildschirmen zwei Spalten, der Text links im Lesemaß, die Karte
   rechts daneben. Darunter — und ohne Ortstext — steht die Karte einfach
   für sich, immer noch über der Tabelle. */
.ort-oben { margin-block: 3rem; }
.ort-oben > section { margin-block: 0; }

@media (min-width: 60rem) {
  .ort-oben {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 18rem;
    gap: 2.5rem; align-items: start;
  }
  .ort-oben > .anbieter-karte { grid-column: 2; grid-row: 1; }
}

.anbieter-karte {
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
  margin-top: 1.75rem;
  padding: 1.1rem 1.2rem 1.2rem;
  border: 1px solid var(--linie);
  border-top: 3px solid var(--marke, var(--leitung));
  border-radius: var(--rundung);
  background: var(--grund);
}
@media (min-width: 60rem) { .anbieter-karte { margin-top: 0; } }

/* Das Schild sagt, warum dieser Anbieter hier steht — es gehört nach oben,
   noch vor das Logo, nicht ans Ende der Karte. */
.karte-kennung {
  margin: 0;
  font-family: var(--schrift-zahl); font-size: .66rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grau);
}
.karte-titel { margin: .2rem 0 0; font-size: 1.05rem; }
.karte-tarif { margin: 0; font-weight: 500; }
.karte-tarif .anschluss { font-weight: 400; }
.anbieter-karte .tarif-tempo { margin: 0; }
.anbieter-karte .tarif-tempo .klein { display: inline; }
.karte-preis { margin: 0; }
.karte-preis strong { font-family: var(--schrift-zahl); font-size: 1.35rem; }
.anbieter-karte .knopf { margin-top: .35rem; }
.karte-zweit { margin: .2rem 0 0; color: var(--grau); font-size: .85rem; }

.tarif-tabelle tr.hervor td { background: var(--leitung-zart); }
.tarif-tabelle tr.hervor td:first-child { box-shadow: inset 3px 0 0 var(--leitung); }
.anbieter-liste li.hervor { font-weight: 500; }

/* Das Schild des hervorgehobenen Anbieters ist bewusst keine Pille: die
   Pillen in der Tarifspalte gehören dem Preisvergleich ("günstigster",
   "schnellster") und sagen etwas über den Tarif. Dieses hier sagt etwas
   über die Platzierung — es steht deshalb in der Anbieterspalte unter dem
   Namen, als stille Zeile in der Hausfarbe statt als zweite Pille neben
   der ersten. */
.hervor-schild {
  display: block; margin-top: .2rem;
  font-family: var(--schrift-zahl); font-size: .64rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--leitung-tief);
}

.knopf {
  display: inline-block; padding: .5rem 1.1rem; border-radius: var(--rundung);
  background: var(--leitung); color: var(--auf-leitung); text-decoration: none;
  font-size: .86rem; font-weight: 500; white-space: nowrap;
  transition: background-color .15s ease;
}
.knopf:hover, .knopf:focus-visible { background: var(--leitung-tief); color: var(--auf-leitung); }

.anbieter-liste, .nachbar-liste, .ort-liste {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: .4rem 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}
.ort-liste-voll { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
/* Name und Anschlussarten stehen in einem Textknoten (siehe ort.njk).
   Getrennt werden sie optisch, nicht im Markup: der Mittelpunkt bekommt
   Luft, der Rest der Zeile bleibt ruhig. */
.anb-zeile { display: block; }

/* Das Markenfeld in der Anbieterliste einer Ortsseite.

   Es steht nur bei den Anbietern, zu denen die Seite auch verlinkt (siehe
   ort.njk), und bleibt deshalb klein: Die Liste soll eine Liste bleiben und
   keine Reihe von Karten werden. Der Kasten ist ausserdem schmaler als im
   Vergleich, weil hier bis zu zwanzig Anbieter untereinander stehen.

   Wer ohne Logo dasteht, bekommt keinen leeren Platzhalter an dessen Stelle:
   Ein leerer Kasten neben dem Namen sieht aus wie ein Bild, das nicht geladen
   hat. Die Zeile beginnt dann eben beim Namen. */
.anbieter-liste li {
  display: flex; align-items: center; gap: .5rem;
  min-height: 1.9rem;
}
.anbieter-liste .anbieter-marke { width: 1.9rem; height: 1.9rem; }
.anbieter-liste .anbieter-marke.hat-logo {
  width: 3.6rem; height: 1.9rem;
  padding: .15rem .25rem;
}
.anbieter-liste .anb-zeile { flex: 1 1 auto; }

.daten {
  display: grid; grid-template-columns: max-content 1fr;
  gap: .35rem 1.5rem; margin: 0;
}
.daten dt {
  font-family: var(--schrift-zahl); font-size: .7rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--grau);
  align-self: center;
}
.daten dd { margin: 0; }

.bl-block {
  margin-block: 2.25rem; padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--linie);
}
.bl-block h2 { margin: 0 0 .15rem; font-size: 1.35rem; }
.bl-block h2 a { color: var(--tinte); text-decoration: none; }
.bl-block h2 a:hover { color: var(--leitung); }
.bl-block > .klein { margin-top: 0; }

/* --- Anbieter im DSL-Vergleich ---------------------------------------

   Ein Anbieter ist ein Block: oben sein Markenfeld mit Namen und
   Verbreitung, darunter zwei Karten — der günstigste und der schnellste
   Tarif. Zwei statt neun, weil eine vollständige Preisliste niemandem
   bei der Entscheidung hilft; die Auswahl trifft der Filter zweiTarife.  */

.anbieter-block {
  margin-block: 2rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--linie);
}
.anbieter-block:first-of-type { border-top: 0; padding-top: 0; }

.anbieter-kopf {
  display: flex; align-items: center; gap: .9rem;
  margin-bottom: 1rem;
}
.anbieter-titel h3 { margin: 0; font-size: 1.25rem; }
.anbieter-titel .abdeckung { margin: .15rem 0 0; }

.abdeckung {
  display: block;
  font-family: var(--schrift-zahl); font-size: .7rem; font-weight: 400;
  font-stretch: normal; letter-spacing: .06em; color: var(--grau);
}
.klein-inline { color: var(--grau); font-size: .85em; }

/* Das Markenfeld. Trägt es ein echtes Logo, ist der Kasten hell und neutral
   umrandet — die Logos bringen ihre eigenen Farben mit und brauchen einen
   ruhigen Untergrund. Fehlt ein Logo, bleibt es beim Anfangsbuchstaben auf
   der Hausfarbe --marke aus src/_data/anbieterMarken.js. */
.anbieter-marke {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 3.25rem; height: 3.25rem;
  border-radius: var(--rundung);
  background: var(--marke, var(--grau));
  color: #fff;
}
.anbieter-marke svg { width: 74%; height: auto; display: block; }

.anbieter-marke.hat-logo {
  width: 7.5rem; height: 3.25rem;
  padding: .45rem .65rem;
  background: #fff;
  border: 1px solid var(--linie);
}
.anbieter-marke.hat-logo img {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}
.marke-schrift {
  font-family: var(--schrift-display);
  font-weight: 800; font-stretch: 92%; letter-spacing: -.02em;
}

.tarif-karten {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.tarif-karte {
  display: flex; flex-direction: column; gap: .55rem;
  padding: 1.1rem 1.2rem 1.2rem;
  border: 1px solid var(--linie);
  border-top: 3px solid var(--marke, var(--leitung));
  border-radius: var(--rundung);
  background: var(--grund);
}

.tarif-rolle {
  margin: 0;
  font-family: var(--schrift-zahl); font-size: .66rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grau);
}
.tarif-name { margin: 0; font-size: 1.05rem; }
.tarif-tempo { margin: 0; font-size: 1.05rem; }
.tarif-tempo strong { font-family: var(--schrift-zahl); font-size: 1.35rem; }

.tarif-daten {
  display: grid; grid-template-columns: max-content 1fr;
  gap: .3rem 1.1rem; margin: .35rem 0 .2rem;
  padding-top: .7rem; border-top: 1px solid var(--linie-zart);
  font-size: .9rem;
}
.tarif-daten dt {
  font-family: var(--schrift-zahl); font-size: .68rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--grau);
  align-self: center;
}
.tarif-daten dd { margin: 0; }
.tarif-daten .zahl { font-family: var(--schrift-zahl); }
.tarif-daten strong.zahl { font-size: 1.05rem; }

/* Der Knopf sitzt unten bündig, auch wenn die Karte daneben höher ist. */
.tarif-karte .knopf { margin-top: auto; align-self: start; }

/* Der hervorgehobene Anbieter auf der Vergleichsseite (aid im Block
   vergleich in src/_data/hervorhebung.js — die Ortsseiten steuert der
   andere Block). Statt der Trennlinie, die die übrigen Blöcke voneinander
   scheidet, bekommt er einen ruhigen Untergrund und dieselbe Kante an der
   Vorderseite wie die markierte Zeile in der Tariftabelle der Ortsseiten.
   Das Schild daneben sagt, warum er oben steht. */
.anbieter-block.hervor {
  padding: 1.3rem 1.3rem 1.4rem;
  border-top: 0;
  border-left: 3px solid var(--leitung);
  border-radius: 0 var(--rundung) var(--rundung) 0;
  background: var(--leitung-zart);
}
.anbieter-titel h3 .hervor-schild {
  display: inline-block; margin: 0 0 0 .55rem; vertical-align: middle;
}

/* Der Wunschtarif (tid im selben Block). Er steht als erste Karte und
   bleibt hell: auf dem getönten Untergrund des Anbieterblocks hebt ihn das
   deutlicher heraus als noch mehr Farbe. */
.tarif-karte.hervor { border-color: var(--leitung); }
.tarif-karte.hervor .tarif-rolle { color: var(--leitung-tief); }

/* --- Tarifvergleich: Filterleiste und Tarifliste ---------------------

   Die Vergleichsseite zeigt jeden Tarif einzeln — rund hundert Zeilen.
   Zwei Dinge müssen das tragen:

   Erstens die Ausrichtung. Preis und Bandbreite stehen in eigenen Spalten
   untereinander, in der Zahlenschrift und rechtsbündig an der Einheit.
   Genau das macht aus einer Liste einen Vergleich: Das Auge fährt die
   Spalte hinunter und sieht die Unterschiede, ohne zu lesen.

   Zweitens die Ruhe. Alles, was nur manchmal gebraucht wird — Anschluss-
   preis, Routermiete, Produktinformationsblatt —, steht zugeklappt in
   einem details. Hundertmal untereinander wäre es eine Wand.

   Ohne JavaScript bleibt die Filterleiste verborgen (Regel unten): Sie
   hat kein Ziel, an das sie sich schicken könnte. Die Liste steht dann
   vollständig und nach Preis sortiert da.                              */

.tarif-filter { display: none; }
.js .tarif-filter {
  display: block;
  margin: 1.5rem 0 1.75rem;
  padding: 1.1rem 1.25rem .9rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--rundung-gross);
}

.filter-felder {
  display: flex; flex-wrap: wrap; gap: 1.1rem 2rem;
}

.filter-gruppe { min-width: 0; border: 0; padding: 0; margin: 0; }
.filter-gruppe legend,
.filter-sortierung label {
  padding: 0; margin-bottom: .4rem;
  font-family: var(--schrift-zahl); font-size: .66rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grau);
}
.filter-sortierung label { display: block; }
.filter-gruppe-breit { flex: 1 1 22rem; }

.filter-knoepfe { display: flex; flex-wrap: wrap; gap: .35rem; }

/* Die Knöpfe sind Beschriftungen um ein echtes Auswahlfeld. Das Feld
   selbst ist verborgen, aber vorhanden — Tastatur und Vorleseprogramm
   bedienen es wie jedes andere, und der Fokusring liegt auf dem Knopf. */
.filter-knopf {
  position: relative;
  display: inline-flex; align-items: center;
  padding: .32rem .7rem;
  border: 1px solid var(--linie);
  border-radius: 2rem;
  background: var(--grund);
  font-size: .84rem; line-height: 1.3;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.filter-knopf input {
  position: absolute; width: 1px; height: 1px;
  margin: 0; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden;
}
.filter-knopf abbr { text-decoration: none; }
.filter-knopf:hover { border-color: var(--leitung); }
.filter-knopf:has(input:checked) {
  background: var(--leitung);
  border-color: var(--leitung);
  color: var(--auf-leitung);
  font-weight: 500;
}
.filter-knopf:has(input:focus-visible) {
  outline: 2px solid var(--leitung-tief);
  outline-offset: 2px;
}

/* Browser ohne :has bekommen keinen gefärbten Knopf, sondern das
   Auswahlfeld selbst zu sehen — sichtbar, bedienbar, nur schmuckloser.
   Das ist der Rückfall, den diese Regel herstellt. */
@supports not selector(:has(*)) {
  .filter-knopf input {
    position: static; width: auto; height: auto;
    clip-path: none; margin-right: .4rem;
  }
}

/* Das Vorwahlfeld. Es steht als erstes in der Leiste, weil es als einziges
   entscheidet, welche Anbieter überhaupt zur Auswahl stehen: NetCologne in
   Köln, M-net in München. Die Zeile darunter sagt jederzeit, was die Eingabe
   gerade bewirkt. */
.filter-vorwahl { flex: 0 0 auto; }
.filter-vorwahl input {
  font: inherit; font-family: var(--schrift-zahl);
  width: 7rem; padding: .3rem .55rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
}
.filter-vorwahl input:focus-visible {
  outline: 2px solid var(--leitung-tief); outline-offset: 1px;
}
/* Die Orte zur Vorwahl. Sie stehen unter dem Feld und nicht daneben: Die
   Eingabe und ihre Bestätigung gehören übereinander, damit das Auge nicht
   springt. Ohne Skript ist die Liste leer und verborgen (hidden im Markup).

   Bis zum 2.9.2026 war das ein Auswahlfeld. Zugeklappt stand darin eine
   Kopfzeile, und welche Orte gemeint sind, sah nur, wer es aufklappte — die
   Bestätigung lag hinter einem Klick, den kaum jemand tut. Jetzt ist es eine
   Schicht: sichtbar, sobald die Vorwahl erkannt ist.

   Sie liegt über der Leiste und nicht darin. Im Fluss schöbe eine Liste von
   dreiunddreißig Orten — so viele hat 089 — die Filterknöpfe bei jedem
   Tastendruck um mehrere Zeilen nach unten. */
.vorwahl-orte {
  margin: .4rem 0 0; padding: .5rem .55rem;
  max-width: min(24rem, calc(100vw - 2rem));
  max-height: min(17rem, 55vh); overflow-y: auto;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
  box-shadow: 0 6px 24px rgb(0 0 0 / .16);
}
/* Wohin die Schicht gehört, rechnet das Skript aus: Das UA-Stylesheet stellt
   ein Popover mittig auf den Schirm, und dort steht diese Liste falsch. Kann
   der Browser kein Popover, bleibt sie eine gewöhnliche Aufzählung im Fluss
   unter dem Feld — sichtbar ist sie dann genauso. */
@supports selector(:popover-open) {
  .vorwahl-orte { position: fixed; inset: auto; margin: 0; }
}
.vorwahl-orte::backdrop { background: transparent; }
.vorwahl-orte[hidden] { display: none; }

.vorwahl-orte-kopf {
  margin: 0 0 .4rem;
  font-size: .74rem; color: var(--grau);
}
/* Nebeneinander und umbrechend: Ortsnamen sind kurz, und untereinander
   ergäbe 089 eine Spalte, durch die man scrollen müsste. */
.vorwahl-orte-liste {
  display: flex; flex-wrap: wrap; gap: .25rem;
  margin: 0; padding: 0; list-style: none;
}
/* Knöpfe und keine Verweise: Ein angetippter Ort führt nicht von der Seite
   weg, sondern verfeinert die Liste darunter auf die Anbieter, die dort
   schalten. Sie sehen deshalb aus wie die Filterknöpfe der Leiste und tragen
   im gedrückten Zustand dieselbe Farbe. */
.vorwahl-orte-liste button {
  display: block; padding: .18rem .45rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
  font: inherit; font-size: .84rem; line-height: 1.3;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.vorwahl-orte-liste button:hover {
  border-color: var(--leitung); color: var(--leitung-tief);
}
.vorwahl-orte-liste button[aria-pressed="true"] {
  background: var(--leitung); border-color: var(--leitung);
  color: var(--auf-leitung); font-weight: 500;
}
.vorwahl-orte-liste button:focus-visible {
  outline: 2px solid var(--leitung-tief); outline-offset: 1px;
}

/* Die Zeile zum gewählten Ort. Sie steht unter der Standzeile und sagt, was
   die Auswahl bewirkt; daneben führt der Weg auf die Ortsseite, der vorher an
   jedem einzelnen Namen hing. */
.vorwahl-ort {
  margin: .3rem 0 0; max-width: 22rem;
  font-size: .76rem; color: var(--grau); line-height: 1.35;
}
.vorwahl-ort[hidden] { display: none; }
.vorwahl-ort a { color: var(--leitung-tief); }
.ort-loesen {
  border: 0; padding: 0; background: none;
  font: inherit; color: var(--leitung-tief);
  text-decoration: underline; cursor: pointer;
}
.ort-loesen:focus-visible { outline: 2px solid var(--leitung-tief); outline-offset: 2px; }

.vorwahl-stand {
  margin: .3rem 0 0; max-width: 18rem;
  font-size: .76rem; color: var(--grau); line-height: 1.35;
}

/* Knopf und Hinweis stehen als Paar nebeneinander, damit der Umbruch sie
   nicht trennt. */
.filter-knopf-paar { display: inline-flex; align-items: center; gap: .15rem; }

/* Der Hinweis.

   Bis zum 2.9.2026 war das ein title-Attribut. Auf einem Telefon gibt es kein
   Überfahren mit der Maus, und damit war die Erklärung für den halben
   Besucherstrom nicht vorhanden. Jetzt ist es ein popover: Ein Tipp öffnet
   es, ein Tipp daneben schließt es, Escape auch, und der Browser legt es über
   alles andere, ohne dass ein z-index geraten werden müsste. */
.hinweis-knopf {
  display: inline-grid; place-items: center;
  width: 1.15rem; height: 1.15rem; padding: 0;
  border: 1px solid var(--linie); border-radius: 50%;
  background: var(--grund); color: var(--grau);
  font-family: var(--schrift-zahl); font-size: .62rem; font-weight: 600;
  font-style: italic; line-height: 1; cursor: pointer;
}
.hinweis-knopf:hover { border-color: var(--leitung); color: var(--leitung-tief); }
.hinweis-knopf:focus-visible { outline: 2px solid var(--leitung-tief); outline-offset: 1px; }

.hinweis {
  /* Der Hinweis steht am Knopf, nicht mittig auf dem Schirm: Das
     UA-Stylesheet zentriert ein Popover, und für einen Hinweis ist das
     falsch. Die Stelle rechnet das Skript aus, hier steht nur, dass er sich
     nicht selbst plaziert. */
  position: fixed;
  inset: auto;
  max-width: min(22rem, calc(100vw - 2rem));
  margin: 0;
  padding: .6rem .8rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
  box-shadow: 0 6px 24px rgb(0 0 0 / .16);
  font-size: .84rem; line-height: 1.45;
}
/* Kein abdunkelnder Grund mehr. Er gehoert zu einem Fenster, das eine
   Entscheidung verlangt; ein Hinweis, der schon beim Ueberfahren aufgeht,
   verlangt keine. */
.hinweis::backdrop { background: transparent; }

/* Der Schildknopf sieht aus wie das Schild daneben, ist aber bedienbar. Der
   Unterschied muss sichtbar sein, sonst tippt niemand darauf: die gepunktete
   Unterlinie ist das gewohnte Zeichen dafür. */
.schild-knopf {
  border: 0; padding: 0; background: none;
  font: inherit; color: inherit;
  text-decoration: underline dotted; text-underline-offset: .18em;
  cursor: pointer;
}
.schild-knopf:focus-visible { outline: 2px solid var(--leitung-tief); outline-offset: 2px; }

.filter-sortierung select {
  font: inherit; font-size: .86rem;
  padding: .3rem .5rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
}

.filter-stand {
  margin: .9rem 0 0; padding-top: .7rem;
  border-top: 1px solid var(--linie);
  font-size: .86rem; color: var(--grau);
}
.filter-stand output { font-family: var(--schrift-zahl); color: var(--tinte); }
.filter-zuruecksetzen {
  margin-left: .6rem;
  border: 0; background: none; padding: 0;
  font: inherit; font-size: .86rem; color: var(--leitung-tief);
  text-decoration: underline; cursor: pointer;
}

/* Die Liste. Auf breiten Schirmen eine Zeile je Tarif in fünf Spalten,
   auf schmalen gestapelt.

   Bis zum 1.9.2026 trug die Vorderkante die Hausfarbe des Anbieters. Sie ist
   weg: Fünf Farben, die sich über die Liste verteilen, gruppieren das Auge
   nach Marken, während die Liste nach Preis sortiert ist. Wer von oben nach
   unten liest, sah damit ein Muster, das nichts bedeutet. Welche Marke eine
   Zeile gehört, sagt das Logo links; die einzige Farbe, die hier noch etwas
   heißt, ist die der hervorgehobenen Zeile. */
.tarif-liste { list-style: none; margin: 0; padding: 0; }
.tarif-liste li[hidden] { display: none; }

.tarif-zeile {
  display: grid; gap: .5rem 1.2rem;
  grid-template-columns: minmax(12rem, 1.7fr) 7rem 9rem minmax(8rem, 1fr) auto;
  grid-template-areas:
    "kopf tempo preis merkmale knopf"
    "mehr mehr  mehr  mehr     mehr";
  align-items: start;
  padding: .95rem 1.1rem;
  border: 1px solid var(--linie);
  border-radius: var(--rundung);
  background: var(--grund);
}
.tarif-zeile + .tarif-zeile { margin-top: .5rem; }

.tarif-kopf { grid-area: kopf; display: flex; align-items: center; gap: .7rem; }
.tarif-bezeichnung { min-width: 0; }
.tarif-kopf .anbieter-marke { width: 2.6rem; height: 2.6rem; }
.tarif-kopf .anbieter-marke.hat-logo { width: 5rem; height: 2.6rem; padding: .3rem .4rem; }

.tarif-anbieter {
  margin: 0;
  font-family: var(--schrift-zahl); font-size: .68rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; color: var(--grau);
}
.tarif-anbieter .hervor-schild { display: inline; margin-left: .5rem; }
.tarif-regional {
  margin-left: .5rem; color: var(--grau); font-weight: 400;
  letter-spacing: .06em;
}
.tarif-zeile .tarif-name { margin: .1rem 0 0; font-size: 1.02rem; font-weight: 600; }
.tarif-anschlussart { margin: .1rem 0 0; color: var(--grau); font-size: .8rem; }

/* Tempo und Preis: dieselbe Bauart, damit beide Spalten gleich aussehen
   und sich vertikal lesen lassen. */
.tarif-zeile .tarif-tempo,
.tarif-preis { grid-area: tempo; margin: 0; line-height: 1.25; }
.tarif-preis { grid-area: preis; }
.tarif-zeile .tarif-tempo .zahl,
.tarif-preis .zahl {
  font-family: var(--schrift-zahl); font-size: 1.3rem; font-weight: 500;
  display: block;
}
.tarif-zeile .tarif-tempo .einheit,
.tarif-preis .einheit { font-size: .78rem; color: var(--grau); }
.tarif-zeile .tarif-tempo .klein,
.tarif-preis .klein { display: block; font-size: .76rem; color: var(--grau); }

.tarif-merkmale {
  grid-area: merkmale;
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .25rem;
}
.tarif-merkmale li {
  padding: .1rem .45rem;
  border: 1px solid var(--linie);
  border-radius: 2rem;
  background: var(--flaeche);
  font-size: .72rem; color: var(--grau);
}

/* Das Bonusschild trägt als einziges einen Betrag, den man geschenkt bekommt.
   Es ist deshalb das einzige farbige in der Zeile: Wer die Liste überfliegt,
   soll die Gutschriften finden, ohne jede Zeile zu lesen. */
.tarif-merkmale .schild-bonus {
  border-color: var(--leitung);
  background: var(--leitung-zart);
  color: var(--leitung-tief);
  font-weight: 600;
}
/* Kein white-space: nowrap mehr. Auf den Schildern steht seit dem 1.9.2026
   die ganze Angabe statt eines Stichworts, und "100 € Routergutschrift bei
   Routermiete" in einer Zeile sprengt die Spalte auf jedem zweiten Schirm. */

.tarif-knopf { grid-area: knopf; align-self: center; }

/* Der Aufklapper ist ohne JavaScript verborgen: Sein Inhalt entsteht erst
   beim Aufklappen (siehe assets/js/tarifvergleich.js), und einer, der sich
   leer öffnet, ist schlimmer als keiner. Dieselbe Entscheidung wie bei der
   Filterleiste. Wie gerechnet wird, steht dann unter der Liste und in den
   häufigen Fragen. */
.tarif-mehr { display: none; }
/* Die ersten Zeilen tragen ihre Einzelheiten im Markup und stehen deshalb
   auch ohne JavaScript offen. Die übrigen entstehen beim Aufklappen, und
   einer, der sich leer öffnet, ist schlimmer als keiner. */
.js .tarif-mehr,
.tarif-mehr-statisch { display: block; grid-area: mehr; font-size: .88rem; }
.tarif-daten-fehlt { margin: .5rem 0 0; color: var(--grau); }
.tarif-mehr summary {
  cursor: pointer; color: var(--grau); font-size: .78rem;
  list-style: none; padding: .15rem 0;
}
.tarif-mehr summary::-webkit-details-marker { display: none; }
.tarif-mehr summary::before {
  content: "›"; display: inline-block; margin-right: .35rem;
  transition: transform .15s ease;
}
.tarif-mehr[open] summary::before { transform: rotate(90deg); }
.tarif-mehr summary:hover { color: var(--leitung-tief); }
.tarif-mehr .tarif-daten {
  grid-template-columns: max-content minmax(0, 1fr);
  margin-top: .5rem; padding-top: .6rem;
}

/* Die Rechnung hinter dem Effektivpreis. Die Betraege stehen rechtsbuendig
   untereinander in der Zahlenschrift, damit sich die Spalte addieren laesst,
   ohne sie zu lesen. Die Summenzeile traegt einen Strich darueber, wie auf
   einem Beleg. */
.tarif-rechnung { margin-bottom: .2rem; }
.tarif-rechnung dd { font-family: var(--schrift-zahl); }
.tarif-rechnung .tarif-summe {
  margin-top: .35rem; padding-top: .35rem;
  border-top: 1px solid var(--linie);
  font-weight: 600;
}
/* Was unter dem Strich steht, gehoert nicht in die Summe. Die blassere
   Schrift sagt das, bevor jemand den Text liest. */
.tarif-rechnung .tarif-nachrichtlich {
  margin-top: .3rem;
  color: var(--grau); font-weight: 400; font-size: .95em;
}

/* Die eine hervorgehobene Zeile (aid und tid im Block vergleich in
   src/_data/hervorhebung.js — die Ortsseiten steuert der andere Block).
   Sie ist jetzt die einzige farbige Zeile der Liste und braucht deshalb
   keinen kräftigen Ton: getönter Untergrund und eine Kante genügen. Das
   Schild daneben sagt, warum sie oben steht. */
.tarif-zeile.hervor {
  background: var(--leitung-zart);
  border-color: var(--leitung);
  /* Die Kante als Schatten nach innen, nicht als dickerer Rahmen: Ein Rahmen
     von 3 statt 1 Pixel schöbe den Inhalt dieser einen Zeile um zwei Pixel
     gegen alle anderen. Dieselbe Bauart wie bei .tarif-tabelle tr.hervor. */
  box-shadow: inset 3px 0 0 var(--leitung);
}

/* Der Knopf unter der Liste. Still gesetzt: Er ist ein Weiterlesen und kein
   Angebot, und neben zwanzig grünen Tarifknöpfen wäre ein einundzwanzigster
   nur Lärm. */
.tarif-mehr-zeigen { margin: 1.1rem 0 0; text-align: center; }
.tarif-mehr-zeigen[hidden] { display: none; }
.knopf-still {
  background: var(--grund); color: var(--leitung-tief);
  border: 1px solid var(--linie);
}
.knopf-still:hover { border-color: var(--leitung); background: var(--flaeche); }

.tarif-leer {
  margin: 1.5rem 0; padding: 1.1rem 1.3rem;
  background: var(--flaeche); border-left: 3px solid var(--leitung);
  border-radius: 0 var(--rundung) var(--rundung) 0;
}
.tarif-leer[hidden] { display: none; }

@media (max-width: 68rem) {
  .tarif-zeile {
    grid-template-columns: 1fr 7rem 9rem;
    grid-template-areas:
      "kopf     tempo preis"
      "merkmale merkmale knopf"
      "mehr     mehr  mehr";
  }
  .tarif-knopf { align-self: end; justify-self: end; }
}

@media (max-width: 44rem) {
  .tarif-zeile {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "kopf     kopf"
      "tempo    preis"
      "merkmale merkmale"
      "mehr     mehr"
      "knopf    knopf";
  }
  .tarif-knopf { justify-self: stretch; text-align: center; }
  .filter-felder { gap: 1rem 1.4rem; }
}

/* Der Hinweis auf die Ortsseiten steht bewusst zwischen Tabelle und
   Ratgeber: die bundesweite Liste sagt nichts darüber, was am eigenen
   Anschluss ankommt. */
.ortshinweis {
  background: var(--flaeche);
  border-left: 3px solid var(--leitung);
  padding: 1.1rem 1.3rem;
  border-radius: 0 var(--rundung) var(--rundung) 0;
}
.ortshinweis p { margin: 0; }

.ratgeber h3 { margin-top: 2rem; font-size: 1.15rem; }
.ratgeber p, .ratgeber ul { max-width: 64ch; }
.ratgeber-knopf { margin: 1.6rem 0 2.2rem; }

/* Die Abschnitte des Ratgebers stehen ab Tabletbreite zweispaltig, wie schon
   auf der Vorgängerseite. Zwei feste Spalten im Markup müssten von Hand
   ausbalanciert werden und würden auf schmalen Schirmen die Reihenfolge
   verwürfeln — hier fließt der Text stattdessen durch zwei Spalten, und die
   Blöcke bleiben dabei ungeteilt. */
.ratgeber-block { break-inside: avoid; }
.ratgeber-block h3 { margin-top: 0; }
.ratgeber-block > :last-child { margin-bottom: 0; }
.ratgeber-block + .ratgeber-block { margin-top: 2rem; }

/* Die beiden Bilder der Altseite. Sie erklären nichts, sie lockern die
   Spalten auf — deshalb stehen sie unter der Überschrift und nicht zwischen
   zwei Absätzen, die zusammengehören. */
.ratgeber-bild {
  display: block; width: 100%; height: auto;
  margin: .2rem 0 1rem;
  border: 1px solid var(--linie);
  border-radius: var(--rundung);
  background: var(--grund);
}

@media (min-width: 60rem) {
  .ratgeber-spalten { columns: 2; column-gap: 3.5rem; }
  .ratgeber-spalten .ratgeber-block + .ratgeber-block { margin-top: 0; }
  /* Im Spaltensatz trägt jeder Block seinen Abstand selbst: der Rand zwischen
     zwei Blöcken darf nicht am Spaltenanfang stehen bleiben. */
  .ratgeber-spalten .ratgeber-block { margin-bottom: 2rem; }
  .ratgeber-spalten p, .ratgeber-spalten ul { max-width: none; }
}

/* --- Häufige Fragen -----------------------------------------------
   Aufklappbar, damit die Liste als Liste lesbar bleibt; der Text steht
   trotzdem im Dokument und wird gefunden.                          */

/* Die Liste läuft über die ganze Breite, wie der Ratgeber darüber und die
   Tarifliste darüber. Die Antworten behalten ihr Zeilenmaß (.faq-eintrag p),
   die Fragen sind einzeilig und vertragen die Breite. */
.faq-liste {
  border-top: 1px solid var(--linie);
}
.faq-eintrag { border-bottom: 1px solid var(--linie); }
.faq-eintrag summary {
  display: flex; align-items: baseline; gap: .7rem;
  padding: .85rem 0;
  cursor: pointer;
  font-family: var(--schrift-display); font-stretch: 106%;
  font-weight: 600; font-size: 1.02rem;
  list-style: none;
}
.faq-eintrag summary::-webkit-details-marker { display: none; }
/* Das Zeichen davor dreht sich beim Aufklappen — ein zweites Element
   dafür braucht es nicht. */
.faq-eintrag summary::before {
  content: "›"; flex: none;
  color: var(--leitung); font-size: 1.1rem; line-height: 1;
  transform: translateY(.1em);
  transition: transform .18s ease;
}
.faq-eintrag[open] summary::before { transform: translateY(.1em) rotate(90deg); }
.faq-eintrag summary:hover { color: var(--leitung-tief); }
.faq-eintrag p {
  margin: 0 0 1rem; padding-left: 1.4rem;
  max-width: 64ch; color: var(--grau);
}

/* --- Rechtliches ------------------------------------------------------ */

/* <address> steht per Vorgabe kursiv. Eine Anschrift ist keine Betonung. */
.anschrift {
  font-style: normal;
  margin: 0 0 1rem;
  font-size: 1.05rem;
}

/* --- Hilfsklassen ---------------------------------------------------- */

.visually-hidden, .visuell-versteckt {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- Ortssuche ---------------------------------------------------
   Das Feld erscheint nur, wenn JavaScript läuft: ohne Server gibt es
   keine Ergebnisseite, ein abschickbares Formular führte ins Leere.
   Dieselbe Regel wie beim Menü — sichtbar erst mit Skript.

   Es steht als eigener Kasten da und nicht als Zeile im Fließtext. Ein
   Eingabefeld mit haarfeiner Kante geht auf diesem hellen Grund unter,
   und wer es nicht sucht, sieht es gar nicht: die Suche ist aber der
   kürzeste Weg zu einer von 4.090 Seiten und soll den Blick auf sich
   ziehen. Der Kasten liegt auf Karton, das Feld darin auf Papier — es
   ist damit die hellste Fläche und die einzige mit kräftiger Kante. */

.ortsuche { display: none; }
.js .ortsuche { display: block; margin: 1.75rem 0 2.5rem; }

.ortsuche-kasten {
  max-width: 40rem;
  padding: 1.15rem 1.25rem 1rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--rundung-gross);
}

.ortsuche-schild {
  display: block; margin-bottom: .55rem;
  font-family: var(--schrift-display);
  font-size: 1.05rem; font-weight: 600; color: var(--tinte);
  cursor: pointer;
}

/* Bezugspunkt für Lupe und Trefferliste: beide sollen sich am Feld
   ausrichten, nicht am Kasten mit seinem Innenabstand. */
.ortsuche-eingabe { position: relative; display: block; }

.ortsuche-lupe {
  position: absolute; left: .85rem; top: 50%;
  transform: translateY(-50%);
  width: 1.15rem; height: 1.15rem;
  color: var(--leitung); pointer-events: none;
}

.ortsuche input {
  width: 100%; box-sizing: border-box;
  padding: .8rem 1rem .8rem 2.7rem;
  font-family: var(--schrift-text); font-size: 1.1rem;
  color: var(--tinte); background: var(--grund);
  border: 1px solid #c4c4c4; border-radius: var(--rundung);
  transition: box-shadow .15s ease, border-color .15s ease;
}
.ortsuche input::placeholder { color: var(--grau); opacity: .85; }
.ortsuche input:hover { box-shadow: 0 0 0 3px var(--leitung-zart); }
.ortsuche input:focus {
  outline: none;
  border-color: var(--leitung);
  box-shadow: 0 0 0 3px var(--leitung-zart);
}
/* Das Kreuzchen, das Safari und Chrome in ein Suchfeld setzen, sitzt in
   dieser Schriftgröße zu dicht am Rand und trägt nichts bei: Escape und
   die Rücktaste leeren das Feld ohnehin. */
.ortsuche input::-webkit-search-decoration,
.ortsuche input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* Die Fassung im Seitenkopf: ein Feld, sonst nichts. Sie steht als drittes
   Glied in der Kopfzeile und rutscht auf schmalen Schirmen unter Wortmarke
   und Menü, weil .kopf-inhalt umbricht. */
.ortsuche-kompakt { flex: 1 1 13rem; max-width: 20rem; }
.js .ortsuche-kompakt { display: block; }
.ortsuche-kompakt .ortsuche-kasten { padding: 0; border: 0; background: none; }
.ortsuche-kompakt .ortsuche-lupe { width: 1rem; height: 1rem; color: var(--grau); }

/* Im Kopf steht das Feld neben Wortmarke und Menue und muss zweierlei
   zugleich: auffallen genug, dass man es sucht und findet, und leise genug,
   dass es der Wortmarke nicht die Schau stiehlt. Deshalb kein Rahmen mit
   Kontrast, sondern ein zart getoenter Grund — ein gefuelltes Feld liest
   sich als "hier kann ich etwas eintragen", ein Kaestchen mit Haarlinie
   nicht.

   Die Pillenform ist keine neue Erfindung: Die Filterschilder auf der
   Vergleichsseite tragen dieselbe (border-radius: 2rem). Im Kopf sagt sie
   ausserdem auf einen Blick "Suche", ohne dass ein Wort dabeistehen muss. */
.ortsuche-kompakt .ortsuche-lupe { left: .8rem; }
.ortsuche-kompakt input {
  padding: .46rem 1rem .46rem 2.35rem;
  font-size: .9rem;
  background: #f3f7fa;
  border-color: #d3dee6;
  border-radius: 2rem;
}
.ortsuche-kompakt input::placeholder { color: var(--grau); opacity: .8; }

/* Beim Zeigen und Schreiben wird der Grund weiss: Das Feld tritt aus der
   Kopfzeile heraus, solange es benutzt wird, und danach wieder zurueck.
   Die Lupe faerbt sich mit, damit die Bewegung zusammengehoert. */
.ortsuche-kompakt input:hover {
  background: var(--grund);
  border-color: #b9c9d6;
  box-shadow: none;
}
.ortsuche-kompakt input:focus {
  background: var(--grund);
  border-color: var(--leitung);
  box-shadow: 0 0 0 3px var(--leitung-zart);
}
.ortsuche-kompakt:focus-within .ortsuche-lupe { color: var(--leitung); }

@media (max-width: 56rem) {
  /* Unter der Wortmarke, über den Inhalt. Ganze Breite, weil daneben nichts
     mehr steht. */
  .ortsuche-kompakt { flex-basis: 100%; max-width: none; order: 3; }
}

.ortsuche-hinweis {
  margin: .6rem 0 0;
  font-size: .82rem; color: var(--grau);
}

/* Die Vorschlagsliste liegt über dem Text darunter, statt ihn beim
   Tippen wegzuschieben — sonst wanderte die Seite bei jedem Buchstaben. */
.ortsuche-liste {
  position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + .3rem);
  list-style: none; margin: 0; padding: .25rem;
  max-height: 22rem; overflow-y: auto;
  background: var(--grund);
  border: 1px solid var(--linie); border-radius: var(--rundung);
  box-shadow: 0 .6rem 1.6rem rgb(0 0 0 / .14);
}
.ortsuche-liste[hidden] { display: none; }

.ortsuche-liste li a {
  display: flex; align-items: baseline; gap: .6rem;
  padding: .5rem .65rem; border-radius: .35rem;
  color: var(--tinte); text-decoration: none;
}
.ortsuche-liste li.an a,
.ortsuche-liste li a:hover { background: var(--leitung-zart); }

.ortsuche-name { font-weight: 500; }
.ortsuche-name b { font-weight: 700; color: var(--leitung-tief); }
.ortsuche-zusatz {
  margin-left: auto; text-align: right;
  font-size: .78rem; color: var(--grau);
}

.ortsuche-leer {
  padding: .55rem .65rem;
  font-size: .9rem; color: var(--grau);
}

/* Auf schmalen Schirmen darf der Kasten den ganzen Platz nehmen; der
   Innenabstand schrumpft, damit das Feld selbst breit bleibt. */
@media (max-width: 32rem) {
  .ortsuche-kasten { padding: 1rem .9rem .85rem; }
  .ortsuche input { font-size: 1.05rem; }
}

/* Der Suchblock am Fuß der Ortsseiten. Dort ist die Suche ein Angebot
   unter anderen und nicht der Einstieg — die <h2> darüber ordnet sie in
   die Seite ein, die Beschriftung im Kasten sagt, was hineingehört. */
.ort-suche-block { margin-block: 2.5rem; }
.ort-suche-block .ortsuche { margin-top: 1rem; }

/* ===============================================================
   Fehlerseite 404

   Wer hier landet, kommt fast immer von aussen und sucht etwas
   Bestimmtes. Die Seite ist deshalb kurz: eine Ueberschrift, drei
   Wege und das Suchfeld — in aller Regel war eine Gemeinde gesucht,
   und dann ist die Suche die Antwort und nicht die Entschuldigung.
   =============================================================== */

.fehler-kopf { padding-block: .5rem 1.6rem; max-width: 40rem; }

.fehler-wege {
  list-style: none; padding: 0; margin: 0 0 1rem;
  display: grid; gap: .45rem;
}
.fehler-wege a { font-weight: 500; }

/* ===============================================================
   Der Ausbau vor Ort

   Die Liste steht auf jeder Ortsseite ueber allem anderen und ist der
   Teil, den es hier gibt und auf einer reinen Tarifseite nicht: je
   Anschlussart die hoechste Bandbreite, die der Breitbandatlas fuer
   diese Gemeinde ausweist.

   Drei Spalten, und die mittlere traegt die Zahl in der Zahlenschrift,
   rechtsbuendig. So stehen die drei Werte im Blick untereinander und
   lassen sich vergleichen, ohne sie zu lesen. Eine Art, die nicht
   ausgebaut ist, bekommt einen Strich und wird blass — sie bleibt
   stehen, weil ihr Fehlen die Auskunft ist.
   =============================================================== */

.ausbau-liste { list-style: none; padding: 0; margin: 0; }

.ausbau-zeile {
  display: grid;
  grid-template-columns: 7.5rem minmax(6rem, max-content) 1fr;
  gap: .2rem 1.5rem;
  align-items: baseline;
  padding: .75rem 0;
  border-bottom: 1px solid var(--linie-zart);
}
.ausbau-zeile:first-child { border-top: 1px solid var(--linie); }

.ausbau-art { font-weight: 600; }

.ausbau-wert {
  font-family: var(--schrift-zahl); font-size: 1.15rem; font-weight: 500;
  text-align: right; white-space: nowrap;
}
.ausbau-wert .einheit {
  margin-left: .35rem;
  font-size: .7rem; font-weight: 400; letter-spacing: .06em;
  color: var(--grau);
}

.ausbau-satz { color: var(--grau); font-size: .86rem; }

/* Nicht ausgebaut: der Strich steht, die Zeile tritt zurueck. */
.ausbau-fehlt .ausbau-art,
.ausbau-fehlt .ausbau-wert { color: var(--grau); font-weight: 400; }

@media (max-width: 34rem) {
  .ausbau-zeile { grid-template-columns: 1fr max-content; }
  .ausbau-satz { grid-column: 1 / -1; }
  .ausbau-wert { text-align: right; }
}

/* --- Anbieter und Tarif in einer Spalte ---------------------------
   Die Tabelle kommt mit vier Spalten aus, weil Anbieter und Tarifname
   zusammen in einer stehen (der Grund dafuer steht in ort.njk). Der
   Anbietername ist dabei nicht ausgezeichnet — er steht vorn, und das
   genuegt.                                                        */

.tarif-zelle { min-width: 14rem; }
.tarif-name { display: block; font-weight: 500; }

/* Das Markenfeld in der Tarifzeile einer Ortsseite. Es steht nur an den
   provisionierten Zeilen (siehe ort.njk); die uebrigen beginnen beim Namen,
   statt einen leeren Kasten davorzustellen. Der innere Kasten traegt das
   Flex-Layout, damit die Tabelle ihre Spaltenbreiten behaelt. */
.tarif-zelle-innen { display: flex; align-items: flex-start; gap: .55rem; }
.tarif-zelle-text { display: block; }
.tarif-zelle .anbieter-marke { width: 2rem; height: 2rem; }
.tarif-zelle .anbieter-marke.hat-logo {
  width: 3.6rem; height: 2rem;
  padding: .15rem .25rem;
}

/* ===============================================================
   Startseite

   Kein Aufmacherbild und keine drei gleich grossen Kacheln: oben die
   Frage und das Suchfeld, darunter die zwei Wege in den Bestand, ganz
   unten der Absatz, der erklaert, warum der Ausbau vor dem Tarif
   steht. Wer die Seite kennt, tippt oben und ist weg.
   =============================================================== */

/* Die beiden Einstiege nebeneinander: links die Frage nach dem Ausbau, rechts
   die nach dem Preis. Bis zum 2.9.2026 stand der Kopf allein in einer Spalte
   von vierzig Zeichen, und die rechte Hälfte des Schirms blieb leer, während
   das Tarifformular unterhalb der Falz wartete.

   Unter 62rem fallen sie untereinander, in derselben Reihenfolge: erst der
   Ausbau, dann der Tarif. Das ist die Gliederung der ganzen Seite, und ein
   Umbruch soll sie nicht umdrehen. */
.start-einstieg {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem 2.5rem;
  align-items: start;
}
@media (min-width: 62rem) {
  .start-einstieg { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

.start-kopf {
  max-width: 40rem;
  padding-block: .5rem 1rem;
}
.start-kopf .anriss { margin-bottom: 1.75rem; }

.weg-liste {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
}
.weg {
  padding: 1.1rem 1.25rem 1.25rem;
  border: 1px solid var(--linie);
  border-left: 3px solid var(--leitung);
  border-radius: var(--rundung);
  background: var(--grund);
}
.weg h3 { margin: 0 0 .4rem; font-size: 1.1rem; }
.weg h3 a { text-decoration: none; }
.weg h3 a:hover { text-decoration: underline; }
.weg p { margin: 0; color: var(--grau); font-size: .92rem; }

.start-erklaerung p + p { margin-top: 1rem; }

/* Der Absatz unter den vier Kaesten fuehrt weiter, er ist kein Nachklapp:
   deshalb derselbe Abstand wie ueber ihnen. */
.start-technik .weg-liste + .mass { margin-top: 1.5rem; }

/* ===============================================================
   Anbieterseiten und Ratgeber
   ---------------------------------------------------------------
   Die Adressen /telekom/, /kabelinternet/, /ratgeber/… gab es unter
   dieser Domain schon zu WordPress-Zeiten. Was hier neu ist, ist
   nicht der Bereich, sondern dass seine Zahlen aus den Daten
   kommen. Das Aussehen folgt deshalb dem, was es schon gibt: die
   Anbieterblöcke und Tarifkarten der Vergleichsseite werden
   unveraendert weiterverwendet, hier steht nur, was dort fehlt.
   =============================================================== */

/* Die Eckdaten unter dem Markenfeld einer Anbieterseite. Vier
   Angaben nebeneinander, die auf schmalen Schirmen zu zweien
   umbrechen — untereinander waeren es vier fast leere Zeilen. */
.anbieter-eckdaten {
  display: grid; gap: 1rem 1.5rem; margin: 0 -1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  padding: 1.15rem 1.25rem;
  border-top: 1px solid var(--linie);
}
.anbieter-eckdaten > div { margin: 0; }
.anbieter-eckdaten dt {
  font-size: .74rem; font-weight: 500; color: var(--grau);
  letter-spacing: .04em; text-transform: uppercase;
}
.anbieter-eckdaten dd {
  margin: .2rem 0 0; font-size: 1rem; color: var(--tinte);
}
.anbieter-eckdaten .zahl {
  font-family: var(--schrift-zahl); font-size: 1.15rem; font-weight: 500;
}

/* Der redaktionelle Teil. Er ist Fliesstext und bekommt deshalb die
   Zeilenlaenge, die sich lesen laesst — nicht die volle Breite des
   Anbieterblocks darueber. */
.anbieter-text { margin-top: 2.5rem; }
.anbieter-text h2:first-child { margin-top: 0; }
.anbieter-text p, .anbieter-text ul, .anbieter-text ol { max-width: 68ch; }

.anbieter-seite > .tarife { margin-top: 2.5rem; }

/* Die Uebersicht /anbieter/. Dieselben Bloecke wie auf der
   Vergleichsseite, aber ohne Tarifkarten — hier steht je Marke nur,
   was sie ist und wohin es weitergeht.

   Der Name lautet "marken-liste" und nicht "anbieter-liste": Letzteres
   ist schon vergeben, und zwar an die Aufzaehlung der Anbieternamen auf
   den Ortsseiten. Zwei Bedeutungen unter einem Klassennamen sind der
   Anfang eines Fehlers, den niemand sucht. */
.marken-liste {
  display: grid; gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
}

/* Der Anbieterblock der Vergleichsseite scheidet sich vom naechsten durch
   einen Strich oben — untereinander reicht das. Nebeneinander in einem
   Raster reicht es nicht: Dort braucht jeder Block einen eigenen Rand,
   sonst schwimmen sie ineinander. Die Hausfarbe sitzt als Oberkante am
   Rahmen, wie an den Tarifkarten auch.

   Dasselbe gilt fuer den Kopfblock einer einzelnen Anbieterseite: Er
   traegt darunter die Eckdaten und ist damit eine Karte, kein Absatz. */
.marken-liste .anbieter-block,
.anbieter-seite > .anbieter-block {
  display: flex; flex-direction: column;
  margin-block: 0;
  padding: 1.25rem 1.25rem 0;
  border: 1px solid var(--linie);
  border-top: 3px solid var(--marke);
  border-radius: var(--rundung);
  background: var(--grund);
}
/* Die Ausnahme fuer den ersten Block gilt nur untereinander. */
.marken-liste .anbieter-block:first-of-type,
.anbieter-seite > .anbieter-block:first-of-type {
  padding-top: 1.25rem;
  border-top: 3px solid var(--marke);
}
.marken-liste .anbieter-kopf,
.anbieter-seite > .anbieter-block .anbieter-kopf { margin-bottom: 1.15rem; }

/* Auf der Startseite tragen die Felder nichts unter dem Kopf — dann darf
   die Polsterung unten auch nicht fehlen. */
.start-anbieter .anbieter-kopf { margin-bottom: 0; }
.start-anbieter .marken-liste .anbieter-block { padding-bottom: 1.25rem; }

.anbieter-anriss {
  margin: auto 0 0; padding-bottom: 1.25rem;
  color: var(--grau); font-size: .92rem;
}
.anbieter-anriss a { white-space: nowrap; }
.marken-liste .anbieter-kopf h2,
.marken-liste .anbieter-kopf h3 { margin: 0; font-size: 1.15rem; }
.marken-liste .anbieter-kopf h2 a,
.marken-liste .anbieter-kopf h3 a { text-decoration: none; }
.marken-liste .anbieter-kopf h2 a:hover,
.marken-liste .anbieter-kopf h3 a:hover { text-decoration: underline; }

/* Das Verzeichnis unter /ratgeber/. Sieben Karten mit Bild — die
   Bilder stammen von der Vorgaengerseite und sind der Grund, warum
   hier Karten stehen und keine Liste: ohne sie waere es eine Liste
   von sieben Zeilen, mit ihnen ist es ein Verzeichnis, in dem man
   das Gesuchte sieht. */
.themen-liste {
  display: grid; gap: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}
.themen-karte { min-width: 0; }
.themen-karte h2 { margin: .75rem 0 .35rem; font-size: 1.1rem; }
.themen-karte h2 a { text-decoration: none; }
.themen-karte h2 a:hover { text-decoration: underline; }
.themen-karte p { margin: 0; color: var(--grau); font-size: .92rem; }

.themen-bild {
  display: block; overflow: hidden;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--flaeche);
}
.themen-bild img {
  display: block; width: 100%; height: 11rem;
  object-fit: cover;
}

/* Bilder im Fliesstext der Ratgeber- und Themenseiten.

   Sie stammen aus der WordPress-Zeit und haben nichts gemeinsam: 225 bis
   929 Pixel breit, Seitenverhaeltnisse von 0,59 (ein Schirmbild im
   Hochformat) bis 2,75 (ein breiter Streifen). Laesst man jedes Bild seine
   eigene Groesse bestimmen, steht auf derselben Seite eine Briefmarke neben
   einem Bild, das die Spalte sprengt — und ein Hochformat, das neben dem
   Text nach unten davonlaeuft und in den naechsten Abschnitt ragt.

   Deshalb gibt hier nicht das Bild den Platz vor, sondern der Platz das
   Bild: Jedes fuellt einen Rahmen mit festem Seitenverhaeltnis und wird
   darin beschnitten. Was wegfaellt, ist Rand — diese Bilder illustrieren,
   sie zeigen nichts, worauf es im Einzelnen ankaeme.

   Fuer Schirmbilder gilt das Gegenteil, siehe .schirmbild weiter unten. */
main figure {
  margin: 1.75rem 0;
  max-width: 26rem;
}
main figure img {
  display: block;
  /* height: auto ist hier nicht Kosmetik, sondern Bedingung: Die
     width- und height-Attribute im Markup wirken als Vorgabe. Bleibt
     height stehen, sind beide Masse fest, und aspect-ratio wird
     stillschweigend uebergangen — die Regel steht da und tut nichts. */
  width: 100%; height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center;
  background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--rundung);
}
main figcaption {
  margin-top: .5rem;
  color: var(--grau); font-size: .85rem;
}

/* "ganz": Bilder, die nicht beschnitten werden duerfen.

   Zwei Faelle. Schirmbilder — ein Routermenue, ein Windows-Dialog, eine
   Meldung auf dem Telefon — leben von den Einzelheiten, die der Beschnitt
   wegnaehme; und sie muessen gross genug stehen, um lesbar zu sein, also
   nicht in einem Rahmen von sechsundzwanzig rem. Der zweite Fall ist die
   Rundstrahlantenne: ein duenner Stab vor weissem Grund, dem ein Schnitt
   auf 3:2 Spitze und Fuss nimmt.

   Beide behalten deshalb ihr eigenes Seitenverhaeltnis und ihre eigene
   Groesse — hoechstens so breit wie die Spalte, hoechstens so hoch, dass
   ein Hochformat nicht davonlaeuft, und nie ueber die eigene Aufloesung
   hinaus vergroessert: aus einem 300 Pixel breiten Bild wird durch
   Aufblasen keines. */
main figure.ganz { max-width: none; }
main figure.ganz img {
  width: auto; height: auto;
  max-width: 100%; max-height: 26rem;
  aspect-ratio: auto;
  object-fit: contain;
  padding: .4rem;
}

@media (min-width: 52rem) {
  /* "bild-rechts" laesst den Text daneben laufen — auf schmalen Schirmen
     nicht, dort blieben vom Absatz drei Woerter je Zeile uebrig. */
  main .bild-rechts {
    float: right; clear: right;
    width: 19rem; margin: .35rem 0 1.25rem 2rem;
  }
  /* Ueberschriften duerfen nicht neben dem Bild anfangen — sonst rutscht
     die Gliederung der Seite in eine Spalte, die es nicht gibt. */
  main h2 { clear: both; }
}

/* --- Startseite: Zahlenband, Staedte, Laender ---------------------
   Die Abschnitte kamen dazu, als der Anbieter- und der Ratgeberbereich
   entstanden: Eine Startseite, die auf die Haelfte der Seite nicht
   verweist, ist keine.                                             */

/* Der zweite Einstieg auf der Startseite: das Kurzformular zum Vergleich.
   Es steht im selben Kasten wie die Ortssuche darüber, damit beide als das
   erkennbar sind, was sie sind — zwei Wege in denselben Bestand. */
/* Im zweispaltigen Kopf trägt das Raster den Abstand, nicht der Rand — sonst
   stünde die rechte Spalte tiefer als die linke. */
.start-tarife { margin-block: 2.5rem; }
.start-einstieg > .start-tarife { margin-block: .5rem 1rem; }
.tarif-kurzform {
  padding: 1.1rem 1.25rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--rundung-gross);
}
.kurzform-felder { display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: flex-start; }
.kurzform-feld { margin: 0; border: 0; padding: 0; min-width: 0; }
/* Die Überschrift eines Feldes. Nicht die Knöpfe darunter: Die Merkmale sind
   ebenfalls <label>, und ohne diese Ausnahme trugen sie bis zum 2.9.2026 die
   Schrift der Überschrift und deren display: block — drei versperrte Balken
   in Großbuchstaben statt drei Pillen zum Antippen. */
.kurzform-feld > label:not(.filter-knopf),
.kurzform-feld > legend {
  display: block; padding: 0; margin-bottom: .35rem;
  font-family: var(--schrift-zahl); font-size: .66rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--grau);
}
.kurzform-feld input[type="text"],
.kurzform-feld select {
  font: inherit; font-size: .9rem;
  padding: .35rem .55rem;
  border: 1px solid var(--linie); border-radius: var(--rundung);
  background: var(--grund); color: var(--tinte);
}
.kurzform-feld input[type="text"] { width: 8rem; font-family: var(--schrift-zahl); }
.kurzform-feld input:focus-visible,
.kurzform-feld select:focus-visible {
  outline: 2px solid var(--leitung-tief); outline-offset: 1px;
}
.kurzform-hinweis {
  display: block; margin-top: .3rem; max-width: 14rem;
  font-size: .74rem; color: var(--grau); line-height: 1.35;
}
.kurzform-haken { flex: 1 1 18rem; }
.kurzform-haken .filter-knopf { margin-right: .35rem; margin-bottom: .35rem; }

.kurzform-los {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem;
  margin: 1rem 0 0; padding-top: .9rem;
  border-top: 1px solid var(--linie);
}
.kurzform-fuss { font-size: .78rem; color: var(--grau); max-width: 34ch; }

.start-zahlen { margin-block: 2.5rem; }
.zahlenband {
  display: grid; gap: 1px; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  background: var(--linie);
  border: 1px solid var(--linie);
  border-radius: var(--rundung);
  overflow: hidden;
}
.zahlenband > div {
  margin: 0; padding: .9rem 1.1rem;
  background: var(--flaeche);
}
.zahlenband dt {
  font-size: .7rem; font-weight: 500; color: var(--grau);
  letter-spacing: .08em; text-transform: uppercase;
}
.zahlenband dd { margin: .2rem 0 0; }
.zahlenband .zahl {
  font-family: var(--schrift-zahl); font-size: 1.4rem; font-weight: 500;
  color: var(--tinte);
}

.start-staedte, .start-laender, .start-anbieter, .start-ratgeber,
.start-technik {
  margin-block: 2.75rem;
}
.start-staedte .klein, .start-anbieter .klein { margin-top: 1rem; }

/* Die sechzehn Laender mit ihrer Ortszahl. Zwei Angaben je Zeile, die
   Zahl rechtsbuendig — so steht sie untereinander und laesst sich
   vergleichen, statt hinter Namen verschiedener Laenge zu verschwinden. */
.land-liste {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: .1rem 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.land-liste li {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .3rem 0;
  border-bottom: 1px solid var(--linie-zart);
}
.land-liste li a { flex: 1 1 auto; }
.land-liste .klein-inline {
  flex: 0 0 auto;
  font-family: var(--schrift-zahl); font-size: .78rem; color: var(--grau);
}
