:root {
  --font-system-ui: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;
  --indigo-7-hsl: 228 81% 59%;
  --gray-12-hsl: 210 40% 2%;
  --gray-7-hsl: 210 9% 31%;
  --gray-0-hsl: 210 17% 98%;
  --red-6-hsl: 0 94% 65%;
  --green-6-hsl: 131 50% 50%;
  --blue-6-hsl: 208 80% 52%;
  --yellow-9-hsl: 31 100% 45%;
  --size-content-3: 60ch;
  --size-fluid-4: max(2rem,min(4vw,3rem));
  --size-fluid-3: max(1.5rem,min(3vw,2rem));
  --indigo-3-hsl: 228 100% 78%;
  --gray-1-hsl: 210 17% 95%;
  --gray-4-hsl: 210 14% 83%;
  --gray-9-hsl: 210 11% 15%;
  --gray-6-hsl: 210 7% 56%;
  --red-4-hsl: 0 100% 76%;
  --green-4-hsl: 130 61% 64%;
  --blue-4-hsl: 207 91% 64%;
  --yellow-4-hsl: 47 100% 62%;
  --font-lineheight-3: 1.5;
  --ease-2: cubic-bezier(.25,0,.4,1);
  --font-weight-9: 900;
  --font-lineheight-1: 1.25;
  --font-size-8: 3.5rem;
  --size-header-1: 20ch;
  --font-size-6: 2.5rem;
  --size-header-2: 25ch;
  --font-size-5: 2rem;
  --font-size-4: 1.5rem;
  --font-size-3: 1.25rem;
  --size-header-3: 35ch;
  --font-size-2: 1.1rem;
  --size-1: .25rem;
  --size-2: .5rem;
  --size-relative-4: 1.25ch;
  --size-content-1: 20ch;
  --size-3: 1rem;
  --size-10: 5rem;
  --font-monospace-code: Dank Mono,Operator Mono,Inconsolata,Fira Mono,ui-monospace,SF Mono,Monaco,Droid Sans Mono,Source Code Pro,Cascadia Code,Menlo,Consolas,DejaVu Sans Mono,monospace;
  --radius-2: 5px;
  --border-size-1: 1px;
  --size-8: 3rem;
  --size-content-2: 45ch;
  --font-weight-7: 700;
  --size-5: 1.5rem;
  --font-size-0: .75rem;
  --border-size-2: 2px;
  --size-fluid-5: max(4rem,min(5vw,5rem));
  --font-size-1: 1rem;
  --border-size-3: 5px;
  --size-4: 1.25rem;
  --radius-3: 1rem;
  --shadow-6: 0 -1px 2px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 3px 2px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 7px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 12px 10px -2px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 22px 18px -2px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 41px 33px -2px hsl(var(--shadow-color)/var(--shadow-strength-7)),0 100px 80px -2px hsl(var(--shadow-color)/var(--shadow-strength-8));
  --shadow-3: 0 -1px 3px 0 hsl(var(--shadow-color)/var(--shadow-strength-3)),0 1px 2px -5px hsl(var(--shadow-color)/var(--shadow-strength-3)),0 2px 5px -5px hsl(var(--shadow-color)/var(--shadow-strength-5)),0 4px 12px -5px hsl(var(--shadow-color)/var(--shadow-strength-6)),0 12px 15px -5px hsl(var(--shadow-color)/var(--shadow-strength-8));
  --size-fluid-2: max(1rem,min(2vw,1.5rem));
  --inner-shadow-4: inset 0 2px 14px 0 hsl(var(--shadow-color)/var(--shadow-strength-10)),var(--inner-shadow-highlight);
  --size-relative-6: 1.75ch;
  --font-weight-6: 600;
  --shadow-color: 220 40% 2%;
  --shadow-strength-3: calc(var(--shadow-strength) + 2%);
  --shadow-strength-4: calc(var(--shadow-strength) + 3%);
  --shadow-strength-5: calc(var(--shadow-strength) + 4%);
  --shadow-strength-6: calc(var(--shadow-strength) + 5%);
  --shadow-strength-7: calc(var(--shadow-strength) + 6%);
  --shadow-strength-8: calc(var(--shadow-strength) + 7%);
  --shadow-strength-10: calc(var(--shadow-strength) + 9%);
  --inner-shadow-highlight: inset 0 -.5px 0 0 hsla(0,0%,100%,.067),inset 0 .5px 0 0 rgba(0,0,0,.467);
  --shadow-strength: 25%;
  --gray-5-hsl: 210 11% 71%;
  --size-relative-7: 2ch;
  --shadow-2: 0 3px 5px -2px hsl(var(--shadow-color)/var(--shadow-strength-4)),0 7px 14px -5px hsl(var(--shadow-color)/var(--shadow-strength-6));
  --shadow-1: 0 1px 2px -1px hsl(var(--shadow-color)/var(--shadow-strength-10));
  --ease-3: cubic-bezier(.25,0,.3,1);
  --ease-4: cubic-bezier(.25,0,.2,1);
}

/*
 * Contao Theme Framework – Haupteinstiegspunkt.
 * Reihenfolge folgt ITCSS (generisch -> Basis -> komponentenspezifisch),
 * damit die Cascade genutzt werden kann statt Spezifität hochzuschrauben.
 */

/* abstracts: Design-Tokens & Farbschema (Light/Dark), zuerst importiert,
   damit alle folgenden Dateien die Tokens (--ctf-, --clr-, --grid-) nutzen
   können */

/*
 * Framework-Tokens & Farbschema.
 * Ergänzt die Design-Tokens von Open Props um Werte, die dort fehlen:
 * eine fluide Schriftgrößen-Skala nach der Utopia-Methode (utopia.fyi),
 * ein eigenes, Light/Dark-fähiges Farbschema und ein paar layoutbezogene
 * Basiswerte. Abstände, Radien usw. kommen weiterhin direkt aus Open Props
 * (var(--size-4), var(--radius-2) ...) statt hier dupliziert zu werden.
 *
 * Anders als in einer früheren Version wird diese Datei jetzt ganz normal
 * per @import eingebunden (siehe styles.css) statt per postcss-jit-props
 * injiziert: Für ein kleines, von Hand gepflegtes Token-Set ist eine
 * build-tool-spezifische Just-in-Time-Injektion unnötige Komplexität –
 * vor allem, weil Light/Dark-Werte ohnehin einen echten, verschachtelten
 * @media-Block brauchen, den jit-props nicht abbilden kann (es kennt nur
 * eine flache Property-zu-Wert-Zuordnung, keine Selektor-/Media-Struktur).
 * Für die große Open-Props-Rohfarbpalette (open-props.min.css) bleibt
 * jit-props weiterhin sinnvoll (siehe postcss.config.js) – nur dort lohnt
 * sich Tree-Shaking wirklich.
 */
:root {
  /* Fluide Typografie: Viewport 320px–1240px, Basisschrift 18px–20px,
     Skalenverhältnis 1.2 (klein) bis 1.25 (groß) */
  --ctf-step--2: clamp(0.7813rem, 0.7747rem + 0.0326vw, 0.8rem);
  --ctf-step--1: clamp(0.9375rem, 0.9158rem + 0.1087vw, 1rem);
  --ctf-step-0: clamp(1.125rem, 1.0815rem + 0.2174vw, 1.25rem);
  --ctf-step-1: clamp(1.35rem, 1.2761rem + 0.3696vw, 1.5625rem);
  --ctf-step-2: clamp(1.62rem, 1.5041rem + 0.5793vw, 1.9531rem);
  --ctf-step-3: clamp(1.944rem, 1.771rem + 0.8651vw, 2.4414rem);
  --ctf-step-4: clamp(2.3328rem, 2.0827rem + 1.2504vw, 3.0518rem);
  --ctf-step-5: clamp(2.7994rem, 2.4462rem + 1.7658vw, 3.8147rem);
  --ctf-step-6: clamp(3.3592rem, 2.8691rem + 2.4507vw, 4.7684rem);

  /* Schrift-Aliase auf die Open-Props-Stacks (modernfontstacks.com).
     Themes können hier umschalten, ohne Selektoren im Framework anzufassen */
  --ctf-font-body: var(--font-system-ui);
  --ctf-font-heading: var(--font-system-ui);

  /*
   * Farbschema (Light, Standardwert). Komponenten referenzieren nur noch
   * --clr-*, nie direkt Open-Props-Rohfarben wie --red-6 – ein Theme kann so
   * sein eigenes Farbschema definieren, ohne Selektoren in contao/*.css oder
   * generic/normalize.css anzufassen. Die numerischen Stufen (-1..-4 bzw.
   * -2) entsprechen der Open-Props-eigenen Konvention (text-1/-2,
   * surface-1..4), die generic/normalize.css als Vorbild übernimmt.
   *
   * Alle Farben sind HSL-Farben: Basiswerte kommen aus den --<farbe>-<n>-hsl-
   * Tripeln von Open Props ("228 81% 59%"), abgeleitete Werte per CSS
   * Relative Colors – hsl(from <farbe> h s l), siehe
   * developer.mozilla.org/en-US/docs/Web/CSS/Guides/Colors/Using_relative_colors.
   * Ein Theme muss dadurch nur die Basisfarben tauschen (--clr-link,
   * --clr-surface-1, die Statusfarben), der Rest zieht nach.
   */
  --clr-link: hsl(var(--indigo-7-hsl));
  /* Besuchter Link: gleiche Helligkeit/Sättigung wie der Link, Farbton um
     60° Richtung Violett gedreht (indigo 228° -> purple 288°) */
  --clr-link-visited: hsl(from var(--clr-link) calc(h + 60) s l);
  --clr-text-1: hsl(var(--gray-12-hsl));
  --clr-text-2: hsl(var(--gray-7-hsl));
  --clr-surface-1: hsl(var(--gray-0-hsl));
  /* Flächen 2-4: Stufen vom Seitenhintergrund aus, hier jeweils dunkler.
     Im Dark Mode zeigt die Richtung nach oben (heller), siehe unten */
  --clr-surface-2: hsl(from var(--clr-surface-1) h s calc(l - 5));
  --clr-surface-3: hsl(from var(--clr-surface-1) h s calc(l - 9));
  --clr-surface-4: hsl(from var(--clr-surface-1) h s calc(l - 15));
  --clr-scrollthumb: hsl(var(--gray-7-hsl));

  /*
   * Status-Farben, je drei Stufen:
   *   <status>             Akzentfarbe (z. B. Text/Icon auf neutraler Fläche)
   *   <status>-surface       Hintergrund einer gefüllten Box (z. B. .message)
   *   <status>-surface-text  Textfarbe auf dieser Box
   * Nur die Akzentfarbe wird festgelegt, Fläche und Text daraus abgeleitet
   * (gleicher Farbton, Fläche mit 60 % der Sättigung, Helligkeit fest: hell 92 %/
   * Text 22 %, im Dark Mode umgekehrt). So reichen vier Zeilen für ein
   * neues Statusschema.
   * error/success werden von echten Contao-Klassen genutzt
   * (.message.error/.message.confirm, siehe contao/modules.css für den
   * tl_error-Alias – tl_confirm bewusst nicht gespiegelt, siehe dort).
   * info/warning sind (noch) keine von Contao selbst gesetzten Klassen,
   * aber als Helper-Klassen nutzbar (.message.info/.message.warning),
   * falls ein Projekt sie manuell braucht.
   */
  --clr-error: hsl(var(--red-6-hsl));
  --clr-success: hsl(var(--green-6-hsl));
  --clr-info: hsl(var(--blue-6-hsl));
  --clr-warning: hsl(var(--yellow-9-hsl));

  --clr-error-surface: hsl(from var(--clr-error) h calc(s * 0.6) 92%);
  --clr-error-surface-text: hsl(from var(--clr-error) h s 22%);
  --clr-success-surface: hsl(from var(--clr-success) h calc(s * 0.6) 92%);
  --clr-success-surface-text: hsl(from var(--clr-success) h s 22%);
  --clr-info-surface: hsl(from var(--clr-info) h calc(s * 0.6) 92%);
  --clr-info-surface-text: hsl(from var(--clr-info) h s 22%);
  --clr-warning-surface: hsl(from var(--clr-warning) h calc(s * 0.6) 92%);
  --clr-warning-surface-text: hsl(from var(--clr-warning) h s 22%);

  /* Breitenbegrenzung für header/main/footer > .inside (base/skeleton.css) */
  --ctf-content-width: 75rem;

  /* Lesemaß (typografische Zeilenlänge): generic/normalize.css (:where(p))
     und contao/elements.css (.content-text) referenzieren beide dieses eine
     Token, damit eine andere Zeilenlänge nur an dieser Stelle geändert
     werden muss, statt an mehreren Dateien synchron */
  --ctf-measure: var(--size-content-3);

  /* Vertikaler Rhythmus (base/typography.css): Abstand zwischen Artikeln,
     größer als der zwischen Inhaltselementen (--size-fluid-3) */
  --ctf-article-space: var(--size-fluid-4);

  /* Gridsystem (base/grid.css): Spaltenzahl und Rinnenbreite waren dort
     bisher referenziert, aber nirgends definiert – ohne diese beiden
     Werte griff var(--grid-columns)/var(--grid-gutter) ins Leere */
  --grid-columns: 12;
  --grid-gutter: var(--size-fluid-3);

  /* .row hat per gap: var(--grid-gutter) standardmäßig denselben Abstand in
     beide Richtungen. --grid-gutter-y ist der Override-Punkt für .row--gap-y,
     wenn ein Theme einen abweichenden vertikalen Abstand braucht; per Default
     identisch zu --grid-gutter, also ohne eigene Anpassung ein No-op */
  --grid-gutter-y: var(--grid-gutter);
}

/*
 * Farbschema (Dark). Echter, verschachtelter @media-Block statt einer
 * build-tool-spezifischen Konvention – funktioniert unabhängig vom
 * verwendeten PostCSS-Setup und ist für jeden CSS-Entwickler auf Anhieb
 * lesbar. Nur die Farb-Tokens werden hier überschrieben, alles andere
 * (Typografie, Grid, Abstände) bleibt schemaunabhängig.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --clr-link: hsl(var(--indigo-3-hsl));
    --clr-text-1: hsl(var(--gray-1-hsl));
    --clr-text-2: hsl(var(--gray-4-hsl));
    --clr-surface-1: hsl(var(--gray-9-hsl));
    /* Flächen 2-4 werden im Dark Mode heller statt dunkler; die Schritte
       (+8/+16/+41) entsprechen den Open-Props-Graustufen 8/7/6 */
    --clr-surface-2: hsl(from var(--clr-surface-1) h s calc(l + 8));
    --clr-surface-3: hsl(from var(--clr-surface-1) h s calc(l + 16));
    --clr-surface-4: hsl(from var(--clr-surface-1) h s calc(l + 41));
    --clr-scrollthumb: hsl(var(--gray-6-hsl));

    --clr-error: hsl(var(--red-4-hsl));
    --clr-success: hsl(var(--green-4-hsl));
    --clr-info: hsl(var(--blue-4-hsl));
    --clr-warning: hsl(var(--yellow-4-hsl));

    --clr-error-surface: hsl(from var(--clr-error) h calc(s * 0.6) 20%);
    --clr-error-surface-text: hsl(from var(--clr-error) h s 92%);
    --clr-success-surface: hsl(from var(--clr-success) h calc(s * 0.6) 20%);
    --clr-success-surface-text: hsl(from var(--clr-success) h s 92%);
    --clr-info-surface: hsl(from var(--clr-info) h calc(s * 0.6) 20%);
    --clr-info-surface-text: hsl(from var(--clr-info) h s 92%);
    --clr-warning-surface: hsl(from var(--clr-warning) h calc(s * 0.6) 20%);
    --clr-warning-surface-text: hsl(from var(--clr-warning) h s 92%);
  }
}
/* generic: Reset & Basiswerte, an die normalize.css von Open Props angelehnt */
/*
 * Reset & sinnvolle Basiswerte, nach dem Vorbild der normalize.css von Open
 * Props (siehe node_modules/open-props/normalize.min.css) – möglichst
 * unverändert übernommen, wo es rein strukturelles Reset-Verhalten betrifft
 * (box-sizing, Ränder, Formular-/Tabellen-Grundstyling, Fokus-Stile usw.).
 *
 * Farben wurden bewusst ersetzt: statt der eingebauten --text-1/--surface-1/
 * --link-Tokens von Open Props referenziert dieses File unser eigenes
 * Farbschema (--clr-*, siehe abstracts/custom-properties.css) – so pflegen
 * wir Light/Dark-Werte an einer Stelle, statt zwei parallele Systeme
 * (Open-Props-Semantik und unser eigenes) im Framework zu haben.
 *
 * Ausgelassen: die button/.btn-bezogenen Custom-Property-Zuweisungen aus dem
 * Original (--_highlight, --_bg, --_ink-shadow usw.) – die greifen nur im
 * Zusammenspiel mit Open Props' eigenem Buttons-Modul, das wir nicht
 * einbinden, und wären hier totes Gewicht ohne Wirkung.
 */

:where(html) {
  -webkit-text-size-adjust: none;
  accent-color: var(--brand, var(--clr-link));
  background-color: var(--clr-surface-1);
  block-size: 100%;
  caret-color: var(--brand, var(--clr-link));
  color: var(--clr-text-1);
  --csstools-color-scheme--light: initial;
  color-scheme: light;
  font-family: var(--font-system-ui);
  line-height: var(--font-lineheight-3);
  scrollbar-color: var(--clr-scrollthumb) transparent;
}

@media (prefers-color-scheme: dark) {
  :where(html) {
    --csstools-color-scheme--light:  ;
    color-scheme: dark;
    --shadow-strength: 10%;
    --shadow-color: 220 40% 2%;
  }
}

:where(html) :where(dialog) {
  background-color: var(--clr-surface-1);
}

:where(html) :where(textarea, select, input:not([type="button"]):not([type="submit"]):not([type="reset"])) {
  background-color: var(--clr-surface-2);
}

:where(a[href]) {
  color: var(--brand, var(--clr-link));
}

:where(a[href]):where(:visited) {
  color: var(--clr-link-visited);
}

:focus-visible {
  outline-color: var(--brand, var(--clr-link));
}

*,
:after,
:before {
  box-sizing: border-box;
}

:where(:not(dialog)) {
  margin: 0;
}

:where(:not(fieldset):not(progress):not(meter)) {
  background-origin: border-box;
  background-repeat: no-repeat;
  border-style: solid;
  border-width: 0;
}

@media (prefers-reduced-motion: no-preference) {
  :where(html) {
    scroll-behavior: smooth;
  }

  :where(:focus-visible) {
    transition: outline-offset 145ms var(--ease-2);
  }

  :where(:not(:active):focus-visible) {
    transition-duration: 0.25s;
  }
}

:where(:not(:active):focus-visible) {
  outline-offset: 5px;
}

:where(body) {
  min-block-size: 100%;
}

:where(h1, h2, h3, h4, h5, h6) {
  text-wrap: balance;
  font-weight: var(--font-weight-9);
  line-height: var(--font-lineheight-1);
}

:where(h1) {
  font-size: var(--font-size-8);
  max-inline-size: var(--size-header-1);
}

:where(h2) {
  font-size: var(--font-size-6);
  max-inline-size: var(--size-header-2);
}

:where(h3) {
  font-size: var(--font-size-5);
}

:where(h4) {
  font-size: var(--font-size-4);
}

:where(h5) {
  font-size: var(--font-size-3);
}

:where(h3, h4, h5, h6, dt) {
  max-inline-size: var(--size-header-3);
}

:where(p, ul, ol, dl, h6) {
  font-size: var(--font-size-2);
}

:where(a, u, ins, abbr) {
  text-underline-offset: 1px;
}

@supports (-moz-appearance: none) {
  :where(a, u, ins, abbr) {
    text-underline-offset: 2px;
  }
}

:where(a[href], area, button, input:not([type="text"]):not([type="email"]):not([type="number"]):not([type="password"]):not([type=""]):not([type="tel"]):not([type="url"]), label[for], select, summary, [tabindex]:not([tabindex*="-"]):not(pre)) {
  cursor: pointer;
}

:where(a[href], area, button, input, label[for], select, summary, textarea, [tabindex]:not([tabindex*="-"])) {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

:where(a):where([href]) {
  text-decoration-color: hsl(from var(--clr-link) h s l / 40%);
}

:where(a):where([href]):where(:visited) {
  text-decoration-color: hsl(from var(--clr-link-visited) h s l / 40%);
}

:where(a):where(:not(:hover)) {
  text-decoration: inherit;
}

:where(img, svg, video, canvas, audio, iframe, embed, object) {
  display: block;
}

:where(img, svg, video) {
  block-size: auto;
  max-inline-size: 100%;
}

:where(input, button, textarea, select),
:where(input[type="file"])::-webkit-file-upload-button {
  color: inherit;
  font: inherit;
  font-size: inherit;
  letter-spacing: inherit;
}

::-moz-placeholder {
  color: var(--clr-text-2);
  opacity: 0.75;
}

::placeholder {
  color: var(--clr-text-2);
  opacity: 0.75;
}

:where(input:not([type="range"]), textarea) {
  padding-block: var(--size-1);
  padding-inline: var(--size-2);
}

:where(select) {
  field-sizing: content;
  padding-block: 0.75ch;
  padding-inline: var(--size-relative-4) 0;
}

:where(textarea, select, input:not([type="button"]):not([type="submit"]):not([type="reset"])) {
  background-color: var(--clr-surface-2);
  border-radius: var(--radius-2);
}

:where(textarea) {
  field-sizing: content;
  min-block-size: 2lh;
  min-inline-size: var(--size-content-1);
  resize: vertical;
}

:where(input[type="checkbox"], input[type="radio"]) {
  block-size: var(--size-3);
  inline-size: var(--size-3);
}

:where(svg:not([width])) {
  inline-size: var(--size-10);
}

:where(code, kbd, samp, pre) {
  font-family: var(--font-monospace-code), monospace;
}

:where(:not(pre) > code, kbd) {
  white-space: nowrap;
}

:where(pre) {
  direction: ltr;
  max-inline-size: -moz-max-content;
  max-inline-size: max-content;
  min-inline-size: 0;
  white-space: pre;
  writing-mode: lr;
}

:where(:not(pre) > code) {
  background: var(--clr-surface-2);
  border-radius: var(--radius-2);
  padding: var(--size-1) var(--size-2);
  writing-mode: lr;
}

:where(kbd, var) {
  border-color: var(--clr-surface-4);
  border-radius: var(--radius-2);
  border-width: var(--border-size-1);
  padding: var(--size-1) var(--size-2);
}

:where(mark) {
  border-radius: var(--radius-2);
  padding-inline: var(--size-1);
}

:where(ol, ul) {
  padding-inline-start: var(--size-8);
}

:where(li) {
  padding-inline-start: var(--size-2);
}

:where(li, dd, figcaption) {
  max-inline-size: var(--size-content-2);
}

:where(p) {
  text-wrap: pretty;
  max-inline-size: var(--ctf-measure);
}

:where(dt, summary) {
  font-weight: var(--font-weight-7);
}

:where(dt:not(:first-of-type)) {
  margin-block-start: var(--size-5);
}

:where(small) {
  font-size: max(0.5em, var(--font-size-0));
  max-inline-size: var(--size-content-1);
}

:where(hr) {
  background-color: var(--clr-surface-3);
  height: var(--border-size-2);
  margin-block: var(--size-fluid-5);
}

:where(figure) {
  display: grid;
  grid-gap: var(--size-2);
  gap: var(--size-2);
  align-items: center;
  justify-items: center;
  place-items: center;
}

:where(figure) > :where(figcaption) {
  text-wrap: balance;
  font-size: var(--font-size-1);
}

:where(blockquote, :not(blockquote) > cite) {
  border-inline-start-width: var(--border-size-3);
}

:where(blockquote) {
  display: grid;
  grid-gap: var(--size-3);
  gap: var(--size-3);
  max-inline-size: var(--size-content-2);
  padding-block: var(--size-3);
  padding-inline: var(--size-4);
}

:where(:not(blockquote) > cite) {
  padding-inline-start: var(--size-2);
}

:where(summary) {
  background: var(--clr-surface-3);
  border-radius: var(--radius-2);
  margin: calc(var(--size-2) * -1) calc(var(--size-3) * -1);
  padding: var(--size-2) var(--size-3);
}

:where(details) {
  background: var(--clr-surface-2);
  border-radius: var(--radius-2);
  padding-block: var(--size-2);
  padding-inline: var(--size-3);
}

:where(details[open] > summary) {
  border-end-end-radius: 0;
  border-end-start-radius: 0;
  margin-bottom: var(--size-2);
}

:where(fieldset) {
  border: var(--border-size-1) solid var(--clr-surface-4);
  border-radius: var(--radius-2);
}

:where(del) {
  background: var(--clr-error-surface);
  color: var(--clr-error-surface-text);
}

:where(ins) {
  background: var(--clr-success-surface);
  color: var(--clr-success-surface-text);
}

:where(abbr) {
  text-decoration-color: var(--clr-info);
}

:where(dialog) {
  background-color: var(--clr-surface-1);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-6);
  color: inherit;
}

:where(menu) {
  display: flex;
  gap: var(--size-3);
  padding-inline-start: 0;
}

:where(sup) {
  font-size: 0.5em;
}

:where(table) {
  --nice-inner-radius: calc(var(--radius-3) - 2px);
  background: var(--clr-surface-2);
  border: 1px solid var(--clr-surface-2);
  border-radius: var(--radius-3);
  width: -moz-fit-content;
  width: fit-content;
}

:where(table:not(:has(tfoot)) tr:last-child td:first-child) {
  border-end-start-radius: var(--nice-inner-radius);
}

:where(table:not(:has(tfoot)) tr:last-child td:last-child) {
  border-end-end-radius: var(--nice-inner-radius);
}

:where(table thead tr:first-child th:first-child) {
  border-start-start-radius: var(--nice-inner-radius);
}

:where(table thead tr:first-child th:last-child) {
  border-start-end-radius: var(--nice-inner-radius);
}

:where(tfoot tr:last-child th:first-of-type) {
  border-end-start-radius: var(--nice-inner-radius);
}

:where(tfoot tr:last-child td:first-of-type) {
  border-end-start-radius: var(--nice-inner-radius);
}

:where(tfoot tr:last-child th:last-of-type) {
  border-end-end-radius: var(--nice-inner-radius);
}

:where(tfoot tr:last-child td:last-of-type) {
  border-end-end-radius: var(--nice-inner-radius);
}

:where(th) {
  background-color: var(--clr-surface-2);
  color: var(--clr-text-1);
}

:where(table a:not(.does-not-exist):focus-visible),
:where(table button:not(.does-not-exist):focus-visible),
:where(table [contenteditable]:focus-visible) {
  outline-offset: -2px;
}

:where(td) {
  text-wrap: pretty;
  background: var(--clr-surface-1);
  max-inline-size: var(--size-content-2);
}

:where(td, th) {
  padding: var(--size-2);
  text-align: left;
}

:where(td:not([align])),
:where(th:not([align])) {
  text-align: center;
}

:where(thead) {
  border-collapse: collapse;
}

:where(table tr:hover td),
:where(tbody tr:nth-child(2n):hover td) {
  background-color: var(--clr-surface-3);
}

:where(table > caption) {
  margin: var(--size-3);
}

:where(tfoot button) {
  padding-block: var(--size-1);
  padding-inline: var(--size-3);
}

/* Im Original ein eigener Dark-Mode-Override (Dialog etwas heller als der
   normale Seitenhintergrund) – die übrigen Dark-Anpassungen des Originals
   (Eingabefelder, Placeholder) entfallen hier, da sie über --clr-surface-2/
   --clr-text-2 schon automatisch mit dem Farbschema mitschalten */
@media (prefers-color-scheme: dark) {
  :where(dialog) {
    background-color: var(--clr-surface-2);
  }
}
/* base: unstyled HTML-Elemente, Seitengerüst, Gridsystem */
/*
 * Seitengerüst nach page/layout.html.twig (siehe resources/layout.html.twig):
 * #wrapper enthält <header>, <main> und <footer>, jeweils mit einem
 * .inside-Div für die Breitenbegrenzung/Zentrierung. Kein #container,
 * kein #left/#right: Sidebars sind hier bewusst nicht vorgesehen, das
 * wäre Aufgabe des Projekt-Layouts, das diese Vorlage erweitert.
 */

body {
  font-family: var(--ctf-font-body);
}

/* Sticky Footer per Grid statt Flex: header/main/footer liegen ohnehin
   schon in dieser Reihenfolge im Markup, "auto 1fr auto" reicht als einzige
   Regel – main braucht keine zusätzliche flex:1-Angabe mehr.
   100dvh statt 100vh, damit mobile Adressleisten (ein-/ausblendend) nicht zu
   Sprüngen führen; 100vh bleibt als Fallback für ältere Browser stehen */
#wrapper {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-block-size: 100vh;
  min-block-size: 100dvh;
}

/* Breitenbegrenzung/Zentrierung für header/main/footer. padding-inline
   verhindert, dass der Inhalt auf schmalen Viewports am Rand klebt; nutzt
   denselben Wert wie der Grid-Gutter statt einen weiteren Token einzuführen */
:is(header, main, footer) > .inside {
  max-inline-size: var(--ctf-content-width);
  margin-inline: auto;
  padding-inline: var(--grid-gutter);
}

/* Visuell verborgen, aber für Screenreader vorhanden. Contao setzt die Klasse
   auf Skip-Links ("Navigation überspringen", <a class="invisible">), aber
   auch auf Texte, die nie fokussierbar sind (<span>, <label>, <legend>).
   :not(:focus-visible) heißt: Sobald ein Skip-Link per Tastatur (Tab) den
   Fokus bekommt, gilt das Verbergen nicht mehr, ohne dass man es einzeln
   zurücksetzen muss. Nicht fokussierbare Elemente haben nie :focus-visible
   und bleiben deshalb immer verborgen. (:focus-within wäre falsch: der Fokus
   liegt auf dem Link selbst, nicht auf einem Kind darin.) */
.invisible:not(:focus-visible) {
  position: absolute;
  overflow: hidden;
  inline-size: 1px;
  block-size: 1px;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Sichtbarer Skip-Link: oben links über der Seite. position: fixed, damit
   das Einblenden das Layout nicht verschiebt */
.invisible:focus-visible {
  position: fixed;
  inset-block-start: var(--size-2);
  inset-inline-start: var(--size-2);
  z-index: 100;
  padding: var(--size-2) var(--size-3);
  background: var(--clr-surface-1);
  border-radius: var(--radius-2);
  box-shadow: var(--shadow-3);
}
/*
 * Fluide Typografie. Überschreibt die statischen Schriftgrößen aus der
 * Open-Props-normalize.css mit der Utopia-Skala aus abstracts/custom-properties.css –
 * das ist die Cascade in Aktion, kein zusätzlicher Reset nötig.
 */

:is(h1, h2, h3, h4, h5, h6) {
  font-family: var(--ctf-font-heading);
}

h1 { font-size: var(--ctf-step-6); }
h2 { font-size: var(--ctf-step-5); }
h3 { font-size: var(--ctf-step-4); }
h4 { font-size: var(--ctf-step-3); }
h5 { font-size: var(--ctf-step-2); }
h6 { font-size: var(--ctf-step-1); }

:is(body, p, ul, ol, dl) {
  font-size: var(--ctf-step-0);
}

small {
  font-size: var(--ctf-step--2);
}

/*
 * Vertikaler Rhythmus per Owl-Selektor (* + *), statt jedem Inhaltselement
 * einzeln einen margin-block-end mitzugeben – ein zentraler Ort statt
 * verstreuter Regeln, und kein doppelter Abstand zwischen zwei Elementen.
 * Drei Stufen, von grob nach fein:
 *   1. Zwischen Artikeln (padding statt margin: die Artikel-Hintergrundfarbe
 *      reicht dadurch bis an die Kante, außerdem kein Margin-Collapsing
 *      zwischen den .mod_article-Geschwistern).
 *   2. Zwischen den Inhaltselementen eines Artikels (.mod_article > .inside
 *      wird per angepasstem Template um dieses .inside-Div ergänzt).
 *   3. Innerhalb eines einzelnen Inhaltselements bzw. Rich-Text-Blocks
 *      (.rte kommt aus component/_rich_text.html.twig), z. B. zwischen
 *      Absätzen eines Textelements.
 */
main .mod_article {
  padding-block: var(--ctf-article-space);
}

.mod_article > .inside > * + * {
  margin-block-start: var(--size-fluid-3);
}

:is([class*="content-"], .rte) > * + * {
  margin-block-start: var(--size-fluid-2);
}

/*
 * 12-Spalten-Gridsystem, abgeleitet vom Nutshell-Framework-Grid, aber
 * konsolidiert: keine SCSS-Loops mehr, sondern handgeschriebenes,
 * dedupliziertes CSS mit @custom-media fuer die Breakpoints.
 *
 * Aufbau: .row (Grid-Container) + Utility-Klassen fuer Spalten-/Zeilen-
 * Spannweite, -Start und Ausrichtung, jeweils optional mit Breakpoint-
 * Suffix (-sm-/-md-/-lg-/-xl-). Die "xs"-Variante (kleinster Breakpoint)
 * ist mit der unpraefigierten Basisklasse identisch (min-width: 0 gilt
 * immer) und wurde daher per :is() zusammengefuehrt statt dupliziert.
 */

/* Breakpoints einmal benennen statt die em-Werte mehrfach zu wiederholen */ /* ~550px */     /* ~768px */  /* ~940px */  /* ~1100px */

/* Grid-Container: Spaltenzahl und Rinnenbreite kommen aus Custom
   Properties, damit Themes sie ueberschreiben koennen. gap statt nur
   column-gap, da .row-Elemente in der Praxis meist mehrzeilig umbrechen
   (Galerien, Teaser-Listen) und dort auch ohne Opt-in ein Row-Gap wollen */
.row {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  grid-auto-columns: 1fr;
  grid-gap: var(--grid-gutter);
  gap: var(--grid-gutter);
}

/* Override fuer einen abweichenden vertikalen Abstand (z. B. mehr Weissraum
   zwischen Zeilen als zwischen Spalten) – ueber --grid-gutter-y steuerbar */
.row--gap-y {
  row-gap: var(--grid-gutter-y);
}

/* Kindelemente von Contao-Artikeln/-Galerien, die eine Spaltenbreite
   bekommen sollen, muessen selbst Grid-Items sein. [class*="…"] statt
   der bisherigen 1-durch-12-Aufzaehlung pro Breakpoint (120 Selektoren) */
[class*="article-xl-"] > .inside > *,
[class*="article-lg-"] > .inside > *,
[class*="article-md-"] > .inside > *,
[class*="article-sm-"] > .inside > *,
[class*="article-xs-"] > .inside > *,
.content-gallery > ul > li,
[class*="col-xl-"],
[class*="col-lg-"],
[class*="col-md-"],
[class*="col-sm-"],
[class*="col-xs-"] {
  display: grid;
  grid-column: 1 / -1;
  max-inline-size: 100%;
}

/* Basis-Tier: gilt auf jeder Breite. -xs-Pendants sind hier eingeschlossen */
.col {
  grid-column: 1 / -1;
}

:is(.col-1, .col-xs-1) {
  grid-column: span 1 / span 1;
}

:is(.col-2, .col-xs-2) {
  grid-column: span 2 / span 2;
}

:is(.col-3, .col-xs-3) {
  grid-column: span 3 / span 3;
}

:is(.col-4, .col-xs-4) {
  grid-column: span 4 / span 4;
}

:is(.col-5, .col-xs-5) {
  grid-column: span 5 / span 5;
}

:is(.col-6, .col-xs-6) {
  grid-column: span 6 / span 6;
}

:is(.col-7, .col-xs-7) {
  grid-column: span 7 / span 7;
}

:is(.col-8, .col-xs-8) {
  grid-column: span 8 / span 8;
}

:is(.col-9, .col-xs-9) {
  grid-column: span 9 / span 9;
}

:is(.col-10, .col-xs-10) {
  grid-column: span 10 / span 10;
}

:is(.col-11, .col-xs-11) {
  grid-column: span 11 / span 11;
}

:is(.col-12, .col-xs-12) {
  grid-column: span 12 / span 12;
}

:is(.row-start-1, .row-start-xs-1) {
  grid-row-start: 1;
}

:is(.row-start-2, .row-start-xs-2) {
  grid-row-start: 2;
}

:is(.row-start-3, .row-start-xs-3) {
  grid-row-start: 3;
}

:is(.row-start-4, .row-start-xs-4) {
  grid-row-start: 4;
}

:is(.row-start-5, .row-start-xs-5) {
  grid-row-start: 5;
}

:is(.row-start-6, .row-start-xs-6) {
  grid-row-start: 6;
}

:is(.row-start-7, .row-start-xs-7) {
  grid-row-start: 7;
}

:is(.row-start-8, .row-start-xs-8) {
  grid-row-start: 8;
}

:is(.row-start-9, .row-start-xs-9) {
  grid-row-start: 9;
}

:is(.row-start-10, .row-start-xs-10) {
  grid-row-start: 10;
}

:is(.row-start-11, .row-start-xs-11) {
  grid-row-start: 11;
}

:is(.row-start-12, .row-start-xs-12) {
  grid-row-start: 12;
}

:is(.row-span-1, .row-span-xs-1) {
  grid-row: span 1 / span 1;
}

:is(.row-span-2, .row-span-xs-2) {
  grid-row: span 2 / span 2;
}

:is(.row-span-3, .row-span-xs-3) {
  grid-row: span 3 / span 3;
}

:is(.row-span-4, .row-span-xs-4) {
  grid-row: span 4 / span 4;
}

:is(.row-span-5, .row-span-xs-5) {
  grid-row: span 5 / span 5;
}

:is(.row-span-6, .row-span-xs-6) {
  grid-row: span 6 / span 6;
}

:is(.row-span-7, .row-span-xs-7) {
  grid-row: span 7 / span 7;
}

:is(.row-span-8, .row-span-xs-8) {
  grid-row: span 8 / span 8;
}

:is(.row-span-9, .row-span-xs-9) {
  grid-row: span 9 / span 9;
}

:is(.row-span-10, .row-span-xs-10) {
  grid-row: span 10 / span 10;
}

:is(.row-span-11, .row-span-xs-11) {
  grid-row: span 11 / span 11;
}

:is(.row-span-12, .row-span-xs-12) {
  grid-row: span 12 / span 12;
}

/* Nur als -xs-Variante vorhanden (kein unpraefigiertes Pendant im
   Original) – bewusst ohne @media (min-width: 0), da das ohnehin immer
   zutrifft */
.col-start-xs-1 { grid-column-start: 1; }
.col-start-xs-2 { grid-column-start: 2; }
.col-start-xs-3 { grid-column-start: 3; }
.col-start-xs-4 { grid-column-start: 4; }
.col-start-xs-5 { grid-column-start: 5; }
.col-start-xs-6 { grid-column-start: 6; }
.col-start-xs-7 { grid-column-start: 7; }
.col-start-xs-8 { grid-column-start: 8; }
.col-start-xs-9 { grid-column-start: 9; }
.col-start-xs-10 { grid-column-start: 10; }
.col-start-xs-11 { grid-column-start: 11; }
.col-start-xs-12 { grid-column-start: 12; }

.pull-right-xs { grid-column-end: -1; }
.pull-left-xs {
  grid-row-start: 1;
  grid-column-end: inherit;
}

/* -- Breakpoint sm (--bp-sm) -- */
@media screen and (min-width: 34.375em) {
  .col-sm-1 { grid-column: span 1 / span 1; }
  .col-sm-2 { grid-column: span 2 / span 2; }
  .col-sm-3 { grid-column: span 3 / span 3; }
  .col-sm-4 { grid-column: span 4 / span 4; }
  .col-sm-5 { grid-column: span 5 / span 5; }
  .col-sm-6 { grid-column: span 6 / span 6; }
  .col-sm-7 { grid-column: span 7 / span 7; }
  .col-sm-8 { grid-column: span 8 / span 8; }
  .col-sm-9 { grid-column: span 9 / span 9; }
  .col-sm-10 { grid-column: span 10 / span 10; }
  .col-sm-11 { grid-column: span 11 / span 11; }
  .col-sm-12 { grid-column: span 12 / span 12; }

  .row-span-sm-1 { grid-row: span 1 / span 1; }
  .row-span-sm-2 { grid-row: span 2 / span 2; }
  .row-span-sm-3 { grid-row: span 3 / span 3; }
  .row-span-sm-4 { grid-row: span 4 / span 4; }
  .row-span-sm-5 { grid-row: span 5 / span 5; }
  .row-span-sm-6 { grid-row: span 6 / span 6; }
  .row-span-sm-7 { grid-row: span 7 / span 7; }
  .row-span-sm-8 { grid-row: span 8 / span 8; }
  .row-span-sm-9 { grid-row: span 9 / span 9; }
  .row-span-sm-10 { grid-row: span 10 / span 10; }
  .row-span-sm-11 { grid-row: span 11 / span 11; }
  .row-span-sm-12 { grid-row: span 12 / span 12; }

  .col-start-sm-1 { grid-column-start: 1; }
  .row-start-sm-1 { grid-row-start: 1; }
  .col-start-sm-2 { grid-column-start: 2; }
  .row-start-sm-2 { grid-row-start: 2; }
  .col-start-sm-3 { grid-column-start: 3; }
  .row-start-sm-3 { grid-row-start: 3; }
  .col-start-sm-4 { grid-column-start: 4; }
  .row-start-sm-4 { grid-row-start: 4; }
  .col-start-sm-5 { grid-column-start: 5; }
  .row-start-sm-5 { grid-row-start: 5; }
  .col-start-sm-6 { grid-column-start: 6; }
  .row-start-sm-6 { grid-row-start: 6; }
  .col-start-sm-7 { grid-column-start: 7; }
  .row-start-sm-7 { grid-row-start: 7; }
  .col-start-sm-8 { grid-column-start: 8; }
  .row-start-sm-8 { grid-row-start: 8; }
  .col-start-sm-9 { grid-column-start: 9; }
  .row-start-sm-9 { grid-row-start: 9; }
  .col-start-sm-10 { grid-column-start: 10; }
  .row-start-sm-10 { grid-row-start: 10; }
  .col-start-sm-11 { grid-column-start: 11; }
  .row-start-sm-11 { grid-row-start: 11; }
  .col-start-sm-12 { grid-column-start: 12; }
  .row-start-sm-12 { grid-row-start: 12; }

  .pull-right-sm { grid-column-end: -1; }
  .pull-left-sm {
    grid-row-start: 1;
    grid-column-end: inherit;
  }
}

/* -- Breakpoint md (--bp-md) -- */
@media screen and (min-width: 48em) {
  .col-md-1 { grid-column: span 1 / span 1; }
  .col-md-2 { grid-column: span 2 / span 2; }
  .col-md-3 { grid-column: span 3 / span 3; }
  .col-md-4 { grid-column: span 4 / span 4; }
  .col-md-5 { grid-column: span 5 / span 5; }
  .col-md-6 { grid-column: span 6 / span 6; }
  .col-md-7 { grid-column: span 7 / span 7; }
  .col-md-8 { grid-column: span 8 / span 8; }
  .col-md-9 { grid-column: span 9 / span 9; }
  .col-md-10 { grid-column: span 10 / span 10; }
  .col-md-11 { grid-column: span 11 / span 11; }
  .col-md-12 { grid-column: span 12 / span 12; }

  .row-span-md-1 { grid-row: span 1 / span 1; }
  .row-span-md-2 { grid-row: span 2 / span 2; }
  .row-span-md-3 { grid-row: span 3 / span 3; }
  .row-span-md-4 { grid-row: span 4 / span 4; }
  .row-span-md-5 { grid-row: span 5 / span 5; }
  .row-span-md-6 { grid-row: span 6 / span 6; }
  .row-span-md-7 { grid-row: span 7 / span 7; }
  .row-span-md-8 { grid-row: span 8 / span 8; }
  .row-span-md-9 { grid-row: span 9 / span 9; }
  .row-span-md-10 { grid-row: span 10 / span 10; }
  .row-span-md-11 { grid-row: span 11 / span 11; }
  .row-span-md-12 { grid-row: span 12 / span 12; }

  .col-start-md-1 { grid-column-start: 1; }
  .row-start-md-1 { grid-row-start: 1; }
  .col-start-md-2 { grid-column-start: 2; }
  .row-start-md-2 { grid-row-start: 2; }
  .col-start-md-3 { grid-column-start: 3; }
  .row-start-md-3 { grid-row-start: 3; }
  .col-start-md-4 { grid-column-start: 4; }
  .row-start-md-4 { grid-row-start: 4; }
  .col-start-md-5 { grid-column-start: 5; }
  .row-start-md-5 { grid-row-start: 5; }
  .col-start-md-6 { grid-column-start: 6; }
  .row-start-md-6 { grid-row-start: 6; }
  .col-start-md-7 { grid-column-start: 7; }
  .row-start-md-7 { grid-row-start: 7; }
  .col-start-md-8 { grid-column-start: 8; }
  .row-start-md-8 { grid-row-start: 8; }
  .col-start-md-9 { grid-column-start: 9; }
  .row-start-md-9 { grid-row-start: 9; }
  .col-start-md-10 { grid-column-start: 10; }
  .row-start-md-10 { grid-row-start: 10; }
  .col-start-md-11 { grid-column-start: 11; }
  .row-start-md-11 { grid-row-start: 11; }
  .col-start-md-12 { grid-column-start: 12; }
  .row-start-md-12 { grid-row-start: 12; }

  .pull-right-md { grid-column-end: -1; }
  .pull-left-md {
    grid-row-start: 1;
    grid-column-end: inherit;
  }
}

/* -- Breakpoint lg (--bp-lg) -- */
@media screen and (min-width: 58.75em) {
  .col-lg-1 { grid-column: span 1 / span 1; }
  .col-lg-2 { grid-column: span 2 / span 2; }
  .col-lg-3 { grid-column: span 3 / span 3; }
  .col-lg-4 { grid-column: span 4 / span 4; }
  .col-lg-5 { grid-column: span 5 / span 5; }
  .col-lg-6 { grid-column: span 6 / span 6; }
  .col-lg-7 { grid-column: span 7 / span 7; }
  .col-lg-8 { grid-column: span 8 / span 8; }
  .col-lg-9 { grid-column: span 9 / span 9; }
  .col-lg-10 { grid-column: span 10 / span 10; }
  .col-lg-11 { grid-column: span 11 / span 11; }
  .col-lg-12 { grid-column: span 12 / span 12; }

  .row-span-lg-1 { grid-row: span 1 / span 1; }
  .row-span-lg-2 { grid-row: span 2 / span 2; }
  .row-span-lg-3 { grid-row: span 3 / span 3; }
  .row-span-lg-4 { grid-row: span 4 / span 4; }
  .row-span-lg-5 { grid-row: span 5 / span 5; }
  .row-span-lg-6 { grid-row: span 6 / span 6; }
  .row-span-lg-7 { grid-row: span 7 / span 7; }
  .row-span-lg-8 { grid-row: span 8 / span 8; }
  .row-span-lg-9 { grid-row: span 9 / span 9; }
  .row-span-lg-10 { grid-row: span 10 / span 10; }
  .row-span-lg-11 { grid-row: span 11 / span 11; }
  .row-span-lg-12 { grid-row: span 12 / span 12; }

  .col-start-lg-1 { grid-column-start: 1; }
  .row-start-lg-1 { grid-row-start: 1; }
  .col-start-lg-2 { grid-column-start: 2; }
  .row-start-lg-2 { grid-row-start: 2; }
  .col-start-lg-3 { grid-column-start: 3; }
  .row-start-lg-3 { grid-row-start: 3; }
  .col-start-lg-4 { grid-column-start: 4; }
  .row-start-lg-4 { grid-row-start: 4; }
  .col-start-lg-5 { grid-column-start: 5; }
  .row-start-lg-5 { grid-row-start: 5; }
  .col-start-lg-6 { grid-column-start: 6; }
  .row-start-lg-6 { grid-row-start: 6; }
  .col-start-lg-7 { grid-column-start: 7; }
  .row-start-lg-7 { grid-row-start: 7; }
  .col-start-lg-8 { grid-column-start: 8; }
  .row-start-lg-8 { grid-row-start: 8; }
  .col-start-lg-9 { grid-column-start: 9; }
  .row-start-lg-9 { grid-row-start: 9; }
  .col-start-lg-10 { grid-column-start: 10; }
  .row-start-lg-10 { grid-row-start: 10; }
  .col-start-lg-11 { grid-column-start: 11; }
  .row-start-lg-11 { grid-row-start: 11; }
  .col-start-lg-12 { grid-column-start: 12; }
  .row-start-lg-12 { grid-row-start: 12; }

  .pull-right-lg { grid-column-end: -1; }
  .pull-left-lg {
    grid-row-start: 1;
    grid-column-end: inherit;
  }
}

/* -- Breakpoint xl (--bp-xl) -- */
@media screen and (min-width: 68.75em) {
  .col-xl-1 { grid-column: span 1 / span 1; }
  .col-xl-2 { grid-column: span 2 / span 2; }
  .col-xl-3 { grid-column: span 3 / span 3; }
  .col-xl-4 { grid-column: span 4 / span 4; }
  .col-xl-5 { grid-column: span 5 / span 5; }
  .col-xl-6 { grid-column: span 6 / span 6; }
  .col-xl-7 { grid-column: span 7 / span 7; }
  .col-xl-8 { grid-column: span 8 / span 8; }
  .col-xl-9 { grid-column: span 9 / span 9; }
  .col-xl-10 { grid-column: span 10 / span 10; }
  .col-xl-11 { grid-column: span 11 / span 11; }
  .col-xl-12 { grid-column: span 12 / span 12; }

  .row-span-xl-1 { grid-row: span 1 / span 1; }
  .row-span-xl-2 { grid-row: span 2 / span 2; }
  .row-span-xl-3 { grid-row: span 3 / span 3; }
  .row-span-xl-4 { grid-row: span 4 / span 4; }
  .row-span-xl-5 { grid-row: span 5 / span 5; }
  .row-span-xl-6 { grid-row: span 6 / span 6; }
  .row-span-xl-7 { grid-row: span 7 / span 7; }
  .row-span-xl-8 { grid-row: span 8 / span 8; }
  .row-span-xl-9 { grid-row: span 9 / span 9; }
  .row-span-xl-10 { grid-row: span 10 / span 10; }
  .row-span-xl-11 { grid-row: span 11 / span 11; }
  .row-span-xl-12 { grid-row: span 12 / span 12; }

  .col-start-xl-1 { grid-column-start: 1; }
  .row-start-xl-1 { grid-row-start: 1; }
  .col-start-xl-2 { grid-column-start: 2; }
  .row-start-xl-2 { grid-row-start: 2; }
  .col-start-xl-3 { grid-column-start: 3; }
  .row-start-xl-3 { grid-row-start: 3; }
  .col-start-xl-4 { grid-column-start: 4; }
  .row-start-xl-4 { grid-row-start: 4; }
  .col-start-xl-5 { grid-column-start: 5; }
  .row-start-xl-5 { grid-row-start: 5; }
  .col-start-xl-6 { grid-column-start: 6; }
  .row-start-xl-6 { grid-row-start: 6; }
  .col-start-xl-7 { grid-column-start: 7; }
  .row-start-xl-7 { grid-row-start: 7; }
  .col-start-xl-8 { grid-column-start: 8; }
  .row-start-xl-8 { grid-row-start: 8; }
  .col-start-xl-9 { grid-column-start: 9; }
  .row-start-xl-9 { grid-row-start: 9; }
  .col-start-xl-10 { grid-column-start: 10; }
  .row-start-xl-10 { grid-row-start: 10; }
  .col-start-xl-11 { grid-column-start: 11; }
  .row-start-xl-11 { grid-row-start: 11; }
  .col-start-xl-12 { grid-column-start: 12; }
  .row-start-xl-12 { grid-row-start: 12; }

  .pull-right-xl { grid-column-end: -1; }
  .pull-left-xl {
    grid-row-start: 1;
    grid-column-end: inherit;
  }
}

/* Ausrichtung innerhalb der Grid-Zelle, Basis-Tier inkl. -xs-Pendants */
:is(.justify-start, .justify-xs-start) {
  justify-self: start;
  text-align: left;
}

:is(.justify-center, .justify-xs-center) {
  justify-self: center;
  text-align: center;
}

:is(.justify-end, .justify-xs-end) {
  justify-self: end;
  text-align: right;
}

:is(.align-start, .align-xs-start) {
  align-self: start;
}

:is(.align-center, .align-xs-center) {
  align-self: center;
}

:is(.align-end, .align-xs-end) {
  align-self: end;
}

@media screen and (min-width: 34.375em) {
  .justify-sm-start {
    justify-self: start;
    text-align: left;
  }
  .justify-sm-center {
    justify-self: center;
    text-align: center;
  }
  .justify-sm-end {
    justify-self: end;
    text-align: right;
  }

  .align-sm-start { align-self: start; }
  .align-sm-center { align-self: center; }
  .align-sm-end { align-self: end; }
}

@media screen and (min-width: 48em) {
  .justify-md-start {
    justify-self: start;
    text-align: left;
  }
  .justify-md-center {
    justify-self: center;
    text-align: center;
  }
  .justify-md-end {
    justify-self: end;
    text-align: right;
  }

  .align-md-start { align-self: start; }
  .align-md-center { align-self: center; }
  .align-md-end { align-self: end; }
}

@media screen and (min-width: 58.75em) {
  .justify-lg-start {
    justify-self: start;
    text-align: left;
  }
  .justify-lg-center {
    justify-self: center;
    text-align: center;
  }
  .justify-lg-end {
    justify-self: end;
    text-align: right;
  }

  .align-lg-start { align-self: start; }
  .align-lg-center { align-self: center; }
  .align-lg-end { align-self: end; }
}

@media screen and (min-width: 68.75em) {
  .justify-xl-start {
    justify-self: start;
    text-align: left;
  }
  .justify-xl-center {
    justify-self: center;
    text-align: center;
  }
  .justify-xl-end {
    justify-self: end;
    text-align: right;
  }

  .align-xl-start { align-self: start; }
  .align-xl-center { align-self: center; }
  .align-xl-end { align-self: end; }
}

/* Vertikale Ausrichtung von Grid-Items innerhalb einer .row (nicht zu
   verwechseln mit .row-start-N, das die Startzeile eines Items setzt!) */
.row-align-start {
  align-self: start;
}

.row-align-center {
  align-content: center;
}

/*
 * Buttons – übernommen aus Open Props (src/extra/buttons.css), mit CSS-Nesting
 * wie in der Quelle. Light/Dark über prefers-color-scheme. Gestylt werden alle
 * nativen Buttons (button, input[type=button|submit|reset], input[type=file])
 * sowie die Klasse .btn, die bei Bedarf manuell vergeben werden kann (z. B. als
 * CSS-Klasse eines Hyperlink-Elements im Contao-Backend). Alles steht in
 * :where() und hat damit Spezifität 0 – Vendor-CSS (z. B. handorgel) und
 * Themes überschreiben es ohne Spezifitäts-Rennen.
 *
 * Abweichungen vom Original:
 *  - Farb-Tokens zeigen auf unser Schema (--clr-surface-1 bis -3, --clr-link,
 *    --clr-text-2) statt auf --surface-N, --link und --text-2 aus der
 *    Open-Props-normalize.css, die es bei uns nicht mehr gibt. Reset-Button:
 *    rot über --clr-error (Rahmen per Relative Color halbtransparent), der
 *    eigene Dark-Override des Originals entfällt, --clr-error schaltet selbst.
 *    Alle Farben sind HSL (hsl(var(--gray-N-hsl)), siehe abstracts/).
 *  - Die Selektorliste steht einmal als @custom-selector (:--ctf-btn) statt
 *    in jeder Regel neu.
 *  - @media (--OSdark) heißt hier ausgeschrieben prefers-color-scheme: dark.
 *  - Das ::-webkit-file-upload-button-Präfix entfällt, alle aktuellen Browser
 *    kennen ::file-selector-button.
 *  - Sämtliche Transitions stehen gebündelt am Ende der Datei (siehe dort).
 */

/* Alles, was wie ein Button aussieht. Neben den nativen Buttons und .btn
   stehen hier die Contao-Elemente, die Contao selbst als Link ausgibt, aber
   als Button zeigen soll – hier ergänzen oder streichen, was dazu gehören
   soll.
   - .as-btn a: Opt-in für beliebige Elemente, die genau einen Link enthalten.
     Im Backend als "CSS-Klasse" des Elements eintragen (landet am Wrapper,
     nicht am <a> – ein .btn am Wrapper würde dagegen den Wrapper selbst
     zum Button machen). Gedacht für Hyperlink-, Download- und Teaser-Elemente.
   - .content-toplink a: "Nach oben"-Link (content_element/toplink.html.twig)
   - .content-teaser > a: "Weiterlesen"-Link des Teaser-Elements
     (component/_read_more.html.twig). Nur direkte Kinder, damit Links im
     Teaser-Text Links bleiben.
   - .more a: "Weiterlesen" in News- und Terminlisten (<p class="more">)
   - .back a: "Zurück"-Link in News-/Termin-Leser und Artikel (<p class="back">)
   - a.submit: als Link ausgegebene Submit-Aktionen, z. B. "Abbrechen" und
     "Bearbeiten" in content_element/two_factor.html.twig */

/* Grundaussehen: Variablen mit Unterstrich (--_*) sind intern und lassen
   sich pro Button überschreiben (z. B. --_accent, --_size, --_bg).
   Der Datei-Upload-Button ist ein Pseudo-Element und kann nicht per & an die
   Liste hängen, steht deshalb mit im Selektor dieser einen Regel. */
:where(:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)),
:where(input[type="file"])::file-selector-button {
  --_accent: initial;
  --_text: initial;
  --_size: initial;
  --_bg-light: hsl(0, 0%, 100%);
  --_bg-dark: var(--clr-surface-3);
  --_bg: var(--_bg-light);
  --_border: var(--clr-surface-3);
  --_highlight-size: 0;
  --_highlight-light: hsl(var(--gray-5-hsl) / 25%);
  --_highlight-dark: hsl(var(--gray-12-hsl) / 25%);
  --_highlight: var(--_highlight-light);
  --_ink-shadow-light: 0 1px 0 var(--clr-surface-3);
  --_ink-shadow-dark: 0 1px 0 var(--clr-surface-1);
  --_ink-shadow: var(--_ink-shadow-light);
  --_icon-size: var(--size-relative-7);
  --_icon-color: var(--_accent, var(--clr-link));
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  align-items: center;
  background: var(--_bg);
  border: var(--border-size-2) solid var(--_border);
  border-radius: var(--radius-2);
  box-shadow: var(--shadow-2), 0 1px var(--clr-surface-3), 0 0 0 var(--_highlight-size) var(--_highlight);
  color: var(--_text);
  display: inline-flex;
  font-size: var(--_size);
  font-weight: var(--font-weight-7);
  gap: var(--size-2);
  justify-content: center;
  padding-block: 0.75ch;
  padding-inline: var(--size-relative-6);
  text-align: center;
  text-shadow: var(--_ink-shadow);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;

  @media (prefers-color-scheme: dark) {
    --_highlight: var(--_highlight-dark);
    --_bg: var(--_bg-dark);
    --_ink-shadow: var(--_ink-shadow-dark);
  }
}

:where(:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)) {
  /* Hover: der Highlight-Ring wächst von 0 auf --size-2 */
  &:where(:not(:active):hover) {
    --_highlight-size: var(--size-2);
  }

  /* Icons (inline-SVG) direkt im Button */
  & > :where(svg) {
    block-size: var(--_icon-size);
    filter: drop-shadow(var(--_ink-shadow));
    flex-shrink: 0;
    inline-size: var(--_icon-size);

    & > * {
      stroke: var(--_icon-color);
      stroke-width: var(--border-size-2);
    }
  }
}

/* Links im Button-Look nicht unterstreichen */
:where(a:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)) {
  -webkit-text-decoration: none;
  text-decoration: none;
}

/* Deaktiviert (nur echte Formular-Buttons, Links kennen kein [disabled]) */
[disabled]:where(:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)) {
  --_bg: none;
  --_text: hsl(var(--gray-6-hsl));
  box-shadow: var(--shadow-1);
  cursor: not-allowed;

  @media (prefers-color-scheme: dark) {
    --_text: hsl(var(--gray-5-hsl));
  }
}

/* Absenden-Buttons (auch als Link ausgegebene, a.submit) in Akzentfarbe */
:where([type="submit"], a.submit, form button:not([type]):not([disabled])) {
  --_text: var(--_accent, var(--clr-link));
}

/* Zurücksetzen-Buttons in Rot */
:where([type="reset"]) {
  --_text: var(--clr-error);
  --_border: hsl(from var(--clr-error) h s l / 50%);

  &:focus-visible {
    outline-color: var(--clr-error);
  }
}

/* Hover/Fokus: Rahmen nimmt die Textfarbe an */
:where(form button:not([type]), [type="submit"], a.submit, [type="reset"]) {
  &:is(:hover, :focus-visible):not([disabled]) {
    --_border: currentColor;
  }
}

/* Datei-Upload */
:where(input[type="file"]) {
  align-self: flex-start;
  border: var(--border-size-1) solid var(--clr-surface-2);
  border-radius: var(--radius-2);
  box-shadow: var(--inner-shadow-4);
  color: var(--clr-text-2);
  cursor: auto;
  cursor: initial;
  max-inline-size: 100%;
  padding: 0;

  &::file-selector-button {
    cursor: pointer;
    margin-inline-end: var(--size-relative-6);
  }
}

/* Dark: Hintergrund für deaktivierte, Reset-, Submit- und Formular-Buttons */
@media (prefers-color-scheme: dark) {
  :where([disabled], [type="reset"], [type="submit"], form button:not([type="button"])) {
    --_bg: var(--clr-surface-1);
  }
}

/*
 * Bewegung. Bewusste Ausnahme von der Regel "keine Easings/Animationen" aus
 * CLAUDE.md: Die Button-Transitions aus Open Props bleiben im Framework. Im
 * Original über die ganze Datei verteilt, hier gebündelt. Ein Theme, das sie
 * nicht will, löscht einfach diesen Abschnitt: die Buttons funktionieren
 * unverändert, Zustandswechsel (Hover, Fokus) passieren dann ohne Übergang.
 */
:where(:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)),
:where(input[type="file"])::file-selector-button {
  transition: border-color 0.5s var(--ease-3);

  @media (prefers-reduced-motion: no-preference) {
    transition:
      border-color 0.5s var(--ease-3),
      box-shadow 145ms var(--ease-4),
      outline-offset 145ms var(--ease-4);
  }
}

:where(:is(button, input[type="button"], input[type="submit"], input[type="reset"], .btn, .as-btn a, .content-toplink a, .content-teaser > a, .more a, .back a, a.submit)):where(:not(:active):hover) {
  transition-duration: 0.25s;
}

/* contao: Klassen aus den Contao-Core-Templates */

/*
 * Textbasierte Inhaltselemente: content-text, content-html, content-code,
 * content-hyperlink, content-list, content-table, content-teaser, content-toplink
 * (twig/content_element/text.html.twig, code.html.twig, list.html.twig, table.html.twig,
 * teaser.html.twig, toplink.html.twig, twig/component/_read_more.html.twig).
 *
 * Wichtig: Die Wrapper-Klasse jedes Inhaltselements wird von
 * content_element/_base.html.twig dynamisch aus dem Elementtyp gebaut:
 * "content-#{type}" (Unterstriche im Typ werden zu Bindestrichen), also z. B.
 * content-text, content-download, content-element-group. Keine ce_*-Klassen mehr!
 *
 * Der Abstand zwischen den Inhaltselementen kommt zentral aus dem
 * vertikalen Rhythmus in base/typography.css, nicht aus einzelnen
 * margin-block-end-Regeln hier.
 */

/* content-text: dieselbe Maßbegrenzung wie :where(p) in generic/normalize.css,
   aber auf dem Wrapper statt nur auf <p>. <p> und <figure> sind Geschwister
   im selben Wrapper (siehe unten) – ohne das hier läuft <p> auf seine eigene,
   schmalere max-inline-size, während ein gefloatetes <figure> sich am
   (breiteren) Containing Block des Wrappers ausrichtet. Zwei unabhängige
   Breiten, die besonders bei einspaltigem Layout auseinanderlaufen: das Bild
   "rutscht" zum entfernten Wrapper-Rand, der Text bleibt davon losgelöst
   schmal. Mit der Grenze auf dem Wrapper teilen sich Bild und Text denselben
   Containing Block – kein Sonderfall für "einspaltig" nötig. */
.content-text {
  max-inline-size: var(--ctf-measure);
}

/* Bild im Fließtext per Layout-Modifier "media media--{above|left|right|below}".
   Die Modifier-Klasse sitzt am content-text-Wrapper selbst (content_layout_attributes
   in text.html.twig), das Bild liegt als <figure> darin – daher float auf dem
   Nachfahren, nicht auf der Modifier-Klasse. flow-root auf dem Wrapper statt eines
   Clearfix-Hacks, damit das gefloatete Bild ihn nicht nach unten überragt.
   .media--above/.media--below brauchen keine eigene Regel mehr: die Reihenfolge von
   Bild und Text im Markup ändert sich zwar, der Abstand dazwischen kommt aber
   bereits aus dem vertikalen Rhythmus in base/typography.css.

   Dasselbe gilt für Bilder in News/Terminen (news_… und event_…-Templates): dort sitzt
   die Ausrichtung als float_left/float_right direkt am <figure>
   (Figure::floatClass), der Elternteil bekommt flow-root, sobald er so ein
   Bild direkt enthält. */
:is(.media--left, .media--right, :has(> figure:is(.float_left, .float_right))) {
  display: flow-root;
}

.media--left figure,
figure.float_left {
  float: left;
  margin-inline-end: var(--size-4);
}

.media--right figure,
figure.float_right {
  float: right;
  margin-inline-start: var(--size-4);
}

/* content-code: Syntax-Highlighting per highlight.js (Klasse .hljs kommt von dort) */
.content-code pre {
  padding: var(--size-3);
  background-color: var(--clr-surface-2);
  border-radius: var(--radius-2);
  overflow-x: auto;
}

/* content-list/-table: reine semantische Elemente, Grundstyling kommt bereits
   aus der Open-Props-normalize.css (ul/ol/table/th/td) */

/* content-teaser: der "Weiterlesen"-Link (component/_read_more.html.twig) ist
   ein Button, siehe :--ctf-btn in base/buttons.css */

/* content-toplink: "Nach oben"-Link, per [data-toplink] statt fester Klasse erkannt */
.content-toplink {
  text-align: end;
}
/*
 * Medien-Inhaltselemente: content-image, content-gallery, content-player,
 * content-youtube, content-vimeo (twig/content_element/image.html.twig,
 * gallery.html.twig, player.html.twig, _video.html.twig, twig/component/_figure.html.twig).
 *
 * figure/figcaption/img/picture bleiben bewusst ohne eigene Wrapper-Klassen
 * (component/_figure.html.twig gibt keine vor) – das Grundstyling kommt aus
 * der Open-Props-normalize.css. Der Abstand zwischen den Inhaltselementen
 * kommt zentral aus dem vertikalen Rhythmus in base/typography.css.
 */

/* content-gallery: Spaltenzahl kommt als BEM-Modifier auf dem Wrapper-Div an
   (content-gallery--cols-N, 1–12 laut tl_content.perRow), nicht mehr auf dem <ul> */
.content-gallery ul {
  display: grid;
  grid-template-columns: repeat(var(--ctf-cols, 4), 1fr);
  grid-gap: var(--size-4);
  gap: var(--size-4);
  padding-inline-start: 0;
  list-style: none;
}

.content-gallery[class~="content-gallery--cols-1"] ul { --ctf-cols: 1; }
.content-gallery[class~="content-gallery--cols-2"] ul { --ctf-cols: 2; }
.content-gallery[class~="content-gallery--cols-3"] ul { --ctf-cols: 3; }
.content-gallery[class~="content-gallery--cols-4"] ul { --ctf-cols: 4; }
.content-gallery[class~="content-gallery--cols-5"] ul { --ctf-cols: 5; }
.content-gallery[class~="content-gallery--cols-6"] ul { --ctf-cols: 6; }
.content-gallery[class~="content-gallery--cols-7"] ul { --ctf-cols: 7; }
.content-gallery[class~="content-gallery--cols-8"] ul { --ctf-cols: 8; }
.content-gallery[class~="content-gallery--cols-9"] ul { --ctf-cols: 9; }
.content-gallery[class~="content-gallery--cols-10"] ul { --ctf-cols: 10; }
.content-gallery[class~="content-gallery--cols-11"] ul { --ctf-cols: 11; }
.content-gallery[class~="content-gallery--cols-12"] ul { --ctf-cols: 12; }

/* Container Query: unabhängig von der konfigurierten Spaltenzahl nie enger
   als eine Mindestbreite pro Spalte werden lassen (z. B. schmale Sidebar) */
.content-gallery {
  container-type: inline-size;
}

@container (width < 30rem) {
  .content-gallery ul {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* content-youtube/content-vimeo: Seitenverhältnis über die aspect--"16:9"-Klasse.
   Der Doppelpunkt aus den Contao-Optionen (16:9, 4:3, 21:9 …) ist nur als
   Attribut-Selektor sicher zu matchen, nicht als CSS-Bezeichner */
.aspect {
  position: relative;
  aspect-ratio: var(--ctf-aspect-ratio, 16 / 9);
}

.aspect[class~="aspect--16:9"] { --ctf-aspect-ratio: 16 / 9; }
.aspect[class~="aspect--16:10"] { --ctf-aspect-ratio: 16 / 10; }
.aspect[class~="aspect--21:9"] { --ctf-aspect-ratio: 21 / 9; }
.aspect[class~="aspect--4:3"] { --ctf-aspect-ratio: 4 / 3; }
.aspect[class~="aspect--3:2"] { --ctf-aspect-ratio: 3 / 2; }
.aspect[class~="aspect--9:16"] { --ctf-aspect-ratio: 9 / 16; }
.aspect[class~="aspect--1:1"] { --ctf-aspect-ratio: 1 / 1; }

.aspect iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
}

/* content-player: lokale Video-/Audio-Dateien ohne aspect-ratio-Zwang */
.content-player :is(video, audio) {
  inline-size: 100%;
}
/*
 * content-download / content-downloads: einzelne bzw. mehrere Dateien zum
 * Herunterladen (twig/content_element/download.html.twig, downloads.html.twig,
 * twig/component/_download.html.twig). Die .download-element/.ext-<ext>-Klassen
 * sitzen weiterhin auf dem Wrapper bzw. den Listenelementen.
 *
 * component/_download.html.twig gibt nur einen Link aus (plus optionale
 * Vorschaubilder bei show_file_previews) – kein .size-Element wie im alten
 * Legacy-Template. Vorschaubilder sind bewusst nicht gestylt: Sonderfall,
 * der ins Theme gehört, nicht in dieses Basis-Framework.
 */

/* .enclosure: Anhänge bei News/Terminen (news_full/event_full), gleiches
   Markup wie die Download-Liste, ebenfalls mit .download-element */
.content-downloads ul,
.enclosure {
  padding-inline-start: 0;
  list-style: none;
}

/* Generisches Datei-Icon aus Contaos eigenem Icon-Satz. iconPLAIN.svg ist der
   extensionsunabhängige Fallback; ein Theme kann .ext-pdf/.ext-zip/... gezielt
   mit den passenden Icons (iconPDF.svg, iconZIP.svg, ...) überschreiben.
   Absoluter Pfad ab Domain-Root, da diese Dateien unabhängig vom Ablageort
   der kompilierten CSS-Datei immer an derselben Stelle liegen.
   background-position bleibt bewusst physisch ("left", nicht "start"): CSS
   kennt für Hintergrundbilder noch keine logische Positionierung. */
.download-element {
  padding-inline-start: 1.25em;
  background: url("/assets/contao/images/iconPLAIN.svg") no-repeat left center;
  background-size: 1em;
}

/* Beispiel für ein dateityp-spezifisches Icon: PDF ist der mit Abstand
   häufigste Downloadtyp. Überschreibt nur background-image, Position/Größe
   bleiben vom generischen Fallback oben geerbt. Weitere Typen (.ext-zip,
   .ext-docx, ...) nach demselben Muster bei Bedarf ergänzen. */
.download-element.ext-pdf {
  background-image: url("/assets/contao/images/iconPDF.svg");
}
/*
 * content-accordion (twig/content_element/accordion.html.twig): Akkordeon mit
 * der Bibliothek Handorgel. Contao lädt deren CSS (handorgel.min.css) selbst,
 * und zwar über {% add … to stylesheets %} NACH unserer eigenen CSS-Datei.
 * Bei gleicher Spezifität gewinnt dann das Vendor-CSS. Deshalb stehen die
 * Selektoren hier alle unter div.content-accordion (Spezifität 0,1,1 bzw.
 * 0,2,1) und schlagen die Einzelklassen von Handorgel (0,1,0), egal in welcher
 * Reihenfolge die Dateien geladen werden.
 *
 * Markup (vom Template, nicht änderbar ohne eigenes Template):
 *   <div class="content-accordion">
 *     <h3 class="handorgel__header"><button class="handorgel__header__button" aria-expanded="…">Titel</button></h3>
 *     <div class="handorgel__content"><div class="handorgel__content__inner">…</div></div>
 *     … (Header und Inhalt abwechselnd)
 *   </div>
 * Handorgel setzt per JavaScript aria-expanded/aria-disabled am Button und die
 * Zustandsklassen --open/--opened/--focus/--disabled an Header und Inhalt.
 *
 * Bewusst NICHT angefasst: display, height, overflow und die height-Transition
 * von .handorgel__content. Handorgel animiert die Höhe und wartet auf das
 * Ereignis transitionend (height), um das Öffnen/Schließen abzuschließen
 * (--opened bzw. display: none). Ohne diese Transition bliebe der Zustand
 * hängen. Das ist die zweite funktional nötige Ausnahme von "keine
 * Animationen" neben den Button-Transitions. Bei prefers-reduced-motion wird
 * die Transition auf (fast) null verkürzt, das Ereignis feuert trotzdem.
 *
 * Optik angelehnt an details/summary aus generic/normalize.css: Titelzeile
 * auf --clr-surface-3, Inhalt auf --clr-surface-2, abgerundet, ohne Rahmen.
 * Der Wrapper selbst bleibt unberührt, denn die Überschrift des Elements
 * steht im Wrapper (content_element/_base.html.twig).
 *
 * content-swiper: Der Slider kommt mit dem CSS der Bibliothek Swiper
 * (twig/content_element/swiper.html.twig), das wir nicht überschreiben.
 */
div.content-accordion {
  /* Handorgel gibt dem Wrapper eine graue Linie unten (border-bottom: #eee) */
  border: 0;

  /* Der Titel steckt in einer Überschrift (h2–h6, im Element einstellbar).
     Deren Schriftgröße würde der Button erben (font-size: inherit im
     Vendor-CSS), und das max-inline-size der Überschriften aus
     generic/normalize.css würde den Titel schmaler machen als den Inhalt. */
  & .handorgel__header {
    max-inline-size: none;
  }

  /* Rhythmus (base/typography.css): Er legt Abstand zwischen alle Kinder
     eines content-*-Wrappers. Das gilt hier für Überschrift (steht im
     Wrapper), Titel und Inhalte. Titel und zugehöriger Inhalt müssen aber
     bündig sein; zwischen den Einträgen bleibt ein kleiner Abstand. */
  & .handorgel__header + .handorgel__content {
    margin-block-start: 0;
  }

  & .handorgel__content + .handorgel__header {
    margin-block-start: var(--size-2);
  }

  & .handorgel__header__button {
    position: relative;
    padding-block: var(--size-3);
    /* rechts Platz für den Pfeil */
    padding-inline: var(--size-4) var(--size-8);
    border: 0;
    border-radius: var(--radius-2);
    background-color: var(--clr-surface-3);
    box-shadow: none;
    text-shadow: none;
    color: inherit;
    font-size: var(--ctf-step-0);
    font-weight: var(--font-weight-7);
    text-align: start;
    /* Hover-Übergang des Vendors entfällt, er hat keine Funktion für Handorgel */
    transition: none;

    &:hover {
      background-color: var(--clr-surface-4);
    }

    /* Pfeil aus Rahmenlinien wie bei li.submenu in navigation.css: zeigt
       zugeklappt nach unten und gedreht nach oben, folgt aria-expanded */
    &::after {
      content: "";
      position: absolute;
      inset-inline-end: var(--size-4);
      inset-block-start: 50%;
      inline-size: 0.5em;
      block-size: 0.5em;
      border-inline-end: 2px solid currentColor;
      border-block-end: 2px solid currentColor;
      rotate: 45deg;
      translate: 0 -75%;
    }

    /* Geöffnet: unten eckig, geht nahtlos in den Inhalt über (wie
       details[open] > summary in generic/normalize.css) */
    &[aria-expanded="true"] {
      border-end-start-radius: 0;
      border-end-end-radius: 0;

      &::after {
        rotate: 225deg;
        translate: 0 -25%;
      }
    }

    &[aria-disabled="true"] {
      color: var(--clr-text-2);
      cursor: not-allowed;
    }
  }

  & .handorgel__content {
    border: 0;
    border-end-start-radius: var(--radius-2);
    border-end-end-radius: var(--radius-2);
    background-color: var(--clr-surface-2);
  }

  & .handorgel__content__inner {
    padding: var(--size-3) var(--size-4);
  }
}

/* Bewegung auf (fast) null kürzen, aber nicht entfernen – sonst feuert
   transitionend nicht und Handorgel schließt das Öffnen/Schließen nie ab */
@media (prefers-reduced-motion: reduce) {
  div.content-accordion :is(.handorgel__content, .handorgel__content__inner) {
    transition-duration: 0.01ms;
    transition-delay: 0s;
  }
}
/*
 * mod_navigation und mod_customnav (twig/mod_navigation.html.twig,
 * twig/nav_default.html.twig). Breadcrumb, Artikel-Pagination und Buch-
 * Navigation haben eigene Dateien (breadcrumb.css, pagination.css, booknav.css).
 *
 * Markup, das Contao ausgibt:
 *   <nav class="mod_navigation block [eigene Klasse]">
 *     <ul class="level_1">
 *       <li class="submenu trail"><a class="submenu trail" aria-haspopup="true">…</a>
 *         <ul class="level_2"> … </ul></li>
 *       <li class="active"><strong class="active">…</strong></li>   (aktuelle Seite)
 *       <li class="forward"><a class="forward">…</a></li>            (Weiterleitung)
 *
 * Zwei Stufen:
 *  1. Grundstil für jede Navigation (ohne Zusatzklasse): Liste ohne
 *     Aufzählungszeichen, Einträge nebeneinander.
 *  2. Hauptnavigation: Im Navigationsmodul unter "CSS-Klasse" nav--main
 *     eintragen. Ab --bp-nav waagerechte Leiste mit Dropdown für level_2,
 *     darunter untereinander. Ohne Zusatzklassen funktioniert sie bereits;
 *     für den Mobil-Schalter siehe "Mobile Ansicht" weiter unten.
 *
 * Bewusst ohne Übergänge/Animationen (Theme-Sache).
 */

/* Ab dieser Breite wird aus dem Mobil-Menü die waagerechte Leiste. Wert hier
   ändern, wenn die Navigation mehr/weniger Platz braucht */
/* Gegenstück für "schmaler als --bp-nav" (ein "not (--bp-nav)" lässt sich
   nicht zuverlässig bauen). Beide Werte zusammen ändern: 52em -> 51.99em */

/* --- 1. Grundstil für jede Navigation --- */
:is(.mod_navigation, .mod_customnav) {
  & ul {
    display: flex;
    flex-wrap: wrap;
    gap: var(--size-2);
    padding-inline-start: 0;
    list-style: none;
  }

  & li {
    padding-inline-start: 0;
  }

  /* Verschachtelte Ebenen (level_2, level_3 …) untereinander statt nebeneinander */
  & li ul {
    flex-direction: column;
    inline-size: 100%;
  }

  /* Aktuelle Seite (strong.active) und Pfad dorthin (.trail) hervorheben */
  & :is(strong.active, a.trail, strong.trail, strong.forward) {
    font-weight: var(--font-weight-7);
  }

  & a {
    -webkit-text-decoration: none;
    text-decoration: none;

    &:hover {
      -webkit-text-decoration: underline;
      text-decoration: underline;
    }
  }
}

/* --- 2. Hauptnavigation --- */
.nav--main {
  /* Mobil: eine Spalte, level_1 untereinander */
  & ul {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
  }

  & :is(a, strong) {
    display: block;
    padding: var(--size-2) var(--size-3);
  }

  /* Eintrag mit Unterebene: kleiner Pfeil hinter dem Text. Aus Rahmenlinien
     gebaut statt aus einer Bilddatei, damit keine Icon-Datei nötig ist und
     der Pfeil die Textfarbe annimmt */
  & li.submenu > :is(a, strong) {
    display: flex;
    align-items: center;
    gap: var(--size-2);

    &::after {
      content: "";
      inline-size: 0.5em;
      block-size: 0.5em;
      border-inline-end: 2px solid currentColor;
      border-block-end: 2px solid currentColor;
      rotate: 45deg;
      translate: 0 -0.15em;
    }
  }

  /* Unterebene mobil eingerückt */
  & .level_2 {
    padding-inline-start: var(--size-4);
  }

  @media screen and (min-width: 52em) {
    & .level_1 {
      flex-direction: row;
      flex-wrap: wrap;
      gap: var(--size-2);

      & > li {
        position: relative;

        & > :is(a, strong) {
          white-space: nowrap;
        }
      }
    }

    /* Dropdown: aus dem Fluss genommen, standardmäßig ausgeblendet.
       display:none nimmt das Menü zugleich aus der Tab-Reihenfolge; per
       :hover und :focus-within (Tastatur) wird es sichtbar. */
    & .level_2 {
      display: none;
      position: absolute;
      inset-inline-start: 0;
      inset-block-start: 100%;
      z-index: 10;
      min-inline-size: 11rem;
      padding-inline-start: 0;
      background: var(--clr-surface-1);
      border: var(--border-size-1) solid var(--clr-surface-3);
      border-radius: var(--radius-2);
      box-shadow: var(--shadow-3);
    }

    & li.submenu:is(:hover, :focus-within) > .level_2 {
      display: flex;
    }
  }
}

/* --- Mobile Ansicht ---
   Unterhalb von --bp-nav wird die Navigation per Popover-API geöffnet, ganz
   ohne JavaScript. Im Template gehören dazu ZWEI Buttons – der Schließen-
   Button ist Pflicht, weil ein langes Menü die ganze Höhe füllt und es dann
   weder eine Fläche "daneben" zum Antippen noch auf dem Smartphone ein Esc
   gibt:
     <button class="nav-toggler" popovertarget="nav-main">Menü</button>
     <nav id="nav-main" popover class="nav--main …">
       <button class="nav-toggler" popovertarget="nav-main"
               popovertargetaction="hide">Schließen</button>
       …
     </nav>
   Ohne das popover-Attribut zeigt sich die Navigation mobil einfach
   dauerhaft als Liste (der Schließen-Button ist dann nutzlos, schadet aber
   nicht) – das Menü ist also nie unerreichbar. Zusätzlich schließen Esc und
   ein Tipp außerhalb des Menüs (Light-Dismiss), solange das Menü nicht die
   ganze Höhe füllt. */
.nav--main[popover] {
  /* Geöffnet: volle Breite, Höhe nach Inhalt (maximal die Bildschirmhöhe,
     dann scrollt das Menü) */
  &:popover-open {
    inset: 0 0 auto 0;
    inline-size: 100%;
    block-size: auto;
    max-inline-size: none;
    max-block-size: 100dvh;
    margin: 0;
    padding: var(--grid-gutter);
    border: 0;
    background: var(--clr-surface-1);
    color: var(--clr-text-1);
    overflow-y: auto;
  }

  /* Schließen-Button bleibt beim Scrollen oben rechts sichtbar */
  & .nav-toggler {
    position: sticky;
    inset-block-start: 0;
    margin-inline-start: auto;
  }

  /* Breit: Popover-Standardverhalten abschalten, Navigation ist wieder ein
     normales Element im Seitenfluss und immer sichtbar */
  @media screen and (min-width: 52em) {
    display: block;
    position: static;
    inline-size: auto;
    block-size: auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    overflow: visible;
  }
}

/* Der Schalter wird nur mobil gebraucht */
.nav-toggler {
  @media screen and (min-width: 52em) {
    display: none;
  }
}
/* Alternative zur Popover-Variante: mobiler Menü-Schalter mit JS (src/js/navigation.js)
@import "contao/navigation-js.css";
*/
/*
 * mod_breadcrumb (twig/mod_breadcrumb.html.twig): <nav> mit <ul>, der letzte
 * Eintrag ist <li class="active" aria-current="page"> ohne Link. Die
 * Trennzeichen kommen per ::after, damit sie nicht im Markup stehen (und von
 * Screenreadern nicht vorgelesen werden).
 */
.mod_breadcrumb ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--size-2);
  padding-inline-start: 0;
  list-style: none;

  & li {
    padding-inline-start: 0;

    &:not(:last-child)::after {
      content: "/";
      margin-inline-start: var(--size-2);
      color: var(--clr-text-2);
    }
  }
}
/*
 * mod_articlenav (twig/mod_articlenav.html.twig): Blättern zwischen den
 * Artikeln einer Seite. Wrapper-Klasse .pagination, Einträge first/previous/
 * link/active/next/last. Die Klasse .pagination wird auch von anderen
 * Contao-Paginierungen verwendet und bekommt hier dasselbe Aussehen.
 */
.pagination ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--size-2);
  padding-inline-start: 0;
  list-style: none;

  & li {
    padding-inline-start: 0;
  }

  /* Aktuelle Seite ist <strong class="active">, kein Link */
  & strong.active {
    font-weight: var(--font-weight-7);
  }
}
/*
 * mod_booknav (twig/mod_booknav.html.twig): "Buch"-Navigation mit
 * previous/up/next. Fehlt ein Ziel, gibt Contao <li class="... empty">&nbsp;</li>
 * aus – die Liste bleibt dadurch dreispaltig und "up" bleibt mittig.
 */
.mod_booknav ul {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: var(--size-2);
  gap: var(--size-2);
  padding-inline-start: 0;
  list-style: none;

  & li {
    padding-inline-start: 0;
  }

  & .up {
    text-align: center;
  }

  & .next {
    text-align: end;
  }
}
/*
 * Nachrichten: mod_newslist, mod_newsarchive, mod_newsreader, mod_newsmenu
 * (news-bundle/contao/templates/twig/mod_news*.html.twig, news_*.html.twig).
 *
 * Die Meldungen selbst kommen in vier Layouts, jeweils als <div class="layout_<name>
 * arc_<archiv-id> block [featured|eigene Klasse]">:
 *   layout_latest  Info, Bild, Überschrift (h2), Teaser, "Weiterlesen"
 *   layout_short   wie latest, ohne Bild
 *   layout_simple  nur Datum + Titel in einer Zeile
 *   layout_full    Leseansicht: h1, Info, Teaser/Text, Anhänge (.enclosure)
 * Das Teaser-/Textfeld steckt in <div class="ce_text content-text block"> –
 * die Klasse .content-text bekommt ihr Lesemaß aus contao/elements.css.
 *
 * Die layout_*-Klassen und .info/.more/.enclosure teilen sich News und Events
 * (calendar-bundle). Dieser Abschnitt gilt deshalb auch für Events; die
 * Event-Besonderheiten stehen in events.css.
 */

/* Meldungen in der Liste untereinander (der Wrapper enthält direkt die
   Meldungen, bei Archiv-Modulen davor ggf. die Überschrift) */
:is(.mod_newslist, .mod_newsarchive) > * + * {
  margin-block-start: var(--size-fluid-3);
}

/* Inhalt einer Meldung: derselbe Rhythmus wie zwischen Inhaltselementen
   (base/typography.css) */
:is(.layout_latest, .layout_short, .layout_full, .layout_list, .layout_teaser) > * + * {
  margin-block-start: var(--size-fluid-2);
}

/* Datum/Autor (<p class="info"><time>…</time> Autor</p>) zurückgenommen */
:is(.layout_latest, .layout_short, .layout_full) .info {
  color: var(--clr-text-2);
  font-size: var(--font-size-1);
}

/* layout_simple: ein Eintrag = Datum, danach der Link zur Meldung */
.layout_simple time {
  margin-inline-end: var(--size-2);
  color: var(--clr-text-2);
}

/* "Weiterlesen" (<p class="more"><a>…</a></p>) und "Zurück" (<p class="back">)
   sind Buttons, siehe :--ctf-btn in base/buttons.css */

/* Bild im Teaser mit Ausrichtung links/rechts: Contao setzt float_left bzw.
   float_right am <figure> (siehe contao/elements.css, dort das Umfließen) */

/* mod_newsmenu (+ mod_eventmenu, gleiches Markup): Archiv nach Jahren/Monaten
   als Liste (<li class="year submenu"> mit verschachteltem level_2) oder als
   Mini-Kalender (siehe calendar.css) */
:is(.mod_newsmenu, .mod_eventmenu) {
  & ul {
    padding-inline-start: 0;
    list-style: none;
  }

  & li {
    padding-inline-start: 0;
  }

  /* Monate unter dem Jahr eingerückt */
  & .level_2 {
    padding-inline-start: var(--size-4);
  }

  & strong.active {
    font-weight: var(--font-weight-7);
  }
}
/*
 * Termine: mod_eventlist, mod_eventreader, mod_eventmenu
 * (calendar-bundle/contao/templates/twig/mod_event*.html.twig, event_*.html.twig).
 * Das Monatsraster steht in calendar.css, Meldungs-Layouts und Archivmenü
 * (.layout_*, .info, .more, .enclosure, mod_eventmenu) in news.css – die
 * Klassen sind bei News und Events dieselben.
 *
 * Jeder Termin ist ein <div class="event layout_<name> [Zustand] cal_<id>">:
 *   layout_list      Überschrift (Link), Zeit, Ort, Bild, Details
 *   layout_teaser    wie list, mit Teaser und "Weiterlesen"
 *   layout_upcoming  eine Zeile: Datum + Link (z. B. "Nächste Termine")
 *   layout_full      Leseansicht (.event.layout_full)
 * Zustandsklassen, die Contao ergänzt: bygone (vorbei), upcoming (kommt),
 * current (läuft gerade), featured (hervorgehoben).
 */

/* Termine und die Datumsüberschriften dazwischen untereinander */
.mod_eventlist > * + * {
  margin-block-start: var(--size-fluid-3);
}

/* Datumsüberschrift (<div class="header"><span class="day">…</span>
   <span class="date">…</span></div>) gehört zu dem Termin darunter */
.mod_eventlist .header {
  padding-block-end: var(--size-1);
  border-block-end: var(--border-size-1) solid var(--clr-surface-3);
  font-weight: var(--font-weight-7);
}

.mod_eventlist > .header + .event {
  margin-block-start: var(--size-3);
}

/* Zeit, Ort und Wiederholungs-Info zurückgenommen */
.event :is(.time, .location, .info) {
  color: var(--clr-text-2);
  font-size: var(--font-size-1);
}

/* Vergangene Termine abgeschwächt, Links behalten ihre Linkfarbe */
.event.bygone {
  color: var(--clr-text-2);
}

/* layout_upcoming: Datum vor dem Link, keine eigene Zeile nötig */
.layout_upcoming .date {
  margin-inline-end: var(--size-2);
  color: var(--clr-text-2);
}
/*
 * Kalender: mod_calendar mit cal_default (Monatsraster, <table class="calendar">)
 * und der Mini-Kalender <table class="minicalendar"> aus cal_mini, den auch
 * mod_newsmenu im Tages-Modus ausgibt (calendar-bundle/contao/templates/twig/
 * cal_default.html.twig, cal_mini.html.twig; news-bundle: mod_newsmenu.html.twig).
 *
 * Gemeinsames Markup: Kopfzeile <th class="head previous|current|next">
 * (Monatswechsel), Wochentage <th class="label [weekend]">, Tageszellen
 * <td class="[empty|active] [weekend] [today] [selected]">. Tabellen-Grund-
 * styling (Rahmen, Zellenfarben) kommt aus generic/normalize.css.
 */

/* Container für die Breitenabfrage unten */
.mod_calendar {
  container-type: inline-size;
}

:is(.calendar, .minicalendar) {
  inline-size: 100%;
  table-layout: fixed;

  & :is(th, td) {
    max-inline-size: none;
  }

  /* Kopfzeile: zurück | Monat | vor */
  & .head.previous {
    text-align: start;
  }

  & .head.current {
    text-align: center;
  }

  & .head.next {
    text-align: end;
  }

  /* Leere Zellen vor dem 1. und nach dem letzten Tag des Monats */
  & td.empty {
    background-color: var(--clr-surface-2);
  }

  /* Heute und gewählter Tag (?day=…) */
  & td.today {
    outline: var(--border-size-2) solid var(--clr-link);
    outline-offset: calc(var(--border-size-2) * -1);
  }

  & td.selected {
    background-color: hsl(from var(--clr-link) h s l / 15%);
  }
}

/* Monatsraster: Zellen oben ausgerichtet, Termine als kleine Einträge */
.calendar {
  & td {
    text-align: start;
    vertical-align: top;
  }

  & .header {
    font-weight: var(--font-weight-7);
  }

  & .event {
    margin-block-start: var(--size-1);
    font-size: var(--font-size-0);
    word-wrap: anywhere;
  }

  /* Schmale Spalte: engere Zellen, damit die sieben Tage Platz haben */
  @container (max-width: 40rem) {
    & td {
      padding: var(--size-1);
    }
  }
}

/* Mini-Kalender: kompakt, Tage zentriert; Tage mit Terminen/Meldungen sind
   Links und deshalb fett */
.minicalendar {
  & :is(th, td) {
    padding: var(--size-1);
    text-align: center;
  }

  & td.active a {
    font-weight: var(--font-weight-7);
  }
}
/*
 * Formulare (twig/form_row.html.twig, form_text.html.twig, form_textarea.html.twig,
 * form_select.html.twig, form_checkbox.html.twig, form_submit.html.twig,
 * form_upload.html.twig, form_explanation.html.twig). Die Klassen stammen aus
 * der jeweiligen Contao\Widget-Unterklasse (this.prefix) und sind in den
 * Twig-Templates identisch zu den klassischen Vorlagen. Grundstyling von
 * input/select/textarea kommt bereits aus der Open-Props-normalize.css.
 */

.widget {
  display: grid;
  grid-gap: var(--size-1);
  gap: var(--size-1);
  margin-block-end: var(--size-4);
}

.mandatory {
  color: var(--clr-error);
}

.widget .error {
  color: var(--clr-error);
  font-size: var(--ctf-step--2);
}

.widget .help {
  color: var(--clr-text-2);
  font-size: var(--ctf-step--2);
}

/* Zeile mit einer Meldung, statt eines Eingabefelds, hebt sich per :has()
   automatisch etwas ab, ohne dass form_row eine eigene Fehler-Klasse braucht */
.widget:has(.error) {
  border-inline-start: var(--border-size-3) solid var(--clr-error);
  padding-inline-start: var(--size-3);
}

:is(.checkbox_container, .radio_container) {
  border: 0;
  padding: 0;
  display: grid;
  grid-gap: var(--size-1);
  gap: var(--size-1);
}

:is(.checkbox_container, .radio_container) legend {
  font-weight: var(--font-weight-6);
}

:is(.checkbox_container, .radio_container) span {
  display: flex;
  align-items: center;
  gap: var(--size-2);
}

.explanation {
  margin-block-end: var(--size-4);
  color: var(--clr-text-2);
}

.form-confirmation {
  padding: var(--size-3);
  background-color: var(--clr-surface-2);
  border-radius: var(--radius-2);
}

/* .formbody: Wrapper der handgeschriebenen (Nicht-Symfony-)Formulare wie
   Login, Suche, Quicknav/-link, Passwort ändern/Konto löschen (u. a.
   mod_login.html.twig, mod_search.html.twig, content_element/login.html.twig).
   Übernimmt den Zeilenabstand selbst, damit .widget darin nicht zusätzlich
   seinen eigenen margin-block-end aufaddiert */
.formbody {
  display: grid;
  grid-gap: var(--size-2);
  gap: var(--size-2);
}

.formbody .widget {
  margin-block-end: 0;
}

/* Hinweistext bei bereits angemeldeten Nutzern ("Angemeldet als …"),
   in content_element/login.html.twig UND mod_login.html.twig identisch */
.login_info {
  color: var(--clr-text-2);
}

/* Link zum Passwort-Reset unterhalb des Login-Formulars */
.password-reset {
  margin-block-start: var(--size-2);
  font-size: var(--ctf-step--2);
}
/*
 * mod_article (Syndication-Icons, "Zurück"-Link) und mod_message.
 * Twig-Ports sind auch hier 1:1-identisch zu den klassischen Vorlagen
 * (twig/mod_article.html.twig, twig/mod_message.html.twig).
 */

.syndication {
  display: flex;
  gap: var(--size-2);
  margin-block-end: var(--size-3);
}

.syndication a {
  display: inline-flex;
}

/* mod_message: Klasse ist $this->type (z. B. "confirm", "error") + " message"
   (u. a. von ModuleRegistration so gesetzt – Registrierungsbestätigungen
   laufen über dieses normale .message.confirm, kein tl_-Präfix).

   .tl_error ist eigentlich eine Backend-Klasse, sickert aber real im
   Frontend durch: content_element/two_factor.html.twig rendert sie direkt
   bei ungültigem Code bzw. erzwungener 2FA (TwoFactorController setzt
   invalid_verification_code/enforce_two_factor echt) – deshalb als Alias
   mitgestylt.

   .tl_confirm dagegen NICHT mitgestylt: das wird nur noch von den alten
   Legacy-Modulklassen ModuleChangePassword/ModulePersonalData gesetzt.
   Reales Testen (2026-10-01) hat gezeigt, dass "Passwort ändern" in dieser
   Contao-Version über den modernen Content-Element-Flow läuft (eigenes
   Symfony-Form-Theme @Contao/form/contao_layout.html.twig, das nur
   .mandatory/.error erzeugt, nie message/tl_confirm) – der Legacy-Modul-Pfad
   ist damit praktisch tot, ein Alias dafür wäre spekulativ.

   .message.info/.message.warning sind (noch) keine von Contao selbst gesetzten
   Typen, aber als Helper-Klassen nutzbar, falls ein Projekt sie manuell braucht. */
:is(.message, .tl_error) {
  padding: var(--size-3);
  border-radius: var(--radius-2);
  background-color: var(--clr-surface-2);
}

:is(.message.error, .tl_error) {
  background-color: var(--clr-error-surface);
  color: var(--clr-error-surface-text);
}

.message.confirm {
  background-color: var(--clr-success-surface);
  color: var(--clr-success-surface-text);
}

.message.info {
  background-color: var(--clr-info-surface);
  color: var(--clr-info-surface-text);
}

.message.warning {
  background-color: var(--clr-warning-surface);
  color: var(--clr-warning-surface-text);
}

/* print: zuletzt, damit die Druckregeln die Bildschirm-Styles überstimmen */

/*
 * Druckansicht. Steht bewusst als Letztes in styles.css: Die Regeln hier
 * sollen die Bildschirm-Styles aller anderen Dateien überstimmen, ohne dass
 * dafür Spezifität oder !important nötig wäre – gleiche Spezifität, spätere
 * Position gewinnt. Alles steckt in einem @media print.
 *
 * Ziele: nur Inhalt drucken (keine Navigation, Schalter, Buttons, Videos),
 * Tinte sparen (schwarz auf weiß, keine Schatten/Hintergründe), Linkziele
 * lesbar machen und Seitenumbrüche an sinnvollen Stellen setzen.
 */
@media print {
  @page {
    margin: 2cm;
  }

  /* Immer helles Farbschema, auch wenn das System auf Dark Mode steht, und
     kleinere Grundschrift: Die fluiden Schriftgrößen (rem + vw) sind für den
     Bildschirm gedacht, 75 % ergeben auf Papier eine übliche Textgröße */
  html {
    --csstools-color-scheme--light: initial;
    color-scheme: light;
    background: hsl(0, 0%, 100%);
    color: hsl(0, 0%, 0%);
    font-size: 75%;
  }

  /* Seitengerüst: kein Grid mit Mindesthöhe, keine Breitenbegrenzung, der
     Text darf die ganze Papierbreite nutzen */
  #wrapper {
    display: block;
    min-block-size: 0;
  }

  :is(header, main, footer) > .inside {
    max-inline-size: none;
    padding-inline: 0;
  }

  /* Nur Inhalt: Navigation samt Menü-Schalter, Buchnavigation,
     Syndication-Icons, "Nach oben"-Link, Buttons, Formular-Absender und
     eingebettete Medien haben auf Papier keine Funktion. Als Link ausgegebene
     Buttons (:--ctf-btn in base/buttons.css, z. B. Hyperlink-Element mit
     .as-btn) bleiben bewusst stehen, ihr Linktext gehört zum Inhalt. */
  :is(
    .mod_navigation,
    .mod_customnav,
    .nav-toggler,
    .mod_booknav,
    .syndication,
    .content-toplink,
    .content-player,
    .content-youtube,
    .content-vimeo,
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    iframe,
    video,
    audio
  ) {
    display: none;
  }

  /* Keine Schatten und Hintergrundflächen, die nur Tinte kosten */
  * {
    box-shadow: none;
    text-shadow: none;
  }

  :where(td, th, summary, details, code, pre) {
    background: transparent;
  }

  /* Links schwarz und unterstrichen, besuchte ebenso */
  a[href],
  a[href]:visited {
    color: inherit;
    -webkit-text-decoration: underline;
    text-decoration: underline;
  }

  /* Bei externen Links im Fließtext die Adresse dahinter ausdrucken, weil
     man Papier nicht anklicken kann */
  :is(.rte, .content-text, .content-hyperlink) a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }

  /* Zugeklappte details (z. B. künftiges Akkordeon) mitdrucken. Browser, die
     ::details-content noch nicht kennen, ignorieren die Regel */
  details::details-content {
    content-visibility: visible;
    display: block;
  }

  /* Seitenumbrüche: Überschrift nicht allein am Seitenende, Bilder, Tabellen-
     zeilen, Zitate und Code nicht mitten durchschneiden, Tabellenkopf auf
     jeder Seite wiederholen */
  :where(h1, h2, h3, h4, h5, h6) {
    page-break-after: avoid;
    -moz-column-break-after: avoid;
         break-after: avoid;
  }

  :where(img, figure, pre, blockquote, tr) {
    page-break-inside: avoid;
    -moz-column-break-inside: avoid;
         break-inside: avoid;
  }

  :where(p, li) {
    orphans: 3;
    widows: 3;
  }

  :where(thead) {
    display: table-header-group;
  }
}
