/* finance-stack — styles split (Phase 46 Wave 4)
   Datei: layout-shell.css  •  Lade-Position: 2/6 — App-Header, PWA-Banner, Sidebar, Nav, Mobile-Tabbar
   Lade-Reihenfolge: base → layout-shell → components → pages → charts-hero → polish
*/

/* === PWA Install-Banner (iOS Safari im Tab) === */
.pwa-install-banner {
  display: none; /* nur aktiv wenn body.pwa-install-hint */
  position: sticky;
  top: 0;
  z-index: 350;
  background: linear-gradient(180deg, var(--accent, #6366f1) 0%, color-mix(in srgb, var(--accent, #6366f1) 80%, black 20%) 100%);
  color: #fff;
  padding: .65rem 1rem;
  font-size: .88rem;
  line-height: 1.4;
  align-items: center;
  gap: .8rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, .25);
}
body.pwa-install-hint .pwa-install-banner { display: flex; }
.pwa-install-banner-text { flex: 1; }
.pwa-install-banner-text strong { font-weight: 600; }
.pwa-install-banner-text em { font-style: normal; font-weight: 500; }
.pwa-share-icon {
  display: inline-block;
  background: rgba(255, 255, 255, .2);
  border-radius: 4px;
  padding: 0 .35rem;
  font-size: .9em;
}
.pwa-install-dismiss {
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, .85);
  font-size: 1.4rem;
  line-height: 1;
  padding: .2rem .55rem;
  cursor: pointer;
  border-radius: 6px;
  flex-shrink: 0;
}
.pwa-install-dismiss:hover { background: rgba(255, 255, 255, .15); color: #fff; }

/* === Persistente App-Navigation === */
.app-header {
  position: sticky;
  top: 0;
  z-index: 300;
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  min-height: var(--header-h);
  box-sizing: border-box;
}
.app-header-inner {
  /* Edge-to-edge: Burger sitzt am linken Bildschirmrand, Aktionen am rechten.
     Vorher waren beide auf 1100px zentriert → Burger lag eingerückt im "Content-Slot". */
  max-width: none;
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.5rem;
  padding: .55rem 1.25rem;
}
.app-header .brand {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: .45rem;
}
.app-header .brand:hover { text-decoration: none; }
/* Brand-Mark (Move 3, v14.0) — Icon-v2, das gestapelte Layer-Symbol.
   Eigene Rundung im Asset → keine border-radius hier, sonst Doppel-Cut. */
.brand-mark {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: block;
}
.app-header nav {
  display: flex;
  gap: .15rem;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.app-header nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: .9rem;
  padding: .35rem .8rem;
  border-radius: 7px;
  transition: background .12s, color .12s;
}
.app-header nav a:hover { background: var(--nav-hover); color: var(--text); }
.app-header nav a.active { background: var(--nav-active-bg); color: var(--nav-active-text); }
.app-header form.inline button.link { color: var(--text-muted); font-size: .85rem; }
.app-header form.inline button.link:hover { color: var(--text); }

/* Nav actions (Abmelden + Toggle) */
.nav-actions {
  display: flex;
  align-items: center;
  gap: .25rem;
  white-space: nowrap;
}

/* Dark mode toggle */
.theme-toggle {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: .95rem;
  padding: .35rem .5rem;
  border-radius: 7px;
  cursor: pointer;
  line-height: 1;
  transition: background .12s, color .12s;
}
.theme-toggle:hover { background: var(--nav-hover); color: var(--text); }
.theme-toggle .theme-icon-dark { display: none; }
[data-theme="dark"] .theme-toggle .theme-icon-light { display: none; }
[data-theme="dark"] .theme-toggle .theme-icon-dark { display: inline-block; }

.privacy-toggle {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 1.1rem; padding: .35rem .55rem;
  border-radius: 7px; cursor: pointer; line-height: 1;
  transition: background .12s, color .12s;
}
.privacy-toggle:hover { background: var(--nav-hover); color: var(--text); }
.privacy-toggle .privacy-icon-on { display: none; }
[data-privacy="1"] .privacy-toggle .privacy-icon-off { display: none; }
[data-privacy="1"] .privacy-toggle .privacy-icon-on { display: inline-block; }

/* === Vorführungsmodus: Sensible Werte unkenntlich machen ===
   Zwei Klassen-Familien:
   - Beträge/Zahlen: .num/.stat-value/.private/.tx-amount/.due-amount/code
   - Personenbezogener Text (Empfänger, Anbieter, Kontolabel): .private-text
   .cat-badge bewusst NICHT geblurrt — Vertrags-/Budget-/Kategorie-Namen sind
   Bezeichner ohne Personenbezug; Anbieter & Empfänger werden gezielt per
   .private-text markiert. */
[data-privacy="1"] .num,
[data-privacy="1"] .stat-value,
[data-privacy="1"] .private,
[data-privacy="1"] .private-text,
[data-privacy="1"] .tx-amount,
[data-privacy="1"] .due-amount,
[data-privacy="1"] code {
  filter: blur(7px);
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}
[data-privacy="1"] .y-ticks-overlay,
[data-privacy="1"] .line-chart .area,
[data-privacy="1"] .line-chart .line,
[data-privacy="1"] .line-chart .forecast-line { filter: blur(5px); }
[data-privacy="1"] .chart-tooltip { display: none !important; }
/* SVG-Text-Blur ist in Safari unzuverlässig — Reference-Labels in Charts
   komplett verbergen. Die gestrichelte Linie zeigt die Position weiter. */
[data-privacy="1"] svg text.private { visibility: hidden; }

#main-content > h1 {
  margin: 0 0 1rem;
  font-size: 1.5rem;
  font-weight: 600;
}

/* HTMX-Indikator */
.htmx-indicator {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  background: var(--text);
  color: var(--surface);
  padding: .4rem .9rem;
  border-radius: 999px;
  font-size: .8rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s;
  z-index: 200;
}
.htmx-request .htmx-indicator,
.htmx-indicator.htmx-request { opacity: 1; }

/* Burger button — sichtbar auf Desktop + Mobile */
.nav-burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  padding: .35rem .45rem;
  border-radius: 7px;
  color: var(--text-muted);
  font-size: 1.25rem;
  line-height: 1;
  transition: background .12s;
}
.nav-burger:hover { background: var(--nav-hover); }

/* === Desktop-Sidebar (links, einklappbar als Rail) === */
:root {
  --sidebar-w: 232px;
  --sidebar-w-rail: 64px;
  --sidebar-w-current: var(--sidebar-w);
  --header-h: 56px;
}
html[data-sidebar-collapsed="1"] { --sidebar-w-current: var(--sidebar-w-rail); }

.nav-sidebar {
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sidebar-w-current);
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: calc(var(--header-h) + .75rem) .55rem 1rem;
  z-index: 250;
  overflow-x: hidden;
  overflow-y: auto;
  transition: width .22s cubic-bezier(.4, 0, .2, 1);
}

.nav-sidebar nav {
  display: flex;
  flex-direction: column;
  gap: .15rem;
}
.nav-sidebar nav a {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .55rem .7rem;
  border-radius: 8px;
  color: var(--text-muted);
  text-decoration: none;
  font-size: .95rem;
  white-space: nowrap;
  transition: background .12s, color .12s, padding .22s cubic-bezier(.4, 0, .2, 1);
}
.nav-sidebar nav a:hover { background: var(--nav-hover); color: var(--text); }
.nav-sidebar nav a.active { background: var(--nav-active-bg); color: var(--nav-active-text); }
.nav-link__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  flex-shrink: 0;
  position: relative;
}
.nav-link__icon svg { width: 20px; height: 20px; display: block; }
/* Gelesen-Badge: ungelesene-Buchungen-Zähler am Buchungen-Icon. Sitzt oben rechts
   am Icon, damit es auch bei eingeklappter Sidebar (nur Icons) sichtbar bleibt. */
.nav-badge {
  position: absolute;
  top: -7px;
  left: 11px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 8px;
  background: var(--danger);
  color: #fff;
  font-size: .62rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nav-link__label {
  flex: 1 1 auto;
  min-width: 0;
  opacity: 1;
  transition: opacity .14s ease;
}
/* Rail-Modus: Labels ausblenden, Links zentriert. gap=0 + label flex:0
   damit der Flex-Container kein Phantom-Padding zwischen Icon und (verschwundenem)
   Label rendert — Icon sitzt sonst leicht links statt mittig auf der Active-Pill. */
html[data-sidebar-collapsed="1"] .nav-sidebar nav a {
  justify-content: center;
  gap: 0;
  padding: .55rem 0;
}
html[data-sidebar-collapsed="1"] .nav-link__label {
  opacity: 0;
  pointer-events: none;
  width: 0;
  flex: 0 0 0;
  overflow: hidden;
}
.nav-sidebar-bottom { display: none; } /* Abmelden bleibt in nav-actions auf Desktop */

/* Header-Layout: Burger ganz links → Brand → Spacer → Actions */
.app-header nav { display: none; }
.app-header-inner { grid-template-columns: auto auto 1fr auto; gap: .5rem 1rem; }
.app-header .brand { gap: .55rem; }
.app-header .nav-actions { justify-self: end; }
.nav-burger { order: -1; }

/* Desktop: Content-Padding ist KONSTANT auf Rail-Breite. Beim Ausklappen wird
   die Sidebar breiter und überlagert den Content (Overlay-Pattern wie Linear/Vercel),
   statt den Content zu stauchen. */
@media (min-width: 621px) {
  body main { padding-left: calc(var(--sidebar-w-rail) + 1.25rem); }
  html:not([data-sidebar-collapsed="1"]) .nav-sidebar {
    box-shadow: 4px 0 24px rgba(0, 0, 0, .12);
  }
}

.nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .5);
  z-index: 400;
}
/* Auf Desktop kein Backdrop — Sidebar koexistiert mit Content */

@media (max-width: 800px) {
  .app-header-inner { grid-template-columns: auto 1fr auto; gap: .4rem; padding: .5rem 1rem; }
}

@media (max-width: 620px) {
  /* Mobile: Burger rechts (besser für Rechtshänder-Daumen). Grid: Logo | Aktionen | Burger.
     order:1 schiebt den Burger ans Ende, brand/actions folgen ihrer Source-Reihenfolge. */
  .app-header-inner {
    grid-template-columns: auto 1fr auto;
    padding: .45rem .75rem;
  }
  .nav-burger { order: 1; }
  .nav-actions { gap: .1rem; }
  .brand-text { display: none; } /* Mobile: nur Logo zeigen — Burger + Logo + Aktionen brauchen Platz */

  /* Sidebar von links → wieder von rechts wie zuvor */
  .nav-sidebar {
    position: fixed;
    top: 0;
    left: auto;
    right: 0;
    bottom: auto;
    height: 100%;
    width: 72vw;
    max-width: 300px;
    background: var(--surface);
    border-right: none;
    box-shadow: -6px 0 32px rgba(0, 0, 0, .22);
    z-index: 500;
    transform: translateX(110%);
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    overflow-y: auto;
    padding: 4.5rem 1rem 2rem;
    gap: .15rem;
  }
  /* Desktop-State (data-sidebar-collapsed) wirkt nicht auf Mobile — dort entscheidet body.nav-open */
  html[data-sidebar-collapsed="1"] .nav-sidebar { transform: translateX(110%); width: 72vw; }
  body.nav-open .nav-sidebar { transform: translateX(0) !important; }

  .nav-sidebar nav a {
    padding: .7rem .9rem;
    border-radius: 10px;
    font-size: 1rem;
    justify-content: flex-start;
  }
  /* Auf Mobile sind Labels immer sichtbar, auch wenn Desktop-collapsed-State gesetzt ist.
     CRITICAL: flex MUSS zurückgesetzt werden — sonst killt das Desktop-Rule
     `flex: 0 0 0` die Labels auf 0px Breite trotz `width: auto`/`opacity: 1`
     (Mobile-Drawer zeigt dann nur Icons + Whitespace, Fred 2026-06-08). */
  .nav-link__label,
  html[data-sidebar-collapsed="1"] .nav-link__label {
    opacity: 1;
    width: auto;
    pointer-events: auto;
    flex: 1 1 auto;
    overflow: visible;
  }
  html[data-sidebar-collapsed="1"] .nav-sidebar nav a {
    justify-content: flex-start;
    padding: .7rem .9rem;
  }

  .nav-sidebar-bottom {
    display: block;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
    margin-top: auto;
  }
  .nav-sidebar-bottom button.link {
    color: var(--text-muted);
    font-size: .9rem;
    padding: .4rem .5rem;
  }

  body.nav-open .nav-backdrop { display: block; }

  /* Move 2 (v14.0): Burger weg auf Mobile — Tabbar-"Mehr" übernimmt Sidebar-Toggle */
  .nav-burger { display: none; }

  /* Move 2: Content unterhalb der Tabbar lassen (safe-area-aware).
     Nicht anwenden wenn body.no-tabbar (Login/Lock haben eh keine Nav, aber
     z.B. Import-Wizard kann den Slot per Body-Class freischalten).
     +6px synchron zur Tabbar (Home-Indicator-Puffer 2026-05-29). */
  body:not(.no-tabbar) main {
    padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--space-4) + 14px);
  }

  /* Filter-FAB oberhalb der Tabbar parken — sonst Overlap */
  body:not(.no-tabbar) .tx-filter-fab {
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--space-3) + 14px);
  }

  /* Global table scroll on mobile */
  .card table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  /* Dashboard Konten: hide IBAN + Stand */
  .accounts th:nth-child(2), .accounts td:nth-child(2),
  .accounts th:nth-child(4), .accounts td:nth-child(4) { display: none; }

  /* Contracts: hide Anbieter + Konto columns */
  .contracts-table th:nth-child(2), .contracts-table td:nth-child(2),
  .contracts-table th:nth-child(3), .contracts-table td:nth-child(3) { display: none; }

  /* Contract rules table: hide Priorität */
  .rules-table th:nth-child(4), .rules-table td:nth-child(4) { display: none; }

  /* Wallet transactions: hide Status + TX hash */
  .wallet-txs th:nth-child(4), .wallet-txs td:nth-child(4),
  .wallet-txs th:nth-child(5), .wallet-txs td:nth-child(5) { display: none; }

  /* Cat checklist: prevent badge overflow */
  .cat-checklist { gap: .35rem; }
  .cat-badge { white-space: normal; word-break: break-word; }

  /* Settings kontenfilter table: allow scroll, shrink padding */
  .kontenfilter-table th, .kontenfilter-table td { padding: .4rem .5rem; font-size: .85rem; }
}

/* ============================================================
   Mobile Bottom-Tab-Bar (Move 2, v14.0 Design-Foundation)
   Apple-/Fintech-Standard: 5 Slots, sticky bottom, safe-area-aware,
   blur-Backdrop. Desktop nutzt weiterhin die Sidebar.
   ============================================================ */
.tabbar { display: none; }

@media (max-width: 620px) {
  .tabbar {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 320;
    background: var(--header-bg);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
    border-top: 1px solid var(--border);
    /* 2026-05-31 (Fred Iteration 2): +6px war zu knapp — auf iPhone 15/16 sass
       das Tabbar-Label direkt an der iOS-Home-Pille (visuelle Kollision). +14px
       gibt klar lesbaren Abstand, ohne dass die Bar unnötig hoch wird. Die
       Atemluft sitzt unterhalb der Tap-Targets — Touch-Area bleibt unverändert. */
    padding: var(--space-1) var(--space-1) calc(var(--space-1) + env(safe-area-inset-bottom) + 14px);
    min-height: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 14px);
    box-sizing: border-box;
    /* Edge-Anti-Alias: dezenter Top-Shadow für Tiefenwirkung über Content-Scroll */
    box-shadow: 0 -1px 0 rgba(0, 0, 0, .02), 0 -8px 24px -16px rgba(15, 23, 41, .12);
    /* 2026-06-10: translateZ(0) promotet Tabbar auf eigenen Compositing-
       Layer. Defensive gegen iOS-Safari WebKit-Bug, der position:fixed
       Elemente bei mix-blend-mode/rAF-Repaints aus dem Viewport-Anchor
       reißt. Belt-and-Suspenders zur isolation:isolate-Eindämmung an
       den Quellen (.ruecklagen-gauge etc.). */
    transform: translateZ(0);
  }
  [data-theme="dark"] .tabbar {
    box-shadow: 0 -1px 0 rgba(255, 255, 255, .04), 0 -8px 24px -12px rgba(0, 0, 0, .6);
  }

  body.no-tabbar .tabbar { display: none; }

  .tabbar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: var(--space-1) 0;
    background: transparent;
    border: 0;
    color: var(--text-muted);
    text-decoration: none;
    font: inherit;
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: .01em;
    cursor: pointer;
    min-height: 44px;
    position: relative;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--duration-fast) var(--ease-out);
  }
  /* Hover-Color NUR für echte Pointer-Devices (Desktop-Maus). iOS-Safari
     hält den :hover-State nach einem Tap fest („klebrig"), wodurch das
     zuletzt getippte Item dunkler erscheint als die anderen muted-Items
     und faelschlich wie aktiv aussieht. (hover: hover) + (pointer: fine)
     filtert Touch-Devices sauber raus. */
  @media (hover: hover) and (pointer: fine) {
    .tabbar__item:hover { color: var(--text); }
  }
  .tabbar__item:active { transform: translateY(1px); }

  .tabbar__icon {
    display: inline-flex;
    width: 24px;
    height: 24px;
    align-items: center;
    justify-content: center;
    position: relative;
  }
  .tabbar__icon svg { width: 22px; height: 22px; }
  /* Mobil ist zu wenig Platz für eine Zahl → nur ein farbiger Punkt am Icon
     signalisiert ungelesene Buchungen (Fred-Vorgabe). */
  .tabbar__badge {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--danger);
    border: 2px solid var(--surface, #fff);
    box-sizing: content-box;
  }

  .tabbar__label {
    line-height: 1;
    white-space: nowrap;
  }

  /* Aktiver Slot: Akzent-Farbe + dezenter Pill-Background */
  .tabbar__item[aria-current="page"] {
    color: var(--accent);
  }
  .tabbar__item[aria-current="page"] .tabbar__icon::before {
    content: '';
    position: absolute;
    /* Exakte Zentrierung beider Achsen via Transform — `top: 2px` (alt) sass
       leicht nach unten/seitlich versetzt, weil das Pseudo (28×28) größer als
       der Icon-Container (24×24) ist. Mit translate(-50%, -50%) sitzt der
       Highlight-Kreis pixelgenau hinter der Icon-Mitte. */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 30px;
    height: 30px;
    background: var(--accent-bg);
    border-radius: var(--r-pill);
    z-index: -1;
  }
  /* Pill-Hintergrund liegt hinter dem Icon, daher Container Position needs */
  .tabbar__item[aria-current="page"] .tabbar__icon {
    position: relative;
    z-index: 1;
  }

  /* Focus für Tastatur — A11y */
  .tabbar__item:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -3px;
    border-radius: var(--r-md);
  }
}

