/* ═══════════════════════════════════════════════════════════════════════════════
   ViCORE — vi-ui: ARBEITSFLÄCHEN-BAUSTEINE  (Betrieb-Redesign, 03.08.2026)
   ───────────────────────────────────────────────────────────────────────────────
   EIN Satz Bausteine für alle Listen-, Arbeits- und Aktenseiten. Entstanden aus dem
   Umbau des Bereichs „Betrieb", bewusst modulunabhängig gehalten — Vorgänge, Energie,
   Beschaffung usw. sollen dieselben Klassen benutzen.

   VERBINDLICHES SEITENMUSTER (docs/BETRIEB_REDESIGN.md §2.3) — höchstens VIER
   Leisten, bevor die erste Datenzeile kommt:

     .vi-pagehead    Titel · Ansichtsumschalter · genau EINE Primäraktion
     .vi-metricbar   Kennzahlen — jede ist ein Filter, keine Dekoration
     .vif-bar        Suche · Objekt · Fachfilter · Weitere Filter   → VIFilters
     .vi-listhead    Trefferzahl · Gruppierung · Sortierung · Exportieren
     .vi-tbl-…       Tabelle und Karten                             → VITable

   ABGRENZUNG: Tabellen kommen aus vi-table.css (docs/TABLE_STANDARD.md), Filter aus
   vi-filters.css (docs/FILTER_STANDARD.md). Diese Datei baut beides NICHT nach — sie
   ergänzt nur, was dort fehlt: Seitenkopf, Metrikleiste, Aktenkopf, Prozesskette,
   Datenvollständigkeit, Arbeitsliste, Leer-/Lade-/Fehlerzustand, Aktionsmenü.

   REGELN
   • Nur Tokens aus css/design-system.css. Keine Hex-Werte, keine rohen px-Schriftgrößen.
   • Weiß ist die Inhaltsfläche. Cream/Beige NUR als Seitenhintergrund, nie als Kartenfarbe.
   • Zustand steht IMMER auch als Text — Farbe ist Verstärkung, nie alleiniger Träger.
   • Kritisches erscheint als schmale Kante, nie als großflächig rote Fläche.
   • Genau EINE Optik je Bedeutung: Navigation ≠ Tab ≠ Segment ≠ Chip ≠ Badge ≠ Button.

   Ladeposition: als LETZTES Stylesheet in index.html (nach vi-filters.css), damit die
   Bausteine die gewachsenen Modulstile für ihre eigenen Klassen sicher gewinnen.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────────────
   0 · SEITENRAHMEN
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-page {
  display: flex;
  flex-direction: column;
  /* 8 px zwischen Filterleiste und Arbeitsbereich statt 12 px (UX-Phase 3):
     die Blöcke sind durch Fläche und Typografie längst getrennt. */
  gap: var(--space-2);
  min-width: 0;
  max-width: 100%;
}
/* Jede Leiste darf schmaler werden als ihr Inhalt. Ohne diese Regel setzt eine Leiste
   mit `flex-wrap:nowrap` (z. B. die Metrikleiste unter 1180 px) ihre Mindestbreite
   nach oben durch, bis die ganze SEITE waagerecht scrollt — gemessen 1189 px Inhalt
   in einem 1024-px-Fenster. Regel: nur der Inhaltsbereich scrollt, nie der Body. */
.vi-page > * { min-width: 0; max-width: 100%; }
/* AP 1.2 — eine Datei über der Seite: die Fläche zeigt an, dass sie sie annimmt.
   Kein eigener Kasten und keine Überlagerung, nur ein ruhiger Markenrahmen —
   der Inhalt bleibt lesbar, während die Datei noch in der Luft hängt. */
.vi-page.is-filedrag { outline: 2px dashed var(--brand-primary); outline-offset: var(--space-2); border-radius: var(--radius-lg); }
/* Zwischen Filterbereich und Ergebnisbereich etwas mehr Luft als zwischen den Leisten. */
.vi-page > .vi-listhead { margin-top: var(--space-1); }

/* ───────────────────────────────────────────────────────────────────────────────
   1 · SEITENKOPF — Titel, Ansicht, EINE Primäraktion
   Bewusst OHNE Untertitel: erklärende Beschreibungszeilen sind laut CLAUDE.md
   Entwicklungsinfos und gehören nicht ins Frontend.
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-pagehead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  min-height: var(--ui-btn-h);
}
.vi-pagehead__l { display: flex; align-items: center; gap: var(--space-4); min-width: 0; flex-wrap: wrap; }
.vi-pagehead__r { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; min-width: 0; }
/* Ohne min-width:0 nimmt ein Flex-Kind mindestens seine Inhaltsbreite ein und
   schrumpft nie — der Kopf lief dadurch auf schmalen Breiten über (gemessen 37 px
   bei 520 px Inhaltsbreite). Gilt für Titel UND Segmentschalter. */
.vi-pagehead__l > *, .vi-pagehead__r > * { min-width: 0; }
.vi-pagetitle {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--ui-text-page);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  color: var(--gray-900);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Abschnittsüberschrift innerhalb einer Seite oder Akte. */
.vi-sectionhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: var(--space-2) 0 var(--space-2);
}
.vi-sectiontitle {
  margin: 0;
  font-size: var(--ui-text-section);
  font-weight: var(--fw-semibold);
  color: var(--gray-900);
  line-height: var(--lh-snug);
}
.vi-sectiontitle .vi-n {
  margin-left: var(--space-2);
  font-size: var(--ui-text-meta);
  font-weight: var(--fw-medium);
  color: var(--gray-500);
  font-variant-numeric: tabular-nums;
}

/* ───────────────────────────────────────────────────────────────────────────────
   2 · SEGMENTSCHALTER (Ebene 3: Ansicht im Tab) — höchstens drei Einträge
   Klar unterscheidbar von Tabs (Unterstrich) und Chips (rund, entfernbar).
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-seg {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  gap: 2px;
  background: var(--ui-surface-2);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius);
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.vi-seg::-webkit-scrollbar { display: none; }
.vi-seg__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 30px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: calc(var(--ui-radius) - 3px);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--ui-text-meta);
  font-weight: var(--fw-medium);
  color: var(--gray-700);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition), color var(--transition);
}
.vi-seg__btn:hover { color: var(--gray-900); background: rgba(255, 255, 255, 0.6); }
.vi-seg__btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.vi-seg__btn.is-active {
  background: var(--ui-surface);
  color: var(--gray-900);
  font-weight: var(--fw-semibold);
  box-shadow: var(--shadow-sm);
}
.vi-seg__n { font-size: var(--ui-text-label); font-variant-numeric: tabular-nums; opacity: 0.7; }

/* ───────────────────────────────────────────────────────────────────────────────
   3 · METRIKLEISTE — Kennzahl = Filter
   Ersetzt .anl-kpis + .anl-viewrow (zwei Leisten mit derselben Aufgabe), .cmp-stats,
   .ckpi-card, .fri-kpi und .wk-kpis. Kompakt, klickbar, mit Zustand.
   ─────────────────────────────────────────────────────────────────────────────── */
/* EIN zusammenhängendes Bedienelement, keine Reihe einzelner Pillen.
   Einzelpillen mit inhaltsabhängiger Breite und eigenem Rahmen wirkten verstreut und
   ungleichmäßig („unförmig", Nutzerbefund 03.08.2026) und brachen zudem in eine zweite
   Zeile um. Jetzt: gemeinsamer Rahmen, dünne Trennlinien, feste Höhe, immer EINE Zeile
   — bei Platzmangel scrollt die Leiste in sich, nicht die Seite. */
.vi-metricbar {
  display: inline-flex;
  align-items: stretch;
  /* In einer Flex-Spalte (.vi-page) würde `align-items: stretch` die Leiste auf die
     volle Seitenbreite ziehen — ein langer leerer weißer Streifen hinter den paar
     Einträgen. Sie soll sich um ihren Inhalt legen. */
  align-self: flex-start;
  flex-wrap: nowrap;
  /* Explizit 0: gewachsene Modulklassen am selben Element (z. B. `.anl-kpis`) setzen
     einen Abstand aus der Zeit der Einzelkacheln. Der würde das zusammenhängende
     Segment wieder in Einzelteile zerlegen. */
  gap: 0;
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius);
  background: var(--ui-surface);
}
.vi-metricbar::-webkit-scrollbar { display: none; }
.vi-metric {
  /* display/white-space EXPLIZIT: der globale Elementselektor `button` in
     design-system.css setzt inline-flex + nowrap. Ohne diese Angaben liefen
     Zahl und Beschriftung nebeneinander aus der Kachel heraus (Fehlerbild
     „überlappende Kennzahlen" auf /betrieb/wartungen). */
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  white-space: nowrap;
  flex: 0 0 auto;
  min-width: 0;
  height: var(--ui-metric-h);
  padding: 0 var(--space-3);
  border: 0;
  border-right: 1px solid var(--ui-line);
  border-radius: 0;
  background: transparent;
  font-family: var(--font-body);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.vi-metric:last-child { border-right: 0; }
.vi-metric:hover { background: var(--ui-surface-2); }
.vi-metric:focus-visible { outline: none; background: var(--ui-surface-2); box-shadow: inset 0 0 0 2px var(--color-sage); }
.vi-metric__l {
  font-size: var(--ui-text-meta);
  font-weight: var(--fw-medium);
  color: var(--gray-700);
  /* Im Zweispalten-Raster (≤620 px) ist die Kachel schmaler als lange Beschriftungen
     wie „Ohne Dienstleister" — dann kürzen statt überlaufen. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vi-metric__n { flex: 0 0 auto; }
.vi-metric__n {
  /* Die Zahl trägt die Aussage, muss die Kachel aber nicht dominieren — bei 20px
     wirkte die Leiste wie eine Kennzahlen-Kachelreihe statt wie eine Filterzeile. */
  font-size: var(--ui-text-body);
  font-weight: var(--fw-bold);
  color: var(--gray-900);
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum", "tnum";
  line-height: 1;
}
.vi-metric__dot { width: 7px; height: 7px; border-radius: 50%; align-self: center; flex: 0 0 auto; }
/* Aktiv = gewählter Filter. Voller Forest-Ton, damit die Auswahl unübersehbar ist. */
.vi-metric.is-active { background: var(--color-forest); box-shadow: none; }
.vi-metric.is-active .vi-metric__l,
.vi-metric.is-active .vi-metric__n { color: var(--text-inverse); }
.vi-metric.is-active .vi-metric__dot { background: rgba(255, 255, 255, 0.85); }
/* Kritikalität trägt AUSSCHLIESSLICH der farbige Punkt vor der Beschriftung.
   Eine linke Farbkante je Eintrag würde das zusammenhängende Segment zerschneiden. */
.vi-metric__dot--crit { background: var(--color-danger); }
.vi-metric__dot--warn { background: var(--color-warning-ink); }
.vi-metric__dot--info { background: var(--color-info); }
.vi-metric__dot--ok   { background: var(--color-success-ink); }

/* ───────────────────────────────────────────────────────────────────────────────
   4 · ERGEBNISZEILE — Trefferzahl links, Werkzeuge rechts
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-listhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  min-width: 0;
}
.vi-listhead__l, .vi-listhead__r { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
.vi-count {
  font-size: var(--ui-text-meta);
  color: var(--gray-700);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.vi-count strong { font-weight: var(--fw-semibold); color: var(--gray-900); }

/* Kompakte Werkzeugschaltfläche (Sortierung, Gruppierung, Export, Spalten). */
.vi-tool {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--ui-btn-sm-h);
  padding: 0 var(--space-3);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius);
  background: var(--ui-surface);
  font-family: var(--font-body);
  font-size: var(--ui-text-meta);
  font-weight: var(--fw-medium);
  color: var(--gray-700);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--transition), background var(--transition), color var(--transition);
}
.vi-tool:hover { border-color: var(--gray-500); color: var(--gray-900); background: var(--ui-surface-2); }
.vi-tool:focus-visible { outline: none; border-color: var(--color-sage); box-shadow: var(--focus-ring); }
.vi-tool svg { width: 14px; height: 14px; flex: 0 0 auto; }
.vi-tool__caret { font-size: var(--ui-text-label); opacity: 0.6; }

/* ───────────────────────────────────────────────────────────────────────────────
   5 · STATUS — EINE Badge-Familie, fünf Töne, immer mit Text
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px var(--space-2);
  border-radius: var(--vi-r-pill);
  font-family: var(--font-body);
  font-size: var(--ui-text-label);
  font-weight: var(--fw-semibold);
  line-height: 1.5;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vi-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; opacity: 0.85; }
.vi-badge--plain::before { display: none; }
.vi-tone-ok      { background: var(--color-success-soft); color: var(--color-success-ink); }
.vi-tone-warn    { background: var(--color-warning-soft); color: var(--color-warning-ink); }
.vi-tone-crit    { background: var(--color-danger-soft);  color: var(--color-danger-ink); }
.vi-tone-info    { background: var(--color-info-soft);    color: var(--color-info-ink); }
.vi-tone-neutral { background: var(--gray-100);           color: var(--gray-700); }

/* Reiner Textzustand ohne Fläche (z. B. in dichten Tabellenzellen). */
.vi-state { font-size: var(--ui-text-meta); font-weight: var(--fw-medium); }
.vi-state.vi-tone-ok      { background: none; color: var(--color-success-ink); }
.vi-state.vi-tone-warn    { background: none; color: var(--color-warning-ink); }
.vi-state.vi-tone-crit    { background: none; color: var(--color-danger-ink); }
.vi-state.vi-tone-info    { background: none; color: var(--color-info-ink); }
.vi-state.vi-tone-neutral { background: none; color: var(--gray-500); }

/* Fehlender Wert — einheitlich, dezent, nie eine große graue Kachel. */
.vi-missing { color: var(--gray-500); font-style: italic; }

/* ───────────────────────────────────────────────────────────────────────────────
   6+7 · TABELLE UND KARTEN — bewusst NICHT hier.
   Tabellen kommen ausschließlich aus dem zentralen Tabellensystem
   public/vi-table.css + public/vi-table.js (Namespace .vi-tbl-…, docs/TABLE_STANDARD.md).
   Ein zweites Tabellen-CSS wäre genau die Doppelung, die dieser Umbau beseitigt.
   ─────────────────────────────────────────────────────────────────────────────── */

/* ───────────────────────────────────────────────────────────────────────────────
   8 · LEERZUSTÄNDE — kompakt, konkret, höchstens zwei Aktionen
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-empty {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius-lg);
  background: var(--ui-surface);
}
.vi-empty__ic {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: 0 0 auto;
  border-radius: 50%;
  background: var(--gray-100);
  color: var(--gray-500);
}
.vi-empty__ic svg { width: 18px; height: 18px; }
.vi-empty--ok .vi-empty__ic { background: var(--color-success-soft); color: var(--color-success-ink); }
.vi-empty__tx { min-width: 0; flex: 1 1 auto; }
.vi-empty__t { font-size: var(--ui-text-body); font-weight: var(--fw-semibold); color: var(--gray-900); }
.vi-empty__s { font-size: var(--ui-text-meta); color: var(--gray-700); margin-top: 2px; }
.vi-empty__a { display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; flex-wrap: wrap; }

/* Sehr kompakter Leerzustand innerhalb eines Abschnitts einer Akte. */
.vi-empty--inline {
  padding: var(--space-3) var(--space-4);
  background: var(--gray-100);
  border: 0;
}
.vi-empty--inline .vi-empty__ic { display: none; }

/* ───────────────────────────────────────────────────────────────────────────────
   9 · VOLLSTÄNDIGKEIT — ersetzt Felder-mit-„nicht erfasst"-Kachelwüsten
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-completeness {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius);
  background: var(--ui-surface);
}
.vi-completeness__bar { position: relative; width: 120px; height: 6px; border-radius: 3px; background: var(--gray-100); flex: 0 0 auto; overflow: hidden; }
.vi-completeness__fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--color-sage); }
.vi-completeness--low  .vi-completeness__fill { background: var(--color-warning-ink); }
.vi-completeness--full .vi-completeness__fill { background: var(--color-success-ink); }
.vi-completeness__tx { font-size: var(--ui-text-meta); color: var(--gray-700); min-width: 0; flex: 1 1 auto; }
.vi-completeness__tx strong { color: var(--gray-900); font-weight: var(--fw-semibold); }

/* ───────────────────────────────────────────────────────────────────────────────
   10 · AKTIONSMENÜ (Kebab / Exportieren) — EINE Optik app-weit
   ─────────────────────────────────────────────────────────────────────────────── */
/* Menü/Popover-Zuordnung laut Designsystem: Radius `--radius-lg`, Schatten
   `--shadow-pop`. Die Stapelhöhe kommt aus der EINEN Leiter (vi-dialog.css);
   der Fallback hält den Bestandswert, falls die Datei einmal fehlt. Ein Menü
   liegt IMMER über dem Dialog, aus dem es aufklappt. */
.vi-menu {
  position: fixed;
  z-index: var(--vdlg-z-pop, 9000);
  min-width: 210px;
  max-width: 320px;
  padding: var(--space-1);
  background: var(--ui-surface);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius-lg);
  box-shadow: var(--shadow-pop);
}
.vi-menu__i {
  /* justify-content MUSS hier stehen: public/design-system.css definiert global
     "button, .btn { justify-content: center }". Ohne diese Angabe stünden alle
     Menüeinträge zentriert statt linksbündig — das weiter unten gesetzte
     text-align wirkt in einem Flex-Container nicht. */
  display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2);
  width: 100%; padding: var(--space-2) var(--space-3);
  border: 0; background: none; border-radius: var(--radius-sm);
  font: inherit; font-family: var(--font-body); font-size: var(--ui-text-body);
  color: var(--gray-900); text-align: left; cursor: pointer; white-space: nowrap;
}
.vi-menu__i:hover { background: var(--gray-100); }
.vi-menu__i:focus-visible { outline: none; background: var(--gray-100); box-shadow: var(--focus-ring); }
.vi-menu__i--danger { color: var(--color-danger-ink); }
.vi-menu__i[disabled] { opacity: 0.45; cursor: not-allowed; }
/* Symbolspalte: feste Breite, damit ALLE Beschriftungen auf derselben Kante
   beginnen — auch wenn ein Symbol schmaler zeichnet als das andere. */
.vi-menu__ic {
  flex: 0 0 16px; width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--gray-500);
}
.vi-menu__ic svg { display: block; }
.vi-menu__i:hover .vi-menu__ic { color: var(--gray-700); }
.vi-menu__i--danger .vi-menu__ic { color: var(--color-danger-ink); }
.vi-menu__l { flex: 1 1 auto; min-width: 0; text-align: left; }
/* Haken steht rechts — vorne sitzt das Funktionssymbol. */
.vi-menu__ck { flex: 0 0 auto; display: inline-flex; margin-left: var(--space-3); color: var(--color-primary, var(--gray-700)); }
.vi-menu__ck svg { display: block; }
.vi-menu__sep { height: 1px; margin: var(--space-1) var(--space-2); background: var(--ui-line); }
.vi-menu__h {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-size: var(--ui-text-label); font-weight: var(--fw-semibold);
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--gray-500);
}

/* ───────────────────────────────────────────────────────────────────────────────
   11 · PROZESSKETTE — Anlage → Pflicht → Termin → Durchführung → Nachweis
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-chain { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }
.vi-chain__s {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px var(--space-2);
  border-radius: var(--vi-r-pill);
  font-size: var(--ui-text-label); font-weight: var(--fw-medium);
  background: var(--gray-100); color: var(--gray-500);
  white-space: nowrap;
}
.vi-chain__s.is-done    { background: var(--color-success-soft); color: var(--color-success-ink); }
.vi-chain__s.is-current { background: var(--color-forest); color: var(--text-inverse); font-weight: var(--fw-semibold); }
.vi-chain__s.is-blocked { background: var(--color-danger-soft); color: var(--color-danger-ink); }
.vi-chain__sep { color: var(--gray-300); font-size: var(--ui-text-label); }
/* Leitdaten als dichte Definitionsliste — keine großen leeren Kacheln. */
.vi-facts { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-5); }
.vi-fact { display: flex; align-items: baseline; gap: var(--space-2); min-width: 0; font-size: var(--ui-text-meta); }
.vi-fact__k { color: var(--gray-500); white-space: nowrap; }
.vi-fact__v { color: var(--gray-900); font-weight: var(--fw-medium); min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ───────────────────────────────────────────────────────────────────────────────
   13 · AKTENREITER — bewusst NICHT hier.
   Reiter einer Akte benutzen das kanonische Tab-System (.vi-tabs/.vi-tab mit Ink-
   Unterstrich, ui-standard.css §3 + vi-tabs-ink.js). Ein zweites Tab-Design wäre
   genau die Doppelung, die dieser Umbau beseitigt. Ergänzt wird dort nur die
   Zählmarke .vi-tab__badge--crit für offene Mängel.
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-tab__badge--crit { background: var(--color-danger-soft); color: var(--color-danger-ink); }

/* ───────────────────────────────────────────────────────────────────────────────
   15 · LADE- UND FEHLERZUSTAND
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-skel { display: flex; flex-direction: column; gap: var(--space-2); }
.vi-skel__row {
  height: var(--ui-row-h);
  border-radius: var(--ui-radius);
  background: linear-gradient(90deg, var(--gray-100) 25%, var(--ui-surface) 50%, var(--gray-100) 75%);
  background-size: 400% 100%;
  animation: vi-skel-shine 1.4s ease-in-out infinite;
}
@keyframes vi-skel-shine { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .vi-skel__row { animation: none; } }

.vi-error {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-danger);
  border-radius: var(--ui-radius);
  background: var(--color-danger-soft);
  color: var(--color-danger-ink);
  font-size: var(--ui-text-body);
}
.vi-error__a { margin-left: auto; }

/* ───────────────────────────────────────────────────────────────────────────────
   16 · NUR-SCREENREADER
   ─────────────────────────────────────────────────────────────────────────────── */
.vi-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ───────────────────────────────────────────────────────────────────────────────
   17 · RESPONSIVE STUFEN
   Gemessen wird die INHALTSBREITE, nicht die Fensterbreite — die Seitenleiste
   belegt 272 px, dieselbe Seite ist auf 1366 und 1920 px unterschiedlich breit.
   ─────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .vi-pagehead { align-items: flex-start; }
}
@media (max-width: 900px) {
  .vi-pagehead__l { width: 100%; }
  .vi-pagehead__r { width: 100%; }
  .vi-pagehead__r > .btn, .vi-pagehead__r > .vi-tool { flex: 1 1 auto; justify-content: center; }
  .vi-listhead { align-items: flex-start; }
}
@media (max-width: 620px) {
  /* Die Metrikleiste bleibt AUCH schmal ein zusammenhängendes Segment und scrollt in
     sich — als Zweispalten-Raster zerfiel sie wieder in einzelne Kacheln. */
  .vi-empty { flex-direction: column; align-items: flex-start; }
  .vi-empty__a { width: 100%; }
}

/* ───────────────────────────────────────────────────────────────────────────────
   18 · DRUCK
   ─────────────────────────────────────────────────────────────────────────────── */
@media print {
  .vi-metricbar, .vi-listhead__r, .vi-seg { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   MOBILER NUTZUNGSKONTEXT — die Seitenbausteine verdichten (UI-Welle §42/§48)
   ───────────────────────────────────────────────────────────────────────────────
   Auf dem Telefon stapelten sich Modulreiter, Ansichtsumschalter, Seitenkopf,
   Kennzahlen und Filterleiste zu rund 490 px, bevor die erste Zeile begann — bei
   844 px Bildhöhe blieb für die eigentliche Arbeit weniger als die Hälfte.
   Die Bausteine bleiben dieselben (kein zweiter Seitenaufbau, keine Parallelwelt),
   sie treten nur zurück: kleinerer Titel, einzeilige Kopfzeile, engere Abstände.
   Ausdruck zeichengleich mit mobile.js/mobile.css — Telefon quer bleibt Telefon.
   ═══════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 767px), (max-height: 540px) and (pointer: coarse) {
  .vi-page { gap: var(--space-2); }

  /* Kopfzeile einzeilig halten: Titel schrumpft, die Primäraktion bleibt daneben. */
  .vi-pagehead { gap: var(--space-2); flex-wrap: nowrap; align-items: center; min-height: 0; }
  .vi-pagehead__l { flex: 1 1 auto; min-width: 0; }
  .vi-pagehead__r { flex: 0 0 auto; }
  .vi-pagetitle { font-size: var(--text-lg); }
  /* Beschriftung der Primäraktion darf kürzen, das Ziel bleibt fingergroß. */
  .vi-pagehead__r .btn-primary,
  .vi-pagehead__r .btn { min-height: var(--control-h-lg); padding-inline: var(--space-3); }

  /* Ergebniszeile: Zahl links, Werkzeuge rechts — beides einzeilig und scrollbar,
     statt in drei Zeilen umzubrechen. */
  .vi-listhead { flex-wrap: nowrap; gap: var(--space-2); }
  .vi-listhead__r { flex: 0 1 auto; overflow-x: auto; scrollbar-width: none; }
  .vi-listhead__r::-webkit-scrollbar { display: none; }
  .vi-listhead__l { flex: 0 0 auto; }
  .vi-tool { min-height: 40px; }        /* Touch-Ziel (§47) */

  /* Kennzahlen: waagerecht durchblätterbar statt umbrechend. */
  .vi-metricbar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .vi-metricbar::-webkit-scrollbar { display: none; }
  .vi-metric { flex: 0 0 auto; min-height: 40px; }
}

/* Mobil trägt die Ergebniszeile ohnehin nur Zahl und Werkzeuge — der zusätzliche
   Abstand darüber kostete auf schmalen Geräten eine Zeile Inhalt. */
@media (max-width: 767px), (max-height: 540px) and (pointer: coarse) {
  .vi-page > .vi-listhead { margin-top: 0; }
  .vi-listhead { padding-block: 0; }
}

/* Ergebniszeile SCHMAL: Zahl über den Werkzeugen statt in drei umgebrochenen Reihen
   (gemessen 136 px). Bewusst NUR an die Breite gebunden — das quer gehaltene Telefon
   ist 844 px breit und hat Platz für EINE Zeile; gestapelt kostete die Zeile dort
   24 px der knappen 390-px-Bildhöhe. */
@media (max-width: 767px) {
  .vi-listhead { flex-direction: column; align-items: stretch; gap: var(--space-1); }
  .vi-listhead__l { justify-content: flex-start; }
  .vi-listhead__r { justify-content: flex-start; flex-wrap: nowrap; }
}
