/* =========================================================
   MALERPLUS • DOCK — GLAS & BEWEGUNG
   ---------------------------------------------------------
   Marcel (31.07.2026): „Die Dockleiste darf nicht wie eine
   gewöhnliche Navigationsleiste aussehen. Sie soll sich wie
   ein echtes Betriebssystem anfühlen."

   Diese Datei liegt ALS LETZTE über dem gewachsenen Dock-CSS
   (mp-dock-nav.css, 67 KB). Sie baut nichts um, sondern legt
   eine Gestaltungsebene darüber — umkehrbar durch Entfernen
   einer Zeile in index.html.

   AUSGANGSLAGE (gemessen, nicht geraten):
     nav.bottom-nav::before trägt bereits Glas —
     blur(28px) saturate(1.5), Grundton rgba(148,163,184,.2),
     Radius 26px, Schatten 0 10px 34px rgba(15,23,42,.18).
     Das Blur war also da; es wirkte flach, weil der Grundton
     grau statt weiß ist, der Schatten einlagig bleibt und
     jede Lichtführung fehlt.

   WAS SICH ÄNDERT
   1. Glas: weißlicher Grundton statt Grau, zweistufiger
      Lichtverlauf (oben hell → unten neutral), dazu ein
      Innenlicht an der Oberkante.
   2. Schatten: drei Lagen statt einer — Kontaktschatten,
      mittlere Streuung, weiter Abwurf. So entsteht Höhe,
      ohne dass es schwer wird.
   3. Symbole: Federbewegung beim Überfahren und Drücken,
      Aktiv-Zustand mit eigenem Indikator.

   PHYSIK STATT LINEAR
   Alle Bewegungen laufen über zwei Kurven:
     --dock-spring  — Überschwingen, für Hover/Aktiv
     --dock-ease    — sattes Ausklingen, für Flächen
   Beides sind Annäherungen an Federn; echte Spring-Physik
   bräuchte JS pro Frame und wäre die Bildrate nicht wert.

   BILDRATE
   Ausschließlich transform, opacity, filter, box-shadow.
   Kein width/height/top/left in Übergängen → keine Layout-
   Sprünge. `will-change` steht nur dort, wo wirklich bewegt
   wird, und wird nicht pauschal gesetzt (sonst hält der
   Browser für jedes Symbol dauerhaft eine Ebene vor).
   ========================================================= */

:root {
  --dock-spring: cubic-bezier(.34, 1.56, .64, 1);   /* federt über */
  --dock-ease:   cubic-bezier(.16, 1, .3, 1);       /* klingt aus */
  --dock-hover:  200ms;                              /* 180–220ms */
  --dock-open:   280ms;                              /* 250–320ms */
}


/* ── 1. DIE GLASFLÄCHE ────────────────────────────────────
   Ein Element, drei Lagen: Grundglas (::before), Lichtkante
   und Innenschein. Radius 30px — in der Mitte der gewünschten
   Spanne 28–34px, passend zur Dock-Höhe von 75px. */

html body nav.bottom-nav {
  border-radius: 30px !important;
  /* Der Rahmen kommt als Schatten, nicht als border: eine echte
     Kontur würde bei Blur eine harte Kante erzeugen. */
  box-shadow: none !important;
}

html body nav.bottom-nav::before {
  border-radius: 30px !important;

  /* Weißliches Glas statt Grau. Der Verlauf ist der Unterschied
     zwischen „Fläche mit Blur" und „Glas": oben fängt es Licht,
     unten wird es neutral. */
  background:
    linear-gradient(
      180deg,
      rgba(var(--mp-flaeche-rgb), .74) 0%,
      rgba(var(--mp-flaeche-rgb), .58) 46%,
      rgba(var(--mp-f2-f7f9fc), .60) 100%
    ) !important;

  -webkit-backdrop-filter: blur(30px) saturate(180%) !important;
  backdrop-filter: blur(30px) saturate(180%) !important;

  /* Drei Schattenlagen + zwei Innenlichter:
     1) Kontakt — hält das Dock am Boden
     2) Streuung — die eigentliche Höhe
     3) Abwurf — weiche Verankerung im Raum
     4) Innenlicht oben — die Glaskante
     5) Innenschatten unten — Materialstärke */
  box-shadow:
    0 1px 2px rgba(15, 23, 42, .06),
    0 8px 24px -6px rgba(15, 23, 42, .12),
    0 28px 64px -16px rgba(15, 23, 42, .20),
    inset 0 1px 0 rgba(255, 255, 255, .90),
    inset 0 -1px 0 rgba(15, 23, 42, .05) !important;

  /* Feine Kontur, die das Glas vom Hintergrund trennt, ohne
     als Linie zu lesen. */
  border: .5px solid rgba(255, 255, 255, .65) !important;
}

/* Lichtreflex, der über die Oberkante läuft — das Detail, das
   Glas von Milchglas unterscheidet. Bewusst statisch: eine
   Dauer-Animation auf einer 550px-Fläche kostet Bildrate. */
html body nav.bottom-nav::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 42%;
  border-radius: 30px 30px 0 0;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, .40) 0%,
    rgba(255, 255, 255, 0) 100%
  );
  pointer-events: none;
  z-index: 0;
}


/* ── 2. SYMBOLE: RUHE, DANN REAKTION ──────────────────────
   Unberührt sind sie still. Erst die Hand bringt Bewegung —
   das ist der Unterschied zwischen „lebendig" und „unruhig". */

html body nav.bottom-nav .nav-btn,
html body nav.bottom-nav .mp-dsm-start {
  position: relative;
  border-radius: 15px !important;
  transition:
    transform var(--dock-hover) var(--dock-spring),
    filter var(--dock-hover) var(--dock-ease) !important;
  transform-origin: 50% 85%;   /* Drehpunkt unten: wirkt wie angehoben */
}

/* Überfahren: anheben, minimal drehen, Licht darunter.
   1,5° — genug, dass es lebt; wenig genug, dass es niemand
   als Kippen wahrnimmt.

   ⚠ KORREKTUR 31.07.2026 — Marcel: „der Button den ich auswählen
   will soll hervorgehoben werden, aber irgendwie sind das immer
   nur die daneben."

   Ursache war diese Datei. In mp-dock-nav.css (~Z.125-147) steht
       html body nav.bottom-nav .nav-btn.dash-launch-tile:hover
       { transform: none !important; }
   — VIER Klassen. Mein Hover-Selektor hatte nur drei
   (.bottom-nav .nav-btn :hover) und verlor deshalb. Der
   Nachbar-Selektor kam durch das zusätzliche `+ .nav-btn` auf
   vier und GEWANN. Ergebnis: Der anvisierte Knopf blieb stehen,
   der daneben bewegte sich. Genau das war zu sehen.

   Zwei Konsequenzen:
   1. `.dash-launch-tile` gehört in den Selektor — damit gleiche
      Klassenzahl, und weil diese Datei später lädt, gewinnt sie.
   2. Der Nachbar-Effekt ist RAUS. Er war ein Zierstück, hat aber
      den Blick vom gemeinten Knopf weggezogen. Bei einer Leiste,
      in der man zielt, ist Eindeutigkeit mehr wert als Spielerei. */
@media (hover: hover) and (pointer: fine) {
  html body nav.bottom-nav .nav-btn:hover,
  html body nav.bottom-nav .nav-btn.dash-launch-tile:hover,
  html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile:hover,
  html body nav.bottom-nav .mp-dsm-start:hover {
    transform: translate3d(0, -6px, 0) !important;
    filter: none !important;
    z-index: 35 !important;
    will-change: transform;
    -webkit-font-smoothing: antialiased;
    backface-visibility: hidden;
  }
  html body nav.bottom-nav .nav-btn:hover .dash-launch-tile-icon,
  html body nav.bottom-nav .mp-dsm-start:hover .mp-dsm-start-logo {
    box-shadow: 0 10px 24px -4px rgba(15, 23, 42, .24), 0 0 16px rgba(43, 176, 255, .32) !important;
    will-change: transform;
    backface-visibility: hidden;
    -webkit-font-smoothing: antialiased;
  }
}

/* Drücken: kurz einsinken, dann federn.
   Kürzer als der Hover, damit es sofort quittiert.
   `.dash-launch-tile` aus demselben Grund wie oben — die Altregel
   sperrt transform auch für :active und .active. */
html body nav.bottom-nav .nav-btn:active,
html body nav.bottom-nav .nav-btn.dash-launch-tile:active,
html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile:active,
html body nav.bottom-nav .mp-dsm-start:active {
  transform: translate3d(0, -1px, 0) scale(.93) !important;
  transition-duration: 110ms !important;
}


/* ── 3. AKTIVES MODUL ─────────────────────────────────────
   Kein Rahmen, kein Farbklecks: eine schwebende Lichtfläche
   dahinter und ein Punkt darunter. */

/* ⚠ Marcel 31.07., zum ZWEITEN Mal: „man kann kaum den aktiven
   erkennen, wenn man den angewählt hat."

   Erst die Messung im Browser hat es erklärt — mein erster Anlauf
   hatte die falsche Ursache vermutet (Spezifität). In Wahrheit
   streiten sich ZWEI Dateien um dieselben zwei Pseudoelemente,
   mit vertauschter Bedeutung:

     mp-dock-nav.css  ::before = der 5px-Punkt (Z.285)
                      ::after  = display:none  (Z.252)
     diese Datei      ::before = Lichtfläche
                      ::after  = der Punkt

   Folge, im Browser gemessen:
     ::before → 5x5 px statt der Fläche. Ich setze nur `inset`;
                die Altregel setzt `width/height: 5px`, und bei
                absoluter Position schlägt eine gesetzte Breite
                die aus left/right berechnete. Ohne `width:auto`
                war meine Fläche ein Fleck.
     ::after  → opacity 0 / display none. Die Altregel blendet es
                hart aus; !important allein half nicht, weil ich
                `display` nie zurückgesetzt habe.

   Deshalb jetzt: Größe und display EXPLIZIT zurückdrehen. Und der
   Zustand wird kräftiger — ein Indikator, den man suchen muss,
   ist keiner. */

/* 1 — KEIN Sockel hinter der Kachel.
   Marcel 31.07.: „Auf meinem Handy habe ich ja auch keinen
   Glashintergrund mit den App-Icons. Vielleicht sollten wir das
   so machen, dass wir gar keinen Button, also Hintergrund haben."

   Er hat recht, und es ist derselbe Gedanke wie bei iOS: Dort
   liegen die App-Symbole frei auf dem Dockglas, der aktive wird
   allein durch den Punkt darunter markiert. Hier SIND die bunten
   Kacheln bereits die Symbole — eine graue Fläche dahinter wäre
   ein zweiter Knopf um einen Knopf.

   Der erste Anlauf hatte genau diesen Sockel. Er ist wieder
   raus; die Erkennbarkeit trägt jetzt der Balken (2) plus das
   Zurücktreten der anderen (4). Das ::before wird dabei aktiv
   stillgelegt, sonst käme der 5px-Punkt aus mp-dock-nav.css
   Z.285 wieder durch und stünde neben dem Balken. */
html body nav.bottom-nav .nav-btn.active::before,
html body nav.bottom-nav .nav-btn.is-active::before,
html body nav.bottom-nav .nav-btn[aria-current="page"]::before,
html body nav.bottom-nav .nav-btn.dash-launch-tile.active::before,
html body nav.bottom-nav .nav-btn.dash-launch-tile.is-active::before,
html body nav.bottom-nav .nav-btn.dash-launch-tile[aria-current="page"]::before,
html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile.active::before {
  display: none !important;
}

/* 2 — Der Indikator: ein weißer Balken AUF der Kachel.
   Marcel 31.07.: „Der Strich für aktiv müsste eigentlich weiß sein,
   denn sieht man besser in den Icons."

   Er hat recht, und der Grund ist handfest: Unter der Kachel steht
   der Balken auf hellem Grund und muss dagegen ankämpfen. Auf der
   Kachel liegt er auf einer kräftigen Modulfarbe — und Weiß trägt
   dort gegen jede der zwölf, ohne dass man pro Modul nachjustiert.

   Position gemessen, nicht geschätzt: Die Kachel ist 52×52 und
   endet 7px über der Knopfunterkante. bottom:13px setzt den Balken
   damit 6px innerhalb der Kachelkante.

   ⚠ Warum am Knopf und nicht am Symbol: Lucide ersetzt das
   Icon-DIV durch ein <svg> (geprüft: tagName === "svg"). SVG-
   Elemente tragen keine Pseudoelemente — ein ::after am Symbol
   wäre nie erschienen. */
/* ⚠ Marcel 31.07.: „Der Markierstrich ist erst immer unten, klick
   ich einmal, dann geht er nach oben."

   Es gibt eine DRITTE Regel — mp-bottom-nav-premium.css Z.196-212
   setzt ebenfalls einen weißen Strich, aber bei `bottom: -1px`,
   also unter der Kachel. Sie zielt unter anderem auf
   `[aria-current="page"]`; meine Regeln kannten nur `.active`.

   Beim Laden trägt der aktive Knopf offenbar zuerst nur das
   Attribut — dann gilt allein die Premium-Regel und der Strich
   steht unten. Erst der Klick setzt `.active` dazu, meine Regel
   greift, und der Strich springt hoch. Genau das war zu sehen.

   Deshalb steht `[aria-current="page"]` jetzt in beiden Listen.
   Wer hier weitere Aktiv-Zustände ergänzt, muss daran denken:
   In dieser App markieren DREI Dateien den aktiven Knopf. */
/* ⚠ VIERTE Regel gefunden: mp-dock-nav.css Z.501-505 blendet
   ::after ebenfalls aus — und zwar auch für [aria-current="page"],
   mit derselben Spezifität (0,4,3) wie mein erster Versuch. Bei
   Gleichstand entscheidet die Ladereihenfolge, weshalb der Strich
   je nach Zustand mal kam und mal nicht.

   Alle Selektoren tragen deshalb jetzt `.nav-launch-tile` und
   liegen bei (0,5,3) — damit gewinnen sie gegen alle vier Dateien
   unabhängig von der Reihenfolge. Zusätzlich `top: auto`: Sollte
   irgendeine der Regeln ein top setzen, schlüge es sonst mein
   bottom, und der Strich säße oben statt unten. */
html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile.active::after,
html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile.is-active::after,
html body nav.bottom-nav .nav-btn.dash-launch-tile.nav-launch-tile[aria-current="page"]::after,
html body nav.bottom-nav .nav-btn.dash-launch-tile.active::after,
html body nav.bottom-nav .nav-btn.dash-launch-tile.is-active::after,
html body nav.bottom-nav .nav-btn.dash-launch-tile[aria-current="page"]::after {
  content: "" !important;
  /* ⚠ Pflicht: mp-dock-nav.css Z.252 setzt display:none !important. */
  display: block !important;
  position: absolute !important;
  /* ⚠⚠ DIE EIGENTLICHE URSACHE — Marcel dreimal: „der Strich ist
     immer noch oben", „zu Beginn der App unten, nach einem Klick oben."

     mp-micro-animations.css Z.40 setzt auf `.tile-interactive::after`
     ein `inset: 0` (ein Touch-Highlight). `inset` setzt top MIT.
     Meine Regel setzte bottom und height — aber nie top. Damit ist
     die Box ÜBERBESTIMMT, und die CSS-Spezifikation verwirft in
     diesem Fall bei direction:ltr das `bottom`. Übrig bleiben
     top:0 + height:3px → der Strich klebt oben.

     Der Zeitpunkt passt exakt: `tile-interactive` kommt ERST BEIM
     KLICK an den Knopf. Vorher gilt mein bottom (unten), danach
     das geerbte top:0 (oben) — genau die beobachtete Reihenfolge.

     `top:auto` und `right:auto` sind deshalb PFLICHT, nicht Kosmetik:
     Sie machen die Box wieder eindeutig. (In der Runde davor stand
     top:auto nur im Kommentar und fehlte im Code — deshalb blieb
     der Fehler.) */
  top: auto !important;
  right: auto !important;
  left: 50% !important;
  bottom: 9px !important;
  width: 18px !important;
  height: 3px !important;
  margin-left: -9px !important;
  border-radius: 2px !important;
  background: rgb(var(--mp-flaeche-rgb)) !important;
  /* Der Schatten ist kein Zierrat: Auf den hellen Modulfarben
     (Gelb, Hellblau) verschwände reines Weiß sonst. */
  box-shadow: 0 1px 3px rgba(15, 23, 42, .35) !important;
  opacity: 1 !important;
  transform: none !important;
  z-index: 3 !important;
  pointer-events: none;
  animation: mp-dock-punkt var(--dock-open) var(--dock-spring) both;
}

/* 3 — Das Symbol selbst: einen Hauch größer, volle Deckkraft.
   Damit ist der Zustand auch lesbar, wenn jemand den Balken
   übersieht — und ohne Anheben, das nur wieder an den oberen
   Rand stoßen würde.

   ⚠ NACHBESSERUNG MP-20260901-018, Punkt ② (01.09., Jonas Falk, echt
   gemessen mit `getBoundingClientRect()`, nicht vermutet): Genau DIESE
   Kachel — die AKTIVE, also die des gerade offenen Moduls, dauerhaft
   sichtbar — landete mit `scale(1.08)` auf Sub-Pixel-Werten (bei der
   48px-Desktop-Basisgröße: 51,84px statt 52px, Position um
   0,08-0,16px verschoben). Ein nicht-ganzzahliges Ergebnis zwingt den
   Renderer zum Kanten-Antialiasing über Pixelgrenzen hinweg — exakt
   das, was als „irgendwie unscharf" auffällt, und zwar dauerhaft am
   Dock-Icon des aktuell offenen Moduls.
   Erster Versuch `1.083333` (= 52/48) war NUR für die 48px-Basisgröße
   (Desktop 1280/Tablet 1024, beide bestätigt) exakt — bei 810px nutzt
   das Dock eine ANDERE, kleinere Kachel-Basisgröße (gemessen: 40px,
   eigener responsiver Breakpoint), bei der 1.083333 wieder auf
   Sub-Pixel landet (43,33px statt 43px). `1.125` (= 9/8) trifft BEIDE
   gemessenen Basisgrößen exakt ganzzahlig (48×1.125=54, 40×1.125=45)
   und bleibt mit „12,5 % statt 8 % größer" weiterhin im Rahmen von
   „ein Hauch größer" (die beiden Werte sind auf einer 40-54px-Kachel
   visuell kaum unterscheidbar). Nur diese EINE Dock-Regel geändert —
   `.mp-pti-ic`/`.mp-pbm-ic` in mp-icon-system.css haben andere
   Basisgrößen und je eigene Skalierungslogik, dort NICHT angefasst.
   Nicht getestete weitere Breakpoints/Basisgrößen bleiben ein
   Restrisiko (siehe Handoff). */
html body nav.bottom-nav .nav-btn.dash-launch-tile.active .dash-launch-tile-icon,
html body nav.bottom-nav .nav-btn.dash-launch-tile.is-active .dash-launch-tile-icon {
  transform: scale(1.125) !important;
  opacity: 1 !important;
  filter: saturate(1.1) !important;
}

/* 4 — Die INAKTIVEN treten zurück. Das ist der stärkste Hebel:
   Sechs gleich kräftige Farbkacheln nebeneinander haben keine
   Rangordnung — erst wenn die anderen ruhiger werden, sticht der
   aktive hervor. Bewusst dezent (92 %), damit das Dock bunt bleibt. */
html body nav.bottom-nav .nav-btn.dash-launch-tile:not(.active):not(.is-active):not(.mp-dtb-ki) .dash-launch-tile-icon {
  opacity: .82;
  filter: saturate(.88);
  transition: opacity var(--dock-hover, 220ms) ease,
              filter var(--dock-hover, 220ms) ease;
}
html body nav.bottom-nav .nav-btn.dash-launch-tile:not(.active):hover .dash-launch-tile-icon {
  opacity: 1;
  filter: none;
}

@keyframes mp-dock-aktiv {
  from { opacity: 0; transform: scale(.86); }
  to   { opacity: 1; transform: none; }
}
@keyframes mp-dock-punkt {
  from { opacity: 0; transform: scaleX(.3); }
  to   { opacity: 1; transform: none; }
}

/* ⚠ Marcel 31.07.: „wenn man da drüber geht und der hebt so ab,
   dann wirkt der auch ein bisschen abgeschnitten am oberen Rand."

   Ursache gemessen: nav.bottom-nav steht auf `overflow: auto hidden`.
   Der Hover hebt den Knopf per translateY heraus — und overflow-y
   schneidet ihn oben ab. overflow-y:visible allein hilft nicht: Ist
   die andere Achse nicht `visible`, macht der Browser daraus wieder
   `auto`. Es müssen also BEIDE Achsen frei sein.

   ⚠ Diese Regel steht hier NUR noch als Spur. Sie wirkt nicht,
   und das ist gemessen, nicht vermutet:
     - die Regel wird geparst (im CSSOM gefunden)
     - die Media-Bedingung trifft zu (hover:hover → true)
     - trotzdem bleibt computed „auto hidden"
     - ein Inline-`!important` auf demselben Element wirkt sofort
   Es gewinnt also etwas, das ich über das CSSOM nicht zu fassen
   bekomme — vermutlich setzt eine Regel overflow-x auf auto, und
   Chrome rechnet meine freie Y-Achse daraufhin selbst wieder zu.
   Statt weiter dagegen zu stylen macht es mp-dock-glas.js inline,
   und zwar NUR, wenn das Dock tatsächlich nicht scrollt. */
@media (hover: hover) and (pointer: fine) {
  html body nav.bottom-nav {
    overflow: visible !important;
  }
}

/* ⚠ MP-20260901-014 (Marcel-Screenshot, 01.09.): „Beim Hover wirkt die
   Kachel oben abgeschnitten." Ursache diesmal NICHT dieselbe wie oben:
   `mp-ui-final-hardwall.css` laedt nach dieser Datei UND nach
   mp-dock-nav.css, hat mit `html body nav.bottom-nav:not(.hidden-nav)`
   die hoehere Spezifitaet und setzt `overflow-y:hidden !important` fest
   — das ueberstimmt sowohl das `overflow:visible` oben als auch den
   Inline-Fallback aus mp-dock-glas.js (core/mp-dock-glas.js:132-138).
   Gegen diese Regel weiter mit overflow zu arbeiten ist aussichtslos:
   overflow-y alleine auf `visible` zu setzen, waehrend overflow-x
   scrollbar bleibt, rechnet der Browser laut Spezifikation ohnehin
   wieder zu `auto` zurueck (das war schon die Erkenntnis von 31.07.,
   siehe Kommentar oben — „es muessen beide Achsen frei sein", und beide
   frei heisst: kein horizontales Scrollen mehr moeglich, das brauchen
   schmale Fenster mit vielen Kacheln aber).
   Deshalb hier NICHT an overflow schrauben, sondern Kopfpolster geben,
   das den gehobenen+skalierten Zustand (translate -6px, scale 1.09,
   Ursprung 50% 85%) vollstaendig traegt, ohne dass er die Padding-Box
   je verlaesst — das wirkt unabhaengig davon, welche overflow-Regel am
   Ende gewinnt. Nur oben, nur bei Maus/Trackpad (hover:hover,
   pointer:fine); Touch-Geraete bleiben unveraendert. Weil nur
   padding-top erhoeht wird (die Leiste haengt an `bottom`, siehe
   mp-ui-final-hardwall.css:1254), wandert die sichtbare Unterkante der
   Leiste NICHT — es waechst nur unsichtbarer Luftraum oben dazu.

   ⚠ NACHMESSUNG MP-20260901-018 (01.09., Jonas Falk): Marcel meldete den
   Clip weiterhin — "in allen Modulen ausser dem Aufmass". Echte
   Chromium-Messung (echte Maus, `nav.bottom-nav`-Oberkante vs. gehoberte
   Kachel-Oberkante, 5+21 Zeitstempel ueber die volle 200ms-Transition,
   8 Modul-Body-Klassen × 6 Kacheln × 3 Breiten, Wache
   `tools/test-dock-hover-clip-across-modules-p0.js`) zeigt: 18px reichte
   NICHT — Rest-Clip von ~2.9px im GERUHTEN Hover-Zustand (nicht nur ein
   Feder-Ueberschwinger) plus bis zu ~4.2px Spitze waehrend des
   Uebersteuerns der `--dock-spring`-Kurve (cubic-bezier(.34,1.56,.64,1),
   die den Zielwert kurz ueberschiesst). UND: dieser Rest-Clip besteht
   GENAUSO im Aufmass — die Messung fand KEINEN modulspezifischen
   Unterschied (Aufmass clippte in derselben Groessenordnung wie jedes
   andere Modul). Der sichtbare Unterschied ist daher keine andere
   Geometrie, sondern dass die Aufmass-eigene Ruhe-Regel
   (mp-baustellen-golden-v2.css, "WORKSPACE 50", `box-shadow:none`,
   `filter:none`, `animation:none` auf `nav.bottom-nav`/Kacheln im
   Aufmass) den Hover-Leuchtschein (drop-shadow-Filter aus Abschnitt 2
   oben) unterdrueckt — es gibt dort keinen weichen Schein, der an der
   Container-Kante hart gekappt werden koennte, waehrend er in jedem
   anderen Modul sichtbar bleibt und exakt an der `overflow-y:hidden`-
   Kante endet ("gerade Kante statt runder Kachel" bezieht sich auf den
   Schein, nicht auf die Kachel selbst — beide clippen geometrisch gleich
   viel). Fix: Kopfpolster auf 26px angehoben (2,9px Ruhe + 4,2px
   Ueberschwinger + Sicherheitsabstand, gerundet), gilt unveraendert fuer
   ALLE Module gleich (diese Regel war nie modulspezifisch) — keine
   Aenderung in mp-baustellen-golden-v2.css noetig, die Aufmass-Ruhe
   bleibt wie sie ist.

   ⚠ ZWEITER, TIEFERER BEFUND (per CSS.getMatchedStylesForNode
   nachgewiesen, nicht vermutet): Diese ganze Regel — mit der
   urspruenglichen 18px UND mit den 26px oben — hat NIE gewonnen. In
   `index.html` steht im fruehen "CRITICAL SPLASH CSS"-Inline-<style>
   (P0 31.08.2026, "Dock bereits in Frame 1 fertig") die Regel
   `html body nav.bottom-nav.bottom-nav{ padding:8px 12px!important; ... }`
   — der doppelte Klassen-Selektor `.bottom-nav.bottom-nav` zaehlt laut
   CSS-Spezifikation ZWEIMAL und schlaegt jeden Selektor ohne Klasse
   (wie den einfachen `html body nav.bottom-nav` hier), UNABHAENGIG von
   Ladereihenfolge oder Media-Query — Spezifitaet entscheidet vor
   Reihenfolge. Effektiv war `padding-top` auf JEDEM Geraet, mit und
   ohne Hover, durchgehend 8px — der komplette MP-20260901-014-Fix war
   seit seiner Einfuehrung wirkungslos (computed style gemessen: 8px,
   nicht 18px). Fix: derselbe Doppel-Klassen-Trick, damit diese Regel
   bei GLEICHER Spezifitaet gewinnt (spaeter im Dokument als das
   Inline-<style>-Fragment) — `index.html` selbst bleibt unangetastet,
   der Touch-Pfad (kein hover:hover) behaelt unveraendert 8px.

   ⚠ NACHBESSERUNG MP-20260901-018, zweite Runde (01.09., Jonas Falk):
   Marcel am ausgelieferten Stand: „oben ist so viel vom Glas" UND
   „sieht unsynchron aus" — die 26px waren NUR oben aufgesetzt, unten
   blieben die urspruenglichen 8px. Zwei echte Messungen dazu:
   1) `overflow:visible` (echtes Chromium, mit echtem `elementFromPoint`
      an der Kachel-Oberkante statt nur Geometrie) beseitigt den Clip
      TATSAECHLICH vollstaendig, auch waehrend das Feder-Ueberschwingen
      lokal ueber die Box hinausragt — die Kachel bleibt an jedem
      Zeitpunkt echt treffbar/sichtbar. Die alte "beide Achsen muessen
      frei sein"-Sperre (Kommentar oben, 31.07.) ist damit fuer den
      MALZUSTAND weiter richtig (overflow-x:auto + overflow-y:visible
      kollabiert laut Spezifikation zu overflow:auto), aber sie bedeutet
      NICHT, dass eine Padding-Loesung die einzig moegliche ist.
   2) Der no-JS-Testrahmen (`mp-dock-startmenu.js` fehlt dort, siehe
      SHARED_LEARNINGS L-2026-09-01-X) zeigt bei nachgebauten Kachelmengen
      einen konstanten ~36px `scrollWidth`/`clientWidth`-Unterschied OHNE
      sichtbar ueberlaufenden Inhalt (letzte echte Kachel endet exakt
      an der Innenkante) — die reale, JS-getriebene Favoriten-Kuerzung
      (core/mp-dock-startmenu.js) sorgt im echten Boot dafuer, dass der
      Dock-Inhalt fast immer in die Box passt; ob `mp-dock-glas.js`s
      `freiraumOben()` das im no-JS-Rahmen zuverlaessig erkennt, laesst
      sich damit NICHT sauber nachstellen. Statt die Loesung an diese
      Fallunterscheidung zu haengen, deshalb ein Fix, der UNABHAENGIG
      vom Scroll-Zustand funktioniert:

   Symmetrisches Kopfpolster oben UND unten (`padding: 15px 12px`, statt
   nur `padding-top`) statt einseitig. 15px deckt den gemessenen Bedarf
   (8px Basis + 2,9px Ruhe-Clip + 4,2px Ueberschwing-Spitze = 12,3px als
   ZIEL-Gesamthoehe von der Box-Oberkante) mit ~2,7px Puffer — deutlich
   schlanker als die vorherigen 26px (nur +7px gegenueber der
   Basis-8px, statt +18px), UND symmetrisch: derselbe Wert oben wie
   unten haelt die Kachelreihe optisch mittig im Glas, exakt wie vor
   MP-014/-018, nur mit minimal mehr Luft auf BEIDEN Seiten. Kein
   `overflow`- oder JS-Eingriff noetig — die Loesung wirkt unabhaengig
   davon, ob der Browser den Container gerade als scrollend einstuft.
   Verifiziert (`tools/test-dock-hover-clip-across-modules-p0.js`,
   erweitert um Symmetrie- und Headroom-Kriterien): 0px Clip UND
   |padding-top-effektiv − padding-bottom-effektiv| = 0px in allen
   Proben. */
@media (hover: hover) and (pointer: fine) {
  html body nav.bottom-nav.bottom-nav {
    padding: 15px 12px !important;
  }
}

/* ⚠ DRITTER ANLAUF — MP-20260910-058 (Marcel-Screenshot, 10.09.):
   „wenn ich diesen Hover-Effekt hab, wirkt dieses Icon abgeschnitten.
   Die muessen vom Z-Index her ueber dieser Glaskarte liegen."

   Marcels Diagnose trifft die Wahrnehmung, aber nicht die Mechanik:
   die Glasplatte ist `nav.bottom-nav::before` mit `z-index:-1` und
   liegt bereits HINTER den Kacheln (computed gemessen). Es verdeckt
   also nichts. Was kappt, ist `overflow` — und overflow ignoriert
   z-index vollstaendig. Ein z-index-Eingriff waere wirkungslos
   geblieben, so wie 2026-09-01 die Padding-Eingriffe.

   Was die beiden Vorlaeufer (-014, -018) uebersehen haben: sie haben
   die KACHEL vermessen, nicht den LEUCHTSCHEIN. Gemessen am echten
   Stand (Staging, Inhaber-Konto, Chrome, 1440x900, nach normalem
   Laden — nicht im Testrahmen):
     - Hover wirkt voll: scale(1.09) rotate(-1.5deg) translateY(-6px)
     - Leiste steht auf `overflow: auto hidden`; der Inline-Fallback
       aus core/mp-dock-glas.js greift NICHT, weil das Dock ueberlaeuft
       (scrollWidth 518 > clientWidth 482). Es wird also geclippt.
     - Clip-Kante y=807, Kachel in Ruhe top 822, gehoben top 811,8
       → nur 4,8px Luft.
     - Der Schein `drop-shadow(0 0 14px)` reicht bis y≈797,8, also
       9,2px UEBER die Clip-Kante. Dort endet er hart: gerade Kante
       statt weichem Auslauf. Genau das sieht Marcel.
   Die Wache tools/test-dock-hover-clip-across-modules-p0.js meldet
   dabei weiterhin 0px Clip — sie prueft die Kachelgeometrie und ist
   fuer den Schein blind. Ein Beleg, der den Schaden nicht sehen kann.

   ⚠ IM BROWSER WIDERLEGT, damit es niemand ein viertes Mal versucht:
   `overflow-y: clip` + `overflow-clip-margin: 24px` loest es NICHT.
   CSS.supports() ist true, die Eigenschaft wird gesetzt — aber bei
   `overflow-x: auto` kollabiert computed `overflow-y` von `clip` auf
   `hidden`, genau wie `visible` zu `auto` kollabiert (Erkenntnis vom
   31.07.). Gemessen, nicht aus der Spezifikation abgeleitet.

   LOESUNG: Clip-Box und sichtbare Glaskarte ENTKOPPELN. Die Leiste
   bekommt oben 30px unsichtbaren Luftraum dazu, und die Platte wird
   per `top` um denselben Betrag zurueckgenommen. Damit bleibt die
   Karte exakt so gross und exakt dort, wo sie heute ist (gemessen:
   Verschiebung 0,00px, Hoehe unveraendert 85px, Luft Kachel↔Karte
   unveraendert 15px oben wie unten — Marcels Einwand vom 01.09.
   „oben ist so viel vom Glas" bleibt damit erfuellt), waehrend die
   Clip-Kante von 15px auf 45px ueber die Kachel rueckt. Der Schein
   hat dann 20,8px Reserve statt 9,2px Ueberstand.
   Die Leiste haengt an `bottom` (mp-ui-final-hardwall.css:1254),
   deshalb waechst NUR padding-top — die Unterkante wandert nicht,
   `bottom` bleibt unangetastet.
   Nebenwirkung geprueft, nicht angenommen: `nav.bottom-nav` traegt
   `pointer-events: none` (die Kacheln setzen es selbst auf `auto`),
   der neue unsichtbare Streifen faengt also KEINE Klicks ab —
   12 Proben mit elementFromPoint ueber die volle Breite treffen
   durchgehend den Inhalt darunter, nie das Dock.
   Nur Maus/Trackpad, nur Bodenlage: der Touch-Pfad und die seitlichen
   Dock-Lagen (data-mp-dock-pos left/right) bleiben unveraendert. */
@media (hover: hover) and (pointer: fine) {
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav {
    padding: 45px 12px 15px !important;
  }
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav::before,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav::before,
  html:not(.mp-dock-stil-hell):not(.mp-dock-stil-dunkel) body nav.bottom-nav.bottom-nav::before,
  html.mp-dock-stil-hell body nav.bottom-nav.bottom-nav::before,
  html.mp-dock-stil-dunkel body nav.bottom-nav.bottom-nav::before {
    top: 30px !important;
    bottom: 0 !important;
  }
}


/* ── 4. DER KI-KNOPF ──────────────────────────────────────
   Das teuerste Element der Leiste — und deshalb das ruhigste.
   Kein Farbverlauf, keine Buntheit: ein langsamer Atem im
   Glow, sonst nichts. Vier Sekunden pro Zyklus liegt unter
   der Schwelle, ab der Bewegung nervös wirkt. */

html body nav.bottom-nav .mp-dock-ki,
html body nav.bottom-nav [data-dock-ki],
html body nav.bottom-nav .nav-btn.is-ki {
  position: relative;
}

html body nav.bottom-nav .mp-dock-ki::before,
html body nav.bottom-nav [data-dock-ki]::before,
html body nav.bottom-nav .nav-btn.is-ki::before {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 20px;
  background: radial-gradient(
    60% 60% at 50% 50%,
    rgba(43, 176, 255, .26) 0%,
    transparent 72%
  );
  z-index: -1;
  animation: mp-ki-atem 4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes mp-ki-atem {
  0%, 100% { opacity: .40; transform: scale(.94); }
  50%      { opacity: .92; transform: scale(1.04); }
}

/* Beim Aktivieren läuft einmal ein Lichtring herum. Die Klasse
   setzt mp-dock-glas.js und nimmt sie danach wieder ab. */
html body nav.bottom-nav .mp-ki-ring::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 20px;
  border: 2px solid transparent;
  border-top-color: var(--mp-blue, #2bb0ff);
  border-right-color: rgba(43, 176, 255, .55);
  animation: mp-ki-ring 820ms var(--dock-ease) 1;
  pointer-events: none;
}

@keyframes mp-ki-ring {
  from { transform: rotate(0deg);   opacity: 1; }
  to   { transform: rotate(360deg); opacity: 0; }
}


/* ── 5. AUFTRITT ──────────────────────────────────────────
   Beim Start steigt die Leiste einmal auf, die Symbole folgen
   versetzt. Läuft genau einmal — die Klasse nimmt das JS nach
   dem Lauf wieder ab, damit bei jedem Ansichtswechsel Ruhe ist. */

html body nav.bottom-nav.mp-dock-auftritt {
  animation: mp-dock-rein 460ms var(--dock-ease) both;
}

@keyframes mp-dock-rein {
  from { opacity: 0; transform: translate3d(-50%, 22px, 0) scale(.96); }
  to   { opacity: 1; }
}

html body nav.bottom-nav.mp-dock-auftritt .nav-btn,
html body nav.bottom-nav.mp-dock-auftritt .mp-dsm-start {
  animation: mp-dock-symbol 340ms var(--dock-spring) both;
  animation-delay: calc(120ms + var(--i, 0) * 34ms);
}

@keyframes mp-dock-symbol {
  from { opacity: 0; transform: translate3d(0, 12px, 0) scale(.82); }
  to   { opacity: 1; transform: none; }
}


/* ── 6. GEZOGEN WIRD MIT GEFÜHL ───────────────────────────
   ⚠ KORREKTUR 31.07.2026: Hier standen zuerst erfundene Klassen
   (.mp-dragging, .mp-drop-ziel). Die gibt es nirgends — der
   ganze Abschnitt war wirkungslos. Nachgesehen, wie es wirklich
   heißt:

     mp-dock-nav.js Z.127        nav.mp-dock-dragging
                                 → das DOCK wird verschoben
     mp-dock-startmenu.js Z.1157 .mp-dsm-ghost
                                 → Klon am body, folgt dem Finger
     mp-dock-startmenu.js Z.1163 .mp-dsm-dragging / .is-dragging
                                 → Sortieren im Startmenü

   Das Sortieren läuft also im Startmenü, nicht an der Leiste.
   Der Ghost bringt scale(1.05) rotate(1.6deg) bereits selbst mit
   (inline gesetzt) — hier kommt nur dazu, was ihm fehlt: Tiefe
   und ein Zielbild. */

/* Der Klon, der am Finger hängt */
html body .mp-dsm-ghost {
  filter: drop-shadow(0 18px 32px rgba(15, 23, 42, .28))
          drop-shadow(0 4px 8px rgba(15, 23, 42, .16));
  opacity: .95;
  cursor: grabbing;
  /* Kein transition: die Position setzt das JS pro Bewegung —
     ein Übergang würde den Klon dem Finger hinterherschleifen. */
}

/* Die Lücke, die zurückbleibt: eingesunken statt einfach weg,
   damit man sieht, wo das Symbol herkam. */
html body .mp-dsm-cell.is-dragging,
html body .is-dragging {
  opacity: .28;
  transform: scale(.92);
  transition: transform 200ms var(--dock-spring), opacity 160ms linear;
}

/* Während gezogen wird, weichen die übrigen Kacheln weich aus,
   statt zu springen. */
html body.mp-dsm-dragging .mp-dsm-cell:not(.is-dragging) {
  transition: transform 260ms var(--dock-spring) !important;
}

/* Das Dock selbst wird verschoben (mp-dock-nav.js): es folgt
   ohne Übergang, hebt aber sichtbar ab. */
html body nav.bottom-nav.mp-dock-dragging {
  transition: none !important;
  cursor: grabbing;
}
html body nav.bottom-nav.mp-dock-dragging::before {
  box-shadow:
    0 2px 6px rgba(15, 23, 42, .10),
    0 16px 40px -8px rgba(15, 23, 42, .20),
    0 40px 90px -20px rgba(15, 23, 42, .28),
    inset 0 1px 0 rgba(255, 255, 255, .90) !important;
}

/* MP-20260830-003 · RUHIGES DOCK
   Marcel moechte keinerlei Bump/Puls/Intro beim Ansichtswechsel. Das Dock
   darf seine feste Zentrierung behalten; nur Kacheln und Symbole bewegen
   sich nicht mehr. */
html body nav.bottom-nav .nav-btn,
html body nav.bottom-nav .nav-btn:hover,
html body nav.bottom-nav .nav-btn:active,
html body nav.bottom-nav .nav-btn.active,
html body nav.bottom-nav .nav-btn .dash-launch-tile-icon,
html body nav.bottom-nav .nav-btn:hover .dash-launch-tile-icon,
html body nav.bottom-nav .nav-btn:active .dash-launch-tile-icon,
html body nav.bottom-nav .nav-btn.active .dash-launch-tile-icon,
html body nav.bottom-nav .mp-dock-bounce,
html body nav.bottom-nav .mp-dock-aktivpuls,
html body nav.bottom-nav .mp-dock-tap {
  animation:none !important;
  transform:none !important;
}

html body nav.bottom-nav.mp-dock-auftritt,
html body nav.bottom-nav.mp-dock-auftritt .nav-btn,
html body nav.bottom-nav.mp-dock-auftritt .mp-dsm-start {
  animation:none !important;
}

/* Worker erhalten ein eigenes, immer vorhandenes Fünfer-Dock. Diese Regeln
   stehen nach der mobilen Owner-Regel, die sonst alle Nicht-Home-Kacheln
   ausblendet. Startmenue, Taskbereich und KI gehoeren hier bewusst nicht hin. */
html body.mp-role-worker nav.bottom-nav .nav-btn[data-nav="view-projekte"],
html body.mp-role-worker nav.bottom-nav .nav-btn[data-nav="view-meine-stunden"],
html body.mp-role-worker nav.bottom-nav .nav-btn[data-nav="view-worker-fotos"],
html body.mp-role-worker nav.bottom-nav .nav-btn[data-nav="view-baustellenchat"],
html body.mp-role-worker nav.bottom-nav .nav-btn[data-nav="view-workerstatus"],
html body.mp-role-foreman nav.bottom-nav .nav-btn[data-nav="view-projekte"],
html body.mp-role-foreman nav.bottom-nav .nav-btn[data-nav="view-meine-stunden"],
html body.mp-role-foreman nav.bottom-nav .nav-btn[data-nav="view-worker-fotos"],
html body.mp-role-foreman nav.bottom-nav .nav-btn[data-nav="view-baustellenchat"],
html body.mp-role-foreman nav.bottom-nav .nav-btn[data-nav="view-workerstatus"] {
  display:inline-flex !important;
  visibility:visible !important;
  opacity:1 !important;
}

html body.mp-role-worker nav.bottom-nav :is(.mp-dsm-start,.mp-dtb,.mp-dock-laser,#mpDockKi),
html body.mp-role-foreman nav.bottom-nav :is(.mp-dsm-start,.mp-dtb,.mp-dock-laser,#mpDockKi) {
  display:none !important;
}


/* ── 7. TABLET UND HANDY ──────────────────────────────────
   Gleiche Sprache, engere Maße. Auf Touch fällt Hover weg —
   dort trägt die Bewegung allein der Druck. */

@media (max-width: 1024px) {
  html body nav.bottom-nav,
  html body nav.bottom-nav::before { border-radius: 26px !important; }
  html body nav.bottom-nav::after  { border-radius: 26px 26px 0 0; }
}

@media (max-width: 768px) {
  html body nav.bottom-nav,
  html body nav.bottom-nav::before { border-radius: 22px !important; }
  html body nav.bottom-nav::after  { border-radius: 22px 22px 0 0; }
  html body nav.bottom-nav::before {
    /* Auf kleinen Geräten ist weniger Blur schneller und sieht
       bei kleiner Fläche ohnehin gleich aus. */
    -webkit-backdrop-filter: blur(22px) saturate(165%) !important;
    backdrop-filter: blur(22px) saturate(165%) !important;
  }
}


/* ── 8. RUHE BEWAHREN ─────────────────────────────────────
   Wer Bewegung abgeschaltet hat, bekommt das Glas — aber
   keinen Atem, keinen Auftritt, keine Federn. */

@media (prefers-reduced-motion: reduce) {
  html body nav.bottom-nav *,
  html body nav.bottom-nav::before,
  html body nav.bottom-nav::after {
    animation: none !important;
    transition: none !important;
  }
  html body nav.bottom-nav .nav-btn:hover {
    transform: scale(1.04) !important;
  }
}


/* =========================================================
   9. OHNE GLAS — nur die Symbole
   ---------------------------------------------------------
   Marcel 31.07.: „Ich meinte auch den Glashintergrund in
   dieser Leiste in der Navigation. Da kann der doch auch weg,
   dass wir nur die Icons haben."

   Damit fällt die Glasfläche aus Abschnitt 1 wieder weg —
   bewusst, und in EINER Regel, damit man es in einer Zeile
   zurückdrehen kann, statt die halbe Datei zu suchen.

   Der Gedanke dahinter ist derselbe wie beim iPhone-Homescreen:
   Die bunten Kacheln SIND schon die Symbole. Eine Glasleiste
   darum ist ein Rahmen um einen Rahmen.

   Was die Fläche allerdings mitgenommen hat, war der Kontrast:
   Auf dem Glas stand jedes Symbol sicher, jetzt liegt es direkt
   auf dem Seiteninhalt. Deshalb bekommen die Symbole hier einen
   eigenen weichen Schatten — sie sollen schweben, nicht kleben.
   ========================================================= */

html body nav.bottom-nav::before,
html body nav.bottom-nav::after {
  display: none !important;
}

html body nav.bottom-nav {
  background: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  box-shadow: none !important;
  border: 0 !important;
}

/* Ohne Glasgrund braucht jedes Symbol seinen eigenen Stand.
   Der Schatten ist zweistufig: eng und dunkel für die Kante,
   weit und weich für die Tiefe — sonst sieht es aus wie
   aufgeklebt. */
html body nav.bottom-nav .nav-btn .dash-launch-tile-icon {
  box-shadow:
    0 1px 2px rgba(15, 23, 42, .10),
    0 6px 16px -4px rgba(15, 23, 42, .18) !important;
}

/* Die Trennstriche zwischen den Gruppen ergaben nur auf der
   Glasfläche Sinn — frei schwebend wirken sie wie Reste. */
html body nav.bottom-nav .mp-dtb-trenner,
html body nav.bottom-nav .nav-sep,
html body nav.bottom-nav .mp-dock-sep {
  opacity: .25 !important;
}

/* MP-20260829 · Das im Aufmaß freigegebene weiße Glas-Podest gilt global. */
/* MP-20261004-011 · nav.bottom-nav bleibt immer transparent. Die Glasplatte ist ::before. */
html body nav.bottom-nav.bottom-nav,
html.mp-dock-stil-dunkel body nav.bottom-nav.bottom-nav,
html.mp-dock-stil-hell body nav.bottom-nav.bottom-nav {
  isolation: isolate !important;
  overflow: visible !important;
  border: 0 !important;
  border-radius: 30px !important;
  background: transparent !important;
  box-shadow: none !important;
}

html body nav.bottom-nav.bottom-nav::before {
  content: "" !important;
  position: absolute !important;
  inset: 0 calc(-1 * max(var(--mp-plate-r, 36px), 14px)) !important;
  z-index: -1 !important;
  display: block !important;
  opacity: 1 !important;
  border-radius: 30px !important;
  pointer-events: none !important;
}

/* MP-20261004-014: Standard-Stil ohne blockierendes inset: 0 */
html:not(.mp-dock-stil-hell):not(.mp-dock-stil-dunkel) body nav.bottom-nav.bottom-nav::before {
  border: 1px solid rgba(255, 255, 255, .92) !important;
  border-radius: 30px !important;
  background: rgba(var(--mp-f2-f9fbfd), 0.9) !important;
  box-shadow: 0 1px 2px rgba(15,23,42,.06), 0 14px 34px -20px rgba(15,23,42,.32), inset 0 1px 0 rgba(255,255,255,.82) !important;
  -webkit-backdrop-filter: blur(32px) saturate(165%) !important;
  backdrop-filter: blur(32px) saturate(165%) !important;
}

/* MP-20261004-011 / MP-20261004-014: Explizite Glas-Stile fuer Dunkel & Hell */
html.mp-dock-stil-dunkel body nav.bottom-nav.bottom-nav::before {
  border: 1px solid rgba(255, 255, 255, .14) !important;
  border-radius: 30px !important;
  background: linear-gradient(180deg, rgba(255,255,255,.06) 0%, rgba(255,255,255,.01) 100%), rgba(10,15,26,.88) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 14px 44px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.35) !important;
  -webkit-backdrop-filter: blur(32px) saturate(180%) !important;
  backdrop-filter: blur(32px) saturate(180%) !important;
}

html.mp-dock-stil-hell body nav.bottom-nav.bottom-nav::before {
  border: 1px solid rgba(15,23,42,.10) !important;
  border-radius: 30px !important;
  background: linear-gradient(180deg, rgba(255,255,255,.95) 0%, rgba(248,250,252,.90) 100%) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.95), 0 12px 40px rgba(15,23,42,.14), 0 2px 8px rgba(15,23,42,.06) !important;
  -webkit-backdrop-filter: blur(32px) saturate(165%) !important;
  backdrop-filter: blur(32px) saturate(165%) !important;
}

html body nav.bottom-nav.bottom-nav::after {
  content: none !important;
  display: none !important;
}

/* Klare App-Kacheln: kein milchiger Weissverlauf und keine weisse
   Hairline auf den farbigen Icons. Farben und SVG-Konturen bleiben satt. */
html body nav.bottom-nav .nav-btn .dash-launch-tile-icon {
  border-color: rgba(15,23,42,.08) !important;
  box-shadow: 0 2px 4px rgba(15,23,42,.10), 0 8px 18px -8px rgba(15,23,42,.30) !important;
}

html body nav.bottom-nav .nav-btn .dash-launch-tile-icon::before {
  content: none !important;
  display: none !important;
  background: none !important;
}

@media (max-width: 1024px) {
  html body nav.bottom-nav.bottom-nav,
  html body nav.bottom-nav.bottom-nav::before { border-radius: 26px !important; }
  html body nav.bottom-nav.bottom-nav::after { border-radius: 26px 26px 0 0 !important; }
}

@media (max-width: 768px) {
  html body nav.bottom-nav.bottom-nav,
  html body nav.bottom-nav.bottom-nav::before { border-radius: 22px !important; }
  html body nav.bottom-nav.bottom-nav::after { border-radius: 22px 22px 0 0 !important; }
}

/* MP-20260912-009: separate the desktop glass from its hover space. */
@media (hover: hover) and (pointer: fine) {
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav {
    padding: 45px 12px 15px !important;
  }
  html:not([data-mp-dock-pos]) body:not(.sheet-open):not(.mp-planner-vollbild-open) nav.bottom-nav.bottom-nav:not(.hidden-nav),
  html[data-mp-dock-pos="bottom"] body:not(.sheet-open):not(.mp-planner-vollbild-open) nav.bottom-nav.bottom-nav:not(.hidden-nav) {
    pointer-events: none !important;
  }
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav > *,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav > * {
    pointer-events: auto;
  }
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav::before,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav::before,
  html:not(.mp-dock-stil-hell):not(.mp-dock-stil-dunkel) body nav.bottom-nav.bottom-nav::before,
  html.mp-dock-stil-hell body nav.bottom-nav.bottom-nav::before,
  html.mp-dock-stil-dunkel body nav.bottom-nav.bottom-nav::before {
    top: 30px !important;
    bottom: 0 !important;
    /* Keep the rounded plate inside the horizontal scroll clip. */
    left: 0 !important;
    right: 0 !important;
  }
  html:not([data-mp-dock-pos]) body nav.bottom-nav.bottom-nav::after,
  html[data-mp-dock-pos="bottom"] body nav.bottom-nav.bottom-nav::after {
    top: 30px !important;
    height: 24px;
  }
}
