/* Farbtoken aus app.css uebernommen — nicht hier aendern. */
:root {
  --bg: #0b0e13;
  --surface: #11161d;
  --surface-2: #161c25;
  --surface-3: #1c2430;
  --border: #232c38;
  --border-soft: #1d2530;
  --text: #e8edf2;
  --text-dim: #a3afbc;
  --text-faint: #96a2b0;
  --text-ghost: #5d6876;
  /* Violett seit 27.09.2026 (Proton-Look der Website, Zeichen violett).
     #8b72ff statt #6d4aff: auf #0d0d0f muss der Akzent auch als Text
     lesbar sein -- #8b72ff kommt auf 5,3:1, #6d4aff nur auf 3,4:1.
     --auf-akzent bleibt dunkel, dunkle Schrift auf #8b72ff: 5,3:1. */
  --accent: #3ddc97;
  --accent-soft: #6be5b0;
  --accent-bg: rgba(61, 220, 151, 0.1);
  --accent-line: rgba(61, 220, 151, 0.32);
  --success: #3ddc97;
  --success-bg: rgba(95, 216, 143, 0.1);
  --warn: #f2b84d;
  --warn-bg: rgba(242, 184, 77, 0.12);
  --danger: #f16060;
  --danger-bg: rgba(241, 96, 96, 0.12);

  --radius: 10px;
  --radius-sm: 8px;
  --radius-lg: 14px;
  --sidebar-w: 236px;
  /* 71 statt 60. Nicht willkuerlich: der Kopf der Website ist 71 px hoch
     (16 px Polster oben und unten um eine Zeile von 1,05rem, plus die
     Linie), und seit Variante B ist es DERSELBE Kopf. 60 px waeren beim
     Wechsel von /app/ auf /seo/ ein Sprung von elf Pixeln. */
  --topbar-h: 71px;

  /* Hintergrund der klebenden Kopfleiste und die Farbe, die AUF dem
     Akzent lesbar ist.

     Beide standen bisher nur in magazin.css. Sie gehoeren aber in den
     gemeinsamen Satz: der Bau stellt genau diesen :root-Block der
     magazin.css voran ("eine Wahrheit fuer die Farben"), und seit die
     App dieselbe Kopfleiste traegt, braucht sie ihn auch. */
  --band: rgba(11, 14, 19, 0.92);
  --auf-akzent: #05140c;

  /* Die Breite, in der die Website steht (.mag-kopf in magazin.css).
     Seit dem 25.08.2026 steht die App im selben Kasten -- Kopf,
     Seitenleiste und Inhalt. Gemessen live: das Logo sitzt auf beiden
     Seiten an derselben Stelle, vorher sprang es um 264 px. */
  --seite-max: 1180px;
  --mono: 'JetBrains Mono', ui-monospace, monospace;
  --sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --anzeige: 'Space Grotesk', 'IBM Plex Sans', sans-serif;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.22);
}

/* ==========================================================================
   Das Magazin.

   Die Farbtoken stehen NICHT hier. bauen.mjs zieht den :root-Block aus
   app.css und setzt ihn beim Bau oben an diese Datei. Sonst gaebe es zwei
   Wahrheiten fuer dieselben Farben, und die eine liefe der anderen davon.

   Die App ist rein dunkel -- kein Themenschalter, keine Medienabfrage.
   Deshalb hat auch das Magazin nur einen Zustand; das ist eine
   Entscheidung der bestehenden Seite, nicht meine.

   app.css wird auf den Magazinseiten bewusst NICHT geladen: dort stehen
   Seitenleiste, Kopfleiste und Anmeldung der Anwendung. Ein Beitrag
   braucht nichts davon, und die Regeln wuerden sich in die Quere kommen.
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body.magazin {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font:
    400 16px/1.72 "Inter",
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* --- Kopf und Fuss -------------------------------------------------------- */

/* Die Kopfzeile klebt oben.

   Auf der Startseite scrollt man an 4.000 Pixeln vorbei; ohne das ist
   der Anmelde-Knopf nach dem ersten Bildschirm weg. Das Band traegt den
   Hintergrund und liegt ueber allem, der Kasten darin haelt die Breite.

   backdrop-filter statt voller Deckkraft: darunter durchscheinende
   Inhalte verraten, dass die Seite weiterlaeuft. Wo der Filter fehlt,
   greift die Farbe darunter -- deshalb steht sie ausdruecklich da und
   nicht nur als Ersatz. */
.mag-kopf-band {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--band);
  border-bottom: 1px solid var(--border-soft);
  backdrop-filter: saturate(1.3) blur(10px);
  -webkit-backdrop-filter: saturate(1.3) blur(10px);
}

/* Breiter als der Inhalt (900px): das Menue traegt jetzt neun Punkte mit
   den vollen Namen aus der alten Seite, und "Softwareentwicklung" allein
   ist neunzehn Zeichen. In 900 Pixeln braeuchte es zwei Zeilen, wo eine
   reicht. Der Text darunter bleibt bei 900. */
.mag-kopf {
  display: flex;
  align-items: center;
  gap: 24px;
  /* 1228 statt 1180: dieselbe Kante wie .mag-huelle, damit Logo und
     Seiteninhalt fluchten. Vorher stand das Logo 24 px weiter innen. */
  max-width: 1228px;
  margin: 0 auto;
  padding: 16px 24px;
}

.mag-logo {
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
}

/* Aus zwei Verweisen sind acht geworden. Sie brechen um, statt die
   Zeile zu sprengen -- kein Aufklappmenue, das waere Javascript fuer
   acht Woerter. */
/* DAS MENUE STEHT AM LOGO, NICHT AM RAND (03.09.2026).

   Es trug margin-left:auto und wanderte damit ganz nach rechts -- direkt
   neben die Knopfgruppe, die dasselbe tut. Ergebnis: 245 px Leere hinter
   dem Logo und ein Gedraenge rechts. Jetzt schiebt nur noch die
   Knopfgruppe, das Menue beginnt, wo es hingehoert. */
.mag-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 4px;
}

.mag-nav a {
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: var(--text-dim);
  text-decoration: none;
}

.mag-nav a:hover {
  background: var(--surface-2);
  color: var(--text);
}

/* Wo man gerade ist. aria-current traegt die Auskunft fuer den
   Screenreader, der Strich darunter fuer alle anderen -- eine Farbe
   allein ist zu wenig, wer sie nicht unterscheiden kann, sieht keinen
   Unterschied. */
.mag-nav a[aria-current="page"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--accent);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

/* Der Werkzeug-Knopf.

   Er ist der einzige Punkt im Menue, der nicht auf die Hauptseite
   fuehrt, sondern in die App -- deshalb sieht er anders aus: umrahmt im
   Akzent, mit einer Rakete davor. Gefuellt waere er zu laut fuer eine
   Menuezeile; der Rahmen reicht, um ihn herauszuheben. */
/* WERKZEUGE IST EIN MENUEPUNKT, KEIN ZWEITER AUFRUF (03.09.2026).

   Er trug einen orangen Rahmen und stand damit als Knopf in der Zeile --
   sinnvoll, solange die App "das Angebot dahinter" war und man sie eigens
   ausweisen musste. Seit dem 03.09. fuehrt der Kopf das Produkt, und rechts
   steht "Kostenlos starten" in Akzentfarbe. Zwei orange Rufe nebeneinander
   heben sich gegenseitig auf: der Blick weiss nicht, welcher gemeint ist.

   Das Zeichen bleibt -- es unterscheidet den Punkt genug, ohne zu rufen. */
/* WERKZEUGE STEHT RECHTS, bei Anmelden und dem Aufruf (05.09.2026, nach
   dem Entwurf). Es sieht aus wie ein Menuepunkt und nicht wie ein Knopf:
   der Knopf daneben ist der Aufruf, und zwei Knoepfe nebeneinander sind
   zwei Aufrufe.

   Frueher stand hier .mag-nav-app mit einer Rakete davor -- der Punkt
   war der einzige im Menue, der in die App fuehrte, und trug deshalb ein
   Zeichen. In der Dreiergruppe rechts fuehren alle drei dorthin; ein
   Symbol an einem von dreien waere willkuerlich. */
.kopf-werkzeuge {
  align-self: center;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
}

.kopf-werkzeuge:hover {
  background: var(--surface-2);
  color: var(--text);
}

@media (max-width: 640px) {
  .mag-kopf {
    flex-wrap: wrap;
    gap: 12px;
  }

  .mag-nav {
    margin-left: 0;
    justify-content: flex-start;
  }

  .mag-nav a,
  .mag-menue > summary,
  .kopf-werkzeuge {
    padding: 5px 9px;
    font-size: 0.82rem;
  }

  /* Auf dem Handy umbricht das Menue ohnehin auf drei Zeilen. Haengen
     die beiden Knoepfe hinten dran, bekommen sie eine vierte -- 34
     Pixel, die oben auf dem Schirm knapp sind. Also rueckt das Menue
     ganz nach unten und die Knoepfe stehen rechts neben dem Logo, wo
     auf der ersten Zeile ohnehin Platz frei ist. */
  .mag-nav {
    order: 3;
    width: 100%;
  }

  .kopf-knoepfe {
    margin-left: auto;
  }
}

/* EINE BREITE FUER ALLES (03.09.2026, auf Stefans Ansage "alles
   einheitlich").

   Vorher standen auf einer Seite DREI Kanten: die Kopfzeile auf 1180, der
   Inhalt auf 852 und der Aufmacher auf 1092, letzterer ueber ein
   `margin: 0 -120px`, das aus der schmalen Huelle ausbrach. Sichtbar war
   das als Versatz zwischen Logo und Inhalt.

   1228 = 1180 Inhalt + zweimal 24 Polsterung -- damit deckt sich die
   INHALTSkante von Kopfzeile, Hauptteil und Fuss.

   DEN FLIESSTEXT MACHT DAS NICHT BREITER: In den Beitraegen begrenzt sich
   die Karte selbst (`.artikel`, 718,92 px) und der Absatz darin auf 621 px
   (72ch, siehe --mass). Gemessen nach der Umstellung: unveraendert. Die
   Huelle war dort nie der Engpass. */
.mag-huelle {
  max-width: 1228px;
  margin: 0 auto;
  padding: 34px 24px 60px;
}

.mag-fuss {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  max-width: 1228px;
  margin: 0 auto;
  padding: 22px 24px 40px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.85rem;
  color: var(--text-ghost);
}

.mag-fuss a {
  color: var(--text-dim);
}

/* Anschrift links im Fuss. <address> setzt sonst kursiv. */
.mag-fuss-adresse {
  font-style: normal;
  line-height: 1.6;
  flex: 0 0 auto;
  white-space: nowrap;
}

/* --- Beitrag -------------------------------------------------------------- */

.artikel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 0 0 34px;
  overflow: hidden;
}

.kopfbild {
  background: var(--surface-2);
  color: var(--accent);
  line-height: 0;
}

.kopfbild svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Erzeugte Kopfbilder (build/kopfbilder.mjs). Der Grund ist der des
   Bildes, nicht --surface-2: Ein Rasterbild wechselt die Farbe nicht mit
   dem Thema, und beim Laden soll im hellen Thema keine graue Flaeche
   aufblitzen, die dann schwarz wird. */
.kopfbild-illu {
  background: #0d0d0f;
}
.kopfbild-illu img {
  display: block;
  width: 100%;
  height: auto;
}

/* Der Kopf laeuft auf derselben Spur wie der Text darunter.

   Seit die Karte auf grossen Bildschirmen breiter ist als der Text,
   standen Rubrik, Ueberschrift und Datum am linken Kartenrand, waehrend
   der Fliesstext 236 Pixel weiter innen anfing. Zwei verschiedene
   Fluchten auf derselben Seite -- das sieht nicht nach Absicht aus,
   sondern nach Versehen. Dieselbe Breite und dieselbe Zentrierung wie
   die Absaetze, also stehen sie untereinander. */
/* DIE LUFT ZUM KARTENRAND STEHT AN EINER STELLE.

   Vorher stand 34px drei Mal einzeln da -- im Kopf, im Fliesstext, und
   als 68px (das Doppelte) in der Breitenrechnung darunter. Wer einen
   Wert aendert und die anderen uebersieht, bekommt einen Text, der nicht
   mehr unter seiner Ueberschrift steht.

   Sie waechst jetzt mit: eng auf dem Handy, wo jeder Pixel Textbreite
   zaehlt, grosszuegig auf dem Bildschirm, wo die Karte seit dem Ausbruch
   nach links und rechts ohnehin 240 Pixel breiter ist als der uebrige
   Inhalt. Am staerksten wirkt das in der Mitte -- auf einem Tablet
   stiess der Text vorher fast an die Kante, waehrend er auf dem Desktop
   von der 72ch-Grenze ohnehin mittig gehalten wird. */
.artikel {
  --luft: clamp(20px, 3.4vw, 56px);

  /* DAS TEXTMASS, EINMAL UND SCHRIFTUNABHAENGIG.

     Es stand vorher als `72ch` an jedem Textelement einzeln -- und `ch`
     ist relativ zur Schrift des Elements SELBST. Dieselbe Zeile ergab
     deshalb vier verschiedene Breiten (gemessen am 01.09.2026):

         Absatz   16,00px            72ch = 621px
         h2       21,44px            72ch = 888px
         h3       17,60px            72ch = 729px
         h4       16,00px            72ch = 663px   <- gleiche Groesse!

     Die h4 zeigt den zweiten Teil der Ursache: `ch` haengt nicht nur an
     der Schriftgroesse, sondern auch an der Schriftfamilie -- die
     Ueberschriftenschrift hat eine breitere Null.

     Weil jedes Element einzeln zentriert wird, wurde daraus ein
     ausgefranster linker Rand. Sichtbar wird er auf den Seiten mit
     Tabelle, wo `.artikel-breit` die Kartenbreite freigibt: Dort stand
     die Ueberschrift 133 Pixel weiter links als der Absatz, zu dem sie
     gehoert.

     38,8125rem sind exakt dieselben 621 Pixel wie 72ch des Fliesstexts,
     aber unabhaengig davon, wie gross und in welcher Schrift das
     einzelne Element gesetzt ist. Wer die Fliesstextgroesse aendert,
     rechnet diesen Wert neu: 72ch der neuen Groesse. */
  --mass: 38.8125rem;

  /* DIE KARTE IST SO BREIT WIE DER TEXT DARIN, plus die Luft an den
     Seiten. Damit stehen Kartenrand, Ueberschrift, Fliesstext,
     Newsletter und Autorenbox auf derselben Kante -- vorher waren es
     drei verschiedene Breiten: 1092 fuer die Karte, 733 fuer Kopf und
     Autor, 621 fuer den Text.

     72ch ist die Textbreite, nicht willkuerlich: darueber verliert das
     Auge beim Zeilenwechsel den Anschluss. Die Karte richtet sich nach
     dem Text, nicht umgekehrt. */
  max-width: calc(var(--mass) + 2 * var(--luft));
  margin-left: auto;
  margin-right: auto;
}

/* ZURUECKGEDREHT AM 02.09.2026, auf Stefans Ansage: Tabelle und Text sollen
   gleich breit sein.

   Hier stand vorher `.artikel-breit { max-width: none }` -- wer eine Tabelle
   hatte, bekam die breite Karte, und `.tabelle-rahmen` nutzte den Zugewinn
   allein. Gemessen auf /seo/core-web-vitals-testen/: Text 621 Pixel ab x=131,
   Tabelle 772 ab x=56. Zwei Kanten auf einer Seite.

   Der Gedanke dahinter war nicht falsch -- eine breite Tabelle muss weniger
   scrollen. Er kostet aber die gemeinsame Kante, an der das Auge beim Lesen
   entlanglaeuft, und die Tabellen dieser Beitraege sind drei- bis
   vierspaltig: Sie brauchen die zusaetzlichen 150 Pixel nicht.

   MIT DER TABELLENBREITE MUSS DIE KARTENBREITE WEG. Bliebe `.artikel-breit`
   stehen, waere die Karte weiterhin 1092 breit und ALLES darin 621 -- genau
   die "leere Karte", gegen die die Klasse damals eingefuehrt wurde. Die
   Klasse wird deshalb auch in build/bauen.mjs nicht mehr gesetzt. */

.artikel-kopf,
.newsletter,
.autor,
.kommentare {
  max-width: calc(var(--mass) + 2 * var(--luft));
  margin-left: auto;
  margin-right: auto;
}

.artikel-kopf {
  padding: 26px var(--luft) 0;
}

.marke-klein {
  display: inline-block;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-bg);
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  padding: 3px 11px;
  text-decoration: none;
}

.artikel-kopf h1 {
  margin: 14px 0 8px;
  font-size: clamp(1.6rem, 3.6vw, 2.15rem);
  line-height: 1.22;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.artikel-meta {
  margin: 0;
  font-size: 0.84rem;
  color: var(--text-faint);
}

/* Autorenname in Byline und Autorenbox: Verweis auf /about/, aber im Ton
   des umgebenden Textes statt in Browserblau. */
.artikel-meta a,
.autor-name a {
  color: inherit;
  text-decoration: none;
}

.artikel-meta a:hover,
.autor-name a:hover {
  color: var(--accent-soft);
  text-decoration: underline;
}

/* --- Fliesstext ----------------------------------------------------------- */

/* DIE ZEILENBREITE HAENGT AM TEXT, NICHT AM BLOCK.

   Vorher stand die Begrenzung auf 68ch hier oben -- und damit galt sie
   auch fuer Tabellen, Codebloecke und Bilder. Das Ergebnis auf einem
   breiten Bildschirm: eine Vergleichstabelle mit 716 Pixeln Inhalt
   quetschte sich in einen 519 Pixel breiten Scrollkasten, waehrend
   rechts daneben 300 Pixel leer standen. Acht der 56 Beitraege haben
   solche Tabellen.

   Jetzt spannt sich .prosa ueber die volle Kartenbreite, und nur die
   Textelemente bekommen die Begrenzung. Fliesstext bleibt lesbar, alles
   Breite darf breit sein. */
.prosa {
  padding: 8px var(--luft) 0;
}

/* Der Text steht mittig in der Karte, nicht links angeschlagen.

   Vorher klebte er am linken Rand, und rechts blieb ein Drittel der
   Karte leer -- was aussieht, als haette jemand vergessen, etwas
   hinzustellen. Mit auto an beiden Seiten steht die Spalte in der Mitte,
   und die Karte wirkt gesetzt statt halb gefuellt.

   TABELLEN STEHEN SEIT DEM 02.09.2026 IN DIESER LISTE. Bilder und
   Codebloecke nicht: Ein Codeblock scrollt eine lange Zeile lieber selbst,
   als sie umzubrechen, und ein Bild traegt keine Zeilen, an deren Anfang das
   Auge zurueckspringt. Bei einer Tabelle springt es -- deshalb gehoert sie
   auf dieselbe Kante wie der Text. */
.prosa p,
.prosa ul,
.prosa ol,
.prosa blockquote,
.prosa h2,
.prosa h3,
.prosa h4,
.tabelle-rahmen {
  max-width: var(--mass);
  margin-left: auto;
  margin-right: auto;
}

.prosa h2,
.prosa h3,
.prosa h4 {
  line-height: 1.3;
  letter-spacing: -0.015em;
  /* Die Kopfzeile klebt jetzt oben und ist rund 70 Pixel hoch. Ohne
     diesen Abstand landet ein Sprung auf einen Anker genau darunter,
     und die Ueberschrift, die man gesucht hat, ist verdeckt. */
  scroll-margin-top: 92px;
}

.prosa h2 {
  margin: 34px auto 12px;
  font-size: 1.34rem;
}
.prosa h3 {
  margin: 26px auto 10px;
  font-size: 1.1rem;
}
.prosa h4 {
  margin: 22px auto 8px;
  font-size: 1rem;
  color: var(--text-dim);
}

.prosa p {
  margin: 0 auto 17px;
}

.prosa a {
  color: var(--accent-soft);
  text-underline-offset: 2px;
}

/* DIESELBE FARBE IN DEN BRUCHSTUECKEN DER SEITEN, seit dem 11.09.2026.

   Bis zur Nabe /ki-automatisierung/ hatte keine der von Hand
   geschriebenen Seiten einen Link im Fliesstext -- sie verwiesen ueber
   Knoepfe und Kartenueberschriften, und beide tragen eigenes Styling.
   Der erste Textlink kam deshalb im Browser-Blau heraus, auf dunklem
   Grund kaum lesbar und ohne Bezug zur Marke.

   Die Kartenueberschrift bleibt ausgenommen: .karte h3 a erbt bewusst
   die Textfarbe und zeigt seinen Zustand ueber die Linie darunter. */
.abschnitt p a,
.abschnitt li a,
.karte p a {
  color: var(--accent-soft);
  text-underline-offset: 2px;
}

/* AUFZAEHLUNGEN STEHEN BUENDIG ZUM FLIESSTEXT.

   Vorher sprang die Liste um 22px ein, ihre linke Kante lag also neben
   der der Absaetze -- bei einer Textspalte, die ohnehin schon zentriert
   ist, ergibt das eine zweite, unruhige Kante. Jetzt haengen Punkt und
   Zahl im Rand, und der Text der Aufzaehlung beginnt genau dort, wo auch
   der Absatztext beginnt.

   Deshalb `list-style: none` und eigene Marken: der eingebaute Marker
   laesst sich nicht zuverlaessig ausserhalb des Kastens platzieren, ohne
   dass die Zahlen mehrstelliger Listen verrutschen. */
.prosa ul,
.prosa ol {
  margin: 0 auto 17px;
  padding-left: 0;
  list-style: none;
}

.prosa ol {
  counter-reset: prosa-punkt;
}

.prosa li {
  position: relative;
  margin-bottom: 7px;
}

.prosa ul > li::before {
  content: "";
  position: absolute;
  /* Mitte der ersten Zeile bei line-height 1.7 */
  top: 0.72em;
  right: calc(100% + 10px);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--text-faint);
}

/* Zahlen rechtsbuendig an die Textkante: bei 9 auf 10 rutscht sonst der
   Punkt nach aussen und die Kante franst aus. */
.prosa ol > li {
  counter-increment: prosa-punkt;
}

.prosa ol > li::before {
  content: counter(prosa-punkt) ".";
  position: absolute;
  right: calc(100% + 8px);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* SCHMALE FENSTER: dort steht die Textspalte fast am Bildschirmrand,
   und eine haengende Marke wuerde abgeschnitten. Unter 720px also der
   klassische Einzug -- lieber eingerueckt als halb sichtbar. */
@media (max-width: 720px) {
  .prosa ul,
  .prosa ol {
    padding-left: 20px;
  }

  .prosa ul > li::before,
  .prosa ol > li::before {
    right: auto;
    left: -20px;
  }

  .prosa ol > li::before {
    width: 14px;
    text-align: right;
  }
}

.prosa img {
  display: block;
  width: 100%;
  height: auto;
  margin: 22px 0;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

/* Illustrationen im Text (build/textbilder.mjs). Rand und Radius kommen von
   .prosa img; der dunkle Grund wie beim Kopfbild, weil ein Rasterbild nicht
   mit dem Thema wechselt und beim Laden nichts hell aufblitzen soll. */
.prosa .textbild {
  margin: 26px 0;
}
.prosa .textbild img {
  margin: 0;
  background: #0d0d0f;
}

/* "Kurz gesagt" (build/bauen.mjs, kurzGesagt): die Antwort vor dem Text.
   Gruener Balken links, leiser Grund aus dem Akzent, Titel in der
   Anzeigeschrift. Wechselt ueber die Tokens mit dem Thema. Die Kennzahl
   daneben: grosse Zahl, kleine Herkunft. */
.kurz {
  margin: 22px 0 8px;
  padding: 16px 20px 14px;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--accent-bg);
}
.kurz-titel {
  margin: 0 0 6px;
  font-family: var(--anzeige);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.kurz p {
  margin: 0 0 8px;
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
}
.kurz p:last-child {
  margin-bottom: 0;
}
.kurz b {
  font-weight: 600;
}
.kurz code {
  font-family: var(--mono);
  font-size: 0.9em;
}
.kennzahl {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin: 10px 0 8px;
  padding: 12px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.kennzahl b {
  flex: 0 0 auto;
  font-family: var(--anzeige);
  font-weight: 700;
  font-size: 1.9rem;
  letter-spacing: -0.02em;
  color: var(--accent);
}
.kennzahl p {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--text-dim);
}
@media (max-width: 560px) {
  .kennzahl { flex-direction: column; gap: 4px; }
}

/* Screenshots der eigenen Werkzeuge (build/screenshots.mjs): echtes Bild
   mit Haarlinie, Unterschrift mit Datum und Verweis aufs Werkzeug. */
.screenshot {
  margin: 26px 0;
}
.screenshot img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.screenshot figcaption {
  margin-top: 10px;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--text-dim);
}

/* Eingebettete Videos (build/videos.mjs): bis zum Klick nur das eigene
   Vorschaubild mit Abspielknopf; beitrag.js tauscht es gegen den Player.
   16:9 fest, damit beim Tausch nichts springt. */
.video {
  margin: 26px 0;
}
.video-rahmen {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.video-rahmen img,
.video-rahmen iframe {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  object-fit: cover;
}
.video .video-start {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  text-decoration: none;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0) 38%);
}
.video .video-start:hover,
.video .video-start:focus-visible {
  color: #fff;
}
.video-knopf {
  width: 68px;
  height: 48px;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.35);
  position: relative;
  transition: background 0.15s ease, transform 0.15s ease;
}
.video-knopf::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-35%, -50%);
  border-style: solid;
  border-width: 10px 0 10px 17px;
  border-color: transparent transparent transparent #fff;
}
.video-start:hover .video-knopf,
.video-start:focus-visible .video-knopf {
  background: var(--accent);
  transform: scale(1.06);
}
.video-start:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}
.video-titel {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 12px;
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.35;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}
.video-start .visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.video-hinweis {
  display: block;
  margin: 6px 0 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--text-faint);
}
.video figcaption {
  margin-top: 6px;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--text-dim);
}
.video-quelle {
  display: block;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--text-faint);
}
@media (prefers-reduced-motion: reduce) {
  .video-knopf { transition: none; }
}
@media (max-width: 480px) {
  .video-titel { font-size: 0.82rem; left: 10px; right: 10px; bottom: 8px; }
  .video-knopf { width: 56px; height: 40px; }
}

/* Gerechnete Grafiken (build/grafiken.mjs): Inline-SVG, das seine Farben aus
   den Tokens nimmt und deshalb mit dem Thema wechselt. Die Unterschrift
   traegt Aussage und Quelle; ohne Quelle gibt es sie nicht.

   SEIT 08.10.2026 MIT RAHMEN, wie eine Tabelle: Daten (Tabellen, Grafiken)
   stehen im Kasten, Text nie. Dieselbe Behandlung auf den Saeulenseiten,
   in Beitraegen und in der DMARC-Studie. Der Rahmen ist nie breiter als
   die Grafik in 1:1 (--grafik-breite setzt build/grafiken.mjs aus dem
   viewBox) plus Polster -- sonst waechst die Schrift im SVG ueber die des
   Textes. Handgeschriebene Grafiken (seiten/security.html) setzen die
   Variable selbst oder lassen sie weg und laufen dann ueber die Spalte. */
.grafik {
  box-sizing: border-box;
  max-width: min(calc(var(--grafik-breite, 100vw) + 50px), 50rem);
  margin: 28px 0;
  padding: 22px 24px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.grafik svg {
  display: block;
  width: 100%;
  height: auto;
  font-family: var(--mono);
}
.grafik figcaption {
  margin-top: 14px;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--text-dim);
}
.grafik figcaption a {
  color: var(--accent-soft);
}
/* --text-faint statt --text-ghost: die Quelle ist Text und braucht 4,5:1. */
.grafik-quelle {
  display: block;
  margin-top: 4px;
  font-size: 0.8rem;
  color: var(--text-faint);
}
@media (max-width: 560px) {
  .grafik {
    padding: 16px 14px 14px;
  }
}

/* Die Regeln der drei Saeulenseiten (vorher je Seite eigene: .saeule-bild-breit,
   .entscheidung-tabelle, .web-vergleich, .web-messung, #erfahrung) stehen seit
   08.10.2026 gesammelt am Ende dieser Datei unter "SAEULENSEITEN". */
.screenshot figcaption a {
  color: var(--accent);
}

.prosa blockquote {
  margin: 22px auto;
  padding: 2px 0 2px 18px;
  border-left: 3px solid var(--accent-line);
  color: var(--text-dim);
}

.prosa code {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 5px;
}

.prosa pre {
  margin: 20px 0;
  padding: 15px 17px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.86rem;
  line-height: 1.6;
}

.prosa pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
}

/* Tabellen sind in diesen Beitraegen oft breiter als der Text. Sie
   scrollen in ihrem eigenen Kasten, damit die Seite es nicht tut. */
.tabelle-rahmen {
  margin: 22px 0;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* AUCH AUSSERHALB VON .prosa, SEIT DEM 11.09.2026. Die Regeln hingen
   allein an .prosa -- dem Textkoerper eines Magazinbeitrags. Eine
   Nabenseite hat den nicht, und eine Tabelle stand dort ohne Polster
   und ohne Trennlinien: vier Spalten, deren Text ineinanderlief.

   .tabelle-rahmen ist der richtige Aufhaenger, weil er genau das ist,
   was jede Tabelle umgibt -- der Markdown-Bau setzt ihn selbst, und von
   Hand geschriebene Seiten schreiben ihn hin. Im Beitrag sind beide
   Bedingungen erfuellt; dort aendert sich dadurch nichts. */
.prosa table,
.tabelle-rahmen table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
}

.prosa th,
.prosa td,
.tabelle-rahmen th,
.tabelle-rahmen td {
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}

.prosa th,
.tabelle-rahmen th {
  background: var(--surface-2);
  font-weight: 600;
  white-space: nowrap;
}

.prosa tr:last-child td,
.tabelle-rahmen tr:last-child td {
  border-bottom: 0;
}

/* --- Uebersichten --------------------------------------------------------- */

.abschnitt h1 {
  margin: 0 0 6px;
  font-size: clamp(1.6rem, 3.6vw, 2.05rem);
  letter-spacing: -0.022em;
}

.mag-anriss {
  margin: 0 0 22px;
  color: var(--text-dim);
}

/* Startseite: Beitraege nach Thema als reine Textverweise (14.09.2026). Die
   Startseite ist die einzige indexierte Seite und soll ihr Gewicht an mehr
   als sechs Beitraege weitergeben, ohne zur Kartenwand zu werden. */
.themenliste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px 32px;
  margin-top: 18px;
}
.themenliste h3 {
  font-size: 1rem;
  margin: 0 0 10px;
}
.themenliste h3 a {
  color: inherit;
  text-decoration: none;
}
.themenliste h3 a:hover {
  color: var(--accent);
}
.themenliste ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 7px;
}
.themenliste li a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.94rem;
  line-height: 1.4;
}
.themenliste li a:hover {
  color: var(--text);
  text-decoration: underline;
}

/* --- Weiterlesen unter jedem Beitrag (14.09.2026) --------------------------
   Textkarten ohne Bild: der Block soll Wege legen, nicht mit dem Beitrag
   darueber um Aufmerksamkeit konkurrieren. Seitlich dieselben 34 Pixel wie
   Textblock und Autorenbox. Nur Tokens -- eine feste Farbe faellt im
   dunklen Modus aus. */
.weiterlesen {
  margin-top: 38px;
  padding: 26px 34px 0;
  border-top: 1px solid var(--border-soft);
}
.weiterlesen h2 {
  font-size: 1.05rem;
  margin: 0 0 14px;
}
.weiterlesen-liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.weiterlesen-liste a {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}
.weiterlesen-liste a:hover,
.weiterlesen-liste a:focus-visible {
  border-color: var(--accent);
  background: var(--accent-bg);
}
.weiterlesen-liste b {
  font-size: 0.95rem;
  line-height: 1.35;
  color: var(--text);
}
.weiterlesen-liste span {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--text-dim);
}
@media (max-width: 640px) {
  .weiterlesen {
    padding-left: 20px;
    padding-right: 20px;
  }
}

.artikelliste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.artikel-karte {
  display: block;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color 0.14s ease;
}

.artikel-karte:hover {
  border-color: var(--accent-line);
}

.artikel-datum {
  display: block;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-ghost);
  margin-bottom: 6px;
}

.artikel-karte b {
  display: block;
  font-size: 0.98rem;
  line-height: 1.35;
  color: var(--text);
  margin-bottom: 6px;
}

.artikel-anriss {
  display: block;
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--text-dim);
}

/* Der Ankerlink an den Ueberschriften. Beim Ueberfahren sichtbar, bei
   Tastaturfokus ebenfalls -- ein Element, das nur bei :hover existiert,
   ist fuer Tastaturnutzer nicht vorhanden. */
.anker {
  margin-left: 9px;
  color: var(--text-ghost);
  text-decoration: none;
  font-weight: 400;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.prosa h2:hover .anker,
.prosa h3:hover .anker,
.prosa h4:hover .anker,
.prosa h2:focus-within .anker,
.prosa h3:focus-within .anker,
.prosa h4:focus-within .anker,
.anker:focus,
.anker:focus-visible {
  opacity: 1;
}

.anker:hover {
  color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}

/* Die Marke neben der Wortmarke. Der Abstand als gap am Flex-Container ist
   hier unbedenklich: .mag-logo enthaelt genau zwei Kinder, das SVG und die
   <span> mit dem Wort. Bei bitinformer stand die Wortmarke als blosser
   Textknoten daneben und der gap landete mitten im Wort -- deshalb hier
   die <span>. */
.mag-logo {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.mag-marke {
  flex: 0 0 auto;
  color: var(--text);
}

/* ==========================================================================
   Die Seiten der Hauptseite

   Gegen dieselben Tokens wie die App gebaut. Kein eigenes Farbsystem und
   keine Verlaeufe: das Original hatte auf einer Leistungsseite 23
   eingebettete SVGs mit 27 Farbstopps, und davon traegt keiner Bedeutung.
   ========================================================================== */

.hero {
  padding: 46px 0 40px;
  border-bottom: 1px solid var(--border-soft);
}

.eyebrow {
  margin: 0 0 14px;
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: var(--accent);
}

/* IM HELLEN SATZ DER GEDECKTE AKZENT, aus einem gemessenen Grund.

   Die Kopfzeile ist mit 12,2 Pixeln der kleinste Text der Seite, und im
   Aufmacher steht sie ueber dem Schimmer. Gerechnet auf #fbfaf8:

     --accent      #c2450a   4,85:1 blank   4,22:1 ueber dem Schimmer
     --accent-soft #a63a06   6,23:1 blank   5,43:1 ueber dem Schimmer

   4,22 ist unter der Grenze von 4,5:1 -- und zwar schon vor dem Umbau
   des Schimmers am 29.08.2026, der alte Verlauf lag an derselben Stelle
   aehnlich hoch. Der dunkle Satz braucht das nicht: dort steht die
   Kopfzeile auf fast Schwarz und kommt auch ueber dem Schein auf 4,7:1.

   Dieselbe Unterscheidung trifft die Fussnote im Aufmacher laengst --
   ihr Verweis steht dort schon auf --accent-soft. */
:root[data-theme="hell"] .eyebrow {
  color: var(--accent-soft);
}

.hero h1 {
  margin: 0 0 12px;
  font-size: clamp(2.1rem, 6vw, 3.4rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.hero-sub {
  margin: 0 0 18px;
  font-size: clamp(1.05rem, 2.4vw, 1.32rem);
  line-height: 1.4;
  color: var(--text-dim);
  max-width: 34ch;
}

.hero-text {
  margin: 0 0 26px;
  max-width: 62ch;
  color: var(--text-dim);
}

.hero-knoepfe {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.knopf {
  display: inline-block;
  padding: 11px 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: 0.93rem;
  font-weight: 500;
  text-decoration: none;
}

.knopf:hover {
  border-color: var(--accent-line);
}

.knopf-voll {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--auf-akzent);
  font-weight: 600;
}

.knopf-voll:hover {
  filter: brightness(1.08);
}

.abschnitt {
  padding: 40px 0;
  border-bottom: 1px solid var(--border-soft);
}

.abschnitt:last-child {
  border-bottom: 0;
}

.abschnitt h2 {
  margin: 0 0 10px;
  font-size: clamp(1.35rem, 3vw, 1.75rem);
  letter-spacing: -0.024em;
  line-height: 1.24;
  text-wrap: balance;
}

.fuehrung {
  margin: 0 0 4px;
  max-width: 66ch;
  color: var(--text-dim);
}

/* Beschreibungsliste statt Absaetze: "Loesung" und "Ergebnis" sind
   Bezeichner zu einem Inhalt, und genau dafuer ist dl da. Im Original
   standen beide als gleichrangige <p> untereinander, wodurch der
   Zusammenhang nur optisch bestand. */
.fall-liste {
  margin: 0;
  display: grid;
  gap: 4px;
}

.mehr {
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--accent);
}

.mehr::after {
  content: " →";
}

/* --- Ablauf --------------------------------------------------------------- */

.ablauf {
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: schritt;
  display: grid;
  gap: 2px;
}

.ablauf li {
  counter-increment: schritt;
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid var(--border-soft);
}

.ablauf li::before {
  content: counter(schritt);
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--accent);
  padding-top: 2px;
}

/* Beide in die zweite Spalte, ausdruecklich.

   Ohne das landet die <span> in Zeile zwei, Spalte EINS -- also in den
   34 Pixeln, die fuer die Ziffer gedacht sind. Der Text bricht dann auf
   einen Buchstaben pro Zeile um. Das ist auf der Startseite passiert,
   ohne dass es jemandem aufgefallen waere: bei drei Woertern faellt eine
   schmale Spalte nicht auf, bei drei Zeilen schon. */
.ablauf b,
.ablauf span {
  grid-column: 2;
}

.ablauf b {
  font-size: 0.98rem;
  font-weight: 600;
}

.ablauf span {
  display: block;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-dim);
  margin-top: 3px;
}

/* --- Gruende -------------------------------------------------------------- */

.gruende {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin-top: 20px;
}

.grund {
  padding: 18px;
  background: var(--surface-2);
  border-radius: var(--radius);
}

.grund h3 {
  margin: 0 0 7px;
  font-size: 1rem;
  letter-spacing: -0.012em;
}

.grund p,
.gruende-weiter p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.58;
  color: var(--text-dim);
}

.gruende-weiter {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px;
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--border-soft);
}

.gruende-weiter h4 {
  margin: 0 0 7px;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
}

/* --- Aufruf --------------------------------------------------------------- */

.aufruf {
  text-align: left;
}

.haken {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 7px;
}

.haken li {
  padding-left: 26px;
  position: relative;
  color: var(--text-dim);
}

/* Der Haken als Pseudo-Element, nicht als Zeichen im Text: so liest ein
   Screenreader nicht "Haken" vor jedem Punkt. */
.haken li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 8px;
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

.aufruf-knopf {
  margin: 24px 0 0;
}

/* --- Stapel: die Werkzeug- und Technik-Listen ------------------------------

   Die Herstellerzeichen aus dem Original stehen wieder davor, aber klein:
   14 Pixel, so hoch wie die Schrift daneben. In WordPress waren sie so
   gross, dass zwoelf Zeichen die Zeile fuellten und der Name zur
   Bildunterschrift wurde. */

.stapel + .stapel {
  margin-top: 22px;
}

.stapel-titel {
  margin: 0 0 10px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-dim);
}

.chips {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.chips li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--text-dim);
}

/* Ein Chip ohne Zeichen bekommt links denselben Abstand wie rechts,
   damit die Namen nicht um drei Pixel verspringen. */
.chips li:not(:has(.logo)) {
  padding-left: 11px;
}

/* Beim Ueberfahren tritt der Chip einen Schritt vor: Rahmen im Akzent,
   Grund eine Stufe heller, Name in voller Textfarbe. Die einfarbigen
   Zeichen gehen mit -- sie erben die Textfarbe. Die farbigen bekommen
   etwas mehr Saettigung, damit sie nicht als einzige stehenbleiben.

   In @media (hover: hover) gekapselt: auf einem Fingergeraet gibt es
   kein Ueberfahren, dort bleibt der Zustand nach einer Beruehrung
   haengen, und dann sieht ein Chip aus wie ausgewaehlt, ohne es zu sein.

   KEIN cursor: pointer und kein Anheben. Die Chips sind eine
   Aufzaehlung, keine Knoepfe -- sie duerfen aufmerken, aber nicht
   behaupten, dass ein Klick etwas tut. */
@media (hover: hover) {
  .chips li {
    transition:
      border-color 0.16s ease,
      background-color 0.16s ease,
      color 0.16s ease;
  }

  .chips li:hover {
    border-color: var(--accent-line);
    background: var(--surface-3);
    color: var(--text);
  }

  .logo {
    transition: filter 0.16s ease;
  }

  .chips li:hover .logo {
    filter: saturate(1.2) brightness(1.1);
  }
}

/* Die Zeichen sind Schmuck. Sie tragen aria-hidden, und ihre Groesse
   steht hier statt im SVG.

   Die Farbe steht ausdruecklich NICHT hier: die einfarbigen unter ihnen
   sind auf currentColor gesetzt und erben damit die Textfarbe des Chips.
   So sind sie genau so hell wie der Name daneben -- und beim Ueberfahren
   hellen sie mit auf, ohne dass es dafuer eine zweite Regel braucht. */
.logo {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
}

.chips-frei {
  margin-top: 22px;
}

/* --- Karten ---------------------------------------------------------------

   Wie .leistung, aber ohne Verweis: die meisten dieser Karten fuehren
   nirgendwohin, und ein <a> ohne Ziel ist fuer die Tastatur eine
   Sackgasse. */

.karten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 20px;
}

.karte {
  padding: 18px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}

.karte h3 {
  margin: 0 0 7px;
  font-size: 1rem;
  letter-spacing: -0.012em;
}

.karte h3 a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--accent-line);
}

.karte h3 a:hover {
  border-bottom-color: var(--accent);
}

.karte p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.58;
  color: var(--text-dim);
}

.karte p + p {
  margin-top: 12px;
}

/* Das Zeichen ueber der Kartenueberschrift.

   NUR AUF SEITEN, DIE OHNE BILD AUSKOMMEN MUESSTEN. Die Leistungsseiten
   tragen ihr Aufmacherbild und darunter Textkarten; eine Nabe mit zehn
   Textabschnitten hintereinander hat dagegen nichts, woran das Auge
   haengenbleibt. Das Zeichen ist die kleinste Abhilfe, die keine
   Bilddatei braucht und im Dunkeln wie im Hellen funktioniert -- es
   erbt seine Farbe aus den Tokens.

   accent-bg statt surface-3 als Flaeche: auf surface-2 sind die beiden
   kaum zu unterscheiden, und ein Kasten, den man nicht sieht, ist
   Markup ohne Wirkung. */
.karte-zeichen {
  display: flex;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  margin-bottom: 13px;
  border-radius: var(--radius-sm);
  background: var(--accent-bg);
  color: var(--accent);
}

/* Die Auszeichnung ueber der Ueberschrift: "Python · Aktiv". */
/* --text-dim, nicht --text-faint: bei 0.74rem kommt --text-faint auf
   surface-2 nur auf 4.35:1 und faellt damit unter die 4.5, die kleiner
   Text braucht. --text-dim schafft 4.71. */
.karte-marke {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px !important;
  font-size: 0.74rem !important;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim) !important;
}

.marke-sprache {
  font-family: var(--mono);
  text-transform: none;
  letter-spacing: 0;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--text);
}

.marke-neu {
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--accent-bg);
  color: var(--accent-soft);
  font-weight: 600;
}

.mehr-link {
  color: var(--accent-soft);
  text-decoration: none;
  font-weight: 500;
}

.mehr-link:hover {
  text-decoration: underline;
}

/* --- Pfeilliste -----------------------------------------------------------

   Das Dreieck ist ein Pseudo-Element und kein Zeichen im Text: sonst
   liest ein Screenreader vor jedem Punkt "schwarzes Dreieck nach
   rechts". */

.pfeile {
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
}

.pfeile li {
  position: relative;
  padding-left: 22px;
  color: var(--text-dim);
  font-size: 0.93rem;
  line-height: 1.55;
}

.pfeile li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0.55em;
  border-left: 6px solid var(--accent);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

/* --- FAQ ------------------------------------------------------------------

   <details> statt Javascript. Das Zeichen rechts ist ein
   Pseudo-Element -- im Original stand ein "+" als Text in der
   Zusammenfassung, und das las ein Screenreader vor jeder Frage mit. */

.faq {
  margin-top: 20px;
  border-top: 1px solid var(--border-soft);
}

.faq details {
  border-bottom: 1px solid var(--border-soft);
}

.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.96rem;
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "";
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--text-faint);
  border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.18s ease;
}

.faq details[open] summary::after {
  transform: rotate(225deg) translate(-2px, -2px);
}

.faq summary:hover {
  color: var(--accent-soft);
}

.faq details p {
  margin: 0 0 16px;
  padding-right: 25px;
  font-size: 0.92rem;
  line-height: 1.62;
  color: var(--text-dim);
}

/* Quellen am Beitragsende: ein <details> im .faq-Baukasten (08.10.2026). */
.quellen {
  margin-top: 32px;
}
.quellen summary {
  gap: 8px;
  font-size: 1.05rem;
}
.quellen-zahl {
  margin-right: auto;
  font-weight: 400;
  color: var(--text-faint);
}
.quellen details ul {
  margin: 0 0 18px;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-dim);
}
.quellen details li + li {
  margin-top: 6px;
}

/* --- Hinweiskasten und Nachsatz -------------------------------------------- */

.hinweis {
  margin-top: 18px;
  padding: 18px;
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  background: var(--accent-bg);
}

.hinweis b {
  display: block;
  margin-bottom: 6px;
  font-size: 0.96rem;
}

.hinweis p {
  margin: 0 0 14px;
  font-size: 0.9rem;
  line-height: 1.58;
  color: var(--text-dim);
}

.hinweis p:last-child {
  margin-bottom: 0;
}

.nachsatz {
  margin: 18px 0 0;
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text-faint);
}

.nachsatz a {
  color: var(--accent-soft);
}

/* --- Person ---------------------------------------------------------------- */

.person {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 24px;
}

/* Breite und Hoehe stehen am <img>, damit beim Laden nichts springt.
   aspect-ratio haelt den Zuschnitt, wenn das Bild schmaler wird. */
.person-bild {
  flex: 0 0 auto;
  width: 92px;
  height: 92px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 22%;
  border: 1px solid var(--border);
}

.person-name {
  margin: 0;
  font-weight: 600;
}

.person-rolle {
  margin: 2px 0 14px;
  font-size: 0.88rem;
  color: var(--text-dim);
}

.person-text p:last-child {
  margin: 0;
}

/* --- Ein schmaler Kopf ----------------------------------------------------

   Impressum, Datenschutz und Kontakt haben keinen Aufmacher, nur einen
   Titel. Der grosse Abstand des Heldenkopfs waere dort eine Behauptung. */

.hero-schmal {
  padding-bottom: 26px;
}

.hero-schmal h1 {
  font-size: clamp(1.7rem, 4vw, 2.4rem);
}

/* --- Rechtstext -----------------------------------------------------------

   Impressum und Datenschutzerklaerung. Bewusst schmal: 4616 Woerter
   ueber die volle Breite liest niemand. 68 Zeichen pro Zeile ist die
   Spanne, in der das Auge die naechste Zeile noch findet. */

.rechtstext {
  max-width: 68ch;
}

.rechtstext h2 {
  margin: 34px 0 10px;
  font-size: 1.22rem;
  letter-spacing: -0.018em;
  line-height: 1.3;
}

.rechtstext h3 {
  margin: 26px 0 8px;
  font-size: 1.02rem;
  letter-spacing: -0.012em;
}

.rechtstext h2:first-child,
.rechtstext h3:first-child,
.rechtstext p:first-child {
  margin-top: 0;
}

.rechtstext p {
  margin: 0 0 16px;
  color: var(--text-dim);
  line-height: 1.72;
}

.rechtstext strong {
  color: var(--text);
  font-weight: 600;
}

.rechtstext ul,
.rechtstext ol {
  margin: 0 0 16px;
  padding-left: 22px;
  color: var(--text-dim);
}

.rechtstext li {
  margin-bottom: 7px;
  line-height: 1.66;
}

/* Die Verweise in der Datenschutzerklaerung sind teils volle Adressen
   (eur-lex.europa.eu/legal-content/...?uri=celex%3A32016R0679) und
   sprengen sonst auf dem Telefon die Zeile. */
.rechtstext a {
  color: var(--accent-soft);
  text-underline-offset: 2px;
  overflow-wrap: anywhere;
}

/* --- Kennzahlen ------------------------------------------------------------ */

.zahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin: 0;
}

.zahlen > div {
  padding: 18px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}

.zahlen dt {
  font-size: clamp(1.4rem, 3.4vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--accent);
  line-height: 1.1;
}

.zahlen dd {
  margin: 7px 0 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--text-dim);
}

/* --- Diagramm --------------------------------------------------------------

   Das SVG bringt seine eigene Hoehe mit (320) und skaliert ueber die
   Breite. Der Kasten faengt schmale Fenster ab: unter etwa 560 Pixeln
   werden die Monatsnamen sonst zu Strichen. */

.diagramm {
  margin-top: 18px;
  padding: 14px 0;
  overflow-x: auto;
}

.diagramm svg {
  display: block;
  min-width: 560px;
}

.legende {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 0;
  font-size: 0.84rem;
  color: var(--text-dim);
}

.legende-balken,
.legende-linie {
  display: inline-block;
  flex: 0 0 auto;
}

.legende-balken {
  width: 11px;
  height: 11px;
  border-radius: 2px;
  background: var(--accent);
  opacity: 0.22;
}

.legende-linie {
  width: 16px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--accent);
  margin-left: 12px;
}

/* Die Anfuehrungszeichen als Pseudo-Element statt im Text: im Original
   standen sie als Zeichen im Absatz, und ein Screenreader liest
   "Anfuehrungszeichen unten" mit. Das <blockquote> sagt schon, dass es
   ein Zitat ist. */
.stimmen blockquote p {
  margin: 0 0 12px;
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--text-dim);
}

/* --- Erreichbarkeit -------------------------------------------------------- */

.erreichbar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin: 0;
}

.erreichbar > div {
  padding: 18px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}

.erreichbar dt {
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: 8px;
}

.erreichbar dd {
  margin: 0;
  line-height: 1.6;
  color: var(--text);
}

.erreichbar a {
  color: var(--accent-soft);
  text-decoration: none;
}

.erreichbar a:hover {
  text-decoration: underline;
}

/* --- Formular --------------------------------------------------------------

   Die Beschriftung steht ueber dem Feld und ist ein echtes <label> mit
   for -- kein Platzhaltertext. Ein Platzhalter verschwindet, sobald
   jemand tippt, und wer dann nicht mehr weiss, was in das Feld gehoert,
   hat Pech. */

.formular {
  max-width: 40rem;
  margin-top: 20px;
  /* Ziel von /kontakt/?paket=...#formular: sonst verdeckt die klebende
     Kopfzeile die Zeile "Anfrage zu: ..." ganz oben im Formular. */
  scroll-margin-top: 92px;
}

.feld {
  margin: 0 0 18px;
}

.feld label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.9rem;
  font-weight: 600;
}

.pflicht {
  color: var(--accent);
}

.feld-hinweis {
  display: block;
  margin: -2px 0 6px;
  font-size: 0.8rem;
  color: var(--text-faint);
}

.feld input,
.feld textarea {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.94rem;
}

.feld textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.6;
}

.feld input:focus-visible,
.feld textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: transparent;
}

.feld-abschluss {
  margin: 0 0 14px;
}

.feld-abschluss .knopf {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  padding: 11px 22px;
}

/* Der Honigtopf. Nicht display:none -- manche Spam-Programme erkennen
   das und lassen das Feld dann in Ruhe, womit der Zweck verfehlt waere.
   Stattdessen aus dem Bild geschoben. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Karten reagieren jetzt auch --------------------------------------------

   Dieselbe Bewegung wie bei den Chips: Rahmen in den Akzent, Grund eine
   Stufe heller. Auch hier kein Zeiger und kein Anheben -- die meisten
   dieser Karten fuehren nirgendwohin. Die eine, die es tut (Backlink
   Checker), traegt einen richtigen Verweis in der Ueberschrift, und der
   hat seinen eigenen Zeiger. */
@media (hover: hover) {
  .karte,
  .zahlen > div,
  .stimmen blockquote,
  .erreichbar > div {
    transition:
      border-color 0.16s ease,
      background-color 0.16s ease;
  }

  .karte:hover,
  .zahlen > div:hover,
  .stimmen blockquote:hover,
  .erreichbar > div:hover {
    border-color: var(--accent-line);
    background: var(--surface-3);
  }
}


/* ==========================================================================
   Die Startseite als Produktseite

   Bis hierher war das Magazin ein Textkleid: Aufmacher, Absaetze,
   Karten. Die Startseite soll zeigen, dass hinter cyberscale eine
   Anwendung steht -- also steht das Produkt oben, nicht die
   Selbstbeschreibung.
   ========================================================================== */

/* --- Das Band unter der Kopfleiste (22.09.2026) ---------------------------

   Ein erzeugtes Bild ueber die volle Fensterbreite, NUR auf der Startseite.
   Es steht in bauen.mjs ausserhalb von <main class="mag-huelle"> -- nur so
   laeuft es bis an beide Fensterraender und setzt die dunkle Kopfleiste nach
   unten fort. Deshalb keine abgerundeten Ecken und kein Rand.

   DAS BILD IST 3:1, DAS BAND IST FLACHER. Ueber die volle Breite waeren 3:1
   auf einem 1400er Schirm 467 Pixel -- und darunter faengt der Aufmacher an,
   mit Ueberschrift, Pruef-Feld und Produktbild. Das ist der Einstieg der
   Seite und soll im ersten Blick bleiben. 13vw zeigen rund 39 Prozent des
   Bildes, auf jeder Breite gleich viel.

   DER HOEHENDECKEL IST EINE FALLE. Die vw-Angabe haelt den sichtbaren Anteil
   konstant; ein zu niedriger Deckel hebt das ab einer bestimmten Breite
   wieder auf, und dann steht ein Streifen quer durch das Motiv statt des
   Motivs. 360 Pixel greifen erst ab 2770 Pixel Fensterbreite -- auf dem
   32-Zoeller (2560) sind es noch die vollen 13vw. Wer den Deckel senkt, baut
   den Fehler nach: immer bei 2560 nachsehen, nicht nur bei 1400.

   object-position 50 %: Der Gipfel steht in der oberen Bildhaelfte, die
   Taeler duerfen unten heraus.

   Der Grund steht fest auf #0d0d0f statt auf var(--bg): Das Bild ist ein
   Rasterbild und bleibt im hellen Thema dunkel -- der Streifen hinter ihm
   muss es dann auch sein, sonst blitzt beim Laden eine helle Kante auf.

   Keinen eigenen Abstand nach unten: .mag-huelle bringt ihre 34 Pixel
   Innenabstand schon mit. */

.startband {
  background: #0d0d0f;
}

.startband img {
  display: block;
  width: 100%;
  height: clamp(120px, 13vw, 360px);
  object-fit: cover;
  object-position: center 50%;
}

/* --- Der Aufmacher mit Produktbild ---------------------------------------- */

.hero-produkt {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 34px;
  align-items: center;
  position: relative;
}

/* Der Schimmer.

   Ein weicher Schein im Akzent hinter der Ueberschrift -- der einzige
   Verlauf auf der ganzen Seite, und der einzige Ort, an dem er etwas
   tut: er hebt den Aufmacher vom Rest ab, ohne eine zweite Farbe
   einzufuehren.

   Als Pseudo-Element und nicht als Hintergrund am Abschnitt: so kann er
   ueber den Rand hinausragen, ohne die Breite der Seite zu aendern.
   pointer-events: none, damit er nichts abfaengt, was darunter liegt.

   UMGEBAUT AM 29.08.2026. Vorher war es EIN Verlauf mit drei Stopps und
   `closest-side` auf einem 677x622-Kasten. Drei Dinge stimmten daran
   nicht, alle im Browser nachgemessen:

   1. `closest-side` macht daraus einen KREIS mit 311 Pixeln Radius --
      die 130 Prozent Hoehe waren wirkungslos, der Verlauf lief laengst
      aus, bevor er den Kasten fuellte.
   2. Drei Stopps ueber 622 Pixel auf fast schwarzem Grund geben
      sichtbare Streifen. Ein Schein hat keine Kanten.
   3. `transparent` ist in CSS rgba(0,0,0,0) -- WEISS. Zwischen Orange
      und durchsichtigem SCHWARZ zu interpolieren zieht die Mitte ins
      Graue; deshalb sah der Rand schmutzig aus statt weich. Dafuer gibt
      es jetzt --schimmer-null: dieselbe Farbe mit Alpha 0.

   Jetzt zwei Lagen statt einer: ein enger Kern hinter Kopfzeile und
   Ueberschrift, darunter ein weiter, sehr schwacher Hof. Der Kern gibt
   dem Licht eine Quelle, der Hof haelt ihn davon ab, als Fleck zu enden.
   Prozentuale Ellipsen (`38% 34% at 30% 42%`) statt `closest-side`: so
   folgt die Form dem Kasten und nicht seiner kuerzesten Seite. */
.hero-produkt::before {
  content: "";
  position: absolute;
  inset: -44% -18% -28% -18%;
  background:
    radial-gradient(
      34% 30% at 28% 44%,
      var(--schimmer-innen),
      var(--schimmer-mitte) 46%,
      var(--schimmer-null) 74%
    ),
    radial-gradient(
      66% 58% at 24% 40%,
      var(--schimmer-aussen),
      var(--schimmer-null) 72%
    );
  pointer-events: none;
  z-index: 0;
}

/* DIE ZWEITE HAELFTE WAR UNBELEUCHTET. Links ein Schein, rechts das
   Produktbild auf flacher Flaeche -- zwei Haelften, die aussehen, als
   staenden sie nicht im selben Raum. Ein sehr schwacher Schein unter dem
   Rahmen setzt ihn auf die Flaeche, statt ihn hineinzukleben.

   Deutlich schwaecher als der Kern: er soll das Bild tragen, nicht mit
   ihm um Aufmerksamkeit streiten. Erst ab zwei Spalten -- untereinander
   liegt der Rahmen woanders und der Schein daneben. */
@media (min-width: 1160px) {
  .hero-produkt::after {
    content: "";
    position: absolute;
    inset: 30% -14% -34% 44%;
    background: radial-gradient(
      58% 62% at 58% 62%,
      var(--schimmer-aussen),
      var(--schimmer-null) 70%
    );
    pointer-events: none;
    z-index: 0;
  }
}

.hero-produkt > * {
  position: relative;
  z-index: 1;
}

.hero-text-spalte {
  min-width: 0;
}

/* DIE UNTERZEILE BRAUCHT HIER MEHR MASS ALS AUF DEN LEISTUNGSSEITEN.

   34ch stimmen dort: eine kurze Zeile unter einer Ueberschrift, ueber die
   volle Huellenbreite. Im Aufmacher mit Produktbild steht sie in einer
   Spalte, die selbst schon schmal ist -- und der Satz
   „Alles aus einer Hand — ohne Agentur-Theater, ohne Account-Manager
   dazwischen" brach damit NACH DEM BINDESTRICH um: „ohne Agentur-" /
   „Theater,". Ein Wortverbund, in der Mitte auseinandergerissen, an der
   zweitwichtigsten Zeile der Seite.

   42ch fassen den Satz in zwei Zeilen, ohne dass er ueber die Spalte
   hinauswaechst. text-wrap: balance verteilt sie gleichmaessig. */
.hero-produkt .hero-sub {
  max-width: 42ch;
  text-wrap: balance;
}

/* Haelt einen Wortverbund ueber den Zeilenumbruch zusammen. Sparsam
   einsetzen: was zusammenbleibt, kann eine Zeile ueberlaufen lassen. */
.zusammen {
  white-space: nowrap;
}

/* Damit die Fussnote unter dem Feld keine einzelne Waise auf der letzten
   Zeile stehen laesst. `pretty` und nicht `balance`: bei drei Zeilen
   Kleingedrucktem geht es um das Zeilenende, nicht um gleiche Laengen. */
.hero-produkt .hero-fussnote {
  max-width: 52ch;
  text-wrap: pretty;
}

.hero-fussnote {
  margin: 14px 0 0;
  font-size: 0.84rem;
  color: var(--text-faint);
}

/* Der leise zweite Knopf. Er soll da sein, aber nicht mit dem ersten
   um Aufmerksamkeit streiten. */
.knopf-leise {
  background: transparent;
  color: var(--text-dim);
}

/* --- Der Produktrahmen -----------------------------------------------------

   Das SVG bringt seinen eigenen Fensterrahmen mit (drei Punkte, Titel,
   Trennlinie). Der Rahmen hier setzt es nur ab und gibt ihm einen
   Schatten, damit es auf der Flaeche liegt statt in ihr zu kleben. */

.produkt-rahmen {
  min-width: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  line-height: 0;
}

.produkt-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Zwei Spalten erst dann, wenn der Aufmacher auch heraustreten darf --
   dieselbe Schwelle wie unten.

   Dazwischen (900 bis 1160) waere die Bildspalte 441 Pixel breit, und
   ein Dashboard mit drei Kacheln und einer Kurve wird darin zur
   Briefmarke. Untereinander ist es dort 852 Pixel breit und damit
   lesbar. Lieber ein hoher Aufmacher als ein unleserliches Bild. */
@media (min-width: 1160px) {
  .hero-produkt {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: 44px;
  }
}

/* --- Das Zahlenband --------------------------------------------------------

   Dieselben Kacheln wie auf der Case-Study-Seite, nur enger: hier sind
   sie ein Beleg im Vorbeigehen, dort der Inhalt des Abschnitts. */

.zahlenband {
  padding-top: 34px;
}

.zahlenband .zahlen > div {
  padding: 15px 16px;
}

.zahlenband .zahlen dt {
  font-size: clamp(1.25rem, 2.8vw, 1.6rem);
}

.zahlenband .nachsatz {
  margin-top: 12px;
}

.zahlenband .nachsatz a {
  color: var(--accent-soft);
}

/* --- Das Werkzeug-Raster ---------------------------------------------------

   Zehn Kacheln, jede ein Verweis in die App. Anders als .karte sind das
   echte Verweise, also duerfen sie den Zeiger und die Hebung haben --
   hier fuehrt jede Kachel wirklich irgendwohin. */

.werkzeuge {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  margin-top: 22px;
}

.werkzeug {
  display: block;
  padding: 16px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
}

.werkzeug-zeichen {
  display: block;
  width: 20px;
  height: 20px;
  color: var(--accent);
  margin-bottom: 10px;
}

.werkzeug b {
  display: block;
  font-size: 0.95rem;
  color: var(--text);
  margin-bottom: 5px;
}

.werkzeug span {
  display: block;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text-dim);
}

@media (hover: hover) {
  .werkzeug {
    transition:
      border-color 0.16s ease,
      background-color 0.16s ease,
      transform 0.16s ease;
  }

  .werkzeug:hover {
    border-color: var(--accent-line);
    background: var(--surface-3);
    transform: translateY(-2px);
  }
}

/* Der Aufmacher der Startseite darf breiter sein als der Text darunter.

   Die Huelle haelt 900px, weil Fliesstext darueber schlecht lesbar wird.
   Fuer ein Produktbild gilt das nicht -- ein Dashboard in 440 Pixeln ist
   ein Briefmarke. Ab 1160px Fensterbreite tritt der Aufmacher links und
   rechts um 120px heraus; darunter bleibt er in der Spur, sonst
   schoebe er die Seite auf.

   Nur der Aufmacher und das Werkzeug-Raster, nicht der Fliesstext. */
@media (min-width: 1160px) {
  /* Hier stand der -120px-Ausbruch, siehe Begruendung weiter unten. */

  /* `.artikel-breit` ist am 02.09.2026 entfallen -- siehe oben. Sie liess
     Beitraege mit Tabelle aus der Karte heraustreten, damit die Tabelle
     breiter sein konnte. Seit die Tabelle so breit ist wie der Text, gaebe
     es nichts mehr, was den Zugewinn nutzt: uebrig bliebe die leere Karte,
     gegen die die Klasse ueberhaupt eingefuehrt wurde. */
}

/* Das Aenderungsdatum steht unter dem Erscheinungsdatum, nicht daneben.

   51 der 56 Beitraege wurden nach dem Erscheinen ueberarbeitet, und wer
   einen Text von Dezember liest, will wissen, ob er noch gilt. In einer
   Zeile mit Datum und Lesezeit ginge die Angabe unter. */
.artikel-aktualisiert {
  display: block;
  margin-top: 4px;
  font-size: 0.8rem;
  color: var(--text-ghost);
}

/* --- Die Autorenbox --------------------------------------------------------

   Steht am Ende des Beitrags, abgesetzt durch eine Linie. Ein Text mit
   Absender ist mehr wert als einer ohne -- und auf einer Seite, die SEO
   verkauft, sollte sichtbar sein, wer hinter den Texten steht. */

.autor {
  margin-top: 38px;
  /* Seitlich dieselben 34 Pixel wie der Textblock, damit Portraet und
     Name auf der Flucht des Fliesstexts stehen. Die Trennlinie darueber
     darf breiter sein -- eine Linie, die etwas abschliesst, soll das
     ganze Feld abschliessen. */
  padding: 26px 34px 0;
  border-top: 1px solid var(--border-soft);
}

/* Person: Portraet und Name nebeneinander, Text und Wege darunter ueber
   die volle Breite -- der Absatz bekommt so seine 62 Zeichen, statt neben
   dem Bild in eine schmale Spalte gedrueckt zu werden. */
.autor-person {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
}

.autor-bild {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 22%;
  border: 1px solid var(--border);
}

.autor-name {
  margin: 0;
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}

.autor-rolle {
  margin: 2px 0 0;
  font-size: 0.86rem;
  color: var(--text-faint);
}

.autor-text {
  margin: 0 0 14px;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--text-dim);
  max-width: 62ch;
}

.autor-wege {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}

.autor-wege a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 32px;
  color: var(--accent-soft);
  text-decoration: none;
}

.autor-wege a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Die beiden Profile tragen ihr Logo -- in der Farbe des Verweises, damit
   sie zur Seite gehoeren und nicht wie eingeklebte Fremdknoepfe wirken. */
.autor-logo {
  width: 17px;
  height: 17px;
  flex: none;
}

/* --- Offener Code: das, was die Box von einer Visitenkarte unterscheidet.
   Drei echte Repos als Beleg fuer "schreibt die Werkzeuge selbst". Die
   Namen in Mono, weil sie Bezeichner sind, die man so tippen wuerde. */
.autor-code {
  margin-top: 20px;
  padding: 14px 16px 6px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--surface-2, transparent);
}

.autor-code-titel {
  margin: 0 0 8px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

/* Ein Raster fuer alle drei Zeilen (li als display: contents), damit die
   Beschreibungen auf einer Flucht beginnen statt hinter jedem Namen neu. */
.autor-repos {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline;
  gap: 12px 16px;
  margin: 0;
  padding: 0 0 10px;
  list-style: none;
}

.autor-repos li {
  display: contents;
}

.autor-repos a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--accent-soft);
  text-decoration: none;
}

.autor-repos a:hover .autor-repo-name {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.autor-repo-logo {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--text-faint);
}

.autor-repo-name {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.84rem;
}

.autor-repo-text {
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--text-dim);
}

.autor a:focus-visible {
  outline: 2px solid var(--accent-soft);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (max-width: 640px) {
  .autor {
    margin-left: 20px;
    margin-right: 20px;
    padding-left: 0;
    padding-right: 0;
  }
  .autor-bild {
    width: 56px;
    height: 56px;
  }
  .autor-repos {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 2px;
  }
  .autor-repo-text {
    padding-left: 22px;
    margin-bottom: 10px;
  }
}

/* --- Die Diensttabelle der DSGVO-Serie -------------------------------------

   Steht nur auf der Nabe unter /dsgvo/. Die Ampel ist ein Punkt und kein
   Wort in Farbe: Farbe allein darf die Aussage nicht tragen -- wer sie
   nicht unterscheiden kann, liest die Spalte daneben, und dort steht
   dasselbe in Worten. */

.dienste-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.dienste-tabelle th,
.dienste-tabelle td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}

.dienste-tabelle th {
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-faint);
  white-space: nowrap;
}

.dienste-tabelle td:nth-child(1) {
  white-space: nowrap;
  font-weight: 600;
}

/* Die Verweise brauchen ihre Farbe hier ausdruecklich. Ausserhalb von
   .prosa greift die Regel von dort nicht, und der Browser nimmt dann sein
   eigenes Dunkelblau -- auf schwarzem Grund praktisch unlesbar. */
.dienste-tabelle a {
  color: var(--accent-soft);
  text-underline-offset: 2px;
}

.dienste-tabelle td:nth-child(2),
.dienste-tabelle td:nth-child(3) {
  color: var(--text-dim);
}

/* Ohne Mindestbreite bricht "laeuft meist ohne Grundlage" auf drei Zeilen
   um, waehrend der Punkt allein auf der ersten steht. Zwei Zeilen sind in
   Ordnung, drei sehen nach Unfall aus. */
.dienste-tabelle td:nth-child(3) {
  min-width: 11rem;
}

/* Die letzte Spalte traegt den Satz und darf als einzige umbrechen --
   ohne diese Breite zieht sie die Tabelle ueber den Bildschirm hinaus,
   und der Rahmen scrollt, wo er nicht muesste. */
.dienste-tabelle td:nth-child(4) {
  min-width: 22rem;
  color: var(--text-dim);
}

.dienste-tabelle tr:last-child td {
  border-bottom: 0;
}

.ampel {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: 1px;
}

.ampel-rot { background: var(--danger); }
.ampel-gelb { background: var(--warn); }
.ampel-gruen { background: var(--success); }

/* --- Kommentare ------------------------------------------------------------

   Derselbe Rahmen wie die Autorenbox darueber: Trennlinie, 34 Pixel
   seitlich, auf der Flucht des Fliesstexts. Der Bereich schliesst den
   Beitrag ab, er ist kein eigener Abschnitt der Seite.

   DIE ZEILENBREITE STEHT AUF DEN KINDERN, NICHT AUF DEM ABSCHNITT --
   dieselbe Lehre wie bei .prosa weiter oben. Waere sie am Abschnitt,
   muesste jede spaetere breite Sache (eine Sortierung, eine Seitenzahl)
   sich wieder herausrechnen. */

.kommentare {
  margin-top: 34px;
  padding: 26px 34px 4px;
  border-top: 1px solid var(--border-soft);
}

.kommentar-kopfzeile {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 18px;
}

.kommentar-kopfzeile h2 {
  margin: 0;
  font-size: 1.15rem;
  letter-spacing: -0.018em;
}

/* Leer, solange nichts geladen ist -- und leer bleibt es auch, wenn ein
   Beitrag keine Kommentare hat. Eine Null unter jedem der 76 Beitraege
   waere eine Bilanz, die niemand sehen will. */
.kommentar-zahl {
  font-size: 0.84rem;
  color: var(--text-faint);
}

.kommentar-liste {
  list-style: none;
  margin: 0 0 26px;
  padding: 0;
  max-width: 68ch;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.kommentar {
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--surface);
}

.kommentar-kopf {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 6px;
}

.kommentar-name {
  font-size: 0.92rem;
}

.kommentar-datum {
  font-size: 0.78rem;
  color: var(--text-ghost);
}

.kommentar-text p,
.kommentar-antwort p {
  margin: 0 0 8px;
  font-size: 0.94rem;
  line-height: 1.65;
}

.kommentar-text p:last-child,
.kommentar-antwort p:last-child {
  margin-bottom: 0;
}

/* Die Antwort der Redaktion: eingerueckt an einer Akzentkante, keine
   zweite Karte. Sie gehoert zu diesem Kommentar -- eine eigene Karte
   liesse offen, worauf sie sich bezieht. */
.kommentar-antwort {
  margin-top: 12px;
  padding-left: 14px;
  border-left: 2px solid var(--accent-line);
}

.kommentar-antwort-kopf {
  margin: 0 0 5px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--accent);
}

.kommentar-form {
  max-width: 68ch;
}

.kommentar-form .feld-hinweis code {
  font-size: 0.86em;
  color: var(--text-dim);
}

/* Die Rueckmeldung nach dem Absenden. role="status" steht im HTML, damit
   ein Screenreader sie vorliest -- ohne das waere fuer ihn nach dem Klick
   nichts passiert. */
.kommentar-meldung {
  margin: 12px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.89rem;
  line-height: 1.55;
}

.kommentar-meldung-gut {
  border-color: rgba(95, 216, 143, 0.34);
  background: var(--success-bg);
}

.kommentar-meldung-warn {
  border-color: rgba(242, 184, 77, 0.34);
  background: var(--warn-bg);
}

.kommentar-fuss {
  max-width: 68ch;
  margin: 18px 0 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--text-faint);
}

.kommentar-fuss a {
  color: var(--text-dim);
}

@media (max-width: 640px) {
  .kommentare {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/* --- Newsletter-Anmeldung --------------------------------------------------

   Steht unter dem Beitrag und auf der Blog-Uebersicht, nicht auf den
   Leistungsseiten: wer dort liest, will ein Angebot, keinen Newsletter.

   Abgesetzt im Akzent-Grund, damit sie sich vom Text abhebt, ohne wie
   ein Werbebanner zu schreien -- derselbe Kasten wie .hinweis auf der
   Tools-Seite. */

.newsletter {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 22px 32px;
  align-items: end;
  margin-top: 38px;
  padding: 24px 26px;
  border: 1px solid var(--accent-line);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--accent-bg);
}

/* Dieselbe Kapitaelchen-Zeile wie "Kurz gesagt": man erkennt den Kasten
   als Teil der Seite, nicht als fremdes Werbebanner. */
.newsletter-marke {
  margin: 0 0 6px;
  font-family: var(--anzeige);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}

.newsletter h2 {
  margin: 0 0 8px;
  font-family: var(--anzeige);
  font-size: 1.32rem;
  line-height: 1.2;
  letter-spacing: -0.016em;
  color: var(--text);
}

.newsletter-text {
  margin: 0 0 14px;
  font-size: 0.95rem;
  line-height: 1.58;
  color: var(--text-dim);
  max-width: 52ch;
}

.newsletter-themen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.newsletter-themen li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px 4px 9px;
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.82rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--text);
}

.newsletter-themen svg {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Sichtbare Beschriftung: der Platzhalter verschwindet beim Tippen und
   zaehlt fuer Screenreader nicht als Name. */
.newsletter-form label {
  display: block;
  margin: 0 0 6px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

.newsletter-zeile {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.newsletter-zeile input {
  flex: 1 1 9rem;
  min-width: 0;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 1rem;
}

.newsletter-zeile input::placeholder {
  color: var(--text-ghost);
}

.newsletter-zeile input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: transparent;
}

.newsletter-zeile button {
  flex: 0 0 auto;
  min-height: 44px;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
}

.newsletter-hinweis {
  margin: 10px 0 0;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--text-faint);
}

.newsletter-hinweis a {
  color: var(--accent-soft);
}

/* Falle fuer Formular-Bots: fuer Menschen unsichtbar und nicht per Tab
   erreichbar (tabindex -1, aria-hidden). Nicht display:none -- manche Bots
   ueberspringen versteckte Felder genau daran. */
.newsletter-falle {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.newsletter-status:empty {
  display: none;
}

.newsletter-status {
  margin: 10px 0 0;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  line-height: 1.5;
}

.newsletter-status.ist-ok {
  border: 1px solid var(--accent-line);
  background: var(--surface);
  color: var(--text);
}

.newsletter-status.ist-fehler {
  border: 1px solid #c2410c;
  background: var(--surface);
  color: var(--text);
}

.newsletter-zeile button:disabled {
  opacity: 0.7;
  cursor: default;
}

@media (max-width: 760px) {
  .newsletter {
    grid-template-columns: 1fr;
    align-items: start;
  }
}

@media (max-width: 640px) {
  .newsletter {
    margin-left: 20px;
    margin-right: 20px;
    padding: 20px 18px;
  }
}

/* --- Suche und Themenschalter in der Kopfzeile -----------------------------

   Die Suche sass zuerst im Koerper der Blog-Uebersicht. Jetzt steht sie
   in der Leiste und ist damit auf allen 71 Seiten erreichbar statt auf
   einer -- zwei Suchfelder auf derselben Seite waeren eine Zumutung
   gewesen, deshalb ist das alte weg.

   Als Knopf, nicht als dauerhaft offenes Feld: die Leiste traegt bereits
   acht Menuepunkte und den Werkzeug-Knopf. Ein Eingabefeld daneben
   draengt das Menue auf einem 1000 Pixel breiten Bildschirm in die
   zweite Zeile. */

.kopf-knoepfe {
  display: flex;
  align-items: center;
  gap: 6px;
  /* auto statt 8px: die Gruppe steht an der rechten Kante. Mit Anmelden
     endete sie zufaellig fast dort, ohne standen 94 px leer. */
  margin-left: auto;
}

.kopf-knopf {
  display: none; /* kopf.js macht sie sichtbar */
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
}

.kopf-knopf[hidden] {
  display: none;
}

.kopf-knopf:not([hidden]) {
  display: flex;
}

.kopf-knopf:hover {
  border-color: var(--accent-line);
  color: var(--text);
}

.kopf-knopf:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.kopf-knopf svg {
  width: 17px;
  height: 17px;
}

/* Im dunklen Satz die Sonne, im hellen der Mond: das Zeichen zeigt, wohin
   es geht, nicht wo man ist. Beide liegen im Markup, sichtbar geschaltet
   wird per CSS -- so gibt es keinen Moment, in dem das falsche zu sehen
   ist. */
.thema .mond {
  display: none;
}

:root[data-theme="hell"] .thema .sonne {
  display: none;
}

:root[data-theme="hell"] .thema .mond {
  display: block;
}

/* Die aufgeklappte Suche. Sie haengt unter der Leiste und nicht mitten
   auf dem Bild: die Leiste klebt oben, also ist das der Ort, an dem der
   Blick nach dem Klick ohnehin steht. */
.suchlage {
  border-top: 1px solid var(--border-soft);
  background: var(--surface);
}

.suchlage[hidden] {
  display: none;
}

.suchlage-innen {
  max-width: 1180px;
  margin: 0 auto;
  padding: 14px 26px 18px;
}

.suchzeile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-faint);
}

.suchzeile:focus-within {
  border-color: var(--accent);
  color: var(--accent);
}

.suchzeile svg {
  flex: none;
  width: 17px;
  height: 17px;
}

.suchzeile input {
  flex: 1;
  min-width: 0;
  padding: 12px 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
}

.suchzeile input:focus {
  outline: none;
}

.suchzeile input::placeholder {
  color: var(--text-faint);
}

/* Ein <label>, das nur der Screenreader hoert. Weglassen ginge nicht --
   ein Feld ohne Label ist namenlos, und ein Platzhalter zaehlt nicht als
   Name. */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.such-treffer {
  display: block;
  margin-top: 6px;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--text);
}

.such-treffer:hover,
.such-treffer:focus-visible {
  background: var(--surface-2);
  outline: none;
}

.such-treffer:focus-visible {
  box-shadow: inset 0 0 0 2px var(--accent);
}

.such-treffer b {
  display: block;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.35;
}

.such-treffer span {
  display: block;
  margin-top: 2px;
  font-size: 0.78rem;
  color: var(--text-faint);
}

/* Die Trefferzahl steht in einem role="status" -- ein Screenreader soll
   mitbekommen, dass sich die Liste geaendert hat, ohne dass jemand
   dorthin navigiert. Deshalb bleibt der Absatz auch leer im Markup
   stehen: ein Element, das erst beim ersten Treffer entsteht, wird
   nicht vorgelesen. */
.suchstand {
  margin: 10px 0 0;
  min-height: 1.4em;
  font-size: 0.86rem;
  color: var(--text-faint);
}

@media (max-width: 600px) {
  .suchlage-innen {
    padding: 12px 18px 16px;
  }
}

/* ==========================================================================
   DER HELLE SATZ

   Die dunklen Token stehen nicht hier -- bauen.mjs zieht sie aus app.css
   und setzt sie oben an diese Datei. Hier stehen nur die Abweichungen
   fuer hell, und zwar unter [data-theme="hell"]: dunkel bleibt der
   Grundzustand.

   SEIT DER MISCHVARIANTE (27.09.2026) IST HELL DIE VORGABE der Website:
   huelle() in bauen.mjs schreibt data-theme="hell" ins <html>, dunkel
   ist die gespeicherte Wahl ueber den Schalter. Die App bleibt dunkel --
   der Bruch, den der naechste Absatz fuerchtet, ist jetzt Absicht und
   wird von der Website selbst aufgefangen: Kopfleiste, Aufmacher und
   Fuss sind auch im hellen Satz dunkel (siehe "DIE MISCHVARIANTE" am
   Ende dieser Datei). Wer von www in die App wechselt, sieht dieselbe
   dunkle Leiste weiterlaufen.

   WARUM NICHT prefers-color-scheme ALS VORGABE: die Werkzeug-App unter
   app.cyberscale.io ist rein dunkel. Wuerde www dem Systemwunsch folgen,
   saehe jemand mit heller Einstellung eine helle Website und daneben
   eine dunkle App -- derselbe Anbieter, zwei Welten. Solange die App
   nicht mitzieht, ist dunkel die Vorgabe und hell eine bewusste Wahl.
   Umstellen ist eine Zeile in thema.js.

   ZWEI TOKEN SIND NEU und gab es im dunklen Satz gar nicht:
   --band     der Hintergrund der klebenden Kopfzeile. Der stand vorher
              als rgba(13,13,15,.86) fest in der Datei und waere im
              hellen Modus als dunkler Balken stehen geblieben.
   --schimmer der Schein hinter dem Aufmacher, hell schwaecher als
              dunkel -- auf Weiss traegt derselbe Wert viel weiter.

   --band UND --auf-akzent STEHEN SEIT DEM 25.08.2026 NICHT MEHR HIER,
   sondern im :root von app.css, den der Bau dieser Datei voranstellt.
   Grund: die Werkzeug-App traegt seit Variante B dieselbe Kopfleiste
   und braucht dieselben zwei Werte. Zweimal gepflegt waeren sie zwei
   verschieden dunkle Balken, einer je Seite. Der helle Satz unten
   ueberschreibt sie weiterhin -- er steht spaeter in der Datei.

   Der Akzent ist im hellen Satz DUNKLER als im dunklen. #e8590c auf
   Weiss kommt nur auf 3,4:1 und faellt damit unter die Grenze fuer
   Text. Die Marke bleibt dieselbe Farbe, der Text bekommt eine, die man
   lesen kann.
   ========================================================================== */

:root {
  /* Vier Stufen desselben Orange. --null ist der Auslauf: dieselbe Farbe
     mit Alpha 0, damit der Verlauf nicht ueber durchsichtiges Schwarz
     ins Graue laeuft. Siehe Kopf von .hero-produkt::before.

     DIE SPITZE IST AM KONTRAST GEMESSEN, NICHT GESCHAETZT. Der Umbau
     verfuehrt dazu, sie hochzudrehen -- probiert waren 0,20 und 0,18,
     und beide kosteten mehr, als sie brachten:

       innen   Kopfzeile   Unterzeile   Ueberschrift
       0,20    4,59:1      4,67:1       12,4:1
       0,18    4,68:1      4,79:1       12,9:1
       0,16    4,68:1      4,79:1       12,9:1   <- bleibt

     Gemessen wurde der SCHLIMMSTE Punkt ueber jedem Element, nicht
     dessen Mitte. Die Kopfzeile ist mit 12 Pixeln der kleinste Text
     ueber dem Schein und bestimmt damit die Grenze; 4,5:1 ist sie.

     Der Wert bleibt also, wo er war -- die Wirkung kommt aus dem
     Aufbau (Kern, Hof, sauberer Auslauf), nicht aus der Deckkraft.
     Auch das Verschieben des Kerns nach unten wurde durchgerechnet:
     es hilft der Kopfzeile und schadet der Unterzeile genau so viel.

     Wer hier hochgeht, misst nach: der Schein ist an seiner
     staerksten Stelle genau da, wo Text steht. */
  --schimmer-innen: rgba(139, 114, 255, 0.16);
  --schimmer-mitte: rgba(139, 114, 255, 0.09);
  --schimmer-aussen: rgba(139, 114, 255, 0.055);
  --schimmer-null: rgba(139, 114, 255, 0);
}

:root[data-theme="hell"] {
  --bg: #fbfaf8;
  --surface: #ffffff;
  --surface-2: #f3f1ed;
  --surface-3: #e8e5df;
  --border: #d8d4cc;
  --border-soft: #e7e4dd;

  --text: #1b1a18;
  --text-dim: #55524d;
  --text-faint: #67645e;
  --text-ghost: #85817a;

  --accent: #c2450a;
  --accent-soft: #a63a06;
  --accent-bg: rgba(194, 69, 10, 0.08);
  --accent-line: rgba(194, 69, 10, 0.32);

  --success: #16724a;
  --success-bg: rgba(22, 114, 74, 0.1);
  --warn: #8a5a00;
  --warn-bg: rgba(138, 90, 0, 0.12);
  --danger: #b03028;
  --danger-bg: rgba(176, 48, 40, 0.12);

  --band: rgba(251, 250, 248, 0.88);
  --auf-akzent: #ffffff;
  /* Hell traegt derselbe Wert viel weiter -- auf Weiss faellt schon ein
     Zehntel Deckkraft auf. Dieselben vier Stufen, rund halbiert. */
  --schimmer-innen: rgba(194, 69, 10, 0.11);
  --schimmer-mitte: rgba(194, 69, 10, 0.06);
  --schimmer-aussen: rgba(194, 69, 10, 0.035);
  --schimmer-null: rgba(194, 69, 10, 0);

  --shadow: 0 1px 2px rgba(27, 26, 24, 0.06), 0 8px 24px rgba(27, 26, 24, 0.08);
}

/* Beim Umschalten faerbt sich die ganze Seite um. Ohne Uebergang ist das
   ein harter Schnitt; mit einem zu langen wirkt es traege. Wer
   Bewegungsarmut eingestellt hat, bekommt keinen -- dafuer sorgt die
   Regel ganz oben in dieser Datei. */
body.magazin,
.mag-kopf-band,
.artikel,
.karte,
.werkzeug,
.zahlen > div,
.erreichbar > div,
.stimmen blockquote {
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease;
}

/* --- Der Gratis-Download auf der Startseite --------------------------------

   Waagrecht, wo Platz ist, untereinander auf dem Handy. Bewusst ruhiger
   als der Audit-Aufruf darunter: er will nichts ausser einem Klick, und
   zwei gleich laute Aufrufe hintereinander heben sich gegenseitig auf. */

.download-karte {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
  padding: 26px 30px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

/* Der Knopf unter den neuesten Beitraegen auf der Startseite. Er steht als
   Absatz unter der Kartenliste, deshalb braucht er den Abstand selbst --
   die .artikelliste bringt unten keinen mit. Auf dem Telefon ueber die
   volle Breite, dieselbe Regel wie beim Download-Knopf: ein 200 px breiter
   Knopf in einer 335 px breiten Spalte sieht nach Versehen aus. */
.magazin-knopf {
  margin-top: 24px !important;
}

@media (max-width: 600px) {
  .magazin-knopf .knopf {
    display: block;
    text-align: center;
  }
}

@media (max-width: 600px) {
  .download-karte {
    padding: 22px 20px;
    gap: 18px;
  }

  .download-knopf,
  .download-knopf .knopf {
    width: 100%;
    text-align: center;
  }
}

/* --- Das Prueffeld im Aufmacher -------------------------------------------

   Feld und Knopf sitzen in einer gemeinsamen Umrandung, damit sie als ein
   Bedienelement gelesen werden und nicht als zwei Dinge nebeneinander.
   Der Rahmen liegt auf der Zeile, nicht auf dem Feld -- sonst haette man
   zwei Rahmen ineinander, sobald der Knopf danebensteht.

   Auf dem Handy bricht der Knopf unter das Feld und nimmt die volle
   Breite. Ein 90 Pixel breiter Knopf neben einem 180 Pixel breiten Feld
   ist auf beiden Seiten zu wenig. */

.hero-pruefen {
  margin: 22px 0 10px;
}

.hero-pruefen-zeile {
  display: flex;
  gap: 8px;
  padding: 7px;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius-sm) + 7px);
  background: var(--surface);
}

.hero-pruefen-zeile:focus-within {
  border-color: var(--accent);
}

.hero-pruefen input {
  flex: 1;
  min-width: 0;
  padding: 11px 13px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
}

.hero-pruefen input:focus {
  outline: none;
}

/* Nicht --text-ghost: das kommt im dunklen Satz auf 2,5:1 gegen die
   Feldflaeche. Ein Platzhalter ist kein Fliesstext, aber dieser traegt
   das erwartete Format -- wer ihn nicht lesen kann, weiss nicht, was
   hineingehoert. */
.hero-pruefen input::placeholder {
  color: var(--text-faint);
}

.hero-pruefen .knopf {
  flex: none;
  white-space: nowrap;
}

/* Die Fussnote traegt jetzt einen Verweis. Ohne eigene Farbe waere er
   nicht als solcher zu erkennen -- der Absatz ist gedaempft gesetzt. */
.hero-fussnote a {
  color: var(--accent-soft);
}

@media (max-width: 560px) {
  .hero-pruefen-zeile {
    flex-wrap: wrap;
  }

  /* Volle Breite und mindestens 44 Pixel hoch. Der Knopf kam mit dem
     geerbten Innenabstand auf 40 -- unter der Groesse, die man mit dem
     Daumen sicher trifft, und das beim Haupt-Aufruf der Seite. */
  .hero-pruefen .knopf {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 46px;
  }
}

/* --- Marken der eigenen Projekte auf der Startseite -----------------------

   Genommen wird jeweils die favicon-Fassung des Projekts, nicht das
   Logo: beide Projekte legen ihr Logo mit `currentColor` an, damit es die
   Textfarbe der eigenen Seite erbt. Als eigenstaendiges Dokument in einem
   <img> gibt es diese Farbe nicht -- das Zeichen waere unsichtbar oder
   schwarz. Die favicon-Fassungen tragen feste Farben, genau dafuer.

   alt="" mit Absicht: der Name steht als Ueberschrift direkt darunter,
   eine Wiederholung waere fuer Screenreader nur Laerm. */
.projekt-marke {
  display: block;
  width: 40px;
  height: 40px;
  margin-bottom: 14px;
  border-radius: 9px;
}

/* --- Bild in der Beitragskarte -------------------------------------------

   Dasselbe Motiv wie oben im Beitrag, nur kleiner. Kein zweites Bild und
   keine zweite Pflegestelle: `kopfbild()` erzeugt beide.

   Die Karte hat dafuer ihre Innenabstaende verloren -- das Bild soll bis
   an die Kante gehen, der Text nicht. Deshalb das Polster jetzt am Inhalt
   statt an der Karte. */
.artikel-karte {
  padding: 0;
  overflow: hidden;
}

.artikel-karte .kopfbild {
  aspect-ratio: 16 / 7;
  margin: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--border);
}

.artikel-karte .kopfbild svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Die Karte ist 16:7, die Kartenstufe aus kopfbilder.py auch -- cover
   gleicht nur Rundungspixel aus, es schneidet nichts Sichtbares weg. */
.artikel-karte .kopfbild-illu img {
  height: 100%;
  object-fit: cover;
}

.artikel-karte .artikel-datum {
  padding: 14px 18px 0;
}

.artikel-karte b {
  padding: 0 18px;
}

.artikel-karte .artikel-anriss {
  padding: 0 18px 16px;
}

/* ===========================================================================
   STARTSEITE: WERKZEUGKARTEN UND PREISE (03.09.2026)

   Standen zuerst in app.css -- der falschen Datei. Die Website laedt
   magazin.css, app.css gehoert der Werkzeug-App. Sichtbar wurde es sofort:
   die zehn Karten liefen als Fliesstext hintereinander weg.
   =========================================================================== */

/* --- Preistabelle der Startseite (03.09.2026) ------------------------------
   Wird nur ausgeliefert, wenn daten/preise.json Betraege fuehrt und aktiv
   auf true steht -- siehe preisBlock() in build/bauen.mjs. Die Regeln stehen
   trotzdem hier, damit das Scharfschalten eine einzige Aenderung bleibt. */

.preis-gitter {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.preis-karte {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
  padding: 24px;
  /* Spalte, damit der Anfrage-Knopf in allen Karten unten auf einer Linie
     sitzt, egal wie lang die Liste darueber ist. */
  display: flex;
  flex-direction: column;
}

.preis-karte .preis-punkte {
  margin-bottom: 22px;
}

.preis-knopf {
  margin-top: auto;
  text-align: center;
}

.preis-karte.preis-empfohlen {
  border-color: var(--accent);
}

.preis-karte h3 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 1rem;
  margin: 0 0 6px;
}

.preis-marke {
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-bg);
  border-radius: 4px;
  padding: 2px 7px;
}

.preis-zahl {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.6px;
  margin: 0 0 4px;
}

/* "auf Anfrage" ist kein Betrag und soll auch nicht wie einer aussehen --
   sonst liest man es aus dem Augenwinkel als Zahl. */
.preis-zahl.preis-text {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0;
}

.preis-einheit {
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--text-dim);
  margin-left: 5px;
}

.preis-unter {
  font-size: 0.8rem;
  color: var(--text-dim);
  margin: 0 0 18px;
}

.preis-punkte {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 0.8rem;
  color: var(--text-dim);
}

@media (max-width: 800px) {
  .preis-gitter {
    grid-template-columns: 1fr;
  }
}

/* Der Hinweis unter den SEO-Paketen (seiten/seo.html) klebte ohne Abstand
   an den Karten. */
.preis-gitter + .fuehrung {
  margin-top: 24px;
}

/* Zusatzpaket unter dem Gitter (/seo/: KI-Sichtbarkeit): Text links,
   eine Karte rechts. */
.preis-gitter + .preis-zusatz,
.preis-zusatz + .fuehrung {
  margin-top: 24px;
}

.preis-zusatz {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px 32px;
  align-items: start;
}

.preis-zusatz > div:first-child h3 {
  margin: 8px 0 10px;
}

@media (max-width: 800px) {
  .preis-zusatz {
    grid-template-columns: 1fr;
  }
}

/* --- Der Agenturblock am Seitenende (03.09.2026) --------------------------
   Ein Kasten, kein Abschnitt: Text links, ein Weg rechts. Er soll nicht mit
   den Produktabschnitten darueber um Aufmerksamkeit ringen, aber auch nicht
   wie ein Nachtrag aussehen, den niemand anklicken kann. */

.agentur-block {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 22px;
  padding: 24px 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
}

.agentur-text {
  flex: 1 1 420px;
}

.agentur-block h2 {
  font-size: 1.15rem;
  margin: 0 0 6px;
}

.agentur-block p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text-dim);
}

.knopf-umriss {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 11px 22px;
  border: 1px solid var(--accent);
  border-radius: 7px;
  color: var(--accent);
  font-size: 0.88rem;
  font-weight: 600;
  text-decoration: none;
}

.knopf-umriss:hover {
  background: var(--accent);
  color: var(--auf-akzent);
}

/* Der Aufruf in der Kopfzeile. */
.kopf-starten {
  align-self: center;
  padding: 7px 15px;
  border-radius: 6px;
  background: var(--accent);
  color: var(--auf-akzent);
  font-size: 0.83rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.kopf-starten:hover {
  background: var(--accent-soft);
}

/* --- Die Befundliste unter dem Vorschau-Dashboard (03.09.2026) ------------
   Das SVG darueber zeigt Kennzahlen, also DASS gemessen wird. Diese Liste
   zeigt, was dabei herauskommt -- der Teil, den ein Besucher sehen will,
   bevor er eine Adresse eintippt. Beides zusammen ist die Vorschau. */

.befunde {
  margin-top: 12px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}

.befunde-kopf {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
}

.befunde-kopf span {
  font-size: 0.7rem;
  font-weight: 400;
  color: var(--text-faint);
}

.befunde ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.befunde li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.82rem;
  color: var(--text-dim);
}

.befunde li b {
  margin-left: auto;
  font-weight: 400;
  font-size: 0.72rem;
  color: var(--text-faint);
}

/* Der Punkt traegt die Dringlichkeit. Er ist nicht das einzige Signal --
   die Stufe steht rechts als Wort, sonst waere die Liste fuer jemanden mit
   einer Rot-Gruen-Schwaeche eine Reihe grauer Zeilen. */
.befund-punkt {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
}

.befund-punkt.hoch {
  background: var(--accent);
}

.befund-punkt.mittel {
  background: var(--warn);
}

/* DER AUSBRUCH DES AUFMACHERS IST WEG. `.hero-produkt` und `.werkzeuge`
   traten mit `margin: 0 -120px` aus der damals 852 px schmalen Huelle
   heraus -- ein Behelf, der eine zweite Kante erzeugte. Seit die Huelle
   selbst 1180 breit ist, braucht es ihn nicht mehr, und er stuende 120 px
   ueber der neuen Kante. */

/* DER SCHIMMER DARF UEBERSTEHEN, ABER NICHT SCROLLEN LASSEN.

   `.hero-produkt::before` hat negative Insets (-18 Prozent seitlich) -- das
   ist gewollt, der Schein soll ueber den Aufmacher hinausreichen. Gemessen
   am 03.09.2026 erzeugte er damit aber waagrechten Scroll: /seo/ war 15
   Pixel breiter als das Fenster, die auf 1180 verbreiterte Startseite 75.
   Ein Pseudo-Element taucht in keiner Element-Messung auf, deshalb faellt
   so etwas nur auf, wenn man scrollWidth gegen innerWidth haelt.

   `clip` und nicht `hidden`: hidden macht den Body zum Scroll-Container und
   nimmt jedem `position: sticky` darin seinen Bezug. clip schneidet nur ab.
   Der Schimmer reicht damit bis zum Fensterrand und endet dort -- sichtbar
   unveraendert, nur ohne den Scrollbalken. */
html,
body {
  overflow-x: clip;
}


/* ==========================================================================
   Die Produktabschnitte der Startseite (05.09.2026)

   Vier Bausteine, die es vorher nicht gab: die drei Schritte, die
   Produktbloecke mit Beispielansicht, die Fragen und das Abschlussband.
   Dazu der Umschalter monatlich/jaehrlich an der Preistabelle.

   ALLE FARBEN AUS DEN TOKENS. Der helle Satz weiter oben in dieser Datei
   deckt sie mit ab, weil hier ausschliesslich --token-Namen stehen und
   keine festen Werte -- eine Zeile #18181b haette den Hellmodus still
   kaputtgemacht.
   ========================================================================== */

/* --- In drei Schritten ---------------------------------------------------

   Eine <ol>, weil es eine Reihenfolge ist. Die Ziffer steht als eigene
   Marke daneben und traegt aria-hidden: die Nummerierung der Liste sagt
   einem Screenreader dasselbe schon. */

.schritte {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.schritte li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
  padding: 22px;
  display: grid;
  gap: 8px;
  align-content: start;
}

.schritt-nr {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent-bg);
  border: 1px solid var(--accent-line);
  color: var(--accent-soft);
  font-family: var(--mono);
  font-size: 0.86rem;
  font-weight: 600;
  margin-bottom: 4px;
}

.schritte b {
  font-size: 1rem;
  font-weight: 600;
}

.schritte span:not(.schritt-nr) {
  color: var(--text-dim);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* --- Produktblock: Text neben Beispielansicht ---------------------------

   Der Wechsel der Seiten passiert ueber `direction` am Gitter und nicht
   ueber `order` an den Kindern: so bleibt die Reihenfolge im Quelltext
   die des Vorlesens, und die Ansicht wandert trotzdem nach links. */

.produkt-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 34px;
  align-items: center;
}

.produkt-gedreht {
  direction: rtl;
}
.produkt-gedreht > * {
  direction: ltr;
}

.produkt-text .fuehrung {
  margin-bottom: 6px;
}

/* Die Beispielansicht. "Schauklotz" und nicht "Karte": sie zeigt eine
   Oberflaeche, keine Information -- und die Unterscheidung ist wichtig
   genug fuer einen eigenen Namen. */
.schauklotz {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

.schauklotz-kopf,
.schauklotz-fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  font-size: 0.8rem;
  color: var(--text-dim);
}

.schauklotz-kopf {
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  color: var(--text);
}

.schauklotz-fuss {
  background: var(--surface-2);
  border-top: 1px solid var(--border);
}

.schauklotz-fuss .mono,
.schauklotz .mono {
  font-family: var(--mono);
  font-size: 0.74rem;
}

/* DAS WORT "BEISPIEL" IM BILD, nicht darunter. Eine Bildunterschrift
   ueberlebt den Screenshot nicht, den jemand davon macht. */
.beispielmarke {
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent-soft);
  background: var(--accent-bg);
  border: 1px solid var(--accent-line);
  border-radius: 5px;
  padding: 2px 7px;
  white-space: nowrap;
}

.wandelliste,
.befundliste,
.befundzaehler {
  list-style: none;
  margin: 0;
  padding: 0;
}

.wandelliste li {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: baseline;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.85rem;
}
.wandelliste li:last-child {
  border-bottom: 0;
}
.wandelliste b {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.wandelliste i {
  font-style: normal;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-faint);
}
.wandelliste .auf {
  color: var(--success);
}
.wandelliste .ab {
  color: var(--danger);
}

/* --- Befunde: Punkt UND Wort -------------------------------------------

   Die Regel des Hauses, und hier ist sie keine Formsache: wer Rot und
   Gruen nicht unterscheidet, saehe drei gleich aussehende Zahlen. */
.befundzaehler {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.82rem;
  color: var(--text-dim);
}
.befundzaehler li {
  display: flex;
  align-items: center;
  gap: 7px;
}
.befundzaehler b {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.befundliste li {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--border-soft);
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--text-dim);
}
.befundliste li:last-child {
  border-bottom: 0;
}
.befundliste i {
  font-style: normal;
  margin-left: auto;
  color: var(--text-faint);
  font-size: 0.74rem;
}

.punkt {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.punkt-kritisch {
  background: var(--danger);
}
.punkt-warn {
  background: var(--warn);
}
.punkt-ok {
  background: var(--success);
}

.projektschau {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}
.projektschau th {
  text-align: left;
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  font-weight: 400;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}
.projektschau td {
  padding: 9px 16px;
  border-bottom: 1px solid var(--border-soft);
  color: var(--text-dim);
}
.projektschau tbody tr:last-child td {
  border-bottom: 0;
}
.projektschau td:first-child {
  color: var(--text);
}
.projektschau td:not(:first-child) {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* Der Verweis am Ende eines Produktblocks. */
.weiter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  font-size: 0.92rem;
}
.weiter::after {
  content: "→";
}

/* --- Fragen ------------------------------------------------------------

   <details>/<summary>, kein Javascript. Der Pfeil ist ein Pseudo-Element,
   damit die Marker-Darstellung der Browser nicht durchschlaegt. */

.fragen {
  margin-top: 24px;
  display: grid;
  gap: 12px;
}

.fragen details {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
  transition: border-color 0.15s ease;
}
.fragen details[open] {
  border-color: var(--accent-line);
}

.fragen summary {
  cursor: pointer;
  list-style: none;
  padding: 16px 46px 16px 20px;
  font-weight: 600;
  position: relative;
}
.fragen summary::-webkit-details-marker {
  display: none;
}
.fragen summary::after {
  content: "+";
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  font-size: 1.1rem;
  color: var(--text-faint);
}
.fragen details[open] summary::after {
  content: "−";
  color: var(--accent-soft);
}

.fragen p {
  margin: 0;
  padding: 0 20px 18px;
  color: var(--text-dim);
  line-height: 1.65;
  max-width: 72ch;
}

/* --- Abschlussband ------------------------------------------------------ */

.abschlussband {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--accent-line);
  border-radius: 14px;
  padding: 30px 32px;
}
.abschlussband h2 {
  margin: 0 0 8px;
}
.abschlussband p {
  margin: 0;
  color: var(--text-dim);
  max-width: 56ch;
}
.abschlussband .abschluss-direkt {
  margin-top: 10px;
}
.abschlussband .abschluss-direkt a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.abschlussband-knoepfe {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}

/* --- Umschalter an der Preistabelle ------------------------------------- */

.preis-schalter {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin: 22px 0 4px;
}

.preis-vorteil {
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--accent-soft);
}

/* Beide Betraege stehen im Markup; der Schalter blendet einen aus.
   Eine Klasse und nicht [hidden]: jede eigene display-Regel schlaegt das
   Attribut, und .preis-zahl ist genau so eine. */
.preis-betrag {
  margin: 0 0 4px;
}
.preis-weg {
  display: none;
}

.preis-jahressumme {
  display: block;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-faint);
  margin-top: 2px;
}

/* --- Schmale Fenster ---------------------------------------------------- */

@media (max-width: 960px) {
  .produkt-block {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Gedreht ergibt einspaltig keinen Sinn mehr -- und die
     rtl-Umkehrung wuerde die Reihenfolge verkehren. */
  .produkt-gedreht {
    direction: ltr;
  }
  .schritte {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 700px) {
  .abschlussband {
    padding: 24px 20px;
  }
  .abschlussband-knoepfe {
    width: 100%;
  }
  .abschlussband-knoepfe .knopf {
    flex: 1 1 auto;
    justify-content: center;
  }
}


/* --- Aufklappmenue "Leistungen" in der Kopfleiste (05.09.2026) -----------

   Ein <details> und kein Javascript-Menue: ohne Skript geht es trotzdem
   auf und zu. kopf.js legt nur Schliessen-bei-Klick-daneben und Escape
   darauf.

   Auf schmalen Fenstern klappt es NICHT als Ueberlagerung auf, sondern
   in der Zeile -- das war der alte Einwand gegen ein <details> ("verhaelt
   sich auf dem Telefon anders als auf dem Schreibtisch"), und er ist
   erledigt, sobald man beides ausdruecklich setzt.

   Die Masse stammen aus dem Entwurf: Feld 236 px breit, Polster 5,
   Eintraege 8/10 bei Radius 6 und 13 px Schrift, Zeichen 15 px im
   hellen Akzent. */

.mag-menue {
  position: relative;
}

.mag-menue > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Dieselben Masse wie ein .mag-nav a -- sonst sitzt der Punkt einen
     Pixel hoeher als seine Nachbarn. */
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  color: var(--text-dim);
  white-space: nowrap;
}
.mag-menue > summary::-webkit-details-marker {
  display: none;
}
.mag-menue__pfeil {
  flex: 0 0 auto;
  transition: transform 0.12s ease;
}
.mag-menue[open] .mag-menue__pfeil {
  transform: rotate(180deg);
}
.mag-menue > summary:hover {
  background: var(--surface-2);
  color: var(--text);
}
.mag-menue > summary:focus-visible {
  outline: 2px solid var(--accent-soft);
  outline-offset: 2px;
}
/* Aktive Marke nie nur ueber Farbe. */
.mag-menue > summary[aria-current="page"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--accent);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.mag-menue__feld {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 236px;
  display: grid;
  padding: 5px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.mag-menue__feld a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
}
.mag-menue__feld a:hover {
  background: var(--surface-2);
  color: var(--text);
}
.mag-menue__feld a[aria-current="page"] {
  color: var(--accent-soft);
  background: var(--accent-bg);
}
/* Die Zeichen im Akzent, damit die Zeile einen Anker hat. Der Verweis
   auf die Case Study traegt ein blasses -- er ist der Beleg zu den drei
   Leistungen und nicht die vierte. */
.mag-menue__feld svg {
  flex: 0 0 auto;
  color: var(--accent-soft);
}
.mag-menue__strich {
  height: 1px;
  background: var(--border-soft);
  margin: 5px 0;
}
.mag-menue__weiter svg {
  color: var(--text-faint) !important;
}

/* Unter 900 px bricht die Leiste ohnehin um. Ein Feld, das dort
   ueberlagert, deckt die halbe Seite ab -- also klappt es in der Zeile
   auf und schiebt den Rest nach unten. */
@media (max-width: 900px) {
  .mag-menue__feld {
    position: static;
    min-width: 0;
    margin: 6px 0 2px;
    box-shadow: none;
  }
}

/* --- Umschalter zwischen den drei Leistungen (05.09.2026) ---------------

   Sieht aus wie ein Segmentschalter, ist aber eine Navigation aus drei
   Verweisen. Das ist der Unterschied, der zaehlt: es sind drei Seiten,
   keine drei Zustaende einer Seite. Wer mit der mittleren Maustaste
   klickt, bekommt einen neuen Reiter -- bei <button> bekaeme er nichts.

   Die aktive Marke traegt aria-current und einen eigenen Grund, nicht
   nur eine Textfarbe. */

.leistung-seg {
  display: inline-flex;
  padding: 3px;
  margin-top: 20px;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 9px;
}
.leistung-seg a {
  padding: 7px 14px;
  border-radius: 7px;
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--text-dim);
  white-space: nowrap;
}
.leistung-seg a:hover {
  color: var(--text);
}
.leistung-seg a[aria-current="page"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

@media (max-width: 560px) {
  /* ZWEI SPALTEN, SEIT ES VIER LEISTUNGEN SIND (11.09.2026). Vorher
     standen hier drei, passend zur damaligen Zahl -- mit der vierten
     waere ein Eintrag allein in die zweite Zeile gerutscht. Vier
     nebeneinander gehen auf dem Telefon nicht: "Softwareentwicklung"
     und "KI-Automatisierung" brauchen zusammen mehr als die Breite. */
  .leistung-seg {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
  }
  .leistung-seg a {
    text-align: center;
    padding: 10px 6px;
  }
}


/* ==========================================================================
   DIE WERKZEUGE AUF /tools/ (19.09.2026)

   Derselbe Block wie unter jeder Werkzeugseite (build/verwandte.mjs), nur
   vollstaendig. Er steht hier, weil /tools/ bis zum 19.09.2026 vier
   Werkzeugarten beschrieb und auf genau eine Adresse verwies -- /app/.
   Wer dort las, kam nie zu einem Werkzeug.

   Die Regeln sind aus app.css uebernommen, weil die Seiten unter /app/
   ihr eigenes Stylesheet haben und dieselbe Liste dort schon so aussieht.
   Wer eine Regel aendert, aendert sie an beiden Stellen -- gemeinsam
   erzeugt wird das Markup, nicht das Aussehen.
   ========================================================================== */
.werkzeug-weitere {
  margin: 40px 0 8px;
  padding-top: 28px;
  border-top: 1px solid var(--border-soft);
}

.werkzeug-weitere h2 {
  font-size: 1.05rem;
  margin: 0 0 10px;
  color: var(--text);
}

.werkzeug-weitere ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 2px 24px;
}

.werkzeug-weitere li a {
  display: block;
  padding: 8px 10px;
  margin: 0 -10px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
  transition: background .15s ease;
}

.werkzeug-weitere li a:hover,
.werkzeug-weitere li a:focus-visible {
  background: var(--surface-2);
}

.werkzeug-weitere b {
  display: block;
  font-size: .92rem;
  line-height: 1.35;
  color: var(--text);
}

.werkzeug-weitere span {
  display: block;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--text-dim);
}

.werkzeug-weitere-alle {
  margin: 12px 0 0;
  font-size: .88rem;
}

.werkzeug-weitere-alle a {
  color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .werkzeug-weitere li a { transition: none; }
}


/* ==========================================================================
   DIE MISCHVARIANTE (27.09.2026), SEIT DEMSELBEN TAG IN VIOLETT

   Aufbau nach dem Proton-Entwurf: helle Flaechen, dunkle Zonen fuer
   Kopfleiste, Aufmacher der Startseite, Agenturblock und Fuss. Zuerst in
   Orange mit warmem Grau gebaut, dann auf Wunsch doch in den Farben des
   Entwurfs: Violett #6d4aff als einziger Akzent, Lavendel statt warmem
   Grau, ein violettes Schwarz in den dunklen Zonen. Der Entwurf liegt als
   Canvas unter https://claude.ai/artifact/6hsUiSMcUfk1A9MusT9seg (die
   linke Spalte, "Proton-Look (Lila)").

   Die orangen Werte weiter oben in dieser Datei (heller Satz, Schimmer,
   die Kontrasttabelle bei .eyebrow) sind damit fuer hell ueberschrieben;
   ihre Begruendungen gelten fuer die neuen Werte sinngemaess.

   ALLES HIER HING ANFANGS AN [data-theme="hell"]. Seit dem 01.10.2026
   (dunkler Satz der klaren Variante) haengen die Regeln an
   :root[data-theme] und gelten in beiden Themen; nur die Farbbloecke
   bleiben an "hell" (die dunklen Zonen unten) bzw. "dunkel".
   Das haelt den Umbau rueckbaubar: diesen Block loeschen, in huelle()
   data-theme wieder herausnehmen, fertig.

   DIE DUNKLEN ZONEN SETZEN DIE TOKENS NEU, statt jede Regel darin zu
   ueberschreiben. Alles darunter liest weiter var(--text), var(--surface)
   usw. und bekommt in der Zone die dunklen Werte. Eine Regel pro Zone
   statt einer pro Bauteil.

   VOLLE BREITE OHNE UMBAU DES MARKUPS: Aufmacher, getoente Abschnitte und
   Fuss stehen im 1228er Kasten. Die Flaeche reicht trotzdem bis an den
   Fensterrand, ueber border-image mit Auslauf nach links und rechts.
   Was ein border-image ueber den Rand malt, zaehlt nicht als Ueberlauf:
   kein waagrechter Rollbalken, kein overflow-x:hidden am body, das
   die klebende Kopfleiste kaputt machen wuerde.
   ========================================================================== */

/* --- Schrift --------------------------------------------------------------

   Plus Jakarta Sans, variabel, nur die Teilmenge latin (27 KB), von der
   eigenen Adresse. Inter stand bisher in der Liste, wurde aber nie
   geladen -- gezeichnet hat also immer die Systemschrift. Gilt in beiden
   Themen: die Schrift ist Marke, nicht Farbe. */
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("/schriften/plus-jakarta-sans.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

body.magazin {
  font-family:
    "Plus Jakarta Sans",
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
}

.hero h1,
.abschnitt h1,
.abschnitt h2 {
  font-weight: 800;
  letter-spacing: -0.03em;
}

/* Die Dachzeilen in Mono, wie auf der alten Seite -- das ist, was von der
   bisherigen Handschrift bleibt. */
.eyebrow {
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: 0.08em;
}

/* --- Heller Satz: warmes Grau, groessere Rundungen ------------------------ */

:root[data-theme="hell"] {
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f6f4ff;
  --surface-3: #efebff;
  --border: #e2dcf5;
  --border-soft: #ebe7f8;
  --text: #1b1830;
  --text-dim: #5b5670;
  --text-faint: #6a6580;
  /* #7f7a94 kam auf Weiss nur auf 4,1:1 -- zu wenig fuer Datum und
     "Zuletzt aktualisiert" mit 12 bis 13 Pixeln. #6c6783: Weiss 5,4:1,
     Lavendel #f6f4ff 4,9:1, #efebff 4,6:1 (Feinschliff 01.10.2026). */
  --text-ghost: #6c6783;

  /* Auf Weiss: #6d4aff 5,1:1, #5b3ae6 6,3:1. Auf dem Lavendel
     (#f6f4ff) kommt #6d4aff nur knapp ueber 4,5 -- deshalb traegt die
     Dachzeile weiter --accent-soft, wie schon im orangen Satz. */
  --accent: #6d4aff;
  --accent-soft: #5b3ae6;
  --accent-bg: rgba(109, 74, 255, 0.08);
  --accent-line: rgba(109, 74, 255, 0.3);

  --radius: 14px;
  --radius-sm: 10px;
  --radius-lg: 20px;

  --shadow: 0 1px 2px rgba(27, 24, 48, 0.05), 0 12px 32px rgba(60, 40, 140, 0.1);

  /* Der Knopf hat eine eigene Farbe, nicht --accent: in den dunklen Zonen
     wird --accent heller (Text muss dort auf Dunkel lesbar sein), der
     Knopf soll aber ueberall derselbe sein. #6d4aff traegt weisse Schrift
     mit 5,1:1. */
  --knopf: #6d4aff;
  --knopf-hover: #5b3ae6;
}

/* --- Die dunklen Zonen ---------------------------------------------------- */

:root[data-theme="hell"] .mag-kopf-band,
:root[data-theme="hell"] .hero-produkt,
:root[data-theme="hell"] .agentur-block,
:root[data-theme="hell"] .mag-fuss {
  --bg: #16131f;
  --surface: #1f1b2b;
  --surface-2: #2a2440;
  --surface-3: #332c4d;
  --border: #3a3350;
  --border-soft: #2a2638;
  --text: #f4f2fa;
  --text-dim: #c8c3d9;
  --text-faint: #b3adc8;
  --text-ghost: #9a94b0;
  /* Auf #16131f: #a594ff 7,6:1, #c2b6ff 10,4:1. */
  --accent: #a594ff;
  --accent-soft: #c2b6ff;
  --accent-bg: rgba(165, 148, 255, 0.14);
  --accent-line: rgba(165, 148, 255, 0.35);
  --success: #5fd88f;
  --success-bg: rgba(95, 216, 143, 0.1);
  --warn: #f2b84d;
  --warn-bg: rgba(242, 184, 77, 0.12);
  --danger: #f16060;
  --danger-bg: rgba(241, 96, 96, 0.12);
  --band: rgba(22, 19, 31, 0.92);
  /* Violett ist dunkler als Orange und hellt den Grund weniger auf -- die
     Kopfzeile ueber dem Schein bleibt bei 0,22 innen ueber 7:1. */
  --schimmer-innen: rgba(109, 74, 255, 0.22);
  --schimmer-mitte: rgba(109, 74, 255, 0.12);
  --schimmer-aussen: rgba(109, 74, 255, 0.07);
  --schimmer-null: rgba(109, 74, 255, 0);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.22);
  color: var(--text);
}

/* Aufmacher der Startseite: dunkel ueber die volle Breite, direkt unter
   dem Band. Die -34px heben das obere Polster von .mag-huelle auf, sonst
   stuende ein weisser Streifen zwischen Band und Aufmacher. */
:root[data-theme] .hero-produkt {
  /* Der Schein (::before/::after) reicht weit ueber den Aufmacher hinaus.
     Oben und unten wird er an der Kante abgeschnitten, sonst faerbt er
     das Band darueber und den getoenten Abschnitt darunter an; seitlich
     darf er bis an den Fensterrand. */
  clip-path: inset(0 -100vmax);
  background: var(--bg);
  border-image: conic-gradient(var(--bg) 0 0) fill 0 // 0 100vmax;
  border-bottom: 0;
  margin-top: -34px;
  padding: 72px 0 64px;
}

:root[data-theme] .hero-produkt h1 {
  font-size: clamp(2.3rem, 5.6vw, 3.9rem);
}

/* Das Prueffeld bleibt weiss auf Dunkel -- es ist die eine Stelle, an der
   etwas eingetippt werden soll, und muss sich davon abheben. */
:root[data-theme] .hero-produkt .hero-pruefen-zeile {
  background: #ffffff;
  border-color: #ffffff;
  border-radius: 16px;
}

:root[data-theme] .hero-produkt .hero-pruefen input {
  color: #1b1830;
}

:root[data-theme] .hero-produkt .hero-pruefen input::placeholder {
  color: #6a6580;
}

:root[data-theme] .mag-fuss {
  background: var(--bg);
  border-image: conic-gradient(var(--bg) 0 0) fill 0 // 0 100vmax;
  border-top: 0;
  padding-top: 40px;
  padding-bottom: 48px;
  max-width: 1228px;
}

:root[data-theme] .agentur-block {
  background: var(--bg);
  border-color: var(--bg);
  border-radius: 24px;
  padding: 36px 40px;
}

:root[data-theme] .agentur-block h2 {
  font-size: clamp(1.35rem, 3vw, 1.75rem);
}

/* --- Knoepfe -------------------------------------------------------------- */

:root[data-theme] .knopf {
  border-radius: 12px;
  padding: 13px 24px;
  font-weight: 600;
}

:root[data-theme] .knopf-voll,
:root[data-theme] .kopf-starten {
  background: var(--knopf);
  border-color: var(--knopf);
  color: #ffffff;
  font-weight: 700;
}

:root[data-theme] .knopf-voll:hover,
:root[data-theme] .kopf-starten:hover {
  background: var(--knopf-hover);
  border-color: var(--knopf-hover);
  filter: none;
}

:root[data-theme] .kopf-starten {
  border-radius: 10px;
  padding: 9px 16px;
}

:root[data-theme] .knopf-umriss {
  border-width: 1.5px;
  border-radius: 12px;
  background: transparent;
}

:root[data-theme] .knopf-umriss:hover {
  background: var(--knopf);
  border-color: var(--knopf);
  color: #ffffff;
}

/* --- Abschnitte ----------------------------------------------------------- */

:root[data-theme] .abschnitt {
  padding: 56px 0;
}

/* Getoent: die Flaeche im warmen Grau, ueber die volle Breite. Karten
   darin werden weiss -- sonst verschwaenden sie in der Flaeche. */
:root[data-theme] .abschnitt-getoent {
  background: var(--surface-2);
  border-image: conic-gradient(var(--surface-2) 0 0) fill 0 // 0 100vmax;
  border-bottom: 0;
  padding: 64px 0;
}

:root[data-theme] .abschnitt-getoent .zahlen > div,
:root[data-theme] .abschnitt-getoent .werkzeug,
:root[data-theme] .abschnitt-getoent .fragen details {
  background: var(--surface);
}

/* --- Karten --------------------------------------------------------------- */

:root[data-theme] .zahlen > div {
  border-radius: 20px;
  padding: 24px;
}

:root[data-theme] .zahlen dt {
  font-size: clamp(1.7rem, 3.8vw, 2.5rem);
  font-weight: 800;
}

:root[data-theme] .schritte li {
  border-radius: 24px;
  padding: 30px;
  gap: 10px;
}

:root[data-theme] .schritt-nr {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  border: 0;
  background: var(--accent-bg);
  color: var(--accent);
  font-size: 1.1rem;
  font-weight: 700;
}

:root[data-theme] .schritte b {
  font-size: 1.15rem;
  font-weight: 700;
}

:root[data-theme] .schauklotz {
  border-radius: 20px;
}

/* Die Werkzeuge wie eine Produktfamilie: Zeichen weiss auf einer Kachel
   in Markenfarbe. */
:root[data-theme] .werkzeug {
  border-radius: 20px;
  padding: 22px;
}

:root[data-theme] .werkzeug-zeichen {
  width: 44px;
  height: 44px;
  padding: 11px;
  border-radius: 12px;
  background: var(--knopf);
  color: #ffffff;
  margin-bottom: 14px;
}

:root[data-theme] .werkzeug b {
  font-size: 1.02rem;
}

/* --- Preise --------------------------------------------------------------- */

:root[data-theme] .preis-gitter {
  gap: 20px;
  align-items: stretch;
}

:root[data-theme] .preis-karte {
  border-radius: 24px;
  padding: 30px;
}

:root[data-theme] .preis-karte.preis-empfohlen {
  border: 2px solid var(--knopf);
  box-shadow: 0 20px 50px rgba(109, 74, 255, 0.18);
}

:root[data-theme] .preis-karte h3 {
  font-size: 1.2rem;
}

:root[data-theme] .preis-marke {
  background: var(--knopf);
  color: #ffffff;
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 0.7rem;
  font-weight: 700;
}

:root[data-theme] .preis-zahl {
  font-size: 2.4rem;
  font-weight: 800;
}

:root[data-theme] .preis-punkte {
  font-size: 0.88rem;
  gap: 9px;
}

/* --- Fragen --------------------------------------------------------------- */

:root[data-theme] .fragen details {
  border-radius: 16px;
}

:root[data-theme] .fragen summary {
  padding: 20px 52px 20px 24px;
  font-size: 1.05rem;
  font-weight: 700;
}

:root[data-theme] .fragen p {
  padding: 0 24px 20px;
}

/* --- Abschlussband: voll in Markenfarbe ----------------------------------

   Der eine laute Block der Seite. Weisse Schrift auf #6d4aff: 5,1:1 --
   die helle Unterzeile aus dem Entwurf (#ece7ff) kaeme nur auf 4,3:1,
   deshalb auch sie weiss. */
:root[data-theme] .abschlussband {
  background: var(--knopf);
  border: 0;
  border-radius: 24px;
  padding: 44px 44px;
  color: #ffffff;
}

:root[data-theme] .abschlussband h2,
:root[data-theme] .abschlussband p {
  color: #ffffff;
}

:root[data-theme] .abschlussband .knopf-voll {
  background: #ffffff;
  border-color: #ffffff;
  color: #4a2fd0;
}

:root[data-theme] .abschlussband .knopf-voll:hover {
  background: #efebff;
  border-color: #efebff;
}

:root[data-theme] .abschlussband .knopf-umriss {
  border-color: #ffffff;
  color: #ffffff;
}

:root[data-theme] .abschlussband .knopf-umriss:hover {
  background: #ffffff;
  color: #4a2fd0;
}

/* --- Der Umschalter an der Preistabelle ----------------------------------

   bauen.mjs schreibt ihn als .seg -- die Klasse der App, deren Regeln in
   app.css stehen. Die wird auf den Magazinseiten nicht geladen, also
   standen hier bisher zwei nackte Browser-Knoepfe. Gilt in beiden Themen. */
.preis-schalter .seg {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}

.preis-schalter .seg button {
  padding: 8px 18px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text-dim);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.preis-schalter .seg button:hover {
  color: var(--text);
}

.preis-schalter .seg button[aria-pressed="true"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

/* Die Kopfzeile: die neue Schrift laeuft breiter, und mit den alten
   Abstaenden rutschte "Kontakt" auf 1440 px in eine zweite Zeile. */
.mag-nav a {
  padding: 6px 9px;
}

@media (max-width: 560px) {
  :root[data-theme] .hero-produkt {
    padding: 48px 0 40px;
  }

  :root[data-theme] .abschlussband,
  :root[data-theme] .agentur-block {
    padding: 28px 22px;
  }
}


/* --- Kopfzeile: deckend und mit Menueknopf (27.09.2026) ------------------

   DECKEND. Das Band war zu 92 % deckend. Ueber dem weissen Grund der hellen
   Seiten ergab das ein Grau, das weder zum Violett des Aufmachers noch zum
   Fuss passte. */
:root[data-theme="hell"] .mag-kopf-band {
  --band: #16131f;
}

/* EIN PIXEL UEBERLAPPUNG. Auf dem Handy endet das Band auf einem
   Bruchteil eines Pixels, und zwischen Band und Aufmacher schien eine
   helle Linie vom weissen Grund durch. Das Band liegt darueber (z-index),
   der Pixel verschwindet darunter. */
:root[data-theme] .hero-produkt {
  margin-top: -35px;
}

/* DER MENUEKNOPF. Er ist erst unter 1200 px zu sehen: darueber passt die
   Leiste in eine Zeile, darunter brach sie auf zwei bis vier Zeilen um. */
.menue-knopf:not([hidden]) {
  display: none;
}
.menue-knopf .auf {
  display: none;
}
.nav-offen .menue-knopf .zu {
  display: none;
}
.nav-offen .menue-knopf .auf {
  display: block;
}

@media (max-width: 1200px) {
  .mit-menue .menue-knopf:not([hidden]) {
    display: inline-flex;
  }

  .mit-menue .mag-kopf {
    flex-wrap: wrap;
    row-gap: 0;
  }

  .mit-menue .kopf-knoepfe {
    margin-left: auto;
  }

  /* Zugeklappt verschwindet die Leiste ganz, aufgeklappt steht sie als
     Liste unter der Zeile -- ueber die volle Breite, ein Punkt je Zeile. */
  .mit-menue .mag-nav {
    display: none;
    order: 10;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 12px 0 4px;
    margin-top: 14px;
    border-top: 1px solid var(--border-soft);
  }

  .mit-menue.nav-offen .mag-nav {
    display: flex;
  }

  .mit-menue .mag-nav a,
  .mit-menue .mag-menue > summary {
    display: flex;
    padding: 10px 12px;
    font-size: 0.95rem;
  }

  .mit-menue .mag-nav a[aria-current="page"],
  .mit-menue .mag-menue > summary[aria-current="page"] {
    box-shadow: inset 2px 0 0 var(--accent);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  }

  /* Das Aufklappmenue der Leistungen oeffnet in der Liste nach unten,
     nicht als schwebendes Feld. */
  .mit-menue .mag-menue__feld {
    position: static;
    width: auto;
    margin: 2px 0 6px 12px;
    box-shadow: none;
  }
}

/* HANDY. Die Knopfgruppe loest sich auf (display: contents), damit ihre
   Teile einzeln einsortiert werden koennen: in der Zeile stehen nur Logo,
   Aufruf und Menueknopf. Suche, Thema und Werkzeuge erscheinen
   erst im aufgeklappten Menue, unter der Liste. */
@media (max-width: 760px) {
  .mit-menue .mag-kopf {
    gap: 8px;
    padding: 12px 16px;
  }

  .mit-menue .kopf-knoepfe {
    display: contents;
  }

  .mit-menue .kopf-starten {
    margin-left: auto;
    padding: 8px 14px;
    font-size: 0.85rem;
  }

  .mit-menue .menue-knopf {
    order: 2;
  }

  .mit-menue .kopf-knopf:not(.menue-knopf),
  .mit-menue .kopf-werkzeuge {
    display: none;
    order: 11;
  }

  .mit-menue.nav-offen .kopf-knopf:not(.menue-knopf):not([hidden]) {
    display: inline-flex;
    margin-bottom: 12px;
  }

  .mit-menue.nav-offen .kopf-werkzeuge {
    display: inline-flex;
    margin-bottom: 12px;
  }
}

/* --- E-Mail-Check (/e-mail-check/, 29.09.2026) ------------------------------

   Rechts neben dem Formular steht ein Kasten, der vor der Pruefung sagt,
   was geprueft wird, und danach die vier Ampelzeilen zeigt. Beide Zustaende
   benutzen dasselbe Markup (.ec-zeile), damit der Kasten beim Umschalten
   nicht springt. Die Farbe steht nie allein: jede Zeile nennt ihre Ampel
   auch in Worten ("SPF · Rot"). Die Punkte sind die .ampel-Punkte der
   DSGVO-Tabelle, nur groesser. */

.ec-selector {
  margin-top: 10px;
  font-size: 0.88rem;
  color: var(--text-dim);
}

.ec-selector summary {
  cursor: pointer;
  width: fit-content;
}

.ec-selector label {
  display: block;
  margin: 10px 0 6px;
}

.ec-selector input {
  width: 100%;
  max-width: 22rem;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

.ec-selector input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.ec-ergebnis {
  min-width: 0;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.ec-ergebnis-titel {
  margin: 0 0 12px;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.ec-zeilen {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
}

.ec-zeile {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.ec-zeile p {
  margin: 0 0 6px;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

.ec-zeile p:last-child {
  margin-bottom: 0;
}

.ec-punkt {
  width: 12px;
  height: 12px;
  margin: 5px 0 0;
  background: var(--text-ghost);
}

.ec-rot .ec-punkt { background: var(--danger); }
.ec-gelb .ec-punkt { background: var(--warn); }
.ec-gruen .ec-punkt { background: var(--success); }

.ec-rot { border-color: var(--danger); }
.ec-gelb { border-color: var(--warn); }

/* SPF-Abfragebaum (05.10.2026, spf-baum.js aus werkzeuge-js/): Leiste mit
   einem Feld je DNS-Abfrage, darunter der include-Baum. Farben aus den
   Tokens, damit Hell und Dunkel stimmen; die Ampelfarbe steht nie allein,
   Kosten und Zustand stehen als Text in jeder Zeile. */
.ec-spfbaum-platz { margin-top: 12px; }
.ec-spfbaum { margin: 0; }
.ec-spfbaum svg { display: block; overflow: visible; font-family: var(--mono); font-size: 12px; }
.ec-spfbaum-titel { margin: 0 0 8px; font-weight: 700; font-size: 0.9rem; color: var(--text); }
.ec-spfbaum-zuviel { color: var(--danger); }
.ec-spfbaum-frei { fill: none; stroke: var(--border); stroke-dasharray: 3 3; }
.ec-spfbaum-belegt { fill: var(--accent); fill-opacity: 0.22; stroke: var(--accent); }
.ec-spfbaum-rot { fill: var(--danger); fill-opacity: 0.25; stroke: var(--danger); }
.ec-spfbaum-zahl { fill: var(--text); font-size: 11px; }
.ec-spfbaum-zahl-frei { fill: var(--text-faint); font-size: 11px; }
.ec-spfbaum-an rect { fill-opacity: 0.6; stroke-width: 2; }
.ec-spfbaum-grenze { stroke: var(--danger); stroke-width: 2; }
.ec-spfbaum-ast { fill: none; stroke: var(--border); stroke-width: 1.5; }
.ec-spfbaum-hinter { fill: transparent; }
.ec-spfbaum-zeile.ec-spfbaum-an .ec-spfbaum-hinter { fill: var(--surface); }
.ec-spfbaum-punkt { fill: var(--accent); }
.ec-spfbaum-punkt-leer { fill: var(--surface-2); stroke: var(--text-faint); }
.ec-spfbaum-domain { fill: var(--text); }
.ec-spfbaum-kosten { fill: var(--text-dim); }
.ec-spfbaum-mech { fill: var(--text-faint); }
.ec-spfbaum-ueber .ec-spfbaum-punkt { fill: var(--danger); }
.ec-spfbaum-ueber .ec-spfbaum-kosten,
.ec-spfbaum-ueber .ec-spfbaum-domain { fill: var(--danger); }
.ec-spfbaum-warn .ec-spfbaum-kosten { fill: var(--warn); }
.ec-zeile p.ec-spfbaum-erklaerung { margin: 8px 0 4px; font-size: 0.8rem; color: var(--text-faint); }
.ec-spfbaum-liste { font-size: 0.82rem; color: var(--text-dim); }
.ec-spfbaum-liste summary { cursor: pointer; width: fit-content; color: var(--accent); }
.ec-spfbaum-liste ul { margin: 6px 0 0; padding-left: 18px; }
.ec-spfbaum-liste li { margin: 2px 0; overflow-wrap: anywhere; }

p.ec-name {
  font-family: var(--mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

p.ec-befund {
  font-weight: 700;
  font-size: 0.98rem;
  color: var(--text);
}

.ec-zeile a,
.ec-nachsatz a {
  color: var(--accent);
  text-underline-offset: 2px;
}

.ec-meldung,
.ec-nachsatz {
  margin: 12px 0 0;
  font-size: 0.9rem;
  color: var(--text-dim);
}

.ec-text p {
  margin: 0 0 14px;
  max-width: 66ch;
  color: var(--text-dim);
  line-height: 1.65;
}

.ec-text p:last-child {
  margin-bottom: 0;
}

.ec-text code,
.ec-selector code,
.karte code {
  font-family: var(--mono);
  font-size: 0.88em;
}

/* Ein langes Ergebnis macht den Kasten hoeher als die Textspalte; dann
   bleibt das Formular oben stehen statt in die Mitte zu rutschen. */
.ec-kopf {
  align-items: start;
}

/* ==========================================================================
   Feinschliff 01.10.2026 -- Barrierefreiheit und Bedienung

   Gemessen in Chromium bei 390, 768 und 1440 Pixeln, hell und dunkel. Der
   Look bleibt; geaendert wird nur, was unter 4,5:1 Kontrast lag, zu kleine
   Tippflaechen und ein paar Ausreisser.
   ========================================================================== */

/* --- Dunkler Satz der Website ---------------------------------------------

   Die Tokens kommen aus app.css. Dort ist --text-ghost bewusst nur fuer
   Punkte und Rahmen gedacht (#5a5955, 2,5:1) -- das Magazin setzt es aber
   fuer Text ein: Datum auf den Karten, "Zuletzt aktualisiert", die
   Fusszeile. Und --text-faint kam auf --surface-2 (Tabellenkoepfe) nur auf
   4,35:1. Nur die Website bekommt hier hoehere Werte; die App laedt diese
   Datei nicht und bleibt, wie sie ist.

             auf #0d0d0f  #18181b  #202024
     dim     #9a9893      6,8      6,2      5,7
     faint   #918f8a      6,0      5,5      5,0
     ghost   #86847f      5,2      4,7      4,4  (nur noch auf bg/surface) */
:root:not([data-theme="hell"]) {
  --text-dim: #9a9893;
  --text-faint: #918f8a;
  --text-ghost: #86847f;
}

/* Kleine Marken in Akzentfarbe (SEO, empfohlen) liegen mit 10 bis 11 Pixeln
   auf --accent-bg: #8b72ff kommt dort auf 4,3:1, #a594ff auf 6,0:1. */
:root:not([data-theme="hell"]) .marke-klein {
  color: var(--accent-soft);
}

/* --- Knopf im Fliesstext ----------------------------------------------------

   ".prosa a" und ".abschnitt p a" faerben jeden Verweis in --accent-soft --
   auch den vollen Knopf ("Erstgespraech vereinbaren", "Jetzt melden").
   Im dunklen Satz stand dann #a594ff auf #8b72ff: 1,4:1, die Aufschrift
   war praktisch weg. Im hellen Satz gewinnt die [data-theme="hell"]-Regel
   (drei Klassen gegen zwei), dort fiel es nicht auf. */
.prosa a.knopf-voll,
.abschnitt p a.knopf-voll,
.abschnitt li a.knopf-voll,
.karte p a.knopf-voll {
  color: var(--auf-akzent);
}

/* --- Tippflaechen ------------------------------------------------------------

   Suche, Thema und Menue sind 34 Pixel gross. Groesser zeichnen hiesse:
   die Kopfleiste wird hoeher, und sie muss genau 71 Pixel bleiben
   (--topbar-h, derselbe Kopf wie in der App). Also waechst nur die
   Flaeche, die den Finger annimmt -- unsichtbar, 44 x 44. */
.kopf-knopf {
  position: relative;
}
.kopf-knopf::after {
  content: "";
  position: absolute;
  inset: -5px;
}

/* Die Themenliste der Startseite: Verweise mit 19 Pixeln Hoehe und 7 Pixeln
   Abstand -- auf dem Telefon trifft man leicht den Nachbarn. Als Block mit
   Polster ist jede Zeile rund 35 Pixel hoch, der Abstand steckt im Polster. */
.themenliste ul {
  gap: 0;
}
.themenliste li a {
  display: block;
  padding: 6px 0;
}


/* Die Leistungs-Auswahl ist ein Segment-Schalter, kein Fliesstext -- der
   unterstrichene Standard-Verweis liess sie aussehen wie vier lose Links. */
.leistung-seg a {
  text-decoration: none;
}

/* --- Sprungmarke zum Inhalt ---------------------------------------------------

   Wer mit der Tastatur kommt, muss sonst auf jeder Seite durch Logo,
   Navigation, Leistungen-Menue und vier Knoepfe. Unsichtbar, bis sie den
   Fokus hat. */
.sprung {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--knopf, var(--accent));
  color: #ffffff;
  font-weight: 600;
  text-decoration: none;
}
:root:not([data-theme="hell"]) .sprung {
  color: var(--auf-akzent);
}
.sprung:focus {
  top: 12px;
}
main#inhalt:focus {
  outline: none;
}

/* --- Formular ----------------------------------------------------------------

   Die Pruefung macht der Browser selbst (required, type="email"); seine
   Meldung steht am Feld. Dazu jetzt ein roter Rahmen -- aber erst, wenn
   jemand das Feld verlassen hat (:user-invalid), nicht schon beim Laden. */
.feld input:user-invalid,
.feld textarea:user-invalid {
  border-color: var(--danger);
}

/* ==========================================================================
   DIE KLARE VARIANTE (01.10.2026) -- "seriöser, das Violett bleibt"

   Entwurf A aus https://claude.ai/artifact/5NzEHK2qVJsDUyu598NV9W. Die
   Website wird durchgehend HELL: keine dunklen Zonen mehr fuer Kopfleiste,
   Aufmacher, Agenturblock und Fuss, kein violetter Schein hinter der
   Ueberschrift, kein vollflaechig violettes Abschlussband. Violett #6d4aff
   bleibt die Marke, steht aber nur noch auf Knoepfen, Verweisen, Dachzeilen
   und kleinen Marken. Ruhe kommt aus Weissraum, Haarlinien und 8 Pixeln
   Rundung statt 14 bis 24.

   Die Regeln haengen an :root[data-theme] und gelten hell wie dunkel;
   nur die Farbtoken unterscheiden sich (heller Block hier, dunkler Block
   direkt darunter). Die App bleibt, wie sie ist: app.css ist nicht
   angefasst.

   Kontrast, gerechnet (WCAG 2.x):
     --text      #17142a  Weiss 17,9  #f7f6fb 16,7
     --text-dim  #55516a  Weiss  7,6  #f7f6fb  7,1
     --text-faint#5f5b74  Weiss  6,5  #f7f6fb  6,0
     --text-ghost#66627a  Weiss  5,8  #f7f6fb  5,4  #efedf6 5,0
     --accent    #6d4aff  Weiss  5,1  #f7f6fb  4,8
     --accent-soft #5a37f0 Weiss 6,5  #f7f6fb  6,0
     Weiss auf dem Knopf #6d4aff 5,1, auf #5a37f0 (Hover) 6,5.
     Rahmen von Eingabefeldern #8b879c: 3,5:1 gegen Weiss (1.4.11 will 3).
   ========================================================================== */

:root[data-theme="hell"],
:root[data-theme="hell"] .mag-kopf-band,
:root[data-theme="hell"] .hero-produkt,
:root[data-theme="hell"] .agentur-block,
:root[data-theme="hell"] .mag-fuss {
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f7f6fb;
  --surface-3: #efedf6;
  --border: #e6e3ef;
  --border-soft: #eceaf3;
  --text: #17142a;
  --text-dim: #55516a;
  --text-faint: #5f5b74;
  --text-ghost: #66627a;
  --accent: #6d4aff;
  --accent-soft: #5a37f0;
  --accent-bg: rgba(109, 74, 255, 0.07);
  --accent-line: rgba(109, 74, 255, 0.28);
  --success: #16724a;
  --success-bg: rgba(22, 114, 74, 0.1);
  --warn: #8a5a00;
  --warn-bg: rgba(138, 90, 0, 0.12);
  --danger: #b03028;
  --danger-bg: rgba(176, 48, 40, 0.1);
  --band: #ffffff;
  --knopf: #6d4aff;
  --knopf-hover: #5a37f0;
  --rand-feld: #8b879c;
  --kopf-bg: #ffffff;
  --feld-bg: #ffffff;
  --schatten-rahmen: 0 1px 2px rgba(23, 20, 42, 0.04), 0 12px 32px rgba(23, 20, 42, 0.06);
  --schatten-klotz: 0 1px 2px rgba(23, 20, 42, 0.04), 0 10px 28px rgba(23, 20, 42, 0.05);
  --radius: 8px;
  --radius-sm: 8px;
  --radius-lg: 10px;
  --shadow: 0 1px 2px rgba(23, 20, 42, 0.05);
  color: var(--text);
}

/* --- Dunkler Satz der klaren Variante (01.10.2026) -------------------------

   Derselbe Aufbau wie hell -- Haarlinien, gerahmtes Kennzahlenraster,
   01/02/03, 8 Pixel Rundung --, nur die Tokens sind dunkel: ein flaches,
   leicht violettes Schwarz statt des neutralen Graus der App, kein Schein.
   Die Regeln dieses Blocks und der Mischvariante haengen dafuer an
   :root[data-theme] (gleiche Spezifitaet wie vorher), nur die Farbbloecke
   an "hell" bzw. "dunkel". Die App laedt diese Datei nicht.

   Kontrast, gerechnet (WCAG 2.x), auf #13111d / #19162a / #1d1a2e:
     --text        #f2f0fa  16,5 / 15,7 / 15,0
     --text-dim    #b4afc8   8,8 /  8,3 /  8,0
     --text-faint  #aaa4c0   7,8 /  7,4 /  7,1
     --text-ghost  #9d97b5   6,7 /  6,3 /  6,1
     --accent      #a594ff   7,4 /  7,0 /  6,7   (Verweise, Dachzeilen)
     --accent-soft #b9abff   9,2 /  8,7 /  8,3
     Weiss auf dem Knopf #6d4aff 5,1, auf #5a37f0 (Hover) 6,5.
     Rahmen von Eingabefeldern #77718f: 4,0 / 3,8 / 3,7 (1.4.11 will 3). */
:root[data-theme="dunkel"],
:root[data-theme="dunkel"] .mag-kopf-band,
:root[data-theme="dunkel"] .hero-produkt,
:root[data-theme="dunkel"] .agentur-block,
:root[data-theme="dunkel"] .mag-fuss {
  --bg: #13111d;
  --surface: #1d1a2e;
  --surface-2: #19162a;
  --surface-3: #221e36;
  --border: #2e2a42;
  --border-soft: #29253b;
  --text: #f2f0fa;
  --text-dim: #b4afc8;
  --text-faint: #aaa4c0;
  --text-ghost: #9d97b5;
  --accent: #a594ff;
  --accent-soft: #b9abff;
  --accent-bg: rgba(165, 148, 255, 0.12);
  --accent-line: rgba(165, 148, 255, 0.32);
  --success: #5fd88f;
  --success-bg: rgba(95, 216, 143, 0.1);
  --warn: #f2b84d;
  --warn-bg: rgba(242, 184, 77, 0.12);
  --danger: #ff7b7b;
  --danger-bg: rgba(255, 123, 123, 0.12);
  --band: #13111d;
  --auf-akzent: #ffffff;
  --knopf: #6d4aff;
  --knopf-hover: #5a37f0;
  --rand-feld: #77718f;
  --kopf-bg: #13111d;
  --feld-bg: #19162a;
  --schatten-rahmen: none;
  --schatten-klotz: none;
  --schimmer-innen: transparent;
  --schimmer-mitte: transparent;
  --schimmer-aussen: transparent;
  --schimmer-null: transparent;
  --radius: 8px;
  --radius-sm: 8px;
  --radius-lg: 10px;
  --shadow: none;
  color: var(--text);
}

/* --- Kopfleiste: weiss, eine Haarlinie darunter --------------------------- */

:root[data-theme] .mag-kopf-band {
  background: var(--kopf-bg);
  border-bottom: 1px solid var(--border);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

:root[data-theme] .mag-nav a,
:root[data-theme] .mag-menue > summary {
  color: var(--text-dim);
}

:root[data-theme] .mag-nav a:hover,
:root[data-theme] .mag-nav a[aria-current="page"] {
  color: var(--text);
}

:root[data-theme] .kopf-starten {
  border-radius: 8px;
}

/* --- Aufmacher: hell, ohne Schein ------------------------------------------ */

:root[data-theme] .hero-produkt {
  clip-path: none;
  padding: 88px 0 96px;
}

:root[data-theme] .hero-produkt::before,
:root[data-theme] .hero-produkt::after {
  content: none;
}

:root[data-theme] .hero-produkt h1 {
  font-size: clamp(2.3rem, 5.2vw, 4rem);
  line-height: 1.07;
  letter-spacing: -0.035em;
}

:root[data-theme] .hero-produkt .hero-sub {
  color: var(--text-dim);
}

:root[data-theme] .hero-produkt .hero-pruefen-zeile {
  background: var(--feld-bg);
  border: 1px solid var(--rand-feld);
  border-radius: 8px;
}

:root[data-theme] .hero-produkt .hero-pruefen-zeile:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}

:root[data-theme] .hero-produkt .hero-pruefen input {
  color: var(--text);
}

:root[data-theme] .hero-produkt .hero-pruefen input::placeholder {
  color: var(--text-ghost);
}

:root[data-theme] .produkt-rahmen {
  border: 1px solid var(--border);
  box-shadow: var(--schatten-rahmen);
}

/* --- Abschnitte: mehr Luft, Haarlinien --------------------------------------- */

:root[data-theme] .abschnitt {
  padding: 96px 0;
  border-bottom: 1px solid var(--border);
}

:root[data-theme] .abschnitt-getoent {
  padding: 96px 0;
  border-bottom: 0;
}

:root[data-theme] .abschnitt h2 {
  font-size: clamp(1.7rem, 3.4vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -0.03em;
  margin-bottom: 14px;
}

/* Dachzeile: klein, Versalien, eine kurze Haarlinie dahinter. Nicht mehr
   in Mono -- die Schrift der Seite traegt sie ruhiger. */
:root[data-theme] .eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--accent-soft);
  margin-bottom: 16px;
}

:root[data-theme] .eyebrow::after {
  content: "";
  flex: 0 0 auto;
  width: 120px;
  max-width: 30%;
  height: 1px;
  background: var(--border);
}

/* --- Kennzahlen: ein gerahmtes Raster statt vier Kacheln --------------------

   Die Haarlinien zwischen den Zellen sind der Hintergrund der Liste, der
   durch einen Pixel Abstand scheint -- so gibt es keine doppelten Linien,
   auch wenn das Raster auf dem Telefon auf zwei Spalten umbricht. */
:root[data-theme] .zahlen {
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

:root[data-theme] .zahlen > div,
:root[data-theme] .abschnitt-getoent .zahlen > div {
  background: var(--surface);
  border: 0;
  border-radius: 0;
  padding: 28px;
}

:root[data-theme] .zahlen dt {
  color: var(--text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: clamp(1.7rem, 3.4vw, 2.5rem);
  letter-spacing: -0.02em;
}

:root[data-theme] .zahlenband .nachsatz {
  margin-top: 16px;
  font-size: 0.86rem;
}

/* --- Drei Schritte: 01 / 02 / 03 statt Ziffer in der Kachel ---------------- */

:root[data-theme] .schritte {
  counter-reset: schritt;
  gap: 24px;
}

:root[data-theme] .schritte li {
  counter-increment: schritt;
  border-radius: 8px;
  padding: 28px;
}

:root[data-theme] .schritt-nr {
  display: block;
  width: auto;
  height: auto;
  background: none;
  border: 0;
  border-radius: 0;
  font-size: 0;
  margin-bottom: 6px;
}

:root[data-theme] .schritt-nr::before {
  content: counter(schritt, decimal-leading-zero);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--accent-soft);
  font-variant-numeric: tabular-nums;
}

:root[data-theme] .schritte b {
  font-size: 1.1rem;
}

/* --- Karten und Beispielansichten: 8 bis 10 Pixel, kaum Schatten ----------- */

:root[data-theme] .schauklotz,
:root[data-theme] .werkzeug,
:root[data-theme] .fragen details,
:root[data-theme] .artikel-karte,
:root[data-theme] .karte {
  border-radius: 10px;
}

:root[data-theme] .schauklotz {
  box-shadow: var(--schatten-klotz);
}

:root[data-theme] .werkzeug-zeichen {
  background: var(--accent-bg);
  color: var(--accent-soft);
  border-radius: 8px;
}

/* --- Preise ------------------------------------------------------------------ */

:root[data-theme] .preis-gitter {
  gap: 24px;
}

:root[data-theme] .preis-karte {
  border-radius: 8px;
  padding: 28px;
}

:root[data-theme] .preis-karte.preis-empfohlen {
  border: 2px solid var(--knopf);
  box-shadow: none;
}

:root[data-theme] .preis-zahl {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* --- Knoepfe: 8 Pixel, mindestens 44 hoch ----------------------------------- */

:root[data-theme] .knopf {
  border-radius: 8px;
  min-height: 44px;
  padding: 11px 22px;
}

:root[data-theme] .knopf-umriss {
  border: 1px solid var(--rand-feld);
  color: var(--text);
}

:root[data-theme] .knopf-umriss:hover {
  background: var(--surface-2);
  border-color: var(--text-dim);
  color: var(--text);
}

/* --- Abschlussband: hell statt vollflaechig violett ------------------------- */

:root[data-theme] .abschlussband {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 48px;
  color: var(--text);
}

:root[data-theme] .abschlussband h2 {
  color: var(--text);
}

:root[data-theme] .abschlussband p {
  color: var(--text-dim);
}

:root[data-theme] .abschlussband .knopf-voll {
  background: var(--knopf);
  border-color: var(--knopf);
  color: #ffffff;
}

:root[data-theme] .abschlussband .knopf-voll:hover {
  background: var(--knopf-hover);
  border-color: var(--knopf-hover);
}

:root[data-theme] .abschlussband .knopf-umriss {
  border-color: var(--rand-feld);
  color: var(--text);
}

:root[data-theme] .abschlussband .knopf-umriss:hover {
  background: var(--surface);
  color: var(--text);
}

/* --- Agenturblock und Fuss: hell ------------------------------------------- */

:root[data-theme] .agentur-block {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 40px 44px;
}

:root[data-theme] .mag-fuss {
  background: var(--surface-2);
  /* Die Haarlinie oben laeuft mit der Flaeche bis an den Fensterrand:
     der erste Pixel des Bildes ist Linie, der Rest Flaeche. */
  border-image: linear-gradient(var(--border) 0 1px, var(--surface-2) 1px) fill 0 // 0 100vmax;
  border-top: 0;
  color: var(--text-dim);
}

:root[data-theme] .mag-fuss a {
  color: var(--text-dim);
}

:root[data-theme] .mag-fuss a:hover {
  color: var(--text);
}

/* --- Eingabefelder: ein Rahmen, den man sieht ------------------------------

   #e6e3ef auf Weiss sind 1,2:1 -- das Feld waere nur an seinem Schatten zu
   erkennen. WCAG 1.4.11 will fuer die Grenze eines Bedienelements 3:1. */
:root[data-theme] .feld input,
:root[data-theme] .feld textarea,
:root[data-theme] .suchzeile input,
:root[data-theme] .ec-selector input {
  border-color: var(--rand-feld);
}

:root[data-theme] .feld input:user-invalid,
:root[data-theme] .feld textarea:user-invalid {
  border-color: var(--danger);
}

/* --- Telefon ------------------------------------------------------------------ */

@media (max-width: 760px) {
  :root[data-theme] .hero-produkt {
    padding: 40px 0 48px;
  }

  :root[data-theme] .abschnitt,
  :root[data-theme] .abschnitt-getoent {
    padding: 56px 0;
  }

  :root[data-theme] .zahlen {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  :root[data-theme] .zahlen > div,
  :root[data-theme] .abschnitt-getoent .zahlen > div {
    padding: 20px;
  }

  :root[data-theme] .abschlussband,
  :root[data-theme] .agentur-block {
    padding: 28px 22px;
  }
}

/* --- Vertrauensleiste und Personenzeile (01.10.2026) -------------------------

   Aus dem Entwurf "Trust-Redesign" uebernommen, ohne den Rest: vier
   nachpruefbare Aussagen direkt unter dem Aufmacher. Die Zeichen tragen
   nichts allein -- jede Kachel hat Ueberschrift und Satz. */
.vertrauen {
  padding: 0 0 56px;
}

.vertrauen-liste {
  list-style: none;
  margin: 0;
  padding: 22px 24px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.vertrauen-liste li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.vertrauen-liste b {
  display: block;
  margin-bottom: 2px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
}

.vertrauen-zeichen {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm, 8px);
  background: var(--accent-bg);
  color: var(--accent-soft);
}

.agentur-person {
  margin-top: 10px !important;
  font-size: 0.86rem;
  color: var(--text-dim);
}

.agentur-person a {
  margin-left: 6px;
  font-weight: 600;
  color: var(--accent-soft);
}

@media (max-width: 980px) {
  .vertrauen-liste {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .vertrauen {
    padding-bottom: 40px;
  }

  .vertrauen-liste {
    grid-template-columns: minmax(0, 1fr);
    padding: 20px;
  }
}

/* ==========================================================================
   NEUGESTALTUNG 01.10.2026 -- "Mischung" (Entwurf C)
   Dunkler Rahmen (Kopfleiste, Aufmacher, Werkzeug-Band, Abschluss, Fuss),
   heller Inhalt im hellen Satz; im dunklen Satz alles dunkel. Signal-Gruen
   als Marke, je Bereich eine Farbe. Space Grotesk / IBM Plex Sans /
   JetBrains Mono, alle selbst ausgeliefert.

   Kontrast, gerechnet (WCAG 2.x):
     hell:   Text #0e1726 auf #f6f7f9 16,4 · --text-dim #465366 7,3
             --accent #0e7a5c auf Weiss 5,3, auf #f6f7f9 5,0
             Knopf #3ddc97 mit #05140c 10,7
     dunkel: Text #e8edf2 auf #0b0e13 16,2 · --text-dim #a3afbc 8,7
             --text-ghost #7e8a98 5,5 · --accent #3ddc97 10,6
             Bereiche: Web #7ab2ff 8,3 · SEO #f2b544 9,9 auf #11161d
   ========================================================================== */

@font-face {
  font-family: "Space Grotesk";
  src: url("/schriften/space-grotesk-500-700.woff2") format("woff2");
  font-weight: 500 700;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("/schriften/ibm-plex-sans-400-600.woff2") format("woff2");
  font-weight: 400 600;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/schriften/jetbrains-mono-400-600.woff2") format("woff2");
  font-weight: 400 600;
  font-display: swap;
}

body.magazin {
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --anzeige: "Space Grotesk", "IBM Plex Sans", system-ui, sans-serif;
  font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
}
body.magazin h1,
body.magazin h2,
body.magazin h3,
body.magazin .mag-logo span,
body.magazin .zahlen dt,
body.magazin .preis-zahl {
  font-family: var(--anzeige);
  letter-spacing: -0.02em;
}
body.magazin h1,
body.magazin .abschnitt h2 { font-weight: 700; }
body.magazin h3 { font-weight: 600; }

/* --- Farben: heller Satz (Inhalt) ---------------------------------------- */
:root[data-theme="hell"] {
  --bg: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #eef1f5;
  --surface-3: #e6eaf0;
  --border: #d9dfe7;
  --border-soft: #e3e8ee;
  --text: #0e1726;
  --text-dim: #465366;
  --text-faint: #4f5c6e;
  --text-ghost: #5b6779;
  --accent: #0e7a5c;
  --accent-soft: #0b6a4f;
  --accent-bg: rgba(14, 122, 92, 0.08);
  --accent-line: rgba(14, 122, 92, 0.3);
  --success: #0e7a5c;
  --success-bg: rgba(14, 122, 92, 0.1);
  --warn: #8a4a00;
  --warn-bg: rgba(163, 74, 11, 0.1);
  --danger: #b3261e;
  --danger-bg: rgba(179, 38, 30, 0.1);
  --band: #f6f7f9;
  --knopf: #3ddc97;
  --knopf-hover: #2fc584;
  --auf-knopf: #05140c;
  --rand-feld: #8792a3;
  --kopf-bg: #0b0e13;
  --feld-bg: #ffffff;
  --farbe-sec: #0e7a5c;
  --farbe-web: #1f4fe0;
  --farbe-seo: #a34a0b;
  --schatten-rahmen: 0 1px 2px rgba(14, 23, 38, 0.05), 0 12px 32px rgba(14, 23, 38, 0.07);
  --schatten-klotz: 0 1px 2px rgba(14, 23, 38, 0.05), 0 10px 26px rgba(14, 23, 38, 0.06);
  --radius: 8px;
  --radius-sm: 8px;
  --radius-lg: 10px;
  --shadow: 0 1px 2px rgba(14, 23, 38, 0.05);
  color: var(--text);
}

/* --- Farben: dunkler Satz und die dunklen Zonen des hellen ---------------- */
:root[data-theme="dunkel"],
:root[data-theme] .mag-kopf-band,
:root[data-theme] .hero-produkt,
:root[data-theme] .band-dunkel,
:root[data-theme] .abschlussband,
:root[data-theme] .mag-fuss {
  --bg: #0b0e13;
  --surface: #11161d;
  --surface-2: #161c25;
  --surface-3: #1c2430;
  --border: #232c38;
  --border-soft: #1d2530;
  --text: #e8edf2;
  --text-dim: #a3afbc;
  --text-faint: #96a2b0;
  --text-ghost: #7e8a98;
  --accent: #3ddc97;
  --accent-soft: #6be5b0;
  --accent-bg: rgba(61, 220, 151, 0.1);
  --accent-line: rgba(61, 220, 151, 0.32);
  --success: #3ddc97;
  --success-bg: rgba(61, 220, 151, 0.1);
  --warn: #f2b544;
  --warn-bg: rgba(242, 181, 68, 0.12);
  --danger: #ff7a7a;
  --danger-bg: rgba(255, 122, 122, 0.12);
  --band: #0b0e13;
  --knopf: #3ddc97;
  --knopf-hover: #6be5b0;
  --auf-knopf: #05140c;
  --rand-feld: #5d6876;
  --kopf-bg: #0b0e13;
  --feld-bg: #11161d;
  --farbe-sec: #3ddc97;
  --farbe-web: #7ab2ff;
  --farbe-seo: #f2b544;
  --schatten-rahmen: none;
  --schatten-klotz: none;
  --schimmer-innen: transparent;
  --schimmer-mitte: transparent;
  --schimmer-aussen: transparent;
  --schimmer-null: transparent;
  --radius: 8px;
  --radius-sm: 8px;
  --radius-lg: 10px;
  --shadow: none;
  color: var(--text);
}
/* Im dunklen Satz wechseln die Abschnitte zwischen zwei Dunkeltoenen. */
:root[data-theme="dunkel"] .abschnitt-getoent { background: #11161d; }

/* --- Knoepfe: Signal-Gruen mit dunkler Schrift ----------------------------- */
:root[data-theme] .knopf-voll,
:root[data-theme] .kopf-starten,
:root[data-theme] .preis-knopf,
:root[data-theme] .hero-pruefen button,
:root[data-theme] .abschlussband .knopf-voll,
:root[data-theme] .preis-marke,
:root[data-theme] .werkzeug-zeichen {
  background: var(--knopf);
  border-color: var(--knopf);
  color: var(--auf-knopf);
}
:root[data-theme] .knopf-voll:hover,
:root[data-theme] .kopf-starten:hover,
:root[data-theme] .preis-knopf:hover,
:root[data-theme] .hero-pruefen button:hover,
:root[data-theme] .abschlussband .knopf-voll:hover {
  background: var(--knopf-hover);
  border-color: var(--knopf-hover);
  color: var(--auf-knopf);
}
:root[data-theme] .knopf-umriss:hover { background: var(--text); color: var(--bg); border-color: var(--text); }

/* --- Dunkle Zonen ------------------------------------------------------------ */
:root[data-theme] .mag-kopf-band { background: var(--kopf-bg); border-bottom: 1px solid var(--border); color: var(--text); }
:root[data-theme] .mag-kopf-band .mag-nav a,
:root[data-theme] .mag-kopf-band .mag-menue > summary,
:root[data-theme] .mag-kopf-band .kopf-werkzeuge { color: var(--text-dim); }
:root[data-theme] .mag-kopf-band .mag-nav a:hover,
:root[data-theme] .mag-kopf-band .mag-nav a[aria-current="page"],
:root[data-theme] .mag-kopf-band .kopf-werkzeuge:hover { color: var(--text); }
:root[data-theme] .mag-kopf-band .mag-logo { color: var(--text); }

:root[data-theme] .hero-produkt {
  background-color: var(--bg);
  background-image: radial-gradient(ellipse 55% 60% at 78% 35%, rgba(61, 220, 151, 0.08), transparent 70%);
  color: var(--text);
}
:root[data-theme] .hero-produkt h1 { color: var(--text); }
:root[data-theme] .hero-produkt .hero-sub,
:root[data-theme] .hero-produkt .hero-fussnote { color: var(--text-dim); }
:root[data-theme] .hero-produkt .hero-pruefen-zeile { background: var(--surface); border-color: var(--rand-feld); }
:root[data-theme] .hero-produkt .hero-pruefen input { color: var(--text); }
:root[data-theme] .hero-produkt .hero-pruefen input::placeholder { color: var(--text-ghost); }

:root[data-theme] .mag-fuss {
  background: var(--bg);
  border-image: linear-gradient(var(--border) 0 1px, var(--bg) 1px) fill 0 // 0 100vmax;
  color: var(--text-dim);
}

/* --- Dachzeilen in Mono, in Markenfarbe ------------------------------------ */
:root[data-theme] .eyebrow { color: var(--accent); }

/* --- Startseite der Neugestaltung ------------------------------------------- */

/* Aufmacher: zwei Spalten, rechts der Pruefbericht. Die dunkle Flaeche
   laeuft ueber border-image bis an den Fensterrand (wie Kopf und Fuss). */
:root[data-theme] .neu-held {
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 56px;
  padding: 84px 0 92px;
  border-image: conic-gradient(var(--bg) 0 0) fill 0 // 0 100vmax;
  margin-top: -34px;
}
:root[data-theme] .neu-held h1 { font-size: clamp(2.3rem, 4.6vw, 3.7rem); line-height: 1.04; letter-spacing: -0.03em; margin: 18px 0 18px; }
.bereich-marken { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.bereich-marken li { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px; font-size: 0.82rem; color: var(--text-dim); background: var(--surface); }
.bereich-marken li::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--farbe-sec); }
.bereich-marken .m-web::before { background: var(--farbe-web); }
.bereich-marken .m-seo::before { background: var(--farbe-seo); }
.neu-feldname { display: block; font-size: 0.9rem; font-weight: 600; margin: 26px 0 8px; color: var(--text); }
.neu-held .hero-fussnote { margin-top: 12px; font-size: 0.86rem; }
.neu-held .hero-fussnote a { color: var(--accent); }

.konsole { margin: 0; background: #05070a; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45); font-family: var(--mono); }
.konsole-kopf { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.konsole-kopf span { width: 10px; height: 10px; border-radius: 50%; background: #3a4350; }
.konsole-kopf b { margin-left: 8px; font-weight: 400; font-size: 12px; color: #7e8a98; }
.konsole-zeilen { list-style: none; margin: 0; padding: 18px 22px; font-size: 0.86rem; line-height: 1.55; color: #a3afbc; }
.konsole-zeilen li { display: flex; gap: 12px; padding: 4px 0; }
.konsole-zeilen i { font-style: normal; width: 14px; flex: 0 0 auto; }
.k-befehl { color: #e8edf2; }
.k-befehl i, .k-ziel, .k-ziel i, .k-ok i { color: #3ddc97; }
.k-krit { color: #e8edf2; } .k-krit i { color: #ff7a7a; }
.k-warn { color: #e8edf2; } .k-warn i { color: #f2b544; }
.konsole-fuss { display: flex; justify-content: space-between; gap: 12px; padding: 12px 22px; border-top: 1px solid var(--border); font-size: 12px; color: #7e8a98; }

/* --- Dreiklang: die drei Bereiche als Ueberschrift (06.10.2026) ------------

   Jedes Wort steht gleich gross; unterschieden werden die Bereiche nur
   durch den Balken links, in derselben Farbe wie ihr Abschnitt im
   Pruefbericht und ihre Karte weiter unten. Der Zweck steht immer klein
   unter dem Wort: daneben passte er nur bei "SEO", und drei Zeilen mit
   zwei verschiedenen Anordnungen lesen sich wie ein Fehler. */
:root[data-theme] .neu-held h1.dreiklang {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0 0 22px;
  font-size: inherit;
  letter-spacing: normal;
  line-height: 1;
}
.dk-zeile {
  --dk-farbe: var(--farbe-sec);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 4px 0 4px 22px;
}
.dk-seo { --dk-farbe: var(--farbe-seo); }
.dk-web { --dk-farbe: var(--farbe-web); }
/* Der Balken: eine Spur in Randfarbe, darueber die Fuellung. */
.dk-zeile::before,
.dk-zeile::after {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 5px;
  border-radius: 3px;
}
.dk-zeile::before { background: var(--border); }
.dk-zeile::after { background: var(--dk-farbe); transform-origin: top; }
.dk-wort {
  font-size: clamp(2.35rem, 5.2vw, 3.55rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
  color: var(--text);
}
.dk-zweck {
  font-family: var(--sans, inherit);
  font-size: clamp(0.98rem, 1.3vw, 1.1rem);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--text-dim);
}
.dk-schluss {
  margin-top: 8px;
  font-size: clamp(1.2rem, 1.9vw, 1.45rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--text);
}

/* "Webentwicklung" ist vierzehn Zeichen lang: unter 480 Pixeln waechst
   das Wort mit der Fensterbreite, sonst laeuft es bei 320 ueber den Rand. */
@media (max-width: 480px) {
  .dk-wort { font-size: clamp(1.8rem, 9vw, 2.35rem); }
}

/* Abschnitte im Pruefbericht, in den Farben der Ueberschrift. */
.konsole-zeilen .k-abschnitt { padding-top: 12px; color: var(--k-farbe); }
.konsole-zeilen .k-abschnitt i { color: var(--k-farbe); }
.k-a-seo { --k-farbe: #f2b544; }
.k-a-sec { --k-farbe: #3ddc97; }
.k-a-web { --k-farbe: #7ab2ff; }

/* Der eine Moment beim Laden: der Bericht laeuft Zeile fuer Zeile durch,
   und jeder Balken fuellt sich, wenn sein Abschnitt fertig ist. */
@media (prefers-reduced-motion: no-preference) {
  .neu-held .konsole-zeilen li {
    animation: k-zeile 0.28s ease-out both;
    animation-delay: calc(0.25s + var(--i, 0) * 0.13s);
  }
  .neu-held .dk-zeile::after { animation: dk-fuellen 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
  /* Je Balken: Ende der letzten Zeile seines Abschnitts
     (0,25 s + Index x 0,13 s + 0,28 s Dauer), Zeilen 4, 7 und 10.
     Seit 07.10.2026 in der Reihenfolge Cybersecurity, Web, SEO. */
  .neu-held .dk-sec::after { animation-delay: 1.05s; }
  .neu-held .dk-web::after { animation-delay: 1.44s; }
  .neu-held .dk-seo::after { animation-delay: 1.83s; }
}
@keyframes k-zeile {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}
@keyframes dk-fuellen {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

/* --- Bauplan: der Pruefbericht als technische Zeichnung (08.10.2026) ------

   Ersetzt auf der Startseite die Konsole. Immer dunkel wie vorher die
   Konsole (Rahmen der "Mischung"), mit Millimeterraster wie auf einem
   Plan. Die Domain steht in der Mitte, die vier Teile, an denen die
   Befunde haengen, drumherum; die Verbindungslinien liegen als SVG
   dahinter und verschwinden unter den deckenden Kaesten. Der eine Mangel
   (DMARC) ist rot gestrichelt umrandet wie eine Korrekturwolke. */
.bauplan {
  --bp-grund: #0a1018;
  --bp-raster: rgba(122, 178, 255, 0.07);
  --bp-raster-grob: rgba(122, 178, 255, 0.13);
  --bp-linie: #3a5068;
  --bp-text: #e8edf2;
  --bp-dim: #8a97a6;
  margin: 0;
  background: var(--bp-grund);
  border: 1px solid #1e2a38;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45);
  color: var(--bp-text);
  font-family: var(--mono);
}
.bp-kopf {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 12px 18px; border-bottom: 1px solid #1e2a38;
  font-size: 12px; color: var(--bp-dim);
}
.bp-kopf b { font-weight: 500; color: var(--bp-text); }
.bp-zeichnung {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-areas: "a b" "m m" "c d";
  gap: 34px 48px;
  padding: 30px 24px;
  background-color: var(--bp-grund);
  background-image:
    linear-gradient(var(--bp-raster-grob) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-raster-grob) 1px, transparent 1px),
    linear-gradient(var(--bp-raster) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-raster) 1px, transparent 1px);
  background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px;
  background-position: -1px -1px;
}
.bp-linien { position: absolute; inset: 0; width: 100%; height: 100%; }
.bp-linien path { fill: none; stroke: var(--bp-linie); stroke-width: 1.5; stroke-dasharray: 5 4; vector-effect: non-scaling-stroke; }
.bp-teil, .bp-mitte { position: relative; background: var(--bp-grund); }
.bp-teil {
  --bp-farbe: #3ddc97;
  padding: 12px 14px;
  border: 1px solid var(--bp-linie);
  border-top: 3px solid var(--bp-farbe);
  border-radius: 4px;
  font-size: 0.8rem;
  line-height: 1.45;
}
.bp-a { grid-area: a; }
.bp-b { grid-area: b; }
.bp-c { grid-area: c; }
.bp-d { grid-area: d; }
.bp-web { --bp-farbe: #7ab2ff; }
.bp-seo { --bp-farbe: #f2b544; }
.bp-name { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 6px; font-size: 0.86rem; font-weight: 600; }
.bp-name small { font-size: 0.72rem; font-weight: 400; color: var(--bp-farbe); }
.bp-teil ul { list-style: none; margin: 0; padding: 0; color: var(--bp-dim); }
.bp-teil li { display: flex; gap: 8px; padding: 2px 0; }
.bp-teil li i { font-style: normal; width: 12px; flex: 0 0 auto; }
.bp-krit { color: var(--bp-text); } .bp-krit i { color: #ff7a7a; }
.bp-warn i { color: #f2b544; }
.bp-ok i { color: #3ddc97; }
.bp-mangel { outline: 1.5px dashed #ff7a7a; outline-offset: 5px; }
.bp-mitte {
  grid-area: m; justify-self: center;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 14px 22px;
  border: 1.5px solid var(--bp-text);
  border-radius: 4px;
}
.bp-mitte span { font-size: 0.98rem; font-weight: 600; }
.bp-mitte small { font-size: 0.72rem; color: var(--bp-dim); }
/* Schriftfeld wie unten rechts auf einem Plan. */
.bp-schriftfeld {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid #1e2a38;
  font-size: 0.8rem;
}
.bp-schriftfeld span { display: flex; flex-direction: column; gap: 3px; padding: 10px 18px; }
.bp-schriftfeld span + span { border-left: 1px solid #1e2a38; }
.bp-schriftfeld small { font-size: 0.7rem; color: var(--bp-dim); }

/* Schmal: untereinander, die Domain oben, die Teile haengen an einer
   senkrechten Leitung statt an den Diagonalen. */
@media (max-width: 560px) {
  .bp-zeichnung { grid-template-columns: minmax(0, 1fr); grid-template-areas: "m" "a" "b" "c" "d"; gap: 14px; padding: 22px 16px 22px 30px; }
  .bp-linien { display: none; }
  .bp-zeichnung::before { content: ""; position: absolute; left: 16px; top: 48px; bottom: 40px; border-left: 1.5px dashed var(--bp-linie); }
  .bp-mitte { justify-self: stretch; align-items: flex-start; }
  .bp-schriftfeld { grid-template-columns: minmax(0, 1fr); }
  .bp-schriftfeld span + span { border-left: 0; border-top: 1px solid #1e2a38; }
}

/* Der eine Moment beim Laden: die Leitungen blenden ein, dann erscheinen
   die Teile nacheinander, und jeder Balken der Ueberschrift fuellt sich,
   sobald sein Bereich steht (Ende von Teil 2, 3 und 4: 0,9 / 1,3 / 1,7 s). */
@media (prefers-reduced-motion: no-preference) {
  .bauplan .bp-linien path { animation: bp-zeichnen 0.5s ease-out 0.1s both; }
  .bauplan .bp-teil { animation: k-zeile 0.3s ease-out both; animation-delay: 0.35s; }
  .bauplan .bp-b { animation-delay: 0.6s; }
  .bauplan .bp-c { animation-delay: 1s; }
  .bauplan .bp-d { animation-delay: 1.4s; }
  .neu-held:has(.bauplan) .dk-sec::after { animation-delay: 0.9s; }
  .neu-held:has(.bauplan) .dk-web::after { animation-delay: 1.3s; }
  .neu-held:has(.bauplan) .dk-seo::after { animation-delay: 1.7s; }
}
@keyframes bp-zeichnen {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Drei Bereiche: Karte mit Farbleiste oben, Pakete als Liste mit Preis. */
.bereiche { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 28px; }
.bereich { display: flex; flex-direction: column; gap: 14px; padding: 28px; background: var(--surface); border: 1px solid var(--border); border-top: 3px solid var(--farbe-sec); border-radius: var(--radius); }
.bereich-web { border-top-color: var(--farbe-web); }
.bereich-seo { border-top-color: var(--farbe-seo); }
.bereich-zeichen { width: 46px; height: 46px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; background: var(--surface-2); color: var(--farbe-sec); }
.bereich-web .bereich-zeichen { color: var(--farbe-web); }
.bereich-seo .bereich-zeichen { color: var(--farbe-seo); }
.bereich h3 { margin: 0; font-size: 1.45rem; }
.bereich > p { margin: 0; color: var(--text-dim); line-height: 1.6; }
.bereich-pakete { list-style: none; margin: 4px 0 0; padding: 0; flex-grow: 1; }
.bereich-pakete li { display: flex; justify-content: space-between; gap: 12px; padding: 11px 0; border-top: 1px solid var(--border); font-size: 0.95rem; color: var(--text); }
.bereich-pakete b { font-family: var(--mono); font-weight: 500; color: var(--text-dim); white-space: nowrap; }
.bereich .weiter { min-height: 44px; display: inline-flex; align-items: center; color: var(--farbe-sec); font-weight: 600; }
.bereich-web .weiter { color: var(--farbe-web); }
.bereich-seo .weiter { color: var(--farbe-seo); }

:root[data-theme] .schritte-vier { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Belege */
.belege-gitter { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr); gap: 28px; align-items: start; margin-top: 28px; }
.beleg-marke { font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.06em; text-transform: uppercase; margin: 0 0 12px; color: var(--farbe-sec); }
.beleg-marke.m-seo { color: var(--farbe-seo); }
:root[data-theme] .beleg-fall .zahlen { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.beleg-studie { padding: 28px; border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border); }
.beleg-zahl { font-family: var(--anzeige); font-size: 3.4rem; font-weight: 700; line-height: 1; color: var(--text); margin: 6px 0 14px; }

/* Werkzeuge als dunkles Band ueber die volle Breite */
:root[data-theme] .band-dunkel { border-image: conic-gradient(var(--bg) 0 0) fill 0 // 0 100vmax; color: var(--text); }
:root[data-theme] .band-dunkel h2 { color: var(--text); }
:root[data-theme] .band-dunkel .fuehrung { color: var(--text-dim); }
:root[data-theme] .band-dunkel .fuehrung a { color: var(--accent); }

/* Person */
.person-neu { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 48px; align-items: start; }
.person-neu-bild { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius); }
.person-neu-fakten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 32px; margin: 22px 0; }
.person-neu-fakten dt { font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-ghost); }
.person-neu-fakten dd { margin: 2px 0 0; color: var(--text); }

/* --- Saeulenseite /security/ (08.10.2026) -------------------------------
   Nur von seiten/security.html benutzt: Bereichskarten mit Illustration,
   Faktenzeilen, Pruefliste, Notfallstellen und die DMARC-Grafik
   (#dmarc-stufen, ohne JS fertig, security-dmarc.js schaltet um). */
.hero-pruefen-titel { display: block; margin: 0 0 8px; font-size: 0.92rem; font-weight: 600; color: var(--text-dim); }

.saeule-bereiche { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-top: 28px; }
.saeule-bereich { display: flex; flex-direction: column; gap: 6px; padding: 0 0 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); text-decoration: none; overflow: hidden; }
.saeule-bereich:hover { border-color: var(--accent-line); }
.saeule-bereich:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.saeule-bereich img { display: block; width: 100%; height: auto; aspect-ratio: 2 / 1; object-fit: cover; background: #0b0e13; margin-bottom: 8px; }
.saeule-bereich > b, .saeule-bereich > span { padding: 0 18px; }
.saeule-bereich > b { font-family: var(--anzeige); font-size: 1.08rem; }
.saeule-bereich > span { color: var(--text-dim); line-height: 1.55; font-size: 0.95rem; }
.saeule-bereich .saeule-bereich-nr { font-family: var(--mono); font-size: 0.78rem; color: var(--text-ghost); }
.saeule-bereich .saeule-bereich-zahl { margin-top: auto; padding-top: 8px; font-family: var(--mono); font-size: 0.8rem; color: var(--text); }
@media (max-width: 1080px) { .saeule-bereiche { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .saeule-bereiche { grid-template-columns: minmax(0, 1fr); } .saeule-bereich img { aspect-ratio: 3 / 1; } }

.saeule-fakten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 32px; margin: 24px 0 8px; }
.saeule-fakten p { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 12px; margin: 0; padding: 12px 0; border-top: 1px solid var(--border-soft); }
.saeule-fakten b { font-family: var(--anzeige); font-size: 1.15rem; color: var(--text); }
.saeule-fakten span { color: var(--text-dim); line-height: 1.55; }
@media (max-width: 760px) { .saeule-fakten { grid-template-columns: minmax(0, 1fr); } }
.saeule-fakten + .nachsatz { margin-bottom: 22px; }

.pruefliste { list-style: none; counter-reset: pruef; margin: 24px 0 0; padding: 0; display: grid; gap: 0; }
.pruefliste li { counter-increment: pruef; display: grid; grid-template-columns: 2.4rem minmax(0, 15rem) minmax(0, 1fr) minmax(0, 14rem); gap: 6px 18px; align-items: baseline; padding: 14px 0; border-top: 1px solid var(--border-soft); }
.pruefliste li::before { content: counter(pruef); font-family: var(--mono); font-size: 0.8rem; color: var(--accent); }
.pruefliste b { color: var(--text); }
.pruefliste span { color: var(--text-dim); line-height: 1.55; }
.pruefliste .pruef-womit { font-size: 0.9rem; }
@media (max-width: 900px) {
  .pruefliste li { grid-template-columns: 2.4rem minmax(0, 1fr); }
  .pruefliste li > span { grid-column: 2; }
}


/* Rahmen, Polster und Unterschrift kommen seit 08.10.2026 von .grafik. */
.ds-kopf { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.ds-titel { margin: 0; font-weight: 600; color: var(--text); }
.ds-schalter { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: 10px; }
.ds-schalter button { min-height: 36px; padding: 6px 14px; border: 0; border-radius: 7px; background: transparent; color: var(--text-dim); font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer; }
.ds-schalter button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); }
.ds-zeile { margin: 0 0 14px; }
.ds-name { display: flex; flex-wrap: wrap; gap: 2px 10px; align-items: baseline; margin: 0 0 6px; }
.ds-name b { color: var(--text); }
.ds-name span { font-size: 0.86rem; color: var(--text-ghost); }
.ds-balken { display: flex; height: 26px; border-radius: 4px; overflow: hidden; background: var(--surface-3); transition: width 0.4s ease; width: 100%; }
.ds-teil { display: flex; align-items: center; justify-content: center; min-width: 0; height: 100%; font-family: var(--mono); font-size: 0.78rem; font-weight: 600; color: var(--bg); white-space: nowrap; overflow: hidden; transition: width 0.4s ease, opacity 0.2s; }
.ds-teil:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.ds-kein { background: var(--danger); }
.ds-none { background: var(--warn); }
.ds-quarantine { background: var(--farbe-web); }
.ds-reject { background: var(--accent); }
.ds-blass { opacity: 0.18; }
.ds-legende { list-style: none; display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 14px 0 0; padding: 0; font-size: 0.88rem; color: var(--text-dim); }
.ds-legende li, .ds-legende button { display: inline-flex; align-items: center; gap: 8px; }
.ds-legende button { min-height: 32px; padding: 2px 8px; margin: 0 -8px; border: 1px solid transparent; border-radius: 6px; background: none; color: inherit; font: inherit; cursor: pointer; }
.ds-legende button[aria-pressed="true"] { border-color: var(--border); color: var(--text); }
.ds-marke { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
.ds-hinweis { min-height: 1.5em; margin: 10px 0 0; font-size: 0.9rem; color: var(--text); }
.ds-tabelle { margin-top: 6px; }
.ds-tabelle summary { cursor: pointer; color: var(--accent); font-size: 0.92rem; }
@media (prefers-reduced-motion: reduce) { .ds-balken, .ds-teil { transition: none; } }

/* Abschluss: dunkles Band ueber die volle Breite */
:root[data-theme] .abschluss-neu {
  border: 0; border-radius: 0; padding: 72px 0; margin-top: 40px;
  border-image: conic-gradient(var(--bg) 0 0) fill 0 // 0 100vmax;
  background: transparent; color: var(--text);
}
:root[data-theme] .abschluss-neu h2 { color: var(--text); font-size: clamp(1.8rem, 3.4vw, 2.6rem); }
:root[data-theme] .abschluss-neu p { color: var(--text-dim); }
:root[data-theme] .abschluss-neu .knopf-umriss { color: var(--text); border-color: var(--rand-feld); }
:root[data-theme="dunkel"] .abschluss-neu { border-image: conic-gradient(#3ddc97 0 0) fill 0 // 0 100vmax; color: #05140c; }
:root[data-theme="dunkel"] .abschluss-neu h2,
:root[data-theme="dunkel"] .abschluss-neu p { color: #05140c; }
:root[data-theme="dunkel"] .abschluss-neu .knopf-voll { background: #05140c; border-color: #05140c; color: #3ddc97; }
:root[data-theme="dunkel"] .abschluss-neu .knopf-umriss { color: #05140c; border-color: #05140c; }
.mag-huelle > .abschluss-neu:last-child { margin-bottom: -60px; }

@media (max-width: 980px) {
  :root[data-theme] .neu-held { grid-template-columns: minmax(0, 1fr); padding: 48px 0 56px; gap: 36px; }
  .bereiche { grid-template-columns: minmax(0, 1fr); }
  :root[data-theme] .schritte-vier { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .belege-gitter { grid-template-columns: minmax(0, 1fr); }
  .person-neu { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .person-neu-bild { max-width: 160px; }
}
@media (max-width: 560px) {
  :root[data-theme] .schritte-vier { grid-template-columns: minmax(0, 1fr); }
  .person-neu-fakten { grid-template-columns: minmax(0, 1fr); }
  .konsole-zeilen { font-size: 0.78rem; padding: 14px 16px; }
  .konsole-fuss { flex-direction: column; gap: 4px; }
}
@media (max-width: 560px) {
  :root[data-theme] .band-dunkel .werkzeuge { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  :root[data-theme] .band-dunkel .werkzeug { padding: 14px; }
  :root[data-theme] .band-dunkel .werkzeug span { display: none; }
}

/* ==========================================================================
   NETZ IM HINTERGRUND (bis 10.10.2026: RASTER, 02.10.2026)
   Seit 10.10. ein Netz wie ein Abhaengigkeitsgraph statt des 48-px-Gitters:
   Knoten (Punkte, Module, Dienste mit Ring) und ihre Verbindungen, von D3
   beim Erzeugen gerechnet (werkzeuge-js/src/netz-hintergrund.mjs), als
   kachelbare 480-px-SVGs in bilder/netz/ -- eine Datei je Farbe, weil ein
   Hintergrundbild keine CSS-Variablen kennt. Dosiert nach Zonen wie zuvor:
   - heller Inhalt: Dunkelblau mit 4,5 Prozent, Karten bleiben weiss darueber;
   - dunkle Zonen (Aufmacher, Werkzeug-Band, Abschluss): Signal-Gruen,
     zum Rand hin ausgeblendet, im Aufmacher am staerksten hinter der Konsole;
   - getoente Abschnitte bleiben ruhige Flaeche, Beitraege ohne Raster
     (Fliesstext geht vor).
   Kein Skript, keine Bewegung, eine gecachte Datei je Thema. Die Zonen malen ihre Flaeche
   per border-image ueber das Body-Raster -- deshalb tragen sie ein eigenes
   als ::before (die alten Schimmer-Pseudos sind seit 01.10. content:none).
   Beide Netze sind auf die Seitenmitte ausgerichtet, damit sie an den
   Zonenkanten seitlich buendig weiterlaufen.
   ========================================================================== */

:root[data-theme="hell"] { --raster: url("/bilder/netz/netz-hell.svg"); }
:root[data-theme="dunkel"] { --raster: url("/bilder/netz/netz-dunkel.svg"); }
/* In den Zonen kraeftiger: die Maske nimmt zum Rand hin ohnehin viel weg. */
:root[data-theme] .hero-produkt,
:root[data-theme] .band-dunkel,
:root[data-theme] .abschlussband { --raster-zone: url("/bilder/netz/netz-zone.svg"); }
:root[data-theme="dunkel"] .abschluss-neu { --raster-zone: url("/bilder/netz/netz-zone-abschluss.svg"); }

body.magazin {
  background-color: var(--bg);
  background-image: var(--raster);
  background-size: 480px 480px;
  background-position: 50% 0;
}
body.magazin:has(.artikel) { background-image: none; }

:root[data-theme] .hero-produkt,
:root[data-theme] .band-dunkel,
:root[data-theme] .abschluss-neu {
  position: relative;
  isolation: isolate;
}
:root[data-theme] .hero-produkt::before,
:root[data-theme] .band-dunkel::before,
:root[data-theme] .abschluss-neu::before {
  content: "";
  position: absolute;
  inset: 0 calc(50% - 50vw);
  z-index: -1;
  pointer-events: none;
  background-image: var(--raster-zone);
  background-size: 480px 480px;
  background-position: 50% 0;
  -webkit-mask-image: radial-gradient(ellipse 60% 85% at 50% 50%, #000 25%, transparent 80%);
  mask-image: radial-gradient(ellipse 60% 85% at 50% 50%, #000 25%, transparent 80%);
}
:root[data-theme] .hero-produkt::before {
  -webkit-mask-image: radial-gradient(ellipse 55% 80% at 72% 45%, #000 20%, transparent 78%);
  mask-image: radial-gradient(ellipse 55% 80% at 72% 45%, #000 20%, transparent 78%);
}
@media (max-width: 980px) {
  :root[data-theme] .hero-produkt::before {
    -webkit-mask-image: radial-gradient(ellipse 90% 60% at 50% 70%, #000 20%, transparent 80%);
    mask-image: radial-gradient(ellipse 90% 60% at 50% 70%, #000 20%, transparent 80%);
  }
}

@media (forced-colors: active), print {
  body.magazin { background-image: none; }
  :root[data-theme] .hero-produkt::before,
  :root[data-theme] .band-dunkel::before,
  :root[data-theme] .abschluss-neu::before { content: none; }
}

/* --- Startseite: Magazin als Textkarten (Mockup C, 02.10.2026) ------------ */
.notiz-raster {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin-top: 28px;
}
.notiz-karte {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px;
  min-height: 44px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease;
}
.notiz-karte:hover { border-color: var(--notiz-farbe, var(--farbe-sec)); }
.notiz-karte:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.notiz-kopf {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--text-dim);
}
.notiz-rubrik {
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--notiz-farbe, var(--farbe-sec));
}
.notiz-web { --notiz-farbe: var(--farbe-web); }
.notiz-seo { --notiz-farbe: var(--farbe-seo); }
.notiz-titel {
  font-family: var(--anzeige);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--text);
}
@media (max-width: 980px) {
  .notiz-raster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .notiz-raster { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .notiz-karte { transition: none; }
}

/* ==========================================================================
   BEITRAEGE AUFGEFRISCHT 02.10.2026 (uupm: Lesefluss vor Effekt)
   Rubrik in Bereichsfarbe, groesserer Kopf mit Mono-Zeile, Vorspann,
   Inhaltsangabe, nummerierte Abschnitte, Lesefortschritt, Weiterlesen als
   Textkarten wie auf der Startseite. Keine eigene Bewegung.
   ========================================================================== */

.artikel-web { --notiz-farbe: var(--farbe-web); }
.artikel-seo { --notiz-farbe: var(--farbe-seo); }

/* Lesefortschritt: an den Bildlauf gebunden, ohne Skript. Wo der Browser
   scroll-getriebene Animationen nicht kennt, bleibt die Leiste weg. */
.lesefortschritt { display: none; }
@supports (animation-timeline: scroll()) {
  .lesefortschritt {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 30;
    background: var(--knopf);
    transform-origin: 0 50%;
    transform: scaleX(0);
    animation: lesefortschritt linear both;
    animation-timeline: scroll(root block);
    pointer-events: none;
  }
}
@keyframes lesefortschritt { to { transform: scaleX(1); } }

/* Kopf */
:root[data-theme] .artikel .marke-klein {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--notiz-farbe, var(--farbe-sec));
  background: transparent;
  border-color: currentColor;
  border-radius: 6px;
}
:root[data-theme] .artikel-kopf h1 {
  margin: 16px 0 14px;
  font-size: clamp(1.9rem, 4.4vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}
:root[data-theme] .artikel-meta {
  font-family: var(--mono);
  font-size: 0.76rem;
  line-height: 1.7;
  color: var(--text-dim);
  padding-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
:root[data-theme] .artikel-meta .artikel-aktualisiert { color: var(--text-dim); }

/* Vorspann: der erste Absatz traegt die Antwort, er darf groesser sein. */
:root[data-theme] .prosa > p:first-child {
  font-size: 1.16rem;
  line-height: 1.6;
  color: var(--text);
}

/* Inhaltsangabe */
.inhaltsangabe {
  max-width: var(--mass);
  margin: 26px auto 6px;
  padding: 18px 22px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-sizing: border-box;
}
.artikel > .inhaltsangabe { width: calc(100% - 2 * var(--luft)); }
.inhaltsangabe-titel {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.inhaltsangabe ol {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: punkt;
}
.inhaltsangabe li { counter-increment: punkt; }
.inhaltsangabe a {
  display: flex;
  gap: 12px;
  min-height: 44px;
  align-items: center;
  padding: 2px 0;
  color: var(--text);
  text-decoration: none;
  font-size: 0.95rem;
  line-height: 1.4;
}
.inhaltsangabe a::before {
  content: counter(punkt, decimal-leading-zero);
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--text-dim);
}
.inhaltsangabe a:hover { color: var(--accent); text-decoration: underline; }
.inhaltsangabe li + li { border-top: 1px solid var(--border-soft); }

/* Abschnitte nummeriert, passend zur Inhaltsangabe */
.prosa { counter-reset: abschnitt; }
:root[data-theme] .prosa h2 {
  counter-increment: abschnitt;
  margin-top: 52px;
  font-size: clamp(1.35rem, 2.6vw, 1.6rem);
  letter-spacing: -0.02em;
}
:root[data-theme] .prosa h2::before {
  content: counter(abschnitt, decimal-leading-zero);
  display: block;
  margin-bottom: 8px;
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--notiz-farbe, var(--farbe-sec));
}

/* Hervorhebungen als leiser Textmarker */
:root[data-theme] .prosa strong {
  background: linear-gradient(transparent 60%, var(--accent-bg) 60%);
  color: var(--text);
}

/* Bilder mit Haarlinie */
:root[data-theme] .prosa .textbild img {
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* Zitate */
:root[data-theme] .prosa blockquote {
  border-left-color: var(--notiz-farbe, var(--farbe-sec));
  color: var(--text);
  font-size: 1.05rem;
}

/* Weiterlesen: Textkarten wie die Startseite */
:root[data-theme] .weiterlesen h2 {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
:root[data-theme] .weiterlesen-liste a {
  gap: 10px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.15s ease;
}
:root[data-theme] .weiterlesen-liste a:hover,
:root[data-theme] .weiterlesen-liste a:focus-visible {
  background: var(--surface);
  border-color: var(--notiz-farbe, var(--farbe-sec));
}
:root[data-theme] .weiterlesen-liste b {
  font-family: var(--anzeige);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
}
:root[data-theme] .weiterlesen-liste .notiz-kopf { font-size: 0.72rem; }
:root[data-theme] .weiterlesen-liste .notiz-kopf span { font-size: inherit; line-height: 1.2; }
:root[data-theme] .weiterlesen-liste .notiz-rubrik { color: var(--notiz-farbe, var(--farbe-sec)); }
.weiterlesen-liste .notiz-web { --notiz-farbe: var(--farbe-web); }
.weiterlesen-liste .notiz-seo { --notiz-farbe: var(--farbe-seo); }
.weiterlesen-liste .notiz-sec { --notiz-farbe: var(--farbe-sec); }

@media (prefers-reduced-motion: reduce) {
  :root[data-theme] .weiterlesen-liste a { transition: none; }
}
@media print {
  .lesefortschritt, .inhaltsangabe { display: none; }
}
:root[data-theme] .weiterlesen-liste { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* ==========================================================================
   LEISTUNGSSEITEN WEBDESIGN ZILLERTAL UND WORDPRESS-WARTUNG (02.10.2026)
   Nur eine Ergaenzung: sechs Karten in drei Spalten statt 4 + 2 aus dem
   auto-fit-Raster von .karten. Farben bleiben die Tokens der Karten,
   der Kontrast ist damit derselbe wie dort.
   ========================================================================== */
.karten-drei { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-top: 28px; }
.karten-drei .karte { padding: 22px; background: var(--surface); border-color: var(--border); }
.karten-drei .karte h3 { margin: 0 0 8px; font-size: 1.08rem; }
.karten-drei .karte p { margin: 0; color: var(--text-dim); line-height: 1.6; }
.karten-drei .karte a { color: var(--accent); }
@media (max-width: 980px) { .karten-drei { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .karten-drei { grid-template-columns: minmax(0, 1fr); } }
/* Codekaesten sind per Tastatur erreichbar (tabindex in build/markdown.mjs),
   also brauchen sie einen sichtbaren Fokus. */
.prosa pre:focus-visible,
.tabelle-rahmen:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Startseite: Notfall-Hinweis in der Security-Karte, Verweise in Paketliste
   und Personen-Fakten (02.10.2026). Farben aus den Tokens, Kontrast wie
   --accent (hell 5,3:1, dunkel 10,6:1). */
.bereich .bereich-notfall { font-size: 0.9rem; }
.bereich .bereich-notfall a,
.bereich-pakete li a,
.person-neu-fakten dd a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.bereich-pakete li a { color: inherit; text-decoration-color: var(--accent-line); }

/* ==========================================================================
   DMARC- UND SPF-GENERATOR (/dmarc-generator/, /spf-generator/, 02.10.2026)

   Links das Formular, rechts der fertige Eintrag mit den Befunden; ab
   1000 px nebeneinander, die Ausgabe bleibt beim Scrollen stehen. Darunter
   untereinander, die Ausgabe direkt nach dem Formular.

   Die Stufe eines Befunds steht immer auch als Wort davor ("Fehler",
   "Warnung"), die Farbe ist nur Zugabe. Farben aus den Tokens: --danger,
   --warn, --success und --accent erreichen in beiden Saetzen mindestens
   4,5:1 auf --surface (siehe Kopf der Neugestaltung oben).
   ========================================================================== */
.gen {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  margin-top: 24px;
}

@media (min-width: 1000px) {
  .gen {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
  }
  .gen-ausgabe {
    position: sticky;
    top: 88px;
  }
}

.gen-formular {
  min-width: 0;
}

.gen-gruppe {
  margin: 0 0 18px;
  padding: 0;
  border: 0;
  min-width: 0;
}

.gen-gruppe legend {
  margin-bottom: 8px;
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
}

.gen-wahl {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: 8px;
  align-items: start;
  margin: 0 0 6px;
  padding: 8px 10px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.92rem;
  line-height: 1.5;
  cursor: pointer;
}

.gen-wahl input {
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  accent-color: var(--accent);
}

.gen-wahl:has(input:checked) {
  border-color: var(--accent);
}

.gen-wahl:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.feld select {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--rand-feld, var(--border));
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.94rem;
}

.feld select:focus-visible,
.gen-mehr summary:focus-visible,
.gen-kopieren:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.gen-mehr {
  margin: 0 0 18px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
}

.gen-mehr summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.92rem;
}

.gen-mehr[open] summary {
  margin-bottom: 14px;
}

.gen-mehr .feld:last-child,
.gen-mehr .gen-gruppe:last-child {
  margin-bottom: 0;
}

.gen-ausgabe {
  min-width: 0;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.gen-felder {
  margin: 0;
  display: grid;
  gap: 12px;
}

.gen-felder dt {
  font-family: var(--mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

.gen-felder dd {
  margin: 4px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.gen-felder code {
  font-family: var(--mono);
  font-size: 0.9rem;
  overflow-wrap: anywhere;
}

.gen-wert {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-all;
}

.gen-klein {
  flex-basis: 100%;
  font-size: 0.82rem;
  color: var(--text-faint);
}

.gen-kopieren {
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
}

.gen-kopieren-gross {
  min-height: 44px;
  padding: 10px 20px;
  border-color: var(--knopf, var(--accent));
  background: var(--knopf, var(--accent));
  color: var(--auf-knopf, var(--auf-akzent));
}

.gen-status {
  min-height: 1.4em;
  margin: 8px 0 0;
  font-size: 0.86rem;
  color: var(--text-dim);
}

.gen-bilanz {
  margin: 14px 0 8px;
  font-weight: 700;
}

.gen-bilanz:empty {
  margin: 0;
}

.gen-befunde {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.gen-befund {
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

.gen-marke {
  display: inline-block;
  margin-right: 8px;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.gen-fehler { border-left-color: var(--danger); }
.gen-fehler .gen-marke { color: var(--danger); }
.gen-warnung { border-left-color: var(--warn); }
.gen-warnung .gen-marke { color: var(--warn); }
.gen-hinweis { border-left-color: var(--text-ghost); }
.gen-hinweis .gen-marke { color: var(--text-faint); }
.gen-ok { border-left-color: var(--success); }
.gen-ok .gen-marke { color: var(--success); }

.gen-weiter {
  margin: 16px 0 0;
  font-size: 0.9rem;
  color: var(--text-dim);
}

.gen-weiter a,
.gen-ausgabe a {
  color: var(--accent);
  text-underline-offset: 2px;
}

.gen-pruefer {
  max-width: 46rem;
  margin-top: 20px;
}

.gen-pruefer textarea {
  font-family: var(--mono);
  font-size: 0.88rem;
}

.gen-pruefer .knopf {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
}

.gen-schritte {
  max-width: 66ch;
  margin: 0 0 18px;
  padding-left: 1.3em;
  color: var(--text-dim);
  line-height: 1.65;
}

.gen-schritte li {
  margin-bottom: 10px;
}

.gen-schritte code,
.fuehrung code,
.hero-sub code,
.ec-zeile code {
  font-family: var(--mono);
  font-size: 0.88em;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   BLACKLIST-CHECK (/blacklist-check/, 02.10.2026)
   Die Zeilen sind die .ec-zeile des E-Mail-Checks; darin je Adresse eine
   kurze Liste der fuenf Blacklists. Der Status steht als Wort da
   ("gelistet"), die Farbe kommt nur beim Treffer dazu.
   ========================================================================== */
.bl-listen {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 4px;
  font-size: 0.88rem;
  color: var(--text-dim);
}

.bl-listen li {
  overflow-wrap: anywhere;
  line-height: 1.5;
}

.bl-gelistet strong {
  color: var(--danger);
}

.bl-unklar strong {
  color: var(--warn);
}

.bl-grund,
.bl-tun {
  color: var(--text-dim);
}

.bl-listen a {
  color: var(--accent);
  text-underline-offset: 2px;
}

/* --- Magazin-Uebersicht: Durchsicht mit UI UX Pro Max (03.10.2026) --------

   Beitraege vor den Messungen (die Liste ist, wofuer man kommt), eine
   Kopfzeile mit Rubrik-Filter, Stand-Datum auf jeder Karte, und die
   Messtabelle auf dem Handy als gestapelte Karten statt einer Tabelle, die
   seitlich abgeschnitten wird. */

.mag-kopfzeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  margin-bottom: 22px;
}

.mag-kopfzeile h2 {
  margin: 0;
}

.mag-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.mag-filter[hidden] {
  display: none;
}

.mag-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.mag-chip span {
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-faint);
}

.mag-chip:hover {
  border-color: var(--accent-line);
}

.mag-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.mag-chip[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-bg);
}

.mag-chip[aria-pressed="true"] span {
  color: var(--accent);
}

.mag-filter-status:empty {
  display: none;
}

.mag-filter-status {
  margin: -8px 0 16px;
  font-size: 0.88rem;
  color: var(--text-faint);
}

.artikelliste .artikel-karte[hidden] {
  display: none;
}

.artikel-datum time {
  white-space: nowrap;
}

/* Links in der Messtabelle in der Akzentfarbe statt Browser-Blau. */
.mess-tabelle a {
  color: var(--accent-soft);
  text-underline-offset: 2px;
}

.mess-tabelle td:first-child {
  white-space: nowrap;
}

@media (max-width: 720px) {
  .mess-tabelle {
    overflow: visible;
    border: 0;
  }
  .mess-tabelle table,
  .mess-tabelle tbody,
  .mess-tabelle tr,
  .mess-tabelle td {
    display: block;
    width: 100%;
  }
  .mess-tabelle thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .mess-tabelle tr {
    margin: 0 0 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
  }
  .mess-tabelle td {
    padding: 4px 0;
    border: 0;
  }
  .mess-tabelle td:first-child {
    white-space: normal;
  }
  .mess-tabelle td::before {
    content: attr(data-titel);
    display: block;
    font-family: var(--mono);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
}

@media (prefers-reduced-motion: reduce) {
  .mag-chip {
    transition: none;
  }
}

/* Auf dem Handy ist das Heldenbild der Uebersicht zu klein zum Lesen
   (Schrift unter 8 px) und schiebt die Beitraege eine Bildschirmhoehe nach
   unten. Die Zahlen stehen ohnehin in Filter und Karten. */
@media (max-width: 640px) {
  .hero-magazin .produkt-rahmen {
    display: none;
  }
}

/* --- Beitragsseite: Durchsicht mit UI UX Pro Max (03.10.2026) ------------

   1. Codekaesten brechen um statt seitlich abzuschneiden. Auf dem Handy war
      von einem DNS-Eintrag nur die erste Haelfte zu sehen -- ausgerechnet
      das, was man abschreiben soll. Dazu ein Kopierknopf (beitrag.js).
   2. "Kurz gesagt", Kennzahl und Newsletter stehen in derselben Flucht wie
      Inhaltsangabe und Text statt buendig am Kartenrand.
   3. Inhaltsangabe ab 760 px zweispaltig: zwoelf Punkte fuellten sonst
      einen ganzen Bildschirm.
   4. Screenshots tragen ein Etikett, damit niemand auf den abgebildeten
      Knopf "Kopieren" tippt. */

.prosa pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.code-huelle {
  position: relative;
}

.code-huelle pre {
  padding-right: 92px;
}

.code-kopieren {
  position: absolute;
  top: 8px;
  right: 8px;
  min-height: 32px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 0.74rem;
  cursor: pointer;
}

.code-kopieren:hover {
  color: var(--text);
  border-color: var(--accent-line);
}

.code-kopieren:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.code-kopieren-status {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

@media (pointer: coarse) {
  .code-kopieren {
    min-height: 40px;
  }
}

.artikel > .kurz,
.artikel > .kennzahl {
  box-sizing: border-box;
  width: calc(100% - 2 * var(--luft));
  max-width: var(--mass);
  margin-left: auto;
  margin-right: auto;
}

.artikel > .newsletter {
  box-sizing: border-box;
  width: calc(100% - 2 * var(--luft));
  max-width: var(--mass);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 760px) {
  .inhaltsangabe ol {
    columns: 2;
    column-gap: 28px;
  }
  .inhaltsangabe li {
    break-inside: avoid;
  }
}

.screenshot {
  position: relative;
  /* Nie breiter als die Aufnahme in 1:1 plus Polster und Haarlinie
     (build/screenshots.mjs setzt --screenshot-breite). */
  max-width: calc(var(--screenshot-breite, 100vw) + 22px);
}

.screenshot img {
  padding: 30px 10px 10px;
  background: var(--surface-2);
  box-sizing: border-box;
}

.screenshot::before {
  content: "Screenshot";
  position: absolute;
  top: 8px;
  left: 12px;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

@media (max-width: 640px) {
  .artikel > .newsletter {
    margin-left: auto;
    margin-right: auto;
    width: calc(100% - 2 * var(--luft));
  }
}

/* --- Kontaktseite mit klarem CTA (UI UX Pro Max, 03.10.2026) ---------------

   Vorher stand das Formular nach drei Textabschnitten ganz unten, die
   Nachricht war auf 180 Zeichen begrenzt und es gab kein Feld fuer die
   Website, obwohl der Text darum bittet. Jetzt: zwei Knoepfe im Kopf,
   Formular als erste Spalte, Hinweise und direkte Wege daneben (auf dem
   Handy darunter), Thema als Auswahl. */

.kontakt-raster {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 32px 48px;
  align-items: start;
}

:root[data-theme] .kontakt-raster .kontakt-formular-spalte h2,
.kontakt-formular-spalte h2,
.kontakt-block h2 {
  margin: 0 0 14px;
  font-size: 1.3rem;
}

.formular-karte {
  max-width: none;
  margin-top: 0;
  padding: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.feld-paar {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}

.feld input,
.feld textarea {
  min-height: 44px;
  font-size: 1rem;
}

.paket-hinweis {
  margin: 0 0 16px;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: var(--accent-bg);
  color: var(--text);
  font-size: 0.9rem;
}

.thema-wahl {
  margin: 0 0 18px;
  padding: 0;
  border: 0;
}

.thema-wahl legend {
  margin-bottom: 8px;
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
}

.thema-optionen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.thema-optionen label {
  position: relative;
  cursor: pointer;
}

/* Das Radio bleibt im DOM und per Tastatur bedienbar (Pfeiltasten in der
   Gruppe); sichtbar ist nur der Chip. */
.thema-optionen input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.thema-optionen span {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.thema-optionen label:hover span {
  border-color: var(--accent-line);
}

.thema-optionen input:checked + span {
  border-color: var(--accent);
  background: var(--accent-bg);
}

.thema-optionen input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.notfall-hinweis {
  margin: 10px 0 0;
  padding: 8px 12px;
  border-left: 3px solid var(--danger);
  background: var(--surface-2);
  color: var(--text);
  font-size: 0.9rem;
}

.notfall-hinweis a {
  color: var(--accent-soft);
  font-weight: 600;
}

.feld-abschluss .knopf {
  min-height: 48px;
  padding: 12px 28px;
}

.kontakt-seite {
  display: grid;
  gap: 28px;
}

.kontakt-block .haken {
  margin-top: 0;
}

.erreichbar-kompakt {
  grid-template-columns: 1fr;
  gap: 8px;
}

.erreichbar-kompakt > div {
  padding: 12px 14px;
}

@media (max-width: 900px) {
  .kontakt-raster {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 560px) {
  .feld-paar {
    grid-template-columns: 1fr;
  }
  .formular-karte {
    padding: 18px 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .thema-optionen span {
    transition: none;
  }
}

/* --- Diagramm auf /cybersecurity/ (03.10.2026) -----------------------------
   Das breite Balkendiagramm (800 x 300) schrumpfte auf dem Handy auf
   6-px-Schrift und wurde rechts abgeschnitten. Unter 640 px steht statt
   dessen eine hohe Fassung mit Beschriftung ueber dem Balken.
   Mit .diagramm davor (08.10.2026): ".diagramm svg { display: block }"
   wiegt mehr als die Klasse allein, und so stand die hohe Fassung auch
   am Desktop unter der breiten. */
.diagramm .diagramm-mobil {
  display: none;
}

@media (max-width: 640px) {
  .diagramm .diagramm-breit {
    display: none;
  }
  .diagramm .diagramm-mobil {
    display: block;
    min-width: 0;
    width: 100%;
    height: auto;
  }
  .diagramm {
    overflow: visible;
  }
}

/* --- Dienste-Tabelle auf /dsgvo/ (03.10.2026) ------------------------------
   Vier Spalten auf 390 px: die Tabelle war 880 px breit und jede Zeile
   so hoch wie ihre laengste, unsichtbare Zelle. Auf dem Handy als Karten. */
@media (max-width: 720px) {
  .tabelle-rahmen:has(.dienste-tabelle) {
    overflow: visible;
    border: 0;
  }
  .dienste-tabelle,
  .dienste-tabelle tbody,
  .dienste-tabelle tr,
  .dienste-tabelle td {
    display: block;
    width: 100%;
  }
  .dienste-tabelle thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .dienste-tabelle tr {
    margin: 0 0 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
  }
  .dienste-tabelle td {
    padding: 3px 0;
    border: 0;
  }
  .dienste-tabelle td:first-child {
    font-weight: 700;
    font-size: 1rem;
  }
  .dienste-tabelle td:nth-child(n + 2)::before {
    display: block;
    font-family: var(--mono);
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .dienste-tabelle td:nth-child(2)::before { content: "Wofür"; }
  .dienste-tabelle td:nth-child(3)::before { content: "Aufwand"; }
  .dienste-tabelle td:nth-child(4)::before { content: "Der Kern"; }
}

/* hidden muss gewinnen: .feld-hinweis setzt display:block. */
.paket-hinweis[hidden],
.notfall-hinweis[hidden] {
  display: none;
}

:root[data-theme] .kontakt-raster h2,
.kontakt-raster h2 {
  margin: 0 0 14px;
  font-size: 1.35rem;
  line-height: 1.25;
}

@media (max-width: 720px) {
  .dienste-tabelle tr,
  .dienste-tabelle td {
    box-sizing: border-box;
  }
}

@media (max-width: 640px) {
  figure:has(> .diagramm) {
    margin-left: 0;
    margin-right: 0;
  }
}

/* --- Ruhiger (03.10.2026) ---------------------------------------------------

   Dachzeilen: keine Versalien, keine Haarlinie, keine Markenfarbe. Eine
   gesperrte Grossbuchstaben-Zeile ueber jeder Ueberschrift ist das, was
   jede Vorlage hat -- als normaler Satz in Grau sagt sie dasselbe leiser.

   Gruen bleibt den Aktionen: Knopf, Link, Pruefergebnis. Die Werkzeug-
   Zeichen standen als zehn gruene Kacheln neben dem Hauptknopf und nahmen
   ihm die Aufmerksamkeit; jetzt nur noch das Zeichen selbst. */
:root[data-theme] .eyebrow {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-dim);
}

:root[data-theme] .eyebrow::after {
  content: none;
}

:root[data-theme] .werkzeug-zeichen {
  width: 24px;
  height: 24px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--accent);
  margin-bottom: 14px;
}

/* --- Feinschliff (impeccable, 03.10.2026) ----------------------------------

   Dachzeilen sind aus dem Markup raus -- die Ueberschrift traegt sich
   selbst. Uebrig sind nur die Zeilen, die eine Tatsache sagen, die sonst
   nirgends steht ("Kostenloser E-Mail-Check").

   Weniger Kaesten: Werkzeuge und Fragen sind Listen, keine Kartenstapel.
   Eine Linie oben trennt die Eintraege, mehr braucht es nicht.

   Ein Trennmittel zwischen Abschnitten: Flaeche und Abstand. Die Haarlinie
   unter jedem Abschnitt sagte zum dritten Mal dasselbe. */

:root[data-theme] .abschnitt {
  border-bottom: 0;
}

/* Zwei helle Abschnitte hintereinander: der zweite schliesst ohne zweiten
   vollen Abstand an, sonst klafft ohne Linie ein Loch. */
:root[data-theme] .abschnitt:not(.abschnitt-getoent):not(.band-dunkel)
  + .abschnitt:not(.abschnitt-getoent):not(.band-dunkel) {
  padding-top: 0;
}

/* Werkzeuge: Zeichen, Name, Satz -- als Liste mit Linie oben. */
:root[data-theme] .werkzeuge {
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  column-gap: 32px;
  row-gap: 8px;
}

:root[data-theme] .werkzeug,
:root[data-theme] .abschnitt-getoent .werkzeug {
  background: none;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  padding: 20px 0 16px;
  transform: none;
}

:root[data-theme] .werkzeug:hover {
  background: none;
  border-color: var(--accent-line);
  transform: none;
}

:root[data-theme] .werkzeug:hover b {
  text-decoration: underline;
  text-underline-offset: 3px;
}

:root[data-theme] .werkzeug:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* Fragen: Zeilen mit Linie, kein Kasten pro Frage. */
:root[data-theme] .fragen {
  gap: 0;
  border-top: 1px solid var(--border);
}

:root[data-theme] .fragen details,
:root[data-theme] .abschnitt-getoent .fragen details {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
}

:root[data-theme] .fragen summary {
  padding: 22px 44px 22px 0;
}

:root[data-theme] .fragen summary::after {
  right: 4px;
}

:root[data-theme] .fragen p {
  padding: 0 44px 24px 0;
  max-width: 70ch;
}

/* Textlinks ohne angehaengten Pfeil -- der Linktext sagt, wohin es geht. */
.weiter::after,
.mehr::after {
  content: none;
}

/* "Alle Beitraege im Magazin" sah als grauer Block deaktiviert aus. */
:root[data-theme] .magazin-knopf .knopf {
  background: none;
  border: 1px solid var(--rand-feld);
  color: var(--text);
  font-weight: 600;
}

:root[data-theme] .magazin-knopf .knopf:hover {
  border-color: var(--text-dim);
  background: var(--surface-2);
}

/* Pruefbericht auf dem Handy: eine Spur kleiner, damit Domain und
   Zertifikatszeile nicht mitten im Wort umbrechen. */
@media (max-width: 420px) {
  .konsole-zeilen {
    font-size: 0.75rem;
    padding: 14px 14px;
  }

  .konsole-zeilen li {
    gap: 8px;
  }

  .bereich-marken li {
    font-size: 0.8rem;
  }
}

/* --- Kopfleiste mit frontend-design (04.10.2026) ---------------------------
   Ruhiger und eindeutiger. Die Symbolknoepfe tragen keinen Rahmen mehr, und ein Strich trennt Werkzeuge der Seite (Suche, Thema)
   von den Wegen hinaus (App, Projekt).

   DAS EINE AUFFAELLIGE: Die aktuelle Seite markiert ein gruener Strich,
   der AUF der Unterkante des Bandes sitzt -- wie ein Cursor in der
   Zeile. Dafuer reichen die Punkte ueber die volle Hoehe des Bandes.

   Das Leistungsmenue sagt je Bereich in einer Zeile, worum es geht, und
   nennt den Einstiegspreis. Wer "Leistungen" oeffnet, will wissen, was
   es gibt und was es ungefaehr kostet. */
.mag-kopf-band .kopf-knopf {
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 8px;
  color: var(--text-dim);
}
.mag-kopf-band .kopf-knopf:hover {
  background: var(--surface-2);
  color: var(--text);
}
.mag-kopf-band .kopf-knopf svg {
  width: 18px;
  height: 18px;
}
.mag-kopf-band .kopf-knoepfe {
  align-items: center;
  gap: 4px;
}
:root[data-theme] .mag-kopf-band .kopf-werkzeuge {
  position: relative;
  margin-left: 13px;
  padding: 8px 12px;
  font-size: 0.9rem;
}
.mag-kopf-band .kopf-werkzeuge::before {
  content: "";
  position: absolute;
  left: -9px;
  top: 50%;
  width: 1px;
  height: 20px;
  margin-top: -10px;
  background: var(--border);
}
:root[data-theme] .mag-kopf-band .kopf-werkzeuge:hover {
  background: none;
}
:root[data-theme] .mag-kopf-band .kopf-starten {
  margin-left: 4px;
  padding: 9px 16px;
  border-radius: 8px;
  font-size: 0.88rem;
  font-weight: 600;
}
.mag-kopf-band .kopf-starten:focus-visible,
.mag-kopf-band .kopf-werkzeuge:focus-visible,
.mag-kopf-band .mag-nav a:focus-visible,
.mag-kopf-band .mag-menue > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Breit: die Leiste in einer Zeile, 64 px hoch, Punkte ueber die volle
   Hoehe -- damit der Strich der aktuellen Seite auf der Kante sitzt. */
@media (min-width: 1201px) {
  .mag-kopf-band .mag-kopf {
    min-height: 64px;
    padding-top: 0;
    padding-bottom: 0;
    gap: 28px;
  }
  .mag-kopf-band .mag-logo {
    align-self: center;
  }
  .mag-kopf-band .mag-nav {
    align-self: stretch;
    flex-wrap: nowrap;
    gap: 0 2px;
  }
  .mag-kopf-band .mag-nav > a,
  .mag-kopf-band .mag-menue > summary {
    position: relative;
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 11px;
    border-radius: 0;
    background: none;
    box-shadow: none;
    font-size: 0.9rem;
  }
  .mag-kopf-band .mag-menue {
    display: flex;
  }
  .mag-kopf-band .mag-nav > a:hover,
  .mag-kopf-band .mag-menue > summary:hover,
  .mag-kopf-band .mag-menue[open] > summary {
    background: none;
    color: var(--text);
  }
  .mag-kopf-band .mag-nav > a[aria-current="page"],
  .mag-kopf-band .mag-menue > summary[aria-current="page"] {
    box-shadow: none;
    border-radius: 0;
  }
  .mag-kopf-band .mag-nav > a[aria-current="page"]::after,
  .mag-kopf-band .mag-menue > summary[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 11px;
    right: 11px;
    bottom: -1px;
    height: 2px;
    background: var(--accent);
  }

  /* Der Fokusrahmen umschliesst den Text, nicht die volle Bandhoehe. */
  .mag-kopf-band .mag-nav > a:focus-visible,
  .mag-kopf-band .mag-menue > summary:focus-visible {
    outline: none;
  }
  .mag-kopf-band .mag-nav > a:focus-visible::before,
  .mag-kopf-band .mag-menue > summary:focus-visible::before {
    content: "";
    position: absolute;
    inset: 15px 1px;
    border: 2px solid var(--accent);
    border-radius: 6px;
  }

  /* Das Feld der Leistungen. */
  .mag-kopf-band .mag-menue__feld {
    position: absolute;
    top: calc(100% + 1px);
    left: -6px;
    width: 452px;
    padding: 6px;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
  }
}

.mag-kopf-band .mag-menue__feld > a {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  align-items: start;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 6px;
  white-space: normal;
}
.mag-kopf-band .mag-menue__feld > a svg {
  margin-top: 2px;
}
.mag-menue__name {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text);
}
.mag-menue__name small {
  display: block;
  margin-top: 2px;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--text-faint);
}
.mag-menue__preis {
  padding-top: 1px;
  font-size: 0.8rem;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mag-kopf-band .mag-menue__feld > a:hover .mag-menue__preis,
.mag-kopf-band .mag-menue__feld > a[aria-current="page"] .mag-menue__preis {
  color: var(--text);
}
.mag-kopf-band .mag-menue__feld > a[aria-current="page"] {
  box-shadow: none;
  border-radius: 6px;
}
.mag-menue__fuss {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  gap: 2px;
  margin: 6px -6px -6px;
  padding: 6px;
  border-top: 1px solid var(--border-soft);
  background: var(--surface-2);
  border-radius: 0 0 var(--radius) var(--radius);
}
.mag-kopf-band .mag-menue__fuss a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 0.8rem;
  color: var(--text-dim);
  text-decoration: none;
  white-space: normal;
}
.mag-kopf-band .mag-menue__fuss a:hover {
  background: var(--surface-3);
  color: var(--text);
}

/* Schmal (Menueknopf): die Liste in der Anzeigeschrift, die Leistungen
   offen darunter, jede mit Preis -- die Erklaerzeile faellt weg. */
@media (max-width: 1200px) {
  .mit-menue .menue-knopf:not([hidden]) {
    display: inline-flex;
  }
  .mit-menue .mag-kopf {
    flex-wrap: wrap;
    row-gap: 0;
  }
  .mit-menue .kopf-knoepfe {
    margin-left: auto;
  }
  .mit-menue .mag-nav {
    display: none;
    order: 10;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 0 4px;
    margin-top: 12px;
    border-top: 1px solid var(--border-soft);
  }
  .mit-menue.nav-offen .mag-nav {
    display: flex;
  }
  .mag-kopf-band.mit-menue .mag-nav > a,
  .mag-kopf-band.mit-menue .mag-menue > summary {
    display: flex;
    padding: 10px 12px;
    font-family: var(--anzeige);
    font-size: 1.05rem;
    font-weight: 500;
    color: var(--text);
  }
  .mag-kopf-band.mit-menue .mag-menue > summary .mag-menue__pfeil {
    display: none;
  }
  .mag-kopf-band.mit-menue .mag-menue__feld {
    position: static;
    width: auto;
    min-width: 0;
    margin: 0 0 8px;
    padding: 0;
    border: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    margin-left: 12px;
    background: none;
    box-shadow: none;
  }
  .mag-kopf-band.mit-menue .mag-menue__feld > a {
    grid-template-columns: 16px 1fr auto;
    align-items: center;
    padding: 9px 12px;
  }
  .mag-kopf-band.mit-menue .mag-menue__feld > a svg {
    margin-top: 0;
  }
  .mit-menue .mag-menue__name small {
    display: none;
  }
  .mag-kopf-band.mit-menue .mag-menue__feld > a[aria-current="page"] {
    box-shadow: inset 2px 0 0 var(--accent);
    border-radius: 0 6px 6px 0;
  }
  .mit-menue .mag-menue__fuss {
    grid-template-columns: 1fr;
    margin: 4px 0 0;
    padding: 4px 0 0;
    background: none;
    border-top: 0;
  }
}
@media (max-width: 760px) {
  .mit-menue .kopf-knoepfe {
    display: contents;
  }
  .mit-menue .kopf-starten {
    margin-left: auto;
  }
  :root[data-theme] .mag-kopf-band.mit-menue .kopf-starten {
    padding: 8px 14px;
    font-size: 0.85rem;
  }
  .mit-menue .menue-knopf {
    order: 2;
  }
  /* Unter der Liste: Suche und Thema links, die App rechts als
     Umrissknopf -- als eigene Zeile mit Strich darueber. */
  .mit-menue .kopf-knopf:not(.menue-knopf),
  .mit-menue .kopf-werkzeuge {
    display: none;
    order: 11;
  }
  .mit-menue.nav-offen .kopf-knopf:not(.menue-knopf):not([hidden]) {
    display: inline-flex;
    margin: 0 0 14px;
  }
  :root[data-theme] .mag-kopf-band.mit-menue.nav-offen .kopf-werkzeuge {
    display: inline-flex;
    margin: 0 0 14px auto;
    border: 1px solid var(--rand-feld);
    border-radius: 8px;
    color: var(--text);
  }
  .mit-menue .kopf-werkzeuge::before {
    display: none;
  }
  .mit-menue.nav-offen .mag-nav {
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border-soft);
    padding-bottom: 8px;
  }
}

/* ==========================================================================
   STARTSEITE STIMMIG MACHEN (06.10.2026)

   Nach dem Dreiklang im Aufmacher: weniger gleiche Kaesten darunter, die
   Messung als Bild, Beschriftungen in normaler Schreibweise.
   ========================================================================== */

/* Vertrauen: bleibt die Kachel mit vier Feldern und Zeichen im Kreis
   (am 06.10.2026 kurz als rahmenlose Zeile, auf Wunsch zurueck). */

/* Arbeitsweise als Zeitleiste: vier Punkte auf einer Linie, keine Karten.
   Die Reihenfolge ist echt (messen, priorisieren, umsetzen, nachmessen),
   deshalb bleiben die Ziffern. */
:root[data-theme] #ablauf .schritte {
  position: relative;
  gap: 32px;
  margin-top: 36px;
}
:root[data-theme] #ablauf .schritte li {
  position: relative;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 30px 0 0;
}
/* Die Linie laeuft von Punkt zu Punkt; beim letzten Schritt endet sie. */
:root[data-theme] #ablauf .schritte li::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 58px;
  right: -22px;
  height: 2px;
  background: var(--text-ghost);
  opacity: 0.45;
}
:root[data-theme] #ablauf .schritte li:last-child::before { display: none; }
:root[data-theme] #ablauf .schritt-nr {
  position: absolute;
  top: 0;
  left: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--surface-2);
  margin: 0;
}
:root[data-theme] #ablauf .schritt-nr::before {
  position: absolute;
  left: 26px;
  top: -4px;
  font-size: 0.85rem;
  white-space: nowrap;
}
@media (max-width: 760px) {
  /* Untereinander: die Linie laeuft senkrecht links. */
  :root[data-theme] #ablauf .schritte li { padding: 0 0 0 40px; }
  :root[data-theme] #ablauf .schritte li::before {
    top: 14px;
    bottom: -32px;
    left: 6px;
    right: auto;
    width: 2px;
    height: auto;
  }
  :root[data-theme] #ablauf .schritt-nr { top: 2px; }
  :root[data-theme] #ablauf .schritt-nr::before { display: none; }
}

/* Belege: Titel statt Grossbuchstaben-Marke, die Messung als Punkteraster. */
.beleg-titel {
  margin: 0 0 18px;
  font-size: 1.35rem;
  line-height: 1.3;
}
.punkteraster {
  display: grid;
  grid-template-columns: repeat(30, minmax(0, 1fr));
  gap: 5px;
}
.punkteraster i {
  display: block;
  aspect-ratio: 1;
  border-radius: 50%;
}
.pr-offen { background: #ff7a7a; }
.pr-dicht { background: var(--farbe-sec); }
.punkteraster-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin: 14px 0 18px;
  font-size: 0.86rem;
  color: var(--text-dim);
}
.punkteraster-legende span::before {
  content: "";
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 8px;
  border-radius: 50%;
  vertical-align: 1px;
}
.pr-l-offen::before { background: #ff7a7a; }
.pr-l-dicht::before { background: var(--farbe-sec); }
/* Schmal: 15 statt 30 Spalten, sonst werden die Punkte zu Krumen. */
@media (max-width: 480px) {
  .punkteraster { grid-template-columns: repeat(15, minmax(0, 1fr)); gap: 4px; max-width: 260px; }
}

/* Beschriftungen in normaler Schreibweise statt Mono in Grossbuchstaben. */
.person-neu-fakten dt {
  font-family: inherit;
  font-size: 0.84rem;
  letter-spacing: 0;
  text-transform: none;
}
.notiz-rubrik {
  font-family: var(--sans, inherit);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

/* Magazin: Themenliste im selben Block unter den Karten. */
.notiz-raster + .themenliste { margin-top: 40px; }

/* Kopfleiste unter 380 px (06.10.2026): Logo, "Projekt besprechen" und
   Menueknopf brauchten bei 320 px zusammen 372 px -- der Menueknopf brach
   in eine zweite Zeile. Etwas weniger Rand, kleinerer Aufruf und Schrift
   des Logos; alles bleibt in einer Zeile und der Knopf bleibt 44 px hoch. */
@media (max-width: 380px) {
  :root[data-theme] .mag-kopf-band.mit-menue .mag-kopf { column-gap: 4px; padding-left: 10px; padding-right: 10px; }
  :root[data-theme] .mag-kopf-band.mit-menue .mag-logo { gap: 5px; font-size: 0.9rem; }
  :root[data-theme] .mag-kopf-band.mit-menue .mag-marke { width: 26px; height: 26px; }
  :root[data-theme] .mag-kopf-band.mit-menue .kopf-starten { padding: 8px 9px; font-size: 0.76rem; letter-spacing: -0.01em; }
}

/* ==========================================================================
   Der Fuss in Gruppen (07.10.2026)

   Vorher eine Zeile aus 17 gleichrangigen, unterstrichenen Verweisen.
   Jetzt: Firma links, drei Gruppen nach dem, was jemand sucht, und rechts
   das eine, das ein Sicherheitsdienstleister im Fuss haben sollte -- die
   Nummer fuer den Notfall, gross genug, um sie im Stress zu finden.
   Rechtliches leise darunter. Farben: die des dunklen Bandes, keine neuen.
   ========================================================================== */

:root[data-theme] .mag-fuss {
  display: block;
  padding-top: 52px;
  padding-bottom: 28px;
  font-size: 0.9rem;
  line-height: 1.5;
}

.fuss-oben {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) repeat(3, minmax(0, 1fr)) minmax(250px, 1.3fr);
  gap: 32px 36px;
  align-items: start;
}

/* --- Firma ----------------------------------------------------------------- */
:root[data-theme] .mag-fuss .fuss-marke {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.fuss-marke .mag-marke {
  width: 28px;
  height: 28px;
}
.fuss-satz {
  margin: 14px 0 16px;
  max-width: 34ch;
  color: var(--text-dim);
}
:root[data-theme] .mag-fuss .mag-fuss-adresse {
  font-style: normal;
  color: var(--text-faint);
  line-height: 1.6;
}

/* --- Gruppen --------------------------------------------------------------- */
.fuss-gruppe-titel {
  margin: 4px 0 12px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}
.fuss-gruppe ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.fuss-gruppe li + li {
  margin-top: 6px;
}
:root[data-theme] .mag-fuss a {
  color: var(--text-dim);
  text-decoration: none;
}
:root[data-theme] .mag-fuss a:hover {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
:root[data-theme] .mag-fuss a:focus-visible {
  outline: 2px solid var(--accent-soft);
  outline-offset: 3px;
  border-radius: 3px;
}
.fuss-gruppe a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
}
.fuss-gruppe .autor-logo {
  width: 15px;
  height: 15px;
  flex: none;
}

/* --- Notruf: das eine laute Element ------------------------------------------ */
.fuss-notruf {
  padding: 18px 20px;
  border: 1px solid var(--accent-line);
  border-radius: 12px;
  background: var(--accent-bg);
}
.fuss-notruf-frage {
  margin: 0;
  font-weight: 600;
  color: var(--text);
}
:root[data-theme] .mag-fuss .fuss-notruf-nummer {
  display: inline-block;
  margin: 6px 0 4px;
  color: var(--accent);
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
:root[data-theme] .mag-fuss .fuss-notruf-nummer:hover {
  color: var(--accent-soft);
}
.fuss-notruf-hinweis {
  margin: 0;
  font-size: 0.84rem;
  color: var(--text-dim);
}

/* --- Rechtliches ----------------------------------------------------------- */
.fuss-unten {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin-top: 44px;
  padding-top: 18px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.82rem;
}
:root[data-theme] .mag-fuss .fuss-unten a {
  color: var(--text-faint);
}
.fuss-datei {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.78rem;
}

/* --- Schmaler -------------------------------------------------------------- */
@media (max-width: 1100px) {
  .fuss-oben {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .fuss-firma {
    grid-column: 1 / 3;
  }
  .fuss-notruf {
    grid-column: 3;
    grid-row: 1;
  }
}
@media (max-width: 760px) {
  :root[data-theme] .mag-fuss {
    padding-top: 40px;
  }
  /* Zwei Spalten: links die sechs Leistungen, rechts die beiden kurzen
     Gruppen uebereinander -- so enden beide Spalten etwa gleich hoch. */
  .fuss-oben {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "firma firma"
      "notruf notruf"
      "g1 g2"
      "g1 g3";
    gap: 28px 20px;
  }
  .fuss-firma { grid-area: firma; }
  .fuss-notruf { grid-area: notruf; }
  .fuss-gruppe:nth-of-type(1) { grid-area: g1; }
  .fuss-gruppe:nth-of-type(2) { grid-area: g2; }
  .fuss-gruppe:nth-of-type(3) { grid-area: g3; }
  .fuss-gruppe a {
    min-height: 36px;
  }
  .fuss-gruppe li + li {
    margin-top: 0;
  }
}

/* ==========================================================================
   Kontakt und Danke (07.10.2026, frontend-design)

   Kontakt: die Person dort, wo vorher Leere war -- rechts neben der
   Ueberschrift, eine Karte mit Foto und allen direkten Wegen. Die vier
   grauen Kaesten mit Versal-Etiketten darunter sind weg. Danke: Absender,
   ein Weg fuer Eiliges, ein naechster Schritt. Nur Tokens der Seite.
   ========================================================================== */

.kontakt-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 32px 56px;
  align-items: center;
}
.kontakt-hero .hero-sub {
  max-width: 46ch;
}

.kontakt-person {
  padding: 22px 24px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface);
}
.kontakt-person-kopf {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 16px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.kontakt-person-kopf img {
  flex: none;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 22%;
  border: 1px solid var(--border);
}
.kontakt-person-name {
  margin: 0;
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.kontakt-person-satz {
  margin: 2px 0 0;
  font-size: 0.92rem;
  color: var(--text-dim);
}

/* Die Wege als Zeilen: Etikett in normaler Schreibweise links, Wert
   rechts -- lesbar wie eine Visitenkarte, nicht wie ein Formular. */
.kontakt-wege {
  margin: 0;
}
.kontakt-wege > div {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 12px;
  padding: 10px 0;
}
.kontakt-wege > div + div {
  border-top: 1px solid var(--border-soft);
}
.kontakt-wege dt {
  font-size: 0.86rem;
  color: var(--text-faint);
}
.kontakt-wege dd {
  margin: 0;
  font-size: 0.94rem;
  line-height: 1.5;
  color: var(--text);
}
.kontakt-wege a {
  color: var(--accent-soft);
}
:root[data-theme] .kontakt-wege .kontakt-telefon {
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--accent-soft);
  text-decoration: none;
  white-space: nowrap;
}
.kontakt-wege .kontakt-telefon:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 900px) {
  .kontakt-hero {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 480px) {
  .kontakt-person {
    padding: 18px;
  }
  .kontakt-wege > div {
    grid-template-columns: 1fr;
    gap: 2px;
  }
}

/* --- Danke ------------------------------------------------------------------ */

.danke-absender {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 22px 0 0;
}
.danke-absender img {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--border);
}
.danke-absender > span {
  display: flex;
  flex-direction: column;
  line-height: 1.35;
}
.danke-absender strong {
  color: var(--text);
}
.danke-absender > span > span {
  font-size: 0.88rem;
  color: var(--text-faint);
}

.danke-weiter {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 32px 56px;
  align-items: start;
}
.danke-eilig {
  padding: 20px 22px;
  border: 1px solid var(--accent-line);
  border-radius: 12px;
  background: var(--accent-bg);
}
.danke-eilig-frage {
  margin: 0;
  font-weight: 600;
  color: var(--text);
}
:root[data-theme] .danke-eilig .danke-telefon {
  display: inline-block;
  margin: 8px 0 6px;
  font-family: var(--anzeige, "Space Grotesk", sans-serif);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent-soft);
  text-decoration: none;
  white-space: nowrap;
}
.danke-eilig .danke-telefon:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}
.danke-eilig-mail {
  margin: 0;
  font-size: 0.92rem;
  color: var(--text-dim);
}
:root[data-theme] .danke-schritt h2 {
  margin: 0 0 10px;
  font-size: clamp(1.4rem, 2.6vw, 1.8rem);
}
.danke-schritt p {
  max-width: 58ch;
}
.danke-mehr {
  margin-top: 18px;
  font-size: 0.92rem;
  color: var(--text-dim);
}

@media (max-width: 860px) {
  .danke-weiter {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Paketkarten (07.10.2026, frontend-design)

   Alle Leistungsseiten. Drei Dinge, sonst nichts:
   1. RANGORDNUNG. Im HTML ist nur das empfohlene Paket knopf-voll; die
      Regel "Signal-Gruen" weiter oben machte trotzdem jeden .preis-knopf
      voll gruen -- drei gleich laute Knoepfe nebeneinander. Gibt es eine
      Empfehlung, tragen die anderen jetzt einen Umrissknopf. Ohne
      Empfehlung (einzelne Karte) bleibt alles, wie es war.
   2. HAKEN vor jedem Punkt, derselbe wie in .haken: "ist enthalten" ist
      eine Information, und die Zeilen lassen sich so ueberfliegen.
   3. Laufzeit und Liste durch eine Linie getrennt: oben was es kostet und
      wie lange es dauert, unten was drin ist.
   ========================================================================== */

:root[data-theme] .preis-gitter:has(.preis-empfohlen) .preis-karte:not(.preis-empfohlen) .preis-knopf {
  background: transparent;
  border: 1.5px solid var(--border);
  color: var(--text);
}
:root[data-theme] .preis-gitter:has(.preis-empfohlen) .preis-karte:not(.preis-empfohlen) .preis-knopf:hover {
  background: var(--accent-bg);
  border-color: var(--accent);
  color: var(--text);
}

:root[data-theme] .preis-karte.preis-empfohlen {
  background: linear-gradient(var(--accent-bg), var(--accent-bg)), var(--surface);
}

:root[data-theme] .preis-unter {
  margin-bottom: 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.86rem;
}

:root[data-theme] .preis-punkte li {
  position: relative;
  padding-left: 24px;
}
:root[data-theme] .preis-punkte li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0.55em;
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* ==========================================================================
   /tools/ (07.10.2026, frontend-design)

   Die Etiketten ueber den Repo-Karten ("Aktiv", "Fruehe Version", "Neu")
   in normaler Schreibweise statt in Versalien -- der Rest der Seite
   spricht auch nicht in Grossbuchstaben. Die Werkzeugnamen in der
   Tabelle trugen das Browserblau, weil kein Linkstil auf Tabellen griff;
   jetzt die Linkfarbe der Seite.
   ========================================================================== */
.karte-marke {
  text-transform: none;
  letter-spacing: 0;
}
:root[data-theme] .tabelle-rahmen td a {
  color: var(--accent-soft);
  text-underline-offset: 3px;
}
:root[data-theme] .tabelle-rahmen td a:hover {
  color: var(--text);
}

/* --- /about/: Person im Kopf (07.10.2026) ---------------------------------- */
.ueber-hero {
  align-items: start;
}
.ueber-person-text {
  margin: 12px 0 14px;
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--text-dim);
}
.ueber-profile {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
:root[data-theme] .ueber-profile a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  color: var(--accent-soft);
  text-decoration: none;
}
:root[data-theme] .ueber-profile a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.ueber-profile .autor-logo {
  width: 17px;
  height: 17px;
}

/* --- Magazin-Karten: Rubrik, Lesezeit, Datum in normaler Schreibweise.
   Die Versalien-Zeile ueber jedem Titel war das letzte "Dachzeilen"-Muster
   der Seite (siehe PR #76/#77, 03.10.2026). */
.artikel-datum {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8rem;
}

/* --- Startseite: Personenblock wie der Autorenkasten (07.10.2026) ----------
   Rundes Portraet statt der eckigen Kachel, Profil-Zeile und offener Code
   aus denselben Bausteinen wie unter den Beitraegen. */
:root[data-theme] .person-neu {
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 44px;
}
:root[data-theme] .person-neu-bild {
  border-radius: 50%;
  object-position: center 22%;
  border: 1px solid var(--border);
}
.person-neu .autor-wege {
  margin-top: 4px;
}
.person-neu .autor-code {
  max-width: 760px;
}
@media (max-width: 760px) {
  :root[data-theme] .person-neu {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }
  :root[data-theme] .person-neu-bild {
    max-width: 120px;
  }
}

/* ==========================================================================
   SAEULENSEITEN EINHEITLICH (08.10.2026, frontend-design)

   /security/, /seo/ und /softwareentwicklung/ waren an einem Tag von drei
   Haenden neu geschrieben worden und hatten zwei Sorten Aufmacher, drei
   Handy-Tabellen, zwei FAQ-Baukaesten, Karten neben Spalten neben Listen
   und Bilder in drei Groessen. Jetzt gilt EIN Muster, und jede Komponente
   hat EINE Klasse:

     Aufmacher     .hero.hero-produkt.neu-held (wie die Startseite)
     Abschnitt     .abschnitt.saeule, abwechselnd hell und .abschnitt-getoent
     Unterkopf     .saeule > h3
     Illustration  .saeule-bild (nach dem ersten Absatz, 640 px, 2:1)
     Grafik        .grafik (Rahmen, Unterschrift und Quelle darunter)
     Tabelle       .tabelle-rahmen, Texttabellen dazu .tabelle-stapel
     Spalten       .saeule-spalten (statt .karten, .karten-drei,
                   .gruende-weiter und .saeule-notfall)
     Listen        .ablauf (Reihenfolge), .haken / .haken-nein, .pruefliste
     Pakete        .preis-gitter, Fussnote als .nachsatz
     Person        .person-neu mit autor-wege und autor-code
     Fragen        .fragen (wie die Startseite)
     Abschluss     .abschlussband.abschluss-neu

   Grundsatz: Daten stehen im Rahmen (Tabelle, Grafik), Text nie. Fliesstext,
   Unterkoepfe und Textlisten in Lesebreite (46rem), Raster und Tabellen
   duerfen die Spalte ausnutzen. Nichts haengt an einer ID: #entscheidung,
   #messung und #ki gibt es auf mehreren Seiten.
   ========================================================================== */

.saeule > p:not(.fuehrung):not(.nachsatz),
.saeule > .haken,
.saeule > .ablauf,
.saeule > h3 {
  max-width: 46rem;
}
.saeule > h3 {
  margin: 44px 0 12px;
  font-size: 1.2rem;
  letter-spacing: -0.012em;
  line-height: 1.3;
}
.saeule > .fuehrung + .fuehrung {
  margin-top: 14px;
}

/* Illustration: eine Groesse, eine Behandlung. Dunkler Grund, weil ein
   Rasterbild nicht mit dem Thema wechselt. Sie steht nach dem ersten
   Absatz, damit die Antwort oben bleibt. */
.saeule-bild {
  max-width: 640px;
  margin: 24px 0 28px;
}
.saeule-bild img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #0b0e13;
}

/* Spalten: Titel und Satz, eine Linie oben -- so wie die Werkzeuge und
   Fragen der Startseite. Ab fuenf Eintraegen breiter, damit lange Saetze
   nicht in vier schmale Saeulen zerfallen. */
.saeule-spalten {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 8px 32px;
  margin: 28px 0 0;
  padding: 0;
}
.saeule-spalten:has(> :nth-child(5)) {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}
.saeule-spalten > * {
  margin: 0;
  padding: 18px 0 8px;
  border-top: 1px solid var(--border);
}
.saeule-spalten h3,
.saeule-spalten > li > b:first-child {
  display: block;
  margin: 0 0 8px;
  font-family: var(--anzeige);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  color: var(--text);
}
.saeule-spalten p,
.saeule-spalten > li > span {
  display: block;
  margin: 0;
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--text-dim);
}
.saeule-spalten p + p {
  margin-top: 10px;
}
.saeule-spalten a {
  color: var(--accent);
}

/* "Was nicht hilft": ein Kreuz statt des Hakens, sonst sieht die Liste
   wie eine Empfehlung aus. */
.haken.haken-nein li::before,
.haken.haken-nein li::after,
:root[data-theme] .haken.haken-nein li::before,
:root[data-theme] .haken.haken-nein li::after {
  content: "";
  position: absolute;
  left: 3px;
  top: 12px;
  width: 11px;
  height: 0;
  border: 0;
  border-top: 2px solid var(--danger);
  transform: rotate(45deg);
}
.haken.haken-nein li::after,
:root[data-theme] .haken.haken-nein li::after {
  transform: rotate(-45deg);
}

/* Grafiken mit breiter und schmaler Fassung (g-breit / g-schmal, z. B.
   die elitegear-Klickkurve): unter 640 px waere die breite in 6-px-Schrift. */
.grafik .g-schmal {
  display: none;
}
@media (max-width: 640px) {
  .grafik .g-breit {
    display: none;
  }
  .grafik .g-schmal {
    display: block;
  }
}
/* Die handgeschriebene Grafik auf /security/ hat ihre zwei Fassungen in
   .diagramm; im Rahmen braucht sie kein eigenes Polster und keine
   Mindestbreite mehr. */
.grafik .diagramm {
  margin: 0;
  padding: 0;
  overflow: visible;
}
.grafik .diagramm svg {
  min-width: 0;
}
.grafik .diagramm:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* Tabellen: derselbe Grund wie die Grafik. Zeilenkoepfe (th scope=row)
   stehen links und ohne Flaeche, sie sind Text, keine Spaltenkoepfe. */
.tabelle-rahmen {
  background: var(--surface);
}
.tabelle-rahmen tbody th[scope="row"] {
  background: none;
  white-space: normal;
}
@media (max-width: 640px) {
  .tabelle-rahmen th,
  .tabelle-rahmen td {
    padding-left: 10px;
    padding-right: 10px;
  }
}

/* Texttabellen am Handy: jede Zeile ein Block, der Spaltenname
   (data-label) steht klein ueber dem Wert. Zahlentabellen bleiben
   Tabellen und scrollen in ihrem Rahmen -- dort ist der Vergleich
   untereinander der Sinn. Ersetzt die drei Loesungen von vorher
   (Karten je Zeile auf /seo/, Bloecke mit data-art auf
   /softwareentwicklung/, waagrechtes Scrollen auf /security/). */
@media (max-width: 700px) {
  .tabelle-stapel {
    overflow: visible;
  }
  .tabelle-stapel thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .tabelle-stapel table,
  .tabelle-stapel tbody,
  .tabelle-stapel tr,
  .tabelle-stapel th,
  .tabelle-stapel td {
    display: block;
    width: auto;
  }
  .tabelle-stapel tr {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-soft);
  }
  .tabelle-stapel tr:last-child {
    border-bottom: 0;
  }
  .tabelle-stapel th,
  .tabelle-stapel td,
  .tabelle-stapel tr:last-child td {
    padding: 3px 0;
    border: 0;
  }
  .tabelle-stapel tbody th,
  .tabelle-stapel tr:not(:has(th)) > td:first-child {
    padding-bottom: 6px;
    font-family: var(--anzeige);
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
  }
  .tabelle-stapel tr:not(:has(th)) > td:first-child::before {
    content: none;
  }
  .tabelle-stapel td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--sans);
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--text-faint);
  }
}

/* Zahlentabellen (Nachtrag 08.10.2026): Die erste Spalte ist der
   Schluessel der Zeile -- eine Datumsspanne wie "30.08.–05.09." oder ein
   Name. Bricht sie am Handy um, steht "05.09." allein in der zweiten
   Zeile und die Zeilen sind nicht mehr gleich hoch. Darum bleibt sie
   einzeilig, die Zahlen stehen rechtsbuendig in gleich breiten Ziffern,
   damit Stellen untereinander stehen. Ist die Tabelle zu breit, scrollt
   sie in ihrem Rahmen (.tabelle-rahmen hat overflow-x), nie die Seite. */
.tabelle-zahlen tr > :first-child {
  white-space: nowrap;
}
.tabelle-zahlen td:not(:first-child),
.tabelle-zahlen thead th:not(:first-child) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .tabelle-zahlen table {
    font-size: 0.82rem;
  }
  .tabelle-zahlen th,
  .tabelle-zahlen td {
    padding-left: 6px;
    padding-right: 6px;
  }
  .tabelle-zahlen tr > :first-child {
    padding-left: 8px;
  }
  .tabelle-zahlen tr > :last-child {
    padding-right: 8px;
  }
}

/* Ein Paket und zwei Verweise (/webdesign-zillertal/, /wordpress-wartung/):
   Die Seite verkauft ein Paket; die beiden anderen stehen nur mit Preis
   und Verweis da, damit die Paketinhalte an einer Stelle gepflegt werden.
   Im .preis-gitter wurden die Verweise zu leeren Karten in Kartenhoehe.
   Jetzt: die Preiskarte links, die Verweise rechts als .saeule-spalten
   untereinander. */
.preis-einzel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 24px 40px;
  align-items: start;
  margin-top: 28px;
}
.preis-einzel > .saeule-spalten,
.preis-einzel > .saeule-spalten:has(> :nth-child(5)) {
  grid-template-columns: minmax(0, 1fr);
  margin: 0;
}
@media (max-width: 800px) {
  .preis-einzel {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Paketfussnote: gleicher Abstand unter Gitter und Zusatzpaket. */
.preis-gitter + .nachsatz,
.preis-zusatz + .nachsatz,
.preis-einzel + .nachsatz {
  margin-top: 24px;
}

/* Personenblock im getoenten Abschnitt: der Code-Kasten bekommt die
   Kartenflaeche, sonst verschwindet er in der Toenung. */
:root[data-theme] .abschnitt-getoent .autor-code {
  background: var(--surface);
}
.person-neu-text > p {
  max-width: 66ch;
}

/* Screenshots: derselbe Rahmen wie .grafik, denn auch sie sind Belege.
   Das Wort "Screenshot" bleibt als Hinweis, dass hier kein Bild erfunden
   ist, aber in normaler Schreibweise statt als Versalien-Dachzeile. */
.screenshot {
  box-sizing: border-box;
  padding: 14px 16px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.screenshot img {
  padding: 0;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
}
.screenshot::before {
  position: static;
  display: block;
  margin: 0 0 10px;
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0;
  text-transform: none;
}
.screenshot figcaption {
  margin-top: 12px;
}

/* --- Messprotokoll: organischer Verlauf statt Bauplan (09.10.2026, Test) --

   Gleicher Rahmen wie der Bauplan (.bauplan: dunkel, Mono, Schriftfeld),
   darin ein Plot auf dem Millimeterraster. Die Kurve wechselt die Farbe mit
   der Saeule, die gerade wirkt; vorher (gehackt) rot gestrichelt. Flaeche
   als Schraffur, Groessen als Masslinien wie auf einem Plan. */
.bp-protokoll { --bp-sec: #3ddc97; --bp-web: #7ab2ff; --bp-seo: #f2b544; --bp-rot: #ff7a7a; }
.bp-plot {
  padding: 18px 18px 10px;
  background-color: var(--bp-grund);
  background-image:
    linear-gradient(var(--bp-raster-grob) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-raster-grob) 1px, transparent 1px),
    linear-gradient(var(--bp-raster) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-raster) 1px, transparent 1px);
  background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px;
  background-position: -1px -1px;
}
.bp-plot svg { display: block; width: 100%; height: auto; overflow: visible; }
.bp-achse { font-size: 14px; fill: var(--bp-dim); }
.bp-flaeche { fill: url(#bp-schraffur); }
#bp-schraffur line { stroke: var(--bp-linie); stroke-width: 1.2; }
.bp-grundlinie { stroke: var(--bp-linie); stroke-width: 1.5; }
.bp-hilfe { fill: none; stroke: var(--bp-linie); stroke-width: 1; stroke-dasharray: 3 3; }
.bp-mass { fill: none; stroke: var(--bp-dim); stroke-width: 1.2; }
#bp-pfeil path { fill: none; stroke: var(--bp-dim); stroke-width: 1.4; }
.bp-masszahl { font-size: 15px; fill: var(--bp-text); }
.bp-massgrund { fill: var(--bp-grund); }
.bp-kurve { fill: none; stroke-width: 3; stroke-linejoin: round; stroke-linecap: round; }
.bp-k-vorher { stroke: var(--bp-rot); stroke-dasharray: 0.04 0.03; }
.bp-k-sec { --bp-farbe: var(--bp-sec); stroke: var(--bp-sec); }
.bp-k-web { --bp-farbe: var(--bp-web); stroke: var(--bp-web); }
.bp-k-seo { --bp-farbe: var(--bp-seo); stroke: var(--bp-seo); }
.bp-pos circle { fill: var(--bp-grund); stroke: var(--bp-farbe); stroke-width: 2; }
.bp-pos text { font-size: 13px; font-weight: 600; fill: var(--bp-text); stroke: none; text-anchor: middle; }
/* Positionsliste wie auf einer Zeichnung: Nummer im Kreis in der Farbe der
   Saeule, dahinter was gemacht wurde und wann. */
.bp-positionen {
  list-style: none; margin: 0; padding: 12px 18px 14px;
  display: grid; gap: 8px;
  border-top: 1px solid #1e2a38;
  counter-reset: bp-pos;
  font-size: 0.8rem; line-height: 1.4;
}
.bp-positionen li { counter-increment: bp-pos; display: grid; grid-template-columns: 22px 1fr auto; align-items: baseline; gap: 10px; }
.bp-positionen li::before {
  content: counter(bp-pos);
  display: grid; place-items: center; width: 20px; height: 20px;
  border: 1.5px solid var(--bp-farbe); border-radius: 50%;
  font-size: 0.7rem; font-weight: 600; align-self: center;
}
.bp-positionen b { font-weight: 500; color: var(--bp-text); }
.bp-positionen small { font-size: 0.72rem; color: var(--bp-farbe); white-space: nowrap; }
.bp-protokoll { container-type: inline-size; }
@container (max-width: 640px) {
  .bp-positionen { gap: 10px; }
  .bp-positionen li { grid-template-columns: 22px 1fr; row-gap: 1px; }
  .bp-positionen small { grid-column: 2; white-space: normal; }
}
@media (max-width: 560px) {
  .bp-plot { padding: 14px 10px 6px; }
}
/* Der eine Moment beim Laden: die rote Strecke steht, dann zieht jede Saeule
   ihren Abschnitt nach -- fertig bei 0,9 / 1,3 / 1,7 s wie die Balken der
   Ueberschrift; Position und Listenzeile erscheinen mit ihrem Abschnitt. */
@media (prefers-reduced-motion: no-preference) {
  .bp-protokoll .bp-kurve:not(.bp-k-vorher) { stroke-dasharray: 1; stroke-dashoffset: 1; animation: bp-ziehen 0.4s linear forwards; }
  .bp-protokoll .bp-kurve.bp-k-sec { animation-delay: 0.5s; }
  .bp-protokoll .bp-kurve.bp-k-web { animation-delay: 0.9s; }
  .bp-protokoll .bp-kurve.bp-k-seo { animation-delay: 1.3s; }
  .bp-protokoll .bp-pos, .bp-protokoll .bp-positionen li { animation: k-zeile 0.3s ease-out both; }
  .bp-protokoll .bp-pos-1, .bp-protokoll .bp-positionen li:nth-child(1) { animation-delay: 0.6s; }
  .bp-protokoll .bp-pos-2, .bp-protokoll .bp-positionen li:nth-child(2) { animation-delay: 1s; }
  .bp-protokoll .bp-pos-3, .bp-protokoll .bp-positionen li:nth-child(3) { animation-delay: 1.4s; }
}
@keyframes bp-ziehen { to { stroke-dashoffset: 0; } }
