/* components.css — Layout und Bausteine. Keine Custom-Property-Definition (siehe tokens.css).
   Alle Bausteine sind unter /dev/styleguide sichtbar (nur in NODE_ENV=development gemountet). */

/* ── Seitengerüst ──────────────────────────────────────────────────────────── */

.app-layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  align-items: stretch;
  min-height: 100vh;
  min-height: 100dvh;
}

.public-layout {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 24px 20px 64px;
}

.sidebar {
  grid-column: 1;
  border-right: 1px solid var(--border);
  background: rgba(10, 12, 27, 0.78);
  padding: 24px 20px;
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.content {
  grid-column: 2;
  min-width: 0;
  padding: 24px 32px 64px;
  max-width: var(--content-max);
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--border);
}

.topbar .btn-row {
  flex-wrap: nowrap;
  align-items: center;
}

.topbar .nav-item {
  width: auto;
  padding: 8px 10px;
  white-space: nowrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text);
  text-decoration: none;
}

.brand:hover {
  text-decoration: none;
}

.brand-mark {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  font-size: 1.1rem;
  flex-shrink: 0;
}

.brand strong {
  display: block;
  font-size: 0.98rem;
}

.brand span {
  display: block;
  font-size: 0.78rem;
  color: var(--text2);
}

.side-nav,
.side-footer {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Die Fußnavigation klebt am unteren Rand der sticky Sidebar. */
.side-footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--text2);
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  background: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
}

.nav-item:hover {
  background: var(--glass);
  color: var(--text);
  text-decoration: none;
}

.nav-item.active,
.nav-item[aria-current='page'] {
  background: var(--glass);
  border-color: var(--border);
  color: var(--text);
}

.nav-item:disabled,
.nav-item.disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.nav-icon {
  width: 20px;
  text-align: center;
  flex-shrink: 0;
}

/* ── Menü der schmalen Ansicht ─────────────────────────────────────────────── */
/* Nur bis 820 px sichtbar (siehe „Schmale Ansicht“). Das Panel hängt absolut unter der
   Kopfleiste; deren position: sticky ist der Bezugsrahmen. */

.menue {
  display: none;
}

.menue__schalter {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--glass);
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
  user-select: none;
}

.menue__schalter::-webkit-details-marker {
  display: none;
}

.menue[open] > .menue__schalter {
  border-color: rgba(139, 92, 246, 0.45);
}

/* Zwei Striche, die beim Öffnen zum Kreuz werden. */
.menue__symbol {
  position: relative;
  width: 18px;
  height: 12px;
}

.menue__symbol::before,
.menue__symbol::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transition:
    transform 0.2s ease,
    top 0.2s ease;
}

.menue__symbol::before {
  top: 2px;
}

.menue__symbol::after {
  top: 8px;
}

.menue[open] .menue__symbol::before {
  top: 5px;
  transform: rotate(45deg);
}

.menue[open] .menue__symbol::after {
  top: 5px;
  transform: rotate(-45deg);
}

.menue__panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: calc(100dvh - 64px);
  overflow-y: auto;
  padding: 12px 16px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
  box-shadow: 0 24px 40px -20px rgba(0, 0, 0, 0.8);
}

.menue__panel .side-footer {
  margin-top: 0;
  padding-top: 8px;
}

.menue__panel .nav-item {
  min-height: 48px;
}

/* ── Karte ─────────────────────────────────────────────────────────────────── */

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
}

.card + .card {
  margin-top: 16px;
}

/* In Rastern und Stapeln mit gap trägt der Container den Abstand. Sonst rutscht ab der
   zweiten Kachel jede um 16 px nach unten (Kennwerte) bzw. der Abstand verdoppelt sich. */
:is(.card-grid, .kennwerte, .fassungen, .stufen, .fragenliste) > .card {
  margin-top: 0;
}

/* Kartentitel standen direkt auf dem folgenden Absatz, der Tabelle oder dem Formular. */
.card > .card-title + *,
.public-contact > .card-title + * {
  margin-top: 12px;
}

.card > .card-title + .field-hint {
  margin-top: 4px;
}

.card > .muted + .btn-row,
.public-contact > .muted + .form {
  margin-top: 16px;
}

.card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.card-title {
  font-size: 1.05rem;
  font-weight: 700;
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text2);
  margin-bottom: 6px;
}

.lead {
  color: var(--text2);
  font-size: 1.02rem;
}

.muted {
  color: var(--text2);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}

/* ── Button ────────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--glass);
  color: var(--text);
  font-family: inherit;
  font-size: 0.94rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition:
    background 0.15s ease,
    border-color 0.15s ease,
    box-shadow 0.2s ease,
    transform 0.1s ease;
}

.btn:hover {
  background: rgba(255, 255, 255, 0.1);
  text-decoration: none;
}

.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  border-color: transparent;
  color: #ffffff;
}

.btn-primary:hover {
  filter: brightness(1.08);
  background: linear-gradient(135deg, var(--accent), var(--accent2));
}

.btn-danger {
  background: rgba(233, 69, 96, 0.14);
  border-color: rgba(233, 69, 96, 0.45);
  color: #ffb3c0;
}

.btn-danger:hover {
  background: rgba(233, 69, 96, 0.24);
}

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* ── Formular ──────────────────────────────────────────────────────────────── */

.form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 520px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field label {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text2);
}

/* Radio-Buttons und Checkboxen ausgenommen: mit width: 100% stand jeder Auswahlknopf
   zentriert in voller Breite über seiner Beschriftung. */
.field input:not([type='radio'], [type='checkbox']),
.field select,
.field textarea {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
}

.field > input[type='checkbox'] {
  align-self: flex-start;
  width: 20px;
  height: 20px;
  accent-color: var(--accent);
}

.field textarea {
  min-height: 120px;
  resize: vertical;
}

.field-hint {
  font-size: 0.82rem;
  color: var(--text2);
}

.field-error {
  font-size: 0.84rem;
  color: #ffb3c0;
}

.field input[aria-invalid='true'],
.field textarea[aria-invalid='true'] {
  border-color: rgba(233, 69, 96, 0.6);
}

/* Honigtopf des Kontaktformulars — für Menschen unsichtbar, für Bots ein Feld. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── Tabelle ───────────────────────────────────────────────────────────────── */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

table.data th,
table.data td {
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

table.data th {
  color: var(--text2);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--panel);
}

table.data tr:last-child td {
  border-bottom: none;
}

table.data tbody tr:hover {
  background: var(--glass);
}

/* ── Badge ─────────────────────────────────────────────────────────────────── */

.badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 700;
  border: 1px solid var(--border);
  background: var(--glass);
  color: var(--text2);
  white-space: nowrap;
}

.badge-success {
  background: rgba(98, 229, 143, 0.13);
  border-color: rgba(98, 229, 143, 0.4);
  color: var(--success);
}

.badge-warn {
  background: rgba(246, 195, 68, 0.13);
  border-color: rgba(246, 195, 68, 0.4);
  color: var(--warn);
}

.badge-fail {
  background: rgba(233, 69, 96, 0.13);
  border-color: rgba(233, 69, 96, 0.4);
  color: #ffb3c0;
}

/* ── Flash ─────────────────────────────────────────────────────────────────── */

.flash {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--glass);
  margin-bottom: 20px;
  font-size: 0.94rem;
}

.flash-success {
  background: rgba(98, 229, 143, 0.1);
  border-color: rgba(98, 229, 143, 0.35);
}

.flash-error {
  background: rgba(233, 69, 96, 0.1);
  border-color: rgba(233, 69, 96, 0.35);
}

.flash-warn {
  background: rgba(246, 195, 68, 0.1);
  border-color: rgba(246, 195, 68, 0.35);
}

/* ── Fortschritt ───────────────────────────────────────────────────────────── */

.progress {
  height: 8px;
  border-radius: 999px;
  background: var(--panel);
  border: 1px solid var(--border);
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
}

/* ── htmx-Indikator ────────────────────────────────────────────────────────── */
/* htmx 2 fügt diese Regeln sonst als Inline-<style> ein und bricht damit
   `style-src 'self'`. Abgeschaltet wird das über
   <meta name="htmx-config" content='{"includeIndicatorStyles":false}'> in base.njk. */

.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}

.htmx-request .htmx-indicator {
  opacity: 1;
}

.htmx-request.htmx-indicator {
  opacity: 1;
}

.htmx-request .btn {
  opacity: 0.6;
  pointer-events: none;
}

/* ── Satzbild für Lektionen ────────────────────────────────────────────────── */
/* Umschließt das beim Import gerenderte und bereinigte body_html. Ohne diesen
   Block erbt der Lektionstext den globalen Reset (* { margin: 0 }) und kollabiert. */

.prose {
  max-width: var(--prose-max);
  color: var(--text);
  font-size: 1.02rem;
  line-height: 1.75;
}

.prose > * + * {
  margin-top: 1em;
}

/* Eine Lektion beginnt meist mit einer Zwischenüberschrift; ihr oberer Abstand stand sonst
   als Leerraum oben in der Karte. */
.prose > :first-child {
  margin-top: 0;
}

.prose h2 {
  margin-top: 1.9em;
  margin-bottom: 0.6em;
  font-size: 1.35rem;
  padding-bottom: 0.3em;
  border-bottom: 1px solid var(--border);
}

.prose h3 {
  margin-top: 1.6em;
  margin-bottom: 0.4em;
  font-size: 1.12rem;
}

.prose h4 {
  margin-top: 1.4em;
  margin-bottom: 0.3em;
  font-size: 1rem;
  color: var(--text2);
}

.prose ul,
.prose ol {
  padding-left: 1.5em;
}

.prose li + li {
  margin-top: 0.4em;
}

.prose blockquote {
  border-left: 3px solid var(--accent);
  padding: 0.2em 0 0.2em 1.1em;
  color: var(--text2);
  font-style: italic;
}

.prose code {
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.12em 0.4em;
}

.prose pre {
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  overflow-x: auto;
  line-height: 1.5;
}

.prose pre code {
  background: none;
  border: none;
  padding: 0;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
  display: block;
  overflow-x: auto;
}

.prose th,
.prose td {
  border: 1px solid var(--border);
  padding: 8px 12px;
  text-align: left;
}

.prose th {
  background: var(--panel);
  font-weight: 700;
}

.prose hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 2em 0;
}

.prose a {
  text-decoration: underline;
}

/* ── Abstandshilfen ────────────────────────────────────────────────────────── */
/* Die einzigen Utility-Klassen des Projekts. Sie ersetzen style-Attribute, die unter der
   CSP ohne 'unsafe-inline' gar nicht erst wirken würden. */

.abstand-oben {
  margin-top: 16px;
}

.abstand-unten {
  margin-bottom: 16px;
}

/* ── Gesperrt ──────────────────────────────────────────────────────────────── */

.locked {
  opacity: 0.55;
}

.lock-note {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border);
  color: var(--text2);
  font-size: 0.92rem;
}

/* ── Schmale Ansicht ───────────────────────────────────────────────────────── */

@media (max-width: 820px) {
  /* align-content: start — sonst verteilt das Raster auf kurzen Seiten die Resthöhe auf
     Navigations- und Inhaltszeile, und unter dem Menü klafft eine Lücke. */
  .app-layout {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
  }

  /* Die Sidebar wird zur festen Kopfleiste: Marke links, Menüknopf rechts. Die Navigation
     selbst steht im aufklappbaren Menü, das unter der Leiste aufgeht. Vorher brach sie
     in vier Reihen um und schob den Seiteninhalt unter den ersten Bildschirm. */
  .sidebar {
    grid-column: 1;
    position: sticky;
    top: 0;
    z-index: 20;
    height: auto;
    overflow: visible;
    border-right: none;
    border-bottom: 1px solid var(--border);
    background: var(--bg);
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 16px;
  }

  .sidebar > .side-nav,
  .sidebar > .side-footer {
    display: none;
  }

  .brand {
    min-width: 0;
  }

  .brand > div {
    min-width: 0;
  }

  .brand span {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .menue {
    display: block;
  }

  .viewtab,
  .lektionsliste__eintrag {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .content {
    grid-column: 1;
    padding: 20px 16px 48px;
  }
}

/* ── Öffentliche Startseite ─────────────────────────────────────────────── */

.public-layout {
  width: min(100%, var(--content-max));
}

.brand-mark {
  background: var(--accent);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* Ein Organisationslogo behält sein Seitenverhältnis. Das TB-Logo ist 3:1 und wurde
   vorher in das 38-px-Quadrat des Platzhalters gequetscht. */
img.brand-mark {
  width: auto;
  max-width: 104px;
  height: 32px;
  object-fit: contain;
  background: none;
  border: none;
}

.landing-hero {
  position: relative;
  min-height: 460px;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #0c1020;
}

.landing-hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  width: 52%;
  max-width: 600px;
  min-height: 460px;
  padding: 64px 56px;
}

.landing-hero__content h1 {
  max-width: 13ch;
  font-size: 2.75rem;
  line-height: 1.08;
}

.landing-hero__content .lead {
  max-width: 48ch;
  margin-top: 18px;
  font-size: 1.08rem;
}

.landing-hero__art {
  position: absolute;
  z-index: -1;
  inset: 0;
}

.landing-hero__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.landing-access {
  display: grid;
  grid-template-columns: minmax(320px, 0.85fr) minmax(0, 1.15fr);
  gap: 20px;
  margin-top: 24px;
}

.landing-access > .card {
  height: 100%;
  margin-top: 0;
}

.process-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  padding: 0;
  list-style: none;
  counter-reset: process;
}

.process-list li {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  gap: 10px;
  align-items: start;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text2);
}

.process-list li::before {
  content: counter(process, decimal-leading-zero);
  counter-increment: process;
  display: grid;
  grid-column: 1;
  grid-row: 1;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid rgba(139, 92, 246, 0.7);
  border-radius: 50%;
  color: #d9ceff;
  font-size: 0.72rem;
  font-weight: 700;
}

.process-list strong {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  color: var(--text);
}

.process-list li > span {
  grid-column: 1 / -1;
  grid-row: 2;
  margin-top: 4px;
  line-height: 1.55;
}

.section-block {
  margin-top: 56px;
}

.section-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 18px;
}

.section-heading h2 {
  font-size: 1.45rem;
}

.topic-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
}

.topic-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 190px;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.topic-index {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid rgba(98, 229, 143, 0.45);
  border-radius: 50%;
  color: var(--success);
  font-size: 0.72rem;
  font-weight: 700;
}

.topic-card h3 {
  margin-top: 24px;
  font-size: 1rem;
  overflow-wrap: anywhere;
}

.topic-card .muted {
  margin-top: 8px;
  overflow-wrap: anywhere;
}

.public-contact {
  padding-top: 36px;
  border-top: 1px solid var(--border);
}

@media (max-width: 820px) {
  .landing-hero {
    display: grid;
    grid-template-rows: auto 240px;
    min-height: 0;
  }

  .landing-hero__content {
    width: 100%;
    min-height: 0;
    padding: 36px 24px;
  }

  .landing-hero__content h1 {
    max-width: 15ch;
    font-size: 2rem;
  }

  .landing-hero__art {
    position: relative;
    z-index: 0;
    min-height: 240px;
  }

  .topic-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .section-heading {
    align-items: start;
    flex-direction: column;
    gap: 8px;
  }
}

@media (max-width: 480px) {
  .public-layout {
    padding: 16px 14px 48px;
  }

  .topbar {
    align-items: flex-start;
    flex-direction: column;
  }

  .topbar .btn-row {
    width: 100%;
    justify-content: flex-start;
  }

  .topic-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 680px) {
  .landing-access {
    grid-template-columns: minmax(0, 1fr);
  }

  .process-list {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── Fassungsansicht: Reiter, Kennwerte, Leseansicht, Fragen ───────────────── */
/* Die drei Sichten auf eine Modulfassung teilen sich diese Bausteine. Farben und
   Masse kommen ausschliesslich aus tokens.css — tokens.test.ts schlaegt sonst fehl. */

.flash-info {
  background: rgba(139, 92, 246, 0.1);
  border-color: rgba(139, 92, 246, 0.35);
}

.viewtabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  overflow-x: auto;
}

.viewtab {
  padding: 8px 18px;
  border-radius: var(--radius-sm);
  color: var(--text2);
  text-decoration: none;
  white-space: nowrap;
  font-size: 0.94rem;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}

.viewtab:hover {
  background: var(--glass);
  color: var(--text);
}

.viewtab.active {
  background: var(--card);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border);
}

.kennwerte {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.kennwert {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.kennwert__zahl {
  font-size: 1.9rem;
  line-height: 1.1;
  font-weight: 600;
}

.kennwert__link {
  margin-top: auto;
  font-size: 0.88rem;
}

/* Lesen: schmale Navigationsspalte, breite Textspalte. Die Textbreite deckelt
   .prose ueber --prose-max — Fliesstext ueber die volle Seite liest sich schlecht. */
.leseansicht {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 22px;
  align-items: start;
}

.leseansicht__nav {
  position: sticky;
  top: 24px;
  padding: 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}

/* Die Lektionsliste als Wähler — nur in der einspaltigen Leseansicht (bis 980 px). */
.lektionswahl {
  display: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}

.lektionswahl__schalter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 0 16px;
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 600;
  list-style: none;
  cursor: pointer;
}

.lektionswahl__schalter::-webkit-details-marker {
  display: none;
}

.lektionswahl__schalter::after {
  content: '';
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--text2);
  border-bottom: 2px solid var(--text2);
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.2s ease;
}

.lektionswahl[open] .lektionswahl__schalter::after {
  transform: rotate(-135deg) translateY(-2px);
}

.lektionswahl .lektionsliste {
  margin: 0;
  padding: 0 8px 8px;
}

.lektionsliste {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lektionsliste__eintrag {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  color: var(--text2);
  text-decoration: none;
  font-size: 0.92rem;
}

.lektionsliste__eintrag:hover {
  background: var(--glass);
  color: var(--text);
}

.lektionsliste__eintrag.active {
  background: var(--card);
  color: var(--text);
}

.lektionsliste__nummer {
  flex: none;
  width: 20px;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  font-size: 0.8rem;
}

.lektionstitel {
  font-size: 1.6rem;
  margin: 4px 0 24px;
}

.blaettern {
  display: flex;
  gap: 10px;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.blaettern__weiter {
  margin-left: auto;
}

/* Auf dem Handy klebt die Blätterleiste am unteren Rand, die Knöpfe teilen sich die Breite.
   Die negativen Ränder ziehen sie bis an die Kante des Inhalts bzw. der Karte. */
@media (max-width: 820px) {
  .blaettern {
    position: sticky;
    bottom: 0;
    z-index: 10;
    margin-inline: -16px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: var(--bg);
  }

  .card > .blaettern {
    margin: 28px -22px -20px;
    padding-inline: 22px;
    border-radius: 0 0 var(--radius) var(--radius);
  }

  .blaettern .btn {
    flex: 1;
  }
}

.fragenliste {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.frage__kopf {
  display: flex;
  gap: 14px;
  align-items: baseline;
}

.frage__nummer {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--glass);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.frage__text {
  font-size: 1.08rem;
  margin: 0 0 4px;
}

.frage__erklaerung {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Uebungsaufgaben tragen keine Punkte und keine Wertung — die zurueckgenommene
   linke Kante sagt das, ohne dass ein Hinweistext je Karte noetig waere. */
.frage--uebung {
  border-left: 3px solid var(--accent2);
}

.antwortliste {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.antwort {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card2);
  font-size: 0.94rem;
}

.antwort--richtig {
  border-color: rgba(98, 229, 143, 0.35);
  background: rgba(98, 229, 143, 0.08);
}

.antwort__markierung {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--border);
}

.antwort--richtig .antwort__markierung {
  background: var(--success);
}

@media (max-width: 980px) {
  .kennwerte {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .leseansicht {
    grid-template-columns: minmax(0, 1fr);
  }

  .leseansicht__nav {
    display: none;
  }

  .lektionswahl {
    display: block;
  }
}

/* ── Fortschritt: Breite ohne Inline-Style ─────────────────────────────────── */
/* Die CSP kennt kein unsafe-inline, ein style="width:…" im Template ist damit
   ausgeschlossen. Die Breite kommt deshalb aus einer Regel je Fuenferstufe;
   server/domain/fortschritt.ts rundet den Anteil dafuer auf 5 % genau.

   Ohne diese Regeln hatte .progress-bar ueberhaupt keine width und stand immer
   voll — data-anteil wurde gesetzt, aber von niemandem gelesen. */

.progress-bar {
  width: 0;
  transition: width 0.3s ease;
}

.progress-bar[data-anteil='0'] {
  width: 0%;
}

.progress-bar[data-anteil='5'] {
  width: 5%;
}

.progress-bar[data-anteil='10'] {
  width: 10%;
}

.progress-bar[data-anteil='15'] {
  width: 15%;
}

.progress-bar[data-anteil='20'] {
  width: 20%;
}

.progress-bar[data-anteil='25'] {
  width: 25%;
}

.progress-bar[data-anteil='30'] {
  width: 30%;
}

.progress-bar[data-anteil='35'] {
  width: 35%;
}

.progress-bar[data-anteil='40'] {
  width: 40%;
}

.progress-bar[data-anteil='45'] {
  width: 45%;
}

.progress-bar[data-anteil='50'] {
  width: 50%;
}

.progress-bar[data-anteil='55'] {
  width: 55%;
}

.progress-bar[data-anteil='60'] {
  width: 60%;
}

.progress-bar[data-anteil='65'] {
  width: 65%;
}

.progress-bar[data-anteil='70'] {
  width: 70%;
}

.progress-bar[data-anteil='75'] {
  width: 75%;
}

.progress-bar[data-anteil='80'] {
  width: 80%;
}

.progress-bar[data-anteil='85'] {
  width: 85%;
}

.progress-bar[data-anteil='90'] {
  width: 90%;
}

.progress-bar[data-anteil='95'] {
  width: 95%;
}

.progress-bar[data-anteil='100'] {
  width: 100%;
}

/* ── Kacheln: Fassungen, Stufen, Lektionen ─────────────────────────────────── */
/* Loesen die Datentabellen ab, die vorher Modul- und Lektionslisten trugen. Eine
   Tabelle ist fuer Zahlenkolonnen richtig; ein Lernweg ist keine. */

.fassungen,
.stufen {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.fassung__kopf {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 16px;
}

.fassung__titel {
  font-size: 1.15rem;
  margin: 2px 0 0;
}

.fassung__titel a {
  color: var(--text);
  text-decoration: none;
}

.fassung__titel a:hover {
  color: var(--accent);
}

.fassung__zahlen {
  display: flex;
  gap: 28px;
  margin: 16px 0 0;
}

.fassung__zahlen div {
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
}

.fassung__zahlen dt {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text2);
}

.fassung__zahlen dd {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.fassung__fuss {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

/* Eine abgeloeste Fassung tritt zurueck: sie ist Bestandsdokumentation, kein Angebot. */
.fassung--retired {
  opacity: 0.68;
}

.fassung--draft {
  border-left: 3px solid var(--warn);
}

.fassung--active {
  border-left: 3px solid var(--success);
}

/* Die Stufe eines Lernpfads: Nummer, Inhalt, Aktion — in einer Zeile, damit der Weg
   von oben nach unten lesbar bleibt. */
.stufe {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 20px;
  align-items: center;
}

.stufe__nummer {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #fff;
  font-size: 1.15rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.stufe__titel {
  font-size: 1.12rem;
  margin: 2px 0 10px;
}

.stufe__inhalt .progress {
  max-width: 320px;
}

.stufe--gesperrt {
  opacity: 0.72;
}

.stufe--gesperrt .stufe__nummer {
  background: var(--card2);
  color: var(--text2);
  border: 1px solid var(--border);
}

.stufe--bestanden .stufe__nummer {
  background: linear-gradient(135deg, var(--success), #3fbf72);
  color: #06210f;
}

.lektionen {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lektion {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--text);
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.25s ease,
    transform 0.15s ease;
}

.lektion:hover {
  border-color: var(--accent);
  transform: translateX(2px);
}

.lektion__nummer {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text2);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.lektion__titel {
  flex: 1;
}

.lektion--gelesen .lektion__nummer {
  background: rgba(98, 229, 143, 0.14);
  border-color: rgba(98, 229, 143, 0.4);
  color: var(--success);
}

.pruefungskarte {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}

.pruefungskarte__text {
  flex: 1;
  min-width: 240px;
}

.leerstelle {
  text-align: center;
  padding: 44px 24px;
}

.leerstelle .btn-row {
  justify-content: center;
}

/* ── Bilder im Lernstoff ───────────────────────────────────────────────────── */
/* Sie kommen aus einem Inhaltspaket und werden unter /inhalt/bild/ ausgeliefert.
   Die Kanten bestimmt dieses Stylesheet, nicht das importierte Markdown — img traegt
   dort nur src, alt, width, height und loading. */

.prose img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 22px auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card2);
}

.prose figure {
  margin: 22px 0;
}

.prose figcaption {
  margin-top: 8px;
  text-align: center;
  font-size: 0.88rem;
  color: var(--text2);
}

@media (max-width: 680px) {
  .stufe {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .stufe__aktion {
    grid-column: 1 / -1;
  }

  .fassung__zahlen {
    gap: 20px;
  }
}

/* ── Ergebnis ──────────────────────────────────────────────────────────────── */

.ergebnis {
  display: grid;
  gap: 12px;
  justify-items: start;
}

.ergebnis--bestanden {
  border-left: 3px solid var(--success);
}

.ergebnis--gescheitert {
  border-left: 3px solid var(--fail);
}

.ergebnis__urteil {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ergebnis__zahl {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}

.ergebnis__zahl strong {
  font-size: 3rem;
  line-height: 1;
  font-weight: 600;
}

.ergebnis__zahl span {
  font-size: 1.2rem;
  color: var(--text2);
}

.antwortbilanz {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  counter-reset: bilanz;
}

.bilanz {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
}

.bilanz__markierung {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 999px;
}

.bilanz--richtig .bilanz__markierung {
  background: var(--success);
}

.bilanz--falsch .bilanz__markierung {
  background: var(--fail);
}

.bilanz__frage {
  flex: 1;
}

.bilanz__punkte {
  flex: none;
  font-variant-numeric: tabular-nums;
  color: var(--text2);
}

/* ── Antwortauswahl im Test ─────────────────────────────────────────────────
   Single Choice, Multiple Choice und Wahr/Falsch: jede Antwort ist eine Karte, die als
   Ganzes antippbar ist — auf dem Handy ist das der Hauptweg durch den Test. Kreis und
   Kästchen sind selbst gezeichnet (appearance: none), damit sie in jedem Browser gleich
   aussehen und die Akzentfarbe tragen. Gewählt wird über :checked, nicht über JavaScript. */
.auswahl {
  gap: 8px;
  margin-top: 14px;
}

.auswahl > .auswahl__option {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.45;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease,
    box-shadow 0.2s ease,
    transform 0.1s ease;
}

.auswahl > .auswahl__option:hover {
  border-color: rgba(139, 92, 246, 0.45);
  background: rgba(139, 92, 246, 0.06);
}

.auswahl > .auswahl__option:active {
  transform: scale(0.99);
}

.auswahl > .auswahl__option:has(input:checked) {
  border-color: var(--accent);
  background: rgba(139, 92, 246, 0.12);
  box-shadow:
    0 0 0 1px var(--accent),
    0 10px 28px -14px rgba(139, 92, 246, 0.7);
}

.auswahl__option input {
  appearance: none;
  flex: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin: 0;
  border: 2px solid var(--text2);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.auswahl__option input[type='checkbox'] {
  border-radius: 6px;
}

.auswahl__option input::after {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  transform: scale(0);
  transition: transform 0.18s cubic-bezier(0.3, 1.6, 0.5, 1);
}

.auswahl__option input[type='checkbox']::after {
  border-radius: 2px;
}

.auswahl__option input:checked {
  border-color: var(--accent);
}

.auswahl__option input:checked::after {
  transform: scale(1);
}

.auswahl__option input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ── Lückentext ─────────────────────────────────────────────────────────────
   Der Satz ist der Aufgabentext, die Felder stehen darin. Deshalb erbt er die
   Zeilenhöhe eines Fließtextes und nicht die eines Formulars: die Felder sollen
   sich einfügen, nicht den Satz zerreißen.

   Alle Lücken sind gleich breit. Die Breite aus der erwarteten Antwort abzuleiten
   wäre ein Hinweis auf die Lösung — bei „VPN" gegenüber
   „Zwei-Faktor-Authentisierung" ein sehr deutlicher. */
.cloze {
  line-height: 2.4;
  font-size: 1.02rem;
  max-width: var(--prose-max);
}

.cloze__luecke {
  width: 11rem;
  padding: 4px 10px;
  margin: 0 2px;
  border: 1px solid var(--border);
  border-bottom: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
}

.cloze__luecke:focus-visible {
  background: var(--card2);
}

/* Der Lückensatz in der Verwaltungsvorschau: derselbe Satz, aber mit den
   eingesetzten Lösungen in eckigen Klammern statt mit Eingabefeldern. */
.lueckensatz {
  line-height: 1.9;
  font-size: 1rem;
  max-width: var(--prose-max);
  margin-bottom: 10px;
}

/* ── Wortzähler der Stichwortantwort ────────────────────────────────────────
   Er zeigt an und entscheidet nicht: bewertet wird ausschließlich serverseitig.
   Rot wird er erst, wenn eine Mindestwortzahl gilt und noch nicht erreicht ist —
   ohne Mindestzahl ist keine Wortzahl falsch. */
.zaehler {
  font-size: 0.8rem;
  color: var(--text2);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.zaehler--zuwenig {
  color: var(--warn);
}

/* ── Licht und Bewegung ──────────────────────────────────────────────────────
   Glaskarten, Leuchtrand, Einblenden und Fortschrittsschimmer (TB-202). Hintergrund-Glow und das
   Überblenden zwischen Seiten stehen in base.css, Begründung und Grenzen in
   assets/concepts/oberflaeche.md. „Bewegung reduzieren“ schaltet alles ab (Block am Ende). */

/* Glas: Karten lassen den Glow leicht durchscheinen. Die Unschärfe dahinter erst ab 821 px —
   backdrop-filter auf vielen Karten bremst ältere Handys, und dort bleibt die Kopfleiste
   deckend (siehe „Schmale Ansicht“). */
.card,
.topic-card,
.lektion,
.bilanz {
  background: var(--card-glas);
}

@media (min-width: 821px) {
  .card,
  .topic-card,
  .lektion,
  .bilanz {
    backdrop-filter: blur(14px) saturate(120%);
  }

  .sidebar {
    background: var(--sidebar-glas);
    backdrop-filter: blur(18px);
  }
}

/* Leuchtrand auf Kacheln, hinter denen eine Aktion liegt. Als Schatten statt Randfarbe, damit
   die farbige linke Kante von Fassungen und Stufen erhalten bleibt. */
.stufe,
.fassung,
.kennwert,
.topic-card {
  transition:
    box-shadow 0.25s ease,
    transform 0.2s ease;
}

:is(.lektion, .stufe, .fassung, .kennwert, .topic-card):hover {
  box-shadow:
    0 0 0 1px var(--leuchtrand),
    0 14px 36px -18px rgba(139, 92, 246, 0.55);
}

.topic-card:hover {
  transform: translateY(-2px);
}

.btn:active:not(:disabled) {
  transform: scale(0.97);
}

.btn-primary {
  box-shadow: 0 8px 22px -10px rgba(139, 92, 246, 0.8);
}

.btn-primary:hover {
  box-shadow: 0 10px 30px -10px rgba(139, 92, 246, 1);
}

/* Einblenden: der Inhalt gleitet beim Laden gestaffelt ein. Nur backwards — nach dem Ende
   bleibt kein transform stehen, das sticky- oder fixed-Elemente aus der Bahn brächte. */
.content > *,
.public-layout main > * {
  animation: auftauchen 0.45s var(--kurve-weich) backwards;
}

.content > :nth-child(2),
.public-layout main > :nth-child(2) {
  animation-delay: 0.06s;
}

.content > :nth-child(3),
.public-layout main > :nth-child(3) {
  animation-delay: 0.12s;
}

.content > :nth-child(n + 4),
.public-layout main > :nth-child(n + 4) {
  animation-delay: 0.18s;
}

@keyframes auftauchen {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* Die Seitenleiste bekommt beim Überblenden einen eigenen Namen und steht damit still,
   während der Inhalt wechselt. */
.sidebar {
  view-transition-name: seitenleiste;
}

/* Fortschrittsbalken laufen beim Laden hoch, ein Schimmer zieht in Abständen darüber. */
.progress-bar {
  position: relative;
  overflow: hidden;
  transform-origin: left;
  animation: fortschritt-fuellen 0.9s var(--kurve-weich) backwards;
}

.progress-bar::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: translateX(-100%);
  animation: schimmer 3.2s ease-in-out infinite;
}

@keyframes fortschritt-fuellen {
  from {
    transform: scaleX(0);
  }
}

@keyframes schimmer {
  60%,
  100% {
    transform: translateX(100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .content > *,
  .public-layout main > *,
  .progress-bar,
  .progress-bar::after {
    animation: none;
  }
}

/* ── KI-Anbindung (TB-209) ──────────────────────────────────────────────────── */

.ki-liste {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-left: 1.2em;
  color: var(--text2);
}

.ki-zugaenge {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0;
  list-style: none;
}

.ki-zugaenge li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.ki-schritte {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-left: 1.4em;
}

.ki-schritte h3 {
  margin-bottom: 4px;
  font-size: 1rem;
}

/* Lange Befehle brechen sichtbar um; kopiert wird trotzdem eine Zeile (textContent). */
.befehl {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin-top: 10px;
}

.befehl pre {
  width: 100%;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card2);
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.befehl__kopieren {
  padding: 6px 14px;
  font-size: 0.85rem;
}

/* .btn setzt display und überstimmt damit das hidden-Attribut. */
.befehl__kopieren[hidden] {
  display: none;
}
