/* CheetahLab — öffentlicher Auftritt. Dunkel & Gold. */

:root {
    --ground:   #16191B;
    --surface:  #1E2225;
    --surface2: #2C3236;
    --line:     #33383B;
    --ink:      #ECECE6;
    --ink2:     #B0B0A8;
    --ink3:     #7A7A72;
    --gold:     #EFBE18;
    --gold-dim: #3A2F0A;
    --teal:     #5FB5AE;

    /* Die zweite Achse braucht eine eigene Farbe. Nicht Teal — das traegt
       schon den Tiefstwert und den Regen, und zwei Bedeutungen auf einer
       Farbe sind eine zu viel. */
    --axis2:    #9B8CC4;

    --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
    --body:    "Source Serif 4", Georgia, serif;
    --mono:    "IBM Plex Mono", Consolas, monospace;

    --gutter: clamp(20px, 5vw, 80px);

    /* Die breiteste Begrenzung, die es im Bogen schon gab (.home). Sie war
       nur nie zentriert: Auf einem breiten Schirm klebte alles links, und
       rechts blieb ein Drittel der Flaeche leer. */
    --wrap: 82rem;

    /* SO BREIT DARF ETWAS HOECHSTENS AUSBRECHEN.
       Genau die Inhaltsbreite des Bogens — also das, was der Aufmacher
       einer Werkzeugseite einnimmt. Vorher stand hier `100vw` in der
       Rechnung, und das ist der ganze Schirm: Auf 1440 px kam ein
       Schaubild damit auf 1248 px, waehrend der Aufmacher darueber bei
       1168 endete. Es ragte um achtzig Pixel nach rechts hinaus — sichtbar
       nur, wenn beides auf derselben Seite steht.

       `--wrap` ist die Begrenzung des Bogens, `--gutter` sein Polster.
       Was dazwischen bleibt, ist die Breite, die es zu treffen gilt. */
    --ausbruch: min(78rem, calc(var(--wrap) - 2 * var(--gutter)), calc(100vw - 2 * var(--gutter)));
}

/* UND `100vw` IST NICHT DER PLATZ, DEN ES GIBT.
   Es zaehlt die senkrechte Bildlaufleiste mit, das Layout aber nicht: Bei
   1100 px Fensterbreite kam ein Schaubild damit auf 990 px, waehrend der
   Aufmacher bei 975 endete — die fehlenden 15 px waren genau die Leiste.
   Nachgemessen bei 1920, 1440, 1100 und 390 px.

   `100cqw` misst stattdessen den Inhalt von `main` selbst, also exakt den
   Platz, den auch der Aufmacher bekommt. Wo Container-Abfragen fehlen,
   bleibt die Rechnung oben stehen — dann ist ein Schaubild neben einer
   Bildlaufleiste ein paar Pixel zu breit und sonst nichts. */
@supports (width: 1cqw) {
    main { container-type: inline-size; }

    :root { --ausbruch: min(78rem, 100cqw); }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--ground);
    color: var(--ink);
    font-family: var(--body);
    font-size: 17px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
}

/* Platz fuer die klebende Kopfzeile, wenn ein Sprungziel angesteuert wird.
   Gemessen: 79 Pixel, gerundet auf 5.5rem — in `rem`, damit der Wert der
   Schriftgroesse folgt. Unterhalb von 1000 Pixeln klebt sie nicht, dann
   faellt der Zuschlag weg (siehe unten). */
html { scroll-padding-top: 5.5rem; }

a { color: var(--gold); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: #FFD54A; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 2px; }

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

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

/* UEBER der Kopfzeile, nicht darunter: Seit die klebt, traegt sie einen
   eigenen Stapelwert — und sie steht im Quelltext hinter dem Sprunglink.
   Bei gleichem Wert haette sie ihn verdeckt, und ein Sprunglink, den man
   nicht sieht, ist keiner. */
.skip {
    position: absolute; left: -9999px; top: 0; z-index: 30;
    background: var(--gold); color: #15191A; padding: 12px 20px;
    font-family: var(--mono); font-size: 13px; text-decoration: none;
}
.skip:focus { left: 0; }

/* ------------------------------------------------------------- Kopfzeile */

/* DIE KOPFZEILE BLEIBT STEHEN, die Seite laeuft darunter durch.

   Sie braucht dafuer zwei Dinge, die sie vorher nicht brauchte: einen
   eigenen Grund — sonst scheint der Text hindurch, sobald er darunter
   wegrutscht — und einen Stapelwert, damit sie ueber dem Inhalt liegt.

   `scroll-padding-top` am Dokument gehoert dazu: Ohne das landet ein
   Sprungziel (`/notizen#note-44`) genau unter der klebenden Zeile, und der
   Leser sieht die Notiz nicht, die er angeklickt hat.

   NUR SOLANGE SIE EINE ZEILE BLEIBT — siehe die Ausnahme weiter unten. */
.site-head {
    position: sticky; top: 0; z-index: 20;
    background: var(--ground);
    max-width: var(--wrap);
    margin-inline: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px 30px;
    padding: 22px var(--gutter);
    border-bottom: 1px solid var(--line);
}

/* EINE KLEBENDE KOPFZEILE DARF NICHT DEN HALBEN SCHIRM FRESSEN.
   Gemessen: Ab 1000 Pixeln steht sie in einer Zeile und ist 79 Pixel hoch.
   Darunter bricht die Navigation um — 125 Pixel bei 960, 179 bei 700, und
   auf dem Telefon **200**. Das waere ein Viertel des Fensters, das
   dauerhaft belegt ist. Also klebt sie dort nicht, und der Zuschlag fuer
   Sprungziele faellt mit ihr weg. */
@media (max-width: 1000px) {
    .site-head { position: static; }
    html { scroll-padding-top: 0; }
}

.brand {
    display: flex;
    align-items: center;
    gap: 13px;
    text-decoration: none;
    color: var(--ink);
}

/* Feste Maße: sonst springt das Layout, während das Bild lädt (§09). */
.brand img { display: block; width: 41px; height: 30px; flex: none; }

.wordmark { font-family: var(--display); font-size: 21px; font-weight: 700; letter-spacing: -.02em; }

.head-right { display: flex; align-items: center; gap: 30px; flex-wrap: wrap; }

/* DIE MENUEPUNKTE BRECHEN UM. Ohne `wrap` bleibt die Leiste eine
   einzige Zeile: Bei sieben Punkten sind das 583 Pixel, und auf einem
   375 Pixel breiten Schirm schiebt sie die ganze Seite quer — jede
   Unterseite, nicht nur diese. `.site-head` und `.head-right` haben
   das Umbrechen laengst, nur das `nav` dazwischen hatte es nicht.
   `row-gap` kleiner als die Spalte: Umbrochene Zeilen sollen enger
   stehen als die Punkte nebeneinander. */
.site-head nav {
    display: flex; flex-wrap: wrap; gap: 10px 26px;
    font-family: var(--mono); font-size: 13px;
}
.site-head nav a { color: var(--ink2); text-decoration: none; padding-bottom: 3px; }
.site-head nav a:hover { color: var(--ink); border-bottom: 2px solid var(--gold); }

/* DER BEREICH, IN DEM MAN STEHT, sieht aus wie der Punkt unter dem Zeiger:
   derselbe goldene Balken. Dirks Wunsch vom 01.10.2026 — bis dahin sagte
   das Menue nur, wohin man kann, und nicht, wo man ist.

   `aria-current="page"` statt einer Klasse: Dieselbe Angabe, die eine
   Vorlesehilfe braucht, faerbt hier auch. Zwei Wege fuer eine Aussage
   waeren zwei Gelegenheiten, dass sie auseinanderlaufen. */
.site-head nav a[aria-current="page"] { color: var(--ink); border-bottom: 2px solid var(--gold); }

/* Kontakt und Suche sind Zeichen ohne Balken — ein Strich unter einem
   Symbol sieht aus wie ein Fehler. Sie faerben sich stattdessen. */
.site-head .kopfzeichen a[aria-current="page"] { color: var(--gold); }

.langswitch {
    display: flex; gap: 1px;
    font-family: var(--mono); font-size: 11px;
    border: 1px solid var(--line); border-radius: 2px; overflow: hidden;
}
.langswitch a, .langswitch span { padding: 5px 10px; text-decoration: none; }
.langswitch .on { background: var(--gold); color: #15191A; }
.langswitch a { color: var(--ink2); }
.langswitch a:hover { background: var(--surface2); color: var(--ink); }
.langswitch .off { color: #4A4F4C; cursor: not-allowed; }

/* --------------------------------------------------------------- Inhalte */

main {
    max-width: var(--wrap);
    margin-inline: auto;
    padding: 56px var(--gutter) 72px;
}

.preview-note {
    font-family: var(--mono); font-size: 12px;
    background: var(--gold-dim); color: var(--gold);
    border: 1px solid var(--gold); border-radius: 2px;
    padding: 10px 16px; margin: 0 0 32px; max-width: 66ch;
}

/* LINKSBUENDIG, und das ist Absicht.
   Ein Versuch, die Spalte zu zentrieren, sah für sich genommen besser aus —
   beim Durchklicken sprang aber der Textanfang von 24 px in die Mitte,
   während Startseite, Übersichten und Live-Ansichten links bleiben. Ein
   Layout, das je nach Seite woanders beginnt, wirkt kaputt, auch wenn jede
   Seite einzeln stimmt. Der Platz rechts wird durch Abbildungen gefuellt,
   nicht durch Verschieben des Textes. */
.prose { max-width: 68ch; }

.eyebrow {
    font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
    text-transform: uppercase; color: var(--gold); margin: 0 0 18px;
}

/* ABBILDUNGEN DUERFEN AUS DER TEXTSPALTE AUSBRECHEN.
   Der Text steht bei 68 Zeichen — richtig zum Lesen, aber auf einem breiten
   Schirm bleibt daneben viel Platz. Eine Zeichnung braucht ihn und wird
   dadurch lesbar; den Text zu verbreitern oder zu verschieben waere die
   schlechtere Antwort auf dieselbe Beobachtung. */
.prose > .abbildung { margin: 32px 0; }

/* `max-width: none` allein genuegt nicht: Ein Block-Kind fuellt die Breite
   des Elternteils und waechst nicht von selbst darueber hinaus. Erst eine
   ausdrueckliche `width` laesst die Abbildung nach rechts ausbrechen —
   begrenzt auf das, was der Schirm nach dem Seitenrand noch hergibt, damit
   die Seite nie quer scrollt. */
.prose > .abbildung.breit {
    max-width: none;
    width: var(--ausbruch);
}

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

.abbildung figcaption {
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
    margin-top: 10px; letter-spacing: .02em;
}

/* Der Schichtaufbau des Gateways. Farben ausschliesslich hier — die
   Content-Security-Policy verwirft `style=` im SVG ohne Fehlermeldung. */
.gw-karte  { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.gw-pi     { fill: var(--surface2); }
.gw-chip   { fill: var(--surface2); stroke: var(--ink3); stroke-width: 1; }
.gw-oled   { fill: #0E1113; stroke: var(--ink3); stroke-width: 1; }
.gw-port   { fill: var(--ground); stroke: var(--line); stroke-width: 1; }
.gw-led    { fill: var(--gold); }

.gw-mast   { stroke: var(--ink2); stroke-width: 2.5; }
.gw-punkt  { fill: var(--gold); }
.gw-welle  { fill: none; stroke: var(--gold); stroke-width: 1.5; opacity: .55; }
.gw-kabel  { fill: none; stroke: var(--ink3); stroke-width: 2; stroke-dasharray: 5 4; }

.gw-stift line { stroke: var(--ink3); stroke-width: 2; }
.gw-fuehrung   { stroke: var(--line); stroke-width: 1; }

.gw-name {
    font-family: var(--mono); font-size: 13px; fill: var(--ink);
}
.gw-label {
    font-family: var(--mono); font-size: 13px; fill: var(--gold);
}
.gw-sub, .gw-fuss {
    font-family: var(--mono); font-size: 11.5px; fill: var(--ink3);
}

/* --- Spreizfaktor: Reichweite gegen Sendezeit -------------------------
   Dieselben Farben wie der Ring auf der Live-Seite. Hier wie dort ist es
   eine Reihe und keine Sammlung von Kategorien; wer beide Seiten sieht,
   erkennt SF12 an seinem Rot wieder. */
.sfg-spur   { fill: var(--surface2); }
.sfg-balken { stroke: none; }

.sfg-7,  .sfg-7-f  { fill: var(--sf7); }
.sfg-8,  .sfg-8-f  { fill: var(--sf8); }
.sfg-9,  .sfg-9-f  { fill: var(--sf9); }
.sfg-10, .sfg-10-f { fill: var(--sf10); }
.sfg-11, .sfg-11-f { fill: var(--sf11); }
.sfg-12, .sfg-12-f { fill: var(--sf12); }

.sfg-name { font-family: var(--mono); font-size: 13px; fill: var(--ink); }
.sfg-zeit { font-family: var(--mono); font-size: 12px; fill: var(--ink2); }
.sfg-kopf {
    font-family: var(--mono); font-size: 11px; fill: var(--ink3);
    letter-spacing: .14em; text-transform: uppercase;
}
.sfg-linie { stroke: var(--line); stroke-width: 1; }
.sfg-fuss  { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

/* --- Funkstrecke: Sensor, Gateways, Netzwerkserver, Anwendung ---------
   Gold ist der Funkweg, Grau der Draht — dieselbe Aufteilung wie bei den
   anderen Zeichnungen. Der Rueckweg ist gestrichelt, weil er nicht immer
   stattfindet: Klasse A antwortet nur im Fenster nach dem eigenen Senden.

   Die Sinnbilder folgen dem Aufbaubild: Flaechen in `--surface2`, Umrisse
   in `--ink3`, und Gold nur dort, wo etwas aktiv ist — Antennenspitze,
   Quecksilber, Leuchtdiode. */
.fs-kasten { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.fs-sensor { stroke: var(--ink3); }
.fs-lns    { stroke: var(--ink2); }
.fs-app    { stroke: var(--ink3); }

.fs-icon-flaeche { fill: var(--surface2); stroke: var(--ink3); stroke-width: 1; }
.fs-icon-fenster { fill: var(--ground); stroke: var(--ink3); stroke-width: 1; }
.fs-icon-strich  { stroke: var(--ink3); stroke-width: 1; }
.fs-icon-linie   { fill: none; stroke: var(--ink3); stroke-width: 1.5; }
.fs-icon-gold    { fill: var(--gold); }
.fs-icon-tropfen { fill: none; stroke: var(--teal); stroke-width: 1.5; }
.fs-icon-taste   { fill: var(--ground); stroke: var(--gold); stroke-width: 1.2; }
.fs-icon-led     { fill: var(--gold); }
.fs-icon-schirm  { fill: var(--ground); stroke: var(--ink3); stroke-width: 1; }
.fs-icon-kurve   { stroke: var(--gold); stroke-width: 1.8; }
.fs-icon-fuss    { fill: var(--surface2); stroke: var(--ink3); stroke-width: 1; }

.fs-mast      { stroke: var(--gold); stroke-width: 2; }
.fs-mast-quer { stroke: var(--gold); stroke-width: 1.2; opacity: .7; }
.fs-punkt     { fill: var(--gold); }
.fs-welle     { fill: none; stroke: var(--gold); stroke-width: 1.5; opacity: .5; }

.fs-funk  { fill: none; stroke: var(--gold); stroke-width: 2; opacity: .8; }
.fs-draht { fill: none; stroke: var(--ink3); stroke-width: 2; }
.fs-klar  { fill: none; stroke: var(--gold); stroke-width: 2; }
.fs-rueck { fill: none; stroke: var(--ink3); stroke-width: 1.5; stroke-dasharray: 5 4; }

.fs-geraet-name { font-family: var(--mono); font-size: 12.5px; fill: var(--ink); }
.fs-geraet-sub  { font-family: var(--mono); font-size: 10.5px; fill: var(--ink3); }
.fs-weg {
    font-family: var(--mono); font-size: 10.5px; fill: var(--ink3);
    letter-spacing: .06em;
}
.fs-kopf {
    font-family: var(--mono); font-size: 11px; fill: var(--ink3);
    letter-spacing: .14em; text-transform: uppercase;
}
.fs-linie { stroke: var(--line); stroke-width: 1; }
.fs-fuss  { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

/* --- Der Weg der Daten -----------------------------------------------
   Nach draussen gestrichelt und blass, ins Haus durchgehend und in Gold:
   Der rechte Ast ist das, was hier dazugebaut wurde. */
.dw-kasten  { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.dw-quelle  { stroke: var(--ink3); }
.dw-eigen   { stroke: var(--gold); }
.dw-fremd   { stroke: var(--line); }

.dw-haus {
    fill: none; stroke: var(--gold); stroke-width: 1;
    stroke-dasharray: 3 5; opacity: .5;
}
.dw-haus-name {
    font-family: var(--mono); font-size: 11px; fill: var(--gold);
    text-anchor: end; opacity: .7;
}

.dw-weg    { fill: none; stroke-width: 2; }
.dw-aussen { stroke: var(--ink3); stroke-dasharray: 6 5; }
.dw-innen  { stroke: var(--gold); }

.dw-titel {
    font-family: var(--display); font-size: 16px; font-weight: 600;
    fill: var(--ink); text-anchor: middle;
}
.dw-klein {
    font-family: var(--mono); font-size: 11.5px; fill: var(--ink3);
    text-anchor: middle;
}
.dw-kante {
    font-family: var(--mono); font-size: 11.5px; fill: var(--gold);
    text-anchor: middle;
}
.dw-kante-aussen { fill: var(--ink3); }

/* Die kurze Verbindung zwischen ChirpStack und Broker: Sie traegt keine
   Beschriftung, weil der Weg offensichtlich ist, sobald beide Kaesten
   danebenstehen. */
.dw-quer { stroke-width: 2; }
.dw-linie { stroke: var(--line); stroke-width: 1; }
.dw-fuss  { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

/* --- Mit wem Cloud2MQTT redet ----------------------------------------
   Gleiche Sprache wie der Datenweg beim Gateway: nach draussen gestrichelt
   und blass, ins eigene Netz durchgehend und gold. Wer beide Seiten sieht,
   liest die zweite ohne Legende. */
.c2m-kasten { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.c2m-mitte  { stroke: var(--ink3); }
.c2m-eigen  { stroke: var(--gold); }
.c2m-neben-k { fill: none; stroke: var(--line); stroke-dasharray: 4 4; }

.c2m-haus {
    fill: none; stroke: var(--gold); stroke-width: 1;
    stroke-dasharray: 3 5; opacity: .5;
}
.c2m-haus-name {
    font-family: var(--mono); font-size: 11px; fill: var(--gold);
    text-anchor: end; opacity: .7;
}

.c2m-weg    { fill: none; stroke-width: 2; marker-end: none; }
.c2m-aussen { stroke: var(--ink3); stroke-dasharray: 6 5; }
.c2m-innen  { stroke: var(--gold); }
.c2m-neben  { stroke: var(--line); stroke-width: 1.5; stroke-dasharray: 4 4; }

.c2m-titel {
    font-family: var(--display); font-size: 16px; font-weight: 600;
    fill: var(--ink); text-anchor: middle;
}
.c2m-klein {
    font-family: var(--mono); font-size: 11.5px; fill: var(--ink3);
    text-anchor: middle;
}
.c2m-kante {
    font-family: var(--mono); font-size: 11.5px; fill: var(--ink3);
    text-anchor: middle;
}
.c2m-kante-gold { fill: var(--gold); }
.c2m-linie { stroke: var(--line); stroke-width: 1; }
.c2m-fuss  { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

/* --- Software-Stapel und Lizenzen ------------------------------------
   Farbe traegt hier Bedeutung: eine je Lizenzwelt, Gold fuer das Eigene. */
.st-block { fill: var(--surface); stroke-width: 1.5; }
.st-os    { stroke: var(--line); }
.st-bsd   { stroke: #5FB5AE; }
.st-gpl   { stroke: #C98A5B; }
.st-eigen { stroke: var(--gold); fill: var(--surface2); }

.st-name  { font-family: var(--mono); font-size: 13px; fill: var(--ink); }
.st-klein { font-family: var(--mono); font-size: 11px; fill: var(--ink3); }
.st-eigen-t { fill: var(--gold); }

.st-lizenz  { font-family: var(--mono); font-size: 12px; }
.st-bsd-t   { fill: #5FB5AE; }
.st-gpl-t   { fill: #C98A5B; }
.st-frei    { fill: var(--ink3); }
.st-fuss    { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

/* Auf dem Telefon wird die Zeichnung sonst zur Briefmarke: Dort steht sie
   in einem Rahmen, der zur Seite geschoben werden kann. */
@media (max-width: 640px) {
    .abbildung.breit { overflow-x: auto; }
    .abbildung.breit svg { min-width: 620px; }
}

/* Die Unternavigation der Wetterseiten. Sie steht UNTER der Überschrift:
   Oben führt die Krume aus dem Bereich hinaus, hier geht es quer. Deshalb
   auch keine Monospace-Kleinschrift wie dort — das wären zwei Zeilen, die
   gleich aussehen und Verschiedenes tun. */
.unternav {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin: 0 0 30px;
    font-family: var(--mono); font-size: 12px;
}

.unternav a, .unternav-hier {
    display: inline-block; padding: 7px 12px; border-radius: 2px;
    text-decoration: none; border: 1px solid var(--line);
}

.unternav a { color: var(--ink2); }
.unternav a:hover, .unternav a:focus-visible { color: var(--ink); border-color: var(--ink3); }

/* Der eigene Punkt bleibt stehen, aber als Zustand, nicht als Weg: gefüllt
   statt umrandet. Ihn wegzulassen liesse die Zeile bei jedem Wechsel
   springen. */
.unternav-hier { background: var(--gold); border-color: var(--gold); color: #15191A; }

/* Der Export: je Jahr ein Block, darin die Monate als Tabelle. Eine Liste
   aus Links waere kuerzer, aber die Tagesanzahl gehoert daneben — sie sagt,
   ob ein Monat vollstaendig ist. */
.export-jahr { margin-bottom: 38px; }

.export-jahr h2 {
    display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
    margin-bottom: 14px;
}

.export-monate { width: 100%; border-collapse: collapse; font-size: 15px; }

.export-monate th {
    text-align: left; font-family: var(--mono); font-size: 11px;
    letter-spacing: .13em; text-transform: uppercase; color: var(--ink3);
    font-weight: 400; padding: 6px 12px 6px 0; border-bottom: 1px solid var(--line);
}

.export-monate td { padding: 8px 12px 8px 0; border-bottom: 1px solid var(--surface2); }
.export-monate td.num { font-variant-numeric: tabular-nums; color: var(--ink2); }
.export-monate a { color: var(--gold); }

.button.small { font-size: 12px; padding: 7px 14px; }

.export-lizenz { margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--line); }
.export-lizenz pre { margin: 12px 0; }

/* Die Krume steht dort, wo vorher die Rubrikzeile stand, und sieht auch so
   aus — nur folgen kann man ihr jetzt. Dieselbe Schrift, dieselbe Groesse,
   derselbe Abstand nach unten: Es ist kein neues Element auf der Seite,
   sondern dasselbe mit einer Aufgabe. */
.krume {
    font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
    text-transform: uppercase; margin: 0 0 18px;
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 .5em;
}

.krume a { color: var(--gold); text-decoration: none; }

/* Unterstreichen erst beim Zeigen: Eine Zeile aus drei unterstrichenen
   Stuecken sieht aus wie ein Fehler, nicht wie ein Weg. */
.krume a:hover, .krume a:focus-visible { text-decoration: underline; }

/* Der Trenner ist Beiwerk und traegt keine Bedeutung — deshalb blasser als
   die Glieder und im Lesefluss ausgeblendet (aria-hidden in der Vorlage). */
.krume-trenner { color: var(--ink3); }

.prose h1, .listing-head h1 {
    font-family: var(--display); font-weight: 700;
    font-size: clamp(2rem, 5vw, 3rem); line-height: 1.05; letter-spacing: -.03em;
    margin: 0 0 22px; text-wrap: balance;
}

.standfirst { font-size: 1.2rem; line-height: 1.5; color: var(--ink2); margin: 0 0 32px; }

.prose h2 {
    font-family: var(--display); font-weight: 600; font-size: 1.55rem;
    letter-spacing: -.02em; margin: 44px 0 14px; text-wrap: balance;
}
.prose h3 {
    font-family: var(--display); font-weight: 600; font-size: 1.15rem;
    margin: 34px 0 10px;
}

.prose p, .prose li { max-width: 68ch; }
.prose p { margin: 0 0 20px; }
/* Die Aufzaehlungszeichen ausdruecklich setzen, statt sie zu erben:
   Steht `.prose` in einer Liste, die selbst `list-style: none` traegt —
   etwa in den Notizen —, erbt es das Fehlen der Punkte mit. */
.prose ul, .prose ol { padding-left: 1.15em; margin: 0 0 20px; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-bottom: 8px; }

.prose blockquote {
    margin: 0 0 20px; padding: 2px 0 2px 20px;
    border-left: 2px solid var(--gold); color: var(--ink2);
}

.prose code {
    font-family: var(--mono); font-size: .85em;
    background: var(--surface2); border-radius: 3px; padding: .1em .38em;
}

.prose pre {
    font-family: var(--mono); font-size: 13px; line-height: 1.6;
    background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
    padding: 18px 20px; overflow-x: auto; margin: 0 0 22px; color: var(--ink2);
}
.prose pre code { background: none; padding: 0; font-size: inherit; }

/* Der Abstand nach unten fehlte: Der naechste Absatz begann direkt unter
   der letzten Trennlinie und sah aus wie eine weitere Tabellenzeile. Oben
   genuegt der Abstand des vorangehenden Absatzes. */
.prose table {
    border-collapse: collapse; width: 100%; font-size: 15px;
    margin: 0 0 26px;
}
.prose table th, .prose table td { text-align: left; padding: 9px 14px; border-bottom: 1px solid var(--line); }

.tags { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; padding: 0; margin: 40px 0 0; }
.tags li {
    font-family: var(--mono); font-size: 11px; color: var(--teal);
    background: #17302E; padding: 5px 11px; border-radius: 2px;
}

/* IM FLIESSTEXT GEWINNT SONST DIE AUFZAEHLUNG.
   Die Schlagwortliste steht in `.prose`, und dort ist `.prose ul` mit
   Punkt und Einzug spezifischer als `.tags` allein — jedes Schlagwort
   bekam einen Aufzaehlungspunkt davor und ruecke ein. Sichtbar wurde es
   erst, als die Schlagworte im Blog zu Links wurden; auf den Werkzeug-
   und Konstruktionsseiten stand es genauso, nur unauffaelliger.
   Zwei Klassen schlagen eine Klasse und ein Element. */
.prose .tags { list-style: none; padding-left: 0; }
.prose .tags li { margin-bottom: 0; max-width: none; }

/* IN EINER NOTIZ SIND VIERZIG PIXEL ZU VIEL. Am Ende eines Artikels
   trennen sie den Text vom Anhang; eine Notiz ist selbst nur ein paar
   Zeilen lang, und der Abstand waere groesser als der Absatz darueber.
   Zugleich muessen die Schildchen unter dem gezogenen Aufmacher stehen,
   nicht neben ihm — sonst haengen sie in der Luft, sobald der Text
   kuerzer ist als das Bild. */
.tags.klein { margin-top: 18px; clear: both; }

/* Ein Schlagwort, das irgendwohin fuehrt, sieht aus wie die anderen: Die
   Kachel IST der Knopf. Gold und Unterstrich der uebrigen Verweise wuerden
   sie sonst aus der Reihe reissen. */
.tags a { color: inherit; text-decoration: none; }
.tags a:hover { color: var(--ink); text-decoration: underline; }

/* ------------------------------------------------------------- Listen */

.listing { max-width: 76ch; }

/* Die Ueberschrift folgt nicht dem Lesemass. 76ch sind fuer Fliesstext
   gedacht; eine Zeile in 48 px bricht darin schon nach vier Woertern —
   „Kurze Eintraege aus der Werkstatt" stand zweizeilig, obwohl rechts
   daneben die halbe Seite frei war. `max-content` laesst die Zeile so
   breit werden, wie sie sein will, die Schranke faengt schmale Schirme
   ab: Passt sie nicht, bricht sie wie zuvor. */
.listing-head h1 { width: max-content; max-width: var(--ausbruch); }

.listing-head { margin-bottom: 42px; }

.entries, .notes { list-style: none; padding: 0; margin: 0; }

/* NUR DIE DIREKTEN KINDER. Ohne `>` traf die Regel jedes `li` im
   Bereich — auch die einer Aufzaehlung IM Text. Aus vier Stichpunkten
   wurden dann vier Zeilen mit Datumsspalte und Trennlinie. */
.entries > li {
    display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 24px;
    padding: 24px 0; border-top: 1px solid var(--line);
}
.entries > li:last-child { border-bottom: 1px solid var(--line); }

/* `.datumsbox` ist ausgenommen: Sie bringt Schrift, Groesse und Farbe
   selbst mit — die alte Regel setzte hier eine graue Monozeile darueber. */
.entries time, .notes > li > time:not(.datumsbox), .kind {
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
    padding-top: 6px; font-variant-numeric: tabular-nums;
}

.entries h2 {
    font-family: var(--display); font-size: 1.25rem; font-weight: 600;
    letter-spacing: -.015em; margin: 0 0 8px;
}
.entries h2 a { color: var(--ink); text-decoration: none; }
.entries h2 a:hover { color: var(--gold); }
.entries p { margin: 0; color: var(--ink2); font-size: 16px; }

.notes > li {
    display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: 28px;
    padding: 28px 0; border-top: 1px solid var(--line);
}
.notes > li:last-child { border-bottom: 1px solid var(--line); }

/* Der Text einer Notiz ist Fliesstext wie jeder andere und traegt deshalb
   `.prose` — wie auf der Startseite. Die eigenen `.note-body`-Regeln
   kannten weder Listen noch Bilder; die erste Notiz mit einer Aufzaehlung
   hat das sofort gezeigt.

   DIE ABSAETZE TRAGEN HIER KEIN EIGENES MASS.
   `.prose p` ist sonst auf 68ch begrenzt — damit blieb der Text auch dort
   schmal, wo das Aufmacherbild laengst zu Ende war, und die Notiz wurde
   unnoetig hoch. Neben dem Bild bremst jetzt der Float, darunter der
   Container. Der ist bewusst nicht die volle Seitenbreite: 992 Pixel
   waeren rund 125 Zeichen je Zeile, und dabei verliert das Auge beim
   Zeilenwechsel die Spur. */
.notes > li > div { max-width: 54rem; }
.notes > li .prose { max-width: none; }

/* 84ch statt der 68ch des uebrigen Fliesstextes: Neben dem Bild bremst
   ohnehin der Float auf rund 70 Zeichen, darunter darf die Zeile laenger
   werden — aber nicht beliebig. Ueber die volle Containerbreite gemessen
   waeren es 107 Zeichen; ab etwa 90 findet das Auge den Zeilenanfang
   nicht mehr zuverlaessig.

   Der Wert ist gemessen, nicht geschaetzt: 1ch ist die Breite der Ziffer
   '0', und die faellt in dieser Serifenschrift breiter aus als ein
   Durchschnittsbuchstabe — 65ch ergeben rund 85 echte Zeichen. */
.notes > li .prose :is(p, li, h2, h3, blockquote) { max-width: 65ch; }

/* Die Ueberschrift einer Notiz. Kleiner als die eines Artikels: Sie steht
   in einer Liste und soll die Seitenueberschrift nicht ueberstimmen. */
.note-titel {
    font-family: var(--display); font-size: 1.15rem; font-weight: 600;
    letter-spacing: -.01em; color: var(--ink); margin: 0 0 14px;
}

/* Das Aufmacherbild nach rechts, der Text fliesst daneben und darunter
   weiter. Ein Grid haette gewusst werden muessen, wo „der erste Absatz"
   endet — das weiss die Vorlage nicht, weil der Text als ein Block kommt.
   Ein Float weiss es auch nicht und braucht es nicht.
   Die Breite ist so gewaehlt, dass ein 480 Pixel breites Bild nicht
   hochgerechnet wird: Der Kern rechnet nie hoch, das Stylesheet soll es
   auch nicht tun. */
.note-cover {
    float: right;
    width: 260px; max-width: 45%; height: auto;
    margin: 0 0 16px 24px;

    /* Kein Rahmen: Ein freigestelltes Bild soll frei stehen — sonst wird
       aus dem Motiv ein Kasten mit viel Luft darin. Ein Foto bringt seine
       Kanten selbst mit. */
    border-radius: 3px;
}

/* Der Float darf die Trennlinie der naechsten Notiz nicht unterlaufen. */
.notes > li > div::after { content: ""; display: block; clear: both; }

.pager {
    display: flex; align-items: center; gap: 24px;
    font-family: var(--mono); font-size: 13px; margin-top: 36px;
}

.searchform { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.searchform input {
    flex: 1 1 18rem; min-height: 44px;
    font-family: var(--body); font-size: 17px; color: var(--ink);
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 2px; padding: 11px 16px;
}
.searchform button {
    min-height: 44px; font-family: var(--mono); font-size: 13px;
    color: #15191A; background: var(--gold); border: 0;
    border-radius: 2px; padding: 11px 22px; cursor: pointer;
}
.searchform button:hover { background: #FFD54A; }

.empty { color: var(--ink3); }
.dim { color: var(--ink3); }

/* ------------------------------------------------------------- Fußzeile */

.site-foot {
    max-width: var(--wrap);
    margin-inline: auto;
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 14px 26px;
    padding: 30px var(--gutter) 46px;
    border-top: 1px solid var(--line);
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}
.site-foot nav { display: flex; gap: 24px; }
.site-foot a { color: var(--ink3); text-decoration: none; }
.site-foot a:hover { color: var(--gold); }

/* DER VERMERK IST GOLD, nicht grau wie der Rest der Zeile — er ist das
   einzige dort, das etwas ueber die Seite selbst sagt und kein Pflichtteil.

   `color: inherit` und nicht noch einmal `var(--gold)`: Der Verweis erbt
   damit die Farbe der Klammer, statt sie zu wiederholen — sonst stuenden
   zwei Stellen fuer eine Entscheidung. Noetig ist die Zeile trotzdem, denn
   `.site-foot a` faerbt sonst grau. */
.site-foot .gebaut { color: var(--gold); }
.site-foot .gebaut a { color: inherit; }
.site-foot .gebaut a:hover { color: #FFD54A; text-decoration: underline; }

@media (max-width: 640px) {
    .entries > li, .notes > li { grid-template-columns: 1fr; gap: 8px; }

    /* Kein Platz fuer ein Bild neben dem Text: Es steht darueber. */
    .note-cover { float: none; width: 100%; max-width: none; margin: 0 0 16px; }
    .entries time, .notes time { padding-top: 0; }
}

/* ALLES STEHT STILL, WENN JEMAND BEWEGUNG ABBESTELLT HAT.
   `*` mit `!important` ist hier Absicht: Eine einzelne vergessene
   Animation macht die Zusicherung sonst wertlos.

   GENAU EINE AUSNAHME GIBT ES, weiter unten bei `.puls` benannt und
   begruendet — ein langsames Hell/Dunkel ohne Bewegung im Raum. Wer
   hier sucht, warum etwas trotzdem laeuft, findet es dort. Und wer
   sich wundert, warum eine neue Animation nicht laeuft: Sie braucht
   dieselbe ausdrueckliche Ausnahme, sonst gewinnt diese Zeile. */
@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* -------------------------------------------- Stufe 03: Werkzeuge, Modelle */

.listing.wide, .prose.wide { max-width: 78rem; margin-inline: auto; }

.cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
    gap: 20px;
}

.card {
    border: 1px solid var(--line);
    border-radius: 3px;
    background: var(--surface);
    padding: 22px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.card header { display: flex; flex-direction: column; gap: 10px; }
.card h2 { font-family: var(--display); font-size: 1.2rem; font-weight: 600; letter-spacing: -.015em; margin: 0; }
.card h2 a { color: var(--ink); text-decoration: none; }
.card h2 a:hover { color: var(--gold); }
.card p { margin: 0; font-size: 15.5px; color: var(--ink2); }

.card footer {
    display: flex; justify-content: space-between; gap: 16px;
    border-top: 1px solid var(--surface2); padding-top: 12px; margin-top: auto;
    font-size: 11px; color: var(--ink3); font-variant-numeric: tabular-nums;
}

/* Das Datum einer Notizkachel sitzt dort, wo bei einem Werkzeug der
   Zustand steht: oben, klein, zurueckhaltend. So haben alle Kacheln
   derselben Reihe denselben Aufbau. */
.kachel-datum {
    align-self: flex-start;
    font-family: var(--mono); font-size: 11px; color: var(--ink3);
    letter-spacing: .06em; font-variant-numeric: tabular-nums;
}

.state {
    align-self: flex-start;
    font-family: var(--mono); font-size: 10.5px;
    padding: 3px 9px; border-radius: 2px;
    background: #17302E; color: var(--teal);
}
/* DIESELBE BEDEUTUNG WIE IN DER REDAKTION — das war sie bis zum 08.09.2026
   nicht: Vorne trug `beta` das Gold und `arbeit` einen gestrichelten
   Rahmen, in der Liste der Redaktion war es umgekehrt. Wer beides am selben
   Tag ansieht, muss zweimal umdenken.

   Gold heisst „daran wird gearbeitet". Das ist der Zustand, der auffallen
   soll: Er sagt dem Leser, dass sich hier noch etwas aendert. `beta` ist
   dagegen ein Zwischenschritt und bleibt ruhig. */
.state-beta { background: var(--surface2); color: var(--ink2); }
.state-arbeit { background: var(--gold-dim); color: var(--gold); }
.state-eingestellt { background: transparent; color: var(--ink3); border: 1px solid var(--line); }

/* ------------------------------------------------------------ Werkzeugseite */

.tool { max-width: 78rem; margin-inline: auto; }

.tool-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22rem;
    gap: 52px;
    align-items: start;
    padding-bottom: 40px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 40px;
}

.tool-head h1 {
    font-family: var(--display); font-weight: 700;
    font-size: clamp(2rem, 5vw, 3rem); line-height: 1.05; letter-spacing: -.03em;
    margin: 0 0 18px; text-wrap: balance;
}

.actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 28px; }

.button {
    display: inline-flex; align-items: center; min-height: 44px;
    font-family: var(--mono); font-size: 13px;
    color: #15191A; background: var(--gold);
    padding: 12px 22px; border-radius: 2px; text-decoration: none;
}
.button:hover { background: #FFD54A; color: #15191A; }

/* Der zweite Weg zum selben Modell: gleiches Gewicht in der Form, weniger
   im Ton. Zwei goldene Schaltflaechen nebeneinander wuerden fragen lassen,
   welche die richtige ist — dabei sind es zwei Tueren zum selben Raum. */
.button.ghost {
    background: none; color: var(--gold);
    box-shadow: inset 0 0 0 1px var(--line);
}
.button.ghost:hover { background: none; color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }

.modell-wege { display: flex; flex-wrap: wrap; gap: 10px; }

/* ------------------------------------------- Die Werkzeugliste als Regal

   Bis zum 01.10.2026 standen hier drei kleine Textkaesten nebeneinander
   und darunter zwei Drittel Schwarz — bei drei Werkzeugen endete die
   Seite nach 470 Pixeln. Jetzt bekommt jedes eine ganze Reihe: links,
   was es ist, rechts, wie es aussieht. Bei drei Eintraegen ist Platz die
   bessere Antwort als Dichte; ab etwa sechs waere es umgekehrt. */

.wz-band {
    display: flex; flex-wrap: wrap; gap: 0 48px;
    margin: 0 0 44px; padding: 22px 0;
    border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.wz-band .z {
    font-family: var(--display); font-weight: 600; font-size: 25px; line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.wz-band .z em { font-style: normal; color: var(--gold); }
.wz-band .b {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em;
    text-transform: uppercase; color: var(--ink3); margin-top: 5px;
}

/* Die Rubrikzeile traegt ihre Linie selbst: eine Ueberschrift, die bis
   zum Rand laeuft, ohne dafuer ein eigenes Element zu brauchen. */
.wz-rubrik { display: flex; align-items: center; gap: 16px; margin: 0 0 10px; }
.wz-rubrik.nachher { margin-top: 50px; }
.wz-rubrik h2 {
    margin: 0; font-family: var(--mono); font-size: 11px; font-weight: 500;
    letter-spacing: .16em; text-transform: uppercase; color: var(--ink3);
    white-space: nowrap;
}
.wz-rubrik::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.wz-rubrik-sub { margin: 0 0 22px; font-family: var(--mono); font-size: 11.5px; color: var(--ink3); }

.werkzeug {
    display: grid; grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
    border: 1px solid var(--line); background: var(--surface); margin-bottom: 20px;
}
/* Ohne Bildschirmfoto bleibt keine leere Haelfte stehen. */
.werkzeug.ohnebild { grid-template-columns: 1fr; }

.wz-text { padding: 32px 34px; display: flex; flex-direction: column; gap: 14px; align-self: center; }

.wz-zeile { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* DER ZUSTAND SASS 11,5 PIXEL ZU HOCH. `.state` traegt seit der
   Kachelliste `align-self: flex-start` — dort steht der Zustand ueber
   der Ueberschrift und soll am linken oberen Rand kleben. In dieser
   Reihe steht er NEBEN dem Namen, und dort schlug dieselbe Zeile das
   `align-items: center` der Reihe. Gemessen: Zeichen und Ueberschrift
   mittig bei 631, der Chip bei 619,5. Dirks Blick, 01.10.2026. */
.wz-zeile .state { align-self: center; }

/* DAS ZEICHEN QUADRATISCH, DER NAME ALS TEXT. Beides zusammen, nicht
   eines statt des anderen: Das Zeichen erkennt man aus dem Augenwinkel,
   den Namen kann man suchen, vorlesen und markieren — eine Wortmarke als
   Bild kann das zweite nicht. */
.wz-zeichen {
    width: 46px; height: 46px; flex: none; overflow: hidden;
    border-radius: 9px; border: 1px solid var(--line); background: #0E1113;
}
.wz-zeichen img { width: 100%; height: 100%; object-fit: cover; }

.werkzeug h2 {
    margin: 0; font-family: var(--display); font-weight: 600; font-size: 25px;
    letter-spacing: -.015em;
}
.werkzeug h2 a { color: var(--ink); text-decoration: none; }
.werkzeug h2 a:hover { color: var(--gold); }

.wz-anriss { margin: 0; color: var(--ink2); font-size: 16.5px; max-width: 44ch; }

/* Die harten Angaben als Paare: Beschriftung klein und grau, Wert hell.
   Als Satz gesetzt laesen sie sich wie Prosa und nicht wie Daten. */
.wz-fakten { display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 4px 0 0; font-family: var(--mono); }
.wz-fakten div { display: flex; flex-direction: column; gap: 2px; }
.wz-fakten .et {
    font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink3);
}
.wz-fakten .wt { font-size: 11.5px; color: var(--ink2); font-variant-numeric: tabular-nums; }
.wz-fakten .wt.zahl { color: var(--gold); }

.wz-aktion { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }

.wz-schirm {
    display: flex; align-items: center; justify-content: center;
    background: #0E1113; border-left: 1px solid var(--line); padding: 26px; overflow: hidden;
}
.wz-schirm img { width: 100%; height: auto; border: 1px solid var(--line); }

/* „Entsteht gerade" steht abgesetzt: kein Angebot, eine Ansage. */
.werkzeug.arbeit { background: transparent; border-style: dashed; }
.werkzeug.arbeit .wz-schirm { background: transparent; border-left-style: dashed; }

@media (max-width: 900px) {
    .werkzeug { grid-template-columns: 1fr; }
    .wz-schirm { border-left: 0; border-top: 1px solid var(--line); padding: 20px; }
    .werkzeug.arbeit .wz-schirm { border-left: 0; border-top-style: dashed; }
}

/* Die Wortmarke steht anstelle der Ueberschrift. Hoehe statt Breite
   begrenzen: Die Marken sind unterschiedlich lang, aber gleich hoch gedacht.
   `max-width: 100%` haelt sie auf dem Telefon im Rahmen. */
h1.wordmark {
    margin: 0 0 .6rem;
    line-height: 0;
}

h1.wordmark img {
    height: 2.6rem;
    width: auto;
    max-width: 100%;
    display: block;
}

@media (max-width: 40rem) {
    h1.wordmark img { height: 2rem; }
}

.datasheet { border: 1px solid var(--line); border-radius: 3px; background: var(--surface); padding: 22px 24px; }
.datasheet h2 {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink3);
    margin: 0 0 16px; padding-bottom: 14px; border-bottom: 1px solid var(--surface2);
}
.datasheet dl {
    display: grid; grid-template-columns: auto 1fr; gap: 10px 20px;
    margin: 0; font-family: var(--mono); font-size: 12.5px;
}
.datasheet dt { color: var(--ink3); }
.datasheet dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* Das Zustandsschildchen im Datenblatt. `.state` bringt `align-self` fuer
   den Kartenkontext mit — hier steht es in einem `dd` und braucht nur, dass
   Polster und Rundung wirken. */
.datasheet .state { display: inline-block; }
.datasheet .hint {
    font-family: var(--body); font-size: 12.5px; color: var(--ink3);
    margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--surface2); line-height: 1.45;
}

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

/* Bilder im Fliesstext — Bildschirmfotos aus der Redaktion.
   Ohne das stuenden sie in ihrer Originalbreite da: ein 1920 Pixel breites
   Schema neben 65 Zeichen Text, links buendig und viel zu klein geraten,
   weil der Browser es in die Spalte quetscht. Rahmen und Radius wie beim
   Aufmacher, damit ein Bild ueberall gleich aussieht. */
.prose img {
    display: block;
    width: 100%;
    height: auto;
    margin: 28px 0;
    border: 1px solid var(--line);
    border-radius: 3px;
}

/* EIN SCHAUBILD DARF AUS DER TEXTSPALTE AUSBRECHEN.
   Ein Aufbauschema in 595 px ist eine Briefmarke mit Beschriftung. Die
   Breite steht im Markdown, nicht hier: `![alt](bild:x.png "breit")` — das
   Titelfeld gibt es in Markdown ohnehin, und so entscheidet die Redaktion,
   welches Bild ein Schema ist und welches ein Screenshot am Rand.

   Begrenzt auf das, was nach dem Seitenrand bleibt, damit die Seite nie
   quer scrollt — dieselbe Rechnung wie bei den gezeichneten Abbildungen. */
.prose img[title~="breit"] {
    width: var(--ausbruch);
    max-width: none;
}

/* Der Alt-Text steht als Bildunterschrift darunter, wenn Markdown ein
   `figure` daraus macht — und sonst nicht. Beides ist in Ordnung. */
.prose figure { margin: 28px 0; }
.prose figcaption {
    margin-top: 10px;
    font-size: .8125rem;
    color: var(--ink3);
}

.feedback {
    margin: 48px 0 0; padding-top: 22px; border-top: 1px solid var(--line);
    font-size: 15px; color: var(--ink3); max-width: 60ch;
}

/* ------------------------------------------------------------ Konstruktionen */

.gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
    gap: 22px;
}

.thumb a { display: block; text-decoration: none; color: var(--ink); }
.thumb img, .thumb .noimage {
    display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
    border: 1px solid var(--line); border-radius: 3px; background: var(--surface2);
}
.thumb h2 {
    font-family: var(--display); font-size: 1rem; font-weight: 600;
    letter-spacing: -.01em; margin: 12px 0 4px;
}
.thumb a:hover h2 { color: var(--gold); }
.thumb p { margin: 0; font-size: 11px; }

.specs {
    display: grid; grid-template-columns: auto 1fr; gap: 8px 22px;
    margin: 0 0 32px; font-family: var(--mono); font-size: 13px;
    padding: 18px 20px; border: 1px solid var(--line); border-radius: 3px; background: var(--surface);
}
.specs dt { color: var(--ink3); }
.specs dd { margin: 0; }

@media (max-width: 900px) {
    .tool-head { grid-template-columns: 1fr; gap: 32px; }
    .datasheet dd { text-align: left; }
}

/* ------------------------------------------------------------------ Wetter */

.weather { max-width: 78rem; margin-inline: auto; }

/* WARUM FLEX UND NICHT GRID
   Vorher stand hier ein auto-fit-Raster. Das rechnet eine feste Spaltenzahl
   aus — passten sieben Plaetze nicht (die Temperatur belegt zwei), rutschte
   eine Kachel in eine zweite Zeile und daneben blieb eine grosse leere
   Flaeche stehen. Wie viele Kacheln es gibt, steht aber nicht fest: die
   UV-Kachel erscheint nur, wenn die Station UV meldet.
   Mit Flex waechst die letzte Zeile auf die volle Breite, egal wie viele
   es sind. */
.live {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: 3px;
    overflow: hidden;
    margin-bottom: 52px;
}

/* SECHS KACHELN STATT FUENF. Mit der Helligkeit (06.10.2026) passt die
   Reihe bei 11rem Grundbreite nicht mehr in eine Zeile — gemessen:
   377 + 5×176 = 1257 gegen 1137 verfuegbar, also rutschte die letzte
   Kachel allein in eine zweite Zeile und wurde dort 1135 Pixel breit.
   9rem reichen fuer „1.016 hPa" und bringen alle sechs unter.
   Eng gefasst auf die Live-Kachel der Wetterseite: Dieselbe Klasse
   traegt die Bilanz auf der Tafel, und die hat ihre eigene Anzahl. */
[data-weather] .reading { flex-basis: 9rem; }

.reading {
    flex: 1 1 11rem;
    background: var(--surface);
    padding: 20px 22px;
    display: flex; flex-direction: column; gap: 6px;
}

/* Die Temperatur ist der Wert, wegen dem man die Seite aufruft: doppelt
   Platz — aber nur als Wunsch, wird es eng, schrumpft sie mit. */
.reading.main { flex: 2 1 22rem; background: var(--surface2); }

.reading-label {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink3);
}

.reading strong {
    font-family: var(--display); font-size: 1.5rem; font-weight: 600;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.reading strong.big { font-size: clamp(2.4rem, 7vw, 3.6rem); line-height: 1; letter-spacing: -.04em; }

.reading-note { font-family: var(--mono); font-size: 12px; color: var(--ink3); font-variant-numeric: tabular-nums; }
.reading .dir { color: var(--gold); font-family: var(--mono); font-size: 1rem; margin-left: 6px; }

/* Beide sollen eine eigene, volle Zeile bekommen. Unter Grid stand hier
   grid-column: 1 / -1; unter Flex tut das flex-basis: 100%. */
.live .stale-note {
    flex: 1 1 100%; margin: 0;
    background: var(--gold-dim); color: var(--gold);
    padding: 12px 22px; font-family: var(--mono); font-size: 12.5px;
}

.live .measured {
    flex: 1 1 100%; margin: 0;
    background: var(--surface); padding: 12px 22px;
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}

/* Die Bereichsueberschrift. Sie war 10,5 px grau und las sich wie eine
   Fussnote des Vorherigen statt wie der Anfang von etwas Neuem — bei zwei
   Bereichen untereinander ist genau das die Aufgabe: sagen, wo der eine
   aufhoert. Deshalb groesser, heller, mit Luft darueber und einer feinen
   Linie, die den Schnitt macht. */
.graphs h2 {
    font-family: var(--mono); font-size: 13px; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink2);
    margin: 52px 0 12px; padding-top: 22px;
    border-top: 1px solid var(--line);
}

/* Der erste Bereich braucht keinen Schnitt nach oben — darueber steht
   schon die Auswahl, und eine Linie ohne etwas davor trennt nichts. */
.graphs h2:first-of-type {
    margin-top: 0; padding-top: 0; border-top: 0;
}
.graphs h2 + svg { margin-bottom: 6px; }

/* Der Graph kommt fertig aus dem Server; hier steht nur, wie er aussieht. */
.graph {
    display: block; width: 100%; height: auto;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 3px;
}
.graph .grid { stroke: var(--surface2); stroke-width: 1; }
.graph .line { fill: none; stroke: var(--gold); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
/* Die zweite Temperaturlinie wird in der Tagesansicht nicht mehr
   gezeichnet — dort traegt das Tagesmittel die Aussage und die Spanne
   liegt als Band dahinter. Die Regel bleibt fuer andere Ansichten. */
.graph .line.low { stroke: var(--gold); stroke-width: 1.4; opacity: .6; }

/* Die Spanne von Tiefst- zu Hoechstwert. Blass genug, dass sie hinter
   der Linie bleibt: Sie ist der Hintergrund der Aussage, nicht eine
   zweite daneben. */
.graph .band { fill: var(--gold); opacity: .10; stroke: none; }
.graph .rain { fill: var(--teal); opacity: .45; }

/* DIE MONATSSAEULE. Ein Monat ist ein Eimer und kein Zeitpunkt — wo bei
   den Tagen eine Linie laeuft, steht hier je Monat eine Saeule vom Tiefst-
   zum Hoechstwert. Kraeftiger als `.band`, weil sie hier die Aussage
   traegt und nicht der Hintergrund einer Linie ist. Der Mittelstrich liegt
   darin und hat die Farbe, die auf allen Graphen das Mittel bedeutet. */
.graph .spanne { fill: var(--gold); opacity: .22; stroke: none; }
.graph .mittel { stroke: var(--gold); stroke-width: 2; stroke-linecap: round; }
.graph .ylab, .graph .xlab {
    fill: var(--ink3); font-family: var(--mono); font-size: 11px;
}

.legend, .coverage {
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
    margin: 0 0 38px;
}
.coverage { margin: 0; padding-top: 22px; border-top: 1px solid var(--line); }

@media (max-width: 700px) {
    /* Schmal bekommt die Temperatur eine eigene Zeile. */
    .reading.main { flex-basis: 100%; }
}

/* Kennzahlenliste. Gibt es im Theme von hofherweb schon; hier fehlte sie,
   und die Definitionsliste stand roh untereinander. */
/* ZWEI SCHMALE LISTEN NEBENEINANDER statt untereinander: System und
   Netze fuellen je nur eine halbe Zeilenbreite, und untereinander
   schieben sie den Rest der Seite grundlos nach unten.

   `auto-fit` mit Mindestbreite statt zweier fester Spalten — so
   rutschen sie auf schmalen Schirmen von selbst untereinander, und
   eine allein nimmt die volle Breite. */
.lora-paar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr));
    gap: 0 32px;
    align-items: start;

    /* DENSELBEN ABSTAND WIE ZWISCHEN KACHELREIHE UND REICHWEITE.
       Nachgemessen sind das 52 Pixel — sie kommen von `.live`. Ohne
       diese Zeile klebt das Paar direkt am Graphen darueber: Die
       Regel `.graphs + .graphs` greift hier nicht, weil zwischen den
       Abschnitten jetzt ein `div` steht und kein `.graphs`. */
    margin-top: 52px;
}

.facts {
    display: grid; grid-template-columns: auto 1fr; gap: 8px 28px;
    margin: 0 0 38px; padding: 20px 22px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 3px;
    max-width: 46rem;
}
.facts dt { font-family: var(--mono); font-size: 12px; color: var(--ink3); }
.facts dd { margin: 0; font-variant-numeric: tabular-nums; }

/* Die Wahl der zweiten Achse. Links in der Adresse, kein Skript. */
/* Die kleinen Graphen untereinander. Jeder hat seine eigene Skala — die
   Zeitachse steht einmal unter dem grossen Graphen darueber und gilt fuer
   alle. Deshalb sitzen sie dicht und ohne eigene Rahmen. */
/* Das Fadenkreuz. Steht in Ruhe ausserhalb der Zeichenflaeche; bewegt wird
   nur sein x. `pointer-events: none`, damit es sich nicht selbst im Weg
   steht, wenn die Maus darueberfaehrt. */
.cross {
    /* Gold wie die Zeile "Werte zum Zeitpunkt" darunter: Linie und Liste
       gehoeren zusammen, also sagen sie das auch. Ein Grau waere auf dem
       dunklen Grund ausserdem kaum zu sehen — die erste Fassung stand auf
       `var(--ink-3)`, eine Variable, die es gar nicht gibt. Der Browser
       machte daraus `stroke: none` und zeichnete NICHTS, ohne ein Wort. */
    stroke: var(--gold);
    stroke-width: 1.2;
    stroke-dasharray: 4 4;
    pointer-events: none;
}

/* Die Ableseliste. Zwei Spalten, damit Name und Wert eine Kante haben —
   Zahlen mit Tabellenziffern, sonst wackelt die Spalte beim Wandern. */
.readout {
    display: grid;
    grid-template-columns: auto auto;
    gap: 2px 14px;
    justify-content: start;
    margin: 10px 0 4px;
    font-family: var(--mono);
    font-size: 12px;
}

.readout dt { color: var(--ink3); }
.readout dd { margin: 0; font-variant-numeric: tabular-nums; }
.readout .readout-time { color: var(--gold); }

.crosshair-hint { margin-top: 0; }

/* VIER MESSWERTE, ZWEI PAARE — KEINE REIHE.
   Bei den Spreizfaktoren ist der Verlauf von Gold nach Rot richtig, weil
   SF7 bis SF12 eine Ordnung haben. Luftdruck, Luftfeuchte, Wind und Böen
   haben keine: Ein Verlauf würde hier eine Rangfolge behaupten, die es
   nicht gibt.

   Was sie haben, sind zwei Paare. Druck und Feuchte beschreiben den
   Zustand der Luft — kühle Töne. Wind und Böen ihre Bewegung, und Böen
   sind die Spitzen desselben Windes — deshalb derselbe warme Ton, nur
   heller. Man sieht die Verwandtschaft, ohne die Beschriftung zu lesen.

   Gold und Teal bleiben frei: Sie tragen auf derselben Seite schon die
   Temperatur und den Regen. Zwei Bedeutungen auf einer Farbe sind eine
   zu viel. */
:root {
    --mess-pressure: #9B8CC4;   /* Violett  — träge, schwer */
    --mess-humidity: #6A9FD4;   /* Blau     — Wasser in der Luft */
    --mess-wind:     #C98A5B;   /* Sand     — Bewegung */
    --mess-gust:     #E0B183;   /* helleres Sand — Spitzen desselben Windes */

    /* HELLIGKEIT, seit dem 06.10.2026. Gruen ist der einzige Bereich des
       Farbkreises, der hier noch frei war: Violett und Blau tragen Luft,
       Sand den Wind, Gold (#EFBE18) die Temperatur und Teal (#5FB5AE)
       den Regen. Ein gelber Ton waere das Naheliegende fuer Licht — und
       genau deshalb falsch, er saesse auf dem Gold der Temperaturlinie,
       die im selben Bild laeuft. Entsaettigtes Blattgruen ist weit genug
       von allen vieren weg und bleibt auf dunklem Grund lesbar. */
    --mess-lux:      #A3BF6B;   /* Blattgruen — Licht, ohne dem Gold nahe zu kommen */
}

/* Die Ableseliste trägt dieselben Farben wie die Kurven darüber — die
   Zuordnung erledigt das Auge, nicht der Leser. Nur die Beschriftung ist
   eingefärbt; die Zahl bleibt hell, sonst wird die Spalte, auf die es
   ankommt, zur schwächsten auf der Seite. */
.readout dt.rd-pressure { color: var(--mess-pressure); }
.readout dt.rd-humidity { color: var(--mess-humidity); }
.readout dt.rd-wind     { color: var(--mess-wind); }
.readout dt.rd-gust     { color: var(--mess-gust); }
.readout dt.rd-lux      { color: var(--mess-lux); }
.readout dt.rd-temp,
.readout dt.rd-temp_min { color: var(--gold); }
.readout dt.rd-rain     { color: var(--teal); }

/* Der Vergleich hat keine Messgroessen als Zeilen, sondern zwei
   Abschnitte — dieselben zwei Farben wie die Linien im Bild, damit die
   Zuordnung ohne Suchen gelingt. */
.readout dt.rd-now      { color: var(--gold); }
.readout dt.rd-past     { color: var(--ink2); }

/* Zwei Auswertungsbloecke hintereinander brauchen Luft — sonst klebt die
   naechste Ueberschrift am letzten Balken. */
.graphs + .graphs { margin-top: 34px; }

/* Nebeneinander gilt der Abstand nicht: Er war fuer untereinander
   gedacht und versetzt die beiden Ueberschriften sonst um 34 Pixel
   gegeneinander. */
.lora-paar > .graphs + .graphs { margin-top: 0; }

/* Balken links, Ring rechts. Auf schmalen Schirmen untereinander. */
.sf-split { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 40px; align-items: center; }
/* Ring und Legende gehoeren zusammen und wandern gemeinsam. */
.sf-ring { display: flex; align-items: center; gap: 22px; }
.sf-ring .ring { width: 170px; }
.ring     { display: block; width: 100%; height: auto; }

@media (max-width: 800px) {
    .sf-split { grid-template-columns: 1fr; gap: 24px; justify-items: center; }
}

/* EINE FARBREIHE, KEINE SECHS BUNTEN.
   SF7 bis SF12 sind keine Kategorien, sondern eine Reihe: nah und schnell an
   einem Ende, weit und langsam am anderen. Der Verlauf von Gold nach Rot
   zeigt das, ohne dass man die Beschriftung lesen muss — und bleibt im
   Farbklima der Seite. */
.ring-ground { stroke: var(--surface2); stroke-width: 16; }
.ring-slice  { stroke-width: 16; }

/* Die sechs Werte stehen GENAU EINMAL da. Ring und Legende greifen beide
   darauf zu — zwei Listen mit denselben Farben waeren zwei Listen, die
   irgendwann auseinanderlaufen. */
:root {
    --sf7:  #F6D65B;
    --sf8:  #EFBE18;
    --sf9:  #E39A1C;
    --sf10: #D2741F;
    --sf11: #BC5326;
    --sf12: #9E3A2C;
}

.ring-sf7  { stroke: var(--sf7); }
.ring-sf8  { stroke: var(--sf8); }
.ring-sf9  { stroke: var(--sf9); }
.ring-sf10 { stroke: var(--sf10); }
.ring-sf11 { stroke: var(--sf11); }
.ring-sf12 { stroke: var(--sf12); }

/* Die Legende erklaert die Farben des Rings — die Balken daneben sind alle
   gold und sagen dazu nichts. Senkrecht, in der Reihenfolge der Reihe. */
.sf-legend {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: 7px;
    font-family: var(--mono); font-size: 11.5px; color: var(--ink2);
}
.sf-legend li { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.sf-legend .dot { width: 11px; height: 11px; border-radius: 2px; flex: none; }
.sf-legend .share { color: var(--ink3); font-variant-numeric: tabular-nums; }

.dot-sf7  { background: var(--sf7); }
.dot-sf8  { background: var(--sf8); }
.dot-sf9  { background: var(--sf9); }
.dot-sf10 { background: var(--sf10); }
.dot-sf11 { background: var(--sf11); }
.dot-sf12 { background: var(--sf12); }

.ring-total {
    font-family: var(--mono); font-size: 15px; fill: var(--ink);
    font-variant-numeric: tabular-nums;
}

/* Spreizfaktoren als Balken. Ein Donut waere huebscher, aber sechs Anteile
   nebeneinander liest man in Balken schneller — und sie funktionieren ohne
   ein einziges Skript. */
.sf-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; max-width: 46rem; }
.sf-bars li { display: grid; grid-template-columns: 3.4rem 1fr 4rem; align-items: center; gap: 14px; }
.sf-label { font-size: 12px; color: var(--ink3); }
.sf-track { display: block; width: 100%; height: 10px; border-radius: 2px; }
.sf-bg    { fill: var(--surface2); }
.sf-fill  { fill: var(--gold); }
.sf-value { font-size: 12px; color: var(--ink2); text-align: right; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- Startseite */

.home { max-width: 82rem; margin-inline: auto; }

.hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 24rem;
    gap: 4.5rem;
    align-items: start;
    padding-bottom: 60px;
    border-bottom: 1px solid var(--line);
}

.eyebrow.gold { color: var(--gold); }

.hero h1 {
    font-family: var(--display); font-weight: 700;
    font-size: clamp(2.2rem, 5.4vw, 3.75rem); line-height: 1.02; letter-spacing: -.032em;
    margin: 0 0 22px; text-wrap: balance;
}

.hero .lead { font-size: 1.15rem; line-height: 1.55; color: var(--ink2); max-width: 30em; margin: 0; }

.button.quiet { background: transparent; color: var(--ink2); border: 1px solid var(--line); }
.button.quiet:hover { background: var(--surface2); color: var(--ink); }

/* Die Wetterkachel im Aufmacher — dieselben Werte wie /wetter, nur knapper. */
.tile {
    border: 1px solid var(--line); border-radius: 3px;
    background: var(--surface); padding: 22px 24px 18px;
}
.tile header {
    display: flex; align-items: baseline; justify-content: space-between;
    margin-bottom: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--surface2);
}
.tile .tile-label {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink3);
}
.tile header time { font-family: var(--mono); font-size: 11px; color: var(--ink3); }

.tile-temp { margin: 0 0 18px; font-family: var(--display); letter-spacing: -.04em; color: var(--ink2); }
.tile-temp strong {
    font-size: 3.1rem; font-weight: 700; line-height: 1; color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.tile dl {
    display: grid; grid-template-columns: auto 1fr; gap: 9px 20px; margin: 0;
    font-family: var(--mono); font-size: 12.5px;
}
.tile dt { color: var(--ink3); }
.tile dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.tile .dir { color: var(--gold); margin-left: 5px; }

.tile-more {
    display: block; margin-top: 18px; padding-top: 14px;
    border-top: 1px solid var(--surface2);
    font-family: var(--mono); font-size: 12px;
}

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

.strip { padding: 52px 0; border-bottom: 1px solid var(--line); }
.strip:last-child { border-bottom: 0; }

.strip-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 24px; margin-bottom: 26px;
}
.strip-head h2 {
    font-family: var(--display); font-size: 1.5rem; font-weight: 600;
    letter-spacing: -.02em; margin: 0 0 4px;
}
.strip-head p { margin: 0; font-size: 14.5px; color: var(--ink3); }
.strip-head a { font-family: var(--mono); font-size: 12.5px; white-space: nowrap; }

.strip .card h3 {
    font-family: var(--display); font-size: 1.15rem; font-weight: 600;
    letter-spacing: -.015em; margin: 0;
}
.strip .card h3 a { color: var(--ink); text-decoration: none; }
.strip .card h3 a:hover { color: var(--gold); }

.strip .thumb h3 {
    font-family: var(--display); font-size: 1rem; font-weight: 600;
    letter-spacing: -.01em; margin: 12px 0 4px;
}
.strip .thumb a:hover h3 { color: var(--gold); }
.strip .thumb p { margin: 0; font-size: 11px; color: var(--ink3); }

/* Der Streifen der Startseite ist weg: Notizen stehen dort jetzt in
   denselben Kacheln wie Werkzeuge und Konstruktionen. Vorher war es ein
   eigener Aufbau mit Datumsspalte und vollem Text — bei der ersten Notiz
   mit Bild und Aufzaehlung ein Viertel der Seitenhoehe. */

@media (max-width: 900px) {
    .hero { grid-template-columns: 1fr; gap: 40px; }
    .strip-head { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* ------------------------------------------------- Der Werkstatt-Strom

   Eine Zeitfolge statt vier Rubriken (01.10.2026). Links die Spur, rechts
   ein schmaler Beistand, der mitlaeuft.

   WARUM DAS KLEBEN HIER AUFGEHT: Die Spur wird mit jeder Woche laenger,
   die Kacheln rechts bleiben kurz und sind immer aktuell. Je mehr
   eingetragen wird, desto besser wird es — und nicht umgekehrt. */
.strom-block { padding: 52px 0 0; }

.strom-gitter {
    display: grid; grid-template-columns: minmax(0, 1fr) 17.5rem;
    gap: 56px; align-items: start;
}

/* Die Chips fuehren IN DIE BEREICHE und filtern nicht — deshalb ist der
   erste kein Verweis, sondern die Lage: Man ist schon hier. */
.chips { display: flex; gap: 7px; flex-wrap: wrap; margin: 0 0 6px; }
.chip {
    font-family: var(--mono); font-size: 11.5px; text-decoration: none;
    color: var(--ink3); border: 1px solid var(--line); padding: 5px 12px;
}
a.chip:hover { color: var(--ink); border-color: var(--ink3); }
.chip.an { color: #15191A; background: var(--gold); border-color: var(--gold); }

/* --- Die Spur ------------------------------------------------------- */
.spur { position: relative; margin: 0; padding: 0; list-style: none; }

/* Die Linie beginnt und endet INNERHALB des ersten und letzten Eintrags,
   sonst haengt sie oben und unten in der Luft. */
.spur::before {
    content: ""; position: absolute; left: 6.5rem; top: 1.6rem; bottom: 1.6rem;
    width: 1px; background: var(--line);
}

.spur > li {
    position: relative; display: grid; grid-template-columns: 6.5rem 1fr;
    gap: 0 1.9rem; padding: 22px 0;
}
.spur > li + li { border-top: 1px solid var(--line); }

.spur .wann {
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
    text-align: right; padding: 3px 1rem 0 0; letter-spacing: .03em;
    line-height: 1.45;
}

/* Der Punkt sitzt auf der Linie. Seine Farbe ist die Art des Eintrags —
   dieselbe Zuordnung wie bei der Marke darueber, damit man die Spur auch
   ueberfliegen kann, ohne zu lesen. */
.spur .punkt {
    position: absolute; left: 6.5rem; top: 1.75rem; width: 9px; height: 9px;
    margin-left: -4px; border-radius: 50%;
    background: var(--ground); border: 1.5px solid var(--ink3);
}
.punkt-code  { background: var(--gold);  border-color: var(--gold); }
.punkt-druck { background: var(--teal);  border-color: var(--teal); }
.punkt-mess  { background: var(--axis2); border-color: var(--axis2); }

.spur .art {
    display: inline-block; font-family: var(--mono); font-size: 10px;
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink3);
    margin-bottom: 7px;
}
.art-code  { color: var(--gold); }
.art-druck { color: var(--teal); }
.art-mess  { color: var(--axis2); }

.spur .eintrag.mitbild {
    display: grid; grid-template-columns: minmax(0, 1fr) 12rem;
    gap: 1.6rem; align-items: start;
}
.spur .eintrag h3 {
    font-family: var(--display); font-size: 1.2rem; font-weight: 600;
    letter-spacing: -.01em; margin: 0 0 7px; line-height: 1.28;
}
.spur .eintrag h3 a { color: var(--ink); text-decoration: none; }
.spur .eintrag h3 a:hover { color: var(--gold); }
.spur .eintrag p { margin: 0; color: var(--ink2); font-size: 15.5px; max-width: 62ch; }
.spur .eintrag .fuss {
    margin-top: 10px; font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}
.spur .eintrag .fuss a { text-decoration: none; }
.spur .eintrag .fuss a:hover { text-decoration: underline; }

/* Das Datum ist die Auskunft, auf die es in dieser Zeile ankommt — heller
   als der Satz darum, aber ohne Farbe: Die gehoert dem Verweis. */
.spur .eintrag .fuss .fuss-seit { color: var(--ink2); }

/* Der Zeitraum unter der Kachelliste: einmal gesagt statt in jedem
   Etikett — dort brach er die schmale Spalte um. */
.mini-fuss {
    margin: 10px 0 0; font-family: var(--mono); font-size: 10.5px;
    line-height: 1.6; color: var(--ink3);
}

/* „Zu den / Rekorden →“ auf zwei Zeilen las sich wie zwei Angaben. Der
   Verweis bricht deshalb als Ganzes um, nicht in sich. Im Fuss gibt es
   genau diesen einen — eine eigene Klasse waere eine Stelle mehr, die
   mitgepflegt werden muss. */
.spur .eintrag .fuss a { white-space: nowrap; }

/* Ein Rekord IST die Zahl — deshalb steht sie da, wo sonst der Text steht. */
.spur .messwert strong {
    font-family: var(--display); font-size: 1.95rem; font-weight: 600;
    line-height: 1.1; letter-spacing: -.02em; color: var(--axis2);
    font-variant-numeric: tabular-nums;
}

.spur .rahmen {
    display: block; aspect-ratio: 4 / 3; overflow: hidden;
    background: #0E1113; border: 1px solid var(--line);
}
.spur .rahmen img { width: 100%; height: 100%; object-fit: cover; }

/* Ein Aufmacher kann eine Wortmarke mit eigenem Grund sein. Beschnitten
   saehe sie aus wie ein Fehler, also wird sie eingepasst. */
.spur .rahmen.passend img { object-fit: contain; padding: 14px; }

.strom-ende {
    margin: 26px 0 0; font-family: var(--mono); font-size: 12.5px; color: var(--ink3);
}
.strom-ende a { margin: 0 2px; }

/* --- Der Beistand --------------------------------------------------- */
.beistand { position: sticky; top: 6.5rem; display: grid; gap: 16px; }

.mini { border: 1px solid var(--line); background: var(--surface); padding: 16px 18px; }
.mini h3 {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink3); margin: 0 0 12px; font-weight: 500;
}
.mini dl {
    display: grid; grid-template-columns: 1fr auto; gap: 4px 12px;
    margin: 0; font-family: var(--mono); font-size: 12px;
}
.mini dt { color: var(--ink3); }
.mini dd { margin: 0; text-align: right; color: var(--ink2); font-variant-numeric: tabular-nums; }

.mini-zustand { margin: 0 0 12px; font-family: var(--mono); font-size: 12.5px; }
/* DER PUNKT SAGT DEN ZUSTAND IN FARBE — UND IN BEWEGUNG.
   Er pulst nur, solange das Gateway wirklich sendet; steht es, steht
   auch der Punkt. DREI ZUSTAENDE, NICHT ZWEI: Teal und pulsend heisst
   Betrieb, Rot und still heisst Ausfall, Grau und still heisst, wir
   wissen es nicht — die Meldung ist zu alt. Vorher sahen Ausfall und
   Unkenntnis gleich aus, und das ist ein Unterschied ums Ganze.

   Der Ring ist ein `box-shadow` und keine zweite Flaeche: So braucht
   der Punkt kein Pseudo-Element, und die Bewegung laeuft auf einer
   Eigenschaft, die nichts umbricht. */
.puls {
    display: inline-block; width: 7px; height: 7px; border-radius: 50%;
    background: var(--teal); margin-right: 7px; vertical-align: middle;
    box-shadow: 0 0 0 3px rgba(95, 181, 174, .18);
    animation: puls-ring 1.8s ease-out infinite;
}

/* Kein Puls, wenn nichts pulst. */
.puls.aus { background: var(--ink3); box-shadow: none; animation: none; }

/* Rot ist hier dasselbe Rot wie bei der hoechsten Warnstufe — eine
   zweite Bedeutung auf einer bekannten Farbe statt einer neuen. */
.puls.weg {
    background: #A63A4A; box-shadow: 0 0 0 3px rgba(166, 58, 74, .20);
    animation: none;
}

/* Derselbe Punkt neben dem grossen Wert der LoRa-Seite. Nur die Masse
   aendern sich — Farbe, Bedeutung und Bewegung bleiben dieselben, sonst
   waeren es zwei Zeichen statt einem.

   IN `em`, NICHT IN PIXELN: Der Wert daneben waechst mit dem Fenster
   (`clamp(2.4rem, 7vw, 3.6rem)`). Ein fester Punkt sitzt dann mal
   richtig und mal verloren daneben; in `em` behaelt er sein
   Groessenverhaeltnis zur Schrift, was immer das Fenster macht. */
.puls.gross {
    width: .3em; height: .3em; margin-right: .3em;
    box-shadow: 0 0 0 .1em rgba(95, 181, 174, .18);
    animation-name: puls-ring-gross;
}
.puls.gross.weg { box-shadow: 0 0 0 .1em rgba(166, 58, 74, .20); }

/* DIE BEWEGUNG FASST DEN PUNKT SELBST AN, nicht nur seinen Schatten.
   Der erste Anlauf liess allein einen Ring nach aussen verblassen —
   und der war praktisch unsichtbar, weil Radius und Deckkraft
   GEGENEINANDER liefen: am Anfang volle Deckkraft bei Radius null,
   am Ende voller Radius bei Deckkraft null. Nur dazwischen blieb ein
   Hauch, rund eine halbe Sekunde lang ein 3-px-Ring mit 25 Prozent
   Deckkraft auf dunklem Grund. Dirk am 09.10.2026: „das Pulsieren
   kann ich optisch nicht wahrnehmen“ — zu Recht.

   Jetzt tragen drei Dinge zusammen: Der Punkt waechst und schrumpft,
   er wird dabei heller, und die Welle laeuft zusaetzlich nach aussen.
   Der ruhende Ring bleibt die ganze Zeit stehen — vorher loeschte ihn
   die Animation, und der Punkt sah bewegungslos duenner aus als ohne
   sie. */
@keyframes puls-ring {
    0%   { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 3px rgba(95, 181, 174, .18), 0 0 0 0 rgba(95, 181, 174, .50); }
    40%  { transform: scale(1.35);
           background: #8FD6D0;
           box-shadow: 0 0 0 3px rgba(95, 181, 174, .22), 0 0 0 7px rgba(95, 181, 174, .12); }
    75%  { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 3px rgba(95, 181, 174, .18), 0 0 0 11px rgba(95, 181, 174, 0); }
    100% { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 3px rgba(95, 181, 174, .18), 0 0 0 0 rgba(95, 181, 174, 0); }
}

@keyframes puls-ring-gross {
    0%   { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 .1em rgba(95, 181, 174, .18), 0 0 0 0 rgba(95, 181, 174, .50); }
    40%  { transform: scale(1.35);
           background: #8FD6D0;
           box-shadow: 0 0 0 .1em rgba(95, 181, 174, .22), 0 0 0 .22em rgba(95, 181, 174, .12); }
    75%  { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 .1em rgba(95, 181, 174, .18), 0 0 0 .36em rgba(95, 181, 174, 0); }
    100% { transform: scale(1);
           background: var(--teal);
           box-shadow: 0 0 0 .1em rgba(95, 181, 174, .18), 0 0 0 0 rgba(95, 181, 174, 0); }
}

/* WER BEWEGUNG ABBESTELLT HAT, SIEHT TROTZDEM, DASS ETWAS LAEUFT.
   Kein Wachsen, keine Welle — nichts bewegt sich im Raum, und genau
   darum geht es bei dieser Einstellung. Was bleibt, ist ein langsames
   Hell und Dunkel derselben Farbe, viermal langsamer als der Puls.

   Dass es diese Fassung gibt, hat einen Anlass: Dirks Windows hat
   Animationseffekte abgeschaltet, und damit melden Firefox, Chrome
   und Vivaldi auf seinem Rechner alle `reduce`. Der Puls lief also
   fuer die Besucher, nur nicht fuer ihn — und wer die eigene Seite
   nie lebendig sieht, merkt auch nicht, wenn sie es nicht mehr ist.

   STILL BLEIBT, WAS STILL SEIN SOLL: Rot und Grau heissen Ausfall und
   Unkenntnis. Ein blinkender Ausfall waere ein Widerspruch. Die beiden
   Zustaende stehen hier ausdruecklich noch einmal, statt sich auf die
   hoehere Spezifitaet ihrer Grundregeln zu verlassen — Verlass auf
   Spezifitaet ist die Sorte Annahme, die still bricht. */
@media (prefers-reduced-motion: reduce) {
    /* `!important` schlaegt hier die Pauschalregel weiter oben, die
       mit `*` jede Animation abwuergt. DAS WAR DER WAHRE GRUND, warum
       Dirk in drei Browsern nichts sah — nicht die Einstellung allein,
       sondern diese Zeile, die es laengst gab. */
    .puls { animation: puls-ruhig 4s ease-in-out infinite !important; }
    .puls.aus, .puls.weg { animation: none !important; }
}

@keyframes puls-ruhig {
    0%, 100% { background: var(--teal); }
    50%      { background: #8FD6D0; }
}

.mini-mehr {
    margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line);
    font-family: var(--mono); font-size: 12px;
}
.mini-mehr a { text-decoration: none; }
.mini-mehr a:hover { text-decoration: underline; }

.zahlen { background: transparent; }
.zahlen dd.null { color: var(--gold); }

.mini-rss { margin: 0; font-family: var(--mono); font-size: 12px; color: var(--ink3); }

/* GENAU DIE GRENZE DER KOPFZEILE (siehe oben, 1000 px): Darunter klebt
   sie nicht mehr, also darf auch der Beistand nicht kleben — sonst
   schoebe er sich unter einen Kopf, der mitlaeuft. */
@media (max-width: 1000px) {
    .strom-gitter { grid-template-columns: 1fr; gap: 44px; }
    .beistand { position: static; }
}

@media (max-width: 760px) {
    /* Auf dem Telefon ist die Datumsspalte verlorene Breite: Das Datum
       wandert ueber den Eintrag, Linie und Punkt entfallen mit ihr. */
    .spur::before, .spur .punkt { display: none; }
    .spur > li { grid-template-columns: 1fr; gap: 8px; }
    .spur .wann { text-align: left; padding: 0; }
    .spur .eintrag.mitbild { grid-template-columns: 1fr; gap: 14px; }
    .spur .rahmen { max-width: 16rem; }
}

/* Hinweis auf der oeffentlichen Seite, solange Wartung ist — sichtbar nur
   fuer den Angemeldeten, der gerade Korrektur liest. */
.wartungshinweis {
    display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
    margin: 0; padding: 11px var(--gutter);
    background: var(--gold-dim); color: var(--gold);
    border-bottom: 1px solid #5A4A12;
    font-family: var(--mono); font-size: 12px;
}
.wartungshinweis a { margin-left: auto; }

/* ------------------------------------------------------ Wettersymbole */

/* Das Sprite selbst zeigt nichts — es haelt nur die Zeichnungen bereit. */
.wi-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.wi {
    width: 1.5em; height: 1.5em; display: block; flex: none;
    overflow: visible;
}
.wi.big { width: 3.2rem; height: 3.2rem; }

/* Die Farben.
   Als benutzerdefinierte Eigenschaften und nicht als Selektoren: <use>
   erzeugt einen Schattenbaum, in den gewoehnliche Regeln nicht hineinreichen.
   Vererbte Eigenschaften kommen durch — und diese hier werden vererbt. */
.wi {
    --wi-sun:        var(--gold);
    --wi-ray:        var(--gold);
    --wi-moon:       var(--gold);
    --wi-cloud:      var(--ink2);
    --wi-cloud-back: var(--ink3);
    --wi-drop:       var(--teal);
    --wi-flake:      var(--ink);
    --wi-mist:       var(--ink2);
    --wi-bolt:       var(--gold);
}

/* Grosse Temperaturzeile: Symbol und Zahl auf einer Grundlinie. */
.temp-row { display: flex; align-items: center; gap: 18px; }

/* Ohne Zustand faellt auch der Trenner weg. */
.reading-note [data-w="condition"]:empty + .sep { display: none; }

/* In der Kachel der Startseite steht das Symbol neben der Zahl. */
.tile-temp { display: flex; align-items: center; gap: 12px; }

/* ---------------------------------------------------------- Sonnenstand */

.sunbar { margin: 0 0 44px; }

.sunbar h2 {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink3); margin: 0 0 14px;
}

/* Der Balken ist der ganze Ortstag von Mitternacht bis Mitternacht.
   Gezeichnet wird er als SVG, nicht mit CSS-Variablen aus der Vorlage:
   style-src 'self' verwirft einen Inline-Style stillschweigend, und der
   Balken stand monatelang ohne helles Band da. In SVG sind x und width
   Attribute. Die FARBEN stehen weiterhin hier. */
/* HEISST DAYBAR UND NICHT SUNBAR: Der Abschnitt drumherum traegt schon
   class="sunbar" — dieselbe Klasse fuer das SVG hat ihn auf 22 px gestaucht,
   und der Verlauf darunter schob sich darueber. Im Browser gesehen, nicht
   im Quelltext. */
.daybar { display: block; width: 100%; height: 22px; }

.daybar-ground { fill: var(--surface2); stroke: var(--line); stroke-width: 1; }
.daybar-day    { fill: url(#sunbar-day); }
.daybar-tick   { fill: var(--ground); opacity: .55; }

.daybar .stop-dim  { stop-color: var(--gold-dim); }
.daybar .stop-full { stop-color: var(--gold); }

/* Hell mit dunklem Saum, und zwar immer. Eine dunkle Marke traegt zwar im
   Gold, verschwindet aber nachts auf dem Seitengrund. */
.daybar-ring { fill: var(--ground); }
.daybar-now  { fill: var(--ink); }

/* Der Sprung von Minute zu Minute soll gleiten, nicht springen. */
[data-w="sun-marker"] { transition: transform .6s linear; }


/* Sonne breit, Mond daneben. */
.sun-and-moon {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 34px; align-items: start;
}

.moon-side { margin: 0; display: flex; align-items: center; gap: 14px; }
.moon-side .moon { width: 44px; height: 44px; display: block; flex: none; }
.moon-side figcaption {
    display: flex; flex-direction: column; gap: 2px;
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}
.moon-side strong { font-weight: 500; color: var(--ink2); font-size: 12.5px; }

/* Beleuchtet in Gold, der Rest als Scheibe — sonst waere Neumond ein Loch. */
.moon { --moon-lit: var(--gold); --moon-dark: var(--surface2); }

@media (max-width: 700px) {
    .sun-and-moon { grid-template-columns: 1fr; gap: 22px; }
}

/* Aufgang links, Untergang rechts. Genau unter ihrer Stelle im Balken sassen
   sie frueher — ueber einen Inline-Style, der nie gewirkt hat. */
.bar-marks {
    display: flex; justify-content: space-between; gap: 12px; margin-top: 9px;
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}
.bar-marks span { white-space: nowrap; }
.bar-marks b { color: var(--ink2); font-weight: 400; font-variant-numeric: tabular-nums; }

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

@media (prefers-reduced-motion: reduce) {
    [data-w="sun-marker"] { transition: none; }
}

/* Zweites Band: wann der Mond ueber dem Horizont steht. Dieselbe Skala wie
   die Sonne darueber, damit sich beides vergleichen laesst. */
.moonband {
    display: block; width: 100%; height: 5px; margin-top: 4px;
    border-radius: 3px; background: var(--surface2);
}
/* Geht der Mond vor Mitternacht auf und erst am naechsten Tag unter, zeichnet
   die Vorlage zwei Rechtecke statt eines negativen. */
.moonband-up { fill: var(--ink3); }

.mondzeiten { font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* ---------------------------------------------------------- Auswertung */

/* Das Anfangsdatum der Messreihe. Es steht abgesetzt, weil es die Rekorde
   darunter einordnet — drei Tage sind keine Statistik, und wer das erst im
   Kleingedruckten erfaehrt, hat die Tafel schon anders gelesen. */
.coverage.since {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px;
    margin: 0 0 20px; padding: 14px 18px;
    border-top: 0; border-left: 3px solid var(--gold);
    background: var(--surface);
}
.coverage.since .seit-was {
    text-transform: uppercase; letter-spacing: .09em; font-size: 11px;
}
.coverage.since .seit-datum {
    color: var(--gold); font-family: var(--display); font-size: 21px;
    font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums;
}
.coverage.since .seit-tage { color: var(--ink2); }

.records th {
    text-align: left; font-weight: 400; color: var(--ink2);
    font-family: var(--body); font-size: 15.5px;
}
.records .value {
    font-family: var(--mono); font-size: 15px; color: var(--ink);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.records .when {
    font-family: var(--mono); font-size: 12px; color: var(--ink3);
    text-align: right; white-space: nowrap;
}

/* Kenntage: vier Zahlen, die einen Winter oder Sommer beschreiben. */
.kenntage {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 1px; margin: 1px 0 0;
    background: var(--line); border: 1px solid var(--line); border-radius: 3px;
    overflow: hidden;
}
.kenntage > div {
    background: var(--surface); padding: 16px 20px;
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.kenntage dt {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink3);
}
.kenntage dd {
    margin: 0; font-family: var(--display); font-size: 1.4rem; font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Woher die Schwellen kommen. Steht unter den Kacheln, nicht in einem
   Aufklapper: Wer die Zahlen sieht, soll die Definition daneben finden
   und nicht erst danach suchen muessen. */
.kenntage-def { display: flex; flex-direction: column; gap: 9px; margin-top: 16px; }
.kenntage-def p { margin: 0; }

/* Tabellen im oeffentlichen Teil — die Redaktion hat eigene. */
.weather .tablewrap {
    border: 1px solid var(--line); border-radius: 3px;
    background: var(--surface); overflow-x: auto;
}
.weather table { border-collapse: collapse; width: 100%; font-size: 15px; }
.weather th, .weather td { padding: 11px 18px; border-bottom: 1px solid var(--surface2); }
.weather tr:last-child td, .weather tr:last-child th { border-bottom: 0; }
.weather thead th {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em;
    text-transform: uppercase; color: var(--ink3); font-weight: 400;
    border-bottom: 1px solid var(--line);
}
.weather .right { text-align: right; }
.weather .mono { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }

/* Jahreslinien: das laufende Jahr kraeftig, die Vorjahre blasser. */
.graph .line.now  { stroke: var(--gold); stroke-width: 2.2; }
.graph .line.past { stroke: var(--ink2); stroke-width: 1.5; }

/* EIN MESSWERT OHNE NACHBARN als Punkt (siehe Chart::punkte()). Die Farbe
   kommt von der Linie, zu der er gehoert; hier steht nur die Groesse.
   `path.` im Waehler mit Absicht: Das macht die Regel spezifischer als
   `.graph .line.now` und `.graph .line.zusatz` weiter unten, die sonst
   ihre duenne Strichstaerke durchsetzen wuerden — und ein Punkt von 2 px
   ist so unsichtbar wie gar keiner. */
.graph path.line.punkt { stroke-width: 7; }

/* Die Jahreszahl steht am Ende der Linie statt in einer Legende. */
.graph .yearlab {
    font-family: var(--mono); font-size: 11px; fill: var(--ink2);
}
.graph .yearlab.now { fill: var(--gold); }

/* ------------------------------------------------------- Klimastreifen */

.stripes {
    display: block; width: 100%; height: auto; max-width: 46rem;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 3px;
    padding: 6px;
}
.stripes .stripe.none { fill: var(--surface2); }
.stripes .yearlab { font-family: var(--mono); font-size: 11px; fill: var(--ink3); }
.stripes .xlab    { font-family: var(--mono); font-size: 11px; fill: var(--ink3); }

/* ------------------------------------------------------------ Windrose */

.rose-wrap { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 30px; align-items: center; }

.rose {
    display: block; width: 300px; max-width: 100%; height: auto;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 3px;
}
.rose .rose-ring { fill: none; stroke: var(--line); stroke-width: 1; }
.rose .xlab { font-family: var(--mono); font-size: 12px; fill: var(--ink3); }

/* Von innen nach aussen: Windstaerke 1 bis „4 und mehr". Eine Skala, kein
   Regenbogen — die Staerke waechst, also waechst die Helligkeit. */
/* Schwacher Wind ist die haeufigste Klasse und damit meist der groesste
   Ring — er darf nicht der dunkelste sein. */
.rose .rose-wedge.b0 { fill: #3E6B67; }
.rose .rose-wedge.b1 { fill: var(--teal); }
.rose .rose-wedge.b2 { fill: #C9A227; }
.rose .rose-wedge.b3 { fill: var(--gold); }

/* Die Legende der Rose sind mehrere Saetze: Aufbau, Lesart und, wenn die
   Reihe noch kurz ist, ein Hinweis darauf. Eigene Absaetze mit Abstand,
   damit daraus kein Block wird, den niemand liest. */
.rose-wrap .legend { display: flex; flex-direction: column; gap: 9px; }
.rose-wrap .legend p { margin: 0; }
.rose-wrap .legend .hint { color: var(--gold); }

.legend.wide { max-width: 46rem; }

/* Der laufende Zeitraum in einer Vergleichstabelle. */
.weather tr.jetzt td { color: var(--ink); background: var(--surface2); }

/* Liste der Monatsseiten eines Jahres. */
.monatsliste {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 10rem), 1fr)); gap: 1px;
    background: var(--line); border: 1px solid var(--line); border-radius: 3px; overflow: hidden;
}
.monatsliste a {
    display: flex; flex-direction: column; gap: 3px;
    background: var(--surface); padding: 15px 18px; text-decoration: none;
}
.monatsliste a:hover { background: var(--surface2); }
.monatsliste strong { font-family: var(--display); font-size: 1rem; font-weight: 600; color: var(--ink); }
.monatsliste span { font-family: var(--mono); font-size: 11px; color: var(--ink3); }

@media (max-width: 700px) {
    .rose-wrap { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------- Luftqualität */

/* ---------------------------------------------------------------- Warnungen */
.warn-stand { margin: 0 0 32px; font-size: 13px; color: var(--ink3); line-height: 1.5; }

.warn-block { margin: 0 0 40px; }
.warn-block h2 {
    margin: 0 0 14px; font-size: 15px; font-family: var(--mono);
    font-weight: 500; color: var(--ink2); letter-spacing: .02em;
}

/* „Keine Warnung" ist die haeufigste Antwort dieser Seite. Sie soll ruhig
   dastehen und nicht wie eine Fehlermeldung aussehen. */
.warn-frei {
    margin: 0; padding: 14px 18px; font-size: 14.5px; color: var(--ink2);
    background: var(--surface); border: 1px solid var(--line); border-radius: 3px;
    border-left: 3px solid #6FBF73;
}

/* Auf dieser Seite steht die Meldung als Kasten, nicht als Band ueber
   allem — hier ist sie der Inhalt und nicht die Unterbrechung. */
.warn-block .warnung { margin: 0 0 14px; }
.warn-block .warnung:last-child { margin-bottom: 0; }

ul.warn-liste { margin: 0; padding: 0; list-style: none; }
ul.warn-liste li {
    display: grid; grid-template-columns: 10px 12rem minmax(0, 1fr) auto;
    gap: 12px; align-items: baseline;
    padding: 9px 0; border-bottom: 1px solid var(--line); font-size: 14px;
}
ul.warn-liste li:last-child { border-bottom: 0; }

.wl-punkt {
    width: 10px; height: 10px; border-radius: 2px;
    background: var(--stufe, var(--ink3)); align-self: center;
}
.wl-ort  { color: var(--ink); }
.wl-was  { color: var(--ink2); }
.wl-zeit { font-family: var(--mono); font-size: 12px; color: var(--ink3); white-space: nowrap; }

ul.warn-legende { margin: 0 0 12px; padding: 0; list-style: none; display: grid; gap: 8px; }
ul.warn-legende li {
    display: grid; grid-template-columns: 10px minmax(0, 1fr) auto;
    gap: 12px; align-items: center; font-size: 14px;
}
.wl-name { color: var(--ink2); }
.wl-nr   { font-family: var(--mono); font-size: 12px; color: var(--ink3); }

.warn-legende-fuss { margin: 0; font-size: 12.5px; color: var(--ink3); line-height: 1.6; }

/* ZWEI SPALTEN: links die Karte, rechts der Text dazu. Die Karte zeigt,
   WO etwas ist; der Text sagt, WAS. Nebeneinander beantworten sie
   zusammen die Frage, mit der man auf diese Seite kommt.

   Die Bildspalte richtet sich nach der Karte und nicht nach einem festen
   Anteil: Das Warnschild ist breit, die Gemeindekarten sind hoch. */
.warn-lage {
    display: grid; grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
    gap: 28px; align-items: start;
    margin: 0 0 36px;
}

.warn-lage-bild { min-width: 0; }
.warn-lage-text { min-width: 0; }

/* Die zweite Ueberschrift in derselben Spalte braucht Luft nach oben,
   sonst klebt „In Baden-Wuerttemberg" am Kasten darueber. */
.warn-lage-text h2 { margin: 0 0 12px; }
.warn-lage-text .warn-zweite { margin-top: 28px; }

/* Ein Wert, der steht, ist keine Auskunft ueber draussen mehr. Die
   Zeile bleibt lesbar — geaendert wird die Farbe, nicht die Deckkraft. */
.reading-note.steht { color: #DD6B4D; }

/* AUSGEGEBEN IST NICHT IN KRAFT. Der gestrichelte Rand sagt „noch nicht“,
   ohne den Text blasser und damit schlechter lesbar zu machen. */
.warn-kommt {
    margin: 22px 0 10px; font-size: 12px; font-weight: 500;
    text-transform: uppercase; letter-spacing: .06em; color: var(--ink3);
}
.warnung.kommt { border-left-style: dashed; }
ul.warn-liste.kommt .wl-punkt {
    background: transparent; border: 2px solid var(--stufe, var(--ink3));
}
.warn-karte-fuss { display: block; margin-top: 4px; }

.warn-karten {
    display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start;
    margin: 0 0 14px;
}

.warn-karte { margin: 0; flex: 0 1 auto; }

/* DIE GEMEINDEKARTEN bekommen einen hellen Grund: Sie sind fuer weisse
   Seiten gezeichnet, und auf dunklem Grund saehe die Landesflaeche aus wie
   ein Loch. Das Warnschild bringt seinen eigenen Grund mit und braucht
   keinen. */
.warn-karte img {
    display: block; height: auto; border-radius: 3px; border: 1px solid var(--line);
}
.warn-karte.gemeinde img { max-width: 100%; background: #fff; padding: 8px; }
.warn-karte.schild img   { max-width: 100%; }

/* Ausserhalb der zweispaltigen Zeilen bleiben die Karten klein — dort
   stehen sie fuer sich und tragen keinen Text neben sich. */
.warn-karten .warn-karte.gemeinde img { max-width: min(100%, 300px); }
.warn-karten .warn-karte.schild img   { max-width: min(100%, 560px); }

.warn-kartenquelle { margin: 0 0 36px; }

/* Der Warnlagebericht ist Prosa und keine Meldung — er bekommt deshalb
   keinen Kasten und keinen farbigen Rand, sondern steht als Absatz da.
   Was er sagt, gilt unabhaengig davon, ob gerade gewarnt wird. */
.warn-bericht {
    margin: 14px 0 0; font-size: 14.5px; line-height: 1.65; color: var(--ink2);
}
.warn-bericht-quelle {
    display: block; margin-top: 6px;
    font-family: var(--mono); font-size: 11.5px; color: var(--ink3);
}

.warn-karte figcaption { margin: 8px 0 0; font-size: 12px; color: var(--ink3); }

/* Die Stufenfarbe gilt auch fuer Listenpunkte und Legende — dieselbe
   Bedeutung, dieselbe Farbe. */
.warn-liste .stufe-vorab,    .warn-legende .stufe-vorab    { --stufe: #8FA6C4; }
.warn-liste .stufe-wetter,   .warn-legende .stufe-wetter   { --stufe: #D8C13F; }
.warn-liste .stufe-markant,  .warn-legende .stufe-markant  { --stufe: #E09B3D; }
.warn-liste .stufe-unwetter, .warn-legende .stufe-unwetter { --stufe: #DD6B4D; }
.warn-liste .stufe-extrem,   .warn-legende .stufe-extrem   { --stufe: #A63A4A; }

@media (max-width: 820px) {
    /* Untereinander, und die KARTE ZUERST: Sie beantwortet die Frage „ist
       hier was" schneller als ein Absatz. */
    .warn-lage { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .warn-lage-bild .warn-karte img { max-width: min(100%, 420px); }
}

@media (max-width: 700px) {
    ul.warn-liste li { grid-template-columns: 10px minmax(0, 1fr); }
    .wl-zeit { grid-column: 2; }
}

/* ---------------------------------------------------------------- Vorhersage
   Die Tage als Zeilen und nicht als Kacheln: Man liest sie untereinander
   und vergleicht dabei Spalte fuer Spalte — Hoechstwert neben Hoechstwert.
   Ein Kachelraster zwingt das Auge zum Springen. */
.forecast-quelle {
    margin: 0 0 24px; font-size: 13px; color: var(--ink3); line-height: 1.5;
}

.forecast-tage h2, .forecast-stunden h2 {
    margin: 0 0 14px; font-size: 15px; font-family: var(--mono);
    font-weight: 500; color: var(--ink2); letter-spacing: .02em;
}

.forecast-tage { margin: 0 0 40px; }

table.tage { width: 100%; border-collapse: collapse; table-layout: fixed; }

/* Der Tag nimmt, was er braucht; das Symbol eine feste Spur; die sechs
   Zahlenspalten teilen sich den Rest ZU GLEICHEN TEILEN. Vorher standen
   feste rem-Breiten links und der ganze Rest als Loch rechts. */
table.tage .sp-tag    { width: 22%; }
table.tage .sp-himmel { width: 44px; }
table.tage .sp-zahl   { width: auto; }

/* Die Spaltenkoepfe im Ton der Rubrikzeilen: klein, schmal laufend, in der
   Schreibmaschine. Sie sollen die Spalte benennen und nicht mit den Werten
   um Aufmerksamkeit streiten. */
table.tage thead th {
    /* OBEN ausgerichtet: Nur die Zahlenspalten tragen eine Einheit unter
       ihrem Namen. Bei `bottom` rutschte „Tag" auf die Hoehe der Einheiten
       und sah aus, als stuende er in einer anderen Zeile. */
    padding: 0 0 9px; text-align: left; vertical-align: top;
    font-family: var(--mono); font-size: 11px; font-weight: 500;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink3);
    border-bottom: 1px solid var(--line);
}

/* Von den zwei Bezeichnungen ist breit die lange sichtbar, schmal die
   kurze — nie beide. */
table.tage thead .k-kurz { display: none; }

/* DIE EINHEIT STEHT UNTER DEM NAMEN, nicht dahinter: Sonst wird der Kopf
   breiter als seine Zahlen, und zwei Ueberschriften stossen aneinander —
   genau das war vorher zu sehen. */
table.tage thead .sp-einheit {
    display: block; margin-top: 2px;
    letter-spacing: .02em; text-transform: none; font-size: 10.5px;
    color: var(--ink4, var(--ink3)); opacity: .75;
}

table.tage tbody th,
table.tage tbody td {
    padding: 12px 0; vertical-align: middle;
    border-bottom: 1px solid var(--line);
}
table.tage tbody tr:last-child th,
table.tage tbody tr:last-child td { border-bottom: 0; }

/* ZAHLEN RECHTSBUENDIG, damit Einer unter Einer steht. Das ist der Grund,
   warum die Einheit oben steht: Erst ohne sie lassen sich die Spalten
   ueberhaupt untereinander vergleichen. */
table.tage .sp-zahl {
    text-align: right; padding-left: 14px;
    font-variant-numeric: tabular-nums; font-size: 15px; color: var(--ink);
}
table.tage thead .sp-zahl { text-align: right; padding-left: 14px; }

.tag-name  { font-size: 14.5px; font-weight: 600; text-align: left; }
.tag-datum { font-family: var(--mono); font-size: 12px; color: var(--ink3); margin-left: 6px; font-weight: 400; }

.tag-himmel { text-align: center; }
.tag-himmel .wi { width: 26px; height: 26px; display: inline-block; vertical-align: middle; }

/* Der Hoechstwert traegt den Tag, der Tiefstwert steht zurueck. */
.tag-hoch  { font-weight: 600; }
.tag-tief  { color: var(--ink2); }
.tag-boe, .tag-sonne { color: var(--ink2); }

/* Trockene Tage werden ausgegraut: In dieser Spalte sucht man nach dem,
   was NICHT null ist. */
.tag-regen.still, .tag-risiko.still { color: var(--ink3); opacity: .55; }

/* Der angefangene Tag: eigene Zeile unter dem Namen, damit er die Spalte
   nicht breiter macht als alle anderen zusammen. */
.tag-teil {
    display: block; font-family: var(--mono); font-size: 11px;
    color: var(--ink3); font-weight: 400; margin-top: 3px; white-space: nowrap;
}

/* Die Stunden laufen seitlich — 48 Spalten passen auf keinen Bildschirm,
   und ein Umbruch zerrisse den Verlauf. Nur DIESER Kasten rollt, nie die
   Seite. */
.stunden-rolle { overflow-x: auto; padding-bottom: 6px; }

/* DIE TREFFERQUOTE, vierter Abschnitt der Vorhersageseite. Gleiche Bauart
   wie die Tagestabelle darueber — drei Zeilen sollen nicht aussehen wie
   ein fremdes Bauteil. */
.forecast-guete { margin: 40px 0 0; }
.forecast-guete h2 {
    margin: 0 0 14px; font-size: 15px; font-family: var(--mono);
    font-weight: 500; color: var(--ink2); letter-spacing: .02em;
}
.guete-vor { margin: 0 0 16px; color: var(--ink2); max-width: 62ch; }

table.guete { width: 100%; border-collapse: collapse; }
table.guete thead th {
    padding: 0 0 9px; text-align: left; vertical-align: bottom;
    font-family: var(--mono); font-size: 11px; font-weight: 500;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink3);
}
table.guete thead th + th { text-align: right; padding-left: 14px; }
table.guete tbody th, table.guete tbody td {
    padding: 12px 0; vertical-align: middle; border-bottom: 1px solid var(--line);
}
table.guete tbody tr:last-child th, table.guete tbody tr:last-child td { border-bottom: 0; }
table.guete tbody th { text-align: left; font-size: 14.5px; font-weight: 600; }
table.guete .sp-zahl {
    text-align: right; padding-left: 14px;
    font-variant-numeric: tabular-nums; font-size: 15px; color: var(--ink);
}
/* Die Zahl der Stunden ist die Grundlage, nicht das Ergebnis. */
table.guete .guete-n { color: var(--ink2); }

/* Die Zeichnung steht zwischen Vorspann und Tabelle. `.breit` bringt hier
   keinen Ausbruch (den gibt es nur unter `.prose`), wohl aber den
   Rollrahmen auf dem Telefon — und genau der wird gebraucht. */
.guete-bild { margin: 0 0 24px; }

/* Die Begriffe: eine Spalte auf dem Telefon, mehrere auf dem Schirm.
   Stichwort UEBER dem Satz und nicht daneben — die Saetze sind zu lang
   fuer eine schmale Wertespalte und zerfielen zu Schnipseln.

   Gezaehlt wird das `div` um jedes Paar, nicht `dt` und `dd` einzeln:
   Als eigene Gitterzellen stuenden sie nebeneinander. */
.guete-begriffe {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
    gap: 20px 32px; margin: 22px 0 0;
}
.guete-begriffe dt {
    font-family: var(--mono); font-size: 11px; font-weight: 500;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink3);
    margin: 0 0 5px;
}
.guete-begriffe dd { margin: 0; font-size: 13.5px; color: var(--ink2); }

.guete-fuss { margin: 20px 0 0; font-size: 13px; color: var(--ink3); max-width: 72ch; }

/* --- Wie eine verglichene Stunde entsteht ----------------------------
   Gold ist die Vorhersage, Grau die Messung — dieselbe Aufteilung wie bei
   den Zeichnungen im LoRa-Bereich. Die Striche auf der Messlinie sind die
   Stunden: Die Station wartet auf keinen Lauf. */
.gq-kopf {
    font-family: var(--mono); font-size: 11px; fill: var(--ink3);
    letter-spacing: .14em; text-transform: uppercase;
}
.gq-name  { font-family: var(--mono); font-size: 13.5px; fill: var(--ink); }
.gq-zeit  { font-family: var(--mono); font-size: 12px; fill: var(--ink2); }
.gq-fuss  { font-family: var(--mono); font-size: 11.5px; fill: var(--ink3); }

.gq-weg    { fill: none; stroke: var(--gold); stroke-width: 2; }
.gq-pfeil  { fill: var(--gold); }
.gq-punkt  { fill: var(--gold); }
.gq-mess   { fill: none; stroke: var(--ink3); stroke-width: 2; stroke-dasharray: 2 6; stroke-linecap: round; }
.gq-tick   { stroke: var(--ink3); stroke-width: 1.5; }
.gq-kasten { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
.gq-lot    { stroke: var(--ink3); stroke-width: 1; stroke-dasharray: 3 4; }
.gq-linie  { stroke: var(--line); stroke-width: 1; }

ol.stunden {
    display: flex; gap: 2px; margin: 0; padding: 0; list-style: none;
    min-width: min-content;
}
ol.stunden li {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    min-width: 46px; padding: 8px 4px;
    border-right: 1px solid var(--line);
}
ol.stunden li:last-child { border-right: 0; }

.std-zeit  { font-family: var(--mono); font-size: 12px; color: var(--ink3); }
.stunden .wi { width: 22px; height: 22px; }
.std-temp  { font-variant-numeric: tabular-nums; font-size: 14px; }
.std-regen { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink2); }
.std-wahr  { font-family: var(--mono); font-size: 11px; color: var(--ink3); }

.stunden-legende { margin: 10px 0 0; font-size: 12px; color: var(--ink3); }

@media (max-width: 860px) {
    /* Auf schmalen Geraeten fallen Boeen und Risiko weg — Kopf UND Zellen
       zusammen, sonst stuende eine Ueberschrift ohne ihre Spalte da.
       Uebrig bleibt, wonach man zuerst schaut: warm, kalt, nass. */
    table.tage thead th:nth-child(6), table.tage tbody td:nth-child(6),
    table.tage thead th:nth-child(7), table.tage tbody td:nth-child(7) { display: none; }

    /* Der Tag tritt zurueck, damit die Zahlenspalten Luft bekommen. */
    table.tage .sp-tag  { width: 26%; }
    table.tage .sp-zahl { padding-left: 8px; font-size: 14px; }
    .tag-name { font-size: 14px; }

    /* HIER STEHT DIE KURZFORM. „Niederschlag" ist laenger als seine
       Spalte, sobald der Bildschirm schmal wird — ohne Umbruch laufen die
       Ueberschriften ineinander, mit hartem Umbruch wird „NIE DER SCH LAG"
       daraus, und Silbentrennung greift bei Versalien in dieser Schrift
       nicht (nachgesehen). Bleibt das kuerzere Wort. */
    table.tage thead .k-lang { display: none; }
    table.tage thead .k-kurz { display: inline; }

    table.tage thead th { font-size: 10px; letter-spacing: .02em; line-height: 1.3; }
    table.tage thead .sp-einheit { font-size: 9.5px; margin-top: 1px; }
}

/* Eine Warnung ist kein Messwert, sondern eine Ansage. Deshalb ein volles
   Band mit farbigem Rand — dieselbe Machart wie die Luftkachel darunter,
   aber lauter. Die Farbe ist die Stufe des DWD und keine Gestaltung. */
.warnung {
    margin: 0 0 24px; padding: 16px 20px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 3px;
    border-left: 3px solid var(--stufe, var(--ink3));
}
.warnung .warn-kopf { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; margin: 0 0 8px; }
.warnung .warn-kopf strong { color: var(--stufe, var(--ink)); font-size: 16px; }
.warn-zeit    { font-family: var(--mono); font-size: 12px; color: var(--ink3); }
.warn-text    { margin: 0 0 8px; font-size: 14.5px; color: var(--ink2); }
.warn-hinweis { margin: 0 0 8px; font-size: 14px; color: var(--ink2); white-space: pre-line; }
.warn-quelle  { margin: 0; font-size: 12px; color: var(--ink3); }

.warnung.stufe-vorab    { --stufe: #8FA6C4; }
.warnung.stufe-wetter   { --stufe: #D8C13F; }
.warnung.stufe-markant  { --stufe: #E09B3D; }
.warnung.stufe-unwetter { --stufe: #DD6B4D; }
.warnung.stufe-extrem   { --stufe: #A63A4A; }

/* In der Kachel nur die Ueberschrift, als Weg zur ganzen Meldung.
   Unten mehr Luft als oben: Darunter kommt die grosse Temperatur, und die
   soll nicht an der Warnung kleben. */
.tile-warn {
    display: block; margin: 10px 0 16px; padding: 8px 10px;
    border-left: 3px solid var(--stufe, var(--ink3));
    background: color-mix(in srgb, var(--stufe, #888) 12%, transparent);
    color: var(--ink); font-size: 13px; line-height: 1.35; text-decoration: none;
}
.tile-warn:hover { text-decoration: underline; }
/* Was noch nicht gilt, traegt denselben gestrichelten Rand wie auf der
   Warnseite — und die Uhrzeit, ab der es gilt. */
.tile-warn.kommt { border-left-style: dashed; }
.tile-warn-zeit {
    font-family: var(--mono); font-size: 11px; color: var(--ink3);
    white-space: nowrap; margin-left: 6px;
}

.tile-warn.stufe-vorab    { --stufe: #8FA6C4; }
.tile-warn.stufe-wetter   { --stufe: #D8C13F; }
.tile-warn.stufe-markant  { --stufe: #E09B3D; }
.tile-warn.stufe-unwetter { --stufe: #DD6B4D; }
.tile-warn.stufe-extrem   { --stufe: #A63A4A; }

/* Abgesetzt von den eigenen Messwerten: linker Rand statt Kachelraster.
   Diese Zahl kommt nicht aus dem Garten. */
.air {
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 26px;
    align-items: start;
    margin: 0 0 44px; padding: 20px 24px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 3px;
    border-left: 3px solid var(--stufe, var(--ink3));
}

.air-value { display: flex; flex-direction: column; gap: 4px; min-width: 7rem; }
.air-value strong {
    font-family: var(--display); font-size: 2.6rem; font-weight: 700;
    line-height: 1; letter-spacing: -.03em; color: var(--stufe, var(--ink));
    font-variant-numeric: tabular-nums;
}
.air-level { font-family: var(--mono); font-size: 12px; color: var(--stufe, var(--ink2)); }
.air-unit  { font-family: var(--mono); font-size: 12px; color: var(--ink3); }

.air-detail p { margin: 0 0 10px; font-size: 14.5px; color: var(--ink2); }
.air-detail dl {
    display: flex; flex-wrap: wrap; gap: 8px 26px; margin: 0 0 12px;
    font-family: var(--mono); font-size: 12.5px;
}
.air-detail dl > div { display: flex; gap: 8px; }
.air-detail dt { color: var(--ink3); }
.air-detail dd { margin: 0; font-variant-numeric: tabular-nums; }

.air-source { font-size: 12px !important; color: var(--ink3) !important; line-height: 1.5; }

/* Die Skala hat eine eingefuehrte Lesart — wie bei den Klimastreifen traegt
   die Farbe hier die Bedeutung und nicht die Gestaltung. Gedaempft, damit
   sie auf dunklem Grund nicht schreit. */
.air.level-good,           .tile-air.level-good           { --stufe: #5BC8BE; }
.air.level-fair,           .tile-air.level-fair           { --stufe: #6FBF8B; }
.air.level-moderate,       .tile-air.level-moderate       { --stufe: #D8C13F; }
.air.level-poor,           .tile-air.level-poor           { --stufe: #DD6B4D; }
.air.level-very-poor,      .tile-air.level-very-poor      { --stufe: #A63A4A; }
.air.level-extremely-poor, .tile-air.level-extremely-poor { --stufe: #8B4A9C; }

/* In der Kachel traegt die Stufe ihre Farbe wie die Windrichtung ihr Gold:
   ein Zusatz zum Wert. Anders als dort bedeutet die Farbe hier etwas —
   deshalb die Stufenfarbe und nicht das Gold. */
.tile-air .stufe { color: var(--stufe, var(--gold)); }

@media (max-width: 700px) {
    .air { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------------------------------------------------------------- */
/* Ein Graph je Zeitraum                                            */
/*                                                                  */
/* Der Zeitraum steht in derselben Ueberschrift wie der Titel, nur  */
/* leiser — er ist die Naeherbestimmung, nicht die Sache selbst.    */
.graphs h2 .zeitraum {
    color: var(--ink4, var(--ink3));
    opacity: .7;
}
/* Eckige Klammern: Der Zeitraum ist eine Naeherbestimmung, keine
   Fortsetzung des Titels. Ein Mittelpunkt las sich wie eine Aufzaehlung
   zweier gleichrangiger Dinge. */
.graphs h2 .zeitraum::before { content: "["; }
.graphs h2 .zeitraum::after  { content: "]"; }

/* Zuordnung und Regensumme stehen in einer Zeile. Der Abstand
   trennt sie, ohne einen Punkt oder Strich dafuer zu brauchen. */
.legend .legend-regen { margin-left: 1.6em; }

/* Die Spannen der Zusatzlinien: je Messwert ein Stueck, in seiner
   Farbe. Sie ersetzen die Achsen, die im Bild keinen Platz haben —
   ohne sie waere die Hoehe einer Linie eine leere Behauptung. */
.legend.spannen {
    display: flex; flex-wrap: wrap; gap: 4px 1.6em;
    margin-bottom: 38px;
}

/* Die Zuordnungszeile steht direkt ueber den Spannen und gibt ihren
   Abstand ab — sonst klafft eine Luecke zwischen zwei Zeilen, die
   zusammengehoeren. */
.legend.zuord { margin-bottom: 6px; }
.spanne-temp     { color: var(--gold); }
.spanne-rain     { color: var(--teal); }
.spanne-pressure { color: var(--mess-pressure); }
.spanne-humidity { color: var(--mess-humidity); }
.spanne-wind     { color: var(--mess-wind); }
.spanne-gust     { color: var(--mess-gust); }
.spanne-lux      { color: var(--mess-lux); }

/* Die Zusatzlinien duenner als die Temperatur: Sie hat die Achse,
   also gehoert ihr das Gewicht. */
.graph .line.zusatz { stroke-width: 1.4; opacity: .9; }
.graph .line.zusatz.mini-pressure { stroke: var(--mess-pressure); }
.graph .line.zusatz.mini-humidity { stroke: var(--mess-humidity); }
.graph .line.zusatz.mini-wind     { stroke: var(--mess-wind); }
.graph .line.zusatz.mini-gust     { stroke: var(--mess-gust); }
.graph .line.zusatz.mini-lux      { stroke: var(--mess-lux); }


/* Die Skalen rechts: je Zusatzlinie eine Spalte in ihrer Farbe. */
.graph .achse { stroke-width: 1; opacity: .55; }
.graph .achse-pressure { stroke: var(--mess-pressure); }
.graph .achse-humidity { stroke: var(--mess-humidity); }
.graph .achse-wind     { stroke: var(--mess-wind); }
.graph .achse-gust     { stroke: var(--mess-gust); }
.graph .achse-lux      { stroke: var(--mess-lux); }

/* Die gemeinsame Skala von Wind und Boeen traegt den Namen der Gruppe,
   nicht den einer Linie — ohne eigene Regel blieb sie grau, waehrend
   Luftdruck und Luftfeuchte ihre Farbe hatten. Sie bekommt die des
   Windes: Die Boee ist dessen Spitze, nicht die Hauptsache. */
.graph .achse-wind_gust { stroke: var(--mess-wind); }
.graph .ylab.achse-wind_gust { fill: var(--mess-wind); }
.graph .ylab.achse-pressure { fill: var(--mess-pressure); }
.graph .ylab.achse-humidity { fill: var(--mess-humidity); }
.graph .ylab.achse-wind     { fill: var(--mess-wind); }
.graph .ylab.achse-gust     { fill: var(--mess-gust); }
.graph .ylab.achse-lux      { fill: var(--mess-lux); }
.graph .ylab[class*="achse-"] { font-size: 10px; }

/* Die Wahl im Vergleich sind VERWEISE, keine Knoepfe: Jede Ansicht hat
   ihre eigene Adresse, laesst sich verlinken und funktioniert ohne
   JavaScript. Aussehen wie die Spannen daneben — gleiche Bedienung,
   gleiches Bild. */
.legend.vergleichwahl { display: flex; flex-wrap: wrap; gap: 6px 18px; }

.legend.vergleichwahl .wahl {
    color: var(--ink3); text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.legend.vergleichwahl a.wahl:hover { color: var(--ink); border-bottom-style: solid; }
.legend.vergleichwahl a.wahl:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; }

/* Die laufende Wahl ist kein Verweis mehr — sie ist der Zustand. */
.legend.vergleichwahl .wahl.an { color: var(--gold); border-bottom-style: solid; }

/* Die Spannen sind Schalter. Sie sehen aus wie Text, weil sie einer
   sind — nur der Zeiger und der abgeschaltete Zustand verraten, dass
   man sie anfassen kann. */
.legend.spannen .spanne {
    font: inherit; background: none; border: 0; padding: 0;
    cursor: pointer; border-bottom: 1px dotted currentColor;
}
.legend.spannen .spanne:hover { border-bottom-style: solid; }
.legend.spannen .spanne:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; }

/* Abgeschaltet: die Beschriftung verblasst, sie verschwindet nicht —
   sonst wuesste niemand mehr, wie man die Linie zurueckholt. */
.legend.spannen .spanne[aria-pressed="false"] {
    color: var(--ink3); opacity: .5; border-bottom-style: dashed;
}

/* Und im Bild verschwinden Linie UND Skala gemeinsam: eine Achse ohne
   ihre Linie ist eine Beschriftung fuer nichts. */
/* Die Temperatur nimmt beim Ausblenden ihr Band und ihre Gradzahlen mit.
   Die Gitterlinien bleiben: Sie geben nur waagerechte Orientierung und
   gehoeren keiner Kurve allein. */
/* Der Niederschlag nimmt beim Ausblenden seine Balken mit. */
.crosshair.aus-rain .graph .rain,
.crosshair.aus-temp .graph .line.high,
.crosshair.aus-temp .graph .line.low,
.crosshair.aus-temp .graph .band,
.crosshair.aus-temp .graph .ylab:not([class*="achse-"]),
.crosshair.aus-pressure .mini-pressure,
.crosshair.aus-pressure .achse-pressure,
.crosshair.aus-humidity .mini-humidity,
.crosshair.aus-humidity .achse-humidity,
.crosshair.aus-wind .mini-wind,
.crosshair.aus-wind .achse-wind,
.crosshair.aus-gust .mini-gust,
.crosshair.aus-gust .achse-gust,
.crosshair.aus-lux .mini-lux,
.crosshair.aus-lux .achse-lux { display: none; }

/* Die Ableseliste zieht mit: Ein Wert, den man ausgeblendet hat, soll
   beim Ueberfahren nicht doch wieder auftauchen. */
/* In der Ableseliste faellt mit der Temperatur auch ihre Spanne weg —
   Hoechst- und Tiefstwert sind die Raender des Bandes, das gerade nicht
   mehr da ist. */
.crosshair.aus-rain .rd-rain, .crosshair.aus-rain .rd-rain + dd,
.crosshair.aus-temp .rd-temp, .crosshair.aus-temp .rd-temp + dd,
.crosshair.aus-temp .rd-temp_max, .crosshair.aus-temp .rd-temp_max + dd,
.crosshair.aus-temp .rd-temp_min, .crosshair.aus-temp .rd-temp_min + dd,
.crosshair.aus-pressure .rd-pressure, .crosshair.aus-pressure .rd-pressure + dd,
.crosshair.aus-humidity .rd-humidity, .crosshair.aus-humidity .rd-humidity + dd,
.crosshair.aus-wind .rd-wind, .crosshair.aus-wind .rd-wind + dd,
.crosshair.aus-gust .rd-gust, .crosshair.aus-gust .rd-gust + dd,
.crosshair.aus-lux .rd-lux, .crosshair.aus-lux .rd-lux + dd { display: none; }

/* Der Nachtrag unter dem Tagesgraphen: erklaert, warum heute dort fehlt.
   Leiser als die Legende darueber — er ist eine Fussnote, keine Angabe
   zum Bild. */
.legend.nachtrag {
    color: var(--ink3); opacity: .8; max-width: 46rem;
    margin-top: -26px; margin-bottom: 38px;
}

/* Die angebrochene Stunde: Was in diesem Streifen liegt, waechst noch.
   Blass genug, dass es die Kurven nicht stoert — es ist eine Auskunft
   ueber den Rand des Bildes, keine eigene Aussage. */
.graph .teilstunde { fill: var(--ink1, #e8e6e1); opacity: .045; }

/* ---------------------------------------------------------------- */
/* Bilder einer Konstruktion                                         */
/*                                                                   */
/* Hauptbild links, die Voransichten senkrecht daneben. Beide in     */
/* FESTER GROESSE — und das ist der ganze Punkt: Vorher richtete     */
/* sich die Hoehe nach dem gerade gezeigten Foto, und weil jedes ein */
/* eigenes Seitenverhaeltnis mitbringt, sprang beim Ueberfahren die  */
/* halbe Seite. Eine Reihe, die man durchfahren soll, darf sich      */
/* dabei nicht bewegen.                                              */
/*                                                                   */
/* 4:3 als Grundlage: Alle sechs Aufmacher sind 1200x900, und die    */
/* Fotos von den Portalen sind es auch. Ein Hochformat passt sich    */
/* ein, statt den Rahmen zu sprengen — mit Rand statt Beschnitt,     */
/* denn bei einem gedruckten Teil ist der Rand des Fotos oft die     */
/* Information (wie gross ist es, woran haengt es).                  */
.bilder {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--blattbreite);
    gap: 12px;
    margin: 0 0 40px;

    /* Aufeinander abgestimmt: Sechs Blaetter — der Aufmacher und fuenf
       Fotos — passen genau in die Hoehe des Bildes daneben, ohne zu
       rollen. 6 x 75 px plus fuenf Abstaende zu 8 sind 490 von 500.
       Kommt ein siebtes dazu, rollt die Spalte; die Bildhoehe bleibt. */
    --bildhoehe: 500px;
    --blattbreite: 100px;
}

.bilder .shot {
    margin: 0;
    height: var(--bildhoehe);
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 3px;
    overflow: hidden;
}

.bilder .shot img {
    display: block; width: 100%; height: 100%;
    object-fit: contain;
    border: 0; border-radius: 0;
}

/* Die Voransichten: senkrecht, alle gleich gross. Passt eine mehr
   nicht hinein, rollt die Spalte — die Bildhoehe bleibt, was sie ist. */
.streifen {
    display: flex; flex-direction: column; gap: 8px;
    height: var(--bildhoehe);
    overflow-y: auto;
    scrollbar-width: thin;
}

/* Breite aus der Spalte, Hoehe aus dem Verhaeltnis — nicht beides fest.
   Mit fester Breite entstand neben der senkrechten Rollleiste auch noch
   eine waagerechte: Die Blaetter waren dann breiter als der Platz, der
   nach Abzug der Leiste blieb. */
.blatt {
    display: block; flex: 0 0 auto;
    width: 100%; aspect-ratio: 4 / 3;
    border: 1px solid var(--line); border-radius: 3px;
    overflow: hidden; opacity: .62;
    transition: opacity .12s ease, border-color .12s ease;
}

/* Hier schneidet der Ausschnitt, und das ist richtig: Ein Blatt ist
   ein Wiedererkennungszeichen, kein Bild zum Betrachten. */
.blatt img { display: block; width: 100%; height: 100%; object-fit: cover; }

.blatt:hover, .blatt:focus-visible { opacity: 1; border-color: var(--ink3); }
.blatt:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.blatt[aria-current="true"] { opacity: 1; border-color: var(--gold); }

/* Schmaler Schirm: Die Spalte wandert unter das Bild und legt sich
   quer. Senkrecht neben einem 300 px breiten Foto waere sie breiter
   als das, was sie zeigt. */
@media (max-width: 700px) {
    .bilder {
        grid-template-columns: minmax(0, 1fr);
        --bildhoehe: 260px;
        --blattbreite: 104px;
    }

    .streifen {
        flex-direction: row; height: auto;
        overflow-x: auto; overflow-y: hidden;
    }
}

@media (prefers-reduced-motion: reduce) {
    .blatt { transition: none; }
}

/* ------------------------------------------------------- Die Datumsbox
   Tag und Monat oben, das Jahr darunter — zweifarbig in den Hausfarben:
   Gold trägt das Datum, der dunkle Sockel das Jahr. Das Jahr ändert sich
   selten und darf zurücktreten; der Tag ist das, wonach man sucht.

   Die Ziffern stehen in Tabellenbreite (`tabular-nums`), damit
   untereinander stehende Daten dieselbe Breite haben und die Boxen nicht
   um einen Pixel wackeln. */
.datumsbox {
    display: grid; justify-items: center;

    /* `align-self`, nicht `align-content`: Das Erste sagt, wie hoch die
       Box in IHRER Zeile steht, das Zweite nur, wie ihr Inhalt darin
       sitzt. Ohne das streckte sie sich ueber die ganze Notiz — bei der
       ersten waren das 674 statt 50 Pixel. */
    align-self: start;
    width: 5.5rem;
    border: 1px solid var(--gold); border-radius: 3px;
    overflow: hidden;
    font-family: var(--mono); font-variant-numeric: tabular-nums;
    line-height: 1;
}

.datumsbox .tagmonat {
    display: block; width: 100%;
    background: var(--gold); color: #15191A;
    padding: 7px 0 6px;
    font-size: 14px; font-weight: 600; letter-spacing: .02em;
    text-align: center;
}

.datumsbox .jahr {
    display: block; width: 100%;
    background: var(--surface2); color: var(--gold);
    padding: 5px 0;
    font-size: 11.5px; letter-spacing: .12em;
    text-align: center;
}

/* Auf schmalen Bildschirmen steht das Datum ueber dem Text — dann soll es
   nicht die halbe Zeile fuellen. */
@media (max-width: 700px) {
    .datumsbox { width: auto; justify-self: start; grid-auto-flow: column; }
    .datumsbox .tagmonat, .datumsbox .jahr { padding-left: 10px; padding-right: 10px; }
}

/* Bilder im Text einer Notiz laufen nicht über die ganze Textbreite.
   Gemessen an der ersten Notiz: Das Foto des Halters nahm bei voller
   Breite 678×509 Pixel ein — vierzig Prozent der Höhe des ganzen
   Eintrags, mehr als der Text. Eine Notiz soll kurz WIRKEN, und das tut
   sie nicht, wenn man dreimal scrollen muss.

   Der Wert ist kein Rundungsergebnis: Bei 26rem bleibt das Foto groß
   genug, um den Halter samt Flaschen zu erkennen, und spart gegenüber der
   vollen Breite rund zweihundert Pixel. */
.notes > li .prose img { max-width: 26rem; }

/* ------------------------------------------------------- Blog: Uebersicht */

/* DIE INHALTSLISTE BEKOMMT EIN FESTES MASS, DER TEXT DEN REST.

   Zuerst standen hier zwei Drittel zu einem — Dirks Vorgabe, und als
   Aufteilung richtig gedacht. Nur waechst ein Drittel mit dem Schirm mit:
   Auf 1440 Pixel waren das 400 fuer eine Liste aus Titeln, Kategorien und
   Jahreszahlen, die keine 300 braucht. Was dort ungenutzt stand, fehlte dem
   Anriss daneben.

   16rem sind gemessen, nicht geschaetzt: Der laengste Titel, der hier
   realistisch steht („KNX, Modbus und MQTT an einem Strang"), braucht darin
   zwei Zeilen — genauso viele wie in 18rem. Die Textspalte gewinnt damit auf
   1440 Pixeln 152 Pixel, von 800 auf 952.

   `minmax(0, 1fr)` statt `1fr`: Ohne die Null nimmt eine Rasterspalte als
   kleinste Breite den Inhalt, und ein langes Wort im Anriss haette die
   Spalte aufgeblaeht, statt umzubrechen. */
.blog-raster {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 16rem;
    gap: 40px;
    align-items: start;
}

/* Die Vollansicht eines Artikels: DATUM GANZ LINKS, INHALTSLISTE GANZ
   RECHTS, TEXT FUELLT DIE MITTE — Dirks Vorgabe, und damit ist die lange
   Rechnerei um den ueberschuessigen Platz erledigt.

   Vorher war die mittlere Spur `minmax(0, 68ch)`, also das Lesemass. Was
   darueber hinaus blieb, musste irgendwo liegen, und alle drei Stellen
   waren nacheinander da: zwischen Text und Liste (ein Loch mitten im
   Satz), mittig verteilt (die Liste wanderte vom Seitenrand nach innen),
   links vor dem Text (der Text verlor die Flucht mit Kopfzeile und
   Krume). Jetzt gibt es keinen Ueberschuss mehr: `1fr` nimmt ihn auf.

   Der Preis steht ausdruecklich hier: Die Zeile wird laenger, als das
   Lesemass vorsieht. Gemessen sind es auf dem breitesten Bogen 756 Pixel,
   also rund 94 Zeichen statt 89 — fuenf mehr, und mehr kann es nicht
   werden, weil `--wrap` die Seite vorher begrenzt. */
.blog-einzeln {
    max-width: 78rem;
    margin-inline: auto;

    /* Die erste Spur ist genau die der Datumsbox (`.datumsbox { width }`),
       die letzte die der Inhaltsliste; dazwischen alles, was bleibt.

       `column-gap: 28px` ist der Abstand der Notizen und der Uebersicht —
       damit steht der Titel beim Klick auf „Weiterlesen" an derselben
       Stelle wie in der Liste. Zur Inhaltsliste sollen es die 40 der
       Uebersicht sein; die fehlenden zwoelf traegt sie selbst. */
    grid-template-columns: 5.5rem minmax(0, 1fr) 16rem;
    column-gap: 28px;
}

/* UND DER TEXT MUSS SEINE SPALTE AUCH AUSFUELLEN DUERFEN.
   `.prose` und `.prose p` tragen sonst 68ch. Ohne diese Zeile waere die
   Spalte zwar breiter, der Satz darin aber gleich schmal — das Loch waere
   nur vom Rand in den Text gewandert. */
.blog-einzeln .prose,
.blog-einzeln .prose :is(p, li, h2, h3, blockquote) { max-width: none; }

/* Die Krume gehoert zu keiner der drei Spalten, sondern zur Seite. */
.blog-einzeln > .krume { grid-column: 1 / -1; }

.blog-einzeln > .blogseite { margin-left: 12px; }

/* IM ZWEISPALTIGEN SATZ GIBT ES KEINEN AUSBRUCH.
   `.prose img[title~="breit"]` zieht ein Schaubild auf die volle
   Seitenbreite — neben einer Inhaltsliste liefe es ueber sie hinweg. */
.blog-einzeln .prose img[title~="breit"] { width: 100%; max-width: 100%; }

/* Ein Beitrag: Datumsbox links, alles andere rechts daneben — dieselbe
   Aufteilung wie bei den Lab Notes, damit beide Listen zusammengehoeren. */
.beitrag {
    display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: 28px;
    padding: 28px 0; border-top: 1px solid var(--line);
}
.beitrag:first-child { border-top: 0; padding-top: 0; }

/* `:last-of-type`, NICHT `:last-child`: Das letzte Kind des Stroms ist die
   Blaetterung, nicht der letzte Beitrag — die Schlusslinie waere nie
   erschienen. Bei `.entries` und `.notes` steht nichts hinter der Liste,
   dort faellt der Unterschied nicht auf. */
.beitrag:last-of-type { border-bottom: 1px solid var(--line); }

.beitrag h2 {
    font-family: var(--display); font-size: 1.45rem; font-weight: 600;
    letter-spacing: -.015em; margin: 0;
}
.beitrag h2 a { color: var(--ink); text-decoration: none; }
.beitrag h2 a:hover { color: var(--gold); }

/* Die Kategorie steht dicht unter dem Titel: Sie gehoert zu ihm, nicht
   zum Text. Der Ordner ist so gross wie die Zeile und nimmt ihre Farbe. */
.beitrag-rubrik {
    display: flex; align-items: center; gap: 7px;
    font-family: var(--mono); font-size: 11.5px;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--ink3); margin: 6px 0 0;
}
/* IM ARTIKEL GEWINNT SONST `.prose p`. Die Zeile steht dort in einem
   `.prose`-Block, und `.prose p { margin: 0 0 20px }` ist spezifischer als
   `.beitrag-rubrik` — ohne diese Regel klebte die Kategorie nicht am Titel,
   sondern schwebte im Absatzabstand. Unter einer h1 darf es etwas mehr Luft
   nach unten sein als unter der h2 der Liste. */
.prose > .beitrag-rubrik { margin: 10px 0 26px; }

.beitrag-rubrik .ordner { flex: none; }
.beitrag-rubrik a { color: var(--ink2); text-decoration: none; }
.beitrag-rubrik a:hover { color: var(--gold); }

/* Links der Anriss, rechts Aufmacher und Knopf — SOLANGE BEIDES PASST.

   Als festes Raster (`1fr 15rem`) standen hier auf einem 1100 Pixel breiten
   Fenster drei Spalten nebeneinander: Datumsbox, Anriss, Aufmacher. Fuer den
   Anriss blieben **314 Pixel**, also rund dreissig Zeichen je Zeile — sieben
   Zeilen fuer einen Satz, der in dreien haette stehen koennen. Gepresst.

   Deshalb kein Raster, sondern ein umbrechender Flexkasten: Der Anriss will
   26rem haben, der Aufmacher 15rem. Passt beides samt Abstand nicht mehr in
   die Zeile, rutscht der Aufmacher unter den Text und der Text bekommt die
   ganze Breite. Kein Bruchpunkt, den man raten muesste — die Zeile rechnet
   selbst nach.

   Gemessen: bei 1100 Pixeln umbrochen, Anriss 563 statt 314; bei 1440
   nebeneinander mit 572. */
.beitrag-koerper {
    display: flex; flex-wrap: wrap; gap: 24px;
    align-items: flex-start; margin-top: 16px;
}

/* Anriss und Knopf sind EIN Block — der Knopf gehoert zum Text, nicht zum
   Bild. Er stand unter dem Aufmacher rechts; bei einem Beitrag ohne Bild
   hing er dort allein in der Luft, und bei einem mit Bild stand der Weg
   ins Lesen ausgerechnet nicht am Text. */
.beitrag-text {
    flex: 1 1 26rem;
    display: flex; flex-direction: column; align-items: flex-start; gap: 18px;
}

.beitrag-anriss { margin: 0; color: var(--ink2); font-size: 16px; max-width: 58ch; }



/* IMMER 4:3, egal was das Bild mitbringt. Die Aufmacher sind mal quer,
   mal fast quadratisch — ohne festes Verhaeltnis haette jeder Beitrag eine
   andere Hoehe, und die Liste haette gewackelt. `cover` beschneidet, statt
   zu verzerren. */
.beitrag-bild {
    flex: 0 1 15rem;
    display: block; width: 15rem; line-height: 0;
    border-radius: 3px; overflow: hidden;
}
.beitrag-bild img {
    display: block; width: 100%; height: auto;
    aspect-ratio: 4 / 3; object-fit: cover;
}

/* Zurueck und weiter an die Raender, die Seitenzahl in die MITTE — und die
   bleibt auch dann mittig, wenn eine Seite nur einen der beiden Knoepfe hat.
   Mit blossem `space-between` rutschte sie auf Seite 1 nach links, weil das
   leere linke Feld keine Breite hatte. */
.blaettern { justify-content: space-between; }
.blaettern .links, .blaettern .rechts { display: inline-flex; flex: 1; }
.blaettern .rechts { justify-content: flex-end; }

/* ---------------------------------------------------- Blog: Inhaltsliste */

.blogseite { display: grid; gap: 34px; align-content: start; }

.blogseite-block h2 {
    font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
    text-transform: uppercase; color: var(--ink3);
    margin: 0 0 12px; padding-bottom: 9px;
    border-bottom: 1px solid var(--line);
}

.blogseite-liste { list-style: none; padding: 0; margin: 0; }
.blogseite-liste li { padding: 7px 0; }
.blogseite-liste a { color: var(--ink2); text-decoration: none; }
.blogseite-liste a:hover { color: var(--gold); }

/* Der letzte Beitrag steht abgesetzt — die feine Linie trennt ihn von den
   aelteren. Ein Kasten waere zu viel: Es ist derselbe Beitrag wie die
   anderen, nur der juengste. */
.blogseite-liste .jung { padding-bottom: 13px; border-bottom: 1px solid var(--line); }
.blogseite-liste .jung a { color: var(--ink); }

.blogseite-liste time {
    display: block; font-family: var(--mono); font-size: 11px;
    color: var(--ink3); font-variant-numeric: tabular-nums; margin-top: 3px;
}

/* Kategorien und Jahre: Name links, Anzahl rechts. */
.blogseite-liste.schlagworte li {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.blogseite-liste .anzahl {
    font-family: var(--mono); font-size: 11px; color: var(--ink3);
    font-variant-numeric: tabular-nums;
}
.blogseite-liste .hier { color: var(--gold); }

.blogseite-alle { margin: 0; font-family: var(--mono); font-size: 12px; }

/* Auf schmalen Schirmen steht die Inhaltsliste unter den Beitraegen. Sie
   kommt im Quelltext ohnehin dort — das Raster fuellt nur auf. */
@media (max-width: 900px) {
    .blog-raster, .blog-einzeln { grid-template-columns: minmax(0, 1fr); gap: 44px; }
    .blog-einzeln > .blogseite { margin-left: 0; }

    /* `flex-basis` MIT, nicht nur `width`: Bei einem Flexkasten gewinnt die
       Basis, und `width: 22rem` allein blieb wirkungslos — das Bild stand
       auf dem Telefon in 15rem statt in 22. */
    .beitrag-bild { flex-basis: 22rem; width: 22rem; max-width: 100%; }
}

@media (max-width: 700px) {
    .beitrag { grid-template-columns: 1fr; gap: 14px; }
}

/* Der Aufmacher in der Vollansicht eines Artikels — auf die Textbreite,
   nicht auf die Spaltenbreite. Er steht zwischen Vorspann und Fliesstext
   und soll mit beiden fluchten; ein Bild, das rechts ueber den Text
   hinausragt, sieht aus wie ein Fehler, nicht wie eine Betonung. */
.post-cover { margin: 0 0 32px; }

/* `width: auto`, und zwar AUSDRUECKLICH. Es genuegt nicht, hier kein
   `width` zu setzen: Der Aufmacher steht in `.prose`, und `.prose img`
   traegt `width: 100%` — dieselbe Spezifitaet, nur weiter oben. Ohne
   Gegenwert bleibt es stehen.
   Und es rechnet hoch: Beim ersten Versuch war der Aufmacher ein 256 Pixel
   breites Bildzeichen, ueber die Textbreite gezogen — 710 Pixel, fast
   dreifach vergroessert und entsprechend weich. Der Kern rechnet nie hoch,
   das Stylesheet soll es auch nicht tun.
   Rahmen und Radius kommen von `.prose img` und bleiben; nur die Abstaende
   sitzen an der `figure`, nicht zweimal. */
.post-cover img {
    display: block;
    width: auto; max-width: 100%; height: auto;
    margin: 0;
}

/* ------------------------------------------------- Kontakt und Kopfzeichen */

/* Kontakt und Suche stehen als Zeichen in der Kopfzeile, nicht als Wort.
   Sie sitzen im selben Flexkasten wie die Navigation und bekommen etwas
   mehr Abstand nach links: Sie gehoeren nicht in die Reihe der Rubriken,
   sie stehen daneben. */
.kopfzeichen {
    display: inline-flex; align-items: center; gap: 14px;
    margin-left: 8px; padding-left: 18px;
    border-left: 1px solid var(--line);
}

.kopfzeichen a {
    display: inline-flex; color: var(--ink2);
    padding: 4px; border-radius: 2px;
}
.kopfzeichen a:hover, .kopfzeichen a:focus-visible { color: var(--gold); }
.kopfzeichen svg { display: block; }

/* Auf schmalen Fenstern bricht die Navigation ohnehin um — dann steht die
   Trennlinie quer und die Zeichen ruecken an den Anfang der neuen Zeile. */
@media (max-width: 1000px) {
    .kopfzeichen { margin-left: 0; padding-left: 0; border-left: 0; }
}

/* ------------------------------------------------------ Kontaktformular */

.kontakt { max-width: 46rem; }

.kontaktform { display: grid; gap: 22px; margin-top: 8px; }

.feld { display: grid; gap: 7px; margin: 0; }

.feld label {
    font-family: var(--mono); font-size: 11.5px;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink3);
}

/* Auf breiten Fenstern stehen Name und Mailadresse nebeneinander: Beide
   sind kurz, und untereinander waere das Formular unnoetig lang. */
.feldpaar { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 22px; }

.kontaktform input,
.kontaktform select,
.kontaktform textarea {
    width: 100%; min-height: 44px;
    font-family: var(--body); font-size: 17px; color: var(--ink);
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 2px; padding: 11px 14px;
}

.kontaktform textarea { min-height: 12rem; resize: vertical; line-height: 1.55; }

.kontaktform input:focus, .kontaktform select:focus, .kontaktform textarea:focus {
    border-color: var(--gold); outline: none;
}

/* Ein Pflichtfeld, das der Browser als leer oder falsch ansieht, faerbt
   sich erst nach dem ersten Absendeversuch — `:invalid` allein faerbte
   schon beim Laden alles rot, bevor jemand etwas falsch gemacht hat. */
.kontaktform :user-invalid { border-color: #C97070; }

.formfuss { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 22px; }
.formfuss .hinweis { margin: 0; flex: 1 1 20rem; font-size: 14px; color: var(--ink3); }

.formfehler {
    margin: 0 0 22px; padding: 12px 16px;
    background: #3A1C1C; border: 1px solid #7A3A3A; border-radius: 2px;
    color: #F0C4C4; font-size: 15px;
}

.quittung {
    margin: 0; padding: 16px 20px;
    background: var(--gold-dim); border: 1px solid var(--gold); border-radius: 2px;
    color: var(--gold); font-size: 16px;
}

/* DER HONIGTOPF. Er muss aus dem Bild, aber nicht aus dem Quelltext — ein
   Roboter fuellt aus, was er findet, ein Mensch sieht es nie.
   `display: none` waere die naheliegende Wahl und die schlechtere: Manche
   Ausfuellhilfen ueberspringen verborgene Felder nicht, wohl aber solche,
   die weit ausserhalb liegen. */
.honigtopf {
    position: absolute; left: -9999px;
    width: 1px; height: 1px; overflow: hidden;
}
