/* ==========================================================================
   agencyg.de, Gestaltungsgrundlage
   --------------------------------------------------------------------------
   Ersetzt 32 gewachsene Schriftgroessen durch sieben Stufen, zehn unverbundene
   Abstaende durch ein Viererraster, vier Knopfhoehen durch drei und vier
   Farbwelten durch eine.

   Warum ueberhaupt: die Ueberschrift der Startseite stand bei 96px auf vier
   Zeilen, die Knoepfe bei 60px, und der wichtigste Kaufknopf hatte weissen Text
   auf Tuerkis mit einem Kontrast von 1,86 zu 1. Kleinere Schrift ist nur dann
   eine Verbesserung, wenn der Kontrast gleichzeitig steigt. Beides steht
   deshalb in einer Datei und geht nur gemeinsam raus.

   Reihenfolge der Schichten: Typografie, Raum, Farbe, Bauteile.
   ========================================================================== */

/* --- Schicht 1: Typografie ---------------------------------------------- */
:root{
  /* feste Stufen, kein clamp, keine Zwischenwerte */
  --fs-1: 0.75rem;   /* 12px, harte Untergrenze der ganzen Seite */
  --fs-2: 0.875rem;  /* 14px */
  --fs-3: 1rem;      /* 16px */

  /* fluide Stufen, Wachstumsfenster 390px bis 1440px, darueber gedeckelt.
     Der Deckel ist der Grund, warum die Seite auf einem breiten Monitor nicht
     weiterwaechst. Die alten vw-Formeln erzeugten dort 100px. */
  --fs-4: clamp(1rem,     0.954rem + 0.190vw, 1.125rem); /* 16,0 auf 18,0 */
  --fs-5: clamp(1.125rem, 0.986rem + 0.571vw, 1.5rem);   /* 18,0 auf 24,0 */
  --fs-6: clamp(1.5rem,   1.314rem + 0.762vw, 2rem);     /* 24,0 auf 32,0 */
  --fs-7: clamp(2rem,     1.443rem + 2.286vw, 3.5rem);   /* 32,0 auf 56,0 */

  /* genau drei Zeilenhoehen fuer die ganze Seite, vorher sechs */
  --lh-1: 1.05;  /* nur das h1 */
  --lh-2: 1.20;  /* h2, h3, Kartentitel, Knopfbeschriftung, Kennzahl */
  --lh-3: 1.55;  /* jeder Fliesstext, jede Merkmalszeile, das Terminal */

  --fw-body: 400;
  --fw-ui:   500;
  --fw-head: 600;
  --fw-max:  700;  /* nur h1, Preis, Wortmarke. Vorher stand hier 900. */

  --ls-h1:   -0.02em;
  --ls-h2:   -0.015em;
  --ls-over:  0.08em;   /* nur Versalien auf --fs-1 */
  --ls-mark:  0.16em;   /* Wortmarke */
}

/* --- Schicht 2: Raum ---------------------------------------------------- */
:root{
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px; --sp-5: 24px;
  --sp-6: 32px; --sp-7: 48px; --sp-8: 64px; --sp-9: 96px;

  /* ersetzt 144/128/96/92/80/72/64/48/40/36/32/16 */
  --section-y:      clamp(3rem, 4.4vw, 5.5rem);
  --section-y-show: clamp(4rem, 5.6vw, 7rem);

  --wrap: 1200px;
  --gutter:   clamp(1.25rem, 3.2vw, 2.5rem);
  --grid-gap: clamp(1rem, 2vw, 2rem);
  --header-h: 56px;

  /* Die Vollpille faellt bis auf runde Punkte weg */
  --r-1: 6px;
  --r-2: 10px;
  --r-3: 14px;
  --r-4: 20px;
  --r-dot: 9999px;

  /* zwei Schatten statt 41 einzelner box-shadow-Deklarationen */
  --shadow-1: 0 1px 2px color-mix(in oklab, #000 38%, transparent);
  --shadow-2: 0 8px 24px color-mix(in oklab, #000 30%, transparent);

  /* drei Knopfhoehen statt vier zufaelligen (60 / 56 / 51 / 47) */
  --btn-h-sm: 36px; --btn-pad-sm: 12px;
  --btn-h-md: 44px; --btn-pad-md: 20px;
  --btn-h-lg: 52px; --btn-pad-lg: 28px;
  --tap-min: 44px;  /* Mindesttrefferflaeche, unsichtbar erzwungen */
}

/* --- Schicht 3: Farbe --------------------------------------------------- */
/* Eine Welt statt vier. Gold ist die Marke, weil die Netzwerkleiste auf allen
   sieben Auftritten Gold fuehrt: eine tuerkise Startseite waere der einzige
   goldfreie Punkt im eigenen Verbund gewesen. Tuerkis bleibt, aber nur noch
   als Statusfarbe fuer live und online. */
:root{ color-scheme: dark; }
html.light-mode{ color-scheme: light; }

:root{
  --bg:        light-dark(#f7f7f5, #0a0a0b);
  --surface:   light-dark(#ffffff, #131316);
  --surface-2: light-dark(#efeeea, #1a1b1f);
  --line:      light-dark(color-mix(in oklab, #16181d 14%, transparent),
                          color-mix(in oklab, #f2f3f5 12%, transparent));
  --line-2:    light-dark(color-mix(in oklab, #16181d 24%, transparent),
                          color-mix(in oklab, #f2f3f5 22%, transparent));

  --tx:   light-dark(#16181d, #f2f3f5);
  --tx-2: light-dark(#4b5058, #a9b0ba);  /* 7,7 hell, 8,9 dunkel */
  --tx-3: light-dark(#6a7078, #868e99);  /* 4,7 hell, 5,2 dunkel */

  --brand:      #e2b649;
  --brand-ink:  #17120a;                        /* Text auf Gold, 9,7 zu 1 */
  --brand-text: light-dark(#7a5a12, #e2b649);   /* 6,2 hell, 10,4 dunkel */
  --brand-soft: color-mix(in oklab, var(--brand) 14%, transparent);
  --brand-line: color-mix(in oklab, var(--brand) 34%, transparent);

  --live:  light-dark(#0f766e, #35d6a6);
  --focus: light-dark(#7a5a12, #f0cd6a);
}

/* Rueckfall fuer Browser ohne light-dark(). Ohne diesen Block bliebe alles
   auf dem Anfangswert stehen, also unsichtbar. */
@supports not (color: light-dark(#000, #fff)){
  :root{
    --bg:#0a0a0b; --surface:#131316; --surface-2:#1a1b1f;
    --line:rgba(242,243,245,.12); --line-2:rgba(242,243,245,.22);
    --tx:#f2f3f5; --tx-2:#a9b0ba; --tx-3:#868e99;
    --brand-text:#e2b649; --live:#35d6a6; --focus:#f0cd6a;
  }
  html.light-mode{
    --bg:#f7f7f5; --surface:#fff; --surface-2:#efeeea;
    --line:rgba(22,24,29,.14); --line-2:rgba(22,24,29,.24);
    --tx:#16181d; --tx-2:#4b5058; --tx-3:#6a7078;
    --brand-text:#7a5a12; --live:#0f766e; --focus:#7a5a12;
  }
}

/* --- Schicht 4: Bauteile ------------------------------------------------ */

.wrap{ inline-size: min(100% - 2 * var(--gutter), var(--wrap)); margin-inline: auto; }

/* Typografie an den Elementen. text-wrap: balance haelt Ueberschriften
   gleichmaessig, text-wrap: pretty verhindert Schusterjungen im Fliesstext.
   Beides steckt in der ausgelieferten Tailwind-Datei und wurde nie benutzt. */
.t-h1{
  font-size: var(--fs-7); line-height: var(--lh-1); font-weight: var(--fw-max);
  letter-spacing: var(--ls-h1); text-wrap: balance;
}
.t-h2{
  font-size: var(--fs-6); line-height: var(--lh-2); font-weight: var(--fw-head);
  letter-spacing: var(--ls-h2); text-wrap: balance;
}
.t-h3{ font-size: var(--fs-5); line-height: var(--lh-2); font-weight: var(--fw-head); }
.t-body{ font-size: var(--fs-3); line-height: var(--lh-3); text-wrap: pretty; }
.t-small{ font-size: var(--fs-2); line-height: var(--lh-3); }

.kicker{
  font-size: var(--fs-1); line-height: var(--lh-2); font-weight: var(--fw-head);
  text-transform: uppercase; letter-spacing: var(--ls-over); color: var(--tx-3);
}
.num, .price, .kpi-value{ font-variant-numeric: tabular-nums; }

/* Eine Knopfkomponente fuer die ganze Seite */
.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  block-size: var(--btn-h-md); padding-inline: var(--btn-pad-md);
  font-size: var(--fs-2); font-weight: var(--fw-head); line-height: var(--lh-2);
  border-radius: var(--r-2); border: 1px solid transparent;
  text-decoration: none; position: relative; cursor: pointer; white-space: nowrap;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.btn-sm{ block-size: var(--btn-h-sm); padding-inline: var(--btn-pad-sm); font-size: var(--fs-2); }
.btn-lg{ block-size: var(--btn-h-lg); padding-inline: var(--btn-pad-lg); font-size: var(--fs-3); }

.btn-primary{ background: var(--brand); color: var(--brand-ink); }
.btn-primary:hover{ background: color-mix(in oklab, var(--brand) 88%, #fff); }
.btn-quiet{ background: transparent; color: var(--tx); border-color: var(--line-2); }
.btn-quiet:hover{ border-color: var(--brand-line); background: var(--brand-soft); }

/* Unsichtbare Mindesttrefferflaeche fuer alles unter 44px */
.btn-sm::before, .icon-button::before{
  content: ''; position: absolute; inset: 50% auto auto 50%;
  translate: -50% -50%; inline-size: max(100%, var(--tap-min)); block-size: var(--tap-min);
}

/* Globale Fokusanzeige. Die alte Gestaltung behauptete an einer Stelle, es
   gaebe sie, hatte sie aber auf keiner der Bedienklassen. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible{
  outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-1);
}

/* Auf dem Handy steht jeder Hauptknopf voll breit untereinander. Damit endet
   der auffaelligste Bruch von heute: drei verschieden breite Pillen. */
@media (max-width: 640px){
  .btn-row{ flex-direction: column; align-items: stretch; }
  .btn-row > .btn{ inline-size: 100%; max-inline-size: 420px; margin-inline: auto; }
}

/* --- Hero --------------------------------------------------------------- */
.hero{
  padding-block-start: calc(var(--header-h) + var(--sp-5));
  padding-block-end: var(--sp-8);
  background: linear-gradient(to bottom, var(--surface-2), var(--bg) 60%);
}
.hero-grid{
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: var(--sp-7);
  align-items: start;
}
/* Der entscheidende Griff: die Ueberschrift misst ihre eigene Spalte, nicht
   das Fenster. Genau daran lag es, dass dort 96px standen. */
.hero-copy{ container-type: inline-size; container-name: herocopy; text-align: start; }

.hero-title{
  font-size: var(--fs-7);
  line-height: var(--lh-1); font-weight: var(--fw-max);
  letter-spacing: var(--ls-h1); text-wrap: balance;
  margin-block: var(--sp-4) 0; max-inline-size: 24ch;
}
@supports (container-type: inline-size){
  .hero-title{ font-size: clamp(2rem, 8.5cqi, 3.5rem); }
}
.hero-line, .hero-brand{ display: block; }
.hero-brand{ color: var(--brand-text); }

.status-band{
  display: inline-flex; align-items: center; gap: var(--sp-2);
  block-size: 28px; padding-inline: var(--sp-3);
  font-size: var(--fs-1); font-weight: var(--fw-head);
  border: 1px solid var(--line-2); border-radius: var(--r-1);
  background: var(--surface); color: var(--tx-2); text-decoration: none;
}
.status-band:hover{ border-color: var(--brand-line); color: var(--tx); }
.status-band .dot{
  inline-size: 6px; block-size: 6px; border-radius: var(--r-dot); background: var(--live);
}

.hero-lead{
  font-size: var(--fs-4); line-height: var(--lh-3); color: var(--tx-2);
  max-inline-size: 46ch; margin-block: var(--sp-3) 0;
}
.btn-row{ display: flex; gap: var(--sp-3); margin-block-start: var(--sp-5); flex-wrap: wrap; }

.proof-row{
  display: flex; gap: var(--sp-6); list-style: none; padding: 0;
  margin-block-start: var(--sp-5); padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line);
}
.proof-row li{ display: flex; flex-direction: column; gap: 2px; }
.kpi-value{ font-size: var(--fs-5); font-weight: var(--fw-max); line-height: var(--lh-2); color: var(--tx); }
.kpi-label{ color: var(--tx-3); }

/* Terminal als rechte Spalte, buendig mit der Oberkante des h1 */
.hero-stage{ margin-block-start: calc(28px + var(--sp-4) + var(--fs-1) * 1.2 + var(--sp-4)); }
.hero-stage .dev-terminal{
  border-radius: var(--r-3); border: 1px solid var(--line-2);
  box-shadow: var(--shadow-1); overflow: hidden;
}
/* Pflicht, sonst springt das Layout, waehrend das Terminal tippt, und zwar
   genau im Messfenster fuer die groesste Inhaltsflaeche. */
.hero-stage .dev-terminal-body{ min-block-size: 264px; }

@media (max-width: 1023px){
  .hero-grid{ grid-template-columns: 1fr; gap: var(--sp-6); }
  .hero-stage{ margin-block-start: 0; }
  .hero-stage .dev-terminal-body{ min-block-size: 200px; }
  .proof-row{ gap: var(--sp-5); flex-wrap: wrap; }
}

/* Wer Bewegung abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}

/* --- Abschnitte und Sonderueberschriften -------------------------------- */
/* Ersetzt py-24 sm:py-36 (96/144px) durch das Raster. Genau diese Polsterung
   war der groesste Einzelposten an den 9.300px Seitenhoehe. */
.section-y{ padding-block: var(--section-y); }

/* Zwei Ueberschriften brachten ihre eigene Skala mit: die Showcase-Zeile stieg
   per clamp bis 100px, der Terminaltitel bis 56px. Beide folgen jetzt --fs-6,
   damit die Seite genau eine Groesse fuer h2 kennt. */
.agency-showcase-title,
.dev-terminal-title{
  font-size: var(--fs-6) !important;
  line-height: var(--lh-2);
  font-weight: var(--fw-head);
  letter-spacing: var(--ls-h2);
  text-wrap: balance;
}
/* Der Kicker ueber dem Terminal war 11px, die Untergrenze der Seite ist 12. */
.dev-terminal-kicker{ font-size: var(--fs-1); letter-spacing: var(--ls-over); }
.dev-terminal-body{ line-height: var(--lh-3); }

/* Die drei letzten Ausreisser. Sie stehen in einem Inline-Style-Block, der
   nach dieser Datei geladen wird, deshalb hier mit !important. Der Block
   selbst wird spaeter aufgeloest, dann kann das !important wieder weg. */
.agency-showcase-title{
  font-size: var(--fs-6) !important;
  line-height: var(--lh-2) !important;
  font-weight: var(--fw-head) !important;
  letter-spacing: var(--ls-h2) !important;
  color: var(--brand-text) !important;
}
.exit-popup-title{
  font-size: var(--fs-5) !important;
  line-height: var(--lh-2) !important;
  font-weight: var(--fw-head) !important;
}
.dev-terminal-title{
  font-size: var(--fs-6) !important;
  line-height: var(--lh-2) !important;
  font-weight: var(--fw-head) !important;
}
/* Die Untergrenze der Seite ist 12px. Darunter lag bisher der Terminal-Kicker
   (11px) und die Statistiklabel (11,5px). */
.dev-terminal-kicker,
.dev-terminal-stat span,
.dev-terminal-statlabel{ font-size: var(--fs-1) !important; }

/* --- Terminal: feste Hoehe, damit die Seite beim Tippen nicht waechst ----
   Das Skript haengt 20 Eintraege nacheinander an, mit Umbruechen rund 24
   Zeilen, also etwa 600px. Reserviert waren 280. Die Folge: der Kasten wuchs
   waehrend des Tippens und schob alles darunter nach unten, mitten im
   Scrollen. Jetzt steht die Hoehe von Anfang an fest und der Inhalt scrollt
   darin, wie in einem echten Terminal. */
.hero-stage .dev-terminal-body{
  block-size: clamp(320px, 26vw, 460px);
  min-block-size: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
.hero-stage .dev-terminal-body::-webkit-scrollbar{ inline-size: 6px; }
.hero-stage .dev-terminal-body::-webkit-scrollbar-thumb{
  background: var(--line-2); border-radius: var(--r-dot);
}
@media (max-width: 1023px){
  .hero-stage .dev-terminal-body{ block-size: 320px; }
}

/* --- Material: klare Flaechen statt Glas -------------------------------
   Die Karten lagen als Milchglas ueber einem bewegten Farbnebel: 24px
   Weichzeichner, ein Leuchtschatten, 50px Schlagschatten und 40 dauerhaft
   animierte Partikel dahinter. Das ist der Grund, warum alles unscharf und
   unfertig wirkte. Eine Karte ist jetzt eine Flaeche mit einer 1px-Linie,
   sonst nichts. Wer Tiefe braucht, bekommt sie ueber Helligkeit, nicht ueber
   Unschaerfe. */
.glass-panel{
  background: var(--surface) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-3) !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  transition: border-color .18s ease, background-color .18s ease !important;
}
.glass-panel-hover:hover{
  border-color: var(--brand-line) !important;
  background: var(--surface-2) !important;
  transform: none !important;
}

/* Der Farbnebel und die Partikel verschwinden. Beide kosten dauerhaft
   Rechenzeit und liefern nichts als Rauschen hinter dem Text. */
.mesh-bg, #particles{ display: none !important; }

/* Radien vereinheitlichen: die Seite kannte 8 mal 3xl, 8 mal 2xl und 8 mal
   die Vollpille nebeneinander. */
.rounded-3xl{ border-radius: var(--r-4) !important; }
.rounded-2xl{ border-radius: var(--r-3) !important; }
/* Vollrunde Formen bleiben nur, wo sie ein Punkt oder ein Avatar sind. */
a.rounded-full:not(.status-band), button.rounded-full, div.rounded-full:not([class*="w-1"]):not([class*="w-2"]):not([class*="h-2"]){
  border-radius: var(--r-2) !important;
}

/* Die alten Knopfklassen folgen der neuen Komponente, damit nicht drei
   Knopfsprachen nebeneinander stehen. */
.cta-button, .agency-primary-button{
  background: var(--brand) !important; color: var(--brand-ink) !important;
  border: 1px solid transparent !important; box-shadow: none !important;
  border-radius: var(--r-2) !important; font-weight: var(--fw-head) !important;
  font-size: var(--fs-3) !important; padding: 0 var(--btn-pad-lg) !important;
  block-size: var(--btn-h-lg); display: inline-flex; align-items: center; gap: var(--sp-2);
}
.cta-secondary, .agency-secondary-button, .agency-outline-button{
  background: transparent !important; color: var(--tx) !important;
  border: 1px solid var(--line-2) !important; box-shadow: none !important;
  border-radius: var(--r-2) !important; font-weight: var(--fw-head) !important;
  font-size: var(--fs-3) !important; padding: 0 var(--btn-pad-lg) !important;
  block-size: var(--btn-h-lg); display: inline-flex; align-items: center; gap: var(--sp-2);
}
.cta-button:hover, .agency-primary-button:hover{ background: color-mix(in oklab, var(--brand) 88%, #fff) !important; }
.cta-secondary:hover, .agency-secondary-button:hover, .agency-outline-button:hover{
  border-color: var(--brand-line) !important; background: var(--brand-soft) !important;
}

/* Verlaufstext war an sieben Stellen ein zweiter Markenauftritt. Eine Farbe. */
.gradient-text{
  background: none !important; -webkit-background-clip: initial !important;
  background-clip: initial !important; -webkit-text-fill-color: currentColor !important;
  color: var(--brand-text) !important;
}

/* --- Kopfleiste mit Gruppen -------------------------------------------- */
.site-header, header.glass-panel{
  background: color-mix(in oklab, var(--bg) 88%, transparent) !important;
  backdrop-filter: saturate(140%) blur(10px) !important;
  -webkit-backdrop-filter: saturate(140%) blur(10px) !important;
  border: 0 !important; border-block-end: 1px solid var(--line) !important;
  border-radius: 0 !important; box-shadow: none !important;
  padding-block: var(--sp-2) !important;
}
.nav-group{ position: relative; }
.nav-trigger{
  display: inline-flex; align-items: center; gap: 6px;
  block-size: var(--btn-h-sm); padding-inline: var(--sp-3);
  font-size: var(--fs-2); font-weight: var(--fw-ui); line-height: var(--lh-2);
  color: var(--tx-2); background: transparent; border: 1px solid transparent;
  border-radius: var(--r-2); cursor: pointer;
  transition: color .18s ease, background-color .18s ease;
}
.nav-trigger:hover{ color: var(--tx); background: var(--surface-2); }
.nav-trigger[aria-expanded="true"]{ color: var(--tx); background: var(--surface-2); }
.nav-caret{ transition: rotate .18s ease; opacity: .7; }
.nav-trigger[aria-expanded="true"] .nav-caret{ rotate: 180deg; }

.nav-menu{
  position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0;
  min-inline-size: 224px; padding: var(--sp-2);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-3); box-shadow: var(--shadow-2);
  display: flex; flex-direction: column; gap: 2px; z-index: 60;
}
.nav-menu[hidden]{ display: none; }
.nav-item{
  display: flex; align-items: center; min-block-size: 36px;
  padding-inline: var(--sp-3); border-radius: var(--r-2);
  font-size: var(--fs-2); font-weight: var(--fw-ui); color: var(--tx-2);
  text-decoration: none; white-space: nowrap;
}
.nav-item:hover{ background: var(--surface-2); color: var(--tx); }
.nav-shop{ margin-inline-start: var(--sp-2); }

.mobile-group-label{
  font-size: var(--fs-1); font-weight: var(--fw-head); color: var(--tx-3);
  text-transform: uppercase; letter-spacing: var(--ls-over);
  margin-block: var(--sp-4) var(--sp-1);
}
.mobile-menu nav{ gap: var(--sp-2) !important; font-size: var(--fs-3) !important; }

/* --- Wortmarke ----------------------------------------------------------
   Orbitron trug das sechs Zeichen lange Kuerzel TDYSKY. "Agency Scripts" hat
   vierzehn Zeichen und zwei Woerter, dort laeuft dieselbe Schrift auseinander
   und wirkt sperrig. Inter mit enger Laufweite steht ruhiger neben dem Zeichen. */
.wordmark{
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  font-size: var(--fs-4) !important;
  font-weight: var(--fw-max) !important;
  letter-spacing: -0.01em !important;
  color: var(--tx) !important;
  text-transform: none !important;
}

/* Die Zahlenleiste: vier nachpruefbare Werte statt einer nichtssagenden Eins. */
.proof-row{ flex-wrap: wrap; row-gap: var(--sp-4); }
.kpi-star{ color: var(--brand-text); font-size: .8em; vertical-align: 1px; }
.kpi-value{ letter-spacing: -0.01em; }
@media (max-width: 640px){
  .proof-row{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
}

/* --- Der Agency-Scripts-Bereich ----------------------------------------
   Er brachte eine eigene Welt mit: zwei Radialverlaeufe als Hintergrund, ein
   drittes Leuchten in der Schale, 2,5rem Radien, ein Verlaufsknopf mit
   35px Schein und daneben ein violetter Zweitknopf. Neben einer klaren Seite
   sieht das aus wie ein Fremdkoerper. Er folgt jetzt derselben Materialsprache
   wie alles andere: Flaeche, eine Linie, kein Schein. */
.agency-showcase::before,
.agency-showcase::after,
.agency-showcase-shell::before,
.agency-showcase-shell::after{ display: none !important; }

.agency-showcase-shell{
  padding: var(--sp-8) var(--sp-7) !important;
  border-radius: var(--r-4) !important;
  border: 1px solid var(--line) !important;
  background: var(--surface) !important;
  box-shadow: none !important;
}
.agency-showcase-logo{ inline-size: 56px !important; filter: none !important; }
.agency-overline{
  letter-spacing: var(--ls-over) !important; font-size: var(--fs-1) !important;
  color: var(--tx-3) !important; margin-block-end: var(--sp-3) !important;
}
.agency-showcase-subtitle{
  font-size: var(--fs-4) !important; line-height: var(--lh-3) !important;
  color: var(--tx-2) !important; margin-block-end: var(--sp-6) !important;
  max-inline-size: 62ch !important;
}
.agency-kicker{
  padding: 0 var(--sp-3) !important; block-size: 28px !important;
  border-radius: var(--r-1) !important; border: 1px solid var(--line-2) !important;
  background: var(--surface-2) !important; color: var(--tx-2) !important;
  font-size: var(--fs-1) !important; letter-spacing: var(--ls-over) !important;
  margin-block-end: var(--sp-5) !important; box-shadow: none !important;
}
.agency-kicker::before{ background: var(--brand) !important; box-shadow: none !important; }

.agency-stats{ gap: var(--sp-3) !important; margin-block-start: var(--sp-6) !important;
  padding-block-start: var(--sp-5) !important; border-block-start: 1px solid var(--line) !important; }
.agency-stat{
  padding: var(--sp-4) !important; border-radius: var(--r-3) !important;
  border: 1px solid var(--line) !important; background: var(--surface-2) !important;
}
.agency-stat-title{ color: var(--tx) !important; font-size: var(--fs-3) !important; font-weight: var(--fw-head) !important; }
.agency-stat-label{ color: var(--tx-3) !important; font-size: var(--fs-2) !important; line-height: var(--lh-3) !important; }
.agency-flagship-card, .agency-phone-shell{
  border-radius: var(--r-4) !important; border: 1px solid var(--line) !important;
  background: var(--surface) !important; box-shadow: none !important;
}
.agency-phone-title-main{ color: var(--tx) !important; }
.agency-phone-title-accent{ color: var(--brand-text) !important; }

/* --- Sanfte Uebergaenge, vor allem in den Menues -----------------------
   Ein Menue, das ohne Uebergang erscheint, wirkt wie ein Fehler. 140
   Millisekunden reichen, damit das Auge folgt, ohne dass jemand wartet.
   Wer Bewegung abbestellt hat, bekommt weiter keine: die Regel dafuer steht
   weiter oben in dieser Datei und gilt auch hier. */
@media (prefers-reduced-motion: no-preference){
  .nav-menu{
    animation: menueAuf .14s cubic-bezier(.2,.7,.3,1) both;
    transform-origin: top center;
  }
  @keyframes menueAuf{
    from{ opacity: 0; translate: 0 -4px; scale: .99 }
    to  { opacity: 1; translate: 0 0;    scale: 1   }
  }
  .nav-item, .nav-trigger, .btn, .glass-panel, .status-band{
    transition: background-color .16s ease, border-color .16s ease, color .16s ease, opacity .16s ease;
  }
  /* Abschnitte blenden beim Hereinscrollen auf, ohne Bibliothek und nur, wenn
     der Browser scroll-getriebene Animationen kann. Sonst sind sie sofort da. */
  @supports (animation-timeline: view()){
    .reveal{
      animation: einblenden linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 42%;
    }
    @keyframes einblenden{
      from{ opacity: 0; translate: 0 14px }
      to  { opacity: 1; translate: 0 0 }
    }
  }
}
/* Ohne Unterstuetzung und ohne Bewegungswunsch: einfach sichtbar. Eine Seite
   darf nie an einer Animation haengen bleiben. */
@supports not (animation-timeline: view()){
  .reveal{ opacity: 1 !important; translate: none !important; transform: none !important; }
}
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity: 1 !important; translate: none !important; transform: none !important; }
}

/* --- Framework-Reihe im ersten Bildschirm ------------------------------
   Die erste Frage jedes Serverbetreibers lautet "laeuft das bei mir".
   Die Antwort stand bisher weit unten. Jetzt steht sie oben und fuellt
   gleichzeitig den Raum, der nach dem Verkleinern frei geworden ist. */
.fw-row{
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2);
  margin-block-start: var(--sp-5);
}
.fw-label{ margin-inline-end: var(--sp-1); }
.fw-chip{
  display: inline-flex; align-items: center; block-size: 26px;
  padding-inline: var(--sp-3); border-radius: var(--r-1);
  border: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-1); font-weight: var(--fw-ui); color: var(--tx-2);
}


/* Das Discord-Abzeichen brachte eine violette Pille mit und fiel aus der
   Reihe der drei anderen Zahlen. Es zeigt jetzt nur noch die Zahl. */
.proof-row [data-discord-member-badge],
.proof-row [data-discord-member-badge] *{
  background: none !important; border: 0 !important; box-shadow: none !important;
  padding: 0 !important; border-radius: 0 !important;
  color: inherit !important; font: inherit !important;
}
.proof-row [data-discord-member-badge] span:not(:first-child){ display: none !important; }

/* --- Zustimmungsbalken -------------------------------------------------
   Er kam aus einer eigenen Datei mit eigener Farbwelt: tuerkiser Verlaufsknopf,
   dunkelblaue Flaeche, Vollpillen. Neben der neuen Seite ein Fremdkoerper.
   Er folgt jetzt denselben Token wie alles andere. */
.privacy-consent-banner,
.privacy-consent-root .privacy-consent-banner{
  background: var(--surface) !important;
  border: 1px solid var(--line-2) !important;
  border-radius: var(--r-4) !important;
  box-shadow: var(--shadow-2) !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  padding: var(--sp-5) !important;
}
.privacy-consent-title{
  color: var(--tx) !important; font-size: var(--fs-3) !important;
  font-weight: var(--fw-head) !important; letter-spacing: 0 !important;
  text-transform: none !important; margin-block-end: var(--sp-2) !important;
}
.privacy-consent-text{ color: var(--tx-2) !important; font-size: var(--fs-2) !important; line-height: var(--lh-3) !important; }
.privacy-consent-link{ color: var(--brand-text) !important; text-underline-offset: 3px; }
.privacy-consent-actions{ gap: var(--sp-2) !important; margin-block-start: var(--sp-4) !important; }
.privacy-consent-button{
  block-size: var(--btn-h-md) !important; padding-inline: var(--btn-pad-md) !important;
  border-radius: var(--r-2) !important; font-size: var(--fs-2) !important;
  font-weight: var(--fw-head) !important; box-shadow: none !important;
  background-image: none !important; text-transform: none !important;
}
.privacy-consent-button-primary{ background: var(--brand) !important; color: var(--brand-ink) !important; border: 1px solid transparent !important; }
.privacy-consent-button-primary:hover{ background: color-mix(in oklab, var(--brand) 88%, #fff) !important; }
.privacy-consent-button-secondary{ background: transparent !important; color: var(--tx) !important; border: 1px solid var(--line-2) !important; }
.privacy-consent-button-secondary:hover{ border-color: var(--brand-line) !important; background: var(--brand-soft) !important; }
.privacy-consent-manage{
  background: var(--surface) !important; color: var(--tx-2) !important;
  border: 1px solid var(--line-2) !important; border-radius: var(--r-2) !important;
  box-shadow: none !important; font-size: var(--fs-2) !important; font-weight: var(--fw-ui) !important;
  block-size: var(--btn-h-sm) !important; padding-inline: var(--sp-3) !important;
}
.privacy-consent-manage:hover{ border-color: var(--brand-line) !important; color: var(--tx) !important; }
.privacy-gate{
  background: var(--surface-2) !important; border: 1px dashed var(--line-2) !important;
  border-radius: var(--r-3) !important; box-shadow: none !important;
}
.privacy-gate-title{ color: var(--tx) !important; font-size: var(--fs-3) !important; font-weight: var(--fw-head) !important; }
.privacy-gate-text{ color: var(--tx-2) !important; font-size: var(--fs-2) !important; line-height: var(--lh-3) !important; }

/* --- Fusszeile ---------------------------------------------------------
   Sie trug dieselbe Glasflaeche wie die Karten und stand als graue Zeile am
   Ende. Jetzt eine klare Abschlusskante, ruhige Typografie, Marke statt Kuerzel. */
footer.glass-panel{
  background: var(--surface) !important;
  border: 0 !important; border-block-start: 1px solid var(--line) !important;
  border-radius: 0 !important; box-shadow: none !important;
  padding-block: var(--sp-7) !important;
  font-size: var(--fs-2) !important; color: var(--tx-3) !important;
}
footer .font-orbitron{
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  font-weight: var(--fw-max) !important; letter-spacing: -0.01em !important;
  color: var(--tx) !important; font-size: var(--fs-3) !important;
}
footer nav a{ color: var(--tx-2) !important; text-decoration: none; }
footer nav a:hover{ color: var(--brand-text) !important; }

/* --- Abschieds-Fenster -------------------------------------------------
   Es kam als letztes Stueck der alten Welt daher: violettes Abzeichen,
   blaugrauer Kasten, Vollpillen, ein Discord-Feld in Markenblau. */
.exit-popup, .exit-popup-card, #exit-popup-overlay > div{
  background: var(--surface) !important;
  border: 1px solid var(--line-2) !important;
  border-radius: var(--r-4) !important;
  box-shadow: var(--shadow-2) !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
}
.exit-popup-kicker, .exit-popup .agency-kicker{
  background: var(--surface-2) !important; border: 1px solid var(--line-2) !important;
  color: var(--tx-2) !important; border-radius: var(--r-1) !important;
  box-shadow: none !important; font-size: var(--fs-1) !important;
}
.exit-popup-title{ color: var(--tx) !important; }
.exit-popup-text, .exit-popup p{ color: var(--tx-2) !important; font-size: var(--fs-2) !important; line-height: var(--lh-3) !important; }
.exit-popup-icon, .exit-popup img{ filter: none !important; }
#exit-popup-close, .exit-popup-close{
  background: var(--surface-2) !important; border: 1px solid var(--line-2) !important;
  color: var(--tx-2) !important; border-radius: var(--r-2) !important; box-shadow: none !important;
}
#exit-popup-overlay{ background: color-mix(in oklab, #000 62%, transparent) !important; backdrop-filter: blur(2px) !important; }

/* --- Heller Modus ------------------------------------------------------
   Ein Terminal ist dunkel. Im hellen Modus wurde daraus ein leerer grauer
   Kasten, weil die Schriftfarben fuer dunklen Grund gemacht sind. Es behaelt
   deshalb in beiden Modi seine eigene Flaeche, wie in jedem Editor auch. */
html.light-mode .dev-terminal,
html.light-mode .hero-stage .dev-terminal{
  background: #0b0d12 !important;
  border-color: rgba(0,0,0,.18) !important;
}
html.light-mode .dev-terminal-body,
html.light-mode .dev-terminal-bar,
html.light-mode .dev-terminal-path{ color: #cbd5e1 !important; }
html.light-mode .dev-terminal-body *{ color: inherit; }

/* Suchfeld und Schalter brauchen im Hellen eine sichtbare Kante, sonst
   verschwinden sie in der weissen Flaeche. */
html.light-mode .header-search input,
html.light-mode .header-search,
html.light-mode input[type="search"], html.light-mode input[type="email"], html.light-mode input[type="text"]{
  background: var(--surface) !important;
  border: 1px solid var(--line-2) !important;
  color: var(--tx) !important;
}
html.light-mode .nav-trigger:hover,
html.light-mode .nav-trigger[aria-expanded="true"]{ background: var(--surface-2) !important; }

/* Gold auf Weiss ist als Text zu schwach. Als Flaeche bleibt es hell, als
   Text nimmt es die dunkle Fassung. Das regelt --brand-text bereits, hier
   nur die Stellen, die noch fest auf dem hellen Gold sassen. */
html.light-mode .kpi-star,
html.light-mode .agency-showcase-title,
html.light-mode .gradient-text,
html.light-mode .hero-brand{ color: var(--brand-text) !important; }

/* --- Team ---------------------------------------------------------------
   Zwei Karten, keine Profilbilder von Discord: die liegen auf einem fremden
   Rechner und wuerden die IP jedes Besuchers dorthin schicken, bevor jemand
   zugestimmt hat. Das Zeichen ist der Anfangsbuchstabe, gesetzt in der
   eigenen Schrift. Echte Bilder koennen nachkommen, dann oertlich abgelegt. */
.team-grid{
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--grid-gap); margin-block-start: var(--sp-6);
}
.team-card{
  display: flex; gap: var(--sp-4); align-items: flex-start;
  padding: var(--sp-5); border: 1px solid var(--line);
  border-radius: var(--r-3); background: var(--surface);
}
.team-card:hover{ border-color: var(--brand-line); }
.team-mark{
  flex: 0 0 auto; display: grid; place-items: center;
  inline-size: 44px; block-size: 44px; border-radius: var(--r-2);
  background: var(--brand-soft); border: 1px solid var(--brand-line);
  color: var(--brand-text); font-size: var(--fs-5); font-weight: var(--fw-max);
}
.team-name{ font-size: var(--fs-3); font-weight: var(--fw-head); color: var(--tx); }
.team-handle{ font-size: var(--fs-2); font-weight: var(--fw-body); color: var(--tx-3); }
.team-role{ margin-block-start: 2px; }
.team-bio{ margin-block-start: var(--sp-2); font-size: var(--fs-2); line-height: var(--lh-3); color: var(--tx-2); }

/* --- Letzte Reste der alten Materialsprache ----------------------------
   Aus einer Durchmessung der fertigen Seite: einzelne Bausteine trugen noch
   32px Radien, Vollpillen und Weichzeichner. Solange die stehen bleiben,
   wirkt die Seite an genau diesen Stellen unfertig. */
.agency-phone-visual, .agency-phone-shell, .agency-pad-visual,
.exit-popup-icon, .lang-menu-panel, #lang-menu-panel,
.mobile-menu, .video-card, .project-card{
  border-radius: var(--r-3) !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
}
.lang-menu-panel, #lang-menu-panel{
  background: var(--surface) !important; border: 1px solid var(--line-2) !important;
  box-shadow: var(--shadow-2) !important;
}
.mobile-menu{ background: var(--bg) !important; border-inline-start: 1px solid var(--line) !important; }
.dev-terminal-kicker{
  border-radius: var(--r-1) !important; border: 1px solid var(--line-2) !important;
  background: var(--surface-2) !important; color: var(--tx-3) !important;
  box-shadow: none !important;
}
.exit-popup-icon{ background: var(--surface-2) !important; border: 1px solid var(--line-2) !important; }
/* Sprachmenue: Eintraege wie in den Kopfmenues, damit es eine Sprache gibt. */
.lang-option{
  display: flex; align-items: center; min-block-size: 36px;
  padding-inline: var(--sp-3); border-radius: var(--r-2);
  font-size: var(--fs-2); color: var(--tx-2); background: transparent; border: 0;
  inline-size: 100%; text-align: start; cursor: pointer;
}
.lang-option:hover, .lang-option.active{ background: var(--surface-2); color: var(--tx); }

/* Abschnitte enger stellen. Die Seite war 9.367px hoch, rund zehn
   Bildschirme. Der groesste Posten waren die Produktbloecke mit je 1.100px
   und der Community-Block mit 1.986px. */
#agency-phone, #agency-pad{ padding-block: var(--section-y) !important; }
#community{ padding-block: var(--section-y) !important; }
#community > div > *{ margin-block-start: 0 !important; }
.agency-phone-feature{ min-block-size: 0 !important; padding-block: var(--sp-3) !important; }

/* --- Community enger und in einer Farbe --------------------------------
   Der Block war mit 1.986px der groesste der Seite: drei Tafeln mit je 56px
   Innenpolsterung und 80px Abstand dazwischen. Dazu trugen die Abzeichen dort
   noch das alte Tuerkis als Markenfarbe. */
#community .glass-panel,
#community > div > div[class*="grid"]{
  padding: var(--sp-6) !important;
  margin-block-end: var(--sp-7) !important;
  gap: var(--sp-6) !important;
}
#community h2 + p{ font-size: var(--fs-4) !important; }
#community p{ margin-block-end: var(--sp-4) !important; }
#community .mb-8, #community .mb-6, #community .mb-5{ margin-block-end: var(--sp-4) !important; }
#community .mb-20{ margin-block-end: var(--sp-7) !important; }

/* Tuerkise Abzeichen und Rahmen im Community-Block auf die Marke ziehen.
   Tuerkis bleibt nur der Punkt, der "live" bedeutet. */
#community [class*="rgba(45,212,191"]{
  background: var(--brand-soft) !important;
  border-color: var(--brand-line) !important;
  color: var(--brand-text) !important;
}
#community-servers .relative[class*="rounded-3xl"]{
  background: var(--surface-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-3) !important;
}
#servers-live-count{ color: var(--tx) !important; font-size: var(--fs-5) !important; }

/* Die Zwischenraeume der uebrigen Abschnitte folgen dem Raster. */
.mb-20{ margin-block-end: var(--sp-7) !important; }
.mb-16{ margin-block-end: var(--sp-6) !important; }
.mt-20{ margin-block-start: var(--sp-7) !important; }

/* --- Die letzten Tuerkis-Stellen ---------------------------------------
   Sie stehen als fester Farbwert in Tailwind-Klassen und in style-Attributen,
   nicht in einer Variablen, deshalb hat sie das Umhaengen der Farbwelt nicht
   erwischt. Gefunden durch Durchmessen der fertigen Seite.
   Tuerkis bleibt genau an zwei Stellen: der Schreibbalken im Terminal und der
   Punkt, der "live" bedeutet. Beides ist Status, keine Marke. */
[class*="45,212,191"]:not(.dev-terminal-caret),
[class*="45, 212, 191"]:not(.dev-terminal-caret),
[style*="45,212,191"]:not(.dev-terminal-caret),
[style*="45, 212, 191"]:not(.dev-terminal-caret){
  border-color: var(--brand-line) !important;
}
[class*="bg-[rgba(45,212,191"]{ background: var(--brand-soft) !important; }
[class*="text-[rgba(45,212,191"], [class*="text-[#2dd4bf"]{ color: var(--brand-text) !important; }
.lang-option.active{ border-color: var(--brand-line) !important; background: var(--surface-2) !important; color: var(--tx) !important; }
.ag-cursor-ring{ border-color: var(--brand-line) !important; }
.ag-cursor-dot{ background: var(--brand) !important; }
strong[style*="2dd4bf"], strong[style*="45, 212, 191"], strong[style*="45,212,191"]{ color: var(--brand-text) !important; }

/* Die drei Terminal-Kennzahlen und der Datenschutzhinweis im Newsletter
   trugen den Farbwert aus terminal.css beziehungsweise aus einem
   style-Attribut. Letzte zwei Stellen. */
.dev-terminal-stat strong{ color: var(--brand-text) !important; }
#newsletter div[style*="45,212,191"]{
  background: var(--surface-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-3) !important;
}

/* --- Der erste Bildschirm schliesst buendig ab -------------------------
   Die linke Spalte endete bei rund 560px, der Kasten rechts lief bis 790,
   der Abschnitt bis 1027. Darunter blieb ein Loch. Jetzt enden beide Spalten
   auf gleicher Hoehe und der Abschnitt genau dort. */
.hero{ padding-block-end: var(--sp-7) !important; }
.hero-grid{ align-items: start; }




.proof-row{ margin-block-start: var(--sp-5) !important; padding-block-start: var(--sp-4) !important; }
@media (max-width: 1023px){
  .hero-copy{ display: block; }
  .proof-row{ margin-block-start: var(--sp-5) !important; }
}

/* Der Kasten rechts richtet sich nach der linken Spalte, statt sie zu
   ueberragen. Gemessen: die Kopie endet bei rund 460px unter ihrer Oberkante. */
@media (min-width: 1024px){
  .hero-stage .dev-terminal-body{ block-size: 300px !important; }
}

/* --- Profilbilder im Team ---------------------------------------------- */
.team-bild{
  flex: 0 0 auto; inline-size: 44px; block-size: 44px;
  border-radius: var(--r-2); object-fit: cover;
  border: 1px solid var(--line-2); background: var(--surface-2);
}

/* --- Knopfabstaende ----------------------------------------------------
   Mehrere Knoepfe standen dicht an ihrem Umfeld: der Discord-Knopf klebte
   unter den Teamkarten, Knopfreihen hatten 12px Luft. Eine Regel fuer alle,
   damit nicht jede Stelle einzeln nachgebessert werden muss. */
.btn-row{ gap: var(--sp-4) !important; }
.btn + .btn{ margin-inline-start: 0; }
/* Ein Knopf, der auf einen Block folgt, bekommt Luft nach oben. */
:where(section, .wrap, .team-grid + *, div) > .btn:not(.btn-row > .btn):not(.nav-shop){
  margin-block-start: var(--sp-6);
}
#team .btn{ margin-block-start: var(--sp-6) !important; }
/* Nebeneinander stehende Knoepfe halten immer mindestens 16px Abstand. */
.flex.gap-3 > .btn, .flex.gap-2 > .btn, .flex.gap-4 > .btn{ margin: var(--sp-1); }
.flex.gap-3, .flex.gap-2{ gap: var(--sp-4) !important; }

/* --- Produktbloecke enger, ohne Inhalt zu streichen --------------------
   Phone und Pad waren mit je rund 1.100px die dicksten Bloecke der Seite.
   Vier Merkmalszeilen standen untereinander mit je 70px, fuer je einen
   kurzen Satz. Zweispaltig sind es 140 statt 280px, und der Text steht
   trotzdem vollstaendig da. Dazu 40 statt 64px Rasterluecke. */
@media (min-width: 768px){
  #agency-phone .agency-phone-features,
  #agency-pad .agency-phone-features,
  #agency-phone [class*="space-y"]:has(.agency-phone-feature),
  #agency-pad [class*="space-y"]:has(.agency-phone-feature){
    display: grid !important;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2) var(--sp-4);
  }
}
.agency-phone-feature{
  padding: var(--sp-2) var(--sp-3) !important;
  min-block-size: 0 !important;
  font-size: var(--fs-2) !important;
  line-height: var(--lh-3) !important;
  border-radius: var(--r-2) !important;
}
#agency-phone [class*="grid"], #agency-pad [class*="grid"]{ gap: var(--sp-7) !important; }
.agency-phone-shell{ padding: var(--sp-7) !important; }


/* --- Community enger ---------------------------------------------------
   Mit 1.937px der groesste Block der Seite: drei Tafeln untereinander, jede
   mit eigener Innenpolsterung, dazwischen 48px. Das Newsletter-Formular von
   Brevo bringt allein 604px mit, davon ist gut die Haelfte Luft zwischen
   Beschriftung, Feld und Knopf. Kein Inhalt faellt weg, nur der Leerraum. */
#community .sib-form,
#community .sib-form-container,
#community .sib-container{ padding: 0 !important; }
#community .sib-form-block{ padding: var(--sp-2) 0 !important; }
#community .entry__field{ margin-block: var(--sp-2) !important; }
#community .entry__label{ margin-block-end: var(--sp-1) !important; font-size: var(--fs-2) !important; }
#community .entry__specification{ margin-block-start: var(--sp-1) !important; font-size: var(--fs-1) !important; }
#community .sib-form-block__button{ margin-block-start: var(--sp-3) !important; }
#community .sib-form-message-panel{ margin-block: var(--sp-2) !important; padding: var(--sp-3) !important; }
#community form p, #community form div:empty{ margin-block: 0 !important; }
#community .mt-6{ margin-block-start: var(--sp-4) !important; }

/* --- Suche als Fenster in der Mitte ------------------------------------
   Statt einer Klappliste unter einem Feld in der Kopfleiste. Bei 283
   Eintraegen aus Produkten, Doku, Blog und Aenderungen ist dort zu wenig
   Platz, und neben der Navigation stoert es. <dialog> uebernimmt Fokus,
   Escape und das Ausblenden des Rests fuer Screenreader. */
.suche-knopf{
  display: inline-flex; align-items: center; gap: var(--sp-2);
  block-size: var(--btn-h-sm); padding-inline: var(--sp-3);
  margin-inline-end: var(--sp-3);
  font-size: var(--fs-2); font-weight: var(--fw-ui); color: var(--tx-3);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-2); cursor: pointer;
}
.suche-knopf:hover{ color: var(--tx); border-color: var(--brand-line); }
.suche-knopf kbd{
  font: inherit; font-size: 11px; color: var(--tx-3);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 1px 5px;
}
@media (max-width: 900px){ .suche-knopf span, .suche-knopf kbd{ display: none } .suche-knopf{ padding-inline: var(--sp-2) } }

.suche-dialog{
  inline-size: min(680px, calc(100vw - 2 * var(--gutter)));
  max-block-size: min(70vh, 640px);
  margin: 12vh auto auto;
  padding: 0; border: 1px solid var(--line-2); border-radius: var(--r-4);
  background: var(--surface); color: var(--tx);
  box-shadow: 0 24px 64px color-mix(in oklab, #000 46%, transparent);
  overflow: hidden;
}
.suche-dialog::backdrop{ background: color-mix(in oklab, #000 58%, transparent); backdrop-filter: blur(2px); }
@media (prefers-reduced-motion: no-preference){
  .suche-dialog[open]{ animation: sucheAuf .16s cubic-bezier(.2,.7,.3,1) both }
  @keyframes sucheAuf{ from{ opacity:0; translate:0 -8px; scale:.985 } to{ opacity:1; translate:0 0; scale:1 } }
}
.suche-kopf{
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-block-end: 1px solid var(--line);
}
.suche-lupe{ color: var(--tx-3); flex: 0 0 auto }
.suche-feld{
  flex: 1 1 auto; border: 0; background: transparent; color: var(--tx);
  font-size: var(--fs-5); font-weight: var(--fw-ui); outline: none; min-inline-size: 0;
}
.suche-feld::placeholder{ color: var(--tx-3) }
.suche-esc{
  font: inherit; font-size: 11px; color: var(--tx-3);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 2px 6px;
}
.suche-liste{ overflow-y: auto; max-block-size: calc(70vh - 132px); padding: var(--sp-2) }
.suche-treffer{
  display: grid; grid-template-columns: 88px minmax(0, 1fr);
  grid-template-areas: "typ titel" "typ text";
  gap: 0 var(--sp-3); align-items: baseline;
  padding: var(--sp-3); border-radius: var(--r-2);
  text-decoration: none; color: inherit;
}
.suche-treffer:hover, .suche-treffer.ist-gewaehlt{ background: var(--surface-2) }
.suche-treffer.ist-gewaehlt{ outline: 1px solid var(--brand-line); outline-offset: -1px }
.suche-typ{
  grid-area: typ; font-size: var(--fs-1); font-weight: var(--fw-head);
  text-transform: uppercase; letter-spacing: var(--ls-over); color: var(--brand-text);
  align-self: center;
}
.suche-titel{ grid-area: titel; font-size: var(--fs-3); font-weight: var(--fw-head); color: var(--tx) }
.suche-text{ grid-area: text; font-size: var(--fs-2); line-height: var(--lh-3); color: var(--tx-3) }
.suche-leer{ padding: var(--sp-6) var(--sp-5); color: var(--tx-3); font-size: var(--fs-2); text-align: center }
.suche-fuss{
  padding: var(--sp-3) var(--sp-5); border-block-start: 1px solid var(--line);
  font-size: var(--fs-1); color: var(--tx-3);
}
@media (max-width: 640px){
  .suche-dialog{ margin-block-start: 6vh; max-block-size: 84vh }
  .suche-treffer{ grid-template-columns: 1fr; grid-template-areas: "typ" "titel" "text"; gap: 2px }
  .suche-typ{ align-self: start }
}

/* Die Akzentzeile im Terminalkopf war die letzte tuerkise Stelle im Text. */
.dev-terminal-title .accent{ color: var(--brand-text) !important; }

/* --- Produktbereiche neu geordnet --------------------------------------
   Vorher: Geraetebild links, Text rechts, darunter eine grosse Preistafel in
   Orbitron mit 46px. Der Preis war damit fast so gross wie die Ueberschrift,
   und meine eigene Hoechsthoehe hat das Bild unten abgeschnitten.

   Jetzt: das Bild behaelt sein Seitenverhaeltnis und wird nur skaliert, nie
   beschnitten. Der Preis steht als ruhige Zeile direkt neben dem Kaufknopf,
   wo er hingehoert, in derselben Schrift wie alles andere. */
.agency-phone-visual, .agency-pad-visual{
  max-block-size: none !important;
  overflow: visible !important;
  display: flex; align-items: center; justify-content: center;
}
.agency-phone-visual img, .agency-pad-visual img{
  inline-size: auto !important;
  max-inline-size: 100%;
  max-block-size: min(58vh, 520px);
  block-size: auto !important;
  object-fit: contain;
}

/* Preis: eine Zeile, keine Tafel. */
.agency-price{
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  font-size: var(--fs-6) !important;
  font-weight: var(--fw-max) !important;
  letter-spacing: -0.02em !important;
  font-variant-numeric: tabular-nums;
  color: var(--tx) !important;
  line-height: var(--lh-2) !important;
}
.agency-price-tax, .agency-price + span, .agency-price-note{
  font-size: var(--fs-2) !important; font-weight: var(--fw-body) !important;
  color: var(--tx-3) !important; letter-spacing: 0 !important;
}
/* Die Preistafel wird zur schlichten Zeile ueber den Knoepfen. */
[class*="agency-price"]:not(.agency-price):not(.agency-price-tax){
  background: transparent !important; border: 0 !important;
  padding: 0 !important; margin-block: var(--sp-4) var(--sp-3) !important;
  box-shadow: none !important;
  display: flex; align-items: baseline; gap: var(--sp-2);
}

/* Die Merkmalskarten bekommen ihr Symbol in einer eigenen Spalte, damit die
   zweizeiligen Texte nicht darunter rutschen. */
.agency-phone-feature{
  display: grid !important;
  grid-template-columns: 28px minmax(0, 1fr);
  align-items: center; gap: var(--sp-3);
}
.agency-phone-feature i, .agency-phone-feature svg,
.agency-phone-feature > span:first-child:not(:only-child){
  inline-size: 28px; block-size: 28px; display: grid; place-items: center;
  border-radius: var(--r-1); background: var(--brand-soft); color: var(--brand-text);
  font-size: 13px;
}

/* --- Newsletter ---------------------------------------------------------
   Das Formular kommt von Brevo und bringt eine eigene, helle Gestaltung mit:
   ein grauer Kasten mit grauer Beschriftung auf dunkler Seite, dazu ein
   Knopf mit Leuchtrand. Es folgt jetzt denselben Token wie alles andere. */
#sib-form input, #sib-form input[type="text"], #sib-form input[type="email"],
.sib-form input, #EMAIL{
  background: var(--surface-2) !important;
  border: 1px solid var(--line-2) !important;
  border-radius: var(--r-2) !important;
  color: var(--tx) !important;
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  font-size: var(--fs-3) !important;
  block-size: var(--btn-h-lg) !important;
  padding-inline: var(--sp-4) !important;
  box-shadow: none !important;
  text-transform: none !important;
}
#sib-form input::placeholder, #EMAIL::placeholder{
  color: var(--tx-3) !important; text-transform: none !important; font-size: var(--fs-3) !important;
}
#sib-form input:focus, #EMAIL:focus{
  border-color: var(--brand-line) !important;
  outline: 2px solid var(--focus); outline-offset: 2px;
}
.entry__label, #sib-form label{
  color: var(--tx-2) !important; font-size: var(--fs-2) !important;
  font-weight: var(--fw-ui) !important; text-transform: none !important;
  letter-spacing: 0 !important;
}
.entry__specification{ color: var(--tx-3) !important; font-size: var(--fs-1) !important; }
.sib-form-block__button, #sib-form button[type="submit"]{
  background: var(--brand) !important; color: var(--brand-ink) !important;
  border: 1px solid transparent !important; border-radius: var(--r-2) !important;
  box-shadow: none !important; filter: none !important;
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  font-size: var(--fs-3) !important; font-weight: var(--fw-head) !important;
  text-transform: none !important; letter-spacing: 0 !important;
  block-size: var(--btn-h-lg) !important; padding-inline: var(--btn-pad-lg) !important;
  inline-size: auto !important;
}
.sib-form-block__button:hover{ background: color-mix(in oklab, var(--brand) 88%, #fff) !important; }
/* Das Turnstile-Feld ist ein fremder Rahmen, er bekommt wenigstens denselben Radius. */
#sib-captcha iframe, .cf-turnstile iframe{ border-radius: var(--r-2) !important; }
/* Beide Tafeln gleich hoch, sonst haengt eine in der Luft. */
#newsletter{ align-items: stretch !important; }
#newsletter > *{ display: flex; flex-direction: column; }

/* --- AgencyAI unten rechts ----------------------------------------------
   Dasselbe Fenster, das Shop und Dokumentation haben, jetzt auch hier.
   Es benutzt ausschliesslich die Token dieser Datei, damit es sich nicht
   wie ein fremdes Werkzeug anfuehlt, das man dazugeklebt hat. */
.kai-launcher{
  position: fixed; inset-block-end: var(--sp-6); inset-inline-end: var(--sp-6);
  z-index: 150;
  display: inline-flex; align-items: center; gap: var(--sp-2, .5rem);
  block-size: 48px; padding-inline: 18px;
  background: var(--brand); color: var(--brand-ink);
  border: 1px solid transparent; border-radius: 999px;
  font: var(--fw-head, 600) var(--fs-3) / 1 "Inter", ui-sans-serif, system-ui, sans-serif;
  cursor: pointer;
  box-shadow: 0 6px 24px -8px rgb(0 0 0 / .55);
  transition: transform .18s ease, background .18s ease, box-shadow .18s ease;
}
.kai-launcher:hover{ background: color-mix(in oklab, var(--brand) 88%, #fff); transform: translateY(-1px); }
.kai-launcher:focus-visible{ outline: 2px solid var(--focus); outline-offset: 3px; }
.kai-launcher-glyph{ display: inline-flex; }
.kai-launcher.ist-offen .kai-launcher-text{ display: none; }
.kai-launcher.ist-offen{ padding-inline: 14px; }

.kai-fenster{
  position: fixed; inset-block-end: calc(var(--sp-6) + 60px); inset-inline-end: var(--sp-6);
  z-index: 149;
  inline-size: min(390px, calc(100vw - 2 * var(--sp-6)));
  block-size: min(560px, calc(100vh - 140px));
  display: flex; flex-direction: column;
  background: var(--surface-1, var(--surface-2));
  border: 1px solid var(--line-2); border-radius: var(--r-3);
  box-shadow: 0 24px 60px -20px rgb(0 0 0 / .6);
  overflow: hidden;
  opacity: 0;
  transition: opacity .2s ease, transform .2s ease;
}
.kai-fenster.ist-offen{ opacity: 1; }
@media (prefers-reduced-motion: reduce){
  .kai-fenster, .kai-launcher{ transition: none; }
}

.kai-kopf{
  display: flex; align-items: center; gap: var(--sp-3, .75rem);
  padding: var(--sp-4) var(--sp-4);
  border-block-end: 1px solid var(--line-2);
  background: var(--surface-2);
}
.kai-punkt{
  inline-size: 8px; block-size: 8px; border-radius: 999px;
  background: #22c55e; flex: 0 0 auto;
}
.kai-kopf-text{ display: flex; flex-direction: column; gap: 1px; min-inline-size: 0; flex: 1 1 auto; }
.kai-kopf-text strong{ font-size: var(--fs-3); color: var(--tx); font-weight: var(--fw-head, 600); }
.kai-kopf-text span{ font-size: var(--fs-1); color: var(--tx-3); }
.kai-icon{
  flex: 0 0 auto; inline-size: 30px; block-size: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid transparent; border-radius: var(--r-1);
  color: var(--tx-3); cursor: pointer; transition: color .15s ease, background .15s ease;
}
.kai-icon:hover{ color: var(--tx); background: var(--surface-3, var(--surface-2)); }
.kai-icon:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }

.kai-liste{
  flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3, .75rem);
  scrollbar-width: thin;
}
.kai-blase{
  max-inline-size: 88%; padding: 10px 13px; border-radius: var(--r-2);
  font-size: var(--fs-2); line-height: 1.55; word-wrap: break-word;
}
.kai-du{
  align-self: flex-end;
  background: var(--brand); color: var(--brand-ink);
  border-end-end-radius: var(--r-1);
  font-weight: var(--fw-ui, 500);
}
.kai-ai{
  align-self: flex-start;
  background: var(--surface-2); color: var(--tx);
  border: 1px solid var(--line-2); border-end-start-radius: var(--r-1);
}
.kai-ai p{ margin: 0 0 .55em; }
.kai-ai p:last-child{ margin-bottom: 0; }
.kai-ai ul{ margin: .3em 0 .55em; padding-inline-start: 1.15em; }
.kai-ai li{ margin-block: .15em; }
.kai-ai a{ color: var(--brand-text); text-decoration: underline; text-underline-offset: 2px; }
.kai-ai code{
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .92em; background: var(--surface-3, var(--surface-2));
  border: 1px solid var(--line-2); border-radius: 5px; padding: .08em .34em;
}
.kai-ai pre{
  margin: .4em 0; padding: 10px 12px; overflow-x: auto;
  background: var(--surface-3, var(--surface-2));
  border: 1px solid var(--line-2); border-radius: var(--r-1);
}
.kai-ai pre code{ border: 0; padding: 0; background: none; }

/* Drei Punkte, solange noch nichts da ist. */
.kai-punkte{ display: inline-flex; gap: 4px; padding: 3px 0; }
.kai-punkte i{
  inline-size: 6px; block-size: 6px; border-radius: 999px;
  background: var(--tx-3); animation: kai-wippen 1.1s infinite ease-in-out;
}
.kai-punkte i:nth-child(2){ animation-delay: .16s; }
.kai-punkte i:nth-child(3){ animation-delay: .32s; }
@keyframes kai-wippen{ 0%,80%,100%{ opacity: .3; transform: translateY(0) } 40%{ opacity: 1; transform: translateY(-3px) } }
@media (prefers-reduced-motion: reduce){ .kai-punkte i{ animation: none; opacity: .55 } }

.kai-vorschlaege{ display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-block-start: var(--sp-1); }
.kai-vorschlag{
  padding: 7px 12px; font-size: var(--fs-1); color: var(--tx-2);
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: 999px; cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.kai-vorschlag:hover{ color: var(--tx); border-color: var(--brand-line, var(--brand)); }
.kai-vorschlag:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }

.kai-eingabe{
  display: flex; align-items: flex-end; gap: var(--sp-1);
  padding: var(--sp-3, .75rem) var(--sp-4);
  border-block-start: 1px solid var(--line-2); background: var(--surface-2);
}
.kai-feld{
  flex: 1 1 auto; resize: none; min-block-size: 40px; max-block-size: 104px;
  padding: 10px 12px; color: var(--tx);
  background: var(--surface-1, var(--surface-2));
  border: 1px solid var(--line-2); border-radius: var(--r-2);
  font: var(--fs-2) / 1.45 "Inter", ui-sans-serif, system-ui, sans-serif;
}
.kai-feld::placeholder{ color: var(--tx-3); }
.kai-feld:focus-visible{ outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--brand-line, var(--brand)); }
.kai-senden{
  flex: 0 0 auto; inline-size: 40px; block-size: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand); color: var(--brand-ink);
  border: 1px solid transparent; border-radius: var(--r-2); cursor: pointer;
  transition: background .15s ease;
}
.kai-senden:hover:not(:disabled){ background: color-mix(in oklab, var(--brand) 88%, #fff); }
.kai-senden:disabled{ opacity: .5; cursor: default; }
.kai-senden:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }

.kai-fuss{
  margin: 0; padding: 0 var(--sp-4) var(--sp-3, .75rem);
  font-size: var(--fs-1); color: var(--tx-3); background: var(--surface-2);
}

/* Auf dem Handy nimmt es die ganze Flaeche, sonst tippt niemand darin. */
@media (max-width: 640px){
  .kai-launcher{ inset-block-end: var(--sp-4); inset-inline-end: var(--sp-4); }
  .kai-fenster{
    inset: 0; inline-size: 100%; block-size: 100%;
    border: 0; border-radius: 0;
  }
  .kai-launcher.ist-offen{ display: none; }
}

/* --- Profilbild im Team: Groesse festnageln -----------------------------
   Marcels Bild wurde 34x44 statt 44x44 gezeichnet, also seitlich
   zusammengedrueckt. Grund: das <img> steckt in einem <picture>, und das
   ist ein Flex-Element ohne eigene Breite. Seine Karte traegt zwei Zeilen
   Text statt einer, dadurch ging der Reihe der Platz aus und das <picture>
   gab nach. Das globale "img { max-width: 100% }" zog das Bild dann mit,
   obwohl an ihm 44px stehen. Also bekommt der Rahmen selbst eine feste
   Groesse und darf nicht mehr schrumpfen. */
picture:has(> img.team-bild){
  flex: 0 0 44px !important;
  inline-size: 44px; block-size: 44px;
  display: block; line-height: 0;
}
.team-bild{
  max-inline-size: none !important; min-inline-size: 44px;
  aspect-ratio: 1; object-position: center;
}

/* --- AgencyAI: Bildlaufleisten und Zaehler -------------------------------
   Im Fenster stand die graue Windows-Bildlaufleiste mit Pfeilkoepfen: hell,
   breit, und im Eingabefeld lief sie bis in die abgerundete Ecke. Auf einer
   dunklen Seite faellt das sofort auf. Firefox bekommt scrollbar-*, alle
   anderen die ::-webkit-Regeln; beide fuehren zum selben Bild. */
.kai-liste, .kai-feld{
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--tx-3) 55%, transparent) transparent;
}
.kai-liste::-webkit-scrollbar,
.kai-feld::-webkit-scrollbar{ inline-size: 8px; block-size: 8px; }
.kai-liste::-webkit-scrollbar-track,
.kai-feld::-webkit-scrollbar-track{ background: transparent; }
.kai-liste::-webkit-scrollbar-thumb,
.kai-feld::-webkit-scrollbar-thumb{
  background: color-mix(in oklab, var(--tx-3) 45%, transparent);
  border-radius: 999px;
  /* Der durchsichtige Rand haelt den Griff von der abgerundeten Ecke fern. */
  border: 2px solid transparent;
  background-clip: content-box;
}
.kai-liste:hover::-webkit-scrollbar-thumb,
.kai-feld:hover::-webkit-scrollbar-thumb{
  background: color-mix(in oklab, var(--tx-3) 75%, transparent);
  background-clip: content-box;
}
/* Die Pfeilkoepfe oben und unten fallen ganz weg. */
.kai-liste::-webkit-scrollbar-button,
.kai-feld::-webkit-scrollbar-button{ display: none; block-size: 0; }
.kai-liste::-webkit-scrollbar-corner,
.kai-feld::-webkit-scrollbar-corner{ background: transparent; }
/* Das Eingabefeld haelt rechts Platz frei, damit der Text nicht unter den
   Griff laeuft, sobald es mehrzeilig wird. */
.kai-feld{ padding-inline-end: 14px; }

/* Zaehler und Countdown. Solange etwas uebrig ist, steht dort ruhig
   "7 von 10 Fragen"; ist nichts mehr uebrig, laeuft die Uhr sichtbar und
   der Text wird warnfarben, damit klar ist, warum nichts mehr geht. */
.kai-fuss{ font-variant-numeric: tabular-nums; transition: color .2s ease; }
.kai-fuss.ist-leer{ color: var(--brand-text); font-weight: var(--fw-ui, 500); }
.kai-feld:disabled{
  opacity: .55; cursor: not-allowed;
  background: color-mix(in oklab, var(--surface-2) 70%, transparent);
}

/* --- Datenschutz-Widerruf in der Fusszeile ------------------------------
   Vorher schwebte der Knopf unten links ueber dem Inhalt; auf dem Handy war
   er ein breiter Balken quer ueber der Seite. Jetzt steht er als Text neben
   Impressum, Datenschutz und AGB und sieht aus wie diese Links, damit die
   Zeile ruhig bleibt. Erreichbar ist er weiterhin von jeder Seite aus, was
   fuer den Widerruf einer Einwilligung auch verlangt ist. */
.privacy-consent-manage-fuss{
  position: static !important;
  inset: auto !important;
  z-index: auto !important;
  display: inline !important;
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  box-shadow: none !important;
  color: inherit !important;
  font: inherit !important;
  cursor: pointer;
  text-decoration: none;
  transition: color .15s ease;
}
.privacy-consent-manage-fuss:hover{ color: var(--brand-text) !important; }
.privacy-consent-manage-fuss:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }

/* --- Zwei Ueberschneidungen aus dem Nachmessen ---------------------------

   1. Der KI-Knopf und die Companion-Einblendung sassen an derselben Stelle
      unten rechts, und die Einblendung liegt mit z-index 9998 darueber.
      Der Knopf weicht deshalb nach oben aus, solange sie da ist. Der Versatz
      steht in einer eigenen Variablen, die agencyai.js setzt und wieder
      zuruecknimmt, wenn die Einblendung weggeklickt wird.

   2. Der Widerrufsknopf in der Fusszeile stand eine Zeile tiefer als
      Impressum, Datenschutz und AGB. Als Flex-Element richtete er seinen
      Text anders aus als die Links daneben. */
.kai-launcher{
  transition: transform .18s ease, background .18s ease,
              box-shadow .18s ease, inset-block-end .25s ease;
}
.kai-fenster{
}
@media (max-width: 640px){
  /* Auf dem Handy nimmt das Fenster die ganze Flaeche, der Versatz entfaellt. */
  .kai-fenster{ inset-block-end: 0 !important; }
}



/* --- Companion-Einblendung und KI-Knopf teilen sich die Ecke -------------
   Beide sassen unten rechts uebereinander. Die Einblendung rueckt jetzt
   ueber den Knopf, statt ihn zu verdecken, und tritt ganz zurueck, sobald
   der Chat offen ist. Ihre Masse stehen im HTML als Inline-Angaben, deshalb
   braucht es hier "important".

   .kai-da setzt agencyai.js nur auf Seiten, die den Knopf wirklich haben.
   Auf allen anderen bleibt die Einblendung, wo sie war. */
html.kai-da #cmp-apk-note{
  /* 32px Grundabstand + 48px Knopfhoehe + 12px Luft */
  bottom: 92px !important;
  transition: opacity .2s ease, transform .2s ease;
}
html.kai-offen #cmp-apk-note{
  opacity: 0 !important;
  transform: translateY(8px);
  pointer-events: none !important;
  visibility: hidden !important;
}
@media (max-width: 640px){
  /* Auf dem Handy nimmt der Chat die ganze Flaeche, dort steht die
     Einblendung nie im Weg; nur der Knopf sitzt tiefer. */
  html.kai-da #cmp-apk-note{ bottom: 76px !important; }
}
@media (prefers-reduced-motion: reduce){
  html.kai-da #cmp-apk-note{ transition: none; }
}

/* --- Widerrufsknopf: auf dieselbe Schriftlinie wie seine Nachbarn --------
   Er stand tiefer als Impressum, Datenschutz und AGB. Grund: als Flex-Element
   wurde der Knopf auf die volle Zeilenhoehe gestreckt und zentrierte seinen
   Text darin, waehrend die Links daneben auf ihrer Schriftlinie sitzen.
   "align-self: baseline" richtet ihn an genau dieser Linie aus, statt an der
   Mitte eines gestreckten Kastens. */
.privacy-consent-manage-fuss{
  display: inline-block !important;
  align-self: baseline !important;
  vertical-align: baseline;
  line-height: inherit !important;
  block-size: auto !important;
  min-block-size: 0 !important;
}

/* --- Einblenden: dezent und ausfallsicher -------------------------------
   Vorher: opacity 0 und 50px Versatz, eingeblendet von GSAP ScrollTrigger.
   Loeste das nicht aus, blieb der Text unsichtbar UND verschoben und legte
   sich auf die Ueberschrift darunter. Auf Englisch war genau das zu sehen,
   weil setLanguage() nach dem Messen alle Texte umschreibt und die
   Ausloesepunkte damit nicht mehr passen.

   Jetzt uebernimmt reveal.js das Umschalten per IntersectionObserver, und
   die Bewegung ist auf ein Fuenftel geschrumpft: 10px statt 50px. Man soll
   es kaum bemerken, es soll nur nicht hart erscheinen. */
.reveal{
  opacity: 0;
  transform: translateY(10px) !important;
  transition: opacity .45s cubic-bezier(.22,.61,.36,1),
              transform .45s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
.reveal.ist-sichtbar{
  opacity: 1 !important;
  transform: none !important;
  will-change: auto;
}
/* Wer keine Bewegung moechte, sieht alles sofort und ohne Uebergang. */
html.reveal-sofort .reveal{ transition: none !important; }
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* --- Alte Farbnamen auf die neue Palette legen ---------------------------
   Blog, Vergleichsseiten, Tools und die Rechtstexte tragen noch die alten
   Namen aus der Tuerkis-Zeit: --highlight-start/-end, --text-* und die
   --bg-*. Die Startseite bildet sie laengst auf die neuen Token ab, aber
   das stand nur in ihrem eigenen Kopf. Hier steht es einmal fuer alle
   Seiten, die tokens.css einbinden.

   Die Datei wird als letzte im Kopf eingebunden, deshalb gewinnen diese
   Zeilen gegen die Angaben im Seitenkopf, ohne dass es !important braucht. */
:root{
  --highlight-start: var(--brand-text);
  --highlight-end: var(--brand-text);
  --text-primary: var(--tx);
  --text-secondary: var(--tx-2);
  --text-tertiary: var(--tx-3);
}
html.light-mode{
  --highlight-start: var(--brand-text);
  --highlight-end: var(--brand-text);
  --text-primary: var(--tx);
  --text-secondary: var(--tx-2);
  --text-tertiary: var(--tx-3);
}

/* --- Wortmarke auf Unterseiten ------------------------------------------
   Auf den Unterseiten steht "Agency Scripts" noch in Orbitron. Bei den
   sechs Zeichen von "TDYSKY" ging das; bei vierzehn Zeichen in zwei Woertern
   laeuft die Technikschrift auseinander und wirkt billig. Die Startseite
   traegt sie deshalb laengst in Inter mit enger Laufweite, hier zieht der
   Rest der Seiten nach. */
header a.font-orbitron,
header .font-orbitron{
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif !important;
  letter-spacing: -.02em !important;
  font-weight: 700 !important;
}

/* --- Kategoriemarken im Blog --------------------------------------------
   Lila, Pink und Blau stammen aus der alten Palette und stehen neben dem
   Gold wie versehentlich stehengeblieben. Sie tragen jetzt dieselbe Farbe
   wie alles andere, unterscheiden sich aber weiter in der Beschriftung. */
.category-tag{
  background: color-mix(in oklab, var(--brand) 14%, transparent) !important;
  color: var(--brand-text) !important;
  border: 1px solid color-mix(in oklab, var(--brand) 30%, transparent) !important;
  border-radius: var(--r-1) !important;
  font-weight: var(--fw-ui, 500) !important;
  letter-spacing: .04em;
}

/* --- Tippziele auf dem Handy -------------------------------------------
   Nachgemessen bei 375px: die Punkte im Schubfach waren 235x25 Pixel hoch,
   der Schliessen-Knopf 18x32. Zum Treffen mit dem Daumen ist das zu wenig;
   ueblich sind 44px Kantenlaenge. Die Schrift bleibt gleich gross, es
   wird nur der antippbare Bereich vergroessert. */
@media (max-width: 767px){
  .mobile-menu a,
  .mobile-menu button:not(.mobile-close):not([class*="absolute"]){
    min-block-size: 44px;
    display: flex;
    align-items: center;
  }
  .mobile-menu .mobile-group-label{ margin-block-start: var(--sp-4); }
  /* Der Schliessen-Knopf oben rechts im Schubfach. */
  .mobile-menu button[class*="absolute"]{
    inline-size: 44px !important; block-size: 44px !important;
    display: inline-flex !important; align-items: center; justify-content: center;
    margin: -10px -10px 0 0;
  }
  /* Knoepfe und Links ausserhalb des Schubfachs, die zu flach geraten sind. */
  header button, header a[href]:not(.wordmark):not([class*="font-orbitron"]){
    min-block-size: 40px;
  }
}

/* --- Eigener Mauszeiger und geoeffnete Fenster --------------------------
   Der gezeichnete Zeiger (Ring, Punkt, Funken) liegt bei z-index
   2147483646. Ein <dialog> mit showModal() liegt im Top-Layer und damit
   grundsaetzlich darueber, ganz gleich wie hoch der z-index ist. Ergebnis:
   im Suchfenster lief der Zeiger sichtbar HINTER der Flaeche weiter, waehrend
   daneben der echte Zeiger stand. Solange ein Fenster offen ist, zeichnen
   wir deshalb gar nichts mehr und ueberlassen es dem System. */
html.suche-offen .ag-cursor-ring,
html.suche-offen .ag-cursor-dot,
html.suche-offen > body > canvas[aria-hidden="true"],
html.kai-offen .ag-cursor-ring,
html.kai-offen .ag-cursor-dot,
html.kai-offen > body > canvas[aria-hidden="true"]{
  display: none !important;
}
html.suche-offen, html.kai-offen{ cursor: auto !important; }
html.suche-offen *, html.kai-offen *{ cursor: revert !important; }
html.suche-offen input, html.suche-offen textarea,
html.kai-offen input, html.kai-offen textarea{ cursor: text !important; }
html.suche-offen a, html.suche-offen button,
html.kai-offen a, html.kai-offen button{ cursor: pointer !important; }

/* --- Wortmarke in Gold ---------------------------------------------------
   Logo und Schriftzug standen in Weiss, das Logo daneben jetzt in Gold.
   Beides gehoert zusammen, also traegt auch der Schriftzug die Markenfarbe.
   Zwei Selektoren, weil die Startseite die Klasse .wordmark benutzt und die
   Unterseiten den Rest ihres alten Kopfes mitbringen. */
header a.wordmark,
header a.font-orbitron,
.wordmark{
  color: var(--brand-text) !important;
}
header a.wordmark:hover,
header a.font-orbitron:hover{
  color: color-mix(in oklab, var(--brand-text) 82%, #fff) !important;
  opacity: 1;
}

/* --- Phone und Pad ohne Rahmen, dem Zeiger zugewandt -------------------
   Beide sassen in einem dunklen Kasten mit Rand: das wirkte wie ein Bild im
   Bilderrahmen und liess das Geraet zugleich angeschnitten aussehen, weil der
   Kasten kleiner war als sein Inhalt. Der Kasten ist weg, das Geraet steht
   frei und wird von geraete.js zum Mauszeiger geneigt. */
.agency-phone-visual, .agency-pad-visual{
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  border-radius: 0 !important;
  overflow: visible !important;
  perspective: 1100px;
}
.agency-phone-visual img, .agency-pad-visual img{
  border-radius: var(--r-3);
  transform-style: preserve-3d;
  will-change: transform, filter;
  /* Grundschatten, damit das Geraet auch ohne Zeiger nicht flach aufliegt. */
  filter: drop-shadow(0 26px 42px rgb(0 0 0 / .5));
  transition: filter .2s ease;
}
/* Auf Geraeten ohne Maus bleibt es ruhig, aber es schwebt weiterhin. */
@media (hover: none){
  .agency-phone-visual img, .agency-pad-visual img{
    filter: drop-shadow(0 18px 30px rgb(0 0 0 / .45));
  }
}
@media (prefers-reduced-motion: reduce){
  .agency-phone-visual img, .agency-pad-visual img{ transition: none; }
}

/* --- Terminal: die Eingabezeile ---------------------------------------- */
.term-eingabe{ display: flex; align-items: center; gap: .35rem; }
/* Die Eingabezeile soll als Eingabe erkennbar sein. Vorher stand dort nur
   ein Prompt mit blinkendem Strich, und niemand sah, dass man hier mit der
   AgencyAI schreiben kann. */
.term-eingabe.bereit{ margin-top: .35rem; padding: .5rem .7rem;
  border: 1px solid rgba(45,212,191,.28); border-radius: 10px;
  background: rgba(45,212,191,.05);
  box-shadow: 0 0 0 0 rgba(45,212,191,.35); animation: termBereit 2.6s ease-in-out infinite; }
.term-eingabe.bereit:focus-within{ border-color: rgba(45,212,191,.6);
  background: rgba(45,212,191,.08); animation: none; }
.term-eingabe.bereit .term-feld{ flex: 1; }
@keyframes termBereit{ 0%,100%{ box-shadow: 0 0 0 0 rgba(45,212,191,.30) }
  50%{ box-shadow: 0 0 0 4px rgba(45,212,191,0) } }
@media (prefers-reduced-motion: reduce){ .term-eingabe.bereit{ animation: none } }
.term-feld{
  flex: 1 1 auto; min-inline-size: 4ch;
  background: none; border: 0; outline: none; padding: 0;
  color: var(--tx); font: inherit; caret-color: var(--brand);
}
.term-feld::placeholder{ color: var(--tx-3); }
.dev-terminal-body{ cursor: text; }
.term-link{ color: var(--brand-text); text-decoration: underline; text-underline-offset: 2px; }
.term-link:hover{ color: color-mix(in oklab, var(--brand-text) 80%, #fff); }

/* --- Einwilligung muss bedienbar sein ----------------------------------
   Nachgemessen bei 375px: der APK-Hinweis (#cmp-apk-note, z-index 9998) lag
   ueber dem Zustimmen-Knopf des Banners (z-index 140) und verdeckte 82,5 %
   seiner Flaeche. Ein echter Fingertipp in die Knopfmitte fuehrte nicht zur
   Zustimmung, sondern auf companion.agencyg.de. Bei 320px war der Knopf
   vollstaendig unerreichbar.

   Das ist nicht nur unschoen: eine Einwilligung, die sich nicht erteilen
   laesst, ist keine. Zwei Massnahmen, damit es nicht wieder passieren kann:

   1. Die Einwilligung liegt jetzt oben. Sie ist das Einzige, was auf einer
      Seite wirklich Vorrang hat.
   2. Solange das Banner offen ist, tritt der APK-Hinweis ganz zurueck. Ein
      Produkthinweis darf eine Rechtsabfrage nicht ueberdecken. */
.privacy-consent-root, #privacy-consent-root{
  z-index: 2147483000 !important;
}
html:has(#privacy-consent-banner:not([hidden])) #cmp-apk-note{
  display: none !important;
}
/* Rueckfall fuer Browser ohne :has() : auf schmalen Fenstern rueckt der
   Hinweis grundsaetzlich ueber den Bereich, in dem das Banner steht. */
@media (max-width: 767px){
  #cmp-apk-note{ bottom: 320px !important; }
}

/* --- Merkmalskacheln bei Phone und Pad ---------------------------------
   Vorher: unterschiedlich hoch, je nachdem ob der Text ein- oder zweizeilig
   umbrach, dazu ein schwerer Rahmen und ungleiche Innenabstaende. Neben-
   einander sah das aus wie vier verschiedene Bausteine.

   Jetzt: alle Kacheln einer Reihe sind gleich hoch (das uebernimmt das
   Raster), Symbol und Text sitzen auf einer gemeinsamen Grundlinie, der
   Rahmen ist so leicht wie bei den uebrigen Flaechen der Seite, und der Text
   bricht nicht mehr mitten im Begriff. */
.agency-phone-features, .agency-pad-features{
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--sp-3, .75rem) !important;
  align-items: stretch;
}
.agency-phone-feature, .agency-pad-feature{
  display: flex !important;
  align-items: center;
  gap: var(--sp-3, .75rem);
  min-block-size: 64px;
  padding: var(--sp-3, .75rem) var(--sp-4) !important;
  background: var(--surface-2) !important;
  border: 1px solid var(--line-2) !important;
  border-radius: var(--r-2) !important;
  box-shadow: none !important;
  font-size: var(--fs-2);
  line-height: 1.4;
  color: var(--tx);
  /* Kein Umbruch mitten im Wort, und die Zeilen moeglichst gleich lang. */
  text-wrap: pretty;
  transition: border-color .18s ease, background .18s ease;
}
.agency-phone-feature:hover, .agency-pad-feature:hover{
  border-color: color-mix(in oklab, var(--brand) 34%, var(--line-2)) !important;
  background: var(--surface-3, var(--surface-2)) !important;
}
/* Das Symbol bekommt eine feste Groesse, damit die Textspalten aller vier
   Kacheln an derselben Stelle beginnen. */
.agency-phone-icon, .agency-pad-icon{
  flex: 0 0 34px;
  inline-size: 34px; block-size: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-1);
  background: color-mix(in oklab, var(--brand) 14%, transparent) !important;
  border: 1px solid color-mix(in oklab, var(--brand) 26%, transparent) !important;
  color: var(--brand-text) !important;
  font-size: 14px;
}

/* --- Burger-Knopf fuer die Unterseiten ---------------------------------
   Die Startseite hat ihren eigenen; kopfzeile.js legt auf allen anderen
   Seiten einen an, weil dort am Handy sonst gar kein Menue erreichbar war.
   44px Kantenlaenge, damit man ihn mit dem Daumen trifft. */
.mobile-burger{
  display: none;
  inline-size: 44px; block-size: 44px;
  align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line-2); border-radius: var(--r-1);
  color: var(--tx); cursor: pointer; flex: 0 0 auto;
  margin-inline-start: var(--sp-1);
}
.mobile-burger:hover{ border-color: var(--brand-line, var(--brand)); }
.mobile-burger:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }
@media (max-width: 767px){
  .mobile-burger{ display: inline-flex; }
}
/* Der Schliessen-Knopf im Schubfach, gleiche Trefferflaeche. */
.mobile-menu .mobile-close{
  inline-size: 44px; block-size: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; color: var(--tx-2); cursor: pointer;
}
.mobile-menu .mobile-close:hover{ color: var(--tx); }
.mobile-menu .mobile-group-label{
  color: var(--tx-3); font-size: var(--fs-1); text-transform: uppercase;
  letter-spacing: .08em; margin-block-end: calc(var(--sp-1) * -1);
}
.mobile-menu nav a{ color: var(--tx-2); text-decoration: none; }
.mobile-menu nav a:hover{ color: var(--brand-text); }
.mobile-menu nav a.btn-primary{ color: var(--brand-ink); }

/* --- Logo darf am Handy nicht nachgeben --------------------------------
   Auf schmalen Fenstern wurde das Logo angeschnitten. Ursache ist dieselbe
   wie frueher beim Profilbild im Team: die Kopfleiste ist eine Flex-Reihe,
   und wenn der Platz knapp wird, schrumpft das erste Element. Seit der
   Burger-Knopf dazugekommen ist, wird es schneller knapp.

   Das Logo und die Wortmarke geben deshalb nicht mehr nach; nachgeben soll
   der Bereich, der es verkraftet, naemlich die Wortmarke ueber Auslassungs-
   punkte, bevor sie das Bild mitreisst. */
header #header-logo{
  flex: 0 0 auto !important;
  inline-size: 40px !important; block-size: 40px !important;
  min-inline-size: 40px;
  max-inline-size: none !important;
  object-fit: contain;
}
header a:has(> #header-logo), header picture:has(> #header-logo){
  flex: 0 0 auto !important;
  line-height: 0;
}
header .wordmark, header a.font-orbitron{
  flex: 0 1 auto;
  min-inline-size: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* --- Platz am Handy: der Knopf tritt zurueck, nicht die Marke -----------
   Zuerst hatte ich die Wortmarke unter 420px ausgeblendet, damit das Logo
   nicht mehr angeschnitten wird. Das war die falsche Reihenfolge: dann fehlt
   der Name der Marke ausgerechnet auf dem Geraet, auf dem die meisten
   Besucher ankommen. Platz macht jetzt der Such-Knopf, der unter 480px nur
   noch sein Symbol zeigt. Die Suche selbst bleibt vollstaendig erreichbar,
   sie oeffnet ohnehin ein eigenes Fenster. */
@media (max-width: 480px){
  .suche-knopf span, .suche-knopf kbd{ display: none !important; }
  .suche-knopf{
    inline-size: 44px !important; padding-inline: 0 !important;
    justify-content: center;
  }
  header .wordmark, header a.font-orbitron{
    font-size: var(--fs-3) !important;
    letter-spacing: -.02em !important;
  }
}

/* --- Die Konsole: Eingabezeile und Fensterrahmen -----------------------
   Aus der Vorfuehrung ist eine Konsole geworden, die man bedienen kann.
   Damit sie sich nicht wie ein aufgeklebtes Formular anfuehlt, traegt das
   Eingabefeld keinen eigenen Rahmen: es sitzt einfach hinter dem Prompt,
   wie in einer echten Shell. */
.term-eingabe{ display: flex; align-items: baseline; gap: 0; }
.term-feld{
  flex: 1 1 auto; min-inline-size: 0;
  background: none !important; border: 0 !important; outline: none;
  padding: 0 !important; margin: 0;
  color: var(--term-cmd, #e8e8ea);
  font: inherit;
  caret-color: var(--brand);
}
.term-feld::placeholder{ color: color-mix(in oklab, currentColor 45%, transparent); }
.dev-terminal-body a.term-link{
  color: var(--brand-text); text-decoration: underline; text-underline-offset: 2px;
}
.dev-terminal-body a.term-link:hover{ color: var(--brand); }
/* Der Zeiger im Fenster soll sagen "hier kann getippt werden". */
.dev-terminal-body{ cursor: text; }

/* --- Fenster groesser ziehen -------------------------------------------
   Die drei Punkte oben waren reine Zierde. Jetzt tun sie etwas: gelb legt
   das Fenster zusammen, gruen zieht es auf die volle Breite, rot raeumt den
   Inhalt. Dazu ein Griff an der Unterkante, mit dem man die Hoehe zieht. */
/* Der Ziehgriff sitzt am Inhalt (siehe .dev-terminal-body weiter unten),
   nicht am Rahmen: aussen haette overflow:auto einen zweiten Rollbalken
   um das ganze Fenster gelegt. */
.dev-terminal.ist-gross{
  /* Gross, aber an seinem Platz: absolut im eigenen Umfeld statt fixed am
     Bildschirm. Vorher klebte das Fenster beim Scrollen fest, das war als
     Ueberlagerung gedacht und hat gestoert. Jetzt waechst es dort, wo es
     steht, und wandert beim Scrollen mit. */
  /* Lage und Breite setzt das Skript in Seitenkoordinaten; hier steht nur,
     dass das Fenster aus dem Fluss geht. Die linke Kante bleibt damit stehen
     und das Fenster waechst nach rechts. */
  position: absolute;
  inline-size: 640px;
  max-inline-size: none !important;
  block-size: 448px;
  max-block-size: none;
  display: flex;
  flex-direction: column;
  z-index: 30;
  box-shadow: 0 30px 90px rgba(0, 0, 0, .55);
  animation: devTermAuf .28s cubic-bezier(.2, .8, .2, 1) both;
}
@keyframes devTermAuf{
  from{ opacity: 0; transform: scale(.97); }
  to{ opacity: 1; transform: none; }
}
/* Der Umfeld-Rahmen bekommt beim Aufziehen die Bezugsgroesse, sonst wuerde
   "absolut" auf irgendeinen Vorfahren weiter oben zielen. Setzt das Skript. */
.dev-terminal-umfeld{ position: relative; }
.dev-terminal.ist-gross .dev-terminal-body{
  flex: 1 1 auto;
  overflow: auto;
  resize: none;
  max-block-size: none;
}
/* Zusammenlegen, weich statt schlagartig. Die Hoehe setzt das Skript vor dem
   Umschalten auf den gemessenen Wert, damit es etwas zu bewegen gibt. */
.dev-terminal-body{ transition: opacity .22s ease; }
.dev-terminal-body.faehrt{ overflow: hidden !important; }
.dev-terminal.ist-klein .dev-terminal-body{
  /* Hoehe wirklich auf null, sonst waere block-size:auto am Fenster gleich
     wieder die volle Inhaltshoehe — gemessen kam das Fenster nach dem
     Zuklappen auf 345 statt auf die Leistenhoehe zurueck. */
  block-size: 0 !important;
  min-block-size: 0 !important;
  opacity: 0;
  overflow: hidden;
  padding-block: 0;
  border-block-start-width: 0;
}
/* Zusammengelegt schrumpft auch das grosse Fenster auf die Leiste. */
/* Waehrend der Bewegung fuehrt das Skript die Hoehe in Pixeln; nur dann soll
   ueberhaupt etwas uebergehen, sonst wuerde jede Groessenaenderung nachziehen. */
.dev-terminal.faehrt{ transition: block-size .3s cubic-bezier(.4, 0, .2, 1); }
.dev-terminal.faehrt .dev-terminal-body{ overflow: hidden !important; }
.dev-terminal.ist-klein{ block-size: auto; }
.dev-terminal.ist-gross.ist-klein{ block-size: auto; }
.dev-terminal-platz{ flex: none; }
@media (max-width: 900px){
  /* Kein Platz fuer ein Fenster daneben: gross heisst hier "bleibt stehen,
     nutzt die volle Spaltenbreite und wird hoeher". Die Lage aus dem Skript
     wird bewusst ueberschrieben — am Handy wird sie gar nicht erst gesetzt. */
  .dev-terminal.ist-gross{
    position: relative !important;
    inset: auto !important;
    inline-size: 100% !important;
    block-size: min(72vh, 620px) !important;
  }
  .dev-terminal.ist-gross.ist-klein{ block-size: auto !important; }
}

.dev-terminal-dot{ cursor: pointer; transition: transform .12s ease, filter .12s ease; }
.dev-terminal-dot:hover{ transform: scale(1.18); filter: brightness(1.15); }
.dev-terminal-dot:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }
.dev-terminal-body{
  resize: vertical;
  min-block-size: 160px;
}
@media (max-width: 767px){
  /* Am Handy nicht ziehbar, dort ist die Hoehe knapp und der Griff stoert. */
  .dev-terminal-body{ resize: none; }
}

/* --- Kacheln wirklich gleich hoch --------------------------------------
   Mein erster Versuch zielte auf ".agency-phone-features". So heisst der
   Rahmen aber nicht: er traegt "space-y-4 mb-10" und wird von anderer Stelle
   zum Raster gemacht. Meine Regeln fuer align-items und die Zeilenhoehe
   liefen also ins Leere, gemessen 70/70/70/86 Pixel.

   Jetzt wird der Rahmen ueber seinen Inhalt angesprochen, egal wie er heisst.
   "grid-auto-rows: 1fr" macht alle Zeilen gleich hoch, damit auch eine
   zweizeilige Kachel ihre Nachbarin nicht mehr ueberragt. */
:has(> .agency-phone-feature), :has(> .agency-pad-feature){
  align-items: stretch !important;
  grid-auto-rows: 1fr !important;
}
.agency-phone-feature, .agency-pad-feature{ align-self: stretch !important; }

/* --- Der letzte Tuerkiston -------------------------------------------
   Der kleine Punkt vor den Abschnittsmarken war noch tuerkis. Er ist reine
   Zierde und gehoert zur Marke, also wird er golden. Die gruenen Punkte, die
   "laeuft" oder "online" bedeuten, bleiben gruen: dort traegt die Farbe eine
   Aussage, und Gold wuerde sie unverstaendlich machen. */
.agency-kicker .dot, .kicker .dot, .agency-overline .dot{
  background: var(--brand) !important;
}

/* --- Kachelhoehe, jetzt ohne Umweg -------------------------------------
   Zwei Anlaeufe ueber das Raster haben nicht gereicht: align-items:stretch
   und grid-auto-rows:1fr sind zwar angekommen (nachgemessen), gleichen aber
   ohne feste Rasterhoehe nichts aus, und die Kacheln liegen nicht alle im
   selben Raster.

   Also der direkte Weg: jede Kachel ist mindestens so hoch, wie sie mit zwei
   Textzeilen waere. Dann ist es gleich, ob der Text umbricht, und es haelt
   auch in den anderen vier Sprachen, wo die Beschriftungen laenger sind. */
.agency-phone-feature, .agency-pad-feature{
  min-block-size: 5.5rem !important;
}

/* Der Punkt im Abzeichen der Kopfzeile ist Zierde, kein Betriebszustand. */
a.status-band .dot, .status-band .dot{ background: var(--brand) !important; }

/* --- Kachelhoehe endgueltig -------------------------------------------
   Dritter und letzter Anlauf. Die Untergrenze allein reichte nicht: sie hebt
   die kurzen Kacheln an, die lange bleibt trotzdem hoeher (gemessen 88 gegen
   104), weil ihr Text zwei Zeilen braucht.

   Also eine feste Hoehe mit Reserve fuer drei Zeilen, dazu eine Stufe
   kleinere Schrift. Damit passt jede Beschriftung hinein, auch die langen
   im Franzoesischen und Portugiesischen, und alle Kacheln sind gleich hoch,
   ohne dass etwas abgeschnitten wird. */
.agency-phone-feature, .agency-pad-feature{
  block-size: 6.5rem !important;
  min-block-size: 6.5rem !important;
  font-size: var(--fs-1) !important;
  line-height: 1.4 !important;
}

/* --- Hellmodus fuer ALLE Seiten ----------------------------------------
   Nachgemessen: die Startseite hat 59 Regeln fuer den Hellmodus, Blog und
   Werkzeuge je 10 bis 13, die Produktseiten, die Partnerseite und das
   Changelog aber genau EINE. Dort blieb die Seite dunkel, obwohl die Klasse
   gesetzt war; auf /de/affiliate war der Hintergrund im Hellmodus gemessen
   rgb(23,18,10), also unveraendert dunkel.

   Die Seiten arbeiten alle mit denselben Variablennamen. Sie hier zentral
   umzudrehen ist deshalb wirksamer, als auf tausend Seiten Regeln nachzu-
   tragen: tokens.css liegt auf allen 1050 Seiten. */
html.light-mode{
  --text-primary: #16181d;
  --text-secondary: #4b5563;
  --text-tertiary: #6b7280;

  --glass-bg: rgba(255, 255, 255, .72);
  --glass-border: rgba(0, 0, 0, .08);
  --glass-shadow: 0 18px 44px rgba(0, 0, 0, .10);
  --glass-glow: 0 0 34px rgba(201, 162, 39, .10);

  /* Gold auf hellem Grund braucht mehr Tiefe, sonst verschwindet es. */
  --highlight-start: #7a5a12;
  --highlight-end: #8a6a1a;
  --highlight-purple: #7a5a12;
  --highlight-pink: #8a6a1a;
  --interactive-glow: rgba(122, 90, 18, .28);
  --interactive-glow-intense: rgba(122, 90, 18, .45);
}
html.light-mode body{
  background: #f7f7f5;
  color: var(--text-primary);
}
/* Flaechen, die ihre Farbe fest mitbringen, statt der Variablen zu folgen. */
html.light-mode .glass-panel,
html.light-mode .dev-terminal,
html.light-mode .kai-fenster{
  background: rgba(255, 255, 255, .86);
  border-color: rgba(0, 0, 0, .08);
}
/* Das Terminal bleibt bewusst dunkel: eine Konsole ist dunkel, auch auf einer
   hellen Seite. Nur ihr Rahmen passt sich an. */
html.light-mode .dev-terminal-body{ background: #14161c; }
html.light-mode .dev-terminal-body,
html.light-mode .dev-terminal-body *{ color: #e8e8ea; }

/* --- Sonne und Mond: eine Regel fuer alle Seiten -----------------------
   Die Startseite tauscht die beiden Symbole ueber opacity und bringt ihre
   Regeln selbst mit. Auf den Unterseiten fehlten sie: dort standen im
   Hellmodus BEIDE Symbole gleichzeitig auf Deckkraft 1, also sah man Sonne
   und Mond uebereinander.

   Die Logik folgt der der Startseite: das Symbol zeigt den AKTUELLEN Zustand,
   nicht das Ziel. Dunkel zeigt den Mond, hell die Sonne.

   Die eigenen Regeln der Startseite stehen in einem <style>-Block nach dieser
   Datei und gewinnen dort weiterhin; hier wird nur ergaenzt, wo nichts ist. */
#theme-switch-button{ position: relative; }
#sun-icon, #moon-icon{
  transition: opacity .22s ease, transform .22s ease;
}
#sun-icon{ opacity: 0 !important; }
#moon-icon{ opacity: 1 !important; }
html.light-mode #sun-icon{ opacity: 1 !important; }
html.light-mode #moon-icon{ opacity: 0 !important; }
/* Beide sitzen uebereinander, damit der Knopf beim Wechsel nicht springt. */
#theme-switch-button:has(#sun-icon):has(#moon-icon) #sun-icon,
#theme-switch-button:has(#sun-icon):has(#moon-icon) #moon-icon{
  grid-area: 1 / 1;
}
#theme-switch-button:has(#sun-icon):has(#moon-icon){
  display: grid; place-items: center;
}
@media (prefers-reduced-motion: reduce){
  #sun-icon, #moon-icon{ transition: none; }
}

/* Das eigene Symbol im Theme-Knopf. Es traegt keine fremden Regeln und ist
   deshalb das einzige, was zuverlaessig sichtbar ist. */
#theme-switch-button .theme-eigen{
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--tx, currentColor);
  line-height: 0;
}
#theme-switch-button:hover .theme-eigen{ color: var(--brand-text); }

/* --- Handy: Kopfleiste entlasten ---------------------------------------
   Bei 375px standen Logo, Wortmarke, Lupe, Sprachwahl, Theme-Knopf und
   Burger in einer Zeile. Das war abgeschnitten. Oben bleiben Logo,
   Wortmarke, Lupe und Burger; Sprache und Ansicht wandern ins Schubfach.
   Auf dem Rechner aendert sich nichts, das steuert allein die Breite. */
@media (max-width: 767px){
  header #theme-switch-button,
  header #lang-menu-button,
  header .lang-menu,
  header #lang-menu-panel{
    display: none !important;
  }
  /* Die Lupe bleibt oben, wie Leon es wollte, nur als Symbol. */
  header .suche-knopf{ display: inline-flex !important; }
}

/* Der Zusatzblock im Schubfach. */
.handy-extra{
  margin-block-start: var(--sp-6);
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line-2);
  display: flex; flex-direction: column; gap: var(--sp-3, .75rem);
}
.handy-titel{
  margin: 0; color: var(--tx-3);
  font-size: var(--fs-1); text-transform: uppercase; letter-spacing: .08em;
}
.handy-eintrag{
  display: inline-flex; align-items: center; gap: var(--sp-3, .75rem);
  min-block-size: 44px; padding-inline: 0;
  background: none; border: 0; color: var(--tx);
  font-size: var(--fs-3); cursor: pointer; text-align: start;
}
.handy-eintrag:hover{ color: var(--brand-text); }
.handy-reihe{ display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.handy-chip{
  min-block-size: 40px; padding: 8px 14px;
  display: inline-flex; align-items: center;
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: 999px; color: var(--tx-2);
  font-size: var(--fs-2); text-decoration: none; cursor: pointer;
}
.handy-chip:hover{ color: var(--tx); border-color: var(--brand-line, var(--brand)); }
.handy-chip[aria-current="true"]{
  background: var(--brand); border-color: transparent;
  color: var(--brand-ink); font-weight: var(--fw-ui, 500);
}
.handy-chip:focus-visible, .handy-eintrag:focus-visible{
  outline: 2px solid var(--focus); outline-offset: 2px;
}

/* --- Klappflaeche ohne Luecke ------------------------------------------
   Damit der Zeiger vom Ausloeser zur Flaeche kommt, ohne dazwischen "ins
   Nichts" zu geraten, ueberbrueckt ein unsichtbarer Streifen den Abstand.
   Zusammen mit der Frist im Skript bleibt das Menue zuverlaessig offen. */
header .nav-menu::before{
  content: ""; position: absolute;
  inset-inline: 0; inset-block-start: -10px; block-size: 10px;
}
header .nav-group{ position: relative; }

/* --- Kein Wischen nach links und rechts --------------------------------
   Auf dem Handy liess sich die Seite seitlich wegschieben, obwohl kein
   Inhalt ueberstand (gemessen: scrollWidth 375 bei 375px Fenster). Der
   Grund lag am <html>: overflow-x stand auf "visible" und das seitliche
   Ueberdehnen war erlaubt. */
html{
  overflow-x: clip;
  overscroll-behavior-x: none;
  max-inline-size: 100%;
}
body{
  overflow-x: clip;
  overscroll-behavior-x: none;
  max-inline-size: 100%;
}

/* --- Handy: kuerzer scrollen, ohne Inhalt zu verlieren -----------------
   Gemessen waren es 13 225px, also 16,3 Bildschirme. Gekuerzt wird an den
   Abstaenden und an Texten, die eine Aussage doppelt treffen. Preise,
   Ueberschriften, Knoepfe und Merkmale bleiben alle stehen. */
@media (max-width: 767px){
  /* 1. Abstaende: die Seite atmet auf dem Rechner, auf dem Handy zaehlt jede
        Bildschirmhoehe. */
  section{ padding-block: clamp(2rem, 7vw, 3rem) !important; }
  .section-y{ padding-block: clamp(2rem, 7vw, 3rem) !important; }
  section > .wrap, section > .max-w-7xl{ row-gap: var(--sp-6) !important; }

  /* 2. Der Vorspann unter einer Ueberschrift sagt oft dasselbe wie die
        Ueberschrift. Auf dem Handy bleibt die Ueberschrift, der zweite
        Erklaersatz geht. */
  .agency-overline, .agency-phone-lead + p, .lead-sekundaer{ display: none !important; }

  /* 3. Das Terminal ist eine Schau fuer den Rechner. Auf dem Handy bleibt es,
        aber kompakt: man sieht, worum es geht, ohne zwei Bildschirme dafuer. */
  .dev-terminal-body{ max-block-size: 210px !important; }

  /* 4. Die Community-Tafel war mit 2 857px der laengste Block. Das
        eingebettete Discord-Fenster und der Server-Schaukasten sind auf dem
        Handy kaum lesbar; die Mitgliederzahl und der Beitritts-Knopf sagen
        dasselbe auf einem Zehntel der Hoehe. */
  /* Nur das eingebettete Fenster selbst, NICHT der Zustimmungsrahmen:
     der enthaelt auf dem Handy auch das Newsletter-Formular. */
  #community iframe{ display: none !important; }

  /* 5. Bilder duerfen nicht mehr als eine halbe Bildschirmhoehe fuellen. */
  #agency-phone img, #agency-pad img{ max-block-size: 42vh !important; width: auto !important; }
}

/* --- Ausklappbare Untermenues im Handy-Schubfach -----------------------
   Zugeklappt sieht man nur die vier bis fuenf Titel und braucht nicht zu
   scrollen. Es ist immer nur eine Gruppe offen, das haelt die Liste kurz. */
.handy-falt{ border-block-end: 1px solid var(--line-2); }
.handy-falt:last-of-type{ border-block-end: 0; }
.handy-falt-kopf{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3, .75rem);
  min-block-size: 52px; padding-inline: 2px;
  color: var(--tx); font-size: var(--fs-3); font-weight: var(--fw-ui, 500);
  cursor: pointer; list-style: none;
}
.handy-falt-kopf::-webkit-details-marker{ display: none; }
.handy-falt-kopf:hover{ color: var(--brand-text); }
.handy-falt-kopf:focus-visible{ outline: 2px solid var(--focus); outline-offset: 2px; }
.falt-pfeil{ flex: 0 0 auto; color: var(--tx-3); transition: transform .2s ease; }
.handy-falt[open] > .handy-falt-kopf .falt-pfeil{ transform: rotate(90deg); }
.handy-falt[open] > .handy-falt-kopf{ color: var(--brand-text); }
.handy-falt-koerper{
  display: flex; flex-direction: column; gap: var(--sp-1);
  padding-block: 2px var(--sp-3, .75rem); padding-inline-start: var(--sp-3, .75rem);
}
.handy-falt-koerper > a{
  min-block-size: 44px; display: flex; align-items: center;
  color: var(--tx-2); text-decoration: none; font-size: var(--fs-2);
}
.handy-falt-koerper > a:hover{ color: var(--brand-text); }
.handy-falt-koerper .handy-reihe{ padding-block: var(--sp-1); }
@media (prefers-reduced-motion: reduce){ .falt-pfeil{ transition: none; } }
/* Das Schubfach selbst braucht dadurch keinen eigenen Rollbalken mehr. */
.mobile-menu{ overflow-y: auto; overscroll-behavior: contain; }

/* --- Zusammengefaltete Nebentafeln auf dem Handy -----------------------
   Zugeklappt kostet eine lange Tafel eine Zeile statt 800 Pixel. Der Inhalt
   bleibt vollstaendig da, einen Fingertipp entfernt. */
.handy-tafel-falt{
  border: 1px solid var(--line-2);
  border-radius: var(--r-2);
  background: var(--surface-2);
  margin-block: var(--sp-3, .75rem);
}
.handy-tafel-kopf{
  display: flex; align-items: center; gap: var(--sp-2, .5rem);
  min-block-size: 56px; padding-inline: var(--sp-4);
  color: var(--tx); font-size: var(--fs-3); font-weight: var(--fw-ui, 500);
  cursor: pointer; list-style: none;
}
.handy-tafel-kopf::-webkit-details-marker{ display: none; }
.handy-tafel-kopf > span{ flex: 1 1 auto; min-inline-size: 0; }
.handy-tafel-kopf > em{
  flex: 0 0 auto; font-style: normal;
  color: var(--brand-text); font-size: var(--fs-1);
}
.handy-tafel-kopf > svg{ flex: 0 0 auto; color: var(--tx-3); transition: transform .2s ease; }
.handy-tafel-falt[open] > .handy-tafel-kopf > svg{ transform: rotate(180deg); }
.handy-tafel-falt > .glass-panel{
  border: 0 !important; background: none !important; margin: 0 !important;
}
@media (prefers-reduced-motion: reduce){ .handy-tafel-kopf > svg{ transition: none; } }

/* --- Der Newsletter bleibt am Handy sichtbar ----------------------------
   Nachgemessen: die Tafel mit dem Anmeldeformular stand bei 375px auf
   display:none, auch nach dem Scrollen (opacity war 1, die Einblend-
   Animation war also durch). Ein Anmeldeformular, das auf dem Geraet fehlt,
   ueber das die meisten Besucher kommen, ist ein echter Verlust, deshalb
   wird es hier ausdruecklich zurueckgeholt.

   Die Regel steht am Ende der Datei und traegt Vorrang, damit sie unabhaengig
   davon greift, was es zugeklappt hat. */
@media (max-width: 767px){
  #newsletter,
  #newsletter .glass-panel,
  #community form,
  #community .sib-form,
  #community input[type="email"],
  #EMAIL{
    display: revert !important;
    visibility: visible !important;
    opacity: 1 !important;
  }
  #newsletter .glass-panel{ display: block !important; }
}

/* Kopfleiste auf eine eigene Ebene heben.
   Die Leiste steht fest und traegt backdrop-filter: blur(10px). Ohne eigene
   Ebene muss der Browser diesen Weichzeichner bei jeder Aenderung dahinter neu
   berechnen — auf der Blog-Uebersicht sind das 159 dauerlaufende Animationen
   auf knapp 13.000 Pixel Seitenhoehe, deshalb ruckelt es dort am staerksten.
   translateZ(0) und contain halten das Neuzeichnen in der Leiste selbst.
   Rein technisch, das Aussehen aendert sich nicht. */
/* contain: paint waere hier falsch — es schneidet die Klappmenues am
   unteren Rand der Leiste ab (nachgemessen und im Bild geprueft). */
header{ will-change: transform; transform: translateZ(0); }

/* Die Konsole ist immer dunkel, auch im Hellmodus. Das Eingabefeld hat sich
   daran nicht gehalten: gemessen weisser Grund mit dunkler Schrift, was als
   heller Balken quer durch das Fenster lief. Es gehoert in dieselbe Farbwelt
   wie die Zeilen darueber. */
.dev-terminal .term-feld{
  background: transparent !important;
  color: #e8f3ef !important;
  border: 0 !important;
  outline: none !important;
  box-shadow: none !important;
  caret-color: var(--highlight-start, #e2b649);
}
.dev-terminal .term-feld::placeholder{ color: rgba(232, 243, 239, .38) !important; }
.dev-terminal .term-eingabe{ background: transparent !important; }

/* Ausnahme von der Hellmodus-Regel fuer Eingabefelder weiter oben: die Konsole
   bleibt auch im Hellen dunkel, ein weisses Feld liefe als Balken quer durch
   das Fenster. Gleiche Spezifitaet wie die Regel, die es sonst gewinnt. */
html.light-mode .dev-terminal .term-feld,
html.light-mode .dev-terminal input[type="text"]{
  background: transparent !important;
  border: 0 !important;
  color: #e8f3ef !important;
  box-shadow: none !important;
}

/* --- Scrollleiste --------------------------------------------------------
   Dieselbe schmale goldene Leiste wie auf den Seiten, die sie in ihrem
   eigenen <style> mitbringen. Hier steht sie fuer alle. */
::-webkit-scrollbar{width:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--highlight-start);border-radius:3px;min-height:40px}
