/* ============================================================
   Lernspiegel – Hauptstylesheet
   Font: Montserrat | Design: Modern & Professional
   ============================================================ */

:root {
  /* Höhe der klebenden Topbar. Alles, was darunter klebt (Benachrichtigungen,
     Sprungleisten), rechnet damit; auf Mobile wird sie im @media-Block erhöht,
     weil dort der Seitentitel eine eigene Zeile bekommt. */
  --topbar-h:      64px;
  --primary:       #1E3A5F;
  --primary-light: #2D5480;
  --primary-xlight:#EFF4FA;
  --accent:        #3B82F6;
  --accent-light:  #DBEAFE;
  --tooltip-bg:     #111827;
  --tooltip-text:   #F9FAFB;
  --tooltip-border: rgba(255,255,255,.10);
  --success:       #22C55E;
  --success-light: #DCFCE7;
  --warning:       #F97316;
  --warning-light: #FEF3C7;
  --danger:        #EF4444;
  --danger-light:  #FEE2E2;
  --neutral:       #9CA3AF;
  --neutral-light: #F3F4F6;

  --text-primary:  #111827;
  --text-secondary:#374151;
  --text-muted:    #6B7280;
  --text-light:    #9CA3AF;

  --bg-app:        #F1F5F9;
  --bg-card:       #FFFFFF;
  --bg-sidebar:    #1E3A5F;
  --sidebar-width: 260px;

  --border:        #E5E7EB;
  --border-focus:  #3B82F6;

  --radius-sm:  6px;
  --radius:     10px;
  --radius-lg:  16px;
  --radius-xl:  24px;

  --shadow-sm:  0 1px 3px rgba(0,0,0,.08);
  --shadow:     0 4px 12px rgba(0,0,0,.08);
  --shadow-lg:  0 8px 30px rgba(0,0,0,.12);

  --transition: 200ms ease;
  --font: 'Montserrat', sans-serif;

  /* Aliase für rückwärtskompatible Varianten-Namen */
  --shadow-md: var(--shadow);
  --card-bg:   var(--bg-card);
  --hover-bg:  var(--neutral-light);
  --text:      var(--text-primary);
  --bg:        var(--bg-card);

  /* Helle Tints, die bisher nur als Inline-Fallback existierten – hier zentral,
     damit der Dark-Block sie überschreiben kann. */
  --bg-app-soft: #F8FAFC;
  --bg-subtle:   #F9FAFB;
  --input-bg:    #FFFFFF;

  /* Aliase für abweichende Variablennamen in einzelnen Seiten. Lösen auf
     theme-fähige Tokens auf, statt auf helle Inline-Fallbacks zurückzufallen
     (sonst blieben diese Stellen im Dark Mode hell). */
  --color-border:       var(--border);
  --border-color:       var(--border);
  --color-bg-secondary: var(--neutral-light);
  --bg-secondary:       var(--neutral-light);
  --color-warning:      var(--warning);
  --warning-bg:         var(--warning-light);
  --color-primary:      var(--primary);
  --color-info:         var(--accent);
  --color-danger:       var(--danger);
  --color-text-muted:   var(--text-muted);
}

/* ── Dark Mode ─────────────────────────────────────────────────────────────
   Überschreibt die Design-Tokens. Alles, was die Variablen nutzt (Layout-
   Shell, Sidebar, Topbar, Cards, Tabellen, Formulare, Buttons, Modals), wird
   damit automatisch dunkel. Inline-hartkodierte Farben werden schrittweise
   pro Seite nachgezogen. */
[data-theme="dark"] {
  --primary:       #4B7BB8;
  --primary-light: #5B8BC8;
  --primary-xlight:#16263B;
  --accent:        #60A5FA;
  --accent-light:  #1E3A5F;
  --tooltip-bg:     #E5E7EB;
  --tooltip-text:   #111827;
  --tooltip-border: rgba(0,0,0,.12);
  --success:       #4ADE80;
  --success-light: #14331F;
  --warning:       #FB923C;
  --warning-light: #3A2A12;
  --danger:        #F87171;
  --danger-light:  #3A1A1A;
  --neutral:       #94A3B8;
  --neutral-light: #1E293B;

  --text-primary:  #F1F5F9;
  --text-secondary:#CBD5E1;
  --text-muted:    #94A3B8;
  --text-light:    #64748B;

  --bg-app:        #0F172A;
  --bg-card:       #1E293B;
  --bg-sidebar:    #0B1220;

  --border:        #334155;
  --border-focus:  #60A5FA;

  --shadow-sm:  0 1px 3px rgba(0,0,0,.5);
  --shadow:     0 4px 14px rgba(0,0,0,.55);
  --shadow-lg:  0 8px 30px rgba(0,0,0,.6);

  --hover-bg:      #243247;
  --bg-app-soft:   #172033;
  --bg-subtle:     #172033;
  --input-bg:      #0F172A;
}

/* color-scheme informiert Browser-UI (Scrollbars, Form-Controls) */
[data-theme="dark"] { color-scheme: dark; }

/* Topbar-Schalter Hell/Dunkel */
.topbar-theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border: none; background: transparent;
  color: var(--text-muted); border-radius: 8px; cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.topbar-theme-toggle:hover { background: var(--hover-bg); color: var(--text-primary); }
.topbar-theme-toggle .theme-icon-sun { display: none; }
.topbar-theme-toggle .theme-icon-moon { display: block; }
[data-theme="dark"] .topbar-theme-toggle .theme-icon-moon { display: none; }
[data-theme="dark"] .topbar-theme-toggle .theme-icon-sun { display: block; }

/* Profil: Erscheinungsbild-Auswahl */
.theme-choice { display: flex; gap: .75rem; flex-wrap: wrap; }
.theme-option {
  flex: 1 1 180px; display: flex; align-items: center; gap: .75rem;
  padding: 1rem 1.25rem; border: 2px solid var(--border); border-radius: var(--radius-lg);
  background: var(--bg-card); cursor: pointer; transition: all var(--transition);
  font-family: var(--font); font-size: .875rem; font-weight: 600; color: var(--text-secondary);
}
.theme-option:hover { border-color: var(--accent); background: var(--accent-light); }
.theme-option.is-active { border-color: var(--accent); background: var(--accent-light); color: var(--text-primary); }
.theme-option svg { flex-shrink: 0; color: var(--text-muted); }
.theme-option.is-active svg { color: var(--accent); }

/* Ankündigungs-Banner/Popup – theme-fähige Tints (Inline nutzt var(--ann-*)) */
.ann-style-info    { --ann-bg: var(--accent-light);  --ann-border: var(--accent);  --ann-ink: #1E3A5F; }
.ann-style-success { --ann-bg: var(--success-light); --ann-border: var(--success); --ann-ink: #14532D; }
.ann-style-warning { --ann-bg: var(--warning-light); --ann-border: var(--warning); --ann-ink: #78350F; }
.ann-style-error   { --ann-bg: var(--danger-light);  --ann-border: var(--danger);  --ann-ink: #7F1D1D; }
[data-theme="dark"] .ann-style-info    { --ann-ink: #BFDBFE; }
[data-theme="dark"] .ann-style-success { --ann-ink: #BBF7D0; }
[data-theme="dark"] .ann-style-warning { --ann-ink: #FDE68A; }
[data-theme="dark"] .ann-style-error   { --ann-ink: #FECACA; }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* scrollbar-gutter: reserviert dauerhaft Platz für die vertikale Scrollleiste,
   damit die Seitenbreite beim Navigieren nicht um die Scrollbalken-Breite
   springt (Desktop-Flackern). Auf Mobile (Overlay-Scrollbars) wirkungslos. */
html { font-size: 16px; scrollbar-gutter: stable; }
body { font-family: var(--font); background: var(--bg-app); color: var(--text-primary); line-height: 1.6; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; }

/* ============================================================
   APP LAYOUT
   ============================================================ */
.app-wrapper { display: flex; min-height: 100vh; }

/* ============================================================
   SIDEBAR
   ============================================================ */
.sidebar {
  width: var(--sidebar-width);
  background: var(--bg-sidebar);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 100;
  transition: transform var(--transition);
  overflow-y: auto;
  scrollbar-width: auto;
  scrollbar-color: rgba(255,255,255,.18) transparent;
}
.sidebar::-webkit-scrollbar-track,
.sidebar-collapsed .sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb,
.sidebar-collapsed .sidebar-nav::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.18);
  border-radius: 4px;
}
.sidebar::-webkit-scrollbar-thumb:hover,
.sidebar-collapsed .sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.3); }
.sidebar-collapsed .sidebar-nav {
  scrollbar-width: auto;
  scrollbar-color: rgba(255,255,255,.18) transparent;
}
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem 1.25rem 1rem;
  border-bottom: 1px solid rgba(255,255,255,.1);
}
.sidebar-logo { display: flex; align-items: center; gap: .75rem; }
.logo-icon {
  width: 36px; height: 36px;
  background: var(--accent);
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.1rem; color: #fff;
  flex-shrink: 0;
}
.logo-title { display: block; color: #fff; font-weight: 700; font-size: .95rem; line-height: 1.2; }
.logo-sub   { display: block; color: rgba(255,255,255,.5); font-size: .7rem; font-weight: 500; text-transform: uppercase; letter-spacing: .05em; }
.sidebar-close { display: none; background: none; border: none; color: rgba(255,255,255,.5); cursor: pointer; font-size: 1.5rem; padding: .25rem; }

.sidebar-nav { flex: 1; padding: .75rem 0; }

.nav-group-label {
  /* Abstufung zu den Einträgen darunter, auf mehreren Ebenen gleichzeitig:
     kleinere Schrift (11 px zu 14 px), dafür Versalien, mehr Sperrung und ein
     eigenes Symbol in Blau. Der Titel bleibt so als Kopfzeile erkennbar, ohne
     den Einträgen die Aufmerksamkeit wegzunehmen. */
  padding: .9rem 1.25rem .3rem;
  font-size: .6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: rgba(255,255,255,.85);
}
/* Symbol + Titel bleiben zusammen, der Pfeil sitzt weiterhin rechts aussen. */
.nav-group-title { display: inline-flex; align-items: center; gap: .5rem; min-width: 0; }
.nav-group-title > span { overflow: hidden; text-overflow: ellipsis; }
/* Bewusst ein helles Blau statt Weiss: Es setzt den Bereichstitel farblich von
   den grauweissen Einträgen ab. Deutlich kleiner als die 18 px der Einträge
   und mit feinerer Linie, damit auch die Symbole abgestuft sind. */
.nav-group-icon { display: inline-flex; flex-shrink: 0; color: rgba(147,197,253,.9); }
.nav-group-icon svg { width: 13px; height: 13px; stroke-width: 2.25; }
.nav-group-chevron svg { width: 11px; height: 11px; }
/* Einträge einer Gruppe rücken leicht ein: die dritte Stufe der Abstufung. */
.nav-group-items .nav-item { padding-left: 1.6rem; }
/* Favoriten tragen den Seitentitel, der bei Detailseiten den Set-Namen enthält
   und entsprechend lang wird: eine Zeile, Rest als «…», voller Text im Tooltip. */
.nav-group[data-gruppe="favoriten"] .nav-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
/* Auf- und zuklappbare Bereiche (gleicher Schalter wie die Filterleiste).
   Der Titel wird zum Knopf, behält aber seine Typografie. */
button.nav-group-label {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; background: none; border: 0; font-family: var(--font);
  /* Trefferfläche fürs Tippen: mindestens 38 px hoch. */
  min-height: 38px;
  cursor: pointer; text-align: left;
  transition: color var(--transition);
}
button.nav-group-label:hover { color: rgba(255,255,255,.95); }
button.nav-group-label:hover .nav-group-icon { color: #BFDBFE; }
button.nav-group-label:focus-visible { outline: 2px solid rgba(255,255,255,.5); outline-offset: -2px; }
/* Bereich, in dem die aktuelle Seite liegt: Titel in Weiss, helleres Symbol und
   derselbe Akzentbalken wie beim aktiven Eintrag. Bewusst nur die Kopfzeile und
   nicht die ganze Gruppe, sonst überstrahlt die Fläche den aktiven Eintrag. */
.nav-group--aktiv > .nav-group-label {
  color: #fff;
  box-shadow: inset 3px 0 0 var(--accent);
  background: rgba(96,165,250,.32);
  /* Polster symmetrisch, sonst sässe der Titel in der Fläche zu tief. Die
     Differenz zum sonst ungleichen Polster (.9rem/.3rem) fangen die
     Aussenabstände auf: Die Zeile bleibt 38 px hoch und der Titel steht auf
     derselben Höhe wie die Titel ohne Fläche. */
  padding-top: .6rem;
  padding-bottom: .6rem;
  margin-top: .3rem;
}
/* Zugeklappt folgt der nächste Bereichstitel: Der zusätzliche Platz wird unten
   wieder abgezogen, damit die Titel im gleichen Raster stehen wie sonst. Offen
   folgt der erste Eintrag, dort bleiben die 4.8 px als Abstand zur Fläche. */
.nav-group--aktiv.is-zu > .nav-group-label { margin-bottom: -.3rem; }
.nav-group--aktiv > .nav-group-label .nav-group-icon { color: #BFDBFE; }
.nav-group-chevron { display: inline-flex; transition: transform .15s ease; }
.nav-group.is-zu .nav-group-chevron { transform: rotate(-90deg); }
.nav-group.is-zu .nav-group-items { display: none; }
.nav-item {
  display: flex;
  align-items: center;
  gap: .75rem;
  /* 40 px pro Zeile: kompakt genug für lange Navigationen (als Admin über 60
     Einträge) und im Verhältnis zum 38 px hohen Bereichstitel. Auf Touch-
     Geräten wird weiter unten wieder auf 45 px aufgepolstert. */
  padding: .55rem 1.25rem;
  color: rgba(255,255,255,.7);
  font-weight: 500;
  font-size: .875rem;
  transition: background var(--transition), color var(--transition);
  border-left: 3px solid transparent;
  cursor: pointer;
  text-decoration: none;
}
.nav-item:hover { background: rgba(255,255,255,.08); color: #fff; text-decoration: none; }
.nav-item.active { background: rgba(255,255,255,.12); color: #fff; border-left-color: var(--accent); }
.nav-icon { flex-shrink: 0; opacity: .8; display: flex; align-items: center; }
.nav-item.active .nav-icon { opacity: 1; }
.nav-item.nav-logout { color: rgba(255,255,255,.5); margin-top: auto; }
.nav-item.nav-logout:hover { color: var(--danger); background: rgba(239,68,68,.1); }
.sidebar-footer { padding: .5rem 0 1rem; border-top: 1px solid rgba(255,255,255,.1); }
/* PRO-Abzeichen erscheint nur noch bei gesperrten Einträgen, dort aber deutlich. */
.nav-pro-badge {
  margin-left: auto; font-size: .6rem; font-weight: 700;
  padding: .1rem .35rem; border-radius: 6px; white-space: nowrap;
  background: linear-gradient(135deg,#3B82F6,#8B5CF6); color: #fff;
}
/* Favoriten-Stern in der Topbar: gehört zum Seitentitel, nicht zu den Werkzeugen
   rechts, weil er sich auf genau diese Seite bezieht. */
.fav-form { display: flex; align-items: center; }
.fav-btn {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  background: none; border: 0; border-radius: var(--radius-sm);
  color: var(--text-muted); cursor: pointer;
  transition: color var(--transition), background var(--transition);
}
.fav-btn:hover { color: var(--warning, #F59E0B); background: var(--bg-app); }
.fav-btn.is-fav { color: var(--warning, #F59E0B); }
.fav-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 640px) { .fav-btn { width: 30px; height: 30px; } }
/* Mit dem Finger bedient (Handy, Tablet, Touch-Notebook): zurück auf 45 px
   Zeilenhöhe, damit die Trefferflächen die empfohlenen 44 px halten. Mit der
   Maus bleibt es bei den kompakteren 40 px. */
@media (pointer: coarse) {
  .nav-item { padding: .7rem 1.25rem; }
  .nav-group-items .nav-item { padding-left: 1.6rem; }
}

.sidebar-header-actions { display: flex; align-items: center; gap: .25rem; }
.sidebar-collapse-btn {
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: rgba(255,255,255,.4);
  cursor: pointer; padding: .3rem; border-radius: var(--radius-sm);
  transition: color var(--transition), background var(--transition);
  flex-shrink: 0;
}
.sidebar-collapse-btn:hover { color: #fff; background: rgba(255,255,255,.1); }

/* Collapsed state – hook on app-wrapper */
.sidebar-collapsed .sidebar { width: 56px; overflow: visible; }
.sidebar-collapsed .sidebar-nav { overflow-y: auto; overflow-x: hidden; min-height: 0; }
.sidebar-collapsed .logo-text,
.sidebar-collapsed .nav-label,
.sidebar-collapsed .nav-pro-badge { display: none; }
.sidebar-collapsed .nav-group-label {
  height: 1px;
  margin: .5rem .75rem;
  padding: 0;
  background: rgba(255,255,255,.12);
  overflow: hidden;
  font-size: 0;
}
/* Symbol-Modus: Dort gibt es keine Gruppentitel, also auch nichts zum
   Zuklappen. Die Einträge bleiben sichtbar, sonst wären sie unerreichbar. */
.sidebar-collapsed .nav-group-chevron,
.sidebar-collapsed .nav-group-icon { display: none; }
.sidebar-collapsed .nav-group.is-zu .nav-group-items { display: block; }
/* Im Symbol-Modus ist der Titel nur noch eine dünne Trennlinie: Die
   Trefferfläche von 38 px würde sie zu einem Block aufblasen. */
.sidebar-collapsed button.nav-group-label { cursor: default; pointer-events: none; min-height: 0; }
/* Im Symbol-Modus ist der Titel nur eine Linie: Akzentbalken und Fläche haben
   dort nichts zu suchen. */
.sidebar-collapsed .nav-group--aktiv > .nav-group-label {
  box-shadow: none;
  background: rgba(255,255,255,.12);
  padding: 0;
  margin: .5rem .75rem;
}
.sidebar-collapsed .nav-item,
.sidebar-collapsed .nav-group-items .nav-item { justify-content: center; padding: .65rem; border-left: 3px solid transparent; }
.sidebar-collapsed .nav-item.active { border-left-color: var(--accent); }
.sidebar-collapsed .nav-item:hover { background: rgba(255,255,255,.08); }
.sidebar-collapsed .sidebar-header {
  padding: .75rem .5rem;
  flex-direction: column;
  justify-content: center;
  gap: .5rem;
}
.sidebar-collapsed .sidebar-logo { justify-content: center; }
.sidebar-collapsed .sidebar-header-actions { justify-content: center; }
.sidebar-collapsed .sidebar-collapse-btn svg { transform: rotate(180deg); }
.sidebar-collapsed .main-content { margin-left: 56px; max-width: calc(100vw - 56px); }
.sidebar-collapsed .nav-item { position: relative; }
/* Tooltip wird per JS als position:fixed Element angezeigt (siehe app.js),
   damit es nicht vom overflow-y:auto der Sidebar abgeschnitten wird. */
.sidebar-nav-tooltip {
  position: fixed; z-index: 200; pointer-events: none;
  background: rgba(0,0,0,.85); color: #fff;
  padding: .3rem .65rem; border-radius: var(--radius-sm);
  font-size: .8rem; white-space: nowrap;
  opacity: 0; transition: opacity .12s;
}
.sidebar-nav-tooltip.visible { opacity: 1; }

/* ============================================================
   MAIN CONTENT
   ============================================================ */
.main-content {
  flex: 1;
  min-width: 0;
  margin-left: var(--sidebar-width);
  max-width: calc(100vw - var(--sidebar-width));
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* ============================================================
   TOPBAR
   ============================================================ */
.topbar {
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  padding: 0 2rem;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 50;
  box-shadow: var(--shadow-sm);
}
.topbar-left { display: flex; align-items: center; gap: 1rem; }
/* Seitentitel und Favoriten-Stern gehören zusammen: der Stern bezieht sich auf
   genau diese Seite. Auf schmalen Bildschirmen wandert das Paar in eine eigene
   Zeile (siehe @media weiter unten). */
.topbar-page { display: flex; align-items: center; gap: .15rem; min-width: 0; }
.sidebar-toggle {
  display: none;
  flex-direction: column;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  padding: .4rem;
}
.sidebar-toggle span { width: 22px; height: 2px; background: var(--text-secondary); border-radius: 2px; display: block; }
.page-title { font-size: 1.1rem; font-weight: 700; color: var(--text-primary); }
.topbar-right { display: flex; align-items: center; gap: .375rem; }

/* Globale Suche */
.topbar-search { position: relative; flex: 1 1 400px; max-width: 500px; }
.search-input-wrap { position: relative; display: flex; align-items: center; }
.search-icon { position: absolute; left: .6rem; color: var(--text-muted); pointer-events: none; }
.search-input {
  width: 100%; padding: .45rem .6rem .45rem 2rem; font-size: .85rem;
  border: 1.5px solid var(--border); border-radius: var(--radius);
  background: var(--bg-app); color: var(--text-primary);
  font-family: var(--font); outline: none; transition: border-color var(--transition);
}
.search-input:focus { border-color: var(--accent); }
.search-kbd {
  position: absolute; right: .5rem; font-size: .65rem; font-family: var(--font);
  padding: .15rem .4rem; border-radius: 4px; background: var(--bg-app);
  border: 1px solid var(--border); color: var(--text-muted); pointer-events: none;
}
.search-input:focus ~ .search-kbd { display: none; }
.search-close-btn {
  display: none; position: absolute; right: .4rem; background: none; border: none;
  font-size: 1.2rem; color: var(--text-muted); cursor: pointer; padding: .2rem .4rem; line-height: 1;
}
.search-toggle-btn {
  display: none; background: none; border: none; cursor: pointer;
  color: var(--text-secondary); padding: .4rem;
}
.search-toggle-btn:hover { color: var(--text-primary); }
/* Auf breiten Bildschirmen ist der Knopf nur ein Symbol (und ohnehin aus). */
.search-toggle-label { display: none; }
.search-dropdown {
  display: none; position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--bg-card); border: 1.5px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  max-height: 360px; overflow-y: auto; z-index: 200;
}
.search-dropdown.open { display: block; }
.search-group-label {
  font-size: .65rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted); padding: .6rem .75rem .25rem;
  display: flex; align-items: center; justify-content: space-between;
}
.search-clear-recents {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 1rem; line-height: 1;
  padding: .15rem .35rem; border-radius: 4px;
  text-transform: none; letter-spacing: 0;
}
.search-clear-recents:hover { background: var(--accent-light); color: var(--text-primary); }
.search-row { display: flex; align-items: center; }
.search-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem .75rem; cursor: pointer; text-decoration: none;
  flex: 1; min-width: 0;
  color: var(--text-primary); font-size: .85rem; transition: background .1s;
}
.search-row:hover, .search-item.active,
.search-item.active + .search-actions { background: var(--accent-light); }
/* Zusatzziele eines Treffers: nur beim Treffer unter dem Zeiger bzw. beim mit
   den Pfeiltasten gewählten, damit die Liste zum Überfliegen ruhig bleibt. */
.search-actions { display: none; gap: .3rem; padding-right: .6rem; flex-shrink: 0; }
.search-row:hover .search-actions,
.search-item.active + .search-actions { display: flex; }
.search-action {
  padding: .22rem .5rem; border: 1px solid var(--border); border-radius: 999px;
  background: var(--bg-card); color: var(--text-secondary);
  font-size: .72rem; font-weight: 600; text-decoration: none; white-space: nowrap;
  transition: border-color .12s, color .12s;
}
.search-action:hover { border-color: var(--primary); color: var(--primary); }
[data-theme="dark"] .search-action:hover { border-color: var(--accent); color: var(--accent); }
.search-item-icon {
  width: 28px; height: 28px; border-radius: 6px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: .8rem;
}
.search-item-text { flex: 1; min-width: 0; }
.search-item-label { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-item-label mark, .search-item-sub mark { background: #FEF3C7; color: inherit; padding: 0 .1em; border-radius: 2px; font-weight: 700; }
[data-theme="dark"] .search-item-label mark, [data-theme="dark"] .search-item-sub mark { background: rgba(251,191,36,.28); }
.search-item-sub { font-size: .75rem; color: var(--text-muted); }
.search-all-link {
  display: block; padding: .6rem 1rem; text-align: center;
  font-size: .82rem; font-weight: 600; text-decoration: none;
  color: var(--primary, #1E3A5F); border-top: 1px solid var(--border, #e5e7eb);
  background: var(--bg-app, #f8fafc);
  /* Am unteren Rand des scrollbaren Dropdowns fixieren, damit der Link
     beim Scrollen der Trefferliste sichtbar bleibt. */
  position: sticky; bottom: 0;
}
.search-all-link:hover { background: var(--bg-secondary, #f1f5f9); }
.search-empty { padding: 1.25rem 1rem; text-align: center; color: var(--text-muted); }
.search-empty-title { font-size: .9rem; font-weight: 600; color: var(--text-primary); margin-bottom: .35rem; }
.search-empty-tips { font-size: .8rem; line-height: 1.5; }
@media (max-width: 768px) {
  .search-toggle-btn { display: flex; }
  .topbar-search {
    display: none; position: fixed; top: 0; left: 0; right: 0;
    z-index: 200; background: var(--bg-card); padding: .75rem;
    box-shadow: var(--shadow-md); max-width: 100%;
  }
  .topbar-search.open { display: block; }
  .topbar-search.open .search-input { font-size: .95rem; padding: .6rem .6rem .6rem 2.2rem; }
  .topbar-search.open .search-close-btn { display: block; }
  .search-kbd { display: none; }
  .search-dropdown { position: fixed; left: .5rem; right: .5rem; top: auto; max-height: 60vh; }
  .search-item { padding: .65rem .85rem; font-size: .9rem; }
  /* Auf dem Handy fehlt in der Vorschlagsliste der Platz dafür; die Zusatzziele
     stehen dort auf der Ergebnisseite /suche. */
  .search-actions { display: none !important; }
  .search-item-icon { width: 32px; height: 32px; font-size: .9rem; }
  .search-item-sub { font-size: .78rem; }
  .search-group-label { font-size: .7rem; padding: .7rem .85rem .3rem; }
}

.topbar-notification {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  color: var(--text-secondary);
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
  flex-shrink: 0;
}
.topbar-notification:hover { background: var(--neutral-light); color: var(--primary); }
.topbar-notification svg { display: block; }
.notification-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 99px;
  background: var(--danger);
  color: #fff;
  font-size: .65rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

.user-menu { position: relative; display: flex; align-items: center; gap: .75rem; cursor: pointer; padding: .4rem .6rem; border-radius: var(--radius); transition: background var(--transition); }
.user-menu:hover, .user-menu:focus { background: var(--neutral-light); outline: none; }
.user-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: .9rem; flex-shrink: 0; }
.user-info { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.user-name { font-weight: 600; font-size: .85rem; display: block; max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role-badge { font-size: .65rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; padding: .2rem .6rem; border-radius: 99px; }
.user-role-badge.role-admin { color: var(--danger); }
.user-role-badge.role-schulhaus_admin { color: #7C3AED; }
.user-role-badge.role-class_teacher { color: var(--accent); }
.user-role-badge.role-subject_teacher { color: var(--success); }
/* Einzeilig: Umgebrochen stapelten sich Name, Rolle und Pro-Abzeichen zwischen 961
   und etwa 1180 px über die ganze Topbar-Höhe; die Suche gibt stattdessen Platz ab. */
.user-badges { display: flex; align-items: center; gap: .35rem; flex-wrap: nowrap; white-space: nowrap; }
.badge-pro  { background: linear-gradient(135deg, #3B82F6, #8B5CF6); color: #fff; font-weight: 700; }
.badge-free { background: var(--neutral-light); color: var(--text-muted); }

.user-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + .5rem);
  right: 0;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  min-width: 160px;
  overflow: hidden;
  z-index: 200;
}
.user-menu:focus .user-dropdown, .user-menu:focus-within .user-dropdown, .user-menu.open .user-dropdown { display: block; }
.dropdown-item { display: block; padding: .65rem 1rem; font-size: .875rem; color: var(--text-secondary); transition: background var(--transition); }
.dropdown-item:hover { background: var(--neutral-light); color: var(--text-primary); text-decoration: none; }
.dropdown-danger:hover { background: var(--danger-light); color: var(--danger); }

/* Benachrichtigungs-Glocke (Nutzer) + Dropdown */
.notif-menu { position: relative; display: flex; align-items: center; border-radius: var(--radius); outline: none; cursor: pointer; }
.notif-menu .topbar-notification { cursor: pointer; }
.notif-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + .5rem);
  right: 0;
  width: 340px;
  max-width: calc(100vw - 2rem);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  z-index: 200;
}
.notif-menu:focus .notif-dropdown, .notif-menu:focus-within .notif-dropdown, .notif-menu.open .notif-dropdown { display: block; }
.notif-dropdown-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .6rem .85rem; border-bottom: 1px solid var(--border); }
.notif-dropdown-title { font-weight: 700; font-size: .85rem; color: var(--text-primary); }
.notif-markall-form { margin: 0; }
.notif-markall-btn { background: none; border: none; color: var(--primary); font-family: var(--font); font-size: .78rem; font-weight: 600; cursor: pointer; padding: .1rem .2rem; }
.notif-markall-btn:hover { text-decoration: underline; }
.notif-list { max-height: 380px; overflow-y: auto; }
.notif-item { display: flex; align-items: flex-start; gap: .25rem; border-bottom: 1px solid var(--border); }
.notif-item:last-child { border-bottom: none; }
.notif-item-link { display: flex; align-items: flex-start; gap: .6rem; padding: .7rem .85rem; flex: 1 1 auto; min-width: 0; text-decoration: none; }
.notif-item-link:hover { background: var(--neutral-light); text-decoration: none; }
.notif-item-icon { color: var(--primary); flex-shrink: 0; margin-top: .1rem; display: flex; }
.notif-item-text { display: flex; flex-direction: column; min-width: 0; }
.notif-item-title { font-size: .83rem; font-weight: 600; color: var(--text-primary); }
.notif-item-body { font-size: .78rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-item-time { font-size: .72rem; color: var(--text-muted); margin-top: .15rem; }
.notif-item-read { margin: 0; display: flex; align-self: stretch; align-items: center; padding: 0 .5rem; }
.notif-item-read button { background: none; border: none; color: var(--text-muted); font-family: var(--font); cursor: pointer; padding: .35rem; border-radius: var(--radius); display: flex; transition: background var(--transition), color var(--transition); }
.notif-item-read button:hover { background: var(--success-light); color: var(--success); }

/* Mobile: Dropdown ans Viewport pinnen (volle Breite mit Rand), statt per
   right:0 an der Glocke zu hängen und links/rechts aus dem Bild zu ragen.
   MUSS nach der Basisregel oben stehen – gleiche Spezifität, Quell-Reihenfolge
   entscheidet, sonst überschreibt die Basisregel position/width wieder. */
@media (max-width: 768px) {
  .notif-dropdown {
    position: fixed; top: var(--topbar-h); right: .5rem; left: .5rem;
    width: auto; max-width: none;
  }
  .notif-list { max-height: min(60vh, 380px); }
}

/* ============================================================
   PAGE CONTENT
   ============================================================ */
.page-content { flex: 1; padding: 2rem; }
.page-footer { padding: .75rem 2rem; font-size: .75rem; color: var(--text-muted); border-top: 1px solid var(--border); background: var(--bg-card); display: flex; flex-direction: column; gap: 0; }
.page-actions { display: flex; justify-content: flex-end; margin-bottom: 1.25rem; gap: .75rem; }

/* ============================================================
   FLASH MESSAGES
   ============================================================ */
.flash-container { padding: 2rem 2rem 0; }
.flash {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .875rem 1rem;
  border-radius: var(--radius);
  margin: 0 0 .75rem 0;
  font-size: .875rem;
  font-weight: 500;
  animation: flashIn .3s ease;
}
@keyframes flashIn { from { opacity: 0; transform: translateY(-6px); } }
.flash-success { background: var(--success-light); color: #166534; border: 1px solid #BBF7D0; margin: 0; }
.flash-error   { background: var(--danger-light);  color: #991B1B; border: 1px solid #FECACA; }
.flash-info    { background: var(--accent-light);  color: #1E40AF; border: 1px solid #BFDBFE; }
.flash-warning { background: var(--warning-light); color: #92400E; border: 1px solid #FDE68A; }
[data-theme="dark"] .flash-success { color: #86EFAC; border-color: rgba(34,197,94,.40); }
[data-theme="dark"] .flash-error   { color: #FCA5A5; border-color: rgba(248,113,113,.40); }
[data-theme="dark"] .flash-info    { color: #BFDBFE; border-color: rgba(96,165,250,.40); }
[data-theme="dark"] .flash-warning { color: #FDE68A; border-color: rgba(251,191,36,.40); }

/* Demo-Modus-Banner (read-only Ansichts-Demo) */
.demo-banner {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; justify-content: center;
    padding: .6rem 1rem; background: var(--accent-light); color: #1E40AF;
    border-bottom: 1px solid var(--border); font-size: .85rem; font-weight: 600;
}
.demo-banner a { color: inherit; text-decoration: underline; }
.demo-banner .demo-banner-cta {
    background: var(--primary); color: #fff; padding: .25rem .75rem;
    border-radius: 999px; text-decoration: none; font-weight: 700; white-space: nowrap;
}
.demo-banner .demo-banner-cta:hover { opacity: .9; }
[data-theme="dark"] .demo-banner { color: #BFDBFE; }
.flash-icon { font-size: 1rem; font-weight: 700; }
.flash-close { margin-left: auto; background: none; border: none; cursor: pointer; opacity: .6; font-size: 1.1rem; padding: 0 .25rem; }
.flash-close:hover { opacity: 1; }

/* ============================================================
   CARDS
   ============================================================ */
.card { background: var(--bg-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); border: 1px solid var(--border); margin-bottom: 1.5rem; overflow: hidden; }
.card-header { display: flex; align-items: center; justify-content: space-between; padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--border); gap: 1rem; }
.card-tabs { display: flex; flex-wrap: wrap; gap: .25rem; padding: .375rem; border-bottom: 1px solid var(--border); background: var(--bg-subtle, rgba(0,0,0,.025)); }
.card-title { font-size: 1rem; font-weight: 700; color: var(--text-primary); max-width: 40ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Der Titelblock (erstes Kind) muss schrumpfen dürfen. Ohne min-width:0 hält
   sein min-content die Kopfzeile auf voller Breite, weil der Titel auf einer
   Zeile steht: Der Knopf rechts rutscht dann aus der Karte (beobachtet bei
   «Bewertungsskalen · Überfachliche Kompetenzen» um 820 px). Mit min-width:0
   greift stattdessen die Ellipse des Titels. */
.card-header > div:first-child { min-width: 0; }
.card-danger { border-color: #FECACA; }
.card-danger > .card-header { border-bottom-color: #FECACA; }
.card-danger .card-title { color: #DC2626; }
[data-theme="dark"] .card-danger { border-color: rgba(248,113,113,.40); }
[data-theme="dark"] .card-danger > .card-header { border-bottom-color: rgba(248,113,113,.40); }
[data-theme="dark"] .card-danger .card-title { color: var(--danger); }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .55rem 1.2rem;
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: .875rem;
  font-weight: 600;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all var(--transition);
  white-space: nowrap;
  line-height: 1.4;
}
.btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-primary   { background: var(--primary); color: #fff; border-color: var(--primary); }
.btn-primary:hover { background: var(--primary-light); border-color: var(--primary-light); text-decoration: none; }
.btn-secondary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-secondary:hover { background: #2563EB; border-color: #2563EB; text-decoration: none; }
.btn-ghost     { background: transparent; color: var(--text-secondary); border-color: var(--border); }
.btn-ghost:hover { background: var(--neutral-light); color: var(--text-primary); text-decoration: none; }
/* «Mit Microsoft anmelden»-Button (Login/Registrieren): bewusst weiss mit farbigem
   Provider-Logo; Hover dezent wie beim «Anmelden»-Button (via .btn transition:all). */
.btn-sso { display: flex; align-items: center; justify-content: center; gap: .6rem; background: #fff; color: #1f2937; border: 1.5px solid #d1d5db; font-weight: 600; text-decoration: none; }
.btn-sso:hover { background: #f3f4f6; border-color: #9ca3af; color: #1f2937; text-decoration: none; }
.btn-outline-primary { background: transparent; color: var(--primary); border-color: var(--primary); }
.btn-outline-primary:hover { background: var(--primary); color: #fff; border-color: var(--primary); text-decoration: none; }
.btn-success   { background: var(--success); color: #fff; border-color: var(--success); }
.btn-warning   { background: var(--warning); color: #fff; border-color: var(--warning); }
.btn-danger    { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-danger:hover { background: #DC2626; text-decoration: none; }
.btn-sm  { padding: .3rem .75rem; font-size: .8rem; }
.btn-lg  { padding: .75rem 1.75rem; font-size: 1rem; }
.btn-full { width: 100%; white-space: normal; }

/* ------------------------------------------------------------
   LADEZUSTÄNDE (Buttons)
   Der Doppel-Submit-Schutz in assets/js/app.js deaktiviert den geklickten
   Button und setzt «.is-submitting». Ohne Stil sah das aus wie ein Button,
   der einfach nicht mehr reagiert. Jetzt dreht sich ein Spinner vor der
   Beschriftung, damit erkennbar ist, dass gerade etwas läuft.
   Farbe über currentColor, damit es auf allen Button-Varianten und im
   Dark Mode ohne eigene Regeln stimmt.
   ------------------------------------------------------------ */
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  box-shadow: none;
}
.btn.is-submitting {
  opacity: .9;
  cursor: progress;
}
.btn.is-submitting::before {
  content: '';
  flex: none;
  width: .9em;
  height: .9em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: lsSpin .6s linear infinite;
}

/* ------------------------------------------------------------
   SPINNER (wiederverwendbar)
   Für Bereiche, die per fetch() nachgeladen werden: als Element
   <span class="ls-spinner"></span> oder als fertige Zeile
   <div class="ls-loading"><span class="ls-spinner"></span>Wird geladen…</div>.
   Grösse folgt der Schriftgrösse (em), Farbe der Textfarbe.
   ------------------------------------------------------------ */
.ls-spinner {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  vertical-align: -.15em;
  animation: lsSpin .6s linear infinite;
}
.ls-spinner-lg { width: 1.75em; height: 1.75em; border-width: 3px; }
.ls-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: 1.5rem 1rem;
  color: var(--text-muted);
  font-size: .85rem;
}
/* display:flex oben würde sonst das hidden-Attribut überstimmen */
.ls-loading[hidden] { display: none; }
@keyframes lsSpin { to { transform: rotate(360deg); } }

/* Wer Animationen reduziert haben möchte, bekommt eine ruhige Drehung statt
   gar keiner: ohne Bewegung fehlte die Rückmeldung ganz. */
@media (prefers-reduced-motion: reduce) {
  .btn.is-submitting::before, .ls-spinner { animation-duration: 1.8s; }
}

/* ============================================================
   FORMS
   ============================================================ */
.form-group { margin-bottom: 1.1rem; }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.form-label { display: block; font-size: .8rem; font-weight: 600; color: var(--text-secondary); margin-bottom: .35rem; }
.form-input, .form-select, .form-textarea {
  width: 100%;
  padding: .65rem .9rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: .875rem;
  color: var(--text-primary);
  background: var(--input-bg);
  transition: border-color var(--transition), box-shadow var(--transition);
  line-height: 1.5;
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px rgba(59,130,246,.12);
}
/* type=search browserübergreifend normalisieren: ohne native Optik rendern
   Safari/Firefox das Feld mit eigenem Hintergrund und eckigem Fokus, der
   border-radius/box-shadow ignoriert. So bleibt der Fokusring rund. */
.form-input[type="search"] { -webkit-appearance: none; appearance: none; }
.form-input[type="search"]::-webkit-search-decoration,
.form-input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.form-input:disabled, .form-select:disabled { background: var(--neutral-light); color: var(--text-muted); cursor: not-allowed; }
.form-select { cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right .75rem center; padding-right: 2.5rem; }
.form-select-sm { padding: .3rem .65rem; padding-right: 2.1rem; font-size: .8rem; }
.form-textarea { resize: vertical; min-height: 80px; }
.form-color { height: 42px; padding: .3rem; cursor: pointer; }
.form-hint { font-size: .75rem; color: var(--text-muted); margin-top: .3rem; }
.checkbox-label { display: flex; align-items: center; gap: .5rem; font-size: .875rem; cursor: pointer; }

/* Login-spezifische Input-Wrapper */
.input-wrapper { position: relative; }
.input-icon { position: absolute; left: .9rem; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.input-wrapper .form-input { padding-left: 2.75rem; }
.input-toggle-password { position: absolute; right: .75rem; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; color: var(--text-muted); padding: .2rem; }

/* ============================================================
   TABLES
   ============================================================ */
.table-wrapper { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .875rem; }
.table th { padding: .75rem 1rem; text-align: left; font-weight: 600; font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); background: var(--neutral-light); border-bottom: 1px solid var(--border); }
.table td { padding: .875rem 1rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
/* Kompakte Tabellen mit vielen schmalen Zahlenspalten (Übungsstatistik): Köpfe
   dürfen umbrechen (lange Einzelwörter mit &shy; im Markup), weniger Rand-
   abstand. So passen sie bei üblichen Bildschirmbreiten ohne seitliches Scrollen. */
.table-kompakt th { white-space: normal !important; line-height: 1.25; vertical-align: bottom; padding: .6rem .45rem; }
.table-kompakt td { padding-left: .45rem; padding-right: .45rem; }
.table-kompakt th:first-child, .table-kompakt td:first-child { padding-left: 1rem; }
.table-kompakt th:last-child, .table-kompakt td:last-child { padding-right: 1rem; }
.table-compact td, .table-compact th { padding-top: .5rem; padding-bottom: .5rem; }
.table tr:last-child td { border-bottom: none; }
.table tr:hover td { background: var(--primary-xlight); }
.row-inactive td { opacity: .5; }

/* Aufklappbare Detailzeilen in Tabellen (z. B. Kompetenzen einer Lernstandserfassung) */
/* Chevron wie bei den übrigen aufklappbaren Bereichen (vgl. .ex-sess-chev) */
.row-toggle { display: inline-flex; align-items: center; justify-content: center; margin-right: .5rem; padding: 0;
  border: 0; background: none; color: var(--text-muted); cursor: pointer; vertical-align: middle; }
.row-toggle svg { flex-shrink: 0; transition: transform .15s; }
.row-toggle:hover { color: var(--primary); }
.row-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }
/* Ganze Zeile klickbar; Links darin behalten ihren eigenen Cursor */
.table tr.row-expandable { cursor: pointer; }
.table tr.row-expandable a { cursor: pointer; }
.table tr.row-detail td { background: var(--bg-subtle); font-size: .84rem; padding-top: .55rem; padding-bottom: .55rem; }
.table tr.row-detail:hover td { background: var(--bg-subtle); }
.row-detail-name { padding-left: 2.65rem !important; color: var(--text-secondary); position: relative; }
.row-detail-name::before { content: "–"; position: absolute; left: 1.55rem; color: var(--text-muted); }
/* Namensspalte: genug Platz, damit Titel nicht unnötig umbrechen, aber nach oben
   begrenzt, damit sie die Kennzahlen-Spalten nicht wegdrücken. Im Auto-Layout ist
   max-width auf der Zelle nur ein Hinweis, den der Browser überschreitet, deshalb
   zusätzlich am Inhalt kappen. Lange Wörter werden notfalls umbrochen. */
/* break-word statt anywhere: beide brechen überlange Wörter um, aber anywhere senkt
   die min-content-Breite auf ein Zeichen, worauf die Tabelle die Spalte auf Mobile
   bis zur Buchstabenkolonne zusammenschiebt. */
.table .col-name { --col-name-max: 36rem; width: 30rem; max-width: var(--col-name-max); overflow-wrap: break-word; }
.table .col-name > a { display: inline-block; max-width: var(--col-name-max); }
.table .col-name > div { max-width: var(--col-name-max); }
/* Chevron aus dem Textfluss nehmen, damit umbrochene Titel bündig bleiben statt
   unter dem Chevron weiterzulaufen, und auf Zellenmitte statt am oberen Rand. */
.table td.col-name--chev { position: relative; padding-left: 2.5rem; }
.table td.col-name--chev .row-toggle { position: absolute; left: 1rem; top: 50%; transform: translateY(-50%); margin: 0; }

.action-buttons { display: flex; gap: .4rem; flex-wrap: wrap; }

/* ------------------------------------------------------------
   SET-TABELLEN auf dem Handy: jede Zeile eine Karte
   Titel, darunter eine Merkmal-Zeile, darunter die Zahlen, dann der
   seitenspezifische Teil und die Aktionen. Früher stand jede Spalte mit
   ihrem Namen auf einer eigenen Zeile, eine Karte war 379 px hoch.

   Ab hier abwärts: Schmaler als 1100 px bleibt für eine Tabelle mit acht
   Spalten kein sinnvoller Platz mehr (der Titel fiele unter 140 px), darum
   Karten statt Tabelle.
   ------------------------------------------------------------ */
@media (max-width: 1100px) {
  .set-table thead { display: none; }
  .set-table, .set-table tbody { display: block; }
  .set-table tr {
    display: block;
    position: relative;
    padding: .75rem .9rem .75rem 2.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: .55rem;
    background: var(--bg-card);
  }
  .set-table td {
    display: block;
    border: 0;
    padding: 0;
    text-align: left !important;
    white-space: normal !important;
    font-size: .85rem;
  }
  /* Die Auswahl steht fest am linken Rand; als schwebendes Element lief nur
     die erste Zeile um sie herum und der Text stand ausgefranst. */
  .set-table td.stcol-check { position: absolute; left: .85rem; top: .85rem; margin: 0; }
  .set-table td.stcol-check input { width: 18px; height: 18px; }
  .set-table .st-title, .set-table .st-desc { white-space: normal; }
  .set-table .st-metaline { flex-wrap: wrap; }

  /* Merkmale und Zahlen laufen als zwei Zeilen mit Mittelpunkt-Trennern. */
  .set-table td.stcol-grade,
  .set-table td.stcol-subject,
  .set-table td.stcol-difficulty,
  .set-table td.stcol-count,
  .set-table td.stcol-competencies {
    display: inline;
    color: var(--text-muted);
  }
  .set-table td.stcol-grade::after,
  .set-table td.stcol-subject::after { content: " · "; color: var(--text-muted); }
  /* Nach der Schwierigkeit beginnt die Zahlenzeile. */
  .set-table td.stcol-difficulty::after { content: "\A"; white-space: pre; }
  .set-table td.stcol-count::before { content: "Aufgaben "; }
  .set-table td.stcol-count::after { content: " · "; }
  .set-table td.stcol-competencies::before { content: "Kompetenzen "; }
  .set-table td.stcol-count > *, .set-table td.stcol-competencies > * { display: inline; }

  /* Auftrag und Anbieter behalten ihren Namen davor. */
  .set-table td.stcol-assignment,
  .set-table td.stcol-provider {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin-top: .4rem;
  }
  .set-table td.stcol-assignment::before,
  .set-table td.stcol-provider::before {
    content: attr(data-label) ":";
    font-weight: 600;
    color: var(--text-muted);
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    flex-shrink: 0;
  }
  /* In der Karte steht das Merkmal-Badge auf einer eigenen Zeile unter dem
     Titel; nebeneinander mit der Beschreibung bricht diese unschön um das
     Badge herum um. */
  .set-table .st-metaline { display: block; }
  .set-table .st-metaline .badge { margin: .15rem 0 .1rem; }
  .set-table .st-metaline .st-desc { display: block; }

  /* LP21-Codes gehören auf die gleiche Zeile wie die Zahl und nach links,
     nicht zentriert unter die Karte (die Zelle bringt margin:auto mit). */
  .set-table td.stcol-competencies > div {
    display: inline-flex !important;
    margin: 0 0 0 .35rem !important;
    vertical-align: middle;
    justify-content: flex-start !important;
    max-width: none !important;
  }

  /* Die ganze Karte hebt sich beim Zeigen ab, nicht nur einzelne Zellen. */
  .set-table tbody tr:hover { background: var(--primary-xlight); }
  .set-table tbody tr:hover td { background: transparent; }

  .set-table td.stcol-actions {
    margin-top: .55rem;
    padding-top: .55rem;
    border-top: 1px solid var(--border);
  }
  .set-table td.stcol-actions > div {
    flex-wrap: nowrap;
    justify-content: flex-start !important;
    gap: .4rem;
  }
  /* Fingergerechte Ziele: die Icon-Knöpfe sind am Gerät sonst 30 px hoch. */
  .set-table td.stcol-actions .btn {
    min-width: 40px;
    min-height: 40px;
    justify-content: center;
  }
}

/* Suchfeld der Set-Filter: Lupe links, Leeren-Knopf rechts. */
.set-search { position: relative; display: flex; flex: 1 1 200px; min-width: 0; }
.set-search .form-input { padding-left: 2.2rem; padding-right: 2rem; width: 100%; }
.set-search-icon { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.set-search-clear {
  position: absolute; right: .4rem; top: 50%; transform: translateY(-50%);
  border: 0; background: none; color: var(--text-muted); cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: .1rem .35rem; border-radius: 999px;
}
.set-search-clear:hover { color: var(--text-primary); background: var(--hover-bg); }
.set-search-clear[hidden] { display: none; }

/* Trefferzahl neben dem Kartentitel der Set-Tabellen. */
.set-count { font-weight: 500; font-size: .82rem; color: var(--text-muted); margin-left: .5rem; }

/* Filterleiste in der Kartenansicht: Knopf plus Chips der aktiven Filter. */
.set-filter-mobile { display: none; }
@media (max-width: 1100px) {
  .set-filter-mobile { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-bottom: .75rem; }
  .set-filter-mobile[hidden] { display: none; }
  /* «.filter-bar» setzt display:flex; ohne diese Regel bliebe die Karte trotz
     hidden-Attribut sichtbar. */
  .filter-bar.filter-collapsible[hidden] { display: none !important; }
  .set-filter-toggle { flex: 0 0 auto; }
  .set-filter-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
  .set-filter-chip {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .25rem .55rem; border-radius: 99px;
    border: 1px solid var(--border); background: var(--bg-card);
    color: var(--text-secondary); font-size: .78rem; font-family: var(--font);
    cursor: pointer;
  }
  .set-filter-chip:hover { border-color: var(--accent); color: var(--text-primary); }
  /* Beschreibung in der Karte höchstens zwei Zeilen. */
  .set-table .st-desc {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
}

/* Wenig Platz: Die entbehrlichsten Spalten weichen, damit die Tabelle ohne
   Querscrollen auskommt und die Kopfzeile kleben kann. Die Angaben stehen
   weiterhin in den Filtern und in der Vorschau. */
@media (min-width: 1101px) and (max-width: 1519px) {
  .set-table .stcol-competencies { display: none; }
}
@media (min-width: 1101px) and (max-width: 1299px) {
  .set-table .stcol-grade { display: none; }
}
@media (min-width: 1101px) and (max-width: 1199px) {
  .set-table .stcol-subject { display: none; }
}

/* Aktionsknöpfe der Set-Tabellen: alle gleich, auch das «···». Die Ruhefarbe
   stand vorher als Inline-Stil an den einzelnen Knöpfen und schlug damit den
   Hover, während das «···» ohne Inline-Farbe anders reagierte. */
.set-table .stcol-actions .btn { color: var(--text-muted); min-width: 33px; justify-content: center; }
.set-table .stcol-actions .btn:hover { color: var(--text-primary); }

/* Sortierköpfe sind Knöpfe (Tastatur, Screenreader), sehen aber aus wie der
   Spaltentitel. */
.set-table th.sortable .th-sort {
  all: unset;
  display: block;
  width: 100%;
  cursor: pointer;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.set-table th.sortable .th-sort:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* Ganze Zeile klickbar: öffnet die Vorschau. */
.set-rows-clickable tr { cursor: pointer; }

/* Hinweis über der Tabelle: Auswahl gilt für die Seite oder für alle Treffer. */
.set-selectall {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  padding: .55rem 1.25rem;
  background: var(--accent-light);
  border-bottom: 1px solid var(--border);
  font-size: .85rem; color: var(--text-secondary);
}
.set-selectall[hidden] { display: none; }
[data-theme="dark"] .set-selectall { background: rgba(59, 130, 246, .12); color: var(--text-secondary); }

/* ------------------------------------------------------------
   SET-TABELLEN (Meine Übungssets, Bibliothek)
   Ohne feste Breiten bekommt die Titelspalte die kleinste Breite:
   Titel und Beschreibung brechen dann auf mehrere Zeilen und eine
   Zeile wird dreimal so hoch. Darum «table-layout: fixed» mit einem
   Breitenplan, Titel und Beschreibung je einzeilig mit Auslassung.
   Nur ab 1101 px: darunter laufen die Tabellen als Karten.
   ------------------------------------------------------------ */
@media (min-width: 1101px) {
  .set-table { table-layout: fixed; }
  .set-table th, .set-table td { overflow: hidden; }
  /* Spaltentitel bleiben einzeilig; die Breiten unten sind so gewählt, dass auch
     «Schwierigkeit» und «Kompetenzen» samt Sortierpfeil hineinpassen. */
  .set-table th, .set-table th.sortable { white-space: nowrap; }
  .set-table th, .set-table td { padding-left: .7rem; padding-right: .7rem; }
  .set-table th { font-size: .7rem; letter-spacing: .02em; }
  /* Einzeilige Textspalten enden mit Auslassung statt hartem Schnitt. */
  .set-table .stcol-grade,
  .set-table .stcol-subject,
  .set-table .stcol-provider,
  .set-table .stcol-date { white-space: nowrap; text-overflow: ellipsis; }

  .set-table .stcol-check        { width: 34px; padding-right: .4rem; }
  .set-table .stcol-title        { width: auto; }
  .set-table .stcol-grade        { width: 84px; }
  .set-table .stcol-subject      { width: 100px; }
  .set-table .stcol-difficulty   { width: 132px; }
  .set-table .stcol-count        { width: 100px; text-align: right; }
  .set-table .stcol-competencies { width: 126px; text-align: center; }
  .set-table .stcol-provider     { width: 112px; }
  .set-table .stcol-assignment   { width: 200px; }
  .set-table .stcol-actions      { width: 172px; }

  /* Feste Spaltenbreiten statt Breite nach Inhalt: So kann die Tabelle gar nie
     breiter werden als ihr Rahmen. Reicht der Platz nicht für alle Spalten,
     fallen die entbehrlichsten weg (Regeln weiter oben) und der Titel wird
     gekürzt, statt dass die Tabelle waagrecht scrollt. Das ist die Bedingung
     für die klebende Kopfzeile: In einem waagrecht scrollenden Rahmen wirkt
     «position: sticky» nicht gegen die Seite. */
  .set-table { table-layout: fixed; }
  .set-wrap { overflow: visible; }

  /* Kopfzeile bleibt beim Scrollen stehen (25 Zeilen pro Seite sind länger als
     ein Bildschirm). Sie hängt unter der Topbar. Die Karte darum nicht mehr
     abschneiden: «overflow: hidden» macht sie zum Scroll-Rahmen und Sticky
     wirkt dann nicht mehr. */
  .set-card { overflow: visible; }
  /* Safari lässt «position: sticky» an einem th nicht wirken, solange die
     Tabelle «border-collapse: collapse» hat (WebKit-Fehler, in Chrome und
     Firefox klebt es). «separate» mit border-spacing 0 sieht identisch aus,
     weil nur untere Rahmen gesetzt sind, und klebt in allen Browsern. */
  .set-table { border-collapse: separate; border-spacing: 0; }
  .set-table thead th { position: sticky; top: var(--topbar-h); z-index: 5; }

  /* Ist das Zeilenmenü offen, gehört seine Zelle nach ganz vorn. */
  .set-table .stcol-actions.row-menu-active { position: relative; z-index: 30; }

  /* Titel und Beschreibung: je eine Zeile, Rest als Auslassung.
     Der volle Text steht im Tooltip der Beschreibung. */
  .set-table .st-title { font-weight: 600; color: var(--text-primary); text-decoration: none; }
  .set-table .st-title,
  .set-table .st-desc {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Zweite Zeile der Titelzelle: Merkmal-Badge und Beschreibung. Der Titel
     darüber bekommt so die volle Spaltenbreite. */
  .set-table .st-metaline { display: flex; align-items: center; gap: .35rem; min-width: 0; margin-top: .15rem; }
  .set-table .st-metaline .badge { flex: none; }
  .set-table .st-metaline .st-desc { flex: 0 1 auto; min-width: 0; }
  /* Auftrag: Status und Zeitraum in einer Zeile, Details darunter. */
  .set-table .st-assign-line { display: flex; align-items: center; gap: .4rem; min-width: 0; }
  .set-table .st-assign-line > span:last-child { overflow: hidden; text-overflow: ellipsis; }
}

/* ============================================================
   BADGES
   ============================================================ */
.badge {
  display: inline-flex;
  align-items: center;
  padding: .2rem .6rem;
  border-radius: 99px;
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.badge-success { background: var(--success-light); color: #166534; }
.badge-info    { background: var(--accent-light);  color: #1E40AF; }
.badge-warning { background: var(--warning-light); color: #92400E; }
.badge-danger  { background: var(--danger-light);  color: #991B1B; }
.badge-neutral { background: var(--neutral-light); color: var(--text-muted); }
.badge-outline { background: transparent; border: 1.5px solid var(--border); color: var(--text-secondary); }
.role-admin           { background: var(--danger-light);   color: #991B1B; }
.role-schulhaus_admin { background: #EDE9FE;               color: #5B21B6; }
.role-class_teacher   { background: var(--accent-light);   color: #1E40AF; }
.role-subject_teacher { background: var(--success-light);  color: #166534; }

/* Dark Mode: helle, lesbare Textfarben auf den dunklen Tint-Hintergründen
   (Status- und Rollen-Badges). */
[data-theme="dark"] .badge-info,
[data-theme="dark"] .role-class_teacher    { color: #BFDBFE; }
[data-theme="dark"] .badge-success,
[data-theme="dark"] .role-subject_teacher  { color: #86EFAC; }
[data-theme="dark"] .badge-warning         { color: #FDE68A; }
[data-theme="dark"] .badge-danger,
[data-theme="dark"] .role-admin            { color: #FCA5A5; }
[data-theme="dark"] .role-schulhaus_admin  { background: #2E1065; color: #DDD6FE; }

/* ============================================================
   MODALS
   ============================================================ */
.modal { display: none; position: fixed; inset: 0; z-index: 500; align-items: center; justify-content: center; padding: 1rem; }
.modal.open { display: flex; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.5); backdrop-filter: blur(2px); }
.modal-dialog { position: relative; background: var(--bg-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); width: 100%; max-width: 520px; max-height: 90vh; overflow-y: auto; overflow-x: hidden; animation: modalIn .2s ease; }
.modal-lg { max-width: 680px; }
@keyframes modalIn { from { opacity: 0; transform: scale(.96) translateY(-8px); } }
/* Stufen-Pills in Modalen: Hover in der Options-Farbe (--pill-color je Pill).
   !important, da die Pills inline border/color/background tragen. */
.ueb-modal-pill { transition: background-color .12s, border-color .12s, color .12s; }
.ueb-modal-pill:not(.on):not([disabled]):hover {
    border-color: var(--pill-color, var(--accent)) !important;
    color: var(--pill-color, var(--accent)) !important;
    background: color-mix(in srgb, var(--pill-color, var(--accent)) 12%, var(--bg-card)) !important;
}
.modal-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--border); }
.modal-header h3 { font-size: 1.05rem; font-weight: 700; }
.modal-close { background: none; border: none; cursor: pointer; font-size: 1.5rem; color: var(--text-muted); line-height: 1; padding: 0 .25rem; margin-left: .5rem; }
.modal-close:hover { color: var(--text-primary); }
.modal-body { padding: 1.5rem; }
.modal-footer { padding: 1rem 1.5rem; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: .75rem; }

/* ============================================================
   STAT CARDS
   ============================================================ */
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.25rem; margin-bottom: 1.5rem; }
.stat-card { background: var(--bg-card); border-radius: var(--radius-lg); padding: 1.5rem; display: flex; align-items: center; gap: 1rem; box-shadow: var(--shadow-sm); border: 1px solid var(--border); }
.stat-icon { width: 52px; height: 52px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.stat-icon-blue   { background: var(--accent-light);   color: var(--accent); }
.stat-icon-green  { background: var(--success-light);  color: var(--success); }
.stat-icon-purple { background: #EDE9FE; color: #7C3AED; }
.stat-icon-orange { background: var(--warning-light);  color: var(--warning); }
.stat-icon-amber  { background: #FEF3C7; color: #D97706; }
.stat-icon-red    { background: var(--danger-light);   color: var(--danger); }
/* Violett und Amber haben keine Theme-Tokens; ohne diese Zeilen blieben die
   Kacheln im Dark Mode hell (#EDE9FE / #FEF3C7) auf dunkler Karte. */
[data-theme="dark"] .stat-icon-purple { background: rgba(139, 92, 246, .18); color: #C4B5FD; }
[data-theme="dark"] .stat-icon-amber  { background: rgba(245, 158, 11, .16); color: #FCD34D; }
.stat-card-link { text-decoration: none; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.stat-card-link:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* «anywhere» trennte auch dort, wo es nicht nötig war: «Abgeschlossen|e Versuche»
   mitten im Wort, «15.09.2|026» mitten in der Jahreszahl. «break-word» bricht
   zuerst an Leerzeichen und an ausdrücklichen Gelegenheiten (<wbr>) und greift
   nur dann ins Wort, wenn es allein keine Zeile füllt. */
.stat-value { font-size: 1.75rem; font-weight: 800; color: var(--text-primary); line-height: 1.2; overflow-wrap: break-word; }
/* Lange Beschriftungen («Abgeschlossene Versuche») sind breiter als der Platz
   neben dem Symbol. Trennstellen setzt die Seite selbst mit &shy; bzw. <wbr>,
   damit sauber «Abge-/schlossene» statt «Abgeschlossen/e» umbrochen wird;
   hyphens:auto trennt zusätzlich dort, wo der Browser deutsche Trennmuster
   mitbringt, break-word bleibt der Rückfall für alles Übrige. */
.stat-label { font-size: .8rem; color: var(--text-muted); font-weight: 500; margin-top: .1rem; overflow-wrap: break-word; hyphens: auto; }
.stat-info { min-width: 0; }

/* ============================================================
   DASHBOARD
   ============================================================ */
.dashboard-grid { display: flex; flex-direction: column; gap: 0; }
/* Nur waagrecht ein gap: Senkrecht trennt der margin-bottom der Karte, den sie
   ohnehin mitbringt. Mit row-gap käme er obendrauf, und gestapelte Karten
   (schmale Schirme, mehrzeilige Raster) stünden doppelt so weit auseinander wie
   überall sonst. */
.dashboard-columns { display: grid; grid-template-columns: 1fr 1fr; column-gap: 1.5rem; row-gap: 0; }
.dashboard-columns > * { min-width: 0; }
.class-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.25rem; padding: 1.5rem; }
.class-card { border: 1.5px solid var(--border); border-radius: var(--radius-lg); padding: 1.25rem; transition: box-shadow var(--transition), border-color var(--transition); }
.class-card:hover { box-shadow: var(--shadow); border-color: var(--accent); }
.class-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.class-card-name { font-size: 1rem; font-weight: 700; }
.class-card-meta { display: flex; gap: 1rem; font-size: .8rem; color: var(--text-muted); margin: .5rem 0 1rem; }
.class-card-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.quick-actions { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; padding: 1.25rem; }
.quick-action { display: flex; align-items: center; gap: .75rem; padding: .875rem 1rem; border: 1.5px solid var(--border); border-radius: var(--radius); font-size: .875rem; font-weight: 600; color: var(--text-secondary); transition: all var(--transition); }
.quick-action:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-light); text-decoration: none; }

/* ============================================================
   EMPTY STATE
   ============================================================ */
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4rem 2rem; gap: 1rem; color: var(--text-muted); text-align: center; }
.empty-state svg { opacity: .3; }
.empty-state p { font-size: .95rem; }
.empty-state-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; }
.empty-state-kompakt { padding: 1.25rem 1.5rem; gap: .6rem; margin-bottom: 1rem; }
.empty-state-kompakt > svg { display: none; }

/* ============================================================
   FILTER BAR
   ============================================================ */
/* margin-bottom: 1rem statt der 1.5rem von «.card», damit der Abstand unter der
   Filterleiste gleich gross ist wie der darüber (die Kontext-Navigation setzt
   ebenfalls 1rem). Ohne !important, weil «.filter-bar» im Stylesheet nach
   «.card» steht und bei gleicher Spezifität gewinnt. */
.filter-bar { padding: 1rem 1.25rem !important; overflow: visible !important; display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: 1rem; }
.filter-form { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
/* Formulare direkt in der Filterleiste (oft mit Inline-Flex ohne Umbruch):
   auf schmalen Bildschirmen umbrechen, lange Link-Knöpfe dürfen mehrzeilig werden. */
.filter-bar > form { flex-wrap: wrap; max-width: 100%; min-width: 0; }
.filter-bar > form > .btn { max-width: 100%; white-space: normal; }
.filter-label { font-size: .8rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.filter-bar .form-select, .filter-bar .form-input,
#addPanel .form-select, #lp21Panel .form-select { width: auto; min-width: 120px; max-width: 280px; text-overflow: ellipsis; }

/* ============================================================
   RESULTS GRID
   ============================================================ */
.results-card { overflow: visible; }
.results-grid-wrapper { overflow-x: auto; padding: 1.25rem; min-height: 280px; }
.results-grid {
  display: grid;
  /* Mindestbreite pro Kompetenz-Spalte = Date-Input (72) + Stift-Button (16) +
     Score-Button (44) + Gaps + Padding ≈ 140px. Bei vielen Kompetenzen wächst
     das Grid über den Wrapper hinaus → der Wrapper scrollt horizontal. */
  grid-template-columns: max-content repeat(var(--comp-count, 1), minmax(140px, 1fr));
  gap: 2px;
  min-width: 100%;
}
.rg-corner { padding: .5rem; font-size: .75rem; font-weight: 700; color: var(--text-muted); display: flex; align-items: flex-end; position: sticky; left: 0; z-index: 3; background: var(--card-bg); }
.rg-comp-header { padding: .4rem .25rem; display: flex; flex-direction: column; align-items: center; gap: .5rem; text-align: center; min-width: 130px; }
.rg-comp-num { font-size: .7rem; font-weight: 800; color: var(--primary); background: var(--primary-xlight); width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.rg-comp-label { font-size: .75rem; color: var(--text-secondary); max-height: 4rem; overflow: hidden; line-height: 1.25; }
.rg-comp-avg { font-size: .6rem; font-weight: 600; color: var(--primary); white-space: nowrap; }
.rg-comp-max { font-weight: 400; color: var(--text-muted); }
.rg-student { padding: .35rem .5rem; font-size: .8rem; font-weight: 600; display: flex; align-items: center; background: var(--neutral-light); border-radius: var(--radius-sm); transition: background .1s; position: sticky; left: 0; z-index: 2; }
.rg-cell { display: flex; align-items: center; justify-content: center; gap: .3rem; position: relative; padding: 0 .25rem; transition: background .1s; }
.rg-student.row-hovered { background: #DBEAFE; }
.rg-student.rg-selected { background: #3B82F6; color: #fff; }
.rg-cell.row-hovered { background: #EFF6FF; }
/* Dunkel: helles Blau unter hellem Namen war unlesbar */
[data-theme="dark"] .rg-student.row-hovered { background: #1E3A5F; }
[data-theme="dark"] .rg-cell.row-hovered { background: var(--primary-xlight); }
.rg-date-input {
  font-size: .65rem; color: var(--text-muted);
  background: transparent; border: 1px solid transparent; border-radius: 3px;
  cursor: pointer; padding: .1rem .15rem; width: 72px; flex-shrink: 0;
  font-family: inherit; outline: none; appearance: none; -webkit-appearance: none;
}
.rg-date-input:hover { border-color: var(--border); background: var(--neutral-light); }
.rg-date-input:focus { border-color: var(--primary); }
.rg-date-input::-webkit-calendar-picker-indicator { opacity: 0; width: 0; padding: 0; margin: 0; cursor: pointer; }
.rg-date-input:hover::-webkit-calendar-picker-indicator { opacity: .4; width: auto; }
/* Punkte ohne Erfassungsdatum (auch 0 Punkte). Ohne Datum fehlt das Resultat
   in Lernentwicklung und Tendenz; der Hinweis über der Tabelle zählt sie. */
.rg-date-input.rg-date-input--warn { border-color: var(--warning); background: var(--warning-light); color: var(--warning); }
.score-btn {
  min-width: 44px; height: 32px; padding: 0 .35rem;
  border: 2px solid;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: .75rem;
  font-weight: 700;
  cursor: pointer;
  transition: all var(--transition);
  white-space: nowrap;
}
.score-btn:hover { transform: scale(1.15); box-shadow: 0 2px 8px rgba(0,0,0,.15); }
.rg-details-btn {
  display: flex; flex-shrink: 0;
  width: 16px; height: 16px; border: none; border-radius: 3px;
  background: var(--neutral-light); color: var(--text-muted);
  font-size: 10px; line-height: 1; cursor: pointer; padding: 0;
  align-items: center; justify-content: center;
}
.rg-details-btn:hover { background: var(--border); color: var(--text); }
.rg-date-clear {
  display: flex; flex-shrink: 0;
  width: 14px; height: 14px; border: none; border-radius: 3px;
  background: transparent; color: var(--text-muted);
  font-size: 13px; line-height: 1; cursor: pointer; padding: 0;
  align-items: center; justify-content: center;
}
.rg-date-clear:hover { background: var(--neutral-light); color: var(--text); }
.rg-inline-input {
  width: 52px; height: 30px;
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  font-size: .8rem; font-weight: 700; text-align: center;
  background: var(--bg-card); color: var(--text);
  padding: 0 .2rem; outline: none;
}
.rg-inline-max {
  font-size: .72rem; color: var(--text-muted); white-space: nowrap;
}
.rg-comp-norm-hint {
  position: relative;
  display: block;
  font-size: .58rem; font-weight: 600;
  color: #92400E; background: #FEF3C7;
  border-radius: 3px; padding: .08rem .3rem;
  white-space: nowrap; width: fit-content;
  cursor: help;
}
.rg-comp-norm-hint[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #1e293b;
  color: #f1f5f9;
  font-size: .75rem;
  font-weight: 400;
  white-space: pre-line;
  padding: .45rem .65rem;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,.25);
  min-width: 180px;
  max-width: 300px;
  line-height: 1.5;
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s;
  z-index: 9999;
}
.rg-comp-norm-hint[data-tooltip]:hover::after { opacity: 1; }
.score-badge { display: flex; align-items: center; justify-content: center; min-width: 44px; height: 32px; padding: 0 .35rem; border-radius: var(--radius-sm); font-size: .75rem; font-weight: 700; white-space: nowrap; }
.score-input-wrap { display: flex; align-items: center; gap: .75rem; }
.score-number-input { width: 120px; font-size: 1.2rem; font-weight: 700; text-align: center; }
.score-max-label { font-size: 1.1rem; font-weight: 600; color: var(--text-muted); }
.score-legend { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: 1rem; padding: .75rem 1rem; background: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border); }
.legend-title { font-size: .8rem; font-weight: 700; color: var(--text-muted); }
.score-chip { font-size: .75rem; padding: .25rem .6rem; border-radius: 6px; border: 1.5px solid var(--border); font-weight: 600; }
.comp-details { padding: 1.25rem 1.5rem; border-top: 1px solid var(--border); }
.comp-details summary { cursor: pointer; font-size: .85rem; font-weight: 600; color: var(--text-secondary); padding: .25rem 0; }
.comp-list { list-style: none; padding: 1rem 0 0; margin: 0; display: flex; flex-direction: column; gap: .5rem; font-size: .85rem; }

/* Score-Eingabe im Modal (Nummernfeld) */

/* ============================================================
   CHARTS
   ============================================================ */
.charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1.5rem; }
.charts-grid > .card { margin-bottom: 0; }
.chart-card { padding: 0; }
.chart-card canvas { display: block; }
.chart-card-wide { grid-column: span 1; }
.chart-card-full { grid-column: 1 / -1; }
canvas { max-height: 350px; }
#radarChart { max-height: 500px; }

/* ============================================================
   STATISTICS
   ============================================================ */
.score-dist-list { padding: 1.25rem 1.5rem; display: flex; flex-direction: column; gap: .75rem; }
.score-dist-item { display: flex; align-items: center; gap: 1rem; }
.score-dist-label { font-size: .8rem; font-weight: 600; width: 160px; flex-shrink: 0; }
.score-dist-bar-wrap { flex: 1; height: 10px; background: var(--neutral-light); border-radius: 99px; overflow: hidden; }
.score-dist-bar { height: 100%; border-radius: 99px; transition: width .5s ease; }
.score-dist-count { font-size: .8rem; color: var(--text-muted); width: 80px; text-align: right; flex-shrink: 0; }
.highlight-item { display: flex; align-items: center; gap: .75rem; padding: .875rem 1rem; margin: .5rem 1.5rem; border-radius: var(--radius); }
.highlight-success { background: var(--success-light); }
.highlight-warning { background: var(--warning-light); }
.highlight-badge { font-size: .65rem; font-weight: 700; text-transform: uppercase; padding: .2rem .5rem; border-radius: 4px; background: rgba(0,0,0,.08); white-space: nowrap; }
.highlight-text { flex: 1; font-size: .85rem; font-weight: 600; }
.highlight-val { font-size: .9rem; font-weight: 800; }
.mini-bar { width: 80px; height: 6px; background: var(--neutral-light); border-radius: 99px; overflow: hidden; display: inline-block; margin-right: .5rem; vertical-align: middle; }
.mini-bar-fill { height: 100%; border-radius: 99px; }

/* ============================================================
   EXPORT
   ============================================================ */
.export-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; padding: 1.5rem; }
.export-option-card { border: 1.5px solid var(--border); border-radius: var(--radius-lg); padding: 1.5rem; display: flex; flex-direction: column; gap: .75rem; min-width: 0; }
.export-icon { font-size: 2rem; }
.export-head { display: flex; align-items: center; gap: .65rem; }
.export-icon-chip { width: 38px; height: 38px; border-radius: 10px; background: var(--accent-light); color: var(--accent); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.export-option-card h3 { font-weight: 700; margin: 0; }
.export-option-card p { font-size: .85rem; flex: 1; }
.export-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

/* ============================================================
   INFO BOX
   ============================================================ */
.info-box { background: var(--accent-light); border: 1px solid #BFDBFE; border-radius: var(--radius); padding: .875rem 1rem; font-size: .85rem; color: #1E40AF; }
.info-box strong { color: #1E40AF; }

.info-box-warning { background: var(--warning-light); border-color: #FCD34D; color: #92400E; }
.info-box-warning strong { color: #92400E; }

.info-box-danger { background: var(--danger-light); border-color: #FECACA; color: #991B1B; }
.info-box-danger strong { color: #991B1B; }

.info-box-success { background: var(--success-light); border-color: #86EFAC; color: #166534; }
.info-box-success strong { color: #166534; }

/* Knopf im Info-Kasten: .btn-ghost bringt einen hellgrauen Rahmen mit, der auf
   dem farbigen Tint fast verschwindet — der Knopf sah aus wie loser Text. Im
   Kasten übernimmt er dessen Farbe. Über currentColor gilt das für alle
   Varianten (Warnung, Fehler, Erfolg) und für beide Farbmodi. */
.info-box .btn-ghost { color: inherit; border-color: currentColor; }
.info-box .btn-ghost:hover { background: rgba(127,127,127,.18); color: inherit; }

/* Kompakte Variante (weniger Höhe) */
.info-box-sm { padding: .5rem .85rem; font-size: .8rem; }

/* Dark Mode: helle, kontrastreiche Textfarben auf den dunklen Tints +
   dezentere, theme-fähige Ränder (statt der hellen Light-Mode-Border). */
[data-theme="dark"] .info-box          { color: #BFDBFE; border-color: rgba(96,165,250,.45); }
[data-theme="dark"] .info-box strong   { color: #DBEAFE; }
[data-theme="dark"] .info-box-warning  { color: #FCD34D; border-color: rgba(251,146,60,.45); }
[data-theme="dark"] .info-box-warning strong { color: #FDE68A; }
[data-theme="dark"] .info-box-danger   { color: #FCA5A5; border-color: rgba(248,113,113,.45); }
[data-theme="dark"] .info-box-danger strong { color: #FECACA; }
[data-theme="dark"] .info-box-success  { color: #86EFAC; border-color: rgba(74,222,128,.45); }
[data-theme="dark"] .info-box-success strong { color: #BBF7D0; }

/* ============================================================
   SCORE-CHIP CHECKED STATE
   ============================================================ */
.score-chip.checked { background: var(--accent-light); border-color: var(--accent); color: #1E40AF; }

/* ============================================================
   CHECKLIST (Multi-Select-Liste mit Checkboxen, gruppiert)
   ============================================================ */
.checklist {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    max-height: 320px;
    overflow-y: auto;
    background: var(--bg-card);
}
.checklist-group-label {
    padding: .5rem .875rem;
    background: var(--bg-app);
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 1;
}
.checklist-item {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .55rem .875rem;
    border-bottom: 1px solid #F3F4F6;
    cursor: pointer;
    transition: background var(--transition);
    font-size: .9rem;
    color: var(--text-secondary);
}
.checklist-item:last-child { border-bottom: none; }
.checklist-item:hover { background: var(--bg-app); }
.checklist-item input[type=checkbox] { flex-shrink: 0; margin: 0; cursor: pointer; }
.checklist-item.checked { background: var(--accent-light); color: #1E40AF; font-weight: 500; }
.checklist-item.checked:hover { background: var(--accent-light); }
/* Dark Mode: helle Trennlinie ersetzen + lesbarer Aktiv-Zustand (Stufe/Bereich) */
[data-theme="dark"] .checklist-item { border-bottom-color: var(--border); }
[data-theme="dark"] .score-chip.checked,
[data-theme="dark"] .checklist-item.checked { color: #BFDBFE; }

/* ── Datei-Dropzone (Drag & Drop) ─────────────────────────────────────────── */
.dropzone { display: block; border: 1.5px dashed var(--border); border-radius: var(--radius); background: var(--bg-subtle); padding: 1rem; cursor: pointer; transition: border-color var(--transition), background var(--transition); }
.dropzone:hover { border-color: var(--accent); }
.dropzone.is-dragover { border-color: var(--accent); background: var(--accent-light); }
.dropzone.has-file { border-style: solid; border-color: var(--success); background: var(--success-light); }
.dropzone-inner { display: flex; flex-direction: column; align-items: center; gap: .3rem; text-align: center; pointer-events: none; }
.dropzone-inner > svg { color: var(--text-light); }
.dropzone-text { font-size: .82rem; color: var(--text-secondary); }
.dropzone-text strong { color: var(--accent); font-weight: 600; }
.dropzone-hint { font-size: .7rem; color: var(--text-light); }
.dropzone-file { display: flex; align-items: center; gap: .5rem; font-size: .85rem; color: var(--text-secondary); }
.dropzone-file > svg { color: var(--success); flex-shrink: 0; }
.dropzone-filename { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.dropzone-clear { background: none; border: none; cursor: pointer; color: var(--text-muted); font-size: 1.2rem; line-height: 1; padding: 0 .25rem; flex-shrink: 0; font-family: var(--font); }
.dropzone-clear:hover { color: var(--danger); }
/* [hidden] muss das display:flex der inner/file-Zeile übersteuern, sonst bleibt
   die zuvor gewählte Datei sichtbar. */
.dropzone [hidden] { display: none; }

/* ============================================================
   LP21-VERKNÜPFUNGS-LISTE (LP21-Stufen wählen)
   ============================================================ */
.lp21-list {
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    max-height: 380px;
    overflow-y: auto;
    background: var(--bg-card);
}
.lp21-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: .85rem;
    padding: .85rem 1rem;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
    cursor: pointer;
    transition: background var(--transition);
    position: relative;
}
.lp21-item:last-child { border-bottom: none; }
.lp21-item:hover { background: color-mix(in srgb, var(--accent-light) 45%, transparent); }
.lp21-cb {
    margin: .15rem 0 0;
    flex-shrink: 0;
    width: 17px;
    height: 17px;
    accent-color: var(--accent);
    cursor: pointer;
}
.lp21-item-body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}
.lp21-item-meta {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
}
.lp21-item-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .72rem;
    font-weight: 700;
    color: var(--text-primary);
    background: var(--bg-app);
    padding: .15rem .45rem;
    border-radius: 4px;
    border: 1px solid var(--border);
}
.lp21-item-stufe {
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    background: var(--accent-light);
    color: #1E40AF;
    padding: .14rem .5rem;
    border-radius: 4px;
    max-width: 100%;
    overflow-wrap: anywhere;
}
/* Dark Mode: --accent-light wird zu dunklem Navy → heller Blauton statt
   hartcodiertem Dunkelblau (Muster wie .badge-info / .flash-info). */
[data-theme="dark"] .lp21-item-stufe { color: #BFDBFE; }
.lp21-item-text {
    font-size: .88rem;
    color: var(--text-primary);
    line-height: 1.45;
}
.lp21-item-breadcrumb {
    font-size: .72rem;
    color: var(--text-muted);
    line-height: 1.4;
}
.lp21-item-breadcrumb-sep { opacity: .5; margin: 0 .25rem; }
.lp21-item:has(.lp21-cb:checked) {
    background: var(--accent-light);
}
.lp21-item:has(.lp21-cb:checked) .lp21-item-text {
    font-weight: 600;
}
.lp21-item:has(.lp21-cb:checked)::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    background: var(--accent);
}

/* ============================================================
   MISC
   ============================================================ */
.text-center  { text-align: center; }
.text-muted   { color: var(--text-muted); }
.text-sm      { font-size: .8rem; }

/* Responsive Visibility Helpers — siehe @media (max-width: 640px) für Mobile-Variante */
.sm-only      { display: none; }
.text-mono    { font-family: monospace; }
.text-warning { color: var(--warning); }
.mb-2 { margin-bottom: .5rem; }
.subject-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: .5rem; vertical-align: middle; flex-shrink: 0; }
.user-cell { display: flex; align-items: center; gap: .75rem; }
.avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: .85rem; flex-shrink: 0; }
.avatar-sm { width: 28px; height: 28px; font-size: .75rem; }
.avatar-lg { width: 64px; height: 64px; font-size: 1.5rem; }
.breadcrumb-bar { display: flex; align-items: center; gap: .5rem; font-size: .85rem; color: var(--text-muted); margin-bottom: 1rem; }
.breadcrumb-bar a { color: var(--accent); }
.pagination { display: flex; gap: .4rem; padding: 1rem 1.5rem; flex-wrap: wrap; }
.page-link { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: var(--radius-sm); font-size: .85rem; font-weight: 600; border: 1.5px solid var(--border); color: var(--text-secondary); transition: all var(--transition); }
.page-link.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.page-link:hover:not(.active) { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.results-selectors { margin-bottom: 0; }
/* PDF-Import in der Filterleiste von /results: Nebenfunktion, darum in der Optik
   der Selects daneben (weisse Fläche, ruhiger Rahmen) statt als gefüllter Knopf. */
.res-import { margin-left: auto; flex-shrink: 0; align-self: stretch; display: inline-flex; align-items: center;
  gap: .45rem; padding: 0 .85rem; background: var(--bg-card); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: var(--radius); font-family: var(--font); font-size: .875rem;
  font-weight: 600; text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: border-color var(--transition), color var(--transition); }
.res-import:hover, .res-import:focus-visible { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.res-import svg { color: var(--text-muted); flex-shrink: 0; }
.res-import:hover svg, .res-import:focus-visible svg { color: var(--accent); }
.profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
.profile-avatar-section { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--border); }
code { font-family: monospace; background: var(--neutral-light); padding: .1rem .4rem; border-radius: 4px; font-size: .85rem; overflow-wrap: anywhere; }

/* ============================================================
   LOGIN PAGE
   ============================================================ */
.login-page { background: linear-gradient(135deg, var(--primary) 0%, #1a4a7a 60%, #0f2e4a 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
.login-container { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 420px; }
.login-wrapper { width: 100%; }
.login-disclaimer { width: 100%; margin-top: .875rem; font-size: .72rem; color: rgba(255,255,255,0.45); text-align: center; line-height: 1.5; }
.login-card { background: #fff; border-radius: var(--radius-xl); padding: 2.5rem; box-shadow: var(--shadow-lg); }
.login-header { text-align: center; margin-bottom: 2rem; }
.login-logo { display: flex; justify-content: center; margin-bottom: 1rem; }
.logo-icon-lg { width: 64px; height: 64px; background: var(--primary); border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 1.75rem; color: #fff; }
.login-title { font-size: 1.5rem; font-weight: 800; color: var(--text-primary); margin-bottom: .3rem; }
.login-subtitle { font-size: .85rem; color: var(--text-muted); }
.login-form { display: flex; flex-direction: column; gap: .25rem; margin-bottom: 1.5rem; }
.login-footer { text-align: center; margin-top: 1.5rem; }
.login-privacy { display: flex; align-items: center; justify-content: center; gap: .4rem; font-size: .75rem; color: var(--text-muted); flex-direction: column;}

/* ============================================================
   MULTI-STEP: AREA GRID & BREADCRUMBS
   ============================================================ */
.area-grid { display: grid; gap: 1rem; margin-bottom: 1.5rem; }
.area-card {
    display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
    padding: 1.5rem 1rem; background: var(--card-bg); border: 1px solid var(--border);
    border-radius: var(--radius); text-decoration: none; color: var(--text);
    transition: border-color .15s, box-shadow .15s;
    text-align: center;
}
.area-card:hover { border-color: var(--primary); box-shadow: 0 2px 8px rgba(37,99,235,.1); }
.area-card-icon {
    width: 48px; height: 48px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
}
.area-card-title { font-weight: 600; font-size: 0.95rem; line-height: 1.3; }
.area-card-meta { display: flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: var(--text-muted); }
.area-card-count { font-size: 0.75rem; margin-top: -0.25rem; }

/* ── Icon Picker ── */
.icon-picker {
    display: flex; flex-wrap: wrap; gap: 0.375rem;
    max-height: 200px; overflow-y: auto; padding: 0.5rem;
    border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg);
}
.icon-pick {
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border: 2px solid transparent;
    border-radius: 6px; background: none; cursor: pointer; color: var(--text);
    transition: border-color .15s, background .15s;
}
.icon-pick:hover { background: var(--hover-bg); }
.icon-pick.selected { border-color: var(--primary); background: rgba(37,99,235,.08); }
.icon-pick-none { width: auto; padding: 0 0.75rem; }

.step-breadcrumb {
    display: flex; flex-wrap: wrap; align-items: baseline;
    row-gap: .2rem; column-gap: 0.5rem;
    margin-bottom: 1rem; font-size: 0.875rem;
}
.breadcrumb-link {
    display: flex; align-items: center; gap: 0.25rem;
    color: var(--primary); text-decoration: none; font-weight: 500;
}
.breadcrumb-link:hover { text-decoration: underline; }
.breadcrumb-sep { color: var(--text-muted); }
.breadcrumb-current { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }

/* ============================================================
   SIDEBAR OVERLAY (mobile)
   ============================================================ */
.sidebar-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 90; }

/* ============================================================
   HEATMAP – Kompetenz-Erreichungszeile
   ============================================================ */
.comp-stat-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: .85rem;
  flex-wrap: wrap;
}
.comp-stat-num   { flex: 0 0 20px; text-align: right; color: var(--text-muted); }
.comp-stat-name  { flex: 1; min-width: 120px; }
.comp-stat-bar   { flex: 2; height: 16px; background: #E5E7EB; border-radius: 8px; overflow: hidden; min-width: 60px; }
.comp-stat-pct   { flex: 0 0 40px; text-align: right; font-weight: 600; }
.comp-stat-avg   { flex: 0 0 60px; text-align: right; font-weight: 600; }
.comp-stat-count { flex: 0 0 80px; color: var(--text-muted); }

/* ============================================================
   KLASSENVERGLEICH: ÜBERSICHTS-KARTEN
   ============================================================ */
.cc-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.cc-card {
  padding: 1rem;
  margin-bottom: 0;
  transition: transform var(--transition), box-shadow var(--transition);
}

.cc-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm), 0 4px 12px rgba(0,0,0,.1);
}

.cc-card--mine {
  box-shadow: 0 0 0 2px var(--accent, #3B82F6);
  margin-bottom: 0;
}

.cc-card--mine:hover {
  box-shadow: 0 0 0 2px var(--accent, #3B82F6), 0 4px 12px rgba(0,0,0,.1);
}

.cc-card__header {
  margin-bottom: .5rem;
}

.cc-card__title {
  display: flex;
  align-items: center;
  gap: .4rem;
}

.cc-card__name {
  font-weight: 700;
  font-size: 1rem;
}

.cc-card__badge {
  background: #DBEAFE;
  color: #1D4ED8;
  font-size: .65rem;
  font-weight: 700;
  padding: .1rem .4rem;
  border-radius: 10px;
  white-space: nowrap;
}

.cc-card__score {
  font-size: 2rem;
  font-weight: 800;
  line-height: 1;
}

.cc-card__label {
  margin: .25rem 0;
}

.cc-card__metrics {
  display: flex;
  gap: 1rem;
  margin-top: .5rem;
  font-size: .82rem;
}

.cc-card__metric-icon {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  margin-right: 2px;
  opacity: .55;
}

.plan-current-pct { text-align: right; }
.anon-mode-badge { display:inline-flex; align-items:center; gap:.3rem; font-size:.72rem; font-weight:600; padding:.25rem .6rem; border-radius:999px; background:#FEF3C7; color:#92400E; border:1px solid #FDE68A; text-decoration:none; white-space:nowrap; }
.anon-mode-badge:hover { background:#FDE68A; text-decoration:none; color:#92400E; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* Zwischen 769 und 960 px steht die Seitenleiste noch, die Topbar ist schmal:
   Titel mit Stern, Suche, Symbole und Name samt Rollen passten nicht mehr
   nebeneinander (Auswertungsseiten liefen bis 55 px über). Wie unter 768 px
   entfällt der Name (der Avatar bleibt), der Titel kürzt sich statt zu überlaufen. */
@media (min-width: 769px) and (max-width: 960px) {
  .topbar .user-info { display: none; }
  /* Zuerst schrumpft die Suche, der Titel erst bei sehr langen Namen */
  .topbar-left { flex: 0 0 auto; min-width: 0; max-width: 48%; }
  .topbar-page { min-width: 0; }
  .topbar .page-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar-search { flex: 1 1 0; min-width: 0; }
  .topbar-search .search-kbd { display: none; }
  .topbar-right { flex-shrink: 0; }
}
/* 961 bis 1180 px: Seitenleiste und Name stehen, die Topbar ist noch knapp. Die
   Rolle (zweitrangig, steht im Profil) und der Tastenkürzel-Hinweis entfallen,
   damit die Suche nicht bis auf «Ctrl+K» zusammengedrückt wird. */
@media (min-width: 961px) and (max-width: 1180px) {
  .topbar .user-role-badge { display: none; }
  .topbar-search .search-kbd { display: none; }
}
@media (max-width: 1024px) {
  .dashboard-columns, .charts-grid { grid-template-columns: 1fr; }
  .area-grid { grid-template-columns: 1fr 1fr !important; }
  .chart-card-wide, .chart-card-full { grid-column: auto; }
  .profile-grid { grid-template-columns: 1fr; }
  .export-options { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 600px) {
  .export-options { padding: 1rem; }
  .export-option-card { padding: 1rem; }
}

@media (max-width: 768px) {
  :root { --sidebar-width: 0px; }
  .sidebar { transform: translateX(-260px); }
  .sidebar.open { transform: translateX(0); width: 260px; }
  .sidebar-close { display: block; }
  .sidebar-collapse-btn { display: none; }
  .sidebar-overlay.open { display: block; }
  .main-content { margin-left: 0; }
  .sidebar-toggle { display: flex; }
  .topbar { padding: 0 1rem; }
  .page-content { padding: 1rem; }
  .flash-container { padding: 1rem 1rem 0; }
  .stat-cards { grid-template-columns: 1fr 1fr; }
  .form-row { grid-template-columns: minmax(0, 1fr); }

  .user-info { display: none; }
  /* Topbar darf nicht überlaufen: Titel kürzt sich, Bedienelemente bleiben sichtbar.
     Bewusst an .topbar gebunden: Vier Inhaltsseiten verwenden dieselbe Klasse für
     ihren <h1>, dort soll der Titel umbrechen statt zu kürzen oder zu überlaufen. */
  .topbar-left { flex: 1 1 auto; min-width: 0; }
  .topbar-right { flex-shrink: 0; }
  .sidebar-toggle { flex-shrink: 0; }
  .topbar .page-title { font-size: .95rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .action-buttons { flex-direction: column; }
  .action-buttons .btn { width: 100%; }

  /* Card-Header: Titel und Aktionen dürfen umbrechen */
  .card-header { flex-wrap: wrap; gap: .75rem; }
  /* Schmal: Der Titel bricht um, statt abgeschnitten zu werden. Die Karte nimmt
     hier die ganze Breite ein, eine zweite Zeile stört also nicht, ein an der
     Kartenkante abgeschnittener Titel dagegen schon. */
  .card-header .card-title { white-space: normal; overflow: visible; text-overflow: clip; max-width: 100%; overflow-wrap: break-word; }
  /* Jahresplanung: "Aktuelle Aufgabe" rechte Seite auf volle Breite */
  .plan-current-right { flex: 0 0 100%; flex-direction: column; align-items: center; gap: .5rem; }
  .plan-current-right .plan-current-pct { text-align: center; }

  /* Ergebnisse: Suchfeld und Controls flexibel */
  #studentSearch { width: auto; flex: 1 1 120px; min-width: 0; }
  .results-card .card-header > div:first-child { width: 100%; }
  .results-card .card-header > div:last-child { flex-wrap: wrap; }
  /* Ergebnisse-Grid: auf Mobile Date-Input und Edit-Button ausblenden,
     da der Score-Button-Klick bereits den Edit-Modal öffnet (inkl. Datum). */
  .rg-date-input,
  .rg-details-btn { display: none !important; }
  .rg-date-clear { display: none !important; }
  /* Schülerspalte/Header soll dann nur so breit wie der längste Schülername sein —
     dafür Padding etwas reduzieren, damit die Spalte tight wird. */
  .rg-corner   { padding: .35rem .25rem; }
  .rg-student  { padding: .35rem .35rem; }

  /* Page-Actions: Buttons dürfen umbrechen */
  .page-actions { flex-wrap: wrap; }

  /* Responsive Helper: Element nur auf grösseren Viewports anzeigen */
  .sm-hide { display: none; }
  /* Element nur auf kleinen Viewports anzeigen */
  .sm-only { display: inline; }

  /* Filter-Bar: Selects dürfen umbrechen und auf volle Breite gehen */
  .filter-form { width: 100%; }
  .filter-bar .form-select,
  .filter-bar .form-input { min-width: 0; flex: 1 1 160px; max-width: 100%; }

  /* Score-Verteilung (Statistik): Label schmaler */
  .score-dist-label { width: 130px; }
  .score-dist-count { width: 60px; }

  /* Bewertungsstufen-Zeilen: umbrechen */
  .level-row { flex-wrap: wrap !important; }
  .level-label-group { flex: 1 1 100% !important; order: -1; }

  /* Seitentitel: nicht überlaufen. Die Breitenbegrenzung stammt aus der Zeit,
     als der Titel neben Burger und Bedienelementen stand; in der eigenen
     Titelzeile (siehe Block «Schmale Bildschirme») wird sie unten aufgehoben. */
  .topbar .page-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: calc(100vw - 180px); }

  /* Seitenfuß: seitliche Abstände verkleinern */
  .page-footer { padding: .75rem 1rem; }

  /* Modals: volle Breite minus kleinen Rand */
  .modal-dialog { max-width: calc(100vw - 2rem); }
}

/* Schmale Bildschirme: Seitentitel und Stern in eine eigene Zeile.
   In einer Zeile blieben bei 320 px nur 53 px für den Titel übrig (Burger,
   Stern, Suche, Erscheinungsbild und Avatar belegen den Rest), der Titel war
   praktisch unlesbar. Als eigene Zeile hat er die volle Breite. */
@media (max-width: 640px) {
  :root { --topbar-h: 105px; }
  .topbar {
    height: auto; min-height: var(--topbar-h);
    flex-wrap: wrap; align-items: center; row-gap: .35rem;
    padding: .55rem 1rem .65rem;
  }
  /* Die Kinder der linken Gruppe werden zu direkten Elementen der Topbar,
     damit der Titel in die zweite Zeile umbrechen kann. */
  .topbar-left { display: contents; }
  /* Der Knopf trägt 6.4 px Innenpolster: ohne den Ausgleich begännen seine
     Balken 6 px weiter rechts als der Titel darunter, die linke Kante wirkte
     verschoben. Dasselbe rechts für das letzte Bedienelement. */
  .sidebar-toggle { order: 1; margin-left: -.4rem; }
  .topbar-right   { order: 2; margin-left: auto; margin-right: -.25rem; }
  /* Titel links, Stern rechts: zwei saubere Kanten statt eines Sterns, der
     mitten in der Zeile hängt. */
  .topbar-page    { order: 3; flex: 0 0 100%; gap: .5rem; justify-content: space-between; }
  /* In der eigenen Zeile darf der Titel die volle Breite nutzen; die alte
     Begrenzung auf «100vw minus 180px» galt der einzeiligen Topbar. */
  .topbar .page-title { font-size: 1.05rem; max-width: none; flex: 1 1 auto; }
  .fav-form       { flex: 0 0 auto; margin-right: -.25rem; }
  .topbar-theme-toggle {
    width: 38px; height: 38px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
  }
  /* Zwischen Menü-Knopf und Symbolen klaffte sonst eine leere Fläche (bei
     390 px rund 190 px). Die Suche füllt sie als flaches Feld: Die Lücke ist
     weg und die Suche ist sichtbar, statt sich hinter einem Symbol zu
     verstecken. Angetippt öffnet sie dieselbe Suchleiste wie bisher. */
  .topbar-right { flex: 1 1 auto; min-width: 0; gap: .5rem; }
  .search-toggle-btn {
    flex: 1 1 auto; min-width: 0; height: 38px;
    display: inline-flex; align-items: center; justify-content: flex-start; gap: .45rem;
    padding: 0 .75rem; margin-left: .75rem;
    /* Rahmen, Rundung und Schrift wie das breite Suchfeld, damit der Knopf als
       dasselbe Element gelesen wird (Knöpfe erben die Schriftart nicht). */
    border: 1.5px solid var(--border); border-radius: var(--radius);
    background: var(--bg-app); color: var(--text-muted);
    font-family: var(--font);
  }
  .search-toggle-btn svg { width: 17px; height: 17px; flex-shrink: 0; }
  .search-toggle-label {
    display: inline; font-size: .85rem; font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

}

@media (max-width: 640px) {
  /* View-Tabs: Beschriftung ausblenden, nur Icon anzeigen */
  .view-tab-label { display: none; }
  .view-tab { gap: 0; padding: .5rem .75rem; }
  /* Tabellenspalten auf kleinen Screens ausblenden */
  .hide-sm { display: none; }
  /* Jahresplanung: Fortschrittsbalken auf Mobile ausblenden */
  .plan-progress-cell { display: none; }
  /* Jahresplanung: Filter-Aktionen umbrechen */
  .plan-filter-actions { margin-left: 0 !important; flex-wrap: wrap; }
  /* Jahresplanung: Drag-Handle auf Mobile ausblenden */
  .plan-item .drag-handle { display: none; }
  /* Jahresplanung: Action-Buttons übereinander */
  .plan-item-actions { flex-direction: column; }
  /* Jahresplanung: lange Erfassungsnamen umbrechen statt abschneiden, Zeile enger */
  .plan-item { gap: .5rem !important; padding: .65rem .75rem !important; }
  .plan-item strong { overflow-wrap: anywhere; }
  /* Quellen-Filter: auf schmalen Bildschirmen nur das Icon. Das Menü bleibt
     rechtsbündig am Knopf, sonst ragt es über den Bildschirmrand hinaus. */
  .rsf-label { display: none; }
  /* Notnagel ohne JS: passt in jeden Bildschirm, das Zurückschieben in den
     sichtbaren Bereich übernimmt das Skript in result-source-toggle.php. */
  .rsf-menu { min-width: 200px; max-width: calc(100vw - 1rem); }
  /* Modal-Footer: Buttons umbrechen auf Mobile */
  .modal-footer { flex-wrap: wrap; }
}

@media (max-width: 480px) {
  .stat-cards { grid-template-columns: 1fr; }
  .area-grid { grid-template-columns: 1fr !important; }
  .login-card { padding: 1.75rem 1.25rem; }
  .class-cards { grid-template-columns: 1fr; }
  .quick-actions { grid-template-columns: 1fr; }

  /* View-Toggle: volle Breite auf Mobile */
  .view-toggle { width: 100%; margin-left: 0; }
  .view-toggle-btn { flex: 1; justify-content: center; }

  /* Filter-Bar auf sehr kleinen Bildschirmen: jeder Select und Button geht auf volle Breite */
  .filter-bar .form-select,
  .filter-bar .form-input { flex: 1 1 100%; }
  .filter-bar > .btn { flex: 1 1 100%; justify-content: center; }

  /* Heatmap Kompetenz-Stats: Anzahl-Spalte ausblenden */
  .comp-stat-count { display: none; }

  /* Score-Verteilung: noch schmaler */
  .score-dist-label { width: 110px; }
  .score-dist-count { width: 50px; }

}

/* ============================================================
   PREFERENCE OPTIONS (Profile/Settings)
   ============================================================ */
.pref-options { display: flex; flex-wrap: wrap; gap: 1rem; font-size: .8rem; }
.pref-option {
  display: flex; align-items: flex-start; gap: .75rem;
  padding: 1rem 1.25rem; border: 2px solid var(--border); border-radius: var(--radius-lg);
  cursor: pointer; flex: 1 1 180px; transition: all var(--transition);
}
.pref-option:hover { border-color: var(--accent); background: var(--accent-light); }
.pref-option-active { border-color: var(--accent); background: var(--accent-light); }
.pref-option input[type="radio"] { margin-top: .2rem; accent-color: var(--accent); }
.pref-option svg { flex-shrink: 0; color: var(--text-muted); margin-top: .1rem; }
.pref-option-active svg { color: var(--accent); }

/* ============================================================
   RESULTS: VIEW TOGGLE
   ============================================================ */
.view-toggle { display: inline-flex; border: 2px solid var(--primary); border-radius: var(--radius); overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,.08); }
.view-toggle-btn {
  display: flex; align-items: center; gap: .35rem;
  padding: .45rem 1.1rem; font-size: .85rem; font-weight: 700; font-family: var(--font);
  background: transparent; border: none; color: var(--primary);
  cursor: pointer; transition: all var(--transition);
}
.view-toggle-btn:not(:last-child) { border-right: 2px solid var(--primary); }
.view-toggle-btn:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.view-toggle-btn.active { background: var(--primary); color: #fff; }
.view-toggle-btn svg { flex-shrink: 0; }

/* ============================================================
   RESULTS: OPEN-ONLY TOGGLE
   ============================================================ */
.results-open-toggle {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-size: .85rem;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.results-open-toggle input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.results-open-toggle-track {
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: var(--neutral-200, #d1d5db);
  position: relative;
  transition: background var(--transition), box-shadow var(--transition);
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .08);
  flex-shrink: 0;
}
.results-open-toggle-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .24);
  transition: transform var(--transition);
}
.results-open-toggle input[type="checkbox"]:checked + .results-open-toggle-track {
  background: var(--primary);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 70%, #000 10%);
}
.results-open-toggle input[type="checkbox"]:checked + .results-open-toggle-track::after {
  transform: translateX(16px);
}
.results-open-toggle input[type="checkbox"]:focus-visible + .results-open-toggle-track {
  outline: 2px solid color-mix(in srgb, var(--primary) 45%, white);
  outline-offset: 2px;
}
.results-open-toggle-label {
  font-weight: 600;
  color: var(--text-secondary);
}

/* ============================================================
   RESULTS: LIST VIEW
   ============================================================ */
.results-list { padding: 0; }
.results-list-student { border-bottom: 2px solid var(--border); }
.results-list-student:last-child { border-bottom: none; }
.results-list-header {
  display: flex; align-items: center; gap: .75rem;
  padding: .875rem 1.5rem; background: var(--neutral-light);
  font-weight: 700; font-size: .9rem; cursor: pointer;
  user-select: none; transition: background var(--transition);
}
.results-list-header:hover { background: var(--primary-xlight); }
.results-list-header .avatar { width: 30px; height: 30px; font-size: .75rem; }
.results-list-toggle { margin-left: auto; color: var(--text-muted); transition: transform var(--transition); }
.results-list-student.collapsed .results-list-toggle { transform: rotate(-90deg); }
.results-list-student.collapsed .results-list-body { display: none; }
.results-list-avg { margin-left: auto; margin-right: .5rem; font-size: .8rem; font-weight: 700; }
.results-list-body { padding: 0; }
.results-list-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .65rem 1.5rem .65rem 3.5rem;
  border-top: 1px solid var(--border); font-size: .85rem;
  transition: background var(--transition); cursor: pointer;
  flex-wrap: wrap;
}
.results-list-row:hover { background: var(--primary-xlight); }
.results-list-comp { flex: 1 1 220px; min-width: 0; font-weight: 500; display: flex; flex-direction: column; gap: .15rem; }
.results-list-comp-num { width: 22px; height: 22px; border-radius: 50%; background: var(--neutral-light); font-size: .7rem; font-weight: 800; display: flex; align-items: center; justify-content: center; color: var(--primary); flex-shrink: 0; }
.results-list-score { min-width: 52px; text-align: center; font-weight: 700; font-size: .85rem; padding: .2rem .5rem; border-radius: var(--radius-sm); flex-shrink: 0; }
.results-list-date { font-size: .75rem; color: var(--text-muted); min-width: 80px; text-align: right; flex-shrink: 0; }
/* Bewertetes Resultat ohne Erfassungsdatum: Hinweis in der Listenansicht. */
.results-list-date.results-list-date--warn { color: var(--warning); font-weight: 600; }
.results-list-date.results-list-date--warn::after { content: 'Datum fehlt'; }

@media (max-width: 640px) {
  .results-list-row { padding: .55rem .75rem .55rem 1.5rem; gap: .5rem; }
  .results-list-header { padding: .65rem .75rem; }
  .results-list-date { min-width: 0; text-align: left; }
  .results-list { overflow-x: hidden; }
}

/* ============================================================
   VIEW TABS (Klassenansicht / Schülerübersicht)
   ============================================================ */
.view-tabs {
  display: flex;
  gap: .375rem;
  margin-bottom: 1.25rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .375rem;
  box-shadow: var(--shadow-sm);
  width: 100%;
}
.view-tab {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem 1.1rem;
  border-radius: calc(var(--radius) - 2px);
  font-size: .875rem;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  transition: background var(--transition), color var(--transition), box-shadow var(--transition);
  white-space: nowrap;
  width: 100%;
  justify-content: center;
}
.view-tab:hover { color: var(--primary); background: var(--primary-xlight); text-decoration: none; }
.view-tab.active { background: var(--primary); color: #fff; box-shadow: 0 2px 8px rgba(30,58,95,.18); }
.view-tab svg { flex-shrink: 0; }
.view-tab-label { white-space: nowrap; }

/* Print */
@media print {
  .sidebar, .topbar, .page-actions, .filter-bar, .btn, .modal { display: none !important; }
  .main-content { margin-left: 0; }
  .page-content { padding: 0; }
  .card { box-shadow: none; border: 1px solid #ccc; page-break-inside: avoid; }
  body { background: white; }
}

/* Provider Badge */
.provider-badge {
    display: inline-block;
    font-size: .65rem;
    font-weight: 600;
    background: #F0FDF4;
    color: #166534;
    border: 1px solid #BBF7D0;
    border-radius: 4px;
    padding: .1rem .4rem;
    white-space: nowrap;
    vertical-align: middle;
    margin-left: .25rem;
}

/* LP21 Badge Tooltip */
.lp21-badge { position: relative; cursor: help; font-style: normal; }
.lp21-badge[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: #1e293b;
    color: #f1f5f9;
    font-size: .75rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    white-space: pre-line;
    padding: .45rem .65rem;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,.25);
    min-width: 260px;
    max-width: 480px;
    line-height: 1.5;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s;
    z-index: 9999;
}
.lp21-badge[data-tooltip]:hover::after { opacity: 1; }
/* Mit dem Finger bedient gibt es kein Hover, der Tooltip erscheint also nie.
   Ausgeblendet lässt er sich auch nicht mehr aufklappen: Mit seinen 260 px
   Mindestbreite ragte er neben schmalen Bildschirmen hinaus und erzeugte
   waagrechtes Scrollen, obwohl er unsichtbar war. */
@media (hover: none) {
  .lp21-badge[data-tooltip]::after { display: none; }
}

/* Info-Icon mit Tooltip */
.info-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #93C5FD;
    cursor: help;
    flex-shrink: 0;
    vertical-align: middle;
    transition: color .15s;
}
.info-icon:hover { color: #3B82F6; }
.info-icon[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: #1e293b;
    color: #f1f5f9;
    font-size: .75rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    white-space: pre-line;
    padding: .45rem .65rem;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,.25);
    min-width: 180px;
    max-width: 320px;
    line-height: 1.5;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s;
    z-index: 9999;
}
.info-icon[data-tooltip]:hover::after { opacity: 1; }

/* Kompakter Hover-Tooltip für Icon-Buttons (Toolbars). Breite = Text. */
.ex-tooltip { position: relative; }
.ex-tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(15, 23, 42, .88);
    color: #fff;
    font-size: .72rem;
    font-weight: 500;
    white-space: nowrap;
    padding: .25rem .5rem;
    border-radius: .3rem;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s;
    z-index: 100;
}
.ex-tooltip:hover::after { opacity: 1; }
.ex-tooltip-end::after { left: auto; right: 0; transform: none; }
.ex-tooltip-list::after {
    white-space: pre-line;
    text-align: left;
    max-width: 320px;
    min-width: 200px;
    font-weight: 500;
    line-height: 1.4;
    bottom: auto;
    top: calc(100% + 6px);
}
/* JS-enhanced: CSS-::after-Tooltip ausblenden, damit nur der im body
   gerenderte Floating-Tooltip sichtbar ist (Cut-off-frei). */
.ex-tooltip-jsenhanced::after { content: none !important; }
.ex-tooltip-floating {
    position: fixed;
    background: rgba(15, 23, 42, .92);
    color: #fff;
    font-size: .72rem;
    font-weight: 500;
    padding: .35rem .55rem;
    border-radius: .3rem;
    pointer-events: none;
    opacity: 0;
    transition: opacity .12s;
    z-index: 9999;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(0,0,0,.22);
}
.ex-tooltip-floating.is-visible { opacity: 1; }
.ex-tooltip-floating.is-list {
    white-space: pre-line;
    text-align: left;
    max-width: 320px;
    line-height: 1.4;
}

/* Wiederverwendbarer Zell-Tooltip (z. B. lange Antworten in Tabellen) */
.cell-tip { position: relative; }
.cell-tip[data-tooltip]:not([data-tooltip=""])::after {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    background: #1e293b;
    color: #f1f5f9;
    font-size: .75rem;
    font-weight: 400;
    white-space: pre-line;
    padding: .45rem .65rem;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,.25);
    max-width: 340px;
    line-height: 1.5;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s;
    z-index: 9999;
}
.cell-tip[data-tooltip]:not([data-tooltip=""]):hover::after { opacity: 1; }
/* Tooltip nach oben (für letzte Zeile, damit er nicht unten abgeschnitten wird) */
.cell-tip.cell-tip-up[data-tooltip]:not([data-tooltip=""])::after { top: auto; bottom: calc(100% + 6px); }

/* Sortierbare Tabellenspalten */
th[data-sort] { cursor: pointer; user-select: none; white-space: nowrap; }
th[data-sort]::after { content: ' \2195'; opacity: .3; font-size: .75em; }
th[data-sort][data-dir="asc"]::after { content: ' \2191'; opacity: .7; }
th[data-sort][data-dir="desc"]::after { content: ' \2193'; opacity: .7; }

/* Toast-Benachrichtigungen */
.toast-container { position: fixed; bottom: 5.25rem; right: 1.5rem; z-index: 10000; display: flex; flex-direction: column-reverse; gap: .5rem; pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: center; gap: .6rem; padding: .6rem 1rem; border-radius: var(--radius); font-size: .85rem; font-weight: 500; color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,.18); transform: translateX(120%); opacity: 0; transition: transform .3s ease, opacity .3s ease; }
.toast.show { transform: translateX(0); opacity: 1; }
.toast-success { background: #16a34a; }
.toast-error { background: #dc2626; }
.toast-info { background: #2563eb; }
.toast-icon { flex-shrink: 0; font-size: 1rem; line-height: 1; }
@media (max-width: 480px) { .toast-container { left: 1rem; right: 1rem; bottom: 4.75rem; } .toast { font-size: .8rem; } }

/* ── Kontext-Hilfe (FAB unten rechts, nur eingeloggte Seiten) ───────────── */
.help-fab-wrap { position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 400; }
.help-fab { width: 46px; height: 46px; border-radius: 50%; border: none; cursor: pointer;
    background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 20px -6px rgba(17,24,39,.45); transition: transform .12s, box-shadow .12s; }
.help-fab:hover { transform: translateY(-2px); box-shadow: 0 10px 26px -6px rgba(17,24,39,.5); }
.help-fab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.help-fab-popover { position: absolute; right: 0; bottom: calc(100% + .6rem); width: 340px; max-width: calc(100vw - 3rem);
    background: var(--bg-card); border: 1.5px solid var(--border); border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px -14px rgba(15,23,42,.45), 0 10px 24px -10px rgba(15,23,42,.30);
    padding: .85rem; display: none; }
/* Im Dark Mode wirken Schatten kaum → über einen helleren Rahmen abheben. */
[data-theme="dark"] .help-fab-popover { border-color: rgba(148,163,184,.30);
    box-shadow: 0 24px 60px -10px rgba(0,0,0,.70), 0 0 0 1px rgba(148,163,184,.10); }
.help-fab-wrap.open .help-fab-popover { display: block; }
/* Oberer Abstand (Titel → Einträge) gleich dem unteren (Einträge → „Alle Hilfe-Themen"):
   dort = .help-fab-content margin-bottom (.5rem) + .help-fab-link Padding-oben (.55rem). */
.help-fab-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; margin: 0 .15rem 1.05rem; }
.help-fab-head-main { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.help-fab-head-icon { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; color: var(--primary); }
.help-fab-head-icon svg { width: 22px; height: 22px; display: block; }
.help-fab-head-titles { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.help-fab-popover-title { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.help-fab-popover-page { font-size: .95rem; font-weight: 700; color: var(--text-primary); line-height: 1.25; }
.help-fab-open { text-decoration: none; color: var(--text-muted); font-size: 1rem; line-height: 1; padding: .15rem .3rem; border-radius: 6px; }
.help-fab-open:hover { background: var(--accent-light); color: var(--primary); }
.help-fab-link { display: block; text-decoration: none; border-radius: var(--radius); padding: .55rem .7rem; color: var(--text-primary); transition: background .12s; }
.help-fab-link:hover { background: var(--accent-light); }
.help-fab-link--all { font-size: .84rem; font-weight: 600; color: var(--primary); }
[data-theme="dark"] .help-fab-link--all { color: var(--accent); }
/* Inline-Hilfeinhalt (aus /hilfe?partial=1, single-source) */
.help-fab-content { max-height: min(56vh, 420px); overflow-y: auto; margin-bottom: .5rem; padding-right: .15rem; }
.help-fab-loading { font-size: .82rem; color: var(--text-muted); padding: .4rem .2rem; }
.help-fab-empty { font-size: .82rem; color: var(--text-muted); margin: .2rem; }
.help-fab-content .hilfe-section-header { display: flex; align-items: center; gap: .5rem; margin: 0 0 .65rem; }
.help-fab-content .hilfe-section-icon { width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.help-fab-content .hilfe-section-icon svg { width: 17px; height: 17px; }
.help-fab-content .hilfe-section-header h2 { font-size: 1rem; margin: 0; color: var(--text-primary); }
.help-fab-content .hilfe-accordion { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: .4rem; overflow: hidden; }
/* Letzter Eintrag ohne Rand-Tail, damit der Abstand zu „Alle Hilfe-Themen" sauber
   nur aus content-margin + Link-Padding besteht (siehe .help-fab-head). */
.help-fab-content .hilfe-accordion:last-child { margin-bottom: 0; }
.help-fab-content .hilfe-accordion summary { cursor: pointer; list-style: none; padding: .5rem .65rem; font-size: .82rem; font-weight: 600; color: var(--text-primary); }
.help-fab-content .hilfe-accordion summary::-webkit-details-marker { display: none; }
/* Das „#" hinter dem Titel verlinkt den Eintrag auf /hilfe. Im Popover führt es
   aus dem Kontext heraus (dafür gibt es „In der Hilfe öffnen") und erbt mangels
   eigener Regel die blaue Linkfarbe – darum hier ausgeblendet. */
.help-fab-content .hilfe-anker { display: none; }
.help-fab-content .hilfe-accordion[open] summary { border-bottom: 1px solid var(--border); }
.help-fab-content .hilfe-accordion-body { padding: .55rem .65rem; font-size: .81rem; color: var(--text-secondary); line-height: 1.5; }
.help-fab-content .hilfe-accordion-body p { margin: 0 0 .5rem; }
.help-fab-content .hilfe-accordion-body p:last-child { margin: 0; }
.help-fab-content .hilfe-accordion-body ol, .help-fab-content .hilfe-accordion-body ul { margin: 0 0 .5rem; padding-left: 1.15rem; }
.help-fab-content .hilfe-accordion-body li { margin-bottom: .25rem; }
.help-fab-content .hilfe-accordion-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.help-fab-content .hilfe-accordion-body strong { color: var(--text-primary); }
.help-fab-content .pro-badge { font-size: .56rem; font-weight: 700; padding: .08rem .3rem; border-radius: 5px; background: linear-gradient(135deg,#3B82F6,#8B5CF6); color: #fff; margin-left: .25rem; vertical-align: middle; text-transform: uppercase; }
@media print { .help-fab-wrap { display: none; } }

/* ── Kontext-Navigation (eval + exercise) ────────────────────────────────── */
.eval-context-nav{display:flex;gap:.375rem;padding:.375rem;margin-bottom:1rem;overflow-x:auto;-webkit-overflow-scrolling:touch;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);flex-wrap:wrap}
.eval-nav-item{display:inline-flex;align-items:center;justify-content:center;flex:1;padding:.5rem .9rem;border-radius:calc(var(--radius) - 2px);font-size:.875rem;line-height:1.5;font-weight:500;white-space:nowrap;text-decoration:none;color:var(--text-muted);background:transparent;transition:background var(--transition),color var(--transition)}
.eval-nav-item:hover{background:var(--primary-xlight,rgba(59,130,246,.08));color:var(--primary);text-decoration:none}
.eval-nav-item.active{font-weight:600;color:#fff;background:var(--primary);box-shadow:0 2px 8px rgba(30,58,95,.18)}
.eval-nav-item.active:hover{background:var(--primary);color:#fff}
/* Tab-Icons: klein, folgen der Textfarbe (currentColor → gedämpft/aktiv weiss) */
/* Sechs Einträge: Symbole erst ab 1340 px, sonst bricht die Leiste um */
@media(max-width:1340px) and (min-width:641px){.eval-nav-item>svg{display:none}}
.eval-nav-item>svg{width:16px;height:16px;flex-shrink:0;margin-right:.4rem;opacity:.85}
.eval-nav-item.active>svg{opacity:1}
@media(max-width:640px){.eval-context-nav{gap:.25rem;padding:.25rem}.eval-nav-item{padding:.4rem .75rem;font-size:.8rem;flex:1 1 auto;text-align:center;justify-content:center}
  /* Auf schmalen Screens Icons ausblenden, damit die Leiste nicht breiter wird */
  .eval-nav-item>svg{display:none}}

/* ── Online-Übungen Kontext-Navigation ───────────────────────────────────── */
/* Exercise tab count badge */
.ex-subject-badge {
  display:inline-block; font-size:.68rem; font-weight:600; padding:.1rem .45rem;
  border-radius:.25rem; background:var(--primary-xlight); color:var(--primary);
  vertical-align:middle;
}
.ex-grade-badge {
  display:inline-block; font-size:.68rem; font-weight:500; padding:.1rem .45rem;
  border-radius:.25rem; background:var(--neutral-light); color:var(--text-muted);
  vertical-align:middle;
}
.diff-badge { display:inline-block; font-size:.72rem; font-weight:600; padding:.15rem .45rem; border-radius:.3rem; white-space:nowrap; }
.diff-easy   { background:#D1FAE5; color:#065F46; }
.diff-medium { background:#FEF3C7; color:#92400E; }
.diff-hard   { background:#FEE2E2; color:#B91C1C; }
/* Die drei Tints sind fest hell; im Dark Mode als dezente Flächen mit hellem
   Text (gleiches Muster wie .flash-* und .info-box). */
[data-theme="dark"] .diff-easy   { background:rgba(74,222,128,.16);  color:#86EFAC; }
[data-theme="dark"] .diff-medium { background:rgba(251,191,36,.16);  color:#FDE68A; }
[data-theme="dark"] .diff-hard   { background:rgba(248,113,113,.16); color:#FCA5A5; }
.ex-tab-count {
  display: inline-block;
  min-width: 1.6em; padding: 0 .55em; margin-left: .35rem;
  font-size: .75em; font-weight: 700;
  /* line-height: 2 ergibt zusammen mit font-size: .75em eine Linebox von
     genau 1.5em (Parent-Einheit) — gleich gross wie die Parent-Linebox
     (1em × 1.5). Damit zentriert align-items:center im Tab zwei gleich
     hohe Boxen und kein Sub-Pixel-Rounding kann das Zentrum verschieben. */
  line-height: 2;
  border-radius: 99px;
  background: rgba(255,255,255,.25); color: inherit;
  text-align: center;
}
.eval-nav-item:not(.active) .ex-tab-count {
  background: var(--bg-subtle, rgba(0,0,0,.06)); color: var(--text-muted);
}

/* Exercise assign layout */
/* Zwei Spalten nur, wenn beide mindestens 340 px bekommen (mit Sidebar erst ab
   etwa 1100 px Fensterbreite); sonst untereinander. minmax(0, …) verhindert,
   dass breiter Inhalt einer Spalte die andere zusammendrückt. */
.assign-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 1.5rem;
  align-items: start;
}
.assign-grid > * { min-width: 0; }
.assign-grid .card-header { flex-wrap: wrap; gap: .5rem; }
.assignment-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: .5rem;
  background: var(--bg-card);
}
.assignment-item-header {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .75rem;
}
.assignment-item-edit {
  display: none;
  padding: .75rem 1rem;
  border-top: 1px solid var(--border);
  background: var(--bg-subtle, #f9fafb);
}

.exercise-subnav-wrapper {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  /* Gleicher Abstand wie .eval-context-nav und .filter-bar (1rem). */
  margin-bottom: 1rem;
  overflow: hidden;
}
/* When inside wrapper, strip the nav's own card chrome */
.exercise-subnav-wrapper .eval-context-nav {
  border: none;
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 0;
  background: transparent;
}
.exercise-subnav-breadcrumb {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .1rem;
  padding: .5rem 1rem;
  background: var(--bg-subtle, rgba(0,0,0,.025));
  border-bottom: 1px solid var(--border);
}
.exercise-subnav-breadcrumb a {
  color: var(--primary);
  font-weight: 500;
  text-decoration: none;
}
.exercise-subnav-breadcrumb a:hover { text-decoration: underline; }
.exercise-subnav-sep {
  color: var(--text-muted);
  font-size: .85em;
  line-height: 1;
}
.exercise-subnav-title {
  font-weight: 600;
  color: var(--text-primary);
}

/* Onboarding */
@media (max-width: 640px) {
    .onboarding-step { flex-direction: row; flex-wrap: wrap !important; }
    .onboarding-btn { width: 100%; text-align: center; margin-top: .25rem; }
}

/* ── Resultat-Quellen-Toggle ── */
/* ── Kompakte Filterleiste: Nebenfilter im Aufklapp-Menü ──────────────────
   Markup: includes/filter-popover.php. Der Knopf zeigt die Anzahl aktiver
   Nebenfilter, daneben stehen sie als Chips zum Entfernen. Abschaltbar über
   die Konstante FILTER_POPOVER; dann rendern die Seiten wieder ihre Selects. */
.fpop-wrap { display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.fpop { position: relative; flex-shrink: 0; }
.fpop > summary {
  list-style: none;
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .45rem .75rem;
  /* Gleich hoch wie die Selects der Filterleiste daneben (44 px). */
  min-height: 44px;
  font-size: .85rem; font-weight: 600; font-family: var(--font);
  color: var(--text-secondary);
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer; white-space: nowrap;
  transition: border-color var(--transition), color var(--transition);
}
.fpop > summary::-webkit-details-marker { display: none; }
.fpop > summary::marker { content: ''; }
.fpop > summary:hover { border-color: var(--primary); color: var(--primary); }
.fpop > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.fpop--aktiv > summary { color: var(--primary); border-color: var(--primary); }
.fpop-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 .25rem;
  font-size: .7rem; font-weight: 800; line-height: 1;
  color: #fff; background: var(--primary); border-radius: 999px;
}
.fpop-caret { display: inline-flex; align-items: center; color: var(--text-muted); transition: transform .15s ease; }
.fpop[open] .fpop-caret { transform: rotate(180deg); }
.fpop-menu {
  /* Unter der klebenden Kopfzeile (.topbar, z-index 50): Beim Scrollen soll das
     Menü hinter den Kopf gleiten, nicht darüber. */
  position: absolute; left: 0; top: calc(100% + .4rem); z-index: 40;
  display: flex; flex-direction: column; gap: .5rem;
  min-width: 260px; max-width: calc(100vw - 2rem); padding: .75rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.fpop-menu .form-select { width: 100%; max-width: none; }
.fpop-menu [hidden] { display: none; }
/* «Anwenden»: Das Menü sendet erst auf Knopfdruck, damit Fach, Bereich und
   Erfassung in einem Zug gesetzt werden können. Solange nichts geändert wurde,
   ist der Knopf ruhig (deaktiviert), mit der ersten Änderung wird er aktiv. */
.fpop-apply { width: 100%; justify-content: center; margin-top: .15rem; }
.fpop-apply:disabled { opacity: .45; cursor: default; }
/* Ansicht-Umschalter im Menü: volle Breite, Knöpfe gleich breit. */
.fpop-menu .view-toggle { width: 100%; margin-left: 0 !important; }
.fpop-menu .view-toggle-btn { flex: 1; justify-content: center; }
/* Aktive Filter bleiben sichtbar, damit niemand auf einer Teilmenge rechnet. */
.fpop-chip {
  /* Auch als <button> genutzt (JS-gesteuerte Leisten), darum Schrift und
     Zeiger explizit setzen. */
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--font); cursor: pointer; appearance: none;
  max-width: 240px; min-height: 36px; padding: .35rem .5rem .35rem .65rem;
  font-size: .78rem; font-weight: 600;
  color: var(--primary); background: rgba(59,130,246,.10);
  border: 1px solid rgba(59,130,246,.25); border-radius: 999px;
  text-decoration: none;
  transition: background var(--transition), border-color var(--transition);
}
.fpop-chip:hover { background: rgba(59,130,246,.18); border-color: var(--primary); text-decoration: none; }
.fpop-chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
[data-theme="dark"] .fpop-chip { background: rgba(96,165,250,.14); border-color: rgba(96,165,250,.3); }
/* --primary ist im Dark Mode eine Flächenfarbe: als Schrift auf dem blauen
   Chip-Grund nur 2.6:1. --accent erreicht mindestens 4.5:1 (auch unten bei
   der gefilterten Quelle, dem aktiven Menüpunkt und dem aktiven Filterknopf). */
[data-theme="dark"] .fpop-chip { color: var(--accent); }
[data-theme="dark"] .fpop-chip:hover { border-color: var(--accent); }
[data-theme="dark"] .fpop--aktiv > summary { color: var(--accent); border-color: var(--accent); }
/* Zurücksetzen schliesst die Chip-Reihe ab: gleiche Form, aber neutral, damit
   es nicht wie ein weiterer gesetzter Filter aussieht. */
.fpop-chip--reset { color: var(--text-muted); background: transparent; border-color: var(--border); font-weight: 600; }
.fpop-chip--reset:hover { color: var(--text-primary); background: var(--neutral-light); border-color: var(--text-muted); }
[data-theme="dark"] .fpop-chip--reset { background: transparent; border-color: var(--border); color: var(--text-muted); }
[data-theme="dark"] .fpop-chip--reset:hover { color: var(--text-primary); border-color: var(--text-muted); }

/* ── Quellen-Filter (Alle / Manuell / Online-Übungen) ─────────────────────
   Schmaler Knopf mit dem Icon der aktiven Quelle, Optionen im Aufklapp-Menü.
   Markup: includes/result-source-toggle.php. Ist gefiltert, bleibt das am
   Knopf sichtbar (Tint + Punkt), damit niemand unbemerkt auf einer Teilmenge
   der Resultate arbeitet. */
.rsf { position: relative; flex-shrink: 0; }
.rsf > summary {
  list-style: none;
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .5rem .8rem;
  /* Standardplatz ist die Filterleiste: gleich hoch wie die Selects (44 px). */
  min-height: 44px;
  font-size: .875rem; font-weight: 600; font-family: var(--font);
  color: var(--text-secondary);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.rsf > summary::-webkit-details-marker { display: none; }
.rsf > summary::marker { content: ''; }
.rsf > summary:hover { border-color: var(--primary); color: var(--primary); }
.rsf > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.rsf-ic { display: inline-flex; align-items: center; line-height: 1; }
.rsf-caret { display: inline-flex; align-items: center; color: var(--text-muted); transition: transform .15s ease; }
.rsf[open] .rsf-caret { transform: rotate(180deg); }
/* Gefiltert: getönt, plus Punkt als Signal auch dort, wo nur das Icon steht. */
.rsf--gefiltert > summary { position: relative; color: var(--primary); border-color: var(--primary); background: rgba(59,130,246,.10); }
.rsf--gefiltert > summary::after {
  content: ''; position: absolute; top: -4px; right: -4px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--primary); border: 2px solid var(--bg-app);
}
.rsf-menu {
  /* Wie beim Filter-Menü: bleibt unter der klebenden Kopfzeile. */
  position: absolute; right: 0; top: calc(100% + .35rem); z-index: 40;
  min-width: 220px; padding: .3rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.rsf-item {
  display: flex; align-items: center; gap: .45rem;
  padding: .5rem .6rem;
  font-size: .84rem; font-weight: 500;
  color: var(--text-secondary); text-decoration: none;
  border-radius: calc(var(--radius) - 3px);
  white-space: nowrap;
}
.rsf-item:hover { background: var(--neutral-light); color: var(--text-primary); text-decoration: none; }
.rsf-item.is-active { color: var(--primary); font-weight: 700; }
.rsf-check { display: inline-flex; align-items: center; width: 14px; flex-shrink: 0; }
/* Nur für Screenreader (sichtbar steht am Knopf bloss Icon + Kurzlabel). */
.rsf .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
[data-theme="dark"] .rsf--gefiltert > summary { background: rgba(96,165,250,.14); color: var(--accent); border-color: var(--accent); }
[data-theme="dark"] .rsf-item.is-active { color: var(--accent); }
/* Ausnahme Klassenvergleich ohne Filterleiste: Dort steht der Knopf neben der
   Quer-Navigation und nimmt deren Zeilenhöhe an (51 px, ≤640 px 45 px). */
.eval-context-nav + .rsf > summary { min-height: 51px; }
@media (max-width: 640px) {
  .rsf > summary { padding: .4rem .6rem; font-size: .8rem; }
  .eval-context-nav + .rsf > summary { min-height: 45px; }
}

/* ── Row-menu dropdown (exercises, exercise-library) ─────────────────────── */
.row-menu { position:relative; display:inline-block; }
.row-menu-dropdown {
  display:none; position:fixed;
  background:var(--bg-card); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow-lg);
  min-width:170px; overflow:hidden; z-index:1000;
}
.row-menu-dropdown.open { display:block; }
.row-menu-dropdown button.dropdown-item {
  width:100%; text-align:left; background:none; border:none;
  cursor:pointer; font-family:inherit; font-size:.875rem;
}
/* Ohne diese zwei Zeilen gewinnt die Regel darüber auch im Hover-Zustand, und
   Knopf-Einträge blieben ohne Hintergrund, Link-Einträge nicht. */
.row-menu-dropdown button.dropdown-item:hover { background: var(--neutral-light); }
.row-menu-dropdown button.dropdown-danger:hover { background: var(--danger-light); }
/* Gleiche Höhe für Link- und Knopf-Einträge. */
.row-menu-dropdown .dropdown-item { line-height: 1.35; }


/* ── Upgrade page (Pro) ──────────────────────────────────────────────────── */
.upgrade-cta { background: linear-gradient(135deg,#EFF6FF,#F5F3FF); border: 1px solid #BFDBFE; }
[data-theme="dark"] .upgrade-cta { background: linear-gradient(135deg,#15233B,#1E1B33); border-color: var(--border); }
.iv-track { display:inline-flex; background:var(--bg-app-soft); border:1px solid var(--border); border-radius:8px; padding:3px; gap:3px; }
.iv-opt { display:block; padding:.4rem 1.1rem; border-radius:6px; font-size:.875rem; font-weight:600; color:var(--text-secondary); background:transparent; transition:background .15s,color .15s; cursor:pointer; }
.iv-opt.is-active { background:var(--bg-card); color:var(--text-primary); box-shadow:0 1px 3px rgba(0,0,0,.12); }

/* ── Schulhaus-Lizenz: Auswahlkarten (Tier/Zahlungsart) ──────────────────── */
.lic-pick { display:flex; align-items:center; gap:.875rem; padding:.75rem 1rem; border-radius:8px; border:2px solid var(--border); background:var(--bg-card); cursor:pointer; transition:border-color .15s,background .15s; }
.lic-pick.is-selected { border-color:#7C3AED; background:#F5F3FF; }
[data-theme="dark"] .lic-pick.is-selected { border-color:#8B5CF6; background:#2A1E45; }
.lic-pick.is-current { cursor:not-allowed; }
.lic-pick.is-disabled { background:var(--bg-subtle); cursor:not-allowed; opacity:.55; }

/* ── Schulhaus-Lizenz: Statusboxen (Light-Farben behalten, Dark adaptieren) ─ */
.lic-box--danger  { background:#FEF2F2; border:1px solid #FECACA; color:#991B1B; }
.lic-box--info    { background:#EFF6FF; border:1px solid #BFDBFE; color:#1E40AF; }
.lic-box--warning { background:#FFFBEB; border:1px solid #FDE68A; color:#92400E; }
.lic-box--purple  { background:#F5F3FF; border:1px solid #DDD6FE; color:#5B21B6; }
.lic-box--neutral { background:var(--bg-subtle); border:1px solid var(--border); }
[data-theme="dark"] .lic-box--danger  { background:#3A1A1A; border-color:rgba(248,113,113,.40); color:#FCA5A5; }
[data-theme="dark"] .lic-box--info    { background:#15233B; border-color:rgba(96,165,250,.40); color:#BFDBFE; }
[data-theme="dark"] .lic-box--warning { background:#3A2A12; border-color:rgba(251,191,36,.40); color:#FDE68A; }
[data-theme="dark"] .lic-box--purple  { background:#2A1E45; border-color:rgba(167,139,250,.40); color:#DDD6FE; }

/* ============================================================
   Hübsche Tooltips für die Diagramme/Anzeigen. Wird per JS
   (templates/layout_end.php) NUR aus [data-chart-tip] gespeist
   (Boxplot-Segmente, Streuungs-Kennzahlen). Folgt dem Cursor.
   Bewusst ein eigenes Attribut, damit die eigenständigen
   data-tip-Tooltips anderer Seiten (z. B. adaptive-recommendations,
   user-settings-stats, ueben/dashboard) unberührt bleiben.
   ============================================================ */
#ls-tooltip {
  position: fixed;
  top: 0; left: 0;
  z-index: 10000;
  max-width: 280px;
  padding: .5rem .65rem;
  border-radius: 9px;
  background: var(--tooltip-bg);
  color: var(--tooltip-text);
  border: 1px solid var(--tooltip-border);
  font-size: .78rem;
  line-height: 1.4;
  font-weight: 500;
  box-shadow: 0 8px 28px rgba(0,0,0,.28);
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px) scale(.98);
  transition: opacity .12s ease, transform .12s ease;
  white-space: normal;
  overflow-wrap: anywhere;
}
#ls-tooltip.is-visible { opacity: 1; transform: translateY(0) scale(1); }
/* Hinweis auf beschriftete Grafik-Elemente (Boxplot-Segmente etc.) */
svg [data-chart-tip] { cursor: help; }

/* ============================================================
   Bruchdarstellung: `[[3/4]]` in Aufgaben- und Erklärungstexten
   wird zu Zähler über Nenner. Erzeugt von exFormatText() in
   config.php und den gleichlautenden JS-Formatierern in
   exercise-editor, exercise-stats und adaptive-recommendations.
   Der Bruchstrich nimmt currentColor, damit er im Dark Mode und
   auf farbigen Flächen automatisch stimmt.
   ============================================================ */
.frac {
  display: inline-block;
  vertical-align: -0.42em;
  text-align: center;
  line-height: 1.1;
  font-size: .92em;
  margin: 0 .12em;
}
.frac .frac-z { display: block; padding: 0 .18em; border-bottom: 1px solid currentColor; }
.frac .frac-n { display: block; padding: 0 .18em; }

/* ============================================================
   Eingabefeld für Bruchantworten (Aufgabentyp «Bruch»).
   Markup in includes/fraction-input.php, genutzt im Übungs-Flow
   und in der Fehler-Kiste. Ganze links, darüber/darunter Zähler
   und Nenner mit Bruchstrich aus currentColor (Dark Mode).
   ============================================================ */
.frac-input { display: inline-flex; align-items: center; gap: .55rem; margin-top: .75rem; }
.frac-input input {
  width: 4.6rem; padding: .45rem .35rem;
  text-align: center; font-family: var(--font); font-size: 1.05rem; font-weight: 600;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-card); color: var(--text-primary);
  box-sizing: border-box;
}
.frac-input input:focus { outline: none; border-color: var(--border-focus); box-shadow: 0 0 0 3px rgba(59,130,246,.12); }
.frac-input input::placeholder { font-size: .78rem; font-weight: 500; color: var(--text-muted); }
.frac-input-whole { width: 3.9rem; }
.frac-input-frac { display: inline-flex; flex-direction: column; align-items: stretch; gap: .3rem; }
.frac-input-bar { display: block; height: 2px; border-radius: 2px; background: currentColor; }
.frac-input-hint { margin-top: .4rem; font-size: .8rem; color: var(--text-muted); }

/* ============================================================
   Sammelauswahl von Übungssets (/teacher/exercises,
   /teacher/exercise-library): «Alle auswählen» in der Kartenansicht
   und die Aktionsleiste am unteren Bildschirmrand.
   ============================================================ */
/* In der Kartenansicht verschwindet die Tabellen-Kopfzeile und mit ihr die
   «Alle auswählen»-Checkbox; sie bekommt dort einen eigenen Platz über der Liste. */
.bulk-select-all-mobile {
  display: none; align-items: center; gap: .5rem;
  padding: .6rem 1.25rem; border-bottom: 1px solid var(--border);
  font-size: .85rem; font-weight: 600; color: var(--text-secondary); cursor: pointer;
}
.bulk-select-all-mobile input { cursor: pointer; }
@media (max-width: 1100px) { .bulk-select-all-mobile { display: flex; } }

/* display wird per JS gesetzt (none/flex), darum steht es hier nicht. */
.bulk-toolbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 200;
  align-items: center; gap: .6rem 1rem; flex-wrap: wrap;
  padding: .85rem 1.25rem calc(.85rem + env(safe-area-inset-bottom, 0px));
  background: var(--primary); color: #fff; box-shadow: 0 -4px 12px rgba(0,0,0,.12);
}
/* Auf grossen Schirmen sind die zwei Gruppen keine Zeilen, sondern nur
   Klammern im Markup: alles steht nebeneinander (Reihenfolge über «order»). */
.bulk-toolbar-head, .bulk-toolbar-acts { display: contents; }
.bulk-toolbar-count { order: 1; font-weight: 600; }
.bulk-toolbar .bulk-assign-btn { order: 2; background: #fff; color: #1E3A5F; font-weight: 600; border: none; }
.bulk-toolbar .bulk-unassign-btn {
  order: 3; background: rgba(255,255,255,.14); color: #fff; font-weight: 600;
  border: 1px solid rgba(255,255,255,.55);
}
.bulk-toolbar .bulk-clear-btn {
  order: 4; margin-left: auto;
  background: rgba(255,255,255,.12); color: #fff; border: 1px solid rgba(255,255,255,.4);
  transition: background-color .12s ease, border-color .12s ease;
}
.bulk-toolbar .bulk-clear-btn:hover,
.bulk-toolbar .bulk-clear-btn:focus-visible {
  background: rgba(255,255,255,.22); border-color: rgba(255,255,255,.7); color: #fff;
}
.bulk-lbl-sm { display: none; }
/* Der Hilfe-Knopf unten rechts läge sonst auf der Leiste. */
body.bulk-active .help-fab-wrap { bottom: calc(1rem + var(--bulk-bar-h, 64px)); }

@media (max-width: 640px) {
  /* Zwei Zeilen statt vier: oben Anzahl und «Aufheben», darunter die Aktionen. */
  .bulk-toolbar { gap: .5rem; padding: .6rem .9rem calc(.6rem + env(safe-area-inset-bottom, 0px)); }
  .bulk-toolbar-head, .bulk-toolbar-acts { display: flex; align-items: center; gap: .5rem; flex: 1 1 100%; }
  .bulk-toolbar-count { font-size: .9rem; }
  .bulk-toolbar-acts .btn {
    flex: 1 1 0; min-width: 0;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .bulk-lbl-lg { display: none; }
  .bulk-lbl-sm { display: inline; }
}

/* ── Aufgaben-Vorschau: Lücken im Fragetext (assets/js/exercise-preview.js) ─
   Die Lösung steht an Stelle von «__LÜCKE__», bei Dropdown mit Lückennummer
   (bezieht sich auf «Lücke n:» in der Auswahlliste darunter). */
.preview-gap { text-decoration:underline; text-decoration-thickness:2px; text-underline-offset:2px; color:var(--success); font-weight:600; }
.preview-gap-nr { font-size:.65em; font-weight:700; color:var(--text-muted); margin-left:.1em; }

/* ── Öffentliche Seiten: Kopfzeile (.about-nav) ─────────────────────────────
   Jede öffentliche Seite blendet ihre Textlinks an einem eigenen Breakpoint aus
   (meist 640px). Mit vier Textlinks plus «Anmelden»/«Registrieren» passt die
   Leiste aber schon unter rund 880px nicht mehr, und «Registrieren» wurde aus
   dem Bild geschoben. Diese Untergrenze gilt für alle Seiten; das Menü
   (includes/public_mobile_nav.php) erscheint dann automatisch. */
@media (max-width: 880px) {
    .about-nav-links a:not(.btn-nav) { display: none; }
}

/* Lange zusammengesetzte Wörter («Lernstandserfassungen») in Seiten- und
   Kartentiteln trennen statt über den Rand zu schieben (lang="de"). */
.page-content h1, .page-content h2, .card-title { overflow-wrap: break-word; hyphens: auto; }
