/* ============================================================
   AXONA Core — Newsletter-Modul
   ------------------------------------------------------------
   Ein Markup, drei Rhythmen. Die Optik kommt vollständig aus den
   Theme-Tokens (tokens.css), damit das Modul jede Farb- oder
   Radien-Änderung der Seite ohne Nacharbeit mitnimmt.

   Varianten
     .ax-nl--card    Eigenständige Fläche, ab 760px MODULBREITE zweispaltig
                     (Text links, Formular rechts). Für Seiten, auf denen
                     die Anmeldung ein eigener Abschnitt ist.
     .ax-nl--inline  Für den Fließtext im Blog: volle Breite, einspaltig,
                     kompakter Rhythmus, ohne Eyebrow.
     .ax-nl--slim    Nur Headline, Eingabezeile und Vertrauenszeile — für
                     Footer und Randplatzierungen, wo das Modul nicht
                     führen darf.

   Zustände setzt newsletter.js: .is-focus / .is-valid / .is-invalid am
   Pill, .is-err / .is-tip am Hinweis, .is-busy am Formular, .is-done an
   der Sektion. Alles darunter ist reines CSS ohne JS-Abhängigkeit —
   ohne JavaScript bleibt das Modul ein normales POST-Formular.

   Dark Mode über [data-theme="dark"] am <html>, exakt wie im Theme.
   Das Umbrechen hängt an Container Queries (@container axnl / axnlform),
   nicht am Viewport — das Modul steht im Blog in einer schmalen Spalte.
   Für Browser ohne Container Queries bleibt die Viewport-Logik als
   Rückfall in @supports not (container-type: inline-size) erhalten.
   ============================================================ */

/* ------------------------------------------------------------
   1) Fundament: eigene Skala am Wurzelelement des Moduls
   Alle Abstände, Radien und Schatten werden hier einmal abgeleitet.
   So bleibt der Rest der Datei frei von verstreuten px-Werten und
   die Varianten müssen nur diese Handvoll Werte umdefinieren.
   ------------------------------------------------------------ */
.ax-nl {
  /* Abstandsskala — leitet sich aus den Theme-Tokens ab, ergänzt um
     zwei Zwischenschritte, die es im Theme nicht gibt.

     --nl-k zieht die ganze Skala um eine Stufe enger. Ein Anmeldeformular
     ist kein Abschnitt: es soll dicht stehen. Der Faktor sitzt bewusst an
     einer Stelle, damit die Verhältnisse der Skala erhalten bleiben —
     wer es luftiger will, dreht hier, nicht an einzelnen Regeln. */
  --nl-k: .78;
  --nl-1: calc(var(--space-1, .5rem) * var(--nl-k));
  --nl-2: calc(var(--space-2, .875rem) * var(--nl-k));
  --nl-3: calc(var(--space-3, 1.25rem) * var(--nl-k));
  --nl-4: calc(var(--space-4, 2rem) * var(--nl-k));
  --nl-5: calc(var(--space-5, 3rem) * var(--nl-k));
  --nl-pad: clamp(1.15rem, .9rem + 2vw, 2.25rem);   /* Innenabstand der Fläche */
  --nl-gap: clamp(1.25rem, .9rem + 2vw, 2rem);      /* Spaltenabstand */

  /* Radien */
  --nl-r: var(--r-lg, 24px);
  --nl-r-in: var(--r-sm, 10px);
  --nl-r-pill: var(--r-pill, 999px);

  /* Höhe der Eingabezeile — Pille und Button teilen sie sich, damit die
     Einheit auf dem Desktop wirklich als ein Element gelesen wird.
     3.125rem = 50px: unter der Vorgängerhöhe, aber weiterhin klar über
     den 44px, die eine Touch-Fläche mindestens braucht. */
  --nl-h: 3.125rem;

  /* Dreistufiger Schatten: Kontaktkante, Nahfeld, weiche Tiefe.
     Ein einzelner Schatten wirkt bei dieser Flächengröße immer wie
     ein grauer Kasten. */
  --nl-shadow:
    0 1px 2px rgba(11, 16, 32, .05),
    0 14px 28px -18px rgba(23, 34, 73, .28),
    0 44px 70px -40px rgba(23, 34, 73, .32);

  --nl-line: var(--line, #e3e9f3);
  --nl-field: var(--surface, #fff);
  --nl-ok: #16a34a;
  --nl-err: #dc2626;

  position: relative;
  isolation: isolate;          /* hält den Glow unter dem Inhalt, ohne z-index-Kette */
  margin-block: var(--nl-5);
  color: var(--ink-2);
  font-family: var(--font-body);

  /* Das Modul steht mal in voller Seitenbreite, mal in einer 676px
     schmalen Artikelspalte. Der Viewport sagt darüber nichts aus —
     deshalb misst sich das Layout an der eigenen Breite. */
  container-type: inline-size;
  container-name: axnl;
}

/* Innenabstand und Spaltenabstand an der Modulbreite statt am Viewport:
   in der schmalen Artikelspalte fiel der vw-Wert sonst viel zu groß aus. */
@supports (container-type: inline-size) {
  .ax-nl {
    --nl-pad: clamp(1.15rem, .9rem + 3cqi, 2.25rem);
    --nl-gap: clamp(1.25rem, .9rem + 3cqi, 2rem);
  }
}

.ax-nl *,
.ax-nl-state * { box-sizing: border-box; }

/* [hidden] muss die Layout-Regeln der Zustandsflächen schlagen. Klasse +
   Attribut reicht dafür aus — deshalb hier kein !important. */
.ax-nl [hidden] { display: none; }

/* ------------------------------------------------------------
   1a) Fremdstile aus .entry-content abfangen
   Im Blog hängt das Modul im Artikelfluss. Dort gestaltet das Theme
   jede Liste mit einem grünen Haken (.entry-content ul li::before und
   ::after), setzt padding-left, Absatzabstände und unterstreicht Links.
   Diese Regeln sind mit (0,1,2) spezifischer als die Komponente selbst
   und schlugen bis in die Vertrauenszeile durch.

   Der Vertrag garantiert das Attribut [data-axnl] an der Sektion — damit
   gewinnen die folgenden Regeln ohne !important gegen jede
   .entry-content-Regel, egal in welcher Reihenfolge die Dateien laden.

   Die Typselektoren stehen in :where(), damit die Regeln zwar das Theme
   schlagen, die eigenen Komponentenregeln aber unberührt lassen — sonst
   würde der Reset die Abstände der Vertrauenszeile gleich wieder töten.
   ------------------------------------------------------------ */
.ax-nl[data-axnl] :where(ul, ol) {
  list-style: none;
  padding-left: 0;           /* .entry-content ol setzt 1.3rem */
  padding-inline-start: 0;
}
.ax-nl[data-axnl] :where(li) {
  position: static;          /* das Theme setzt relative, um den Haken zu verankern */
  margin: 0;
  padding-left: 0;           /* .entry-content ul li: 1.75rem, ol li: .3rem */
  padding-inline-start: 0;
  list-style: none;
}
/* Der grüne Haken besteht aus zwei Pseudo-Elementen (Kreis + Häkchen).
   Beide müssen weg, sonst stehen sie vor unserem eigenen Icon. */
.ax-nl[data-axnl] :where(li)::before,
.ax-nl[data-axnl] :where(li)::after { content: none; display: none; }
.ax-nl[data-axnl] :where(li)::marker { content: ""; }

/* Blockquote, hr und Tabellen kommen im Modul nicht vor; Überschriften
   bewusst auch nicht (die Headline ist ein <p>), deshalb greifen die
   h2/h3-Regeln des Artikels hier gar nicht erst. Die Absatz-, Link-,
   strong- und em-Regeln des Artikels sind mit (0,1,1) spezifischer als
   eine einzelne Komponentenklasse — die betroffenen Selektoren tragen
   deshalb unten durchgehend den .ax-nl-Präfix. */
.ax-nl[data-axnl] .ax-nl-consent a {
  color: var(--ink-2);
  text-decoration: underline;
  text-decoration-color: currentColor;   /* das Theme tönt die Linie sonst blau */
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.ax-nl[data-axnl] .ax-nl-consent a:hover {
  color: var(--brand-2);
  text-decoration-color: currentColor;
}

/* ------------------------------------------------------------
   2) Dekorativer Verlauf
   Zwei sehr weiche Farbwolken statt eines flächigen Farbverlaufs:
   das Modul bekommt Tiefe, ohne bunt zu werden.
   ------------------------------------------------------------ */
.ax-nl-glow {
  position: absolute;
  inset: -12% -6%;
  z-index: -1;
  pointer-events: none;
  opacity: .55;
  background:
    radial-gradient(38% 55% at 12% 8%, color-mix(in srgb, var(--brand-1) 26%, transparent), transparent 70%),
    radial-gradient(42% 60% at 92% 88%, color-mix(in srgb, var(--brand-3) 20%, transparent), transparent 72%);
  filter: blur(38px);
  transition: opacity var(--dur-2, .42s) var(--ease, ease);
}

/* ------------------------------------------------------------
   3) Innenraster
   ------------------------------------------------------------ */
.ax-nl-inner { display: grid; gap: var(--nl-gap); grid-template-columns: minmax(0, 1fr); align-items: start; }

.ax-nl-copy { min-width: 0; }
/* Zweiter Container: die Eingabezeile richtet sich nach der Breite ihrer
   Spalte, nicht nach der des ganzen Moduls (siehe Abschnitt 7). */
.ax-nl-form-wrap { min-width: 0; container-type: inline-size; container-name: axnlform; }

/* ------------------------------------------------------------
   4) Textspalte
   ------------------------------------------------------------ */
.ax-nl-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--nl-1);
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--brand-2);
}
.ax-nl-eyebrow svg { width: 16px; height: 16px; flex: none; }

/* Semantisch ein <p>, damit die Überschriften-Hierarchie der Seite
   nicht durch ein eingebettetes Modul gestört wird — optisch aber
   eine Headline. */
.ax-nl .ax-nl-h {
  margin: var(--nl-2) 0 0;
  font-family: var(--font-head);
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -.02em;
  color: var(--ink);
  text-wrap: balance;
}

/* Der Lead trägt seit dem Wegfall der Bullet-Liste beide Aussagen: was in
   der Ausgabe steht und wann keine kommt. Zwei Sätze, eine Ebene — 54ch
   halten daraus zwei bis drei Zeilen, ohne die Spalte auszureizen. */
.ax-nl .ax-nl-lead {
  margin: var(--nl-2) 0 0;
  max-width: 54ch;      /* Lesbarkeit vor Ausnutzung der Spaltenbreite */
  color: var(--muted);
  font-size: var(--step-0);
  line-height: 1.55;
}

/* ------------------------------------------------------------
   5) Formular
   ------------------------------------------------------------ */
.ax-nl-form { display: grid; gap: var(--nl-3); margin: 0; }

/* Honigtopf: für Menschen unsichtbar, für Bots aber ein ganz normales,
   ausfüllbares Feld. display:none oder visibility:hidden erkennen
   Ausfüll-Skripte zuverlässig — deshalb die Offscreen-Technik des
   Projekts. Absolut positioniert nimmt es im Grid keinen Platz ein. */
.ax-nl-hp { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* --- Eingabezeile --- */
.ax-nl-row { display: grid; gap: var(--nl-2); grid-template-columns: minmax(0, 1fr); align-items: center; }

/* Der Pill ist der umschließende Rahmen — Kante, Fläche und Fokusring
   sitzen hier, das <input> selbst bleibt vollständig unsichtbar. */
.ax-nl-input {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--nl-1);
  min-height: var(--nl-h);
  padding: 0 var(--nl-3);
  border: 1px solid var(--nl-line);
  border-radius: var(--nl-r-pill);
  background: var(--nl-field);
  box-shadow: var(--shadow-sm);
  transition:
    border-color var(--dur-1, .18s) var(--ease, ease),
    box-shadow var(--dur-1, .18s) var(--ease, ease);
}
.ax-nl-input > svg {
  width: 19px;
  height: 19px;
  flex: none;
  color: var(--muted);
  transition: color var(--dur-1, .18s) var(--ease, ease);
}
.ax-nl-input input {
  flex: 1 1 auto;
  min-width: 0;
  padding: .7rem 0;   /* die Höhe der Zeile macht --nl-h, nicht das Feld */
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.2;
  color: var(--ink);
}
.ax-nl-input input::placeholder { color: var(--muted); opacity: .8; }

/* Die globale :focus-visible-Regel des Themes legt einen zweiten,
   eckigeren Ring in die Pille. Genau dieser Fehler ist hier schon
   einmal aufgetreten — der Fokus gehört ausschließlich nach außen. */
.ax-nl-input input:focus,
.ax-nl-input input:focus-visible { outline: none; box-shadow: none; border-radius: 0; }

/* Ein Ring, zwei Auslöser: :focus-within trägt den Zustand ohne
   JavaScript, .is-focus setzt ihn das Script identisch. */
.ax-nl-input:focus-within,
.ax-nl-input.is-focus {
  border-color: var(--brand-2);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-2) 18%, transparent);
}
.ax-nl-input:focus-within > svg,
.ax-nl-input.is-focus > svg { color: var(--brand-2); }

.ax-nl-input.is-valid {
  border-color: color-mix(in srgb, var(--nl-ok) 55%, var(--nl-line));
}
.ax-nl-input.is-valid > svg { color: var(--nl-ok); }
.ax-nl-input.is-invalid {
  border-color: color-mix(in srgb, var(--nl-err) 65%, var(--nl-line));
}
.ax-nl-input.is-invalid > svg { color: var(--nl-err); }
/* Der Fokusring gewinnt gegen die Statusfarbe: wer tippt, soll den
   Rahmen nicht rot blinken sehen, sondern wissen, wo er ist. */
.ax-nl-input.is-invalid:focus-within,
.ax-nl-input.is-invalid.is-focus {
  border-color: var(--nl-err);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--nl-err) 18%, transparent);
}

/* --- Absende-Button --- */
.ax-nl-go {
  position: relative;
  justify-content: center;
  min-height: var(--nl-h);
  padding-inline: 1.5rem;
  white-space: nowrap;
}
.ax-nl-go-t { transition: opacity var(--dur-1, .18s) var(--ease, ease); }
/* Eigener Fokusring statt des globalen: auf dem farbigen Verlauf hat der
   Standardring zu wenig Kontrast. Der Versatz hebt ihn von der Kapsel ab. */
.ax-nl-go:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 3px; box-shadow: none; }

/* Der Spinner liegt absolut über der Beschriftung und die Beschriftung
   behält ihren Platz — der Button kann beim Senden nicht springen. */
.ax-nl-go-s {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255, 255, 255, .45);
  border-top-color: #fff;
  border-radius: 50%;
  opacity: 0;
}
.ax-nl-form.is-busy { cursor: progress; }
.ax-nl-form.is-busy .ax-nl-go { pointer-events: none; transform: none; }
.ax-nl-form.is-busy .ax-nl-go-t { opacity: 0; }
.ax-nl-form.is-busy .ax-nl-go-s { opacity: 1; animation: axNlSpin .7s linear infinite; }
.ax-nl-form.is-busy .ax-nl-input { opacity: .7; }
@keyframes axNlSpin { to { transform: rotate(360deg); } }

/* --- Hinweiszeile --- */
.ax-nl .ax-nl-hint {
  margin: calc(var(--nl-3) * -1 + var(--nl-1)) 0 0;   /* rückt näher an die Zeile, auf die sie sich bezieht */
  font-size: .85rem;
  line-height: 1.5;
  color: var(--muted);
  animation: axNlHint .25s var(--ease-out, ease);
}
.ax-nl-hint.is-err { color: var(--nl-err); font-weight: 600; }
.ax-nl-hint.is-tip { color: var(--ink-2); }

/* Tippfehler-Vorschlag: sieht aus wie ein Link, ist aber ein Button —
   deshalb bekommt er hier alle Button-Vorgaben zurückgesetzt. */
.ax-nl-fix {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 700;
  color: var(--brand-2);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ax-nl-fix:hover { color: var(--brand-1); }
.ax-nl-fix:focus-visible { outline: none; border-radius: 4px; box-shadow: 0 0 0 3px var(--ring); }
@keyframes axNlHint { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }

/* --- Einwilligung --- */
.ax-nl-consent {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--nl-2);
  align-items: start;   /* bei Umbruch bleibt das Kästchen an der ersten Zeile */
  font-size: .84rem;
  line-height: 1.45;
  color: var(--muted);
  cursor: pointer;
}
/* Eigene Kästchen-Optik: die Systemdarstellung bricht die Kanten- und
   Radienlogik der übrigen Felder. */
.ax-nl-consent input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0;   /* Kästchen (20px) und Zeilenhöhe (~19.5px) stehen deckungsgleich */
  flex: none;
  border: 1.5px solid var(--nl-line);
  border-radius: 6px;
  background: var(--nl-field);
  cursor: pointer;
  transition:
    background var(--dur-1, .18s) var(--ease, ease),
    border-color var(--dur-1, .18s) var(--ease, ease);
}
.ax-nl-consent input[type="checkbox"]:checked {
  border-color: transparent;
  background:
    var(--brand-grad)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E")
    center / 13px no-repeat;
}
.ax-nl-consent input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.ax-nl-consent:hover input[type="checkbox"]:not(:checked) { border-color: var(--brand-2); }
.ax-nl-consent a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; }
.ax-nl-consent a:hover { color: var(--brand-2); }

/* --- Vertrauenszeile --- */
.ax-nl .ax-nl-trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nl-1) var(--nl-3);
  margin: 0;
  padding: var(--nl-2) 0 0;
  border-top: 1px solid color-mix(in srgb, var(--nl-line) 70%, transparent);
  list-style: none;
}
.ax-nl-trust li {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;   /* Icon und Text sollen nie getrennt umbrechen */
}
.ax-nl-trust svg { width: 15px; height: 15px; flex: none; color: var(--brand-2); opacity: .9; }

/* ------------------------------------------------------------
   6) Erfolgszustand
   Hier entscheidet sich, ob die Doppel-Opt-in-Mail auch wirklich
   bestätigt wird — die Fläche darf also nicht untergehen. Sie braucht
   dafür aber keine eigene Kachelgröße: Haken, eine Zeile Überschrift und
   der Hinweis auf die Bestätigungsmail tragen das auch kompakt.
   ------------------------------------------------------------ */
.ax-nl-done {
  display: grid;
  justify-items: start;
  gap: var(--nl-1);
  padding: var(--nl-3);
  border: 1px solid color-mix(in srgb, var(--brand-2) 28%, var(--nl-line));
  border-radius: var(--nl-r);
  background: var(--brand-grad-soft);
  animation: axNlPop .45s var(--ease-out, ease) both;
}
.ax-nl-done-ic {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: var(--nl-1);
  border-radius: var(--nl-r-pill);
  background: var(--brand-grad);
  color: #fff;
  box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--brand-2) 80%, transparent);
}
/* Der Haken wird gezeichnet statt eingeblendet — die kurze Bewegung
   bestätigt die Handlung, ohne zu feiern. */
.ax-nl-done-ic svg {
  width: 20px;
  height: 20px;
  stroke-width: 2.6;
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  animation: axNlDraw .5s var(--ease-out, ease) .15s forwards;
}
.ax-nl .ax-nl-done-h {
  margin: 0;
  font-family: var(--font-head);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--ink);
}
.ax-nl .ax-nl-done-x {
  margin: 0;
  max-width: 50ch;
  font-size: .9rem;
  line-height: 1.5;
  color: var(--ink-2);
}
@keyframes axNlPop { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes axNlDraw { to { stroke-dashoffset: 0; } }

/* Ist die Anmeldung durch, hat das Formular keine Aufgabe mehr — und der
   Glow tritt zurück, damit die Bestätigung die Fläche trägt. */
.ax-nl.is-done .ax-nl-form { display: none; }
.ax-nl.is-done .ax-nl-glow { opacity: .28; }

/* --- Rückmeldung ohne JavaScript --- */
.ax-nl .ax-nl-flash {
  margin: var(--nl-3) 0 0;
  padding: var(--nl-2) var(--nl-3);
  border: 1px solid var(--nl-line);
  border-left-width: 3px;
  border-radius: var(--nl-r-in);
  font-size: .9rem;
  line-height: 1.55;
}
.ax-nl-flash.is-ok {
  border-left-color: var(--nl-ok);
  background: color-mix(in srgb, var(--nl-ok) 8%, transparent);
  color: var(--ink-2);
}
.ax-nl-flash.is-err {
  border-left-color: var(--nl-err);
  background: color-mix(in srgb, var(--nl-err) 8%, transparent);
  color: var(--ink-2);
}

/* ------------------------------------------------------------
   7) Variante --card
   Eigene Fläche mit feiner Kante. Ab 760px Modulbreite zwei Spalten:
   links die Begründung, rechts die Handlung.
   ------------------------------------------------------------ */
.ax-nl--card { max-width: var(--container); margin-inline: auto; }
.ax-nl--card .ax-nl-inner {
  padding: var(--nl-pad);
  border: 1px solid var(--nl-line);
  border-radius: var(--nl-r);
  background: var(--surface);
  box-shadow: var(--nl-shadow);
}

/* Zwei Spalten erst, wenn das MODUL breit genug ist — nicht der Viewport.
   Am Artikelende steht die Karte in einer 676px-Spalte: dort ergaben die
   alten 900px Viewport-Breite zwei Spalten von 272px und 246px — und
   damit eine Karte, die höher war als der Absatz davor. Bei 760px
   Modulbreite bleiben je Spalte gut 300px plus Innenabstand, ab da trägt
   die Zweispaltigkeit. */
@container axnl (min-width: 760px) {
  .ax-nl--card .ax-nl-inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    align-items: center;
  }
  /* Feine Trennlinie statt eines zweiten Kastens: die Spalten bleiben
     eine Fläche und trennen sich trotzdem sichtbar. */
  .ax-nl--card .ax-nl-form-wrap {
    padding-left: var(--nl-gap);
    border-left: 1px solid color-mix(in srgb, var(--nl-line) 75%, transparent);
  }
}

/* Die Eingabezeile hängt an der Breite ihrer eigenen Spalte, nicht am
   Modul: in der zweispaltigen Karte ist die Formularspalte deutlich
   schmaler als das Modul. Deshalb ist .ax-nl-form-wrap ein zweiter,
   verschachtelter Container — so stapelt die Zeile in einer schmalen
   Spalte automatisch, auch wenn das Modul selbst breit ist. */
@container axnlform (min-width: 440px) {
  .ax-nl-row {
    display: flex;
    gap: 0;
    align-items: stretch;   /* der Button erbt die Höhe der Pille, ohne sie zu kennen */
  }
  .ax-nl-input {
    flex: 1 1 auto;
    padding-right: var(--nl-2);
    border-right-color: transparent;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }
  /* Der Button liegt über der Pille: dadurch endet der Fokusring an der
     Naht sauber, statt als zweiter Ring in die Kapsel hineinzuzeichnen. */
  .ax-nl-go {
    position: relative;
    z-index: 1;
    flex: none;
    min-height: var(--nl-h);
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }
  /* Beim Hover darf die Kapsel nicht auseinanderfallen — der Button hebt
     sich im Theme sonst um 2px an und reißt die Naht auf. Die Rückmeldung
     übernimmt stattdessen die Helligkeit. */
  .ax-nl-go:hover {
    transform: none;
    filter: saturate(1.08) brightness(1.06);
  }
}

/* Rückfall für Browser ohne Container Queries: die alte Viewport-Logik.
   Sie ist in @supports gekapselt, damit sie den Container-Regeln nicht
   in die Quere kommt — sonst würden beide gleichzeitig gelten. */
@supports not (container-type: inline-size) {
  @media (min-width: 900px) {
    .ax-nl--card .ax-nl-inner {
      grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
      align-items: center;
    }
    .ax-nl--card .ax-nl-form-wrap {
      padding-left: var(--nl-gap);
      border-left: 1px solid color-mix(in srgb, var(--nl-line) 75%, transparent);
    }
  }
  @media (min-width: 560px) {
    .ax-nl-row { display: flex; gap: 0; align-items: stretch; }
    .ax-nl-input {
      flex: 1 1 auto;
      padding-right: var(--nl-2);
      border-right-color: transparent;
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
    }
    .ax-nl-go {
      position: relative;
      z-index: 1;
      flex: none;
      min-height: var(--nl-h);
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }
    .ax-nl-go:hover { transform: none; filter: saturate(1.08) brightness(1.06); }
  }
}

/* ------------------------------------------------------------
   8) Variante --inline
   Im Artikel darf das Modul den Lesefluss unterbrechen, aber nicht
   dominieren: keine schwebende Karte, sondern eine ruhige Zone.
   ------------------------------------------------------------ */
.ax-nl--inline {
  --nl-pad: clamp(1.1rem, .9rem + 1.6vw, 1.75rem);
  --nl-gap: var(--nl-3);
  --nl-r: var(--r, 16px);
  margin-block: var(--nl-4);
}
.ax-nl--inline .ax-nl-inner {
  padding: var(--nl-pad);
  border: 1px solid var(--nl-line);
  border-radius: var(--nl-r);
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);   /* flacher als die Karte — es ist kein eigener Abschnitt */
}
/* Im Artikel steht der Block zwischen zwei Absätzen. Das Eyebrow wäre dort
   das dritte „Newsletter" auf engem Raum — die Überschrift und die
   Beschriftung des Buttons sagen es bereits. Es entfällt deshalb hier,
   und mit ihm der Abstand, den die Überschrift darunter hielt. */
.ax-nl--inline .ax-nl-eyebrow { display: none; }
.ax-nl--inline .ax-nl-h { font-size: var(--step-1); margin-top: 0; }
.ax-nl--inline .ax-nl-lead { font-size: .95rem; max-width: 68ch; }
.ax-nl--inline .ax-nl-glow { opacity: .3; }
.ax-nl--inline .ax-nl-trust { font-size: .75rem; }
/* Auch hier misst sich der Innenabstand an der Modulbreite: im Artikel
   ist die Spalte schmal, der Viewport aber breit. */
@supports (container-type: inline-size) {
  .ax-nl--inline { --nl-pad: clamp(1.1rem, .9rem + 2cqi, 1.75rem); }
}

/* ------------------------------------------------------------
   9) Variante --slim
   Die kleinste Stufe: Headline, Eingabezeile, Vertrauenszeile. Eyebrow
   und Lead würden die Randplatzierung nur in die Länge ziehen.
   ------------------------------------------------------------ */
.ax-nl--slim { --nl-h: 2.875rem; --nl-gap: var(--nl-2); margin-block: var(--nl-4); }
.ax-nl--slim .ax-nl-inner { gap: var(--nl-2); }
.ax-nl--slim .ax-nl-eyebrow { display: none; }
.ax-nl--slim .ax-nl-h { font-size: var(--step-1); margin-top: 0; max-width: 30ch; }
.ax-nl--slim .ax-nl-lead { display: none; }
.ax-nl--slim .ax-nl-glow { display: none; }
.ax-nl--slim .ax-nl-form { gap: var(--nl-2); }
.ax-nl--slim .ax-nl-go { padding-inline: 1.25rem; font-size: .9rem; }
.ax-nl--slim .ax-nl-consent { font-size: .78rem; }
/* Ohne Fläche braucht die Vertrauenszeile keine zweite Trennlinie. */
.ax-nl--slim .ax-nl-trust { padding-top: var(--nl-1); border-top: 0; }
.ax-nl--slim .ax-nl-done { padding: var(--nl-2); }

/* ------------------------------------------------------------
   10) Statusmeldung nach Bestätigung oder Abmeldung
   Eigener Shortcode, eigenständige Fläche — sie steht allein auf der
   Seite und muss deshalb ohne das Modul funktionieren.
   ------------------------------------------------------------ */
.ax-nl-state {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3, 1.25rem);
  align-items: start;
  max-width: 46rem;
  margin: var(--space-4, 2rem) auto;
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  border: 1px solid var(--line);
  border-radius: var(--r-lg, 24px);
  background: var(--surface);
  box-shadow:
    0 1px 2px rgba(11, 16, 32, .05),
    0 18px 36px -24px rgba(23, 34, 73, .30);
  font-family: var(--font-body);
  color: var(--ink-2);
  animation: axNlPop .45s var(--ease-out, ease) both;
}
.ax-nl-state-ic {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--r-pill, 999px);
  color: #fff;
  flex: none;
}
.ax-nl-state-ic svg { width: 22px; height: 22px; stroke-width: 2.4; }
.ax-nl-state .ax-nl-state-h {
  margin: 0 0 .3rem;
  font-family: var(--font-head);
  font-size: var(--step-1);
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}
.ax-nl-state .ax-nl-state-x {
  margin: 0;
  font-size: .95rem;
  line-height: 1.65;
  color: var(--ink-2);
}
.ax-nl-state.is-ok { border-color: color-mix(in srgb, var(--nl-ok, #16a34a) 35%, var(--line)); }
.ax-nl-state.is-ok .ax-nl-state-ic { background: linear-gradient(140deg, #22c55e, #15803d); }
.ax-nl-state.is-err { border-color: color-mix(in srgb, #dc2626 35%, var(--line)); }
.ax-nl-state.is-err .ax-nl-state-ic { background: linear-gradient(140deg, #f87171, #b91c1c); }

/* ------------------------------------------------------------
   11) Dark Mode
   Nicht dunkler, sondern anders gewichtet: Schatten tragen im Dunkeln
   keine Information mehr, also übernehmen Kante und Flächenkontrast.
   ------------------------------------------------------------ */
[data-theme="dark"] .ax-nl {
  --nl-shadow:
    0 1px 0 color-mix(in srgb, #fff 6%, transparent) inset,
    0 20px 44px -28px rgba(0, 0, 0, .8);
  --nl-line: var(--line);
  --nl-field: color-mix(in srgb, var(--surface-2) 70%, var(--surface));
  --nl-ok: #4ade80;
  --nl-err: #f87171;
}
[data-theme="dark"] .ax-nl--card .ax-nl-inner {
  border-color: color-mix(in srgb, var(--line) 85%, var(--brand-2));
  background: var(--surface);
}
[data-theme="dark"] .ax-nl--inline .ax-nl-inner {
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
}
/* Im Dunkeln streut Blur stärker — weniger Deckkraft, sonst wirkt der
   Verlauf wie ein Lichtfleck auf der Fläche. */
[data-theme="dark"] .ax-nl-glow { opacity: .38; filter: blur(46px); }
[data-theme="dark"] .ax-nl-input { box-shadow: none; }
[data-theme="dark"] .ax-nl-consent input[type="checkbox"] {
  background-color: color-mix(in srgb, var(--surface-2) 80%, transparent);
}
[data-theme="dark"] .ax-nl-done {
  border-color: color-mix(in srgb, var(--brand-2) 40%, var(--line));
  background: color-mix(in srgb, var(--brand-2) 12%, var(--surface));
}
[data-theme="dark"] .ax-nl-go-s { border-color: rgba(255, 255, 255, .35); border-top-color: #fff; }
[data-theme="dark"] .ax-nl-state {
  box-shadow: 0 20px 44px -28px rgba(0, 0, 0, .8);
  background: var(--surface);
}
[data-theme="dark"] .ax-nl-flash.is-ok { background: color-mix(in srgb, var(--nl-ok) 14%, transparent); }
[data-theme="dark"] .ax-nl-flash.is-err { background: color-mix(in srgb, var(--nl-err) 14%, transparent); }

/* ------------------------------------------------------------
   12) Bewegungsarme Darstellung
   Das Theme schaltet global ab; hier zusätzlich die Endzustände
   sichern, damit gezeichnete Elemente nicht unfertig stehen bleiben.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .ax-nl *,
  .ax-nl-state,
  .ax-nl-state * {
    animation: none;
    transition: none;
  }
  .ax-nl-done,
  .ax-nl-state { opacity: 1; transform: none; }
  .ax-nl-done-ic svg { stroke-dashoffset: 0; }
  .ax-nl-form.is-busy .ax-nl-go-s { opacity: 1; }
}

/* ==================================================================
   Newsletter-Häkchen in den Anfrage-Formularen (Kontakt, Termin,
   Assistent). Es sitzt dort direkt unter der Pflicht-Einwilligung und
   muss sich klar als OPTIONAL zu erkennen geben — deshalb ruhigere
   Fläche, kein Sternchen, kein Rot bei fehlender Auswahl.
   ================================================================== */
.ax-nl-optin {
  margin-top: .75rem;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md, 12px);
  background: var(--surface-2);
}
.ax-nl-optin-l {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .7rem;
  align-items: start;
  cursor: pointer;
  margin: 0;
}
.ax-nl-optin-l input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: .1rem 0 0;
  accent-color: var(--brand-2, var(--brand));
  flex: none;
  cursor: pointer;
}
.ax-nl-optin-l > span { display: block; }
.ax-nl-optin-l strong {
  display: block;
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
}
.ax-nl-optin-l em {
  display: block;
  margin-top: .2rem;
  font-style: normal;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink-2);
}
/* Fokus sichtbar am ganzen Block, nicht nur am kleinen Kästchen. */
.ax-nl-optin:focus-within {
  border-color: var(--brand-2, var(--brand));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-2, var(--brand)) 22%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .ax-nl-optin { transition: border-color .18s ease, box-shadow .18s ease; }
}
