/* ==========================================================================
   Snotra AI — Landingpage snotra-ai.dev
   Aufbau nach Entwurf out/mockup/website-a2.html.

   Zwei Farbebenen, bewusst getrennt:

   (a) Website-Chrome (Kopf, Typo, Buttons, Sektionen, Fuss) —
       ausschliesslich die Token-Palette aus src/renderer/styles/tokens.css.
       Die --ds-*-Namen sind 1:1 von dort uebernommen, damit eine Abweichung
       am Namen auffaellt; die Kurznamen darunter sind reine Aliase.

   (b) Innerhalb von .appwin (Nachbau des App-Fensters) gelten die echten
       Werte der ausgelieferten App aus src/renderer/styles.css. Sie stehen
       als --app-*-Variablen mit Herkunftskommentar und sind NICHT durch
       Token-Grau zu ersetzen — sie sind der Grund, warum das Fenster wie
       Snotra Agent aussieht.

   Light only. Eine Akzentfarbe. Flach. Keine externe Ressource.
   ========================================================================== */

/* ---------- Inter, selbst gehostet -----------------------------------------
   Vendoriert wie in src/renderer/styles/inter.css (@fontsource/inter).
   Vier Schnitte, je Latin und Latin-Ext mit eigenem unicode-range, damit nur
   das benoetigte Subset geladen wird. Lizenz: SIL Open Font License 1.1.
   Kein CDN, keine Google-Fonts-Verbindung.
   -------------------------------------------------------------------------- */
@font-face{
  font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/inter-latin-400-normal.woff2') format('woff2');
  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:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('fonts/inter-latin-ext-400-normal.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,
    U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/inter-latin-500-normal.woff2') format('woff2');
  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:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url('fonts/inter-latin-ext-500-normal.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,
    U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('fonts/inter-latin-600-normal.woff2') format('woff2');
  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:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('fonts/inter-latin-ext-600-normal.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,
    U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url('fonts/inter-latin-700-normal.woff2') format('woff2');
  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:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url('fonts/inter-latin-ext-700-normal.woff2') format('woff2');
  unicode-range:U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,
    U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ---------- Tokens ---------------------------------------------------------
   Block 1:1 aus src/renderer/styles/tokens.css (:root, Light). Wer hier einen
   Wert aendert, muss ihn dort aendern — tokens.css ist die Single Source of
   Truth. Die Kurznamen darunter sind Aliase, damit die Regeln lesbar bleiben.
   -------------------------------------------------------------------------- */
:root{
  color-scheme:light;

  /* Marken-Palette */
  --ds-blue:#00759E;                              /* einzige Akzentfarbe */
  --ds-blue-ink:#005F80;                          /* dunklere Fassung der Akzentfarbe, nur
                                                     fuer Text auf --ds-grey-card noetig.
                                                     Kontrast von --ds-blue: 5,20:1 auf Weiss,
                                                     4,86:1 auf --ds-blue-soft, 4,85:1 auf
                                                     --ds-grey-bg — aber nur 4,56:1 auf
                                                     --ds-grey-card, also 0,06 ueber der
                                                     Anforderung und schon bei angeschnittener
                                                     Deckkraft darunter. Hier 6,25:1.
                                                     Alle Blau-Texte beider Seiten samt Hover-
                                                     und Aktiv-Zustaenden am 2026-09-13
                                                     durchgemessen (Issue #113): Dies war die
                                                     einzige Stelle. */
  --ds-blue-soft:rgba(0,117,158,.05);
  --ds-blue-border:rgba(0,117,158,.25);
  --ds-chat-user-bg:rgba(0,117,158,.08);
  --ds-black:#000000;
  --ds-syntax-string:#3E6B2F;                     /* code in backticks, as in the app's
                                                     source preview; 5,5:1 on --ds-grey-card */
  --ds-white:#FFFFFF;

  /* Neutrale Toene (Light) */
  --ds-grey-bg:#F6F7F9;
  --ds-grey-card:#EFF0F2;
  --ds-grey-divider:#ECEDEF;
  --ds-grey-muted:#6D6D6D;                        /* nur >= 14px */
  --ds-grey-strong:#5C5C5C;                       /* fuer Text < 14px */

  /* Buttons, Overlays */
  --ds-btn-primary-bg-hover:#005F80;
  --ds-btn-primary-active-shadow:0 4px 14px rgba(0,95,128,.35);
  --ds-icon-btn-active-shadow:0 4px 12px rgba(0,0,0,.14);
  --ds-overlay-border:#DCDCE0;
  --ds-overlay-shadow:0 8px 24px rgba(0,0,0,.12),0 2px 6px rgba(0,0,0,.07);

  /* Typografie */
  --ds-font-ui:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --ds-font-mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --ds-font-tool:Consolas,ui-monospace,'SF Mono',Menlo,monospace;

  /* Fokus-Ring */
  --ds-focus-ring:2px solid var(--ds-blue);
  --ds-focus-offset:2px;

  /* Radien, Motion, Touch */
  --ds-radius-sm:4px;                             /* Fokus-Ring */
  --ds-radius-md:6px;                             /* Container, Karten */
  --ds-radius-pill:999px;
  --ds-motion-fast:.15s;
  --ds-motion-medium:.3s;
  --ds-touch-min:32px;

  /* ---- Aliase (Kurznamen dieser Seite) ---- */
  --blue:var(--ds-blue);
  --blue-ink:var(--ds-blue-ink);
  --blue-hover:var(--ds-btn-primary-bg-hover);
  --blue-soft:var(--ds-blue-soft);
  --blue-border:var(--ds-blue-border);
  --chat-user-bg:var(--ds-chat-user-bg);
  --white:var(--ds-white);
  --black:var(--ds-black);
  --grey-bg:var(--ds-grey-bg);
  --grey-card:var(--ds-grey-card);
  --divider:var(--ds-grey-divider);
  --muted:var(--ds-grey-muted);
  --strong:var(--ds-grey-strong);
  --ui:var(--ds-font-ui);
  --mono:var(--ds-font-mono);
  --tool:var(--ds-font-tool);
  --r-focus:var(--ds-radius-sm);
  --r-container:var(--ds-radius-md);
  --r-pill:var(--ds-radius-pill);
  --overlay-border:var(--ds-overlay-border);
  --overlay-shadow:var(--ds-overlay-shadow);
  --primary-active-shadow:var(--ds-btn-primary-active-shadow);
  --icon-btn-active-shadow:var(--ds-icon-btn-active-shadow);
  --fast:var(--ds-motion-fast);
  --medium:var(--ds-motion-medium);

  /* Textmarkierung: Wert wie --ds-chat-user-bg, aber eigener Name — die
     Markierung der Seite darf nicht an einer Entscheidung ueber Chat-Bubbles
     haengen. */
  --selection-bg:rgba(0,117,158,.08);

  /* Rahmen von Bedienelementen (Sekundaer-Button, bedienbare Pille, Sprach-
     umschalter). --ds-grey-divider erreicht auf Weiss nur 1,17:1 und liegt
     damit unter der 3:1-Schwelle aus WCAG 1.4.11 fuer die Begrenzung, die ein
     Bedienelement erkennbar macht. Dieser Wert erreicht 3,1:1. Rein
     dekorative Rahmen (Karten, Panels, Chips) behalten --divider. */
  --ds-grey-control-border:#8A8A8E;
  --control-border:var(--ds-grey-control-border);

  /* Raster (aus Entwurf a1) */
  --gutter:24px;
  --cols:10;
}

/* ---------- Grundlagen ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;position:relative;background:var(--white);color:var(--black);
  font-family:var(--ui);font-size:16px;line-height:1.6;font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
h1,h2,h3,h4,p,ul,ol,dl,dd,figure,figcaption{margin:0}
ul,ol{padding:0;list-style:none}
img,svg{display:block;max-width:100%}
a{color:var(--blue);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}
a:hover{color:var(--blue-hover)}
button{font:inherit;color:inherit}

/* Fokus-Ring: Radius nur dort, wo das Element selbst keinen mitbringt —
   sonst wird der Ring an Pillen und Kreis-Buttons zum 4px-Rechteck. */
button:focus-visible,a:focus-visible,input:focus-visible,
summary:focus-visible,[tabindex]:focus-visible{
  outline:var(--ds-focus-ring);outline-offset:var(--ds-focus-offset);border-radius:var(--r-focus);
}
.btn:focus-visible,.icon-btn:focus-visible,.send:focus-visible,
.pill:focus-visible,.lang-btn:focus-visible,.head-nav a:focus-visible,
.skip:focus-visible{border-radius:inherit}
#main:focus-visible,#main:focus{outline:none}

::selection{background:var(--selection-bg)}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

.wrap{width:min(100% - 40px,1220px);margin-inline:auto}
.skip{
  position:absolute;left:-9999px;top:0;background:var(--white);color:var(--blue);
  padding:10px 16px;z-index:60;border:1px solid var(--blue);border-radius:var(--r-pill);
}
.skip:focus{left:16px;top:12px}

/* ---------- Spaltenraster (aus Entwurf a1) --------------------------------
   Absolut statt fixed und ohne vw-Einheit: die Linien liegen im selben
   Containing Block wie der Inhalt und koennen deshalb bei sichtbarer
   Scrollbar nicht gegen das Layout verrutschen. border-right sitzt am
   Container statt an :last-child, sonst fehlt die rechte Randlinie auf halber
   Hoehe, sobald die Spans umbrechen.
   -------------------------------------------------------------------------- */
.site-head,main,.site-foot{position:relative;z-index:1}

/* ---------- Bausteine, 1:1 aus der App ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:8px 18px;font-size:13px;font-weight:600;font-family:var(--ui);
  border:1px solid transparent;border-radius:var(--r-pill);
  cursor:pointer;box-shadow:none;text-decoration:none;white-space:nowrap;
  transition:background var(--fast),color var(--fast),border-color var(--fast),transform .1s,box-shadow .1s ease;
}
.btn-primary{background:var(--blue);color:var(--white)}
.btn-primary:hover{background:var(--blue-hover);color:var(--white)}
.btn-primary:active{transform:scale(.97);box-shadow:var(--primary-active-shadow)}
.btn-secondary{background:transparent;color:var(--black);border-color:var(--control-border)}
.btn-secondary:hover{border-color:var(--muted);color:var(--black)}
.btn-secondary:active{transform:scale(.97)}
.btn-lg{padding:11px 22px;font-size:14px}
/* Gesperrter Zustand sichtbar machen — Saeule 04 zeigt bewusst einen
   deaktivierten Knopf; ohne diese Regel sieht er aus wie ein bedienbarer. */
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-secondary:disabled:hover{background:transparent;border-color:var(--control-border);color:var(--black)}
.btn:disabled:active{transform:none;box-shadow:none}

.icon-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;padding:0;background:transparent;border:none;border-radius:50%;
  color:var(--strong);cursor:pointer;
  transition:background var(--fast),color var(--fast),transform .1s ease,box-shadow .1s ease;
}
.icon-btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.icon-btn-row{display:inline-flex;align-items:center;gap:0}
.icon-btn-row>:not(:last-child){margin-inline-end:-5px}

.badge{
  display:inline-block;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  padding:1px 7px;border-radius:var(--r-pill);border:1px solid var(--divider);color:var(--strong);white-space:nowrap;
}
.badge--blue{border-color:var(--blue-border);color:var(--blue)}
/* Zwei Hinweis-Badges nebeneinander: als Flex-Zeile, damit sie beim Umbruch
   nicht aneinanderkleben. */
.badge-row{display:flex;flex-wrap:wrap;gap:6px}
/* Lange Hinweis-Badges duerfen umbrechen. Mit dem geerbten nowrap setzt
   „shell_execute: kommt mit der naechsten Version“ eine Mindestbreite von
   rund 335px und schiebt bei 320px die ganze Saeule aus dem sichtbaren
   Bereich — wo sie von .section{overflow-x:clip} ohne Scrollbalken
   abgeschnitten wird. */
.badge--lg{padding:3px 9px;letter-spacing:.06em;white-space:normal}

.sec-label{
  font-family:var(--mono);font-size:11px;font-weight:600;text-transform:lowercase;
  color:var(--blue);margin-bottom:12px;
}
/* Zierzeichen stehen als aria-hidden-Span im Markup, damit Screenreader nicht
   vor jeder Abschnittsmarke "Schraegstrich Schraegstrich" sprechen. */
.deco{letter-spacing:-.14em;margin-right:.45em}
code,.mono{font-family:var(--mono)}
.inline-code{font-family:var(--mono);font-size:.92em;padding:1px 5px;border-radius:4px;background:var(--grey-card);color:var(--black)}

/* ---------- Kopf ---------- */
.site-head{
  position:sticky;top:0;z-index:40;background:var(--white);
  border-bottom:1px solid var(--divider);
}
.head-in{display:flex;align-items:center;gap:20px;min-height:56px}
.brand{
  display:inline-flex;align-items:center;gap:9px;min-height:var(--ds-touch-min);
  text-decoration:none;color:var(--black);
}
/* Das Zeichen der App selbst (dieselbe Datei, die im Dock und im Installer
   steht). Der Farbverlauf steckt in der Bilddatei, nicht im CSS — das „//“
   bleibt Abschnitts-Motiv (.deco, .sec-label) und ist keine Wortmarke. */
.brand-mark{
  width:26px;height:26px;flex-shrink:0;border-radius:var(--r-container);border:none;
}
.brand-name{font-size:15px;font-weight:600;letter-spacing:-.1px;white-space:nowrap}
.head-nav{margin-left:auto;display:flex;align-items:center;gap:4px}
.head-nav a{
  font-size:13px;font-weight:500;color:var(--strong);text-decoration:none;
  padding:6px 12px;border-radius:var(--r-pill);border:1px solid transparent;
  transition:border-color var(--fast),background var(--fast),color var(--fast);
}
.head-nav a:hover{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
.head-nav a[aria-current="true"]{border-color:var(--blue-border);background:var(--blue-soft);color:var(--blue)}
.lang{display:inline-flex;align-items:center;gap:2px;margin-left:10px;padding-left:14px;border-left:1px solid var(--divider)}
.lang-btn{
  font-family:var(--mono);font-size:12px;font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--ds-touch-min);padding:6px 10px;
  background:transparent;color:var(--strong);cursor:pointer;
  border:1px solid var(--control-border);border-radius:var(--r-pill);
  transition:border-color var(--fast),background var(--fast),color var(--fast);
}
.lang-btn:hover{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
.lang-btn[aria-pressed="true"]{border-color:var(--blue-border);background:var(--blue-soft);color:var(--blue)}
.head-cta{margin-left:12px}
@media(max-width:900px){.head-nav a[data-optional]{display:none}}
/* The German header with the Manual link needs about 996 px; below that the
   link goes first, and the footer carries it. */
@media(max-width:999px){.head-nav a[data-wide]{display:none}}
/* In German, Decisions, Download, Blog and the Download button do not fit
   side by side below about 710 px. */
@media(max-width:720px){.head-nav a[data-collapsible]{display:none}}
@media(max-width:640px){
  .head-cta{display:none}
  .lang{margin-left:0;padding-left:0;border-left:none}
}
@media(max-width:400px){
  .head-in{gap:10px;min-height:52px}
  .head-nav a{padding:6px 8px}
  .lang-btn{padding:6px 8px}
}
/* Below 360 px the Blog link no longer fits beside Download and DE/EN; the
   footer carries it there. */
@media(max-width:359px){.head-nav a[data-expendable]{display:none}}

/* ---------- Hinweis auf die englische Fassung (Issue #6) ----------
   Eine Leiste ueber dem Kopf, die mit wegscrollt: Sie verdeckt nichts und
   sieht nicht nach Cookie-Banner aus — die Seite hat keinen, und das soll
   man ihr ansehen. */
.lang-hint[hidden]{display:none}
.lang-hint{
  position:relative;z-index:41;font-size:14px;line-height:1.45;
  background:var(--blue-soft);border-bottom:1px solid var(--blue-border);
}
.lang-hint-in{display:flex;align-items:center;gap:4px 14px;min-height:44px;padding-block:2px}
.lang-hint-text{color:var(--black)}
.lang-hint-go{font-weight:500;white-space:nowrap}
.lang-hint-close{
  appearance:none;border:0;background:transparent;cursor:pointer;flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  width:var(--ds-touch-min);height:var(--ds-touch-min);margin-left:auto;margin-right:-10px;
  border-radius:var(--r-pill);font-size:20px;line-height:1;color:var(--muted);
  transition:background var(--fast),color var(--fast);
}
.lang-hint-close:hover{background:rgba(0,0,0,.05);color:var(--black)}
.lang-hint-close:active{transform:scale(.94)}
@media(max-width:560px){
  .lang-hint-in{display:grid;grid-template-columns:1fr auto;gap:0 8px;padding-block:8px}
  .lang-hint-go{grid-row:2}
  .lang-hint-close{grid-column:2;grid-row:1 / span 2}
}

/* ---------- Hero ---------- */
.hero{border-bottom:1px solid var(--divider);position:relative;overflow-x:clip}
/* Mass wie im gewaehlten Entwurf a2: die Schlagzeile bricht ueber ein
   schmaleres Mass, statt die volle Rasterbreite zu nehmen. Ab 1061px steht
   sie links und Beschreibung samt Knoepfen rechts daneben (Feedback: rechts
   fehlte etwas, das Fenster lag unter der Falz). */
.hero-text{padding:64px 0 46px;max-width:900px}
@media(min-width:1061px){
  .hero-text{
    max-width:none;padding-bottom:52px;
    display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,.8fr);
    column-gap:clamp(40px,5vw,88px);align-items:end;
  }
  .hero-text h1{margin-bottom:0}
  .hero-side{padding-bottom:6px}
  .hero-side .mission{margin-top:0}
}
h1{
  font-size:clamp(2.5rem,7.2vw,5.6rem);line-height:.97;font-weight:600;
  letter-spacing:-.038em;margin:0 0 28px;text-wrap:balance;
}
h1 .line2{display:block;color:var(--blue)}
/* The description sits inside the h1 on purpose: search engines weigh the
   main heading, and the slogan below it says nothing about what Snotra is. */
.h1-lead{
  display:block;font-size:clamp(1.125rem,2.1vw,1.625rem);line-height:1.25;
  letter-spacing:-.015em;font-weight:500;color:var(--black);
  margin-bottom:clamp(12px,1.6vw,20px);
}
/* Kein nowrap: die Telemetrie-Zeile traegt den Zusatz zur Versionsabfrage
   und muss bei 320px umbrechen duerfen, statt die Zeile aufzuspreizen. */
.mission{font-size:17px;line-height:1.6;color:var(--strong);max-width:62ch}
.mission strong{font-weight:600;color:var(--black)}
.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:30px}
.hero-note{margin-top:14px;font-size:13px;color:var(--strong)}

/* Fensterbuehne: volle Breite, das Fenster laeuft rechts aus dem Bild.
   Breitenrechnung ueber 100% statt 100vw — 100vw zaehlt die Scrollbar mit und
   erzeugte damit echten horizontalen Ueberlauf. */
.hero-stage{
  position:relative;overflow:hidden;background:var(--grey-bg);
  border-top:1px solid var(--divider);width:100%;
  display:flex;flex-wrap:wrap;align-items:flex-start;padding:46px max(20px,calc((100% - 1220px) / 2)) 22px;
}
/* Standflaeche des Fensters: eine Lineatur aus --divider-Haarlinien im
   28px-Raster. Das ist kein Farbverlauf und kein Schatten, sondern dieselbe
   Trennerfarbe, wiederholt — das Fenster steht damit auf etwas, ohne dass
   eine Flaeche abhebt. */
.hero-stage::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background-image:repeating-linear-gradient(to bottom,var(--divider) 0 1px,transparent 1px 28px);
}
.stage-caption{
  flex:1 0 100%;position:relative;z-index:3;margin-top:14px;
  font-family:var(--mono);font-size:11px;color:var(--strong);
}
@media(max-width:1180px){
  .hero-text{padding:56px 0 38px}
}

/* ---------- App-Fenster ----------------------------------------------------
   Ab hier gelten die Werte der ausgelieferten App.
   -------------------------------------------------------------------------- */
.appwin{
  /* 1:1 aus src/renderer/styles.css (:root, Light). Diese Werte sind NICHT
     durch Token-Grau zu ersetzen — sie sind der Grund, warum das nachgebaute
     Fenster wie Snotra Agent aussieht. Sie gelten ausschliesslich innerhalb von
     .appwin; ausserhalb gilt tokens.css. */
  --app-bg-secondary:#f3f3f3;   /* --bg-secondary : Sidebar / Dateibaum       */
  --app-bg-header:#e8e8e8;      /* --bg-header, --bg-tertiary, --bg-hover     */
  --app-bg-active:#d6d6d6;      /* --bg-active    : ausgewaehlte Zeile        */
  --app-border:#d4d4d4;         /* --border       : Fensterrahmen und Trenner */
  --app-scrollbar:#c1c1c1;      /* --scrollbar-thumb                          */

  position:relative;z-index:2;flex:0 0 auto;
  width:100%;max-width:none;
  background:var(--white);border:1px solid var(--app-border);border-radius:var(--r-container);
  /* Kein Schatten: das Fenster klappt nicht auf, es steht. Die Abgrenzung
     leistet der Rahmen auf dem grauen Buehnengrund. */
  box-shadow:none;overflow:hidden;
}
/* Scrollbalken im App-Grau nur im Fenster — das Website-Chrome behaelt die
   geprueften Systemscrollbalken. */
.appwin ::-webkit-scrollbar{width:10px;height:10px}
.appwin ::-webkit-scrollbar-thumb{
  background:var(--app-scrollbar);border-radius:5px;
  border:2px solid transparent;background-clip:content-box;
}
.appwin .icon-btn:hover{background:var(--app-bg-header);color:var(--black)}
.appwin .icon-btn:active,.appwin .icon-btn[aria-expanded="true"]{background:var(--app-bg-active);color:var(--black)}
.appwin .icon-btn:active{transform:scale(.97);box-shadow:var(--icon-btn-active-shadow)}

.win-title{
  height:44px;display:flex;align-items:center;gap:10px;padding:0 12px;
  background:var(--app-bg-header);border-bottom:1px solid var(--app-border);
}
.win-drag{width:70px;flex-shrink:0;display:flex;align-items:center;gap:7px}
.win-dot{width:11px;height:11px;border-radius:50%;background:var(--white);border:1px solid var(--app-border)}
.win-brand{font-size:15px;font-weight:600;letter-spacing:-.1px;white-space:nowrap}
.win-spacer{flex:1}
/* Hoehen in rem statt px: bei vergroesserter Schrift waechst der Kasten mit,
   statt Textzeilen mitten durchzuschneiden. */
.win-body{display:flex;height:45rem}

/* Sidebar / Dateibaum */
.win-side{width:260px;flex-shrink:0;background:var(--app-bg-secondary);border-right:1px solid var(--app-border);display:flex;flex-direction:column;overflow:hidden}
.tree-head{display:flex;align-items:center;gap:8px;padding:10px 8px 10px 16px;border-bottom:1px solid var(--app-border)}
.tree-head .name{font-size:13px;font-weight:600;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}
.tree-body{flex:1;overflow:hidden;padding:8px}
.tree-item{
  display:flex;align-items:center;height:1.625rem;padding-right:8px;font-size:14px;
  border-left:2px solid transparent;white-space:nowrap;cursor:default;transition:background .1s;
}
.tree-item:hover{background:var(--app-bg-header)}
.tree-item.active{background:var(--app-bg-active);border-left-color:var(--blue)}
.tree-item .ind{flex-shrink:0}
.tree-item .arw,.tree-item .ico{width:16px;height:16px;flex-shrink:0;fill:none;stroke:var(--strong);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.tree-item .ico{margin-right:4px}
.tree-item .arw.open{transform:rotate(90deg)}
.tree-item .lbl{overflow:hidden;text-overflow:ellipsis}

.win-divider{width:4px;flex-shrink:0;background:transparent}

/* Mittlere Spalte: Dateivorschau */
.win-mid{flex:1;min-width:0;display:flex;flex-direction:column;background:var(--white);border-right:1px solid var(--app-border)}
.prev-head{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--divider)}
.prev-name{font-size:13px;font-weight:600}
.prev-meta{
  font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.4px;
  padding:3px 9px;border-radius:var(--r-pill);background:var(--grey-card);color:var(--strong);margin-left:auto;
}
/* A Markdown file as the app's preview shows it by default: rendered, with
   the heading rule, the framed table and the grey header row of its
   .md-doc, scaled down to the mock-up. */
.prev-body{flex:1;overflow:hidden;padding:14px 16px}
.md-doc{font-size:12px;line-height:1.55;color:var(--black)}
.md-doc p{margin:0 0 .8em}
.md-doc .md-h1{font-size:15px;font-weight:600;line-height:1.25;letter-spacing:-.01em;padding-bottom:.3em;border-bottom:1px solid var(--divider);margin-bottom:.7em}
.md-doc .md-h2{font-size:13px;font-weight:600;line-height:1.3;margin:1.3em 0 .5em}
.md-doc table{border-collapse:collapse;font-size:11.5px;font-variant-numeric:tabular-nums;margin-bottom:.8em}
.md-doc th,.md-doc td{border:1px solid var(--divider);padding:3px 9px;text-align:left}
.md-doc th{background:var(--grey-bg);font-weight:600}
.md-doc ul{margin:0;padding-left:1.4em;list-style:disc}
.md-doc li{margin:.2em 0}

/* Chat-Panel */
.win-chat{width:520px;flex-shrink:0;display:flex;flex-direction:column;background:var(--grey-bg);border-left:1px solid var(--app-border);min-width:0}
.chat-head{display:flex;align-items:center;gap:8px;padding:12px 20px 10px}
.live-dot{width:8px;height:8px;border-radius:50%;background:var(--blue);flex-shrink:0}
.chat-title{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.chat-title>span{overflow:hidden;text-overflow:ellipsis}
.chat-head .icon-btn-row{margin-left:auto}
.chat-msgs{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:flex-end;gap:14px;padding:4px 20px 8px;overflow:hidden}
.msg{max-width:100%;font-size:15px;line-height:1.6;word-break:break-word}
.msg.user{
  align-self:flex-end;max-width:66.6667%;padding:9px 13px;border-radius:12px;
  background:var(--chat-user-bg);white-space:pre-wrap;
}
.msg.assistant{align-self:stretch;background:transparent;padding:0}
.msg.assistant+.msg.user,.msg.user+.msg.assistant{margin-top:16px}

/* Tool-Log — flach, monospaced, ohne Karte */
.tool-log{margin:0 0 4px;padding:0;border:none;background:transparent}
.tool-log>summary{list-style:none;cursor:pointer}
.tool-log>summary::-webkit-details-marker{display:none}
.tool-line{
  display:flex;align-items:flex-start;gap:6px;
  font-family:var(--tool);font-size:13px;line-height:1.5;letter-spacing:-.02em;
  color:var(--strong);padding:4px 0;margin:0;
}
.tool-line svg.tool-ico{width:15px;height:15px;margin-top:2px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.tool-extra{font-size:12px;color:var(--strong);font-variant-numeric:tabular-nums;flex-shrink:0}
.tool-chevron{width:14px;height:14px;margin-left:auto;flex-shrink:0;fill:none;stroke:var(--muted);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform var(--medium) ease-out;align-self:center}
.tool-log[open] .tool-chevron,.tool-log--static .tool-chevron{transform:rotate(90deg)}
.tool-lines{margin:4px 0 0;display:flex;flex-direction:column;gap:2px;max-height:11rem;overflow:hidden}
.tool-lines .tool-line{font-size:12px;padding:2px 0}
.tool-lines .tool-line svg.tool-ico{width:14px;height:14px}
.tool-line--done{color:var(--strong)}
/* Shimmer wie in der App (styles.css 1236 ff.), nur aus Variablen statt aus
   Hex-Werten. Die Bewegung wird nach wenigen Zyklen per JS stillgelegt
   (.tool-line--settled), damit nichts dauerhaft laeuft und der Text am Ende
   wieder auf vollem Kontrast steht. */
.tool-line--running .txt{
  --shimmer-base:var(--strong);
  --shimmer-highlight:color-mix(in srgb,var(--white) 72%,var(--blue) 28%);
  color:transparent;display:inline-block;
  background-image:linear-gradient(90deg,
    var(--shimmer-base) 0%,var(--shimmer-base) 40%,
    var(--shimmer-highlight) 50%,
    var(--shimmer-base) 60%,var(--shimmer-base) 100%);
  background-size:220% 100%;background-position:120% 0;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  animation:shimmer 1.85s ease-in-out infinite;
}
/* Ausserhalb von .appwin ist die laufende Tool-Zeile echter, vorlesbarer
   Seitentext (Saeule 03). Die App-Mischung (Weiss 72 %) faellt im Bandmaximum
   auf 1,4:1 und damit unter WCAG 1.4.3 — hier bleibt das Highlight blaeulich,
   aber dunkel genug: 5,7:1 auf --grey-bg, 6,1:1 auf Weiss. Innerhalb des
   Fensters bleibt der App-Wert unangetastet. */
.demo-surface--bare .tool-line--running .txt{
  --shimmer-highlight:color-mix(in srgb,var(--strong) 45%,var(--blue) 55%);
}
.tool-line--settled .txt{
  animation:none;background-image:none;color:var(--strong);
  -webkit-text-fill-color:currentColor;
}
@keyframes shimmer{0%{background-position:120% 0}100%{background-position:-120% 0}}

/* Freigabe-Karte */
.approval{
  margin:6px 0 8px;padding:14px 16px;border:1px solid var(--blue-border);
  border-radius:var(--r-container);background:var(--white);
  font-size:14px;line-height:1.5;color:var(--black);
}
.approval[data-state="allowed"],.approval[data-state="denied"]{border-color:var(--divider);color:var(--strong)}
.approval[data-state="allowed"] .approval-title,.approval[data-state="denied"] .approval-title{color:var(--strong);font-weight:500}
.approval-title{margin:0 0 4px;font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--blue)}
.approval-headline{margin:0 0 10px;font-size:15px;font-weight:600;overflow-wrap:anywhere}
.approval-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 12px;font-size:13px;margin:0}
.approval-facts dt{color:var(--strong);font-weight:500}
.approval-facts dd{margin:0;overflow-wrap:anywhere}
.approval-warn{margin:10px 0 0;padding:8px 10px;border-radius:var(--r-container);background:var(--grey-card);font-size:13px}
.approval-warn b{font-weight:600}
.approval-prev{margin:10px 0 0;border:1px solid var(--divider);border-radius:var(--r-container);background:var(--grey-bg)}
.approval-prev>summary{display:flex;align-items:center;gap:6px;padding:7px 10px;font-size:13px;color:var(--strong);cursor:pointer;list-style:none}
.approval-prev>summary::-webkit-details-marker{display:none}
.approval-prev-static{display:flex;align-items:center;gap:6px;margin:0;padding:7px 10px;font-size:13px;color:var(--strong)}
/* Chevron als SVG wie ueberall sonst auf der Seite — keine Textglyphen als
   UI-Element. */
.prev-chev{
  width:14px;height:14px;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--medium) ease-out;
}
.approval-prev[open] .prev-chev{transform:rotate(90deg)}
.approval-prevtext{
  margin:0;padding:8px 10px;border-top:1px solid var(--divider);
  font-family:var(--mono);font-size:12px;line-height:1.45;white-space:pre-wrap;color:var(--strong);
  max-height:220px;overflow:auto;
}
.approval-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.approval-hint{margin:10px 0 0;font-size:13px;color:var(--strong)}
.approval-result{margin:2px 0 0;font-size:13px;color:var(--strong)}
.approval-result b{font-weight:600;color:var(--black)}
.approval-replay{
  display:inline-flex;align-items:center;min-height:var(--ds-touch-min);
  margin-top:6px;padding:6px 2px;background:none;border:none;cursor:pointer;
  font-size:12px;color:var(--blue);text-decoration:underline;text-underline-offset:2px;
}

/* Composer */
.composer{
  display:flex;flex-direction:column;padding:4px 6px 6px;margin:8px 20px 20px;
  background:var(--white);border:1px solid var(--divider);border-radius:14px;
  transition:border-color var(--fast);
}
.composer:focus-within{border-color:var(--blue)}
.composer-text{
  min-height:36px;padding:10px 10px 6px;font-size:14px;line-height:1.45;color:var(--black);
  font-family:var(--ui);
}
.composer-text .ph{color:var(--muted)}
.caret{display:inline-block;width:1px;height:1.05em;background:var(--black);vertical-align:-.15em;margin-left:1px;animation:blink 1.1s steps(1,end) infinite}
@keyframes blink{0%,50%{opacity:1}51%,100%{opacity:0}}
.composer-bar{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:32px}
.composer-bar-start,.composer-bar-end{display:flex;align-items:center;gap:6px;min-width:0}
.pill{
  display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:var(--r-pill);
  border:1px solid var(--divider);background:var(--white);
  font-family:var(--mono);font-size:12px;color:var(--strong);cursor:pointer;white-space:nowrap;
  min-width:0;transition:border-color var(--fast),background var(--fast);
}
.pill:hover{border-color:var(--blue);background:var(--blue-soft)}
.pill svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.pill .chev{opacity:.55}
.pill>span{overflow:hidden;text-overflow:ellipsis}
.pill--mode{font-family:var(--ui);font-weight:500}
.pill--mode[data-active="true"]{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
.tokens{font-size:11px;line-height:1.3;padding:0 6px;color:var(--strong);font-variant-numeric:tabular-nums;white-space:nowrap;min-width:12ch;text-align:right}
.send{
  width:32px;height:32px;flex-shrink:0;border:none;border-radius:50%;
  background:var(--blue);color:var(--white);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  transition:background var(--fast),transform .1s ease,box-shadow .1s ease;
}
.send:hover{background:var(--blue-hover)}
.send:active{transform:scale(.97);box-shadow:var(--primary-active-shadow)}
.send svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* ---------- Hero-Demo: ein Auftrag, einmal durchgespielt (Issue #57) -------
   Das Markup ist das Endbild; app.js (Abschnitt 5) spielt davor. Gestapelte
   Zustaende teilen sich eine Rasterzelle, die groesste bestimmt die Hoehe —
   so belegt jeder Teil seinen Platz von Anfang an, und das Fenster aendert
   seine Groesse nie. Bewegt werden nur Deckkraft und Transform. */
.swap{display:grid}
.swap>*{grid-area:1/1;min-width:0}
.appwin .is-off{visibility:hidden;opacity:0}
.appwin.is-demo [data-at],.appwin.is-demo [data-until]{transition:opacity .28s ease-out,transform .28s ease-out,visibility 0s}
.appwin.is-demo .is-off{transition:opacity .16s ease-in,transform .16s ease-in,visibility 0s linear .16s}
.appwin.is-demo .chat-stack .is-off{transform:translateY(6px)}
/* Eine vorab leere Zeile zwischen zwei Dateien saehe falsch aus: Die neue
   Datei kommt wie in der App dazu, README.md rueckt eine Zeile nach unten. */
.appwin.is-demo .tree-item.is-off{display:none}

/* Der Chat scrollt mit wie in der App — per Transform, damit nichts auf der
   Seite verrutscht (app.js, follow()). */
.chat-stack{display:flex;flex-direction:column;gap:14px}
.appwin.is-demo .chat-stack{transition:transform .45s cubic-bezier(.2,.7,.2,1)}
.msg-greeting strong{font-weight:600}

/* Zugeklapptes Tool-Log: eine Zeile mit dem Symbol der Tool-Art. Das Doppel
   haelt die Hoehe der laengsten Fassung, falls sie umbricht. */
.tool-slot>.tool-line{margin:0}
.tool-ico-slot{display:grid;flex-shrink:0}
.tool-ico-slot>svg{grid-area:1/1;visibility:hidden}
.tool-line[data-cat="skill"] .tool-ico[data-cat="skill"],
.tool-line[data-cat="read"] .tool-ico[data-cat="read"],
.tool-line[data-cat="write"] .tool-ico[data-cat="write"]{visibility:visible}
.tool-line svg.tool-ico[viewBox="0 0 16 16"]{stroke-width:1.25}
.tool-text{flex:1;min-width:0}
.tool-ghost{visibility:hidden}
.tool-live .tool-extra{margin-left:.6ch}
/* Vor dem ersten Schritt pulsiert die Denk-Zeile, wie in der App. */
.tool-thinking .txt{animation:think-pulse 1.4s ease-in-out infinite}
@keyframes think-pulse{0%,100%{opacity:1}50%{opacity:.45}}

.approval-muted{color:var(--strong)}
.approval-foot{margin-top:12px}
.approval-foot .approval-actions{margin-top:0}
.approval-foot .approval-result{margin:0}
.approval-foot .approval-hint{margin-top:8px}
.appwin .btn-primary.is-pressed{transform:scale(.97);box-shadow:var(--primary-active-shadow);background:var(--blue-hover)}

.answer>p{margin:0}
.answer-live{display:none}
.appwin.is-demo .answer-live{display:block}
.appwin.is-demo .answer-ghost{visibility:hidden}

.composer-ghost{visibility:hidden}

/* Waehrend des Laufs wird Senden zu Abbrechen, und der Punkt im Kopf pulsiert. */
.send .stop-ico{display:none}
.appwin[data-running] .send{background:var(--black)}
.appwin[data-running] .send .send-ico{display:none}
.appwin[data-running] .send .stop-ico{display:block;fill:currentColor;stroke:none}
.appwin[data-running] .live-dot{animation:live-pulse .9s ease-in-out infinite}
@keyframes live-pulse{0%,100%{opacity:1}50%{opacity:.35}}

.appwin.is-paused,.appwin.is-paused *{animation-play-state:paused !important}

/* Der Zeiger steht fuer dich. */
.demo-pointer{
  position:absolute;left:0;top:0;z-index:6;width:22px;height:22px;margin:-2px 0 0 -5px;
  pointer-events:none;opacity:0;visibility:hidden;
  transition:transform .8s cubic-bezier(.35,.1,.25,1),opacity .2s ease,visibility 0s linear .2s;
}
.appwin.is-demo .demo-pointer.is-shown{
  opacity:1;visibility:visible;
  transition:transform .8s cubic-bezier(.35,.1,.25,1),opacity .2s ease,visibility 0s;
}
.demo-pointer.is-instant{transition:none !important}
.demo-pointer svg{display:block;width:100%;height:100%;fill:var(--black);stroke:var(--white);stroke-width:1.3;stroke-linejoin:round}

/* Anhalten / Abspielen unter dem Fenster (WCAG 2.2.2). */
.demo-toggle{
  display:inline-flex;align-items:center;gap:6px;margin-left:12px;min-height:28px;padding:3px 11px 3px 8px;
  border:1px solid var(--divider);border-radius:var(--r-pill);background:var(--white);color:var(--strong);
  font:inherit;cursor:pointer;vertical-align:middle;
}
.demo-toggle:hover{color:var(--black);border-color:var(--strong)}
.demo-toggle[hidden]{display:none}
.demo-toggle-ico{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.demo-toggle .i-play{fill:currentColor;stroke:none}
.demo-toggle .i-play,.demo-toggle .i-replay,
.demo-toggle[data-mode="paused"] .i-pause,.demo-toggle[data-mode="ended"] .i-pause{display:none}
.demo-toggle[data-mode="paused"] .i-play,.demo-toggle[data-mode="ended"] .i-replay{display:inline}

@media(max-width:1240px){
  .win-mid{display:none}
  /* Der Chat uebernimmt die frei werdende Breite, sonst steht rechts im
     Fenster bis 1060px hinunter eine leere Flaeche (bei 1100px: 416px). */
  .win-chat{width:auto;flex:1 1 auto}
}
@media(max-width:1060px){
  /* Feste Hoehe faellt weg: bei 768px wurde der Chat sonst mitten in einer
     Textzeile abgeschnitten. Lieber ein hohes Fenster als ein zerschnittenes. */
  .win-body{height:auto;min-height:30rem}
  .chat-msgs{overflow:visible}
}
@media(max-width:700px){
  .win-side{display:none}
  /* Auf dem Handy waere das Fenster mit allem, was im Lauf vorkommt, ueber
     1300px hoch und zu Beginn fast leer (Feedback: zu lang gezogen). Wie
     am Desktop bekommt der Chat eine feste Hoehe und scrollt mit (app.js,
     follow()); das Endbild sitzt unten. */
  .win-body{height:36rem;min-height:0;max-height:none}
  .chat-msgs{overflow:hidden}
}
@media(max-width:640px){
  /* Sonst ueberlappen Modus-Pille und Token-Zaehler, und der Senden-Knopf
     wird vom Fensterrand abgeschnitten. */
  .composer-bar{flex-wrap:wrap;row-gap:8px}
  .composer-bar-start{flex:1 1 100%;flex-wrap:wrap}
  .composer-bar-end{margin-left:auto}
  .tokens{display:none}
}

/* ---------- Zahlenzeile ---------- */
.numbers{border-bottom:1px solid var(--divider)}
.numbers-grid{display:grid;grid-template-columns:repeat(var(--cols),1fr);column-gap:var(--gutter)}
.num{grid-column:span 2;padding:26px 0 24px 16px;border-left:1px solid var(--divider)}
.num:first-child{border-left:none;padding-left:0}
.num .v{
  display:block;
  font-family:var(--mono);font-size:clamp(30px,3.6vw,46px);font-weight:600;line-height:1;
  letter-spacing:-.04em;color:var(--blue);font-variant-numeric:tabular-nums;
}
/* Das Unendlich-Zeichen ist in Mono auf feste Zeichenbreite gequetscht und
   schert neben den Ziffern aus. */
.num .v--inf{font-family:var(--ui);letter-spacing:-.02em}
.num .k{display:block;margin-top:8px;font-size:13px;color:var(--strong);line-height:1.35}

/* ---------- Blaue Klammer ---------- */
.claim{background:var(--blue);color:var(--white);padding:74px 0}
/* Selektor mit .claim davor, damit die h2-Basisregel nicht gewinnt:
   (0,2,0) schlaegt (0,0,1). Die Darstellung bleibt unveraendert. */
.claim .big{
  font-size:clamp(1.8rem,4.6vw,3.6rem);line-height:1.04;font-weight:600;letter-spacing:-.03em;
  max-width:20ch;
}
.claim .small{margin-top:22px;font-size:clamp(1rem,1.6vw,1.25rem);font-weight:400;max-width:46ch;color:var(--white)}
.claim .rule{width:64px;height:2px;background:var(--white);margin-bottom:26px}

/* ---------- Abschnittskoepfe ---------- */
/* overflow-x:clip statt hidden: der negative Aussenrand von .pillar-demo darf
   abgeschnitten werden, ohne dass ein Scroll-Container entsteht — der wuerde
   position:sticky im Kopf ausser Kraft setzen. clip schneidet lautlos ab,
   deshalb gehoert zu jeder Breitenaenderung eine Messung (siehe .badge--lg). */
.section{padding:80px 0;border-bottom:1px solid var(--divider);overflow-x:clip}
.sec-head{max-width:46ch;margin-bottom:8px}
h2{font-size:clamp(1.8rem,3.6vw,2.9rem);line-height:1.06;font-weight:600;letter-spacing:-.028em}
.sec-sub{margin-top:14px;font-size:16px;color:var(--strong);max-width:56ch}

/* ---------- Saeulen ---------- */
.pillars{margin-top:52px;border-top:1px solid var(--divider)}
.pillar{
  position:relative;
  display:grid;grid-template-columns:minmax(0,44fr) minmax(0,56fr);gap:0;
  border-bottom:1px solid var(--divider);
}
/* Markierung der gerade gelesenen Saeule (aus Entwurf a3) — sie markiert nur,
   sie dimmt nichts: alle vier Demos bleiben voll sichtbar und bedienbar. */
.pillar::before{
  content:"";position:absolute;left:-20px;top:0;bottom:0;width:2px;
  background:var(--blue);opacity:0;transition:opacity var(--medium) ease;
}
.js .pillar.is-current::before{opacity:1}
.pillar-text{padding:36px 48px 40px 0}
.pillar-no{
  font-family:var(--mono);font-size:13px;font-weight:600;color:var(--blue);
  letter-spacing:.04em;display:flex;align-items:center;gap:10px;margin-bottom:16px;
}
.pillar-no .word{color:var(--strong);text-transform:uppercase;letter-spacing:.1em;font-size:11px}
.pillar h3{font-size:clamp(1.25rem,2.1vw,1.7rem);line-height:1.15;font-weight:600;letter-spacing:-.02em;margin-bottom:12px}
.pillar p{font-size:15px;line-height:1.6;color:var(--strong);max-width:48ch}
.pillar p+p{margin-top:10px}
.pillar-demo{
  padding:28px 0 34px 40px;border-left:1px solid var(--divider);background:var(--grey-bg);
  display:flex;flex-direction:column;justify-content:center;gap:12px;min-width:0;
  margin-right:calc(-1 * max(20px,(100vw - 1220px) / 2));padding-right:max(20px,(100vw - 1220px) / 2);
}
.demo-cap{font-family:var(--mono);font-size:11px;color:var(--strong)}
.demo-surface{background:var(--white);border:1px solid var(--divider);border-radius:var(--r-container);padding:14px 16px;min-width:0}
.demo-surface--bare{background:transparent;border:none;padding:0}
.demo-hint{margin-top:14px}
@media(max-width:980px){
  .pillar{grid-template-columns:1fr}
  .pillar::before{left:-12px}
  .pillar-text{padding:32px 0 22px}
  .pillar-demo{border-left:none;border-top:1px solid var(--divider);padding:24px 0 30px;margin-right:calc(50% - 50vw);padding-inline:max(20px,calc(50vw - 610px))}
}

/* Modell-Pille (bedienbar) und ihr Overlay-Menue */
.picker{position:relative;display:inline-flex}
.pill--control{
  border-color:var(--control-border);min-height:var(--ds-touch-min);padding:6px 12px;
}
.overlay-menu{
  position:absolute;top:calc(100% + 6px);left:0;z-index:20;
  /* Bei 320px reicht eine feste Mindestbreite von 268px ueber den Viewport
     hinaus und wird von .section{overflow-x:clip} abgeschnitten. */
  min-width:min(268px,100%);max-width:calc(100vw - 40px);
  background:var(--white);border:1px solid var(--overlay-border);border-radius:var(--r-container);
  /* Der einzige Ort, an dem eine Flaeche abheben darf: ein Menue schwebt
     ueber dem Inhalt, den es verdeckt. */
  box-shadow:var(--overlay-shadow);padding:6px 0;margin:0;
}
.overlay-menu[hidden]{display:none}
.overlay-menu li button{
  display:flex;align-items:center;gap:10px;width:100%;padding:8px 12px;
  background:none;border:none;text-align:left;cursor:pointer;font-size:13px;
  transition:background var(--fast);
}
.overlay-menu li button:hover{background:var(--blue-soft)}
.overlay-menu .m-name{font-family:var(--mono);font-size:12px;color:var(--black);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.overlay-menu .m-tag{margin-left:auto;font-size:11px;color:var(--strong)}
.overlay-menu button[aria-checked="true"] .m-name{color:var(--blue);font-weight:600}

/* Skill-Datei */
.filecard{border:1px solid var(--divider);border-radius:var(--r-container);background:var(--white);overflow:hidden}
.filecard-head{display:flex;align-items:center;gap:8px;padding:9px 12px;border-bottom:1px solid var(--divider);background:var(--white)}
.filecard-head svg{width:14px;height:14px;flex-shrink:0;fill:none;stroke:var(--strong);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.filecard-head .p{font-family:var(--mono);font-size:12px;color:var(--strong);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.filecard-head .badge{margin-left:auto}
/* SKILL.md as the app's preview colours Markdown source since 1.15.2:
   front-matter keys and headings in the accent, the marks grey, code in
   backticks green. Colour only, no weight, as in the app. */
.filecard-body{margin:0;padding:12px;background:var(--grey-card);font-family:var(--mono);font-size:12px;line-height:1.5;color:var(--black);overflow-x:auto}
.filecard-body .syn-prop{color:var(--blue-ink)}
.filecard-body .syn-k{color:var(--blue)}
.filecard-body .syn-p{color:var(--strong)}
.filecard-body .syn-s{color:var(--ds-syntax-string)}
.minitree{display:flex;flex-direction:column;gap:0;font-family:var(--mono);font-size:12px;color:var(--strong)}
.minitree .row{display:flex;align-items:center;gap:6px;height:24px}
.minitree .row.on{color:var(--blue)}
.minitree .row--in{padding-left:18px}
.minitree svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}

/* CLI-Band */
.cli-strip{display:flex;flex-wrap:wrap;gap:6px}
.cli-chip{
  font-family:var(--mono);font-size:12px;padding:3px 9px;border-radius:var(--r-pill);
  border:1px solid var(--divider);color:var(--strong);background:var(--white);
}
.cli-chip.on{border-color:var(--blue-border);color:var(--blue)}

/* MCP-Server-Liste (Saeule 03)
   Bewusst keine cli-chips: Ein MCP-Server ist kein Befehl in einer Reihe,
   sondern ein eingetragener Anschluss mit eigener Zeile. Dieselbe Mono-Groesse
   wie .cli-chip und .minitree, damit die drei Demos einer Saeule zusammengehoeren. */
.mcp-list{display:flex;flex-direction:column;gap:2px;margin:0;padding:0;list-style:none}
.mcp-row{
  display:flex;align-items:center;gap:8px;min-height:24px;
  font-family:var(--mono);font-size:12px;color:var(--strong);
}
.mcp-ico{
  width:14px;height:14px;flex-shrink:0;
  fill:none;stroke:var(--blue);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;
}
.mcp-name{color:var(--blue)}
/* auto statt fester Spalte: "9 Werkzeuge" und "9 tools" sind verschieden lang,
   eine Grid-Spalte muesste fuer beide Sprachen geraten werden.
   --strong statt --muted: bei 11px gilt die Regel fuer Text < 14px. */
.mcp-tools{margin-left:auto;color:var(--strong);font-size:11px}

/* ---------- Einsatzfelder ---------- */
.fields{
  display:grid;grid-template-columns:repeat(var(--cols),1fr);column-gap:var(--gutter);
  margin-top:44px;border-top:1px solid var(--divider);border-bottom:1px solid var(--divider);
}
.field{grid-column:span 2;padding:28px 0 30px 16px;border-left:1px solid var(--divider)}
.field:nth-child(1),.field:nth-child(2){grid-column:span 3}
.field:first-child{border-left:none;padding-left:0}
.field h3{font-size:18px;font-weight:600;letter-spacing:-.01em;margin-bottom:12px}
.field ul{display:flex;flex-direction:column;gap:8px}
.field li{display:flex;gap:9px;font-size:14px;line-height:1.45;color:var(--strong)}
.field li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--blue);flex-shrink:0;margin-top:8px}

/* ---------- Download ---------- */
.dl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:40px}
.dl{
  border:1px solid var(--divider);border-radius:var(--r-container);background:var(--white);
  padding:22px;display:flex;flex-direction:column;gap:6px;
  transition:border-color var(--fast),background var(--fast);
}
/* Der Wash gehoert zum Knopf, nicht zur Flaeche — die Karte selbst ist nicht
   klickbar, und ein Einladungs-Signal auf einer toten Flaeche geht ins Leere. */
.dl:has(.btn:hover),.dl:focus-within{border-color:var(--blue);background:var(--blue-soft)}
.dl h3{font-size:17px;font-weight:600}
.dl .spec{font-family:var(--mono);font-size:12px;color:var(--strong)}
.dl .btn{margin-top:14px;align-self:flex-start}
.dl .alt{margin-top:10px;font-size:13px;color:var(--strong)}

/* Hinweis fuer Telefon und Tablet. Kein display hier: der Hinweis haengt am
   hidden-Attribut, das app.js nur auf solchen Geraeten abnimmt. */
.dl-mobile{
  margin-top:36px;border:1px solid var(--blue-border);border-radius:var(--r-container);
  background:var(--blue-soft);padding:16px 18px;
  font-size:14px;line-height:1.5;color:var(--strong);max-width:70ch;
}
@media(max-width:820px){.dl-grid{grid-template-columns:1fr}}

/* ---------- Unsignierte Builds ---------- */
.unsigned{margin-top:44px;border:1px solid var(--divider);border-radius:var(--r-container);background:var(--grey-bg);padding:26px}
.unsigned h3{font-size:18px;font-weight:600;margin-bottom:10px}
.unsigned>p{font-size:14px;color:var(--strong);max-width:70ch}
.unsigned-cols{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:20px}
.unsigned-col{background:var(--white);border:1px solid var(--divider);border-radius:var(--r-container);padding:16px 18px}
.unsigned-col h4{font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--blue);margin-bottom:10px}
.unsigned-col ol{counter-reset:s;display:flex;flex-direction:column;gap:8px}
/* The counter sits in the padding rather than in a flex row: as a flex
   container the li would turn every text run and every <code> (data-i18n-code)
   into an item of its own, and a step would break into columns. */
.unsigned-col li{counter-increment:s;position:relative;padding-left:30px;font-size:14px;line-height:1.45;color:var(--strong)}
.unsigned-col li::before{
  content:counter(s);position:absolute;left:0;top:1px;width:20px;height:20px;border-radius:50%;
  border:1px solid var(--blue-border);color:var(--blue);
  font-family:var(--mono);font-size:11px;font-weight:600;display:grid;place-items:center;
}
/* A file name is one word to the reader: it moves to the next line whole
   instead of splitting at its space. */
.unsigned-col li code{white-space:nowrap}
@media(max-width:680px){.unsigned-cols{grid-template-columns:1fr}.unsigned{padding:20px}}

/* ---------- Fuss ---------- */
.site-foot{padding:34px 0 44px}
.foot-in{display:flex;flex-wrap:wrap;gap:14px 28px;align-items:center;justify-content:space-between}
.foot-links{display:flex;flex-wrap:wrap;gap:8px 20px;align-items:center}
.foot-in p{font-size:13px;color:var(--strong)}
.foot-links a{
  display:inline-flex;align-items:center;min-height:var(--ds-touch-min);
  padding:6px 4px;font-size:13px;color:var(--strong);text-decoration:none;
}
.foot-links a:hover{color:var(--blue);text-decoration:underline}

/* ---------- Umbrueche des Rasters ---------- */
@media(max-width:980px){
  :root{--cols:4}
  .num{grid-column:span 2}
  /* Erste Zahl jeder Zeile buendig, wie .field:nth-child(odd) — sonst haengt
     an Zeile 2 und 3 eine Trennlinie am linken Rasterrand. */
  .num:nth-child(odd){border-left:none;padding-left:0}
  .num:last-child{grid-column:1 / -1}
  .field,.field:nth-child(1),.field:nth-child(2){grid-column:span 2}
  .field{border-top:1px solid var(--divider);padding:24px 0 26px 16px}
  .field:nth-child(odd){border-left:none;padding-left:0}
  .field:nth-child(-n+2){border-top:none}
    }
@media(max-width:560px){
  :root{--cols:2}
  .num{grid-column:span 1}
  .num:nth-child(odd){border-left:none;padding-left:0}
  .field,.field:nth-child(1),.field:nth-child(2){grid-column:1 / -1;border-left:none;padding-left:0}
  .field:nth-child(2){border-top:1px solid var(--divider)}
}

/* ---------- Reveal ---------- */
.js .reveal{opacity:0;transform:translateY(14px);transition:opacity .5s ease,transform .5s ease}
.js .reveal.is-in{opacity:1;transform:none}
/* Notbremse: das Inline-Script hat .reveal versteckt, app.js hat sich aber
   nicht gemeldet (404, Blocker, Syntaxfehler) — Inhalt sofort zeigen. */
.no-reveal .reveal{opacity:1 !important;transform:none !important;transition:none}

/* Bauteile, die ohne app.js nur Behauptungen waeren: lieber nicht zeigen, als
   einen Zustand melden, den ein Klick nicht einloest (WCAG 4.1.2). Der
   deutsche Text der Seite steht vollstaendig im HTML und bleibt sichtbar. */
html:not(.js) .lang{display:none}
html:not(.js) .approval[data-demo] .approval-actions{display:none}
html:not(.js) .picker{pointer-events:none}

@media (prefers-reduced-motion: reduce){
  /* Sicherheitsnetz zuerst, damit kuenftige Animationen nicht durchrutschen. */
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important;
  }
  .js .reveal{opacity:1;transform:none;transition:none}
  .tool-line--running .txt{animation:none;color:var(--strong);background-image:none;-webkit-text-fill-color:currentColor}
  .caret{animation:none;display:none}
  .tool-chevron,.prev-chev,.pillar::before{transition:none}
  .btn:active,.icon-btn:active,.send:active{transform:none}
}

/* ==========================================================================
   Rechtstexte (impressum.html, datenschutz.html)
   Beide Seiten binden dieselbe styles.css ein und bleiben unveraendert —
   diese Regeln halten sie lesbar.
   ========================================================================== */
.site-header{
  position:sticky;top:0;z-index:40;background:var(--white);
  border-bottom:1px solid var(--divider);
}
.header-inner{display:flex;align-items:center;gap:20px;min-height:56px}
/* Nur der Kopf der Rechtsseiten: die Startseite setzt ihr Zeichen ueber
   .brand-mark auf 26px (Kopfhoehe 56px). */
.site-header .brand img{width:32px;height:32px;border-radius:var(--r-container)}
.site-header nav{margin-left:auto;display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.site-header nav a{color:var(--strong);text-decoration:none;font-size:13px}
.site-header nav a:hover{color:var(--blue)}
/* On a phone the header keeps one row: the brand, one link and DE/EN. The
   link marked data-expendable goes (GitHub is in the footer, and the brand
   already leads home), and the spacing tightens. Without this the German legal
   notice wrapped up to 424 px, and at 320 px it has 3 px to spare. */
@media(max-width:440px){
  .header-inner{gap:10px}
  .site-header nav{gap:12px}
  .site-header nav a[data-expendable]{display:none}
}
/* The blog header also carries the Manual link (issue #118). With GitHub gone
   it still fits in German down to about 343 px; below 360 it goes as well. */
@media(max-width:359px){.site-header nav a[data-wide]{display:none}}
.legal{padding:56px 0 72px}
/* Bis app.js auf snotra-ai.dev uebersetzt hat (Issue #71, Skript im <head>). */
.i18n-wait main.legal,.i18n-wait .site-header nav{visibility:hidden}
.legal .wrap{width:min(100% - 40px,760px)}
.legal h1{font-size:clamp(1.75rem,4vw,2.25rem);line-height:1.1;margin-bottom:18px}
.legal h2{font-size:1.25rem;margin-top:40px;margin-bottom:10px;scroll-margin-top:80px}
.legal h3{font-size:1rem;font-weight:600;margin-top:24px;margin-bottom:6px}
.legal p,.legal li{color:var(--strong);font-size:15px}
.legal p{margin-bottom:12px}
.legal ul,.legal ol{list-style:revert;padding-left:22px;margin-bottom:12px}
.legal li{margin-bottom:6px}
.legal .back{display:inline-block;margin-bottom:28px;font-size:15px}
.site-footer{border-top:1px solid var(--divider);padding:32px 0;background:var(--white)}
.footer-inner{
  display:flex;flex-wrap:wrap;gap:14px 28px;align-items:center;justify-content:space-between;
  color:var(--strong);font-size:13px;
}
.footer-inner p{margin:0}
.site-footer nav{display:flex;flex-wrap:wrap;gap:8px 20px}
.site-footer nav a{
  display:inline-flex;align-items:center;min-height:var(--ds-touch-min);
  color:var(--strong);text-decoration:none;
}
.site-footer nav a:hover{color:var(--blue);text-decoration:underline}

/* ==========================================================================
   Blog (blog/index.html, blog/*.html) — issue #33
   Articles are English on both domains; only the frame around them (header,
   footer, the overview's intro) follows the language of the domain. The
   header and footer are the legal pages' ones above.
   ========================================================================== */
.i18n-wait .site-footer nav{visibility:hidden}
.post{padding:48px 0 88px}
.post-wrap{width:min(100% - 40px,680px)}
.post-kicker{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--blue);margin-bottom:20px}
.post-kicker a{color:inherit;text-decoration:none}
.post-kicker a:hover{text-decoration:underline}
/* Only on snotra-ai.de (and wherever the frame is German): the head script
   sets lang="de" before the first paint, so the note never moves anything. */
.post-lang-note{display:none;color:var(--strong);font-weight:400}
html[lang="de"] .post-lang-note{display:inline}

.post-head h1{font-size:clamp(2rem,5vw,2.75rem);line-height:1.12;font-weight:600;letter-spacing:-.025em;overflow-wrap:break-word}
/* A compound that would otherwise break at its hyphen ("open- / source"). */
.post .nowrap{white-space:nowrap}
.post-dek{margin-top:16px;font-size:clamp(1.125rem,2.2vw,1.3rem);line-height:1.5;color:var(--strong)}
/* On a phone the line breaks between its parts, never inside the name, the
   date or the reading time. */
.post-meta{display:flex;flex-wrap:wrap;margin-top:22px;font-family:var(--mono);font-size:12px;color:var(--strong)}
.post-meta > *{white-space:nowrap}
.post-meta-sep{margin:0 .6em}

.post-body{margin-top:40px;font-size:17px;line-height:1.7;overflow-wrap:break-word}
.post-body>*+*{margin-top:1.1em}
.post-body h2{font-size:1.5rem;line-height:1.25;font-weight:600;letter-spacing:-.015em;margin-top:2.2em;scroll-margin-top:80px}
.post-body h3{font-size:1.125rem;line-height:1.35;font-weight:600;margin-top:1.8em;scroll-margin-top:80px}
.post-body h2+*,.post-body h3+*{margin-top:.55em}
.post-body ul,.post-body ol{list-style:revert;padding-left:1.4em}
.post-body li+li{margin-top:.35em}
.post-body li::marker{color:var(--strong)}
.post-body a{overflow-wrap:anywhere}
.post-body blockquote{margin-inline:0;padding-left:20px;border-left:2px solid var(--blue);color:var(--strong)}
.post-body :not(pre)>code{font-family:var(--mono);font-size:.88em;padding:1px 5px;border-radius:4px;background:var(--grey-card);overflow-wrap:anywhere}
.post-body pre{
  overflow-x:auto;padding:16px 18px;background:var(--grey-bg);border:1px solid var(--divider);
  border-radius:var(--r-container);font-size:14px;line-height:1.6;tab-size:2;
}
.post-body pre code{font-family:var(--mono)}
.post-body kbd{
  font-family:var(--mono);font-size:.85em;padding:1px 6px;border:1px solid var(--control-border);
  border-bottom-width:2px;border-radius:4px;background:var(--white);
}
.post-body figure{margin-block:1.8em}
/* Screenshots are taken at 2x and shown at the size they have in the app:
   width and height name half the file's pixels. One wider than the text
   column shrinks to fit it; a small one is not blown up to the column and
   sits in its middle, while the caption stays with the text. */
.post-body figure img{height:auto;margin-inline:auto;border:1px solid var(--divider);border-radius:var(--r-container)}
/* A diagram is an inline SVG, so its text stays text and uses the page's
   font. Below its minimum width it scrolls inside its frame like a table,
   rather than shrinking its labels below reading size. */
.post-diagram{overflow-x:auto;border:1px solid var(--divider);border-radius:var(--r-container);padding:16px}
.post-diagram svg{display:block;width:100%;min-width:600px;height:auto}
/* The diagram's vocabulary, in the site's colours. It lives here and not in
   a <style> inside the SVG, which the test suite's parser cannot read. */
.post-diagram .d-t{font-size:17px;font-weight:600;fill:var(--black)}
.post-diagram .d-s{font-size:12px;fill:var(--strong)}
.post-diagram .d-strong{font-weight:600}
.post-diagram .d-h{font-size:13px;font-weight:600;fill:var(--black)}
.post-diagram .d-l{font-size:11.5px;fill:var(--strong)}
.post-diagram .d-sm{font-size:10.5px}
.post-diagram .d-w{font-size:11.5px;fill:var(--blue-ink)}
.post-diagram .d-stamp{font-size:10px;fill:var(--strong)}
.post-diagram .d-box{fill:var(--white);stroke:#C9CBD0;stroke-width:1}
.post-diagram .d-grp{fill:var(--grey-bg);stroke:#C9CBD0;stroke-width:1}
.post-diagram .d-core{fill:var(--blue)}
.post-diagram .d-core-h{font-size:13px;font-weight:600;fill:var(--white)}
.post-diagram .d-core-l{font-size:11.5px;fill:var(--white)}
.post-diagram .d-pill{fill:#E6F1F5;stroke:var(--blue-border);stroke-width:1}
.post-diagram .d-pill-inv{fill:var(--white)}
.post-diagram .d-pill-t{font-size:10.5px;font-weight:600;fill:var(--blue-ink)}
.post-diagram .d-line{stroke:#6D6D6D;stroke-width:1.2;fill:none}
.post-diagram .d-arrow{fill:#6D6D6D}
.post-diagram .d-bound{fill:none;stroke:#8A8D93;stroke-width:1.2;stroke-dasharray:6 4}
.post-body figcaption{margin-top:10px;font-size:14px;line-height:1.5;color:var(--strong)}
.post-table{overflow-x:auto}
.post-body table{border-collapse:collapse;width:100%;min-width:480px;font-size:15px;line-height:1.5}
.post-body th,.post-body td{text-align:left;vertical-align:top;padding:9px 14px 9px 0;border-bottom:1px solid var(--divider)}
.post-body th{font-weight:600;border-bottom-color:var(--control-border)}
/* A comparison has to be read across its columns, so it fits the width
   instead of scrolling: on a phone the scrolled-away column would be the one
   the comparison is about. */
.post-table--fit table{min-width:0}
@media(max-width:480px){
  .post-table--fit table{font-size:14px;line-height:1.45}
  .post-table--fit th,.post-table--fit td{padding-right:10px}
}
.post-body hr{border:0;border-top:1px solid var(--divider);margin-block:2.4em}

/* AI disclosure (EU AI Act, Art. 50(4)): marked in the meta line, stated below the text. */
.post-meta a.post-meta-ai{color:inherit;text-decoration:underline;text-decoration-color:var(--divider);text-underline-offset:3px}
.post-meta a.post-meta-ai:hover{text-decoration-color:currentColor}
.post-ai-note{margin-top:48px;padding-top:18px;border-top:1px solid var(--divider);font-size:15px;line-height:1.6;color:var(--strong);scroll-margin-top:80px}
.post-ai-note strong{color:var(--black)}
.post-ai-note + .post-foot{margin-top:32px}

.post-foot{
  margin-top:56px;padding:24px 26px;border:1px solid var(--blue-border);
  border-radius:var(--r-container);background:var(--blue-soft);
}
.post-foot-title{font-weight:600;font-size:1.125rem}
.post-foot p+p{margin-top:8px}
.post-foot p{color:var(--strong)}
.post-foot .post-foot-title{color:var(--black)}
.post-foot-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px !important}
/* A code span that breaks across lines keeps its padding and corners on both halves. */
.post-body :not(pre)>code{-webkit-box-decoration-break:clone;box-decoration-break:clone}

/* ---------- Blog overview ---------- */
.i18n-wait .blog-index [data-i18n]{visibility:hidden}
.blog-index-h1{font-size:clamp(2rem,5vw,2.75rem);line-height:1.12;font-weight:600;letter-spacing:-.025em}
.post-list{margin-top:48px;border-top:1px solid var(--divider)}
.post-item{padding:26px 0 28px;border-bottom:1px solid var(--divider)}
.post-item time{display:block;font-family:var(--mono);font-size:12px;color:var(--strong)}
.post-item h2{margin-top:8px;font-size:1.375rem;line-height:1.3;font-weight:600;letter-spacing:-.015em;overflow-wrap:break-word}
.post-item h2 a{color:var(--black);text-decoration:none}
.post-item h2 a:hover{color:var(--blue);text-decoration:underline}
.post-item p{margin-top:8px;color:var(--strong)}
