/* ==========================================================================
   stratdata — OSINT-Arbeitsplatz
   Gleiche Marke wie die Webseite: Syne + DM Sans, Navy-Tinte, Verlauf
   Violett→Blau, runde Flächen, weiche Schatten. Hell ist die Vorgabe;
   die dunkle Variante bleibt für lange Sitzungen erhalten.
   Schriften liegen lokal — nie eine Anfrage an Google.
   ========================================================================== */

/* ── Schriften ───────────────────────────────────────────────────────────────
   Hier steht nur, was auch wirklich in assets/fonts/ liegt.

   Der Auftrag nannte eine variable DM Sans mit Gewichtsachse 300-700 und dem
   Latin-Ext-Bereich. Beides deckt sich nicht mit dem Bestand, und beides waere
   als Einbindung schaedlich: die zwei DM-Sans-Dateien fuehren zwar eine
   Variationsachse, aber nur opsz (optische Groesse 9-40) und keine wght — ihr
   Gewicht ist fest 400 beziehungsweise 500. Stuende "font-weight:300 700" an
   der 400er-Datei, holte der Browser sie fuer jede Stufe dazwischen und die
   echte Medium bliebe unbenutzt. Und die Dateien sind der Latin-Teilbereich:
   von den 1162 Zeichen des genannten Latin-Ext-Bereichs enthalten sie sechs —
   mit jenem unicode-range fiele der gesamte gewoehnliche Text auf Helvetica
   zurueck. Darum je Datei ein Gewicht, und ein unicode-range, der die
   tatsaechliche Abdeckung genau umschliesst. Nachgeladen wird nichts: keine
   Anfrage an Google, das ist Absicht und nicht Bequemlichkeit. */
/* DM Sans als VARIABLE Schrift mit Gewichtsachse 300–700.
   Vorher lagen hier zwei feste Schnitte (400 und 500). Alles dazwischen und
   alles darüber musste der Browser fälschen — er zieht die Buchstaben dann
   künstlich in die Breite, was die Formen verzerrt. Deshalb stand in den
   Rechtsseiten der Vermerk «700 würde der Browser fälschen»; mit der
   Gewichtsachse ist das erledigt und 600 wie 700 sind echte Schnitte.
   Zwei Teilbereiche: latin lädt immer, latin-ext nur, wenn ein Zeichen daraus
   wirklich vorkommt — der Browser entscheidet das anhand der unicode-range,
   und ein deutscher Text braucht ihn selten. */
@font-face{font-family:'DM Sans';src:url(../fonts/dmsans-var-latin.woff2)format('woff2');
  font-style:normal;font-weight:300 700;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'DM Sans';src:url(../fonts/dmsans-var-latin-ext.woff2)format('woff2');
  font-style:normal;font-weight:300 700;font-display:swap;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Syne;src:url(../fonts/syne-600.woff2)format('woff2');font-style:normal;font-weight:600;font-display:swap;unicode-range:U+0000-00FF,U+0102,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0300-0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Syne;src:url(../fonts/syne-700.woff2)format('woff2');font-style:normal;font-weight:700;font-display:swap;unicode-range:U+0000-00FF,U+0102,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0300-0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Syne;src:url(../fonts/syne-800.woff2)format('woff2');font-style:normal;font-weight:800;font-display:swap;unicode-range:U+0000-00FF,U+0102,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0300-0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* Platz für die Scrollleiste IMMER freihalten. Ohne das ist eine kurze Seite
   1440 px breit und eine lange 1430 — beim Wechsel rutscht die komplette
   Seite samt Menü um die Leistenbreite zur Seite. Genau dieses Zucken liest
   sich als «mal so, mal so ausgerichtet». */
html{scrollbar-gutter:stable}

:root{
  /* Überschriften laufen jetzt in DM Sans, nicht mehr in Syne.
     Syne ist eine Plakatschrift: sehr weite Versalien, ungewöhnliche
     Formen, im Gewicht 800 sehr dominant. Als Zeile über einem Absatz
     funktioniert das, über einer ganzen Anwendung erschlägt es den
     Inhalt — und lange deutsche Wörter brechen darin über drei Zeilen.
     Mit der Gewichtsachse 300-700 kann DM Sans beides: ruhiger Text
     bei 400 und tragende Überschrift bei 700, aus EINER Schriftdatei
     und ohne zweiten Netzabruf. Syne bleibt als Ersatz stehen, damit
     nichts bricht, falls die Variable einmal nicht lädt. */
  --display:'DM Sans',Syne,"Avenir Next",system-ui,sans-serif;
  --font:'DM Sans',"Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:Menlo,Monaco,"DejaVu Sans Mono",Consolas,monospace;

  /* Ziffernschrift. DM Sans bringt in diesem Ausschnitt weder das tnum-Merkmal
     noch gleich breite Ziffern mit — die 1 ist mit 342 Einheiten knapp halb so
     breit wie die 0 mit 656. Ein Zaehler in DM Sans springt deshalb bei jeder
     Aenderung, und font-variant-numeric allein aendert daran nichts, weil das
     Merkmal in der Datei fehlt. Wo Zahlen untereinander stehen oder laufend
     neu geschrieben werden, ist die Zeile nur mit einer Schrift ruhig zu
     halten, die gleiche Ziffernbreiten garantiert. Syne hat tnum und wird
     deshalb dort belassen, wo Zahlen ohnehin im Titelschnitt stehen. */
  --num:var(--mono);

  /* ── Schrifttreppe ─────────────────────────────────────────────────────────
     Dieselbe Reihe wie auf der Verkaufsseite (site/assets/css/site.css). Die
     kleinen Stufen haengen als feste Verhaeltnisse am Grundmass --fs-base,
     nicht an absoluten Pixeln: so bleiben die Abstaende zwischen den Stufen
     auf beiden Flaechen gleich, obwohl der Arbeitsplatz insgesamt dichter
     gesetzt ist als die Verkaufsseite. Nur das Grundmass selbst unterscheidet
     sich — dort rund 15-16.5px, hier rund 13.5px.
     Die Ueberschriften brauchen eine eigene Reihe, weil sie mit der
     Fensterbreite wachsen muessen und nicht mit der Textgroesse; --type-scale
     verdichtet diese Reihe hier um einen einzigen Faktor, statt jede Stufe
     einzeln zu wuerfeln. clamp() erspart einen eigenen Wert je Umbruchpunkt. */
  --fs-base:clamp(.90rem,.87rem + .2vw,.925rem);
  --type-scale:.90;
  /* Der Arbeitsplatz bleibt dichter gesetzt als die Verkaufsseite — er ist ein
     Werkzeug, kein Prospekt. Aber 0.82 war zu weit weg: dieselbe Ebene wirkte
     18 % kleiner, und genau das liest sich als «uneinheitlich». 0.90 hält die
     Dichte und schliesst den sichtbaren Sprung. */

  --fs-2xs:calc(var(--fs-base) * .70);
  --fs-xs: calc(var(--fs-base) * .80);
  --fs-sm: calc(var(--fs-base) * .90);
  --fs-md: var(--fs-base);
  --fs-lg: calc(var(--fs-base) * 1.12);
  --fs-xl: calc(var(--fs-base) * 1.26);

  --fs-display:calc(clamp(2.2rem,5.2vw,4.3rem)   * var(--type-scale));
  --fs-h1:     calc(clamp(1.95rem,4.2vw,3.3rem)  * var(--type-scale));
  /* Zweite Stufe für schmale Karten (Konto, Anmeldung). Eine einzige h1-Grösse
     kann nicht beides bedienen: clamp() misst am FENSTER, nicht am Behälter,
     und 4.2vw von 1280px sind 53px — in einer 430px breiten Karte bricht das
     um. Also zwei benannte Stufen statt fünf zufälliger Werte. */
  --fs-h1-k:   calc(clamp(1.62rem,2.6vw,2.05rem)  * var(--type-scale));
  --fs-h2:     calc(clamp(1.7rem,3.3vw,2.6rem)   * var(--type-scale));
  --fs-h3:     calc(clamp(1.14rem,1.55vw,1.4rem) * var(--type-scale));
  --fs-h4:     calc(clamp(1rem,1.15vw,1.08rem)   * var(--type-scale));

  /* Laufweite: grosse Titel ruecken zusammen, kleine Versalien gehen auf.
     Bei 40px trennen die Wortbilder sich von selbst, da stoert jeder
     Zwischenraum; bei 10px Grossbuchstaben verkleben sie ohne Zugabe. */
  --ls-display:-.03em;
  --ls-tight:-.02em;
  --ls-label:.04em;
  --ls-caps:.08em;

  --violet:#7c5cff; --blue:#0072ff; --cyan:#00c6ff;
  --grad:linear-gradient(120deg,var(--violet) 0%,var(--blue) 58%,var(--cyan) 100%);

  /* Widget-Akzente in der Markenfamilie statt zwölf beliebiger Töne */
  --c-blue:#0072ff;  --c-cyan:#00c6ff;  --c-teal:#12b3a6; --c-green:#18a558;
  --c-lime:#7bb32e;  --c-amber:#f0b429; --c-orange:#f97316;--c-red:#ff3c5a;
  --c-pink:#e0559b;  --c-purple:#7c5cff;--c-indigo:#5b5bd6;--c-slate:#8899bb;

  --r:12px; --r-lg:18px; --rule:1px;
  --pad:16px; --gap:18px;
}

html[data-theme="light"]{
  --bg:#fbfcff;             /* Seitenfläche */
  --ink:#0a0f1e;            /* dunkelste Tinte, z. B. Toast-Grund */
  --surface:#ffffff;
  --surface-2:#f6f8ff;
  --tint:#eef2ff;
  --line:#e6eaf5;
  --line-2:#d3daed;
  --txt:#0a0f1e;
  --txt-2:#4a5680;          /* 7.7:1 auf Weiss */
  --txt-3:#646f93;          /* 4.96:1 auf Weiss, 4.67:1 auf --surface-2 */
  --accent:#5b3df5;
  --accent-ink:#ffffff;
  --accent-soft:#eceaff;
  --hover:#f2f5ff;
  --shadow:0 1px 2px rgba(10,15,30,.04),0 12px 30px -18px rgba(10,15,30,.20);
  --shadow-lg:0 2px 4px rgba(10,15,30,.05),0 26px 56px -28px rgba(60,40,180,.30);
  --page:linear-gradient(180deg,#f7f8ff 0%,#fbfcff 340px,#fbfcff 100%);

  /* Anschluss an assets/css/ui.css */
  --ctl-surface:#ffffff; --ctl-surface-2:#f6f8ff; --ctl-line:#d3daed;
  --ctl-line-soft:#e6eaf5; --ctl-ink:#0a0f1e; --ctl-ink-2:#4a5680;
  --ctl-accent:#5b3df5; --ctl-accent-soft:#eceaff; --ctl-hover:#f2f5ff;
  --ctl-danger:#ff3c5a;
}
html[data-theme="dark"]{
  --bg:#070b16;
  --ink:#02040a;
  --surface:#0e1424;
  --surface-2:#141b2e;
  --tint:#18213a;
  --line:#1e2740;
  --line-2:#2c3754;
  --txt:#eaeefb;
  --txt-2:#aab6d4;
  --txt-3:#8492b5;
  --accent:#8f78ff;
  --accent-ink:#0a0f1e;
  --accent-soft:rgba(143,120,255,.15);
  --hover:#161e33;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 14px 34px -20px rgba(0,0,0,.7);
  --shadow-lg:0 2px 6px rgba(0,0,0,.5),0 28px 60px -30px rgba(0,0,0,.85);
  --page:linear-gradient(180deg,#080d1a 0%,#070b16 340px,#070b16 100%);

  --ctl-surface:#0e1424; --ctl-surface-2:#141b2e; --ctl-line:#2c3754;
  --ctl-line-soft:#1e2740; --ctl-ink:#eaeefb; --ctl-ink-2:#aab6d4;
  --ctl-accent:#8f78ff; --ctl-accent-soft:rgba(143,120,255,.18); --ctl-hover:#161e33;
  --ctl-danger:#ff3c5a;
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;max-width:100%}
body{
  font-family:var(--font);background:var(--bg);background-image:var(--page);
  color:var(--txt);font-size:var(--fs-md);line-height:1.5;letter-spacing:-.003em;
  -webkit-font-smoothing:antialiased;min-height:100vh;
  display:flex;flex-direction:column;overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}

/* ── Ueberschriften ──────────────────────────────────────────────────────────
   Der Arbeitsplatz setzt seine Titel bisher ausschliesslich ueber Klassen.
   Steht im Markup ein blankes h1-h4 — im Wiki, in den Dialogen —, erbt es die
   Vorgabe des Browsers (2em, Times-Kaskade, eigene Abstaende) und faellt aus
   der Reihe. Diese vier Zeilen fangen das ab, damit jede Ebene ueberall
   dieselbe Stufe trifft. Titel in Syne, Text in DM Sans. */
h1,h2,h3,h4{font-family:var(--display);color:var(--txt);margin:0 0 .5em;line-height:1.16}
h1{font-size:var(--fs-h1);font-weight:700;letter-spacing:var(--ls-display)}
h2{font-size:var(--fs-h2);font-weight:700;letter-spacing:var(--ls-display)}
h3{font-size:var(--fs-h3);font-weight:600;letter-spacing:var(--ls-tight)}
h4{font-size:var(--fs-h4);font-weight:600;letter-spacing:var(--ls-tight)}

/* Lange deutsche Komposita in Überschriften.
   «Allgemeine Geschäftsbedingungen» braucht bei 52px rund 566px — in einer
   346px breiten Spalte auf dem Telefon lief die Seite dadurch waagerecht über.
   hyphens:auto trennt an den richtigen Stellen (die Seiten tragen lang="de",
   sonst wüsste der Browser die Regeln nicht); overflow-wrap greift erst, wenn
   selbst das nicht reicht. Bewusst NICHT word-break:break-all — das zerhackt
   auch dort, wo eine Trennstelle vorhanden wäre. */
h1,h2,h3,h4{overflow-wrap:break-word;hyphens:auto}
::selection{background:var(--accent);color:#fff}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.ico{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;
     stroke-linecap:round;stroke-linejoin:round;flex:none}

/* ============================================================== Kopfzeile */
.topbar{
  position:sticky;top:0;z-index:40;
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:11px 20px;
  background:color-mix(in srgb,var(--surface) 84%,transparent);
  backdrop-filter:saturate(180%) blur(14px);
  border-bottom:var(--rule) solid var(--line);
}
.brand{display:flex;align-items:center;gap:9px;white-space:nowrap;flex:none}
.brand-mark{
  width:24px;height:24px;border-radius:8px;flex:none;background:var(--grad);
  position:relative;font-size:0;color:transparent;
}
.brand-mark::after{content:'';position:absolute;inset:7px;border-radius:3px;background:#fff}
/* Die Wortmarke behält Syne. Sie ist ein Zeichen, kein Text: dort ist der
   eigenwillige Charakter erwünscht, und sie steht genau einmal je Seite. */
.brand-text{font-family:Syne,var(--display);font-weight:700;font-size:var(--fs-lg);
            letter-spacing:var(--ls-display);color:var(--txt)}
.brand-text b{font-weight:800}

/* Das Suchfeld ist der Haupteinstieg — von hier aus kommt man zu jedem der
   578 Ziele und zu jedem Werkzeug. Bisher sah es aus wie jedes andere
   Bedienelement und ging in der Zeile unter. Es hebt sich jetzt an drei
   Stellen ab, ohne aus dem System zu fallen:
     · heller als die Umgebung statt grau — es liegt VOR der Kopfzeile
     · vier Pixel höher als die Knöpfe daneben
     · ein weicher Schatten, der es als eigene Ebene zeigt
   Die Rundung bleibt bei --ctl-r; eine zweite Rundung wäre der falsche Weg,
   Aufmerksamkeit zu erzeugen. */
.omnibar{
  position:relative;flex:1 1 320px;min-width:0;display:flex;align-items:center;gap:10px;
  background:var(--surface);border:var(--rule) solid var(--line-2,var(--line));
  border-radius:var(--ctl-r);padding:0 8px 0 15px;height:var(--ctl-h-lg);
  box-shadow:0 1px 2px rgba(10,15,30,.05), 0 4px 14px -8px rgba(10,15,30,.18);
  transition:border-color .2s,box-shadow .2s,background .2s;
}
.omnibar:hover{border-color:var(--txt-3)}
.omnibar:focus-within{
  border-color:var(--accent);
  box-shadow:0 0 0 4px var(--accent-soft), 0 6px 20px -10px rgba(10,15,30,.25);
}
/* Die Lupe trägt Markenfarbe: sie sagt «hier fängt es an», nicht «hier ist
   noch ein Feld». */
.omnibar > .ico{color:var(--accent);width:17px;height:17px}
#omni{font-weight:450}
#omni::placeholder{opacity:.85}
#omni{flex:1;background:none;border:0;outline:none;height:100%;min-width:0;font-size:var(--fs-md)}
#omni::placeholder{color:var(--txt-3)}
#omniEngine{
  flex:none;background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:8px;height:28px;padding:0 8px;font-size:var(--fs-xs);color:var(--txt-2);
  outline:none;max-width:150px;
}
.omni-results{
  position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:60;
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  max-height:62vh;overflow:auto;padding:6px;
}
.omni-item{display:flex;align-items:center;gap:11px;padding:9px 11px;
           border-radius:var(--r);cursor:pointer}
.omni-item:hover,.omni-item.sel{background:var(--accent-soft)}
.omni-item .ttl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.omni-item .crumb{font-size:var(--fs-2xs);color:var(--txt-3);white-space:nowrap}
.omni-empty{padding:16px;color:var(--txt-3);text-align:center;font-size:var(--fs-sm)}

.topbar-actions{display:flex;align-items:center;gap:7px;margin-left:auto;flex:none}

/* ========================================================= Geteiltes Board */
.sharebar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin:14px 20px -4px;padding:12px 16px;border-radius:var(--r-lg);font-size:var(--fs-md);
  background:var(--accent-soft);
  border:var(--rule) solid color-mix(in srgb,var(--accent) 30%,transparent);
}
.sharebar span{flex:1;min-width:220px}

/* =================================================================== Tabs */
.tabs{
  display:flex;align-items:center;gap:4px;padding:10px 20px;overflow-x:auto;
  position:sticky;top:var(--topbar-h,60px);z-index:35;
  background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:saturate(180%) blur(12px);
  scrollbar-width:none;
}
.tabs::-webkit-scrollbar{display:none}
.tab{
  display:inline-flex;align-items:center;gap:7px;padding:9px 14px;border-radius:var(--ctl-r);
  cursor:pointer;color:var(--txt-2);white-space:nowrap;background:transparent;
  border:var(--rule) solid transparent;font-size:var(--fs-sm);font-weight:500;
  transition:background .2s,color .2s,border-color .2s,box-shadow .2s;
}
.tab:hover{background:var(--hover);color:var(--txt)}
/* border:0 statt transparent — sonst dieselbe 1px-Naht wie bei den Knöpfen */
.tab.active{background:var(--grad);color:#fff;border:0;padding:10px 15px}
.tab .tab-emoji{font-size:14px}
.tab .tab-edit{display:none;margin-left:2px}
body.editing .tab .tab-edit{display:inline-flex;opacity:.6}
.tab-add{color:var(--txt-3);border:1px dashed var(--line-2)}

/* ================================================================== Board */
.board{flex:1;padding:18px 20px 40px;column-gap:var(--gap);column-count:4}
.board[data-cols="2"]{column-count:2} .board[data-cols="3"]{column-count:3}
.board[data-cols="4"]{column-count:4} .board[data-cols="5"]{column-count:5}
.board[data-cols="6"]{column-count:6}
@media(max-width:1650px){.board[data-cols="6"]{column-count:5}}
@media(max-width:1400px){.board[data-cols="5"],.board[data-cols="6"]{column-count:4}}
@media(max-width:1150px){.board[data-cols="4"],.board[data-cols="5"],.board[data-cols="6"]{column-count:3}}
@media(max-width:880px){.board{column-count:2 !important}}
@media(max-width:620px){.board{column-count:1 !important;padding:14px}}

/* ================================================================ Widgets */
.widget{
  break-inside:avoid;page-break-inside:avoid;display:inline-block;width:100%;
  margin:0 0 var(--gap);
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow);overflow:hidden;
  transition:box-shadow .3s,border-color .3s;
  animation:rise .45s cubic-bezier(.22,.68,.28,1) backwards;
}
.widget:hover{box-shadow:var(--shadow-lg)}
.widget:nth-child(1){animation-delay:0s}   .widget:nth-child(2){animation-delay:.03s}
.widget:nth-child(3){animation-delay:.06s} .widget:nth-child(4){animation-delay:.09s}
.widget:nth-child(5){animation-delay:.12s} .widget:nth-child(6){animation-delay:.15s}
.widget:nth-child(7){animation-delay:.18s} .widget:nth-child(n+8){animation-delay:.21s}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.widget.drag-over{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.widget.dragging{opacity:.4}
.widget.flash{animation:flash 1.6s ease-out}
@keyframes flash{0%,100%{box-shadow:var(--shadow)}
                 18%{box-shadow:0 0 0 3px var(--accent),var(--shadow-lg)}}

.w-head{display:flex;align-items:center;gap:10px;padding:14px var(--pad) 12px}
.w-head::before{
  content:'';width:8px;height:8px;border-radius:3px;flex:none;order:-1;
  background:var(--wc,var(--accent));
}
.w-head .w-emoji{font-size:14px;line-height:1}
.w-title{
  flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--display);font-weight:700;font-size:var(--fs-h4);
  letter-spacing:var(--ls-tight);
}
/* Der Zaehler aendert sich beim Bearbeiten laufend. In DM Sans wuerde die
   Pille dabei atmen, weil dort jede Ziffer anders breit ist. */
.w-count{
  font-family:var(--num);font-size:var(--fs-2xs);color:var(--txt-3);
  font-variant-numeric:tabular-nums;
  background:var(--surface-2);border-radius:999px;padding:2px 8px;
}
/* ── Info-Zeichen in der Kartenkopfzeile ──────────────────────────────────
   Sichtbar, aber leise: gedämpft neben dem Titel, erst beim Überfahren in
   der Akzentfarbe. Es soll gefunden werden, wenn man es sucht, und nicht
   mit dem Titel um Aufmerksamkeit streiten.

   28px Tastfläche bei 13px Zeichen. Kleiner ginge optisch, wäre auf einem
   Telefon aber nicht sicher zu treffen; die Fläche liegt ausserhalb des
   sichtbaren Kreises und stört das Bild nicht. */
.w-info{
  flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;margin:-6px -4px -6px -4px;padding:0;
  background:none;border:0;cursor:pointer;color:var(--txt-3);
  transition:color .18s var(--ease,ease);
}
.w-info .fa{width:13px;height:13px}
.w-info:hover,.w-info[aria-expanded="true"]{color:var(--accent)}
.w-info:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:50%}

.w-info-blatt{
  position:fixed;z-index:80;width:min(310px,calc(100vw - 20px));
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:14px;box-shadow:var(--shadow-lg);padding:13px 15px;
  animation:infoAuf .16s cubic-bezier(.22,.68,.28,1);
}
@keyframes infoAuf{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.w-info-blatt strong{
  display:block;font-family:var(--display);font-weight:700;
  font-size:var(--fs-sm);letter-spacing:var(--ls-tight);margin-bottom:5px;
}
.w-info-blatt p{margin:0;font-size:var(--fs-sm);line-height:1.55;color:var(--txt-2)}
/* Die Herkunftszeile trägt Farbe, weil sie eine Aussage über Vertraulichkeit
   ist und nicht bloss Beiwerk. */
.w-info-ort{
  display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  font-size:var(--fs-2xs);font-weight:500;padding:4px 9px;border-radius:999px;
}
.w-info-ort .fa{width:11px;height:11px}
.w-info-ort.lokal{background:var(--c-green-soft,rgba(16,185,129,.12));color:var(--c-green,#059669)}
.w-info-ort.netz{background:var(--tint-2,rgba(0,114,255,.1));color:var(--accent)}

.w-tools{display:none;gap:1px}
body.editing .w-tools{display:flex}
.w-tools .icon-btn{width:24px;height:24px}
.w-tools .icon-btn .ico{width:13px;height:13px}
.w-grip{cursor:grab;color:var(--txt-3);display:none}
body.editing .w-grip{display:inline-flex}

.w-body{padding:0 8px 10px}
.w-body.pad{padding:0 var(--pad) var(--pad)}

/* =============================================================== Linklisten */
.lnk{
  display:flex;align-items:center;gap:10px;padding:7px 10px;min-height:34px;
  border-radius:var(--ctl-r);cursor:pointer;position:relative;
  transition:background .16s,transform .16s;
}
.lnk:hover{background:var(--hover);transform:translateX(2px)}
.lnk.drag-over{box-shadow:inset 0 2px 0 var(--accent)}
.lnk.dragging{opacity:.4}
/* Faellt das Favicon aus, steht hier der Anfangsbuchstabe. DM Sans hat kein
   Gewicht 700 im Bestand — der Browser wuerde es rechnerisch verfetten und der
   Buchstabe verschmierte auf 17px. Syne hat den Schnitt wirklich. */
.lnk-ico{
  width:17px;height:17px;flex:none;object-fit:contain;border-radius:5px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--display);font-size:var(--fs-2xs);font-weight:700;color:#fff;
}
.lnk-txt{flex:1;min-width:0}
.lnk-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-md)}
.lnk-note{font-size:var(--fs-sm);color:var(--txt-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lnk-tools{display:none;gap:1px}
body.editing .lnk:hover .lnk-tools{display:flex}
.lnk-tools .icon-btn{width:22px;height:22px}
.lnk-tools .icon-btn .ico{width:13px;height:13px}
body.compact .lnk{padding:3px 10px;min-height:26px}
body.compact .lnk-note{display:none}
body.compact .lnk-name{font-size:var(--fs-sm)}

.w-add{
  display:none;width:calc(100% - 20px);margin:8px 10px 2px;
  align-items:center;justify-content:center;gap:6px;padding:8px;
  border:var(--rule) dashed var(--line-2);border-radius:var(--ctl-r);
  background:none;color:var(--txt-3);cursor:pointer;font-size:var(--fs-sm);
}
body.editing .w-add{display:flex}
.w-add:hover{color:var(--accent);border-color:var(--accent);background:var(--accent-soft)}

/* ============================================================ Notizen/Todo */
.notes-area{
  width:100%;min-height:140px;resize:vertical;background:var(--surface-2);
  border:var(--rule) solid var(--line);border-radius:var(--r);
  padding:11px;outline:none;font-size:var(--fs-md);line-height:1.55;font-family:var(--font);
}
.todo-list{list-style:none;margin:0;padding:0}
.todo-item{display:flex;align-items:center;gap:10px;padding:7px 0}
.todo-item + .todo-item{border-top:var(--rule) solid var(--line)}
.todo-item input[type=checkbox]{accent-color:var(--accent);width:15px;height:15px;flex:none}
.todo-item span{flex:1;min-width:0;word-break:break-word;font-size:var(--fs-md)}
.todo-item.done span{text-decoration:line-through;color:var(--txt-3)}
.todo-add{display:flex;gap:7px;margin-top:10px}

/* ========================================================= Konsole / Dorks */
.con-row{display:flex;gap:7px;margin-bottom:10px}
.con-sel{width:auto;min-width:120px;flex:none}
.con-meta{font-size:var(--fs-xs);color:var(--txt-3);margin:-4px 0 10px;
          display:flex;align-items:center;gap:6px;flex-wrap:wrap;
          font-variant-numeric:tabular-nums}
/* Pillen sind Statusanzeigen, keine Bedienelemente — sie dürfen rund bleiben.
   Sie tragen meist Trefferzahlen, darum die Ziffernschrift. */
.pill{
  background:var(--surface-2);border:var(--rule) solid var(--line);border-radius:999px;
  padding:3px 10px;font-family:var(--num);font-size:var(--fs-2xs);color:var(--txt-2);
  font-variant-numeric:tabular-nums;
}
.pill.on{background:var(--grad);border:0;color:#fff}
/* Ein Status-Pill entsteht leer und wird erst beim Ergebnis beschriftet.
   Leer trug es trotzdem Rahmen und Innenabstand — als ranloser Fleck
   neben dem Knopf, den man fuer einen Fehler haelt. Ohne Inhalt kein
   Platz; sobald Text kommt, ist es wieder da. */
.pill:empty{display:none}
.con-list{display:flex;flex-direction:column;gap:2px;max-height:340px;overflow:auto}
.con-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:var(--ctl-r);cursor:pointer}
.con-item:hover{background:var(--hover)}
.con-item .nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-sm)}
.con-item .ico{color:var(--txt-3);width:13px;height:13px}
.con-actions{display:flex;gap:6px;margin-top:12px;flex-wrap:wrap}

.dk-grid{display:grid;grid-template-columns:1fr;gap:8px}
.dk-grid label{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm);color:var(--txt-2)}
.dk-out{
  font-family:var(--mono);font-size:var(--fs-sm);background:var(--surface-2);
  font-variant-numeric:tabular-nums;
  border:var(--rule) solid var(--line);border-left:3px solid var(--accent);
  border-radius:var(--ctl-r);padding:10px 12px;margin-top:11px;word-break:break-all;
  min-height:36px;color:var(--txt-2);
}
.dk-presets{display:flex;flex-wrap:wrap;gap:5px;margin-top:11px}

/* ================================================================ Fusszeile */
.foot{
  padding:24px 20px 34px;color:var(--txt-3);font-size:var(--fs-sm);
  display:flex;gap:10px;flex-wrap:wrap;justify-content:center;
  border-top:var(--rule) solid var(--line);margin-top:10px;
}
/* In der Fusszeile stehen die Werkzahlen — sie werden bei jeder Aenderung am
   Board neu geschrieben, und die Zeile ist mittig gesetzt: ohne feste
   Ziffernbreiten wandert der ganze Absatz seitlich mit. Gleiches gilt fuer
   den Zaehler des Wikis, der aus wiki.html kommt. */
#footStats,#wStats{font-family:var(--num);font-variant-numeric:tabular-nums}
.foot-sep{opacity:.4}
.foot a{color:var(--accent)}

/* =================================================================== Dialoge */
.dlg{
  border:var(--rule) solid var(--line);border-radius:22px;background:var(--surface);
  color:var(--txt);padding:26px 28px;width:min(440px,92vw);box-shadow:var(--shadow-lg);
}
.dlg.wide{width:min(620px,94vw)}
.dlg::backdrop{background:rgba(10,15,30,.5);backdrop-filter:blur(3px)}
/* Gewicht 600 wie die dritte Ebene ueberall sonst — ein Dialogtitel ist eine
   Ueberschrift und keine eigene Gattung. */
.dlg h3{font-family:var(--display);font-weight:600;margin:0 0 18px;
        font-size:var(--fs-h3);letter-spacing:var(--ls-tight)}
.dlg label{display:flex;flex-direction:column;gap:6px;margin-bottom:14px;
           font-size:var(--fs-xs);font-weight:500;color:var(--txt-2)}
.dlg label input:not([type=checkbox]),.dlg label select{
  background:var(--surface-2);border:var(--rule) solid var(--line);border-radius:var(--ctl-r);
  padding:10px 12px;outline:none;color:var(--txt);font-size:var(--fs-md);font-weight:400;
}
.dlg label input:focus,.dlg label select:focus{border-color:var(--accent);
                                               box-shadow:0 0 0 4px var(--accent-soft)}
.dlg-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px;flex-wrap:wrap}
.settings .row{display:flex;align-items:center;gap:10px;margin:13px 0;flex-wrap:wrap;font-size:var(--fs-md)}
.settings small{color:var(--txt-3);font-size:var(--fs-sm)}
.settings hr{border:none;border-top:var(--rule) solid var(--line);margin:18px 0}
.settings input[type=checkbox]{accent-color:var(--accent);width:16px;height:16px}
.keys{margin:10px 0 0;padding-left:18px;color:var(--txt-2);font-size:var(--fs-sm)}
kbd{background:var(--surface-2);border:var(--rule) solid var(--line-2);border-radius:6px;
    padding:1px 6px;font-family:var(--num);font-size:var(--fs-2xs);
    font-variant-numeric:tabular-nums}
details summary{cursor:pointer;color:var(--txt-2);font-size:var(--fs-sm)}

/* ===================================================================== Toast */
.toast{
  position:fixed;bottom:22px;left:50%;transform:translateX(-50%);
  background:var(--ink);color:#fff;border-radius:999px;
  padding:12px 22px;box-shadow:var(--shadow-lg);z-index:99;font-size:var(--fs-sm);max-width:88vw;
  animation:toastIn .3s cubic-bezier(.22,.68,.28,1);
}
html[data-theme="dark"] .toast{background:var(--surface-2);border:var(--rule) solid var(--line-2)}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,14px)}to{opacity:1;transform:translate(-50%,0)}}

/* ========================================================================
   Werkzeuge
   ======================================================================== */
.tl-row{display:flex;gap:7px;margin-bottom:10px;flex-wrap:wrap;align-items:center}
/* Auch Auswahlfelder und die Kontaktzeile teilen sich die Zeile. Vorher
   standen hier nur .tl-in und .tl-area — ein <select> daneben behielt seine
   Inhaltsbreite, und der Rest der Zeile blieb leer. Die Untergrenze ist
   dieselbe wie bei Textfeldern: faellt ein <select> unter etwa 110px, ist
   die Beschriftung abgeschnitten; dann soll die Zeile lieber umbrechen,
   wozu .tl-row flex-wrap traegt.

   Hier stand ausserdem `.tl-sel{width:auto;flex:none}`. Genau diese Regel
   war der Grund, dass Auswahlfelder ihre Inhaltsbreite behielten — sie ist
   entfallen, weil sie der Breitenregel in ui.css widersprach und alle 13
   Auswahlfelder der Anwendung ohnehin in einer Zeile stehen. */
.tl-row > .tl-in,.tl-row > .tl-area{flex:1;min-width:110px}
.tl-row > .tl-sel,.con-row > .con-sel{flex:1;min-width:110px}
.con-row > .con-input,.todo-add > input{flex:1;min-width:0}
.tl-area{font-family:var(--mono);font-size:var(--fs-sm);line-height:1.55;resize:vertical;
         margin-bottom:10px;display:block;font-variant-numeric:tabular-nums}

.tl-out{margin-top:5px}
.tl-out:empty{display:none}
.tl-block{margin:10px 0;padding:11px 13px;background:var(--surface-2);border-radius:12px}
/* Versalien auf kleiner Stufe brauchen Luft, sonst verkleben sie. */
.tl-block-h{font-family:var(--display);font-weight:700;font-size:var(--fs-xs);
            letter-spacing:var(--ls-caps);
            text-transform:uppercase;color:var(--txt-3);margin:15px 0 7px}
.tl-mono{font-family:var(--mono);font-size:var(--fs-sm);padding:2px 0;color:var(--txt-2);
         font-variant-numeric:tabular-nums}
.tl-wrap{word-break:break-all}

.tl-kv{width:100%;border-collapse:collapse;font-size:var(--fs-sm);table-layout:fixed}
.tl-kv th{text-align:left;font-weight:400;color:var(--txt-3);padding:7px 10px 7px 0;
          width:38%;vertical-align:top;white-space:nowrap;overflow:hidden;
          text-overflow:ellipsis;font-size:var(--fs-sm)}
/* Die Wertspalte traegt gemischtes Gut — Registrarnamen neben Seriennummern.
   Darum bleibt sie im Textschnitt; rein numerische Zellen holen sich die
   Ziffernschrift ueber .zahl (siehe unten). */
.tl-kv td{padding:7px 0;vertical-align:top;word-break:break-word;white-space:pre-wrap;
          font-variant-numeric:tabular-nums}
.tl-kv tr + tr th,.tl-kv tr + tr td{border-top:var(--rule) solid var(--line)}

.tl-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px;align-items:center}
.tl-chips{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px}
.tl-chips-scroll{max-height:150px;overflow-y:auto;align-content:flex-start;
                 border:var(--rule) solid var(--line);border-radius:12px;
                 padding:8px;background:var(--surface-2)}

.tl-tag{display:inline-block;padding:2px 9px;border-radius:999px;font-size:var(--fs-2xs);
        font-weight:500;background:var(--surface-2);border:var(--rule) solid var(--line);
        color:var(--txt-2);margin-left:7px;font-variant-numeric:tabular-nums}
.tl-tag.ok{background:color-mix(in srgb,var(--c-green) 15%,transparent);
           border-color:transparent;color:var(--c-green)}
.tl-tag.warn{background:color-mix(in srgb,var(--c-amber) 20%,transparent);
             border-color:transparent;color:#a97514}
.tl-tag.bad{background:var(--c-red);border-color:transparent;color:#fff}

.tl-warn,.tl-ok,.tl-bad,.tl-hint{padding:11px 13px;border-radius:12px;font-size:var(--fs-sm);
                                 margin:11px 0;line-height:1.5}
.tl-warn{background:color-mix(in srgb,var(--c-amber) 14%,transparent)}
.tl-ok{background:color-mix(in srgb,var(--c-green) 13%,transparent)}
.tl-bad{background:color-mix(in srgb,var(--c-red) 13%,transparent)}
.tl-hint{background:var(--surface-2);color:var(--txt-3);font-size:var(--fs-xs)}

.tl-link{color:var(--accent);font-size:var(--fs-sm);font-weight:500;white-space:nowrap}
.tl-link:hover{text-decoration:underline}

.tl-busy{color:var(--txt-3);font-size:var(--fs-sm);padding:12px 0;display:flex;align-items:center;gap:10px}
.tl-busy::before{content:'';width:14px;height:14px;border-radius:50%;
                 border:2px solid var(--line-2);border-top-color:var(--accent);
                 animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

.tl-drop{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  padding:24px 16px;border:1.5px dashed var(--line-2);border-radius:14px;
  cursor:pointer;text-align:center;margin:8px 0 12px;
  transition:border-color .2s,background .2s;
}
.tl-drop:hover,.tl-drop.over{border-color:var(--accent);background:var(--accent-soft)}
.tl-drop b{font-size:var(--fs-sm);font-weight:500}
.tl-drop small{color:var(--txt-3);font-size:var(--fs-xs)}

.tl-hop{position:relative;padding:11px 30px 11px 14px;margin:7px 0;border-radius:12px;
        background:var(--surface-2);border-left:3px solid var(--accent);font-size:var(--fs-sm)}
.tl-hop b{font-size:var(--fs-sm);font-weight:500}
/* Laufzeiten und Sprungzahlen, Zeile unter Zeile. */
.tl-hop-meta{color:var(--txt-3);font-size:var(--fs-xs);margin-top:3px;
             font-family:var(--num);font-variant-numeric:tabular-nums}
.tl-del{position:absolute;top:7px;right:7px;background:none;border:none;color:var(--txt-3);
        cursor:pointer;font-size:16px;line-height:1;padding:0 5px}
.tl-del:hover{color:var(--c-red)}

.tl-pre{font-family:var(--mono);font-size:var(--fs-xs);line-height:1.55;background:var(--surface-2);
        border-radius:12px;padding:11px;overflow:auto;max-height:280px;
        white-space:pre-wrap;word-break:break-word;margin:8px 0;
        font-variant-numeric:tabular-nums}
.tl-preview{max-width:100%;border-radius:12px;margin-top:12px;display:block}

/* ======================================================== Hintergrundaufträge */
.jobs-btn{position:relative}
.jobs-btn.active{color:var(--accent)}
/* Die Zahl im Abzeichen zaehlt hoch und runter, waehrend Auftraege laufen.
   In DM Sans gibt es kein Gewicht 700 — der Browser muesste es faelschen, und
   die Ziffern haetten dazu ungleiche Breiten. Syne bringt beides mit. */
.jobs-badge{position:absolute;top:0;right:0;min-width:16px;height:16px;padding:0 4px;
            background:var(--grad);color:#fff;border-radius:999px;
            font-family:var(--display);font-size:var(--fs-2xs);line-height:16px;
            text-align:center;font-weight:700;
            font-variant-numeric:lining-nums tabular-nums}
.jobs-badge.idle{background:var(--line-2);color:var(--txt-2)}
.jobs-panel{
  position:fixed;right:16px;top:calc(var(--topbar-h,60px) + 8px);z-index:65;
  width:min(340px,calc(100vw - 32px));max-height:60vh;overflow-y:auto;
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
}
.jobs-head{display:flex;align-items:center;justify-content:space-between;gap:8px;
           padding:13px 15px;border-bottom:var(--rule) solid var(--line);
           font-family:var(--display);font-weight:700;font-size:var(--fs-sm);
           letter-spacing:var(--ls-tight)}
.jobs-empty{padding:18px 15px;color:var(--txt-3);font-size:var(--fs-sm);text-align:center}
.jobs-row{padding:12px 15px;border-bottom:var(--rule) solid var(--line)}
.jobs-row:last-child{border-bottom:none}
.jobs-row-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.jobs-row-h b{font-size:var(--fs-sm);font-weight:500}
/* Zustand und Fortschritt werden im Sekundentakt neu geschrieben und stehen
   Zeile unter Zeile — ohne feste Ziffernbreiten zappelt die ganze Spalte. */
.jobs-state{font-size:var(--fs-2xs);color:var(--txt-3);white-space:nowrap;
            font-family:var(--num);font-variant-numeric:tabular-nums}
.jobs-row.done .jobs-state{color:var(--c-green)}
.jobs-row.error .jobs-state{color:var(--c-red)}
.jobs-bar{height:4px;background:var(--line);border-radius:99px;margin:9px 0 7px;overflow:hidden}
.jobs-bar i{display:block;height:100%;background:var(--grad);border-radius:99px;transition:width .25s}
.jobs-bar i.indet{width:35%!important;animation:jobsSlide 1.1s ease-in-out infinite}
@keyframes jobsSlide{0%{transform:translateX(-100%)}100%{transform:translateX(320%)}}
.jobs-meta{font-size:var(--fs-2xs);color:var(--txt-3);min-height:12px;
           font-family:var(--num);font-variant-numeric:tabular-nums}
.jobs-acts{display:flex;gap:6px;margin-top:8px}
.jobs-acts button{background:var(--surface-2);border:var(--rule) solid var(--line);
                  border-radius:var(--ctl-r);color:var(--txt-2);padding:4px 11px;font:inherit;
                  font-size:var(--fs-xs);cursor:pointer}
.jobs-acts button:hover{border-color:var(--accent);color:var(--accent)}

/* ================================================================ Assistent */
.as-fab{
  position:fixed;right:20px;bottom:20px;z-index:70;
  display:flex;align-items:center;gap:9px;height:var(--ctl-h);padding:0 20px;
  background:var(--grad);color:#fff;border:none;border-radius:var(--ctl-r);
  font:inherit;font-size:14.5px;font-weight:500;cursor:pointer;
  box-shadow:0 8px 24px -12px rgba(10,15,30,.45);
  transition:transform .18s,box-shadow .25s;
}
.as-fab:hover{transform:translateY(-2px);box-shadow:0 14px 30px -14px rgba(10,15,30,.5)}
.as-fab.open{background:var(--ink)}
.as-fab-dot{width:8px;height:8px;background:currentColor;border-radius:50%;
            animation:asPulse 2.4s ease-in-out infinite}
@keyframes asPulse{0%,100%{opacity:1}50%{opacity:.35}}

.as-panel{
  position:fixed;right:20px;bottom:76px;z-index:71;
  width:min(400px,calc(100vw - 40px));max-height:min(620px,calc(100vh - 150px));
  display:flex;flex-direction:column;
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:22px;box-shadow:var(--shadow-lg);overflow:hidden;
  animation:asIn .22s cubic-bezier(.22,.68,.28,1);
}
@keyframes asIn{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
.as-head{position:relative;padding:16px 56px 14px 18px;border-bottom:var(--rule) solid var(--line)}
.as-title{display:block;font-family:var(--display);font-weight:700;
          font-size:var(--fs-h4);letter-spacing:var(--ls-tight)}
.as-sub{display:block;font-size:var(--fs-sm);color:var(--txt-3);margin-top:3px}
/* 44x44 ist das Mindestmass fuer eine Tippflaeche (Apple HIG). Vorher waren
   es 28x28 — auf dem Telefon trifft der Daumen daneben, und daneben passiert
   nichts. Das Kreuz selbst bleibt optisch klein; nur die Flaeche waechst. */
.as-x{position:absolute;top:6px;right:6px;width:44px;height:44px;background:none;
      border:none;color:var(--txt-3);font-size:22px;line-height:1;cursor:pointer;
      border-radius:999px;display:flex;align-items:center;justify-content:center;
      padding:0;-webkit-tap-highlight-color:transparent}
.as-x:hover{background:var(--hover);color:var(--c-red)}
.as-log{flex:1;overflow-y:auto;padding:15px 18px;display:flex;flex-direction:column;gap:12px;min-height:190px}
.as-msg{font-size:var(--fs-md);line-height:1.55}
.as-msg p{margin:0 0 8px}
.as-me{align-self:flex-end;max-width:88%;background:var(--grad);color:#fff;
       padding:9px 14px;border-radius:16px 16px 4px 16px}
.as-bot{align-self:flex-start;max-width:100%;width:100%;color:var(--txt-2)}
.as-lead{color:var(--txt);font-weight:500;font-size:var(--fs-sm)}
.as-card{border-radius:14px;background:var(--surface-2);padding:12px 14px;margin:8px 0}
.as-card-h{display:flex;align-items:baseline;justify-content:space-between;gap:9px;margin-bottom:5px}
.as-card-h b{font-size:var(--fs-sm);color:var(--txt);font-weight:500}
.as-card-h a{color:var(--accent);font-size:var(--fs-sm);font-weight:500}
.as-card-page{font-size:var(--fs-2xs);color:var(--txt-3);white-space:nowrap;
              font-variant-numeric:tabular-nums}
.as-card p{margin:0;font-size:var(--fs-xs);color:var(--txt-3);line-height:1.5}
.as-go{margin-top:9px;background:var(--grad);border:0;color:#fff;border-radius:var(--ctl-r);
       padding:5px 13px;font:inherit;font-size:var(--fs-sm);font-weight:500;cursor:pointer}
.as-go:hover{filter:brightness(1.08)}
.as-steps{margin:9px 0 0;padding-left:0;list-style:none;counter-reset:as}
.as-steps li{counter-increment:as;position:relative;padding:10px 0 10px 32px;font-size:var(--fs-sm)}
.as-steps li + li{border-top:var(--rule) solid var(--line)}
/* Dieselben Schrittzahlen wie auf der Verkaufsseite (.steps .no): Syne im
   Titelschnitt, Ziffern in Versalhoehe und auf gleicher Breite. Syne setzt von
   sich aus Mediaevalziffern — die 3 und die 7 haengen dann unter die
   Grundlinie und stehen in einem 22px-Feld schief. lining-nums holt die
   Versalziffern, tabular-nums die gleiche Breite; beides hat die Datei. */
.as-steps li::before{
  content:counter(as,decimal-leading-zero);position:absolute;left:0;top:11px;
  width:22px;height:22px;border-radius:8px;background:var(--accent-soft);color:var(--accent);
  font-family:var(--display);font-size:var(--fs-2xs);font-weight:700;
  font-variant-numeric:lining-nums tabular-nums;
  letter-spacing:var(--ls-label);display:grid;place-items:center;
}
.as-llm{padding:11px 18px;border-top:var(--rule) solid var(--line);display:flex;
        flex-wrap:wrap;gap:8px;align-items:center}
.as-llm-note{font-size:var(--fs-2xs);color:var(--txt-3);line-height:1.45;flex:1;min-width:150px}
.as-llm-on{font-size:var(--fs-2xs);color:var(--c-green);font-weight:500}
.as-form{display:flex;gap:7px;padding:13px 18px;border-top:var(--rule) solid var(--line)}
/* Das Feld nimmt den Rest der Zeile. Ohne flex bemisst sich ein input nach
   seinem size-Attribut (voreingestellt 20 Zeichen) — die Zeile blieb dann
   schmaler als das Panel und liess rechts eine Lücke stehen. min-width:0
   hebt die Voreinstellung min-width:auto auf, sonst schrumpft das Feld auf
   schmalen Fenstern nicht unter seine Inhaltsbreite und drängt den Knopf
   aus dem Panel. */
.as-in{flex:1 1 auto;min-width:0}

/* ============================================================== Scrollbalken */
/* NICHT die Seitenleiste des Dokuments: diese Datei laden nur /wiki und
   /dashboard. Dort erzwang die Regel eine klassische 10px-Leiste, waehrend
   alle uebrigen Seiten die ueberlagernde Leiste von macOS behalten — beim
   Wechsel sprang die ganze Seite um 10px zur Seite. Innere Bereiche
   (Listen, Panels) behalten die duenne Leiste. */
*:not(html):not(body)::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:99px;
                           border:2px solid transparent;background-clip:content-box}
*::-webkit-scrollbar-thumb:hover{background:var(--txt-3);background-clip:content-box}
*::-webkit-scrollbar-track{background:transparent}

/* ================================================================ Responsive */
@media(max-width:900px){
  .hide-sm{display:none}
  .topbar{padding:10px 14px;gap:10px}
  /* flex:none aus der Desktop-Regel liess die Knopfgruppe bei 375 px um
     5 px über den Rand ragen — die ganze Seite scrollte dann waagerecht. */
  .topbar-actions{flex:0 1 auto;min-width:0;flex-wrap:wrap;justify-content:flex-end}
  .brand-text{display:none}
  .omnibar{order:3;flex-basis:100%}
  .tabs{padding:8px 14px}
  .foot{padding:20px 14px 30px}
}
@media(max-width:620px){
  .lnk{min-height:40px}
  .as-panel{right:10px;left:10px;bottom:74px;width:auto;max-height:calc(100vh - 100px)}
  .as-fab{right:12px;bottom:12px}
}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0ms!important;
                       transition-duration:.01ms!important}
}
@media print{
  .topbar,.tabs,.foot,.w-tools,.w-add,.sharebar,.as-fab,.as-panel{display:none!important}
  .board{column-count:3}
  .widget{animation:none;box-shadow:none;border:1px solid #ccc}
}


/* ── Kontozustand in der Kopfzeile ───────────────────────────────────────────
   Der Knopf sagt, woran man ist. Der Punkt trägt die Aussage nicht allein —
   daneben steht der Name, und im title die vollständige Adresse; wer Farben
   nicht unterscheidet, verliert dadurch nichts. */
.topbar-actions a[href="/konto"].angemeldet{
  border-color:var(--accent);
  color:var(--accent);
}
.konto-punkt{
  width:8px;height:8px;border-radius:999px;flex:none;
  background:var(--grad);
}

/* ── Zahlen ─────────────────────────────────────────────────────────────────
   Wo Zahlen untereinander stehen oder sich fortlaufend aendern, muss jede
   Ziffer gleich breit sein — sonst wandert die Zeile bei jedem Tick seitlich
   und das Auge liest sie neu, statt nur den Wert zu erfassen.

   .zahl ist der Griff dafuer im Markup: eine Zelle, ein Zaehler, ein Hash, ein
   Zeitstempel bekommt die Klasse und ist damit ruhig gestellt. Sie steht hier
   und nicht bei jedem Bauteil einzeln, weil sonst jede neue Stelle wieder
   vergessen wird.

   Zwei Wege fuehren zum Ziel, und welcher gilt, haengt an der Schrift:
   Syne fuehrt tnum und lnum, dort genuegt font-variant-numeric. DM Sans in
   diesem Ausschnitt fuehrt keines von beiden, dort hilft nur --num. */
.zahl,
.wiki-count,                       /* Trefferzahl je Wiki-Kategorie */
.wiki-card .h,                     /* Hostname unter dem Wiki-Eintrag */
.tl-kv td.zahl{
  font-family:var(--num);
  font-variant-numeric:tabular-nums;
}
/* Die Trefferzahl sitzt im h2 der Kategorie und erbt sonst dessen enge
   Titellaufweite — bei einer vierstelligen Zahl klebt sie dann zusammen.
   Eine Zahl ist kein Titel, sie braucht den Normalabstand. */
.wiki-count{letter-spacing:normal}
/* Im Titelschnitt gesetzte Zahlen bleiben in Syne — sie sollen wie Zahlen der
   Marke aussehen, nicht wie Terminalausgabe. lining-nums ist dort Pflicht:
   ohne sie liefert Syne Mediaevalziffern mit Unterlaenge. */
.zahl-titel{
  font-family:var(--display);
  font-variant-numeric:lining-nums tabular-nums;
  letter-spacing:var(--ls-tight);
}

/* ── Dunkler Modus ──────────────────────────────────────────────────────────
   Helle Schrift auf dunklem Grund laeuft optisch zu: die Glaettung legt an
   jeder Kante Helligkeit zu, und die Buchstaben ruecken scheinbar zusammen.
   Bei 13px faellt das nicht auf, bei einem 40px-Titel mit -.03em schon. Die
   grossen Stufen bekommen deshalb im Dunkeln einen Hauch weniger negative
   Laufweite, damit beide Themen gleich dicht wirken. */
html[data-theme="dark"] h1,
html[data-theme="dark"] h2,
html[data-theme="dark"] .brand-text{letter-spacing:-.024em}
html[data-theme="dark"] .tl-block-h{letter-spacing:.09em}


/* ── Kontomenü in der Kopfzeile ──────────────────────────────────────────────
   Liegt am body und nicht im Knopf: die Kopfzeile hat overflow-Regeln, und ein
   Menü, das darin steckt, würde an deren Kante abgeschnitten — derselbe Fehler
   wie beim Schatten des Assistenten. Die Lage wird beim Öffnen aus der
   Knopfposition gerechnet. */
.konto-menue{
  position:fixed;z-index:80;min-width:210px;
  background:var(--surface);border:var(--rule) solid var(--line);
  border-radius:var(--ctl-r);box-shadow:var(--shadow-lg);
  padding:6px;display:flex;flex-direction:column;gap:2px;
  animation:kmIn .16s cubic-bezier(.22,.68,.28,1);
}
@keyframes kmIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

/* Die Adresse steht ungekürzt im Menü — im Knopf ist nur Platz für den Teil
   vor dem @, und wer zwei Konten hat, muss sie unterscheiden können. */
.konto-menue-kopf{
  display:flex;align-items:center;gap:8px;padding:8px 10px 9px;
  font-size:12.5px;color:var(--txt-3);
  border-bottom:var(--rule) solid var(--line);margin-bottom:4px;
  overflow-wrap:anywhere;
}
.konto-menue a,.konto-menue button{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:0 10px;height:var(--ctl-h-sm);border:0;border-radius:10px;
  background:none;font:inherit;font-size:14.5px;color:var(--txt);
  text-align:left;cursor:pointer;
}
.konto-menue a:hover,.konto-menue button:hover,
.konto-menue a:focus-visible,.konto-menue button:focus-visible{
  background:var(--hover);color:var(--accent);
}
.konto-menue .fa{width:.95em;height:.95em;color:var(--txt-3)}
.konto-menue a:hover .fa,.konto-menue button:hover .fa{color:var(--accent)}
.konto-menue .konto-abmelden:hover{color:var(--c-red)}
.konto-menue .konto-abmelden:hover .fa{color:var(--c-red)}

/* Der kleine Pfeil zeigt, dass hier etwas aufgeht — ein Name allein sieht aus
   wie eine Beschriftung, nicht wie ein Schalter. */
.konto-pfeil{
  width:6px;height:6px;flex:none;margin-left:1px;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:rotate(45deg) translate(-1px,-1px);opacity:.6;
}
.topbar-actions a[href="/konto"][aria-expanded="true"] .konto-pfeil{
  transform:rotate(-135deg) translate(-1px,-1px);
}
