/* ============================================================
   Meadow — Components
   Jede Klasse hier entspricht einem st.*-Eintrag aus Meadow.dc.html.
   Desktop ist die Basis; EINE Media Query (max-width:1023.98px) macht mobil.
   ============================================================ */

/* ============================================================
   SICHTBARKEIT / RESPONSIVE UTILITIES

   Die Utilities blenden nur AUS, sie schalten nie ein. Ein
   "display: revert !important" fuer den sichtbaren Fall wuerde den
   eigenen display-Wert des Elements ueberschreiben - ein
   .mw-title-btn.mw-only-mobile faellt damit von flex auf inline-block
   zurueck und sein Chevron bricht in die naechste Zeile um.
   ============================================================ */
@media (min-width: 1024px) {
  .mw-only-mobile { display: none !important; }
}
@media (max-width: 1023.98px) {
  .mw-only-desktop { display: none !important; }
}

/* ============================================================
   SHELL   (st.shell — ohne die Rahmen-Attrappe des Prototyps)
   ============================================================ */
.mw-shell {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
  background: var(--mw-bg);
}

.mw-body {
  position: relative;
  display: flex;
  flex: 1;
  overflow: hidden;
}

/* st.content */
.mw-content {
  flex: 1;
  overflow-y: auto;
  padding: var(--mw-content-pad);
}
.mw-content-inner {
  max-width: var(--mw-shell-max);
  margin-inline: auto;
}
/* Das Dashboard laesst den Deckel fallen (MeadowRoutes.IsWide). Unterhalb
   von --mw-shell-max aendert das nichts, dort greift die max-width ohnehin
   nie - die Regel wirkt also erst auf breiten Schirmen. */
.mw-content-inner--wide { max-width: none; }

/* ============================================================
   HEADER   (st.header / st.mHeader)
   ============================================================ */
.mw-header {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-shrink: 0;
  height: var(--mw-header-h);
  padding: 0 18px;
  background: var(--mw-header);
  border-bottom: 1px solid var(--mw-border);
  z-index: var(--mw-z-header);
}

/* Titel und Kennzeichen als eine Gruppe: mobil ist .mw-header
   justify-content: space-between, und ein viertes direktes Kind wuerde die
   Ohrmarke vom Titel weg an den rechten Rand schieben.

   Untereinander und nicht nebeneinander: die Ohrmarke gehoert zur Nummer
   darueber, sie steht nicht neben ihr. Nebeneinander konkurrierten ausserdem
   zwei verschieden gewichtete Angaben um dieselbe Zeile, und auf schmalen
   Schirmen musste die Ohrmarke gekuerzt werden. */
.mw-header__heading {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  min-width: 0;
}

/* Ohrmarke und Statusmarken. Die Ohrmarke kuerzt sich, wenn es eng wird;
   die Marken nicht - "Abgang" halb abgeschnitten waere schlimmer als gar
   nicht da. */
.mw-header__meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.mw-header__eartag {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--mw-font-mono);
  font-size: 13px;
  color: var(--mw-muted);
}
/* Die Marke sitzt auf der Grundlinie der Ohrmarke daneben und nicht auf der
   ihres eigenen Textes - sonst haengt sie sichtbar zu tief. */
.mw-header__meta .mw-tag { align-self: center; flex-shrink: 0; }

/* Der Seitentitel ist ein <h1> - Routes.razor fokussiert nach der Navigation
   per FocusOnNavigate Selector="h1", und ohne Ueberschrift bliebe der Fokus
   auf dem angeklickten Nav-Item haengen. Darin sitzt ein Button, der auf
   Desktop inert ist und mobil das Seitenmenue oeffnet. */
/* line-height eng gefuehrt: der Kopf ist am Desktop auf 60px festgenagelt
   (--mw-header-h), und darin muessen Titel und Ohrmarke untereinander
   Platz finden. */
.mw-header__title {
  min-width: 0;
  margin: 0;
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 24px;
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--mw-text);
}
.mw-title-btn__label {
  display: block;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mw-header__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* st.mTitleBtn — existiert nur mobil (siehe MeadowHeader) */
.mw-title-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  padding: 5px 8px;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  border-radius: var(--mw-r-xl);
  transition: background var(--mw-t);
}
.mw-title-btn__chevron { color: var(--mw-muted); flex-shrink: 0; }

/* ============================================================
   ICON-BUTTONS   (st.hamburger / st.iconBtn / st.iconBtnSm)
   ============================================================ */
.mw-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  border-radius: var(--mw-r-xl);
  background: none;
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t);
}
.mw-icon-btn--text { color: var(--mw-text); }

/* Der Zurueck-Pfeil im Seitenkopf ist ein a und kein button - deshalb die
   Reset-Werte, die ein button von sich aus mitbringt. Der Chevron ist
   derselbe wie ueberall, nur gedreht; genauso macht es .mw-pager__btn--prev. */
a.mw-icon-btn { text-decoration: none; }
.mw-icon-btn--back svg { transform: rotate(90deg); }

.mw-icon-btn-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-md);
  background: var(--mw-panel);
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t);
}

@media (hover: hover) {
  .mw-icon-btn:hover    { background: var(--mw-tint); color: var(--mw-text); }
  .mw-icon-btn-sm:hover { background: var(--mw-tint); color: var(--mw-text); }
}

/* ============================================================
   DRAWER   (st.drawerBackdrop / st.drawer / st.navGroupLabel / navItem)
   ============================================================ */
.mw-drawer-backdrop {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  background: var(--mw-backdrop-drawer);
  backdrop-filter: blur(2px);
  cursor: default;
  z-index: var(--mw-z-drawer-backdrop);
  animation: mwFade .2s ease;
}

.mw-drawer {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--mw-drawer-w);
  padding: 18px 14px;
  overflow-y: auto;
  background: var(--mw-navy);
  box-shadow: var(--mw-shadow-drawer);
  z-index: var(--mw-z-drawer);
  animation: mwSlide var(--mw-t-slide) var(--mw-ease);
}

.mw-drawer__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 8px 20px;
}
.mw-drawer__logo {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--mw-r-lg);
  object-fit: cover;
}
.mw-drawer__wordmark {
  font-family: var(--mw-font-display);
  font-weight: 800;
  font-size: 24px;
  letter-spacing: .02em;
  color: #fff;
}

.mw-nav-group {
  padding: 14px 12px 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
}

.mw-nav-item {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 14px;
  border-radius: var(--mw-r-xl);
  border-left: 3px solid transparent;
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, .74);
  background: transparent;
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t), border-color var(--mw-t);
}
.mw-nav-item > svg { flex-shrink: 0; }
.mw-nav-item.is-active {
  color: #fff;
  background: var(--mw-navy-active);
  border-left-color: var(--mw-nav-accent, var(--mw-primary));
}
@media (hover: hover) {
  .mw-nav-item:hover { color: #fff; background: rgba(255, 255, 255, .07); }
  .mw-nav-item.is-active:hover { background: var(--mw-navy-active); }
}

.mw-nav-item--success { --mw-nav-accent: var(--mw-success); }
.mw-nav-item--blue    { --mw-nav-accent: var(--mw-blue); }
.mw-nav-item--sage    { --mw-nav-accent: var(--mw-sage); }
.mw-nav-item--teal    { --mw-nav-accent: var(--mw-teal); }

/* ============================================================
   MOBILE TABBAR + FAB   (st.mTabbar / st.mFab / mtabS)
   Flex-Geschwister des Inhalts, nicht absolut positioniert:
   dann braucht die Leiste keinen z-index gegen den Inhalt und der
   ueberstehende FAB nur overflow:visible.
   ============================================================ */
.mw-tabbar {
  display: none;
  align-items: center;
  justify-content: space-around;
  flex-shrink: 0;
  height: calc(var(--mw-tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  background: var(--mw-panel);
  border-top: 1px solid var(--mw-border);
  overflow: visible;
  z-index: var(--mw-z-tabbar);
}

.mw-tabbar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 4px 10px;
  border: 0;
  background: none;
  font-size: 10px;
  font-weight: 600;
  color: var(--mw-muted);
  cursor: pointer;
  transition: color var(--mw-t);
}
.mw-tabbar__item.is-active { color: var(--mw-primary); }

.mw-fab {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--mw-fab);
  height: var(--mw-fab);
  flex-shrink: 0;
  margin-top: -26px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--mw-primary);
  color: #fff;
  cursor: pointer;
  box-shadow: var(--mw-glow-fab), 0 0 0 5px var(--mw-bg);
  transition: transform var(--mw-t), filter var(--mw-t);
  z-index: var(--mw-z-fab);
}
.mw-fab:active { transform: scale(.94); }

/* ============================================================
   MOBILE MENUES   (st.mMenuBackdrop / st.mMenu / st.mAddMenu / pmi / ami*)
   ============================================================ */
.mw-menu-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: default;
  z-index: var(--mw-z-menu-backdrop);
}

.mw-menu {
  display: none;
  position: fixed;
  /* Zentriert ueber inset + margin-inline, NICHT ueber translateX(-50%):
     mwPop animiert transform und haette das translateX waehrend der Animation
     ueberschrieben - das Menue waere bei jedem Oeffnen sichtbar von rechts
     eingefahren und erst am Ende in die Mitte gesprungen. Genau der Konflikt,
     den .mud-dialog.mw-dlg weiter unten schon beschreibt. */
  left: 0;
  right: 0;
  margin-inline: auto;
  /* 262px reichten fuer "Geplante Klauen Behandlung" nicht: das Label brach
     auf zwei Zeilen, wodurch die Zeilen unterschiedlich hoch wurden und die
     Icon-Spalte optisch verrutschte. 300px halten den laengsten Eintrag
     einzeilig und passen auch auf 320px-Geraeten noch in die max-width. */
  width: 300px;
  max-width: calc(100% - 26px);
  padding: 6px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-4xl);
  z-index: var(--mw-z-menu);
  animation: mwPop var(--mw-t-pop) var(--mw-ease);
}
.mw-menu--page {
  top: calc(var(--mw-header-h-m) + 8px);
  box-shadow: var(--mw-shadow-menu);
}
.mw-menu--add {
  bottom: calc(var(--mw-tabbar-h) + 24px + env(safe-area-inset-bottom));
  box-shadow: var(--mw-shadow-addmenu);
}

.mw-menu__item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 13px;
  border: 0;
  border-radius: var(--mw-r-lg);
  background: transparent;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  color: var(--mw-text);
  cursor: pointer;
  transition: background var(--mw-t-fast);
}
.mw-menu__item.is-active { color: var(--mw-primary); background: var(--mw-soft); }
@media (hover: hover) {
  .mw-menu__item:hover { background: var(--mw-tint); }
  .mw-menu__item.is-active:hover { background: var(--mw-soft); }
}

/* st.amiItem: 12px gap, 12px/13px padding */
.mw-menu--add .mw-menu__item { gap: 12px; padding: 12px 13px; }

.mw-menu__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: var(--mw-r-lg);
  background: var(--mw-soft);
  color: var(--mw-primary);
}

/* ============================================================
   BUTTONS   (st.primaryBtn / ghostBtn / addIconBtn / ghostIconBtn / openBtn)
   ============================================================ */
.mw-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid transparent;
  border-radius: var(--mw-r-xl);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: filter var(--mw-t), background var(--mw-t), border-color var(--mw-t);
}
.mw-btn--primary {
  background: var(--mw-primary);
  color: #fff;
  box-shadow: var(--mw-glow-btn);
}
.mw-btn--ghost {
  background: var(--mw-panel);
  color: var(--mw-text);
  border-color: var(--mw-border);
}
.mw-btn--plain {
  background: transparent;
  color: var(--mw-text);
  border-color: var(--mw-border);
}
.mw-btn--danger  { background: var(--mw-danger);  color: #fff; }
.mw-btn--warning { background: var(--mw-warning); color: #fff; }
.mw-btn--success { background: var(--mw-success); color: #fff; }

/* st.primaryBtn / st.ghostBtn: 10px 22px, radius 8 */
.mw-btn--wide { padding: 10px 22px; border-radius: var(--mw-r-lg); }
/* st.openBtn: 7px 14px, 13px, radius 8 */
.mw-btn--sm   { padding: 7px 14px; font-size: 13px; border-radius: var(--mw-r-lg); }
/* Nur ein Icon, kein Label - schmaler als die 16px Seitenpolsterung. */
.mw-btn--icon { padding-inline: 12px; }
/* Volle Breite (Auth-Karte, Formular-Fuesse) */
.mw-btn--block   { width: 100%; padding: 11px 22px; border-radius: var(--mw-r-lg); }
.mw-btn--spaced  { margin-top: 18px; }

.mw-btn:disabled { opacity: .55; cursor: default; box-shadow: none; }
@media (hover: hover) {
  .mw-btn:not(:disabled):hover { filter: brightness(1.06); }
  .mw-btn--ghost:not(:disabled):hover,
  .mw-btn--plain:not(:disabled):hover { filter: none; background: var(--mw-tint); }
}

/* ============================================================
   PANEL / KARTE   (st.chartCard als generische Flaeche)
   ============================================================ */
.mw-card {
  padding: 20px 22px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-3xl);
  box-shadow: var(--mw-shadow-card);
}
.mw-card-title {
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: .01em;
  color: var(--mw-text);
}

/* st.mSectionTitle */
.mw-section-title {
  margin-bottom: 12px;
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 19px;
  color: var(--mw-text);
}

/* ============================================================
   MOBIL — die eine Grenze.
   1023.98 statt 1023, damit gebrochene Viewport-Breiten (Browser-Zoom)
   nicht in eine Luecke fallen, die keine der beiden Queries trifft.
   ============================================================ */
@media (max-width: 1023.98px) {

  /* Header wird zur Titelleiste mit antippbarem Titel */
  .mw-header {
    height: auto;
    min-height: var(--mw-header-h-m);
    padding: 6px 14px 10px;
    gap: 8px;
    background: var(--mw-bg);
    border-bottom: 0;
    justify-content: space-between;
  }
  .mw-header__title { font-size: 20px; }
  .mw-header__actions { margin-left: 0; }

  /* Die Ohrmarke steht ohnehin unter der Nummer (siehe oben); mobil bekommt
     sie dafuer etwas mehr Luft, weil der Kopf hier height:auto ist.

     Zentriert, weil der Titel mobil selbst mittig zwischen Zurueck-Pfeil und
     Aktionen steht: linksbuendig haengen die beiden Zeilen an einer Kante,
     die sonst nirgends im Kopf vorkommt, und die laengere Ohrmarke zieht die
     Gruppe optisch schief. */
  .mw-header__heading { gap: 2px; align-items: center; text-align: center; }

  /* Inhalt: schmaleres Padding */
  .mw-content { padding: var(--mw-content-pad-m); }

  /* Drawer und Backdrop muessen die Tabbar ueberdecken */
  .mw-drawer-backdrop { position: fixed; }
  .mw-drawer {
    position: fixed;
    width: var(--mw-drawer-w-m);
    padding: 16px 12px;
    box-shadow: none;
  }
  .mw-drawer__brand { gap: 11px; padding: 6px 8px 18px; }
  .mw-drawer__logo { width: 40px; height: 40px; }
  .mw-drawer__wordmark { font-size: 22px; }
  .mw-nav-item { gap: 12px; }

  /* Tabbar und Menues erscheinen */
  .mw-tabbar        { display: flex; }
  .mw-menu-backdrop { display: block; }
  .mw-menu          { display: block; }
}

@media (max-width: 1023.98px) and (hover: hover) {
  .mw-title-btn:hover { background: var(--mw-tint); }
}

/* ============================================================
   404
   ============================================================ */
.mw-notfound {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  max-width: 420px;
  margin: 60px auto;
  padding: 36px 32px;
  text-align: center;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-5xl);
  box-shadow: var(--mw-shadow-card);
}
.mw-notfound__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  margin-bottom: 12px;
  border-radius: 14px;
  background: var(--mw-soft);
  color: var(--mw-primary);
}
.mw-notfound__title {
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 24px;
  color: var(--mw-text);
}
.mw-notfound__text {
  margin-bottom: 14px;
  font-size: 13px;
  color: var(--mw-muted);
}

/* ============================================================
   DASHBOARD
   ============================================================ */

/* Obere Reihe: KPI-Gitter + Aktionsspalte.
   Die min-width-Werte sind der Grund, warum es zwischen 700 und 1259px
   keine weitere Media Query braucht - die Reihe bricht von selbst um. */
.mw-dash-top {
  display: flex;
  gap: 20px;
  align-items: stretch;
  flex-wrap: wrap;
}

.mw-kpi-grid {
  flex: 2;
  min-width: 420px;
  display: grid;
  /* Statt fester Vierteilung: die Spalten kommen aus der verfuegbaren
     Breite - ohne eigene Media Query. Der Mindestwert ist auf 210px
     eingenordet, weil er nach beiden Seiten knapp ist: bei 200px kippt
     schon ein 1728px-Schirm auf sechs Spalten (die acht Kacheln brechen
     dann zu 6+2), bei 230px faellt ein 1280px-Laptop auf drei zurueck.
     Mit 210px bleibt es bis 1440px bei den heutigen vier Spalten und
     wird darueber fuenf. */
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
}

/* kpiCard */
.mw-kpi {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  box-shadow: var(--mw-shadow-card);
  color: inherit;
  cursor: pointer;
  transition: transform var(--mw-t), box-shadow var(--mw-t);
}
@media (hover: hover) {
  .mw-kpi:hover { transform: translateY(-2px); box-shadow: var(--mw-shadow-pop); }
}

.mw-kpi__title {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--mw-muted);
}
.mw-kpi__value {
  font-family: var(--mw-font-display);
  font-weight: 800;
  font-size: 40px;
  line-height: 1;
  color: var(--mw-primary);
}

/* Dritte Zeile: Vergleich zum Vorzeitraum - die Zeile, die der Prototyp
   als st.kpiSub hatte. Sie braucht kein Untertitel-Feld in der Tabelle,
   weil das Delta berechnet und nicht gespeichert wird.

   Bewusst NICHT gruen/rot: mehr Behandlungen sind eine schlechte
   Nachricht, mehr abgenommene Verbaende eine gute. Die Richtung ist in
   dieser Domaene nicht bedeutungstragend - eine Ampel wuerde die Haelfte
   der Kacheln falsch einfaerben. Pfeil und Zahl reichen. */
.mw-kpi__delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--mw-muted);
}
.mw-kpi__delta-arrow {
  font-size: 10px;
  line-height: 1;
}

/* Das erzeugte SQL im KPI-Dialog. Kein Ace-Editor: der Text ist nur zum
   Lesen, und eine zweite Editor-Instanz im selben Dialog waere sowohl
   verwirrend als auch teuer (Ace misst beim Initialisieren, siehe .mw-ace). */
.mw-sqlbox {
  margin: 0;
  max-height: 220px;
  overflow: auto;
  padding: 10px 12px;
  background: var(--mw-canvas);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre;
  color: var(--mw-text);
}

/* Kachel ohne Klick-Ziel: die Quelle hat keine Seite, die ihre Zeilen
   auflisten wuerde (siehe KpiSourceInfo.Route). Der Zeigefinger und das
   Anheben wuerden eine Navigation versprechen, die es nicht gibt. */
.mw-kpi--static {
  cursor: default;
}
@media (hover: hover) {
  .mw-kpi--static:hover { transform: none; box-shadow: var(--mw-shadow-card); }
}

/* Eine kaputte KPI muss von einer leeren unterscheidbar sein - vorher
   zeigten beide "--" und ein Tippfehler konnte monatelang wie
   "keine Daten" aussehen. */
.mw-kpi--error {
  border-color: var(--mw-danger);
}
.mw-kpi--error .mw-kpi__value {
  color: var(--mw-danger);
  font-size: 32px;
}

/* ── Live-Vorschau im KPI-Dialog ──────────────────────────────── */
.mw-kpi-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
  padding: 12px 14px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
}
.mw-kpi-preview__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.mw-kpi-preview__row {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.mw-kpi-preview__value {
  font-family: var(--mw-font-display);
  font-weight: 800;
  font-size: 32px;
  line-height: 1;
  color: var(--mw-primary);
}
.mw-kpi-preview__delta {
  font-size: 12px;
  font-weight: 600;
  color: var(--mw-muted);
}
.mw-kpi-preview__row.is-error .mw-kpi-preview__value {
  font-size: 24px;
  color: var(--mw-danger);
}

/* Die synthetische "KPI hinzufuegen"-Kachel (st.addRow-Optik) */
.mw-kpi--add {
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1.5px dashed var(--mw-border);
  box-shadow: none;
  color: var(--mw-primary);
}
.mw-kpi--add .mw-kpi__title { color: var(--mw-primary); font-weight: 700; }
.mw-kpi--add .mw-kpi__value { font-size: 32px; }

/* Aktionsspalte (act) */
.mw-dash-actions {
  /* Nicht flex:1 - sonst waechst die Spalte auf voller Breite auf ueber
     500px und die vier Buttons wirken auseinandergezogen. Der Rest der
     Reihe gehoert dem KPI-Gitter. Die Mobile-Query weiter unten setzt
     das wieder auf volle Breite. */
  flex: 0 0 clamp(280px, 22%, 380px);
  min-width: 250px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  justify-content: center;
}

.mw-act {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 16px 18px;
  border: 0;
  border-radius: var(--mw-r-2xl);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  color: #fff;
  cursor: pointer;
  transition: transform var(--mw-t), filter var(--mw-t);
}
.mw-act > svg { flex-shrink: 0; }
.mw-act--primary { background: var(--mw-primary); box-shadow: var(--mw-glow-primary); }
.mw-act--teal    { background: var(--mw-teal);    box-shadow: var(--mw-glow-teal); }
@media (hover: hover) {
  .mw-act:hover { filter: brightness(1.06); transform: translateY(-1px); }
}

/* Diagrammreihe */
.mw-dash-charts {
  display: flex;
  gap: 20px;
  margin-top: 20px;
  flex-wrap: wrap;
}
.mw-card--chart { flex: 1; min-width: 300px; }
.mw-card__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.mw-card__tools { display: flex; gap: 6px; }

/* st.barsRow — der Canvas-Container hat die gezeichnete Balkenhoehe */
.mw-chart-canvas {
  position: relative;
  height: var(--mw-bars-h);
}
/* Auf dem Desktop stand unter den Diagrammen bisher rund ein Drittel der
   Flaeche leer. Chart.js laeuft mit responsive:true und
   maintainAspectRatio:false, folgt dieser Hoehe also von selbst.
   Bewusst nur ab 1024px: mobil bleibt es bei --mw-bars-h. */
@media (min-width: 1024px) {
  .mw-chart-canvas { height: clamp(var(--mw-bars-h), 30vh, 300px); }
}

/* ============================================================
   OFFLINE-GATE   (st.backdrop + Karte)
   ============================================================ */
/* ============================================================
   STATUSBAND DER UEBERTRAGUNG   (loest das Offline-Gate ab)
   ============================================================
   Ein Streifen, kein Overlay. Das Gate legte sich als
   role="alertdialog" aria-modal="true" ueber eine App, die ohne
   Netz voll benutzbar ist - gegenueber einem Screenreader eine
   Falschaussage. Hier bleibt alles bedienbar; das Band sagt nur,
   was noch aussteht.

   Die vier Zustaende teilen sich die Grundform und wechseln nur
   die zwei Farbtoken. Farbe ist NIE das einzige Signal: Text und
   Glyph tragen die Aussage auch fuer sich. */
.mw-syncband {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  font-size: 13px;
  line-height: 1.35;
  border-bottom: 1px solid var(--mw-border);
  background: var(--mw-band-bg);
  color: var(--mw-band-fg);
  animation: mwFade var(--mw-t-pop) ease;
}
.mw-syncband--offline,
.mw-syncband--warten { --mw-band-bg: var(--mw-soft);     --mw-band-fg: var(--mw-soft-fg); }
.mw-syncband--aktiv  { --mw-band-bg: var(--mw-block-bg); --mw-band-fg: var(--mw-block-fg); }
.mw-syncband--fehler { --mw-band-bg: var(--mw-neg-bg);   --mw-band-fg: var(--mw-neg-fg); }

.mw-syncband__icon { flex: 0 0 auto; }

/* Nimmt den Platz, damit der Knopf rechts steht; darf umbrechen,
   weil der Offline-Satz auf einem Telefon zweizeilig wird. */
.mw-syncband__text { flex: 1 1 auto; min-width: 0; }

.mw-syncband__action {
  flex: 0 0 auto;
  padding: 4px 10px;
  font: inherit;
  font-weight: 600;
  color: inherit;
  background: transparent;
  border: 1px solid currentColor;
  border-radius: var(--mw-r-pill, 999px);
  cursor: pointer;
}
.mw-syncband__action:hover { background: rgba(0, 0, 0, .06); }
:root[data-mw-theme="dark"] .mw-syncband__action:hover { background: rgba(255, 255, 255, .08); }

/* ── Zeilenzustand in den vier Behandlungstabellen ───────────── */
/* MeadowTable braucht dafuer NULL Aenderungen: RowClass und
   MeadowColumn.Template gibt es laengst. Eine synchronisierte
   Zeile rendert NICHTS - 99 % der Zeilen bleiben pixelgleich. */
.mw-syncdot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.mw-syncdot--warten { background: var(--mw-soft-fg); }
.mw-syncdot--fehler { background: var(--mw-danger); }

/* Die wartende Zeile wird nicht eingefaerbt, nur leicht
   zurueckgenommen: sie ist echt und vollstaendig lesbar, ihr fehlt
   nur die Quittung vom Server. */
.mw-row--warten { opacity: .72; }
.mw-row--fehler { background: var(--mw-neg-bg); }

/* ── Dashboard mobil ──────────────────────────────────────────── */
@media (max-width: 1023.98px) {
  .mw-kpi-grid {
    flex: 1 1 100%;
    min-width: 0;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
  /* Das Design zeigt mobil vier Kacheln - heute waren es nur zwei
     (d-lg-flex d-none ab dem dritten Element). */
  .mw-kpi-grid > *:nth-child(n+5) { display: none; }

  .mw-kpi { padding: 12px 14px; gap: 4px; }
  .mw-kpi__value { font-size: 32px; }

  .mw-dash-actions { flex: 1 1 100%; min-width: 0; margin-top: 14px; }
  .mw-act { padding: 14px 16px; }

  .mw-dash-charts { margin-top: 14px; }
  .mw-card--chart { flex: 1 1 100%; min-width: 0; }
}

.mw-chart-error {
  margin-top: 14px;
  padding: 12px 16px;
  border: 1px solid var(--mw-border);
  border-left: 3px solid var(--mw-warning);
  border-radius: var(--mw-r-lg);
  background: var(--mw-panel);
  font-size: 13px;
  color: var(--mw-muted);
}

/* ============================================================
   TOOLBAR / SUCHE   (st.tbToolbar / st.searchWrap / st.searchInput)
   ============================================================ */
.mw-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.mw-toolbar__left,
.mw-toolbar__right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.mw-toolbar__left { flex: 1; min-width: 0; }

.mw-search {
  display: flex;
  align-items: center;
  gap: 9px;
  /* Kein max-width: die Suche nimmt den Platz, den die linke Toolbar-Haelfte
     uebrig laesst. Links steht sie damit buendig zur Tabellenkante, rechts
     reicht sie bis an den Aktionsblock. Betrifft alle Toolbars mit Suche -
     die fuenf Tabellenseiten und die vier Stammdaten-Ansichten, die
     denselben Aufbau haben. */
  flex: 1;
  min-width: 260px;
  height: var(--mw-control-h);
  padding: 9px 13px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-xl);
  box-shadow: var(--mw-shadow-card);
  transition: border-color var(--mw-t), box-shadow var(--mw-t);
}
.mw-search:focus-within {
  border-color: var(--mw-primary);
  box-shadow: 0 0 0 3px rgba(var(--mw-primary-rgb), .18);
}
.mw-search > svg { color: var(--mw-muted); flex-shrink: 0; }

.mw-search__input {
  width: 100%;
  border: 0;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 14px;
  color: var(--mw-text);
}
.mw-search__input::placeholder { color: var(--mw-muted); }

.mw-result-count {
  font-size: 13px;
  font-weight: 500;
  color: var(--mw-muted);
  white-space: nowrap;
}

/* ============================================================
   FILTER   (fbtn / st.filterBadge / st.filterPop* / fchip)
   ============================================================ */
/* ============================================================
   SPLIT-BUTTON   (Hauptaktion + angesetztes Aktionsmenue)
   ============================================================ */
.mw-split { display: inline-flex; }

/* Die beiden Haelften stossen aneinander: aussen rund, innen eckig. */
.mw-split__main {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.mw-split__toggle {
  padding-inline: 9px;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  /* Trennlinie als inset-Schatten statt als Rahmen - ein echter Rahmen
     wuerde die Hoehe gegen den Hauptteil verschieben. */
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, .3);
}

.mw-split__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 220px;
  padding: 6px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  box-shadow: var(--mw-shadow-pop);
  z-index: var(--mw-z-filter);
  animation: mwPop var(--mw-t-pop) var(--mw-ease);
}

.mw-split__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: var(--mw-r-lg);
  background: transparent;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  color: var(--mw-text);
  cursor: pointer;
  transition: background var(--mw-t);
}
.mw-split__item > svg { color: var(--mw-muted); flex-shrink: 0; }
@media (hover: hover) {
  .mw-split__item:hover { background: var(--mw-tint); }
}

/* Buttons in der Toolbar teilen die Hoehe der Suche. Bewusst auf die
   Toolbar begrenzt: .mw-btn steckt auch in Tabellenzeilen (mw-btn--sm) und
   in Dialogen, wo diese Hoehe nichts zu suchen hat. */
.mw-toolbar .mw-btn,
.mw-toolbar .mw-filter-btn {
  height: var(--mw-control-h);
}

.mw-pop-anchor { position: relative; }

.mw-filter-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-xl);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--mw-text);
  cursor: pointer;
  transition: border-color var(--mw-t), background var(--mw-t), color var(--mw-t);
}
.mw-filter-btn.is-active {
  border-color: var(--mw-primary);
  background: var(--mw-soft);
  color: var(--mw-soft-fg);
}

.mw-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--mw-r-xl);
  background: var(--mw-primary);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.mw-pop-backdrop {
  position: fixed;
  inset: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: default;
  z-index: var(--mw-z-filter-backdrop);
}

.mw-pop {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 300px;
  /* Haelt das Popover auch am Desktop im Bild, wenn der Anker weit rechts
     sitzt oder das Fenster schmal gezogen wird. */
  max-width: calc(100vw - 32px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-3xl);
  box-shadow: var(--mw-shadow-pop);
  z-index: var(--mw-z-filter);
  animation: mwPop var(--mw-t-pop) var(--mw-ease);
}
.mw-pop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.mw-pop__title {
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 18px;
  color: var(--mw-text);
}
.mw-pop__reset {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--mw-primary);
  cursor: pointer;
}
.mw-pop__count {
  padding-top: 12px;
  border-top: 1px solid var(--mw-border);
  font-size: 12px;
  color: var(--mw-muted);
}

/* ============================================================
   FILTER-DROPDOWN   (.mw-select — MeadowMultiSelect / MeadowSingleSelect)
   ============================================================
   Ersetzt die Chip-Reihen im Filterpanel. Klappt INLINE auf, nicht als
   eigenes Popover: das Panel ist mobil ein scrollendes Bottom-Sheet, ein
   verschachteltes Overlay wuerde an dessen overflow abgeschnitten. */
.mw-select {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mw-select__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 42px;
  padding: 9px 12px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  color: var(--mw-text);
  cursor: pointer;
  transition: border-color var(--mw-t), background var(--mw-t), color var(--mw-t);
}
.mw-select__trigger.is-open { border-color: var(--mw-primary); }
@media (hover: hover) {
  .mw-select__trigger:hover { border-color: var(--mw-primary); }
}

/* Chevron dreht beim Aufklappen - das Icon ist das einzige svg im Trigger. */
.mw-select__trigger > svg {
  flex-shrink: 0;
  transition: transform var(--mw-t);
}
.mw-select__trigger.is-open > svg { transform: rotate(180deg); }

/* Kein text-overflow: ellipsis. Ein abgeschnittener Befundname ("Zwischenzehen…")
   ist im Filter unbrauchbar; lieber bricht der Trigger auf zwei Zeilen. */
.mw-select__value {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Lange Wertelisten scrollen im Dropdown, nicht im ganzen Panel. Die
   Zeilentrenner lassen eine angeschnittene Zeile sichtbar, das ist der
   Hinweis, dass hier noch mehr kommt. */
.mw-select .mw-check-list {
  max-height: 232px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.mw-select__label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--mw-muted);
}

/* .mw-filter-group und .mw-chips sind mit MeadowFilterGroup/MeadowChipSelect
   entfallen. .mw-chip bleibt: der Ueberfaellig-Filter der Verbaende-Seite ist
   ein einzelner Umschalt-Chip direkt in der Toolbar. */
.mw-chip {
  padding: 6px 13px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-md);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--mw-muted);
  cursor: pointer;
  transition: border-color var(--mw-t), background var(--mw-t), color var(--mw-t);
}
.mw-chip.is-on {
  border-color: var(--mw-primary);
  background: var(--mw-soft);
  color: var(--mw-soft-fg);
}

/* ============================================================
   TABELLE   (st.tableWrap / st.th / st.td / st.tr / st.emptyRow)
   ============================================================ */
.mw-table-wrap {
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-3xl);
  box-shadow: var(--mw-shadow-card);
  overflow: hidden;
}
.mw-table-scroll { overflow-x: auto; }

.mw-table {
  width: 100%;
  border-collapse: collapse;
}
.mw-table th {
  padding: 13px 16px;
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--mw-muted);
  background: var(--mw-tint);
  border-bottom: 1px solid var(--mw-border);
  white-space: nowrap;
}
.mw-table td {
  padding: 13px 16px;
  font-size: 14px;
  color: var(--mw-text);
  border-bottom: 1px solid var(--mw-border);
}
.mw-table tbody tr:last-child td { border-bottom: 0; }
.mw-table tbody tr { transition: background var(--mw-t-fast); }
/* Zeilen mit Klickziel (MeadowTable.RowHref). Nur der Zeiger - das
   Aufleuchten beim Ueberfahren haben ohnehin alle Zeilen, und genau deshalb
   braucht es hier ein zweites Zeichen dafuer, dass hier etwas passiert. */
.mw-table__row--link { cursor: pointer; }
@media (hover: hover) {
  .mw-table tbody tr:hover { background: var(--mw-tint); }
}

.mw-td--bold    { font-weight: 700; }
.mw-td--mono    { font-family: var(--mw-font-mono); font-size: 13px; color: var(--mw-muted); }
.mw-td--right   { text-align: right; }
/* MeadowTable haengt dieselbe Klasse an den Spaltenkopf. Ohne diese Zeile
   verliert sie dort gegen ".mw-table th { text-align: left }" (0-1-1 schlaegt
   0-1-0), und der Kopf einer rechtsbuendigen Zahlenspalte stuende links
   ueber Zahlen, die rechts stehen. Faellt erst auf, seit es ueberhaupt
   rechtsbuendige Spalten MIT Ueberschrift gibt - die Aktionsspalte hat
   keine. */
.mw-table th.mw-td--right { text-align: right; }
.mw-td--nowrap  { white-space: nowrap; }
.mw-td--actions { text-align: right; white-space: nowrap; }
.mw-td--actions > * + * { margin-left: 6px; }

.mw-th-sort {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  cursor: pointer;
}
.mw-th-sort__caret { opacity: 0; flex-shrink: 0; transition: opacity var(--mw-t); }
.mw-th-sort.is-sorted .mw-th-sort__caret { opacity: 1; }
.mw-th-sort.is-desc .mw-th-sort__caret { transform: rotate(180deg); }
@media (hover: hover) {
  .mw-th-sort:hover { color: var(--mw-text); }
  .mw-th-sort:hover .mw-th-sort__caret { opacity: .5; }
  .mw-th-sort.is-sorted:hover .mw-th-sort__caret { opacity: 1; }
}

.mw-empty {
  padding: 40px 16px;
  text-align: center;
  font-size: 14px;
  color: var(--mw-muted);
}
.mw-empty__reset {
  display: block;
  margin: 10px auto 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 600;
  color: var(--mw-primary);
  cursor: pointer;
}

/* Pager — nicht im Prototyp gezeichnet, aber die Datenmenge ist unbegrenzt.
   Wird ausgeblendet, solange alles auf eine Seite passt. Nur Desktop:
   mobil ersetzt .mw-cards-more das Blaettern. */
.mw-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  /* Der Pager sitzt in .mw-table-wrap, und das ist overflow:hidden. Ohne
     Umbruch wuerde bei schmalem Desktop der Vor-Chevron stumm abgeschnitten
     statt in eine zweite Zeile zu rutschen. */
  flex-wrap: wrap;
  row-gap: 8px;
  padding: 10px 16px;
  background: var(--mw-tint);
  border-top: 1px solid var(--mw-border);
  font-size: 13px;
  color: var(--mw-muted);
}
.mw-pager select {
  /* Schiebt Beschriftung und Auswahl nach links; justify-content oben wird
     damit fuer den Rest wirkungslos. */
  margin-right: auto;
  padding: 5px 8px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-sm);
  background: var(--mw-panel);
  font: inherit;
  color: var(--mw-text);
}
.mw-pager__pages {
  display: flex;
  align-items: center;
  gap: 4px;
  /* Macht ch zu einer verlaesslichen Einheit - ohne das ist eine 1 schmaler
     als eine 8 und die Leiste zappelt trotz fester Slot-Breite. */
  font-variant-numeric: tabular-nums;
}
.mw-pager__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* min-width statt width: dreistellige Seitenzahlen passen sonst nicht. */
  min-width: 28px;
  height: 28px;
  padding-inline: 6px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-md);
  background: var(--mw-panel);
  font: inherit;
  font-size: 13px;
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t);
}
.mw-pager__btn:disabled { opacity: .4; cursor: default; }
.mw-pager__btn--prev svg { transform: rotate(90deg); }
.mw-pager__btn--next svg { transform: rotate(-90deg); }

/* Chevrons und Zahlen randlos und rund - die Flaeche traegt nur die
   aktuelle Seite. */
.mw-pager__btn--prev,
.mw-pager__btn--next,
.mw-pager__btn--page {
  border-color: transparent;
  background: transparent;
  border-radius: var(--mw-r-pill);
}
/* Zahlen und Luecken teilen sich eine Slot-Breite: die groesste Seitenzahl
   (--mw-pager-slot, gesetzt von MeadowTablePager) plus Polsterung, nie
   unter dem 28px-Klickziel. Sonst wandert der Vor-Chevron beim Blaettern
   unter dem Mauszeiger weg - der klassische Pagination-Fehler. */
.mw-pager__btn--page,
.mw-pager__gap {
  min-width: max(28px, calc(var(--mw-pager-slot, 2ch) + 12px));
}
.mw-pager__btn--page { font-weight: 600; }
/* Dieselbe Paarung wie .mw-btn--primary. --mw-primary ist in beiden Themes
   derselbe Ton und taugt nur als Flaeche, nie als Textfarbe (vgl.
   .mw-row-card__date, das deshalb --mw-soft-fg nimmt). */
.mw-pager__btn--page.is-current {
  background: var(--mw-primary);
  color: #fff;
  box-shadow: var(--mw-glow-btn);
}
.mw-pager__gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  color: var(--mw-muted);
  user-select: none;
}
@media (hover: hover) {
  .mw-pager__btn:not(:disabled):not(.is-current):hover {
    background: var(--mw-tint);
    color: var(--mw-text);
  }
}
/* Mit Seitenzahlen wird Blaettern per Tastatur erst zur echten Interaktion -
   bisher hatte im Pager nichts einen Fokusring. */
.mw-pager__btn:focus-visible {
  outline: 2px solid var(--mw-primary);
  outline-offset: 2px;
}

/* ============================================================
   ZELLEN-BAUSTEINE   (st.pill / dayChip / st.tinyBtn)
   ============================================================ */
.mw-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--mw-r-pill);
  background: var(--mw-soft);
  color: var(--mw-soft-fg);
  font-size: 12px;
  font-weight: 600;
}
/* dayChip ab 7 Tagen. Achtung: hier immer --mw-danger, NICHT --mw-neg-fg -
   das gilt nur fuer das "Verband entfernt"-Badge. */
.mw-pill--overdue { background: var(--mw-neg-bg); color: var(--mw-danger); }

.mw-tiny-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--mw-r-md);
  background: var(--mw-soft);
  color: var(--mw-primary);
  cursor: pointer;
  transition: filter var(--mw-t);
}
.mw-tiny-btn--danger { background: var(--mw-neg-bg); color: var(--mw-danger); }
@media (hover: hover) {
  .mw-tiny-btn:hover { filter: brightness(.95); }
}

/* ============================================================
   MOBILE KARTENLISTE   (st.mCard / st.mFilterWrap / st.mSearchWrap)
   ============================================================ */
.mw-cards { display: none; }

.mw-row-card {
  display: block;
  width: 100%;
  padding: 15px;
  margin-bottom: 11px;
  text-align: left;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-4xl);
  box-shadow: var(--mw-shadow-card);
  font: inherit;
  color: inherit;
}
.mw-row-card--clickable { cursor: pointer; }
.mw-row-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.mw-row-card__title { font-size: 16px; font-weight: 700; color: var(--mw-text); }
.mw-row-card__sub   { margin-top: 4px; font-size: 12px; color: var(--mw-muted); }
.mw-row-card__mono  { margin-top: 4px; font-family: var(--mw-font-mono); font-size: 12px; color: var(--mw-muted); }
.mw-row-card__meta {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 13px;
  color: var(--mw-text);
}
.mw-row-card__actions { display: flex; gap: 8px; margin-top: 12px; }
.mw-row-card__actions > * { flex: 1; }

/* ============================================================
   MEHRFACHAUSWAHL   (Verbaende-Tabelle)

   Die Kaestchen sind native input[type=checkbox] wie in .mw-check:
   accent-color reicht, damit sie die Markenfarbe tragen - kein
   Nachbau, keine MudCheckBox.
   ============================================================ */
.mw-row-check {
  width: 17px;
  height: 17px;
  flex: none;
  margin: 0;
  accent-color: var(--mw-primary);
  cursor: pointer;
}

/* .mw-row-card__top verteilt seine Kinder mit space-between. Ohne das
   hier stuenden Kaestchen, Titel und Tage-Chip zu dritt auseinander-
   geschoben statt Kaestchen und Titel links beieinander. */
.mw-row-card__top > .mw-row-check + .mw-row-card__title { margin-right: auto; }

/* Auf die Zellen und nicht auf die Zeile: der tr:hover-Grund liegt
   ebenfalls auf den td, eine Zeilenfarbe waere davon verdeckt. */
.mw-table__row--selected > td { background: var(--mw-soft); }

.mw-row-card--selected {
  background: var(--mw-soft);
  border-color: var(--mw-primary);
}

.mw-selbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
  padding: 10px 14px;
  background: var(--mw-soft);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
}
.mw-selbar__count { font-size: 14px; color: var(--mw-text); }
.mw-selbar__hint { color: var(--mw-muted); }
.mw-selbar__actions { display: flex; flex-wrap: wrap; gap: 8px; }

@media (max-width: 1023.98px) {
  /* Mobil steht die Leiste ueber einer langen Kartenliste - ohne sticky
     waere sie nach dem dritten Abhaken aus dem Bild.

     Oben und nicht unten: die Tabbar traegt einen FAB, der 26px in den
     Inhalt ragt (z-Ebene 1091). Eine untere Leiste laege genau darunter
     und haette sich mit ihm um die Mitte gestritten. */
  .mw-selbar {
    position: sticky;
    top: 0;
    z-index: var(--mw-z-header);
    box-shadow: var(--mw-shadow-card);
  }

  /* Ein Deckel, kein Schmuck: sticky haftet an der Polsterkante von
     .mw-content, nicht an dessen Aussenkante. Ueber der Leiste blieben
     sonst --mw-content-pad-m offen, durch die die Karten sichtbar
     durchwandern.

     Als eigenes Kaestchen und nicht als box-shadow der Leiste: der
     Schatten haette deren abgerundete Ecken geerbt und in den beiden
     oberen Zwickeln weiter Karte durchblitzen lassen. */
  .mw-selbar::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: calc(-1 * (var(--mw-content-pad-m) + 2px));
    right: -4px;
    left: -4px;

    /* Reicht um den Eckradius WEITER als bis zur Leistenkante hinab und
       liegt hinter ihr: in den beiden oberen Rundungen deckt die Leiste
       ihre eigene Hintergrundflaeche nicht ab, und dort blitzte sonst
       weiter die Karte durch. */
    height: calc(var(--mw-content-pad-m) + 2px + var(--mw-r-2xl));
    background: var(--mw-bg);
  }
}

/* ── Kachel mit beschrifteten Feldern ─────────────────────────
   Aufsatz auf .mw-row-card fuer Zeilen, die mobil mehr als drei
   Werte zeigen muessen: Kopf mit Titel und Datum, darunter ein
   Code-Chip (Ohrmarke) und - durch eine Haarlinie getrennt - die
   Werte mit eigener Beschriftung in drei Spalten.

   Das __meta-Band darueber traegt seine Werte ohne Label; sobald
   drei gleich aussehende Zahlen nebeneinander stehen, raet man,
   welche die Menge ist. Deshalb hier Label statt Fliesstext.
   ------------------------------------------------------------ */
.mw-row-card__date {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  /* --mw-soft-fg statt --mw-primary: der Primaerton ist in beiden Themes
     derselbe und traegt auf der dunklen Karte nur 3,1:1. soft-fg dreht mit
     dem Theme mit (hell 7,1:1, dunkel 5,8:1) und ist der Ton, den das Pill
     daneben ohnehin schon benutzt. */
  color: var(--mw-soft-fg);
  white-space: nowrap;
}
.mw-row-card__date svg { flex: none; }

/* Ohrmarken sind lang und ziffernlastig - Mono haelt die Gruppen
   untereinander lesbar, die Flaeche trennt sie vom Titel. */
.mw-row-card__code {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-top: 9px;
  padding: 5px 10px;
  border-radius: var(--mw-r-lg);
  background: var(--mw-tint);
  font-family: var(--mw-font-mono);
  font-size: 13px;
  line-height: 1.35;
  letter-spacing: .02em;
  color: var(--mw-text);
  overflow-wrap: anywhere;
}

.mw-row-card__fields {
  display: grid;
  /* Keine drei gleichen Drittel: Medikamentennamen sind lang, die Menge
     ist es nie. minmax(0,..) statt blossem fr, damit ein langer Name die
     Spalte nicht ueber ihren Anteil hinaus aufblaeht. */
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, .85fr);
  gap: 11px 12px;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--mw-border);
}
.mw-row-card__field { min-width: 0; }
.mw-row-card__label {
  display: block;
  margin-bottom: 5px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--mw-muted);
}
.mw-row-card__value {
  display: block;
  line-height: 1.4;
  font-size: 14px;
  font-weight: 600;
  color: var(--mw-text);
  /* hyphens trennt lange Woerter nach den Regeln von <html lang="de">,
     wo der Browser Trennmuster hat (mobiles Chrome, Safari). Wo nicht,
     bricht overflow-wrap notfalls mitten im Wort - besser als eine Zeile,
     die aus ihrer Spalte laeuft. */
  hyphens: auto;
  overflow-wrap: anywhere;
}
/* Ein Pill als Wert darf umbrechen statt aus seiner Spalte zu laufen -
   aber an Leer- und Bindestrichen, nicht mitten im Wort. Deshalb hier
   break-word statt des geerbten anywhere. */
.mw-row-card__value .mw-pill { max-width: 100%; overflow-wrap: break-word; }

.mw-row-card__sep  { margin: 0 4px; color: var(--mw-muted); font-weight: 500; }
.mw-row-card__unit { margin-left: 3px; font-weight: 500; color: var(--mw-muted); }

/* Auf 320px-Geraeten bleiben von drei Spalten je ~80px - zu wenig fuer
   "Intramuskulaer" oder einen Wirkstoffnamen. Dann lieber zwei Spalten
   und die Menge in der zweiten Zeile. */
@media (max-width: 359.98px) {
  .mw-row-card__fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.mw-filter-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
  margin-bottom: 14px;
}

/* ============================================================
   TABS   (st.setTabs / setTabS / st.miniChip)
   ============================================================ */
.mw-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--mw-border);
}
.mw-tab {
  padding: 11px 20px;
  margin-bottom: -1px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--mw-muted);
  cursor: pointer;
  transition: color var(--mw-t), border-color var(--mw-t);
}
.mw-tab.is-active { color: var(--mw-primary); border-bottom-color: var(--mw-primary); }

.mw-chip-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 16px 0;
}
.mw-mini-chip {
  padding: 7px 14px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--mw-text);
  cursor: pointer;
  transition: border-color var(--mw-t), background var(--mw-t), color var(--mw-t);
}
.mw-mini-chip.is-active {
  border-color: var(--mw-primary);
  background: var(--mw-soft);
  color: var(--mw-soft-fg);
}

/* ============================================================
   FORMULAR-BAUSTEINE   (st.label / st.input) — auch von Etappe 4 genutzt
   ============================================================ */
.mw-label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--mw-muted);
}
.mw-input {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-bg);
  font-family: inherit;
  font-size: 14px;
  color: var(--mw-text);
  outline: none;
  transition: border-color var(--mw-t), box-shadow var(--mw-t);
}
.mw-input:focus {
  border-color: var(--mw-primary);
  box-shadow: 0 0 0 3px rgba(var(--mw-primary-rgb), .18);
}

/* Schalter — ersetzt MudSwitch ("Simple Ansicht") */
.mw-switch {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 600;
  color: var(--mw-text);
  cursor: pointer;
}
.mw-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.mw-switch__track {
  position: relative;
  width: 38px;
  height: 22px;
  flex-shrink: 0;
  border-radius: var(--mw-r-pill);
  background: var(--mw-border);
  transition: background var(--mw-t);
}
.mw-switch__track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--mw-panel);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: transform var(--mw-t);
}
.mw-switch input:checked + .mw-switch__track { background: var(--mw-primary); }
.mw-switch input:checked + .mw-switch__track::after { transform: translateX(16px); }
.mw-switch input:focus-visible + .mw-switch__track {
  outline: 2px solid var(--mw-primary);
  outline-offset: 2px;
}

/* ── Tabellen mobil: Karten statt Tabelle ─────────────────────── */
@media (max-width: 1023.98px) {
  .mw-table-wrap { display: none; }
  .mw-cards      { display: block; }

  .mw-toolbar { gap: 10px; margin-bottom: 14px; }

  /* Der Aktionsblock sitzt neben der Suche statt darunter - mobil bleibt
     dort nach dem Ausblenden der Hinzufuegen-Buttons meist nur der Filter.
     Die min-width haelt die Suche brauchbar breit und sorgt dafuer, dass
     ein breiter Aktionsblock (Stammdaten: "Von XLink aktualisieren") wie
     bisher in die naechste Zeile umbricht, statt die Suche zu zerdruecken. */
  .mw-toolbar__left  { width: auto; min-width: 60%; }
  .mw-toolbar__right { width: auto; }

  .mw-search {
    flex: 1;
    min-width: 0;
    height: var(--mw-control-h-m);
    padding: 10px 13px;
    border-radius: var(--mw-r-lg);
  }
  .mw-toolbar .mw-btn,
  .mw-toolbar .mw-filter-btn { height: var(--mw-control-h-m); }


  /* Mobil nur das Icon, kein Label (Design L440) */
  .mw-filter-btn { padding: 10px 12px; }

  /* Filter mobil: Bottom-Sheet statt Anker-Popover.
     Der Anker ist ein ~48px breiter Icon-Button im rechten Toolbar-Block. Ein
     absolut positioniertes 250px-Popover laesst sich daran nicht ausrichten,
     ohne aus dem Bild zu laufen: mit right:0 klappt es nach links heraus, mit
     left:0 nach rechts. Gemessen lag seine rechte Kante exakt auf der
     Viewport-Kante (0px Rand) - jeder weitere Aktionsbutton in der Toolbar
     und jeder laengere Chip schob es darueber hinaus. Ueber die volle Breite
     gibt es keine Ankergeometrie mehr, die klemmen kann.
     Gleiches Sheet-Muster wie die Dialoge (siehe .mw-dlg weiter unten). */
  .mw-pop-backdrop {
    background: var(--mw-backdrop-dialog);
    z-index: var(--mw-z-sheet-backdrop);
    animation: mwFade .2s ease;
  }
  .mw-pop {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    width: auto;
    max-width: var(--mw-sheet-max);
    margin-inline: auto;
    max-height: 85dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Oben knapp: den Abstand macht der Griff (.mw-sheet-grab). */
    padding: 8px 18px calc(18px + env(safe-area-inset-bottom));
    border-radius: var(--mw-r-6xl) var(--mw-r-6xl) 0 0;
    box-shadow: var(--mw-shadow-sheet);
    z-index: var(--mw-z-sheet);
    animation: mwSheetUp var(--mw-t-sheet) var(--mw-ease);
  }

  /* Im Sheet ist mehr Platz als im 300px-Popover, also darf die Werteliste
     hoeher werden, bevor sie selbst scrollt. */
  .mw-select .mw-check-list { max-height: 40dvh; }

  /* Trefferflaechen fuer die Bedienung mit Handschuhen: 15px Innenabstand auf
     14px Textzeile ergibt 44px hohe Zeilen. Nur im Filter-Dropdown - die
     Checkbox-Liste im Diagramm-Dialog behaelt ihre Dichte. */
  .mw-select__trigger { min-height: var(--mw-control-h-m); }
  .mw-select .mw-check { padding: 15px 12px; }

  .mw-tab { padding: 11px 14px; }
}

/* ============================================================
   DIALOGE
   ============================================================
   MudDialogProvider bleibt der Wirt: MudDialogInstance besitzt Result-Task,
   Escape, Backdrop-Klick und den Stapel fuer verschachtelte Dialoge, und
   alle 16 Aufrufstellen fangen sie schon als CascadingParameter.

   Die Dialoge rendern aber kein <MudDialog> mehr, sondern MeadowDialog -
   mit der Klasse mud-dialog. Zwei Gruende:
   1) MudDialog liest NoHeader/CloseButton/FullWidth/MaxWidth. Ohne sie
      werden diese Optionen an allen Aufrufstellen wirkungslos, statt gegen
      die festen Dialogbreiten zu kaempfen - kein Aufruf muss angepasst werden.
   2) Muds eigene Regel .mud-dialog .mud-popover-cascading-value hebt
      Picker- und Autocomplete-Popover ueber den Dialog. Sie greift nur bei
      genau dieser Klasse.
   ============================================================ */

/* st.backdrop */
.mud-overlay.mud-overlay-dialog .mud-overlay-scrim {
  background: var(--mw-backdrop-dialog);
  backdrop-filter: blur(4px);
  animation: mwFade var(--mw-t-pop) ease;
}

.mud-dialog-container { padding: 0; }

/* st.dialog — zentriert wird ueber Muds vorhandenes Flex-Centering, nicht
   ueber translate(-50%,-50%): der Prototyp tut das, sein eigenes mwPop
   ueberschreibt transform dann aber waehrend der Animation. */
.mud-dialog.mw-dlg {
  width: var(--mw-dlg-w, 480px);
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--mw-panel);
  color: var(--mw-text);
  border-radius: var(--mw-r-5xl);
  border-top: 3px solid var(--mw-primary);
  box-shadow: var(--mw-shadow-dialog);
  animation: mwPop var(--mw-t-dialog) var(--mw-ease);
}

/* MudDialogInstance legt um den Inhalt noch .mud-dialog-content mit eigenem
   Padding, Margin und overflow:auto. Der einzige Scroller soll aber
   .mw-dlg-body sein, damit Kopf und Footer stehenbleiben. */
.mw-dlg .mud-dialog-content.mw-dlg-content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: visible;
  border-radius: inherit;
}
.mw-dlg-shell {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  outline: none;
}

/* Breiten-Klassen, die MudDialogInstance zusaetzlich setzt, ausschalten. */
.mud-dialog.mw-dlg.mud-dialog-width-full,
.mud-dialog.mw-dlg.mud-dialog-width-false,
.mud-dialog.mw-dlg[class*="mud-dialog-width-"] {
  width: var(--mw-dlg-w, 480px);
  max-width: calc(100vw - 32px);
}
.mw-dlg--info     { --mw-dlg-w: 420px; }
.mw-dlg--cow      { --mw-dlg-w: 480px; }
.mw-dlg--showclaw { --mw-dlg-w: 520px; }
.mw-dlg--claw     { --mw-dlg-w: 560px; }
.mw-dlg--wide     { --mw-dlg-w: 760px; }

/* st.dlgHead / st.dlgTitle / st.dlgClose */
.mw-dlg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--mw-border);
}
.mw-dlg-title {
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: .01em;
  color: var(--mw-text);
}
.mw-dlg-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  border-radius: var(--mw-r-lg);
  background: none;
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t);
}
@media (hover: hover) {
  .mw-dlg-close:hover { background: var(--mw-tint); color: var(--mw-text); }
}

/* Meta-Zeile ausserhalb des scrollenden Bodys (ShowClaw) */
.mw-dlg-meta {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  flex-shrink: 0;
  padding: 12px 22px 0;
}
.mw-dlg-meta__value { font-size: 15px; font-weight: 700; color: var(--mw-text); }
.mw-dlg-meta__mono  { font-family: var(--mw-font-mono); font-size: 14px; color: var(--mw-text); }

/* st.dlgBody — der einzige Scroller, damit Kopf und Footer stehenbleiben */
.mw-dlg-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 auto;
  min-height: 0;
  padding: 16px 20px;
  overflow-y: auto;
  overflow-x: hidden;
}
.mw-dlg-body--flush { padding: 0; }

/* st.dlgFooter */
.mw-dlg-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-shrink: 0;
  padding: 14px 22px;
  border-top: 1px solid var(--mw-border);
  background: var(--mw-tint);
}

/* st.mSheetGrab — immer im Markup, per CSS nur mobil sichtbar */
.mw-sheet-grab { display: none; }

/* st.addRow */
.mw-add-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 11px;
  border: 1.5px dashed var(--mw-border);
  border-radius: var(--mw-r-xl);
  background: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--mw-primary);
  cursor: pointer;
  transition: border-color var(--mw-t), background var(--mw-t);
}
@media (hover: hover) {
  .mw-add-row:hover { border-color: var(--mw-primary); background: var(--mw-soft); }
}

.mw-hint { font-size: 12px; line-height: 1.5; color: var(--mw-muted); }
.mw-readonly {
  padding: 10px 13px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-tint);
  font-size: 14px;
  color: var(--mw-muted);
}
.mw-field-row { display: flex; gap: 10px; align-items: flex-end; }
.mw-field-row > * { min-width: 0; }
.mw-field--row { display: flex; gap: 8px; align-items: center; }
.mw-field--row > .mud-input-control { flex: 1; }

/* Medikamentenzeile im Behandlungs-Dialog: eine Karte je Medikament.

   Innen zwei Zeilen (Medikament, darunter Wie/Wo + Menge) statt vier Feldern
   nebeneinander, weil der Dialog 480px breit ist (--mw-dlg-w der Groesse Cow):
   nebeneinander blieben fuer das Wie/Wo-Feld unter 120px uebrig, und darin
   stehen bis zu zwei Icons.

   Zwei Zeilen heisst aber: die Karte MUSS sichtbar zusammenhalten, sonst liest
   sich das Wie/Wo der ersten Karte wie das Medikament der zweiten. Die
   Tierzeilen darueber brauchen das nicht - dort ist eine Zeile eine Zeile.

   Keine Mobil-Regel: die innere Zeile ist .mw-field-row + .mw-col--double +
   .mw-col, also genau das Layout, das der Dialog vorher schon hatte und das im
   Bottom Sheet bereits funktioniert. Es gibt hier nichts neu zu stapeln.

   Rezept wie .mw-show-cell. */
.mw-med-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  background: var(--mw-tint);
}

/* Beschriftung und Papierkorb auf einer Zeile: der Knopf gehoert zur KARTE,
   nicht zu einem Feld. Das margin-bottom ersetzt das der Beschriftung, damit
   der Abstand zum Feld darunter derselbe bleibt. */
.mw-med-row__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
.mw-med-row__head > .mw-label { margin-bottom: 0; }

/* Ace-Editor im KPI-Dialog: feste Hoehe, nie flex:1 - er misst beim
   Initialisieren und rendert in einem 0px-hohen Container unbrauchbar. */
.mw-ace {
  flex: 0 0 300px;
  height: 300px;
  min-height: 300px;
  overflow: hidden;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
}

/* ── Dialog mobil: Bottom-Sheet ───────────────────────────────
   Eine Regel statt der doppelten Dialog-Saetze des Prototyps. */
@media (max-width: 1023.98px) {
  .mud-dialog-container .mud-dialog.mw-dlg {
    position: absolute;
    inset: auto 0 0 0;
    width: auto;
    max-width: var(--mw-sheet-max);
    max-height: 97%;
    margin-inline: auto;
    transform: none;
    border-radius: var(--mw-r-6xl) var(--mw-r-6xl) 0 0;
    box-shadow: var(--mw-shadow-sheet);
    padding-bottom: env(safe-area-inset-bottom);
    animation: mwSheetUp var(--mw-t-sheet) var(--mw-ease);
  }

  .mw-sheet-grab {
    display: block;
    width: 38px;
    height: 4px;
    flex-shrink: 0;
    margin: 9px auto 2px;
    border-radius: 2px;
    background: var(--mw-border);
  }

  .mw-dlg-head { padding: 10px 18px 12px; }
  .mw-dlg-body { padding: 14px 18px; }
  .mw-dlg-footer { padding: 12px 18px; }
  .mw-dlg-meta { padding: 10px 18px 0; gap: 20px; }
}

/* ============================================================
   KLAUEN-SELEKTOR   (st.clawRow / st.hoofCell / hoofWrap / st.subPanel)
   ============================================================ */
.mw-claw-row {
  display: flex;
  gap: 18px;
  align-items: stretch;
}
.mw-claw-hoofs { flex: 0 0 196px; }

.mw-claw-sides {
  display: flex;
  justify-content: space-between;
  padding: 0 8px 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--mw-muted);
}

.mw-hoof-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 14px;
}
.mw-hoof-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.mw-hoof-lbl {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .03em;
  color: var(--mw-muted);
}

/* hoofWrap / hoofColor — die Farbe kommt aus der Klasse, nicht aus C#,
   damit Hover ohne Server-Roundtrip funktioniert. */
.mw-hoof-btn {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  margin: 0 auto;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform var(--mw-t);
  --mw-hoof: var(--mw-hoof-idle);
}
.mw-hoof-btn.has-data    { --mw-hoof: var(--mw-teal); }
.mw-hoof-btn.is-selected { --mw-hoof: var(--mw-primary); transform: scale(1.08); }
@media (hover: hover) {
  .mw-hoof-btn:not(.is-selected):hover { transform: scale(1.03); --mw-hoof: var(--mw-teal); }
}

.mw-subpanel {
  flex: 1;
  min-height: 170px;
  padding: 16px;
  background: var(--mw-tint);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
}
.mw-subpanel-empty {
  padding: 24px 8px;
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
  color: var(--mw-muted);
}
.mw-subpanel-title {
  font-family: var(--mw-font-display);
  font-weight: 700;
  font-size: 19px;
  color: var(--mw-text);
}

/* toggle(on) — "Verband" / "Klotz". Das Design hat hier keine Checkboxen. */
.mw-toggle-row { display: flex; gap: 8px; margin-top: 12px; }
.mw-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  padding: 9px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t), border-color var(--mw-t);
}
.mw-toggle.is-on {
  background: var(--mw-primary);
  border-color: var(--mw-primary);
  color: #fff;
}

/* ============================================================
   KLAUEN-ANZEIGE   (st.legBandage / legBlock / legRemoved / st.showCell)
   ============================================================ */
.mw-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: var(--mw-r-sm);
  font-size: 12px;
  font-weight: 600;
}
.mw-tag--bandage { background: var(--mw-soft);      color: var(--mw-soft-fg); }
.mw-tag--block   { background: var(--mw-block-bg);  color: var(--mw-block-fg); }
/* Nur hier --mw-neg-fg; Tage-Chip und tinyBtnDanger nutzen --mw-danger. */
.mw-tag--removed { background: var(--mw-neg-bg);    color: var(--mw-neg-fg); }


.mw-show-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.mw-show-cell {
  padding: 14px;
  background: var(--mw-tint);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
}
.mw-show-cell__row { display: flex; gap: 12px; align-items: center; }
.mw-show-cell__body { flex: 1; min-width: 0; }
.mw-show-cell__title { font-size: 14px; font-weight: 700; color: var(--mw-text); }
.mw-show-cell__finding { margin-top: 2px; font-size: 13px; color: var(--mw-muted); }
.mw-show-cell__tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; }

.mw-hoof-thumb {
  display: block;
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  --mw-hoof: var(--mw-teal);
}
.mw-hoof-thumb.is-treated { --mw-hoof: var(--mw-primary); }
.mw-hoof-thumb.is-idle    { --mw-hoof: var(--mw-hoof-idle); }

/* ── Klauen mobil ─────────────────────────────────────────────── */
@media (max-width: 1023.98px) {
  .mw-claw-row { flex-direction: column; gap: 14px; }
  .mw-claw-hoofs { flex: 1 1 auto; }
  .mw-hoof-btn { width: 76px; }
  .mw-subpanel { min-height: 0; padding: 12px; }
  .mw-show-grid { grid-template-columns: 1fr; gap: 10px; }
}

/* Der Huf selbst: Groesse kommt vom Elternelement, Farbe aus --mw-hoof. */
.mw-hoof-svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: hidden;
  fill: var(--mw-hoof, var(--mw-teal));
  transition: fill var(--mw-t);
}
.mw-label--spaced { margin-top: 10px; }

/* ============================================================
   INFO-DIALOG   (Statuszeile + Schluessel/Wert-Zeilen)
   ============================================================ */
.mw-status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-radius: var(--mw-r-lg);
  font-weight: 600;
  color: var(--mw-text);
}
.mw-status--ok  { background: var(--mw-soft); }
.mw-status--bad { background: var(--mw-neg-bg); }

.mw-status__dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
}
.mw-status--ok  .mw-status__dot {
  background: var(--mw-success);
  box-shadow: 0 0 0 4px rgba(var(--mw-success-rgb), .18);
}
.mw-status--bad .mw-status__dot {
  background: var(--mw-danger);
  box-shadow: 0 0 0 4px rgba(var(--mw-danger-rgb), .18);
}

.mw-kv {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 14px;
  color: var(--mw-text);
}
.mw-kv > span:first-child { color: var(--mw-muted); }
.mw-kv__mono { font-family: var(--mw-font-mono); }
.mw-kv__ok   { color: var(--mw-success); font-weight: 600; }
.mw-kv__bad  { color: var(--mw-danger); font-weight: 600; }
.mw-kv__sub {
  margin-top: -6px;
  font-family: var(--mw-font-mono);
  font-size: 12px;
  color: var(--mw-muted);
  word-break: break-all;
}

/* MudDialogInstance rendert .mud-dialog-title aus dem Titel-STRING der
   Aufrufstelle - unabhaengig von NoHeader an MudDialog. Der Meadow-Dialog
   bringt seinen eigenen Kopf mit, also hier ausblenden. Per display:none
   ist die Zeile auch aus dem Accessibility-Baum; den zugaenglichen Namen
   liefert aria-labelledby auf .mw-dlg-title. */
.mw-dlg .mud-dialog-title { display: none; }

/* Muds Zwischenelement zwischen Panel und Content (es steht als Geschwister
   hinter .mud-dialog-title) darf die Flex-Kette nicht unterbrechen. */
.mw-dlg > div:not(.mud-dialog-title):not(.mud-dialog-actions) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* Spalten in einer Formularzeile — statt Inline-Styles. */
.mw-col        { flex: 1; min-width: 0; }
.mw-col--wide  { flex: 1.4; }
.mw-col--narrow{ flex: .7; }
.mw-col--double{ flex: 2; }

/* Euterviertel-Auswahl (ersetzt .UdderButton*) */
.mw-quarter-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.mw-quarter {
  padding: 22px 0;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  background: var(--mw-panel);
  font-family: var(--mw-font-display);
  font-size: 24px;
  font-weight: 800;
  color: var(--mw-muted);
  cursor: pointer;
  transition: background var(--mw-t), color var(--mw-t), border-color var(--mw-t);
}
.mw-quarter.is-on {
  background: var(--mw-primary);
  border-color: var(--mw-primary);
  color: #fff;
}

/* ============================================================
   MEHRFACHAUSWAHL-LISTE   (ersetzt die MudTable im ChartEditor)
   ============================================================ */
.mw-check-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  overflow: hidden;
}
.mw-check {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--mw-border);
  font-size: 14px;
  color: var(--mw-text);
  cursor: pointer;
  transition: background var(--mw-t);
}
.mw-check:last-child { border-bottom: none; }
.mw-check.is-on { background: var(--mw-soft); font-weight: 600; }
@media (hover: hover) {
  .mw-check:hover { background: var(--mw-tint); }
}

/* Natives input[type=checkbox]/[type=radio]: accent-color reicht, damit es die
   Markenfarbe traegt - kein Nachbau, keine MudCheckBox. Radios braucht die
   Einfachauswahl im Filter (MeadowSingleSelect). */
.mw-check > input[type="checkbox"],
.mw-check > input[type="radio"] {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  margin: 0;
  accent-color: var(--mw-primary);
  cursor: pointer;
}

.mw-check-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--mw-muted);
}
.mw-check-bar > div { display: flex; gap: 8px; }

/* ============================================================
   FEHLERKASTEN   (SQL-Fehler im KPI-Dialog)
   ============================================================ */
.mw-errbox {
  max-height: 160px;
  overflow: auto;
  padding: 10px 12px;
  border: 1px solid var(--mw-danger);
  border-radius: var(--mw-r-md);
  background: var(--mw-neg-bg);
  font-family: var(--mw-font-mono);
  font-size: 12px;
  line-height: 1.55;
  color: var(--mw-neg-fg);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Der statische Jahres-Picker im ChartDateDialog wird von Mud mit
   einer eigenen Elevation-Karte geliefert - die stoert im Meadow-Body. */
.mw-yearpicker { display: flex; justify-content: center; }

/* ============================================================
   EINSTELLUNGEN   (Tabellenfuss, Standardwerte-Karte)
   ============================================================ */
.mw-table-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 14px;
}
.mw-settings-card {
  max-width: 560px;
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.mw-settings-card .mw-section-title { margin-bottom: 4px; }

/* Basisdaten sind eine Desktop-Admin-Flaeche: dichter, ohne Mobile-Karten. */
.mw-table-wrap--dense .mw-table th,
.mw-table-wrap--dense .mw-table td {
  padding-top: 7px;
  padding-bottom: 7px;
  font-size: 13px;
}

/* Gedaempfter Text in Zellen (Gegenstueck zu .mw-tag--removed). */
.mw-dim { color: var(--mw-muted); }

/* Fuss der Mobil-Kartenliste. Mobil ersetzt Nachladen das Blaettern: der
   Daumen scrollt ohnehin, und ein Pager am Ende einer langen Kartenliste
   wird schlicht uebersehen - er sah dann aus, als haette die Suche nur die
   ersten 25 Treffer gefunden. */
.mw-cards-more {
  margin-top: 4px;   /* .mw-row-card bringt schon 11px margin-bottom mit. */
  text-align: center;
}
/* .mw-btn--block ergibt aus Polsterung und Zeilenhoehe nur ~39px - unter
   dem Touch-Ziel, auf das die uebrige Mobil-CSS zielt. */
.mw-cards-more .mw-btn--block { min-height: var(--mw-control-h-m); }
.mw-cards-more__count {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--mw-muted);
}

/* Der Info-Eintrag im Drawer ist ein <button>, kein NavLink - er braucht
   die Reset-Werte, die NavLink von sich aus mitbringt. */
button.mw-nav-item {
  width: 100%;
  border: 0;
  border-left: 3px solid transparent;
  font-family: inherit;
  text-align: left;
}

/* ============================================================
   KUH-SEITE   (Seitengeruest, Kopfkarte, KPI-Reihe, Klauen-Heatmap,
                Kuchendiagramme, Euterviertel, Zellen-Links)

   Steht bewusst am ENDE der Datei. Drei Regeln hier gewinnen ueber die
   Quellreihenfolge und nicht ueber die Spezifitaet: die Heat-Klassen
   ueberschreiben --mw-hoof aus .mw-hoof-thumb, die KPI-Regeln muessen den
   Mobil-Block des Dashboards (nth-child(n+5)) ueberholen, und die Karten
   der Auswertungsspalte muessen das flex:1 von .mw-card--chart loswerden.
   ============================================================ */

/* ── Seitengeruest ────────────────────────────────────────────── */
/* Mobil ein Stapel, am Desktop zwei Spalten in Fensterhoehe. */
.mw-cow-page {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Kopfkarte und KPI-Reihe sind so hoch wie ihr Inhalt, nicht wie der freie
   Platz. Ohne das zieht .mw-kpi-grid sein flex:2 mit (gedacht fuer die
   Reihe .mw-dash-top des Dashboards) und die sechs Kacheln werden zu
   halbmeterhohen Kaesten. .mw-cow-split holt sich das flex:1 gleich
   darunter wieder - gleiche Spezifitaet, spaetere Regel gewinnt. */
.mw-cow-page > * { flex: 0 0 auto; }

@media (min-width: 1024px) {
  /* Genau der Platz, den .mw-content seinem Inhalt laesst: Fensterhoehe
     minus Kopfzeile minus dessen Innenabstand. Die Tabbar zaehlt nicht mit,
     die ist am Desktop display:none.

     Ein height:100% waere hier wirkungslos - .mw-content-inner ist ein
     Blockelement mit height:auto, und eine Prozenthoehe darin faellt auf
     auto zurueck. Deshalb die Rechnung ueber die Token. */
  .mw-cow-page {
    height: calc(100dvh - var(--mw-header-h) - 2 * var(--mw-content-pad));
  }

  .mw-cow-split {
    display: grid;
    /* minmax(0,...) und nicht 1fr: ein unteilbares "Sohlengeschwuer" im
       Befundtext reichte seine Breite sonst nach oben durch, und die
       Tabellenspalte rechts wuerde dafuer schmaler. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 14px;
    flex: 1;
    min-height: 0;
  }

  .mw-cow-col {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
  }

  /* .mw-card--chart traegt fuer die Diagrammreihe des Dashboards ein
     flex:1 - in einer Spalte hiesse das "so hoch wie der freie Platz", und
     der Canvas waechst mit. Wer hier wachsen darf, sagt die Regel weiter
     unten. */
  .mw-cow-col > * { flex: 0 0 auto; }

  /* Reicht die Hoehe nicht (kurzes Fenster, viele Befunde), scrollt die
     Auswertung in sich. Die SEITE scrollt nicht - das ist der Punkt der
     ganzen Aufteilung. */
  .mw-cow-col--charts {
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .mw-cow-col--lists { overflow: hidden; }

  /* Die Tabelle fuellt den Rest der Spalte und scrollt selbst. Bewusst
     OHNE display-Angabe: .mw-table-wrap ist mobil display:none, und eine
     Regel mit zwei Klassen wuerde dieses none ueberholen. */
  .mw-cow-col--lists > .mw-table-wrap {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
  }

  /* Der eigene Waagerecht-Scroller der Tabelle gibt hier auf. Sonst ist ER
     der naechste scrollende Vorfahr des Spaltenkopfs, und dessen sticky
     klebte an einem Kasten, der beim Scrollen selbst mitwandert - sichtbar
     passiert dann gar nichts. Die Wanne oben scrollt in beiden Richtungen. */
  .mw-cow-col--lists > .mw-table-wrap > .mw-table-scroll { overflow: visible; }

  /* Der Spaltenkopf muss beim Scrollen stehen bleiben. th traegt schon
     eine deckende Flaeche (--mw-tint), sonst schiene der Text durch. */
  .mw-cow-col--lists .mw-table th {
    position: sticky;
    top: 0;
    z-index: 1;
  }

  /* Fuenf Laschen in einer halben Bildschirmbreite. */
  .mw-cow-col--lists .mw-tab { padding: 8px 12px; font-size: 12.5px; }

  /* Der Umschalter der oberen Karte steht statt eines Kartentitels - er darf
     die Karte nicht so hoch machen wie eine Ueberschrift plus Laschen. */
  .mw-cow-col .mw-tabs--card .mw-tab { padding: 4px 10px; font-size: 12.5px; }

  /* Kompakte Karten: die Polsterung von .mw-card ist auf ganze Seiten-
     breite gerechnet, hier stapeln sich drei davon uebereinander. */
  .mw-cow-col .mw-card {
    padding: 9px 12px;
    border-radius: var(--mw-r-2xl);
  }
  .mw-cow-col .mw-card__head { margin-bottom: 6px; }
  .mw-cow-col .mw-card-title { font-size: 14px; }

  /* Das Diagramm ist der Puffer der Spalte: es nimmt, was die drei Karten
     uebrig lassen, und gibt als erstes wieder ab. Zwoelf Balken brauchen
     Breite, nicht Hoehe - unter 96px wird die Achse aber unlesbar, deshalb
     der Boden.

     flex-basis 0 und nicht auto: Chart.js schreibt dem Canvas eine
     Pixelhoehe, und die zaehlte bei auto in die Grundgroesse des Elternteils
     zurueck - der Klassiker, bei dem ein Chart.js-Diagramm bei jedem
     Neuzeichnen ein Stueck waechst.

     Die Karte selbst bekommt bewusst KEIN min-height:0: bei zu wenig Platz
     soll sie auf ihrer Mindestgroesse stehen bleiben und die Spalte scrollen
     lassen. Mit min-height:0 schrumpft sie unter ihren Inhalt, und der
     Canvas laege ungeschnitten auf der Karte darunter. */
  .mw-cow-col > .mw-card--chart {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
  }
  .mw-cow-col .mw-chart-canvas {
    flex: 1 1 0;
    height: auto;
    min-height: 96px;
  }
  /* Und der Canvas selbst darf nicht in die Mindesthoehe seines Kastens
     zaehlen. Sonst waere die zuletzt gezeichnete Pixelhoehe der Boden: das
     Diagramm koennte beim Vergroessern des Fensters wachsen, beim
     Verkleinern aber nie wieder schrumpfen. */
  .mw-cow-col .mw-chart-canvas > canvas { position: absolute; inset: 0; }

  /* 40px Polsterung sind in einer kompakten Karte ein Drittel der Hoehe. */
  .mw-cow-col .mw-empty { padding: 16px 12px; }

  /* In einer Spalte mit gap zaehlt der eigene Abstand doppelt. */
  .mw-cow-col .mw-chart-error { margin-top: 0; }
}


/* ── KPI-Reihe ────────────────────────────────────────────────── */
/* Sechs Kacheln, und sie sollen so flach sein wie moeglich: der Platz, den
   sie hier hergeben, geht unten an die Tabelle.

   Feste Spaltenzahl statt auto-fit: sechs geht in sechs, drei UND zwei
   glatt auf, ein Waisenkind in der letzten Reihe kann gar nicht entstehen.
   Bei auto-fit mit minmax(210px) faellt ein 1280px-Laptop auf 5+1. */
.mw-kpi-grid--cow {
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
/* Ab hier eine einzige Reihe: sechs Kacheln nebeneinander sind halb so hoch
   wie zwei Reihen mit drei, und der gewonnene Platz geht an die Tabelle.
   Darunter wird es zu eng - "Häufigster Klauenbefund" braucht in einer
   160px-Kachel schon zwei Zeilen fuer die Ueberschrift allein, und damit
   ist der Gewinn wieder weg. */
@media (min-width: 1280px) {
  .mw-kpi-grid--cow { grid-template-columns: repeat(6, 1fr); }
}

/* Ein Rasterelement hat min-width:auto und reicht damit die Breite seines
   Inhalts nach oben durch. Ohne das bekommt ein unteilbares
   "Sohlengeschwuer" in Display-Schrift die GANZE Seite einen
   Waagerecht-Scroller - kein Schoenheitsfehler, sondern ein Layoutbruch. */
.mw-kpi-grid--cow > * { min-width: 0; }

/* Raster statt Spalte: der Vergleich zum Vorzeitraum steht RECHTS neben der
   Zahl und nicht darunter. Als dritte Zeile machte er die eine Kachel, die
   ihn hat, 15px hoeher als die anderen fuenf - und weil Rasterzeilen gleich
   hoch sind, die ganze Reihe. */
.mw-kpi-grid--cow .mw-kpi {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 4px 8px;
  padding: 13px 14px;
  border-radius: var(--mw-r-lg);
}
.mw-kpi-grid--cow .mw-kpi__title { grid-column: 1 / -1; font-size: 12px; }
.mw-kpi-grid--cow .mw-kpi__value { font-size: 32px; }
.mw-kpi-grid--cow .mw-kpi__delta { font-size: 12px; }

/* Kacheln, deren Wert ein Wort ist und keine Zahl. Die Groesse steht in der
   --cow-Regel und nicht hier: die Klasse kommt nur auf dieser Seite vor,
   und dort setzt sie ohnehin jede Regel dieses Abschnitts. */
.mw-kpi--text .mw-kpi__value { overflow-wrap: anywhere; }
.mw-kpi-grid--cow .mw-kpi--text .mw-kpi__value { font-size: 19px; line-height: 1.2; }

/* ── Karten der Auswertungsspalte ─────────────────────────────── */
/* Wie .mw-card--chart, aber ohne Canvas - fuer Klauen, Kuchendiagramme und
   Euterviertel, die reines DOM sind.

   Nur min-width und KEIN flex: die Karte stand frueher in einer Reihe
   neben anderen, heute stapelt sie in .mw-cow-col. Ein flex:1 hiesse dort
   "so hoch wie der freie Platz", und weil diese Regel spaeter in der Datei
   steht als das flex:0 0 auto der Spalte, koennte man es dort nicht
   zurueckholen. */
.mw-card--panel { min-width: 0; }


/* ── Klauen und Euterviertel nebeneinander ────────────────────── */
/* Die Klauen bekommen mehr Breite: "Rechts Hinten" ist die laengste
   Beschriftung auf beiden Karten, und die Zelle soll sie nicht kuerzen
   muessen. Mobil stapeln die beiden Karten - siehe den Mobil-Block. */
.mw-cow-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 8px;
  /* Gleich hoch, auch wenn eine Karte weniger Inhalt hat: zwei Karten
     nebeneinander mit unterschiedlich tiefer Unterkante sehen aus, als waere
     eine davon halb geladen. Der Inhalt bleibt oben stehen - die kuerzere
     Karte bekommt unten Luft. */
  align-items: stretch;
}

/* ── Pegel: ein Umriss, der sich von unten fuellt ─────────────── */
/* Zwei deckungsgleiche Umrisse uebereinander: der untere leer, der obere in
   Volltonfarbe und oben weggeschnitten. Traegt sowohl die Klaue als auch das
   Euterviertel - daher der neutrale Name.

   clip-path und keine Maske oder ein Farbverlauf mit hartem Stopp:
   inset() rechnet direkt in Prozent der Elementhoehe, braucht keine im
   Dokument eindeutige id (acht Instanzen je Seite) und bleibt eine gerade
   Kante statt einer weichen.

   Gesetzt werden ZWEI Properties, weil Huf und Zitze je eine eigene haben:
   --mw-hoof traegt der Huf ohnehin quer durch den Klauen-Dialog, und eine
   gemeinsame Property haette ihn dort mitumbenannt. */
.mw-level {
  position: relative;
  display: block;
  flex-shrink: 0;
  --mw-hoof: var(--mw-hoof-idle);
  --mw-teat: var(--mw-hoof-idle);
}
.mw-level__fill {
  position: absolute;
  inset: 0;
  --mw-hoof: var(--mw-level-fill);
  --mw-teat: var(--mw-level-fill);
  clip-path: inset(calc(100% - var(--mw-level, 0%)) 0 0 0);
}

/* Die Zitze: Groesse kommt vom Elternelement, Farbe aus --mw-teat. Wie
   .mw-hoof-svg, nur fuer den anderen Umriss. */
.mw-teat-svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: hidden;
  fill: var(--mw-teat, var(--mw-teal));
  transition: fill var(--mw-t);
}

/* ── Koerperstellen: Klauen und Euterviertel ──────────────────── */
/* Zwei Karten, ein Bauplan. Beide beantworten "wo am Tier?" und zeigen ein
   2x2 aus Umriss, Ort und Zahl - nebeneinander muessen sie gleich aussehen,
   sonst liest man sie als zwei verschiedene Dinge.

   NICHT .mw-show-grid wiederverwenden: das faellt mobil auf eine Spalte
   zurueck. Hier IST das 2x2 die Aussage - vorne/hinten und links/rechts
   stehen an ihrem Platz am Tier. Vier Zellen untereinander waeren eine
   Liste, keine Karte. */
.mw-part-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
.mw-part-grid .mw-level { width: 30px; height: 30px; }

/* Bei den Klauen IST die Zelle der Link auf die gefilterte Liste; beim Euter
   ist sie ein div - Kuhbehandlungen lassen sich nicht nach Viertel filtern.

   min-width:0, weil ein Rasterelement sonst die Breite seines Inhalts nach
   oben durchreicht - "Hinten rechts" wuerde die Karte sprengen statt zu
   kuerzen. */
.mw-part-cell {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 6px 9px;
  background: var(--mw-tint);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--mw-t), background var(--mw-t);
}

/* Der Attributwaehler und nicht die Klasse: eine Klaue ohne Behandlung
   rendert ein a OHNE href (siehe CowHoofLevels), und die Euterzelle ist gar
   kein a. Beide sollen auch nicht so aussehen, als koenne man sie anfassen. */
.mw-part-cell[href] { cursor: pointer; }
@media (hover: hover) {
  .mw-part-cell[href]:hover {
    background: var(--mw-panel);
    border-color: var(--mw-primary);
  }
}
/* Die Klaue, auf die die Liste rechts gerade gefiltert ist. Der Innenschatten
   ist der zweite Rahmenstrich: ein 2px-border liesse die Zelle um einen Pixel
   wachsen und die Reihe daneben mitspringen. */
.mw-part-cell.is-active {
  background: var(--mw-panel);
  border-color: var(--mw-primary);
  box-shadow: inset 0 0 0 1px var(--mw-primary);
}

/* Umbrechen statt kuerzen. Nebeneinander bleiben einer Zelle rund 90px fuer
   die Beschriftung, und "Rechts Hinten" braucht in einer Zeile 110 - mit
   Ellipse stuende dort "Rechts Hin...". Ueber zwei Zeilen bleibt die Zelle
   sogar gleich hoch: zwei Zeilen sind niedriger als der 30px-Umriss daneben. */
.mw-part-cell__label {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--mw-text);
}
.mw-part-cell__count {
  font-family: var(--mw-font-display);
  font-weight: 800;
  font-size: 16px;
  line-height: 1;
  color: var(--mw-text);
}


/* ── Umschaltkarte (Verlauf / Medikamente / Gruende) ─────────── */
/* Die Laschen stehen anstelle eines Kartentitels: die gedrueckte benennt,
   was darunter steht. Deshalb sitzen sie auf dem Kartenrahmen wie ein
   Kartenkopf und nicht als Leiste im Inhalt. */
.mw-tabs--card {
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
/* Der Zeitraum gehoert zur Lasche "Pro Monat" und verschwindet mit ihr.
   Rechts, damit er den Umschalter nicht auseinanderschiebt. */
.mw-tabs__note {
  margin-left: auto;
  padding-left: 12px;
  font-size: 11px;
  color: var(--mw-muted);
}

/* Der Kuchen bekommt die Hoehe, die sonst das Diagramm hat, und steht darin
   mittig statt oben zu kleben.

   flex-basis auto und KEIN min-height:0 - anders als beim Canvas daneben.
   Der Canvas darf schrumpfen, weil Chart.js ihn nachzeichnet; ein Kuchen hat
   eine feste Hoehe aus Scheibe und Legende. Mit basis 0 zaehlte er gar nicht
   in die Mindesthoehe der Karte, die Karte bliebe so hoch wie ihre Laschen,
   und der Kuchen laege darueber. */
.mw-cow-chartpanel {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
}

/* ── Kuchendiagramme (Medikamente / Gruende) ─────────────────── */
/* Kreis links, Legende rechts. Bewusst kein Chart.js - die Begruendung steht
   im Kopf von MeadowPieChart.

   flex-wrap, damit die Legende unter den Kreis rutscht statt sich auf
   Ellipsen zusammenzuquetschen, wenn die Spalte schmal wird. */
.mw-pie {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.mw-pie__disc {
  width: 76px;
  height: 76px;
  flex-shrink: 0;
}
/* Auf der Umschaltkarte steht der Kuchen anstelle des Diagramms und hat
   dessen Platz: eine halbe Spaltenbreite und rund 300px Hoehe. Die Scheibe
   waechst deshalb mit dem Fenster statt auf einer festen Groesse
   stehenzubleiben, und die Legende bleibt daneben - untereinander bliebe
   neben der Scheibe die halbe Karte leer.

   Die Obergrenze ist kein Geschmack: hoeher als die Karte darf die Scheibe
   nicht werden, sonst schiebt sie die Spalte ins Scrollen. */
.mw-pie--large {
  flex: 1;
  min-width: 0;
  /* Kein Umbruch: untereinander waere der Kuchen fast doppelt so hoch wie
     die Karte und schoebe die ganze Spalte ins Scrollen. Wird es eng,
     schrumpfen Scheibe und Legende - sie brauchen nicht untereinander. */
  flex-wrap: nowrap;
  justify-content: center;
  gap: 24px;
}
/* Zwei Deckel, und beide sind noetig: die Hoehe begrenzt die Karte, die
   Breite die halbe Spalte. Ohne den Breitenanteil passte eine 267px-Scheibe
   auf einem 1512er Schirm, auf einem 1280er aber nicht mehr neben die
   Legende. */
.mw-pie--large .mw-pie__disc {
  width: clamp(150px, min(31vh, 40%), 300px);
  height: auto;
  aspect-ratio: 1;
}
/* Gedeckelt: ueber die ganze Kartenbreite gezogen stuenden Beschriftung und
   Zahl so weit auseinander, dass die Zeile nicht mehr als Paar zu lesen
   waere. */
.mw-pie--large .mw-pie__legend {
  flex: 0 1 280px;
  gap: 8px;
}
.mw-pie--large .mw-pie__label,
.mw-pie--large .mw-pie__value { font-size: 14px; }
.mw-pie--large .mw-pie__swatch { width: 11px; height: 11px; }

/* Die Form jedes Stuecks kommt als Pfad aus MeadowPieChart.

   Der Strich ist die Trennfuge und liegt in der Kartenfarbe AUF der Kante.
   non-scaling-stroke haelt ihn bei 2px, egal wie gross die Scheibe gerade
   ist - eine Luecke im Winkel waere bei einer 300px-Scheibe ein Spalt und
   bei einer 76px-Scheibe ein Haarriss. linejoin:round, damit die spitze
   Ecke im Mittelpunkt bei einem schmalen Keil nicht als Dorn hinausschiesst. */
.mw-pie__slice {
  fill: var(--mw-slice, var(--mw-series-other));
  stroke: var(--mw-panel);
  stroke-width: 2;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.mw-pie__legend {
  flex: 1 1 120px;
  min-width: 0;
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.mw-pie__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 7px;
}
.mw-pie__swatch {
  width: 9px;
  height: 9px;
  border-radius: var(--mw-r-xs);
  background: var(--mw-slice, var(--mw-series-other));
}
/* Der ganze Name steht im title-Attribut: neben zwei weiteren Verteilungen
   bleiben der Spalte rund 240px, und "Novaminsulfon 500" passt da nicht. */
.mw-pie__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  line-height: 1.3;
  color: var(--mw-text);
}
/* Die Zahl ist die genaue Auskunft - ein Kuchen unterscheidet zwei aehnlich
   grosse Stuecke nicht. */
.mw-pie__value {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--mw-text);
}

/* Feste Reihenfolge, nie im Kreis weitergezaehlt: ein siebter Eintrag
   bekommt keine neue Farbe, sondern faellt in "Weitere". */
.mw-slice-1 { --mw-slice: var(--mw-series-1); }
.mw-slice-2 { --mw-slice: var(--mw-series-2); }
.mw-slice-3 { --mw-slice: var(--mw-series-3); }
.mw-slice-4 { --mw-slice: var(--mw-series-4); }
.mw-slice-5 { --mw-slice: var(--mw-series-5); }
.mw-slice-6 { --mw-slice: var(--mw-series-6); }
.mw-slice-other { --mw-slice: var(--mw-series-other); }

/* ── Tab-Leiste mit fuenf Laschen ─────────────────────────────── */
/* Umbrechen darf sie nicht: der Unterstrich der aktiven Lasche liegt auf
   dem Rahmen des Containers und hinge in einer ersten Zeile in der Luft.
   Also scrollen. */
.mw-tabs--scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
}
.mw-tabs--scroll .mw-tab { flex: 0 0 auto; white-space: nowrap; }

/* ── Listenauswahl (mobil statt der fuenf Laschen) ────────────── */
/* Ein natives select, damit das Geraet seine eigene Auswahlliste oeffnet -
   die trifft man mit dem Daumen sicherer als fuenf Laschen in einer
   Schiebeleiste, und sie zeigt alle fuenf auf einmal. Die Sichtbarkeit
   regelt .mw-only-mobile am Element. */
.mw-tab-select { position: relative; display: block; }
.mw-tab-select select {
  /* appearance:none nimmt dem Feld den System-Look; den Pfeil zeichnet der
     MeadowIcon daneben. Sonst sitzt hier ein Bedienelement, das als einziges
     nach Betriebssystem aussieht statt nach Anwendung. */
  appearance: none;
  width: 100%;
  padding: 11px 36px 11px 12px;
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-lg);
  background: var(--mw-panel);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--mw-text);
}
/* Die Auswahlliste zeichnet das Betriebssystem. color-scheme sagt ihm, in
   welchem Theme - ohne das nimmt es die Systemeinstellung und malt im hellen
   Theme ein dunkles Menue (oder umgekehrt). Die beiden Farben setzt es aus
   den option-Regeln, die es respektiert. */
.mw-tab-select select { color-scheme: light; }
:root[data-mw-theme="dark"] .mw-tab-select select { color-scheme: dark; }
.mw-tab-select option {
  background: var(--mw-panel);
  color: var(--mw-text);
}
.mw-tab-select > svg {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--mw-muted);
  pointer-events: none;
}

/* ── Aktiver Klauenfilter ─────────────────────────────────────── */
/* Steht zwischen Laschen und Tabelle, weil die Liste darunter sonst
   unerklaerlich kurz waere - besonders fuer jemanden, der ueber einen
   geteilten Link hereinkommt und die Klauen-Karte gar nicht angeklickt hat.
   Das Aufheben ist ein echter Link auf die Lasche ohne ?klaue=. */
.mw-cow-filter {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 7px 12px;
  border: 1px solid var(--mw-border);
  border-left: 3px solid var(--mw-primary);
  border-radius: var(--mw-r-lg);
  background: var(--mw-tint);
  font-size: 13px;
  color: var(--mw-muted);
}
.mw-cow-filter strong { color: var(--mw-text); }
.mw-cow-filter__clear {
  flex-shrink: 0;
  font-weight: 600;
  color: var(--mw-primary);
  text-decoration: none;
}
@media (hover: hover) {
  .mw-cow-filter__clear:hover { text-decoration: underline; }
}

/* Die Anzahl hinter dem Tabnamen. Kein .mw-badge: das ist ein gefuellter
   Zaehler fuer den Filterknopf, hier soll die Zahl der Beschriftung
   nachgeordnet bleiben. */
.mw-tab__count {
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  opacity: .65;
}

/* ── Verlinkte Tabellenzelle ──────────────────────────────────── */
/* Ein echtes a-href statt eines Klicks auf die ganze Zeile: Tastatur,
   Mittelklick und "in neuem Tab oeffnen" funktionieren damit von selbst -
   dasselbe Argument steht im Kopfkommentar von MeadowKpiTile. Und die
   Aktionsknoepfe in den Spalten daneben koennen gar nicht erst mit einem
   Zeilenklick kollidieren. */
.mw-cell-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
@media (hover: hover) {
  .mw-cell-link:hover { color: var(--mw-primary); border-bottom-color: currentColor; }
}
/* Die Karte gibt es als button (oeffnet einen Dialog) und als a (fuehrt zur
   Kuh-Seite); ohne das waere die zweite unterstrichen. */
a.mw-row-card { text-decoration: none; }

/* ── Kuh-Seite mobil ──────────────────────────────────────────── */
@media (max-width: 1023.98px) {
  /* Kein Zweispalter und keine gedeckelte Hoehe: mobil scrollt die Seite
     als Ganzes, so wie jede andere auch. .mw-cow-page bleibt der Stapel,
     der es in der Basis schon ist. */
  .mw-cow-split,
  .mw-cow-col { display: flex; flex-direction: column; gap: 12px; }

  /* Zwei 2x2-Raster nebeneinander sind auf 375px acht Zellen von 40px. */
  .mw-cow-pair { grid-template-columns: 1fr; gap: 12px; }

  /* Muss wiederholt werden: die unbedingte --cow-Regel oben steht SPAETER
     in der Datei als der Mobil-Block des Dashboards und erzwaenge sonst
     auch auf 360px drei Spalten, also 106px je Kachel. */
  .mw-kpi-grid--cow { grid-template-columns: 1fr 1fr; }

  /* Das Dashboard blendet ab der fuenften Kachel aus, weil es acht hat und
     das Design mobil vier zeichnet. Hier sind alle sechs gemeint: offene
     Verbaende und offene Termine sind genau die zwei Zahlen, wegen denen
     jemand im Stall aufs Handy schaut. Doppelte Klasse, damit die Regel
     unabhaengig von der Quellreihenfolge gewinnt; display:flex und nicht
     revert - .mw-kpi IST flex, revert fiele auf inline zurueck. */
  .mw-kpi-grid.mw-kpi-grid--cow > *:nth-child(n+5) { display: flex; }

  /* Am Daumen ist Platz, den der Desktop nicht hat: dort muss die Reihe
     flach bleiben, hier darf die Zahl wieder lesbar gross sein. */
  .mw-kpi-grid--cow .mw-kpi__value { font-size: 28px; }
  .mw-kpi-grid--cow .mw-kpi--text .mw-kpi__value { font-size: 17px; }

  /* Die Legende unter dem Diagramm frisst mobil ein Sechstel der 150px aus
     --mw-bars-h. Nur hier und nicht an .mw-chart-canvas selbst: auf dem
     Dashboard stehen drei Diagramme ohne Legende. */
  .mw-cow-page .mw-chart-canvas { height: 190px; }

  /* Am Daumen sind die vier Zellen Tippziele: 40px Huf plus 11px Polsterung
     ergeben 64px Hoehe, deutlich ueber den 44px, unter denen man daneben
     tippt. */
  /* Am Daumen sind die Klauenzellen Tippziele: 40px Umriss plus 11px
     Polsterung ergeben 64px Hoehe, deutlich ueber den 44px, unter denen man
     daneben tippt. Das Euter erbt dieselben Masse - die beiden Karten
     stehen mobil untereinander und muessen gleich aussehen. */
  .mw-part-grid { gap: 8px; }
  .mw-part-cell { padding: 11px 12px; gap: 11px; }
  .mw-part-grid .mw-level { width: 40px; height: 40px; }
  .mw-part-cell__label { font-size: 14px; }
  .mw-part-cell__count { font-size: 20px; }

  /* Mobil steht jede Verteilung auf voller Breite - da passt ein groesserer
     Kreis, und "Amoxicillin 400 mg" muss nicht mehr zur Ellipse werden. */
  .mw-pie { gap: 16px; }
  .mw-pie__disc { width: 92px; height: 92px; }
  .mw-pie__legend { gap: 6px; }
  .mw-pie__label { white-space: normal; font-size: 13px; }
  .mw-pie__value { font-size: 13px; }

  /* Auf 375px ist neben einer brauchbaren Scheibe keine Legende mehr - also
     darunter. vh statt vw als Deckel, damit ein liegendes Telefon nicht eine
     Scheibe bekommt, die hoeher ist als sein Bildschirm. */
  .mw-pie--large { gap: 16px; flex-direction: column; align-items: center; }
  .mw-pie--large .mw-pie__disc { width: min(62vw, 34vh); }
  .mw-pie--large .mw-pie__legend { flex: 0 1 auto; width: 100%; max-width: 300px; }

  /* Fuenf Laschen passen auf 328px nur mit schmalerem Innenabstand -
     load-bearing, nicht Politur. */
  .mw-tabs--scroll .mw-tab { padding: 11px 12px; }
}

/* ── Seite /uebertragung ─────────────────────────────────────── */
/* Karten und keine Tabelle: die Fehlermeldung des Servers ist ein
   Satz, und ein Satz in einer Tabellenzelle wird entweder
   abgeschnitten oder sprengt die Spaltenbreiten. */
.mw-transfers {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.mw-transfers__empty {
  padding: 32px 0;
  text-align: center;
  color: var(--mw-muted);
}
.mw-transfer {
  padding: 14px 16px;
  background: var(--mw-panel);
  border: 1px solid var(--mw-border);
  border-radius: var(--mw-r-2xl, 14px);
  box-shadow: var(--mw-shadow-card);
}
.mw-transfer--fehler { border-color: var(--mw-danger); }

.mw-transfer__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.mw-transfer__title {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  color: var(--mw-text);
}
.mw-transfer__when {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--mw-muted);
}

/* Woertlich das, was der Server geantwortet hat. Nicht zu einer
   freundlichen Formulierung geglaettet: wer hier landet, braucht
   die Meldung zum Weitergeben, nicht zum Beruhigen. */
.mw-transfer__error {
  margin: 8px 0 0;
  padding: 8px 10px;
  font-family: var(--mw-font-mono);
  font-size: 12px;
  line-height: 1.45;
  color: var(--mw-neg-fg);
  background: var(--mw-neg-bg);
  border-radius: var(--mw-r-md, 8px);
  overflow-wrap: anywhere;
}
.mw-transfer__meta {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--mw-muted);
}
.mw-transfer__actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
