/*
 * Copyright 2026 Yannes Jabboury. Alle Rechte vorbehalten. All rights reserved.
 */

/* ─── Fonts (Outfit + Roboto Mono, self-hosted under vendor/fonts/) ───────────
   Vendored instead of loaded from fonts.googleapis.com - no third-party request
   on every visit, and it can't ever go down independently of this site.
   Roboto Mono's digits use a plain oval zero (no dot/slash), so it stays
   clearly distinct from an 8 even at small sizes - unlike JetBrains Mono's
   dotted zero, which read as an 8 in numbers like salary figures. */
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 300; src: url('vendor/fonts/outfit-latin-300-normal.woff2') format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 400; src: url('vendor/fonts/outfit-latin-400-normal.woff2') format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 500; src: url('vendor/fonts/outfit-latin-500-normal.woff2') format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 600; src: url('vendor/fonts/outfit-latin-600-normal.woff2') format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 700; src: url('vendor/fonts/outfit-latin-700-normal.woff2') format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-display: swap; font-weight: 800; src: url('vendor/fonts/outfit-latin-800-normal.woff2') format('woff2'); }
@font-face { font-family: 'Roboto Mono'; font-style: normal; font-display: swap; font-weight: 100 700; src: url('vendor/fonts/roboto-mono-latin-wght-normal.woff2') format('woff2'); }

/* ─── Design Tokens ────────────────────────────────────────────────────────── */
:root {
  --font-display: 'Outfit', system-ui, sans-serif;
  --font-mono: 'Roboto Mono', monospace;

  /* Radius */
  --r-sm:   6px;
  --r-md:   12px;
  --r-lg:   16px;
  --r-xl:   22px;
  --r-2xl:  28px;
  --r-full: 9999px;

  /* Transitions */
  --t-fast:   120ms cubic-bezier(0.4, 0, 0.2, 1);
  --t-base:   200ms cubic-bezier(0.4, 0, 0.2, 1);
  --t-spring: 350ms cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Shadows (light) */
  --shadow-xs:  0 1px 2px rgb(0 0 0 / .05);
  --shadow-sm:  0 1px 3px rgb(0 0 0 / .08), 0 1px 2px rgb(0 0 0 / .05);
  --shadow-md:  0 4px 12px rgb(0 0 0 / .08), 0 2px 4px rgb(0 0 0 / .04);
  --shadow-lg:  0 12px 32px rgb(0 0 0 / .10), 0 4px 8px rgb(0 0 0 / .06);
  --shadow-xl:  0 24px 64px rgb(0 0 0 / .12), 0 8px 16px rgb(0 0 0 / .08);
}

/* ─── Theme Skins ──────────────────────────────────────────────────────────────
   A "skin" is the accent color family, independent of light/dark mode (that's
   `data-theme`). Every skin only has to define these tokens - --accent-rgb feeds
   every rgba()-based glow/shadow below via rgba(var(--accent-rgb), <alpha>), so
   adding a new skin never requires touching those rules. Wichtig: --accent-rgb ist
   kommagetrennt (auch ui.js baut daraus rgba(...) für die Charts) - die moderne
   Schreibweise rgb(var(--accent-rgb) / <alpha>) ergibt damit "rgb(229,253,93 / .5)",
   ungültiges CSS, und die ganze Deklaration fällt still weg. So war es lange: kein
   Fokusring, keine aktive Sidebar-Fläche, keine Akzent-Schatten. --accent-text is a
   separately-tuned shade for when the accent is used as *text* on a light
   background, since a bright/light accent (e.g. lime) can look great as a fill
   but be nearly unreadable as foreground text - plain --accent covers fills,
   borders and dark-mode text where that's not a problem. */
:root, [data-skin="neon"] {
  --accent-rgb:   229,253,93;
  --accent:       #e5fd5d;
  --accent-light: #eeff8f;
  --accent-dark:  #c8e02e;
  /* Textvariante des Akzents. Etwas dunkler als zuvor (#6d7d12), damit sie auch
     als kleine Schrift auf dem hellgrauen Seitenhintergrund die 4.5:1 erreicht. */
  --accent-text:  #637308;
  --text-on-accent: #151514;
  --accent-faint:  rgba(var(--accent-rgb), .16);
  --accent-faint2: rgba(var(--accent-rgb), .30);
  --shadow-glow:   0 0 0 3px rgba(var(--accent-rgb), .40);
}
[data-skin="original"] {
  --accent-rgb:   99,102,241;
  --accent:       #6366f1;
  --accent-light: #818cf8;
  --accent-dark:  #4f46e5;
  --accent-text:  #6366f1;
  --text-on-accent: #ffffff;
  --accent-faint:  rgba(var(--accent-rgb), .08);
  --accent-faint2: rgba(var(--accent-rgb), .15);
  --shadow-glow:   0 0 0 3px rgba(var(--accent-rgb), .18);
}
[data-theme="dark"][data-skin="original"] { --accent-text: var(--accent-light); }
[data-theme="dark"][data-skin="neon"]     { --accent-text: var(--accent-light); }
[data-theme="dark"] { --shadow-glow: 0 0 0 3px rgba(var(--accent-rgb), .35); }

/* "Original" restores the app's pre-Neon light palette exactly (incl. the
   light sidebar) - the structural bg/border/text + dark-sidebar changes below
   were designed for "Neon" only and must not bleed into "Original". */
[data-theme="light"][data-skin="original"] {
  --bg-base:       #f4f4f8;
  --bg-elevated:   #ffffff;
  --bg-overlay:    rgba(255,255,255,0.88);
  --bg-subtle:     #f0f0f5;
  --bg-hover:      rgba(0,0,0,.035);
  --bg-nav:        #f9f9fc;
  --bg-nav-glass:  rgba(249,249,252,0.92);
  --border:        rgba(0,0,0,.08);
  --border-strong: rgba(0,0,0,.14);
  --border-input:  rgba(0,0,0,.12);
  --border-focus:  var(--accent);
  --text-primary:   #0d0d14;
  --text-secondary: #5c5c7a;
  /* 4.5:1 gegen den hellsten wie den dunkelsten Hintergrund dieses Themes.
     Vorher #9898b2 - nur 2.5:1 und damit deutlich unter der Lesbarkeitsschwelle. */
  --text-muted:     #6b6b85;
}
[data-theme="light"][data-skin="original"] #sidebar {
  --bg-nav:        #f9f9fc;
  --bg-elevated:   #ffffff;
  --bg-subtle:     #f0f0f5;
  --bg-hover:      rgba(0,0,0,.035);
  --border:        rgba(0,0,0,.08);
  --border-strong: rgba(0,0,0,.14);
  --text-primary:   #0d0d14;
  --text-secondary: #5c5c7a;
  --text-muted:     #6b6b85;
  --accent-faint:  rgba(var(--accent-rgb), .08);
  --accent-faint2: rgba(var(--accent-rgb), .15);
  --accent-text:   var(--accent);
}
[data-theme="light"][data-skin="original"] #sidebar .sidebar-warn {
  color: #d97706;
  background: rgba(245,158,11,.1);
  border-color: rgba(245,158,11,.25);
}

/* ─── Light Theme ──────────────────────────────────────────────────────────── */
:root, [data-theme="light"] {
  --bg-base:       #d9d9d9;
  --bg-elevated:   #ffffff;
  --bg-overlay:    rgba(255,255,255,0.90);
  --bg-subtle:     #eeeeec;
  --bg-input:      #ffffff;
  --bg-hover:      rgba(21,21,20,.05);
  --bg-nav:        #ffffff;
  --bg-nav-glass:  rgba(255,255,255,0.92);

  --border:        rgba(21,21,20,.12);
  --border-strong: rgba(21,21,20,.22);
  --border-input:  rgba(21,21,20,.18);
  --border-focus:  var(--accent-text);

  --text-primary:   #151514;
  --text-secondary: #585858;
  /* vorher #6f6f6a - 3.6:1 auf dem hellgrauen Seitenhintergrund */
  --text-muted:     #5f5f5a;

  --status-open-bg:    #eff6ff;
  --status-open-fg:    #2563eb;
  --status-open-bdr:   #bfdbfe;
  --status-int-bg:     #fffbeb;
  --status-int-fg:     #d97706;
  --status-int-bdr:    #fde68a;
  --status-rej-bg:     #fef2f2;
  --status-rej-fg:     #dc2626;
  --status-rej-bdr:    #fecaca;
  --status-acc-bg:     #f0fdf4;
  --status-acc-fg:     #16a34a;
  --status-acc-bdr:    #bbf7d0;

  --kanban-open-accent:  #3b82f6;
  --kanban-int-accent:   #f59e0b;
  --kanban-rej-accent:   #ef4444;
  /* Rot als SCHRIFT. Die Flaechenvariante #ef4444 erreicht als Text auf hellem
     Grund nur 2.6-3.8:1; im dunklen Theme braucht es umgekehrt einen hellen Ton. */
  --danger-text:         #b52727;
  --kanban-acc-accent:   #22c55e;

  --grain-opacity: 0.025;
  --backdrop-blur: saturate(180%) blur(16px);
}

/* Sidebar stays a permanently dark rail even in the light theme (matches the
   reference dashboards - dark nav column, light content). Re-declaring the same
   token names scoped to #sidebar means every existing var(--text-primary) etc.
   rule inside it just picks up these values instead - no selector duplication. */
[data-theme="light"] #sidebar {
  --bg-nav:        #151514;
  --bg-elevated:   #1f1f1d;
  --bg-subtle:     #262624;
  --bg-hover:      rgba(255,255,255,.06);
  --border:        rgba(255,255,255,.08);
  --border-strong: rgba(255,255,255,.16);
  --text-primary:   #f4f4f0;
  --text-secondary: #b5b5b0;
  /* vorher #6f6f6a - nur 3.0:1 auf den dunklen Kartenflaechen */
  --text-muted:     #8d8d88;
  --accent-faint:  rgba(var(--accent-rgb), .16);
  --accent-faint2: rgba(var(--accent-rgb), .22);
  --accent-text:   var(--accent-light);
}
[data-theme="light"] #sidebar .sidebar-warn {
  color: #fbbf24;
  background: rgba(251,191,36,.14);
  border-color: rgba(251,191,36,.3);
}

/* ─── Dark Theme ───────────────────────────────────────────────────────────── */
[data-theme="dark"] {
  --bg-base:       #151514;
  --bg-elevated:   #1f1f1d;
  --bg-overlay:    rgba(31,31,29,0.92);
  --bg-subtle:     #262624;
  --bg-input:      #1c1c1a;
  --bg-hover:      rgba(255,255,255,.045);
  --bg-nav:        #101010;
  --bg-nav-glass:  rgba(16,16,16,0.94);

  --border:        rgba(255,255,255,.08);
  --border-strong: rgba(255,255,255,.14);
  --border-input:  rgba(255,255,255,.10);
  --border-focus:  var(--accent);

  --text-primary:   #f4f4f0;
  --text-secondary: #b5b5b0;
  /* vorher #6f6f6a - nur 3.0:1 auf den dunklen Kartenflaechen */
  --text-muted:     #8d8d88;

  --status-open-bg:    rgba(37, 99, 235, .14);
  --status-open-fg:    #93c5fd;
  --status-open-bdr:   rgba(37, 99, 235, .25);
  --status-int-bg:     rgba(217, 119, 6, .14);
  --status-int-fg:     #fcd34d;
  --status-int-bdr:    rgba(217, 119, 6, .25);
  --status-rej-bg:     rgba(220, 38, 38, .14);
  --status-rej-fg:     #fca5a5;
  --status-rej-bdr:    rgba(220, 38, 38, .25);
  --status-acc-bg:     rgba(22, 163, 74, .14);
  --status-acc-fg:     #86efac;
  --status-acc-bdr:    rgba(22, 163, 74, .25);

  --kanban-open-accent:  #60a5fa;
  --kanban-int-accent:   #fbbf24;
  --kanban-rej-accent:   #f87171;
  --kanban-acc-accent:   #4ade80;

  --shadow-xs:  0 1px 2px rgb(0 0 0 / .25);
  --shadow-sm:  0 1px 3px rgb(0 0 0 / .35), 0 1px 2px rgb(0 0 0 / .20);
  --shadow-md:  0 4px 12px rgb(0 0 0 / .40), 0 2px 4px rgb(0 0 0 / .20);
  --shadow-lg:  0 12px 32px rgb(0 0 0 / .55), 0 4px 8px rgb(0 0 0 / .30);
  --shadow-xl:  0 24px 64px rgb(0 0 0 / .65), 0 8px 16px rgb(0 0 0 / .40);

  --grain-opacity: 0.055;
  --backdrop-blur: saturate(180%) blur(20px);
}

/* ─── Reset & Base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-family: var(--font-display);
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  height: 100%;
  scroll-behavior: smooth;
}

body {
  background: var(--bg-base);
  color: var(--text-primary);
  min-height: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  transition: background var(--t-base), color var(--t-base);
}

/* ── Grain texture ─────────────────────────────────────────────────────────────
   Rendered as a fixed pseudo-element to prevent iOS Safari repaint glitches
   that occur when background-image + background-blend-mode is on <body> itself */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.028;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  background-repeat: repeat;
  will-change: transform; /* own compositing layer - no repaints */
}
[data-theme="dark"] body::after { opacity: 0.055; }
/* Native Bedienelemente (Kalender-Symbol in Datumsfeldern, Uhrzeit-Picker,
   Scrollbars) passend zum Design einfärben - ohne das waren die Kalender-Symbole
   im dunklen Design dunkelgrau auf dunklem Grund und kaum zu sehen. */
:root, [data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }

::selection { background: var(--accent-faint2); color: var(--accent-text); }

::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-full); }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
/* Firefox doesn't support ::-webkit-scrollbar - without this it falls back to a
   bulky native scrollbar (most noticeable on the horizontally-scrolling Kanban board). */
html { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }

/* ─── Typography ───────────────────────────────────────────────────────────── */
h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.2; }
h2 { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em; }
h3 { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }

.mono { font-family: var(--font-mono); }
.text-xs  { font-size: 0.72rem; }
.text-sm  { font-size: 0.85rem; }
.text-base{ font-size: 1rem; }
.text-lg  { font-size: 1.15rem; }
.text-xl  { font-size: 1.35rem; }
.text-2xl { font-size: 1.65rem; }
.text-3xl { font-size: 2rem; }

/* ─── Layout ───────────────────────────────────────────────────────────────── */
#app { display: flex; min-height: 100vh; }

/* Sidebar */
#sidebar {
  width: 220px;
  flex-shrink: 0;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  background: var(--bg-nav);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 1.25rem 0.75rem;
  z-index: 40;
  overflow: hidden;
  transition: width var(--t-base), background var(--t-base), border-color var(--t-base), color var(--t-base);
}

#main {
  flex: 1;
  min-width: 0; /* flex items default to min-width:auto - without this, one unbreakable-
                   text descendant anywhere on any page can force the whole app wider
                   than the viewport on narrow phones instead of just wrapping/scrolling
                   internally */
  margin-left: 220px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  transition: margin-left var(--t-base);
}

/* Collapsible sidebar (desktop only) */
.sidebar-collapse-btn {
  position: fixed;
  top: 26px;
  left: 220px;
  transform: translateX(-50%);
  width: 22px; height: 22px;
  padding: 0;
  border-radius: 50%;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  z-index: 45;
  box-shadow: var(--shadow-xs);
  transition: left var(--t-base), background var(--t-fast), color var(--t-fast);
}
/* --bg-hover ist halbtransparent - als alleiniger Hintergrund wurde der Kreis beim
   Überfahren durchsichtig (Sidebar-Kante schien durch). Daher als Tönung ÜBER den
   deckenden Grund legen. */
.sidebar-collapse-btn:hover {
  color: var(--text-primary);
  background-color: var(--bg-elevated);
  background-image: linear-gradient(var(--bg-hover), var(--bg-hover));
}
.sidebar-collapse-btn svg { transition: transform var(--t-base); }
@media (max-width: 768px) { .sidebar-collapse-btn { display: none !important; } }

#app.sidebar-collapsed #sidebar { width: 68px; padding-left: 0.5rem; padding-right: 0.5rem; }
#app.sidebar-collapsed #main { margin-left: 68px; }
#app.sidebar-collapsed .sidebar-collapse-btn { left: 68px; }
#app.sidebar-collapsed .sidebar-collapse-btn svg { transform: rotate(180deg); }
#app.sidebar-collapsed .nav-logo { justify-content: center; }
#app.sidebar-collapsed .nav-logo-text,
#app.sidebar-collapsed .sidebar-footer,
#app.sidebar-collapsed .nav-count { display: none; }
#app.sidebar-collapsed .nav-item,
#app.sidebar-collapsed .theme-toggle,
#app.sidebar-collapsed .sidebar-warn {
  font-size: 0;
  gap: 0;
  justify-content: center;
}

/* Bottom Nav (Mobile) */
#bottom-nav {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  height: 60px;
  background: var(--bg-nav);
  border-top: 1px solid var(--border);
  z-index: 40;
  align-items: center;
  justify-content: space-around;
  padding: 0 0.5rem;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  transition: background var(--t-base), border-color var(--t-base);
}

/* Info/Job finden live only in the sidebar nav (desktop); surface them inside
   Settings as a fallback entry point where the sidebar is hidden (mobile). */
.settings-mobile-nav { display: none; }

@media (max-width: 768px) {
  #sidebar    { display: none !important; }
  #bottom-nav { display: flex !important; }
  #main { margin-left: 0; padding-bottom: 68px; }
  .settings-mobile-nav { display: block; }
}

/* Mobile salary-blur FAB: floats above the bottom nav; desktop uses the sidebar
   button instead (#salary-blur-btn), so this stays hidden above the breakpoint. */
.salary-blur-fab {
  display: none;
  position: fixed;
  right: 1rem;
  bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 0.875rem);
  width: 42px; height: 42px;
  border-radius: 50%;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
  z-index: 41;
  cursor: pointer;
  transition: all var(--t-fast);
}
.salary-blur-fab.active {
  color: var(--accent-text);
  background: var(--accent-faint);
  border-color: var(--accent);
}
[data-theme="dark"] .salary-blur-fab.active { color: var(--accent-light); }
@media (max-width: 768px) {
  .salary-blur-fab { display: flex; }
}

/* Page Content */
.page { display: none; padding: 2rem; max-width: 1100px; margin: 0 auto; width: 100%; }
.page.active { display: block; animation: pageFadeIn 0.2s ease; }
@keyframes pageFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

@media (max-width: 640px) {
  .page { padding: 1rem 0.875rem; }
}

/* ─── Sidebar Nav ──────────────────────────────────────────────────────────── */
.nav-logo {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.25rem 0.5rem;
  margin-bottom: 1.5rem;
  /* Ist ein <button> (führt zum Dashboard) - Browser-Standardoptik zurücksetzen */
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: var(--r-md);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.nav-logo:focus-visible { outline: none; box-shadow: var(--shadow-glow); }
.nav-logo-icon {
  width: 32px; height: 32px;
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  border-radius: var(--r-md);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(var(--accent-rgb), .45);
  flex-shrink: 0;
}
.nav-logo-text {
  font-size: 1.05rem; font-weight: 700; letter-spacing: -0.02em;
  color: var(--text-primary);
}

/* Reset browser button defaults before applying nav styles */
/* Gesperrte Buttons müssen auch so aussehen - vorher sah ein gesperrter
   Primär-Button aus wie ein aktiver, und ein Klick tat einfach nichts. */
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  box-shadow: none;
  filter: grayscale(.4);
}
.btn:disabled:hover { transform: none; box-shadow: none; }

button.nav-item {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  font-family: var(--font-display);
  width: 100%;
  text-align: left;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.55rem 0.625rem;
  border-radius: var(--r-md);
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--text-secondary) !important;  /* override browser button UA stylesheet */
  cursor: pointer;
  transition: all var(--t-fast);
  border: 1px solid transparent;
  text-decoration: none;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
}
.nav-item:hover { background: var(--bg-hover); color: var(--text-primary) !important; }
.nav-item.active {
  background: var(--accent-faint2);
  color: var(--accent-text) !important;
  border-color: var(--accent-faint2);
}
[data-theme="dark"] .nav-item.active {
  background: rgba(var(--accent-rgb), .14);
  border-color: rgba(var(--accent-rgb), .2);
  color: var(--accent-light) !important;
}
.nav-item .nav-count {
  margin-left: auto;
  background: var(--bg-subtle);
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 600;
  font-family: var(--font-mono);
  padding: 1px 6px;
  border-radius: var(--r-full);
  min-width: 20px;
  text-align: center;
}
.nav-item.active .nav-count {
  background: var(--accent-faint2);
  color: var(--accent-text);
}
[data-theme="dark"] .nav-item.active .nav-count {
  color: var(--accent-light);
}

.nav-bottom { margin-top: auto; }
.sidebar-footer {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 0.625rem 0.5rem 0.25rem;
  font-size: 0.65rem; color: var(--text-muted);
  text-align: center;
}
.settings-build { font-family: var(--font-mono); font-size: 0.68rem; color: var(--text-muted); letter-spacing: 0.02em; text-align: center; margin-top: 0.25rem; }
.sidebar-challenge a { color: var(--accent-text); text-decoration: none; }
.sidebar-challenge a:hover { text-decoration: underline; }
[data-theme="dark"] .sidebar-challenge a { color: var(--accent-light); }

/* Theme toggle in sidebar */
button.theme-toggle {
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-display);
  width: 100%;
  text-align: left;
}
.theme-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.625rem;
  border-radius: var(--r-md);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text-muted) !important;
  cursor: pointer;
  transition: all var(--t-fast);
  border: 1px solid var(--border);
  background: var(--bg-subtle);
  width: 100%;
}
.theme-toggle:hover { color: var(--text-primary) !important; border-color: var(--border-strong); }
.salary-blur-toggle.active { color: var(--accent-text) !important; background: var(--accent-faint); border-color: var(--accent); }
[data-theme="dark"] .salary-blur-toggle.active { color: var(--accent-light) !important; }

/* Mobile Bottom Nav Items */
.bnav-item {
  flex: 1;
  display: flex; flex-direction: column; align-items: center;
  gap: 3px; padding: 0.35rem 0.25rem;
  color: var(--text-muted);
  cursor: pointer; transition: color var(--t-fast);
  font-size: 0.62rem; font-weight: 600;
  /* Ohne Sperrung passt auch das laengste Label ("Einstellungen") in die Zelle -
     vorher brauchte es 84px bei 80px Platz und wurde beschnitten. */
  letter-spacing: 0;
  text-transform: uppercase;
  text-align: center; line-height: 1.15;
  border-radius: var(--r-md);
  position: relative;
  background: none; border: none;
  max-width: 80px;
}
.bnav-item:hover, .bnav-item.active { color: var(--accent-text); }
[data-theme="dark"] .bnav-item:hover,
[data-theme="dark"] .bnav-item.active { color: var(--accent-light); }
.bnav-dot {
  position: absolute; bottom: 3px;
  width: 4px; height: 4px;
  background: var(--accent); border-radius: 50%;
  opacity: 0; transition: opacity var(--t-fast);
}
.bnav-item.active .bnav-dot { opacity: 1; }

/* Mobile count badge */
.bnav-badge {
  position: absolute; top: 4px; right: calc(50% - 20px);
  background: var(--accent);
  color: var(--text-on-accent);
  font-size: 0.6rem; font-weight: 700;
  width: 16px; height: 16px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  display: none;
}
.bnav-badge.visible { display: flex; }

/* ─── Cards & Containers ───────────────────────────────────────────────────── */
.card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 1.25rem;
  box-shadow: var(--shadow-sm);
  transition: background var(--t-base), border-color var(--t-base), box-shadow var(--t-base);
}
.card-sm { padding: 1rem; border-radius: var(--r-lg); }
.card:hover { box-shadow: var(--shadow-md); }

/* ─── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.85rem; font-weight: 600;
  padding: 0.55rem 1.1rem;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  cursor: pointer;
  transition: all var(--t-fast);
  white-space: nowrap;
  text-decoration: none;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
}
.btn:focus-visible { outline: none; box-shadow: var(--shadow-glow); }
.btn:active { transform: scale(0.97); }

.btn-primary {
  background: var(--accent);
  color: var(--text-on-accent);
  box-shadow: 0 2px 8px rgba(var(--accent-rgb), .35);
}
.btn-primary:hover {
  background: var(--accent-dark);
  box-shadow: 0 4px 16px rgba(var(--accent-rgb), .45);
  transform: translateY(-1px);
}

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: var(--border-strong);
}
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-strong); }

.btn-danger {
  /* Textrot etwas dunkler als die Flaechenvariante #ef4444: als Schrift auf
     hellem Grund erreichte die nur 2.7-3.8:1. */
  background: transparent; color: var(--danger-text);
  border-color: rgba(239,68,68,.25);
}
.btn-danger:hover { background: rgba(239,68,68,.08); border-color: rgba(239,68,68,.4); }

.btn-icon {
  padding: 0.5rem; background: transparent;
  color: var(--text-muted); border: none;
}
.btn-icon:hover { color: var(--text-primary); background: var(--bg-hover); }

.btn-sm { font-size: 0.78rem; padding: 0.4rem 0.8rem; border-radius: var(--r-sm); }
.btn-xs { font-size: 0.72rem; padding: 0.3rem 0.65rem; border-radius: var(--r-sm); }

/* ─── Hover-Tooltip (CSS-only, reusable via data-tooltip="...") ─────────────────
   Ersatz für das native title-Attribut - das übernimmt zwar die gleiche Aufgabe,
   sieht aber wie ein reines OS-Fenster aus statt zum Rest der App zu passen (die
   z.B. auch window.confirm() durch ein eigenes Modal ersetzt). Kein Klick nötig,
   erscheint direkt beim Hovern mit der Maus. */
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  max-width: 220px;
  padding: 6px 10px;
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-md);
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.4;
  text-align: left;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms ease, transform 120ms ease;
  z-index: 60;
}
[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

/* ─── Form Elements ────────────────────────────────────────────────────────── */
.form-group { display: flex; flex-direction: column; gap: 0.35rem; }
.form-label {
  font-size: 0.75rem; font-weight: 600;
  color: var(--text-secondary);
  letter-spacing: 0.03em; text-transform: uppercase;
}
.form-input, .form-select, .form-textarea {
  font-family: var(--font-display);
  font-size: 0.88rem;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--r-md);
  color: var(--text-primary);
  padding: 0.6rem 0.85rem;
  width: 100%;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
/* Prevent iOS from zooming into inputs < 16px font-size */
@media (max-width: 640px) {
  .form-input, .form-select, .form-textarea {
    font-size: 16px;      /* exact 16px prevents iOS auto-zoom */
    padding: 0.75rem 0.9rem;  /* larger touch target */
    min-height: 48px;     /* comfortable touch area */
  }
}
.form-input::placeholder, .form-textarea::placeholder { color: var(--text-muted); }
.form-input:focus, .form-select:focus, .form-textarea:focus {
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .35);
}
.form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  padding-right: 2.25rem;
}
.form-textarea { resize: vertical; min-height: 80px; line-height: 1.5; }

/* ─── Status Badges ────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 0.72rem; font-weight: 600;
  padding: 0.22rem 0.6rem;
  border-radius: var(--r-full);
  border: 1px solid;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* Farbige Varianten pro individueller Status-Kategorie werden zur Laufzeit als
   `.badge-dyn.s-<i>` in ein <style id="dyn-status-styles"> injiziert (siehe app.js injectStatusStyles). */

/* ─── KPI Cards ────────────────────────────────────────────────────────────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.875rem;
  margin-bottom: 0.875rem;
}
@media (max-width: 900px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 0.625rem; } }

.kpi-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 1.1rem 1.1rem 1rem;
  position: relative;
  overflow: hidden;
  transition: all var(--t-base);
  box-shadow: var(--shadow-sm);
}
.kpi-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi-card::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(135deg, var(--accent-faint), transparent 60%);
  pointer-events: none;
  opacity: 0; transition: opacity var(--t-base);
}
.kpi-card:hover::before { opacity: 1; }
.kpi-icon {
  width: 32px; height: 32px;
  border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 0.625rem;
  flex-shrink: 0;
}
.kpi-label { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.25rem; }
.kpi-value { font-size: 1.65rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.15; color: var(--text-primary); }
.kpi-sub   { font-size: 0.72rem; color: var(--text-muted); margin-top: 0.25rem; }

/* Gehalts-Sichtschutz: blendet alle als .jt-money markierten Werte aus, solange
   <html> die Klasse .blur-salary trägt (siehe applySalaryBlur() in app.js). */
html.blur-salary .jt-money {
  filter: blur(6px);
  user-select: none;
}

/* Salary row */
.salary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.875rem;
  margin-bottom: 0.875rem;
}
@media (max-width: 480px) {
  .salary-grid { grid-template-columns: 1fr; gap: 0.625rem; }
}

.salary-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0.875rem 1rem;
  transition: all var(--t-base);
}
.salary-label { font-size: 0.7rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.35rem; }
.salary-value { font-size: 1.05rem; font-weight: 700; font-family: var(--font-display); color: var(--text-primary); letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ─── Charts ───────────────────────────────────────────────────────────────── */
.chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.875rem;
  margin-bottom: 0.875rem;
}
@media (max-width: 700px) { .chart-grid { grid-template-columns: 1fr; } }

.chart-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 1.25rem;
  box-shadow: var(--shadow-sm);
}
.chart-card-full { grid-column: 1 / -1; }
.chart-title { font-size: 0.8rem; font-weight: 700; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 1rem; }
.chart-wrap { position: relative; height: 180px; }

/* ─── Table ────────────────────────────────────────────────────────────────── */
.table-toolbar { display: flex; margin-bottom: 0.625rem; }
/* Auf Mobile übernimmt die Sortier-Leiste (.list-sort-bar) den "Spalten"-Button -
   die eigene Toolbar-Zeile der Desktop-Tabelle wäre dann eine doppelte Reihe. */
@media (max-width: 640px) { #view-table > .table-toolbar { display: none; } }
.table-wrap {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.table-scroll { overflow-x: auto; }
/* Ein-/ausblendbare Spalten (Spalten-Popover): applyTableColumnVisibility() in app.js
   setzt data-hide-cols auf .table-wrap als leerzeichengetrennte Liste ausgeblendeter
   Spalten-Keys - eine Regel pro Spalte trifft dann sowohl th als auch td. */
/* .hide-sm/.hide-md waren bis hierher rein JS-gesteuert (applyCssHideClasses() setzte
   Inline-Styles). Das lief aber nur beim Laden und bei einem Breakpoint-Wechsel -
   renderTable() baut das <tbody> neu, die frischen <td> hatten den Inline-Style dann
   nicht mehr, die <th> im statischen HTML dagegen schon. Zwischen 641px und 900px
   waren dadurch 5 Kopfzellen ausgeblendet und 10 Datenzellen sichtbar: die Spalten
   verrutschten. Als CSS-Regel kann das nicht mehr auseinanderlaufen. */
@media (max-width: 900px) {
  .hide-md { display: none !important; }
}
@media (max-width: 640px) {
  .hide-sm { display: none !important; }
}

.table-wrap[data-hide-cols~="position"]        [data-col="position"],
.table-wrap[data-hide-cols~="status"]          [data-col="status"],
.table-wrap[data-hide-cols~="source"]          [data-col="source"],
.table-wrap[data-hide-cols~="applicationDate"] [data-col="applicationDate"],
.table-wrap[data-hide-cols~="expectedSalary"]  [data-col="expectedSalary"],
.table-wrap[data-hide-cols~="priority"]        [data-col="priority"],
.table-wrap[data-hide-cols~="notes"]           [data-col="notes"],
.table-wrap[data-hide-cols~="nextEvent"]       [data-col="nextEvent"] {
  display: none;
}
table { width: 100%; border-collapse: collapse; }
thead { background: var(--bg-subtle); border-bottom: 1px solid var(--border); }
th {
  padding: 0.75rem 1rem;
  font-size: 0.72rem; font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  text-align: left;
  user-select: none; -webkit-user-select: none;
}
/* Zieh-Griff am rechten Spaltenrand (initColumnResizers() in app.js hängt ihn ein).
   Liegt im Padding des th, damit er die Beschriftung nicht verdrängt, und wird erst
   beim Überfahren der Kopfzeile sichtbar - im Ruhezustand soll die Tabelle ruhig
   aussehen. Auf Touch-Geräten ist er dauerhaft (schwach) sichtbar, weil es dort
   keinen Hover gibt, über den man ihn sonst je entdecken würde. */
th { position: relative; }
.col-resizer {
  position: absolute;
  top: 0; right: -3px; bottom: 0;
  width: 9px;
  cursor: col-resize;
  touch-action: none;           /* sonst scrollt die Seite beim Ziehen auf Touch */
  opacity: 0;
  transition: opacity var(--t-fast);
}
.col-resizer::before {
  content: '';
  position: absolute;
  top: 22%; bottom: 22%; left: 4px;
  width: 2px;
  border-radius: 1px;
  background: var(--border-strong);
}
thead:hover .col-resizer { opacity: .65; }
.col-resizer:hover, .col-resizer:active { opacity: 1; }
.col-resizer:hover::before, .col-resizer:active::before { background: var(--accent); }
@media (hover: none) {
  .col-resizer { opacity: .45; }
}
/* Während des Ziehens: kein Textmarkieren, und der Zeiger bleibt überall der Pfeil */
body.col-resizing { user-select: none; -webkit-user-select: none; cursor: col-resize; }
body.col-resizing * { cursor: col-resize !important; }

th.sortable { cursor: pointer; transition: color var(--t-fast); }
th.sortable:hover { color: var(--text-primary); }
th.sort-active { color: var(--accent-text); }
[data-theme="dark"] th.sort-active { color: var(--accent-light); }
.sort-arrow { margin-left: 4px; opacity: 0.5; }
th.sort-active .sort-arrow { opacity: 1; }

tbody tr {
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--t-fast);
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--bg-hover); }
td {
  padding: 0.75rem 1rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
  vertical-align: middle;
}
td.td-primary { color: var(--text-primary); font-weight: 500; }
td.td-mono { font-family: var(--font-mono); font-size: 0.78rem; }

.table-actions { display: flex; gap: 0.25rem; justify-content: flex-end; }

.table-empty {
  padding: 4rem 2rem;
  text-align: center;
  color: var(--text-muted);
}
.table-empty-icon { margin: 0 auto 1rem; opacity: 0.3; }

/* ─── Kanban ───────────────────────────────────────────────────────────────── */
.kanban-board {
  display: flex;
  /* Desktop bleibt immer horizontal: beim Verschieben einer Bewerbung in "den
     nächsten Status" bleibt die Richtung intuitiv. Bei vielen individuellen
     Kategorien wird gescrollt statt in eine zweite Zeile umzubrechen. Größerer
     Abstand, weil die Spalten-Header (Titel/Punkt links, Sortier-Button rechts)
     sonst bis an den Rand reichen und mit der Nachbarspalte zu eng wirken. */
  gap: 1.75rem;
  align-items: start;
  overflow-x: auto;
  padding-bottom: 1.25rem;
  /* Reicht bis nahe an den Viewport-Rand, damit die horizontale Scrollleiste
     unten am Bildschirmrand sitzt statt direkt (und mittig wirkend) unter
     kurzen Spalten zu schweben. */
  min-height: calc(100vh - 200px);
}
.kanban-column { flex: 1 0 220px; min-width: 220px; }

/* Mobile (= Bottom-Nav-Breakpoint): zurück zu einem Raster statt Seitwärts-Scrollen
   - bei 4 Kategorien ergibt das ein griffiges 2×2-Raster, was sich in der Praxis
   deutlich besser bedienen lässt als schmale, seitlich wegscrollende Spalten.
   Bei mehr Kategorien wächst das Raster einfach um weitere Zeilen. */
@media (max-width: 768px) {
  .kanban-board {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    overflow-x: visible;
    gap: 0.5rem;
    padding-bottom: 0;
    min-height: 0;
  }
  .kanban-column { flex-basis: auto; min-width: 0; }
}

.kanban-col-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.625rem;
  gap: 0.5rem;
}
.kanban-col-title {
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em;
  display: flex; align-items: center; gap: 6px;
}
.kanban-col-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.kanban-col-count {
  font-size: 0.68rem; font-weight: 700;
  font-family: var(--font-mono);
  background: var(--bg-subtle);
  color: var(--text-muted);
  padding: 1px 6px; border-radius: var(--r-full);
}
.kanban-sort-btn {
  font-size: 0.65rem; font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 2px 6px;
  cursor: pointer;
  transition: all var(--t-fast);
  display: flex; align-items: center; gap: 3px;
  white-space: nowrap;
}
.kanban-sort-btn:hover { color: var(--text-primary); border-color: var(--border-strong); }

.kanban-col-body {
  min-height: 120px;
  border-radius: var(--r-lg);
  padding: 0.375rem;
  border: 2px dashed transparent;
  transition: border-color var(--t-fast), background var(--t-fast);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.kanban-col-body.drag-over {
  border-color: var(--accent);
  background: var(--accent-faint);
}

/* Einfüge-Linie beim Umsortieren einer Karte per Drag&Drop innerhalb einer Spalte
   (siehe _updateKanbanDropIndicator() in app.js) - zeigt, wo die Karte landen würde. */
.kanban-drop-indicator {
  height: 3px;
  border-radius: var(--r-full);
  background: var(--accent);
  flex-shrink: 0;
}

.kanban-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0.75rem;
  cursor: pointer;
  transition: all var(--t-base);
  box-shadow: var(--shadow-xs);
  position: relative;
  overflow: visible;  /* allow popovers to escape */
}
.kanban-card::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
}
/* Akzentfarbe pro individueller Status-Kategorie: `.kanban-card.s-<i>::before` (injiziert, siehe injectStatusStyles). */

.kanban-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.kanban-card.dragging { opacity: 0.35; transform: scale(0.97); }
.kanban-card-company { font-weight: 600; font-size: 0.85rem; color: var(--text-primary); margin-bottom: 2px; }
.kanban-card-position { font-size: 0.75rem; color: var(--text-secondary); margin-bottom: 0.5rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kanban-card-meta { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.kanban-card-date { font-size: 0.68rem; font-family: var(--font-mono); color: var(--text-muted); }
.kanban-card-salary { font-size: 0.68rem; font-family: var(--font-mono); color: var(--accent-text); font-weight: 600; }
[data-theme="dark"] .kanban-card-salary { color: var(--accent-light); }
.kanban-stale-dot {
  display: inline-block;
  width: 7px; height: 7px; border-radius: 50%;
  background: #ef4444;
  margin-right: 5px;
  flex-shrink: 0;
  animation: pulseDot 2s ease-in-out infinite;
}
@keyframes pulseDot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.5; transform: scale(0.8); }
}

/* ─── Modals ───────────────────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 9000;
  opacity: 0; transition: opacity 0.2s;
  padding: 0;
}
.modal-backdrop.visible { opacity: 1; }
@media (min-width: 640px) {
  .modal-backdrop { align-items: center; padding: 1.5rem; }
}

.modal-box {
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  box-shadow: var(--shadow-xl);
  width: 100%;
  /* dvh shrinks when keyboard opens on mobile */
  max-height: 92dvh;
  max-height: 92vh; /* fallback for browsers without dvh */
  display: flex; flex-direction: column;
  transform: translateY(32px);
  transition: transform 0.28s cubic-bezier(0.34, 1.2, 0.64, 1);
  overflow: hidden;
}
.modal-backdrop.visible .modal-box { transform: translateY(0); }

@media (min-width: 640px) {
  .modal-box {
    max-width: 540px;
    border-radius: var(--r-2xl);
    transform: scale(0.96) translateY(12px);
  }
  .modal-backdrop.visible .modal-box { transform: scale(1) translateY(0); }
}

.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.25rem 1.5rem 1rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-header h2 { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
/* Detail-Modal-Header: bricht die Aktions-Icons auf eine eigene Zeile um, statt
   den Firmennamen-Block auf schmalen Screens zusammenzuquetschen. */
.detail-header { flex-wrap: wrap; row-gap: 0.5rem; position: relative; padding-right: 3rem; }
.detail-header-info { flex: 1 1 200px; min-width: 0; }
/* align-self statt des vom .modal-header geerbten align-items:center - sonst
   rutscht die Icon-Reihe zur vertikalen Mitte des (mehrzeiligen) Info-Blocks
   ab und wirkt gegenüber dem oben fixierten X-Button versetzt. */
.detail-header-actions { display: flex; gap: 4px; align-items: center; align-self: flex-start; flex-shrink: 0; margin-left: 8px; }
/* X bleibt fest oben rechts, unabhängig davon ob die übrigen Action-Icons umbrechen. */
.detail-close-btn { position: absolute; top: 0.75rem; right: 1rem; }
@media (max-width: 480px) {
  .detail-header { padding-right: 2.5rem; }
  .detail-close-btn { top: 0.5rem; right: 0.5rem; }
  .detail-header-actions { flex: 1 1 100%; justify-content: flex-end; margin-left: 0; }
}
.modal-body {
  overflow-y: auto;
  overflow-x: hidden;
  padding: 1.25rem 1.5rem;
  flex: 1;
  /* Smooth momentum scroll on iOS */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.modal-footer {
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--border);
  display: flex; gap: 0.625rem;
  flex-shrink: 0;
  /* Stay above keyboard on iOS */
  padding-bottom: max(1rem, env(safe-area-inset-bottom, 1rem));
}
.modal-footer .btn { flex: 1; }

/* ─── Lokaler Geräte-Sync (QR) ─────────────────────────────────────────────── */
/* Reines Schwarz-Weiß-QR-Raster bleibt (zuverlässig für jeden Standard-Decoder) -
   der pulsierende Farbverlauf drumherum sorgt für den "sieht nicht nach
   technischem Scanner aus"-Effekt, ohne die Modul-Farben selbst anzufassen.
   --accent-rgb kommt aus dem aktuell gewählten Skin, passt sich also automatisch an. */
.qr-glow {
  position: relative;
  display: inline-block;
  padding: 14px;
  border-radius: var(--r-lg);
  isolation: isolate;
}

/* Ohne diese Regel wurde das Canvas in seiner reinen Bitmap-Größe dargestellt und
   blieb winzig - der Hauptgrund, warum schwächere Webcams den Code nicht lasen.
   pixelated hält die Modulkanten beim Hochskalieren hart; würde der Browser sie
   weichzeichnen, verwischen gerade die kleinen Module ineinander. */
#qr-send-canvas {
  display: block;
  width: min(76vw, 380px);
  height: auto;
  aspect-ratio: 1 / 1;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  border-radius: 4px;
}
.qr-glow::before {
  content: '';
  position: absolute; inset: -18px;
  z-index: -1;
  border-radius: var(--r-lg);
  background: conic-gradient(from var(--qr-glow-angle, 0deg),
    rgba(var(--accent-rgb), .55), transparent 30%, transparent 60%, rgba(var(--accent-rgb), .55));
  filter: blur(18px);
  animation: qrGlowSpin 5s linear infinite;
}
@keyframes qrGlowSpin { to { --qr-glow-angle: 360deg; } }
@property --qr-glow-angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.qr-glow canvas {
  display: block;
  /* Feste Anzeigegröße statt "so groß wie die Bitmap gerade ist": die Modul-Anzahl
     hängt an der Datenmenge, dadurch wanderten Schließen-X und "Fertig"-Button bei
     jedem Frame-Wechsel mit. Das Layout darf nicht an der Bitmap hängen. */
  width: min(280px, 100%);
  aspect-ratio: 1 / 1;
  height: auto;
  /* Beim Hochskalieren harte Modulkanten behalten - weichgezeichnete Ränder machen
     den Code für die Kamera der Gegenseite schlechter lesbar. */
  image-rendering: pixelated;
  border-radius: calc(var(--r-lg) - 4px);
  background: #fff;
  box-shadow: 0 2px 14px rgb(0 0 0 / .12);
}

.qr-progress-track {
  height: 5px;
  border-radius: var(--r-full);
  background: var(--bg-subtle);
  overflow: hidden;
}
.qr-progress-bar {
  height: 100%;
  width: 0%;
  border-radius: var(--r-full);
  /* --accent-dark vorne, damit er sich auch auf hellem Grund vom Track abhebt. */
  background: linear-gradient(90deg, var(--accent-dark), var(--accent));
  transition: width 160ms ease;
}

.qr-scan-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  max-width: 320px;
  margin: 0 auto;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #000;
}
.qr-scan-frame video {
  width: 100%; height: 100%;
  object-fit: cover;
}
.qr-scan-frame::after {
  content: '';
  position: absolute; inset: 10%;
  border: 2px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: 0 0 0 999px rgb(0 0 0 / .35);
  animation: qrScanPulse 1.8s ease-in-out infinite;
  pointer-events: none;
}
/* Kurzes Aufblinken bei jedem NEU erkannten Code (siehe _qrFlashHit()) - die Rückmeldung,
   dass die Kamera den Code tatsächlich liest, auch bevor der Zähler weit ist. */
.qr-scan-frame.qr-scan-hit::after {
  animation: none;
  border-color: #22c55e;
  border-width: 3px;
}
@keyframes qrScanPulse {
  0%, 100% { border-color: var(--accent-dark); }
  50%      { border-color: var(--accent); }
}

.qr-result-details {
  margin-top: .75rem;
  text-align: left;
  max-height: 220px;
  overflow-y: auto;
  border-top: 1px solid var(--border);
  padding-top: .625rem;
}
.qr-result-group + .qr-result-group { margin-top: .625rem; }
.qr-result-group-title {
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); margin-bottom: .25rem;
}
.qr-result-details ul { list-style: none; }
.qr-result-details li {
  font-size: .8rem; color: var(--text-secondary);
  padding: .25rem 0;
  border-bottom: 1px solid var(--border);
}
.qr-result-details li:last-child { border-bottom: none; }

/* ─── Form Grid ────────────────────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.875rem; }
.form-grid .col-span-2 { grid-column: 1 / -1; }
@media (max-width: 640px) {
  .form-grid { grid-template-columns: 1fr; gap: 0.625rem; }
  .form-grid .col-span-2 { grid-column: 1; }
}

/* ─── Detail Modal ─────────────────────────────────────────────────────────── */
.detail-section { margin-bottom: 1.25rem; }
.detail-section-title {
  font-size: 0.68rem; font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 0.625rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.detail-section-title::after {
  content: ''; flex: 1;
  height: 1px; background: var(--border);
}
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.detail-item-label { font-size: 0.7rem; color: var(--text-muted); margin-bottom: 2px; }
.detail-item-value { font-size: 0.88rem; font-weight: 500; color: var(--text-primary); }

.link-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 0.78rem; font-weight: 600;
  padding: 0.35rem 0.75rem;
  border-radius: var(--r-full);
  border: 1px solid var(--border-strong);
  color: var(--accent-text);
  text-decoration: none;
  transition: all var(--t-fast);
  background: var(--accent-faint);
}
[data-theme="dark"] .link-pill { color: var(--accent-light); }
.link-pill:hover { border-color: var(--accent); transform: translateY(-1px); }

/* Timeline */
.timeline { display: flex; flex-direction: column; gap: 0; }
.timeline-item {
  display: flex; gap: 0.75rem;
  padding-bottom: 0.875rem;
  position: relative;
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-line-wrap { display: flex; flex-direction: column; align-items: center; gap: 0; width: 20px; flex-shrink: 0; }
.timeline-dot {
  width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid var(--bg-elevated);
  box-shadow: 0 0 0 2px currentColor;
  flex-shrink: 0; margin-top: 2px;
}
.timeline-connector {
  flex: 1; width: 1px;
  background: var(--border); margin: 3px 0;
  min-height: 16px;
}
.timeline-item:last-child .timeline-connector { display: none; }
.timeline-content { flex: 1; padding-top: 0; }
.timeline-status { font-size: 0.85rem; font-weight: 600; color: var(--text-primary); }
.timeline-ts { font-size: 0.72rem; font-family: var(--font-mono); color: var(--text-muted); margin-top: 1px; }

/* Farbe pro individueller Status-Kategorie: `.tl-dyn.s-<i>` (injiziert, siehe injectStatusStyles). */

/* ─── Filter Bar ───────────────────────────────────────────────────────────── */
.filter-bar {
  display: flex; gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  align-items: center;
}
.filter-search-wrap {
  flex: 1; min-width: 140px;
  position: relative;
}
.filter-search-icon {
  position: absolute; left: 0.75rem; top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted); pointer-events: none;
}
.filter-search-wrap .form-input { padding-left: 2.25rem; }

.filter-status-btn {
  display: flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.88rem;
  background: var(--bg-input);
  border: 1px solid var(--border-input);
  border-radius: var(--r-md);
  color: var(--text-primary);
  padding: 0.6rem 0.85rem;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.filter-status-btn:hover { border-color: var(--border-strong); }
.filter-status-btn.active { border-color: var(--border-focus); }
.filter-status-btn svg { flex-shrink: 0; color: var(--text-muted); margin-left: auto; }
.filter-status-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.view-switch {
  display: flex;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 3px;
  gap: 2px;
}
.view-btn {
  display: flex; align-items: center; gap: 5px;
  font-size: 0.75rem; font-weight: 600;
  padding: 0.35rem 0.7rem;
  border-radius: var(--r-sm);
  cursor: pointer; transition: all var(--t-fast);
  color: var(--text-muted); border: none;
  background: transparent;
}
.view-btn:hover { color: var(--text-primary); }
.view-btn.active {
  background: var(--bg-elevated);
  color: var(--accent-text);
  box-shadow: var(--shadow-xs);
}
[data-theme="dark"] .view-btn.active { color: var(--accent-light); }

/* Mobile Sortierung: Richtung oben als Umschalter, darunter die Felder (ui.js). */
.sort-popover--mobile { min-width: 250px; }
.sort-dir-switch { margin: 0.125rem 0.125rem 0.375rem; }
.sort-dir-switch .view-btn { flex: 1; justify-content: center; padding: 0.45rem 0.5rem; white-space: nowrap; }
.sort-popover-dir { font-size: 0.7rem; color: var(--text-muted); white-space: nowrap; margin-left: 0.5rem; }

/* ─── Page Header ──────────────────────────────────────────────────────────── */
.page-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

/* ── Beispieldaten-Hinweis ──────────────────────────────────────────────────────
   Sitzt über allen Seiteninhalten in <main> und wird von renderDemoBanner()
   ein-/ausgeblendet. Bewusst zurückhaltend statt alarmierend: die Daten sind ja
   kein Fehler, sie sollen nur nicht mit echten verwechselt werden. */
.demo-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  /* Dieselbe Spalte wie der Seiteninhalt (.page: max. 1100px, 2rem Innenabstand) -
     vorher lief der Banner randlos über die ganze Breite von #main, klebte oben am
     Rand und stand am Desktop deutlich links neben Überschrift und Karten. */
  box-sizing: border-box;
  width: calc(100% - 4rem);
  max-width: calc(1100px - 4rem);
  margin: max(2rem, env(safe-area-inset-top, 0px)) auto 0;
  border: 1px dashed var(--border);
  border-radius: var(--r-md);
  background: var(--bg-subtle);
}
/* Unter dem Banner braucht die Seite nicht noch einmal den vollen Abstand nach oben
   (inkl. Safe-Area) - sonst klafft zwischen Banner und Überschrift eine Lücke. */
.demo-banner:not(.hidden) ~ .page { padding-top: 1.5rem; }
.demo-banner-icon { display: flex; color: var(--text-muted); flex-shrink: 0; }
.demo-banner-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 0.82rem;
  line-height: 1.45;
  min-width: 0;
  flex: 1 1 240px;
}
.demo-banner-text span { color: var(--text-muted); }
.demo-banner-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: auto;
}
@media (max-width: 640px) {
  .demo-banner { padding: 0.7rem 0.85rem; gap: 10px; width: calc(100% - 1.75rem); margin-top: max(1rem, env(safe-area-inset-top, 0px)); }
  .demo-banner:not(.hidden) ~ .page { padding-top: 1rem; }
  .demo-banner-actions { margin-left: 0; width: 100%; }
  .demo-banner-actions .btn { flex: 1 1 0; min-width: 0; justify-content: center; text-align: center; }
}
/* Umzugs-Hinweis (nur alte Adresse, siehe renderMoveBanner()): nutzt das Layout des
   Beispieldaten-Hinweises, fällt aber stärker auf. Steht der Beispieldaten-Hinweis
   direkt darunter, rücken beide zusammen statt den vollen Abstand zu wiederholen. */
.move-banner { border-style: solid; border-color: var(--accent); }
.move-banner-emoji { font-size: 1.15rem; line-height: 1; }
.move-banner .demo-banner-text b { color: var(--text-primary); font-weight: 600; }
.move-banner .demo-banner-text a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.move-banner:not(.hidden) ~ .demo-banner { margin-top: 0.75rem; }
/* Sprungziel von goToBackup(): Überschrift nicht an den oberen Rand kleben. */
#settings-backup { scroll-margin-top: max(1.5rem, env(safe-area-inset-top, 0px)); }
.page-header-left h1 { margin-bottom: 0.2rem; }
.page-header-subtitle { font-size: 0.82rem; color: var(--text-muted); }

/* ─── Onboarding-Slider (nur beim allerersten Besuch) ─────────────────────── */
.onboarding-body { padding-top: 1.75rem; text-align: center; }
.onboarding-slide { display: none; }
.onboarding-slide.active { display: block; animation: pageFadeIn 0.25s ease; }
.onboarding-icon {
  width: 56px; height: 56px;
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 1rem;
}
.onboarding-slide h2 { font-size: 1.05rem; margin-bottom: 0.5rem; }
.onboarding-slide p { font-size: 0.85rem; line-height: 1.6; color: var(--text-secondary); max-width: 30ch; margin: 0 auto; }
.onboarding-dots { display: flex; justify-content: center; gap: 0.5rem; margin-top: 1.5rem; }
.onboarding-dot {
  width: 8px; height: 8px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: var(--border-strong);
  cursor: pointer;
  transition: all var(--t-fast);
}
.onboarding-dot.active { background: var(--accent); width: 20px; border-radius: var(--r-full); }

/* ─── Job finden: Portal-Checkliste ───────────────────────────────────────── */
.jobportal-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem 0.75rem;
}
@media (max-width: 480px) {
  .jobportal-grid { grid-template-columns: 1fr; }
}
.jobportal-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
}
.jobportal-item input[type="checkbox"] {
  accent-color: var(--accent);
  width: 15px; height: 15px;
  flex-shrink: 0;
  cursor: pointer;
}

/* ─── Priorität (1-3 Sterne) ───────────────────────────────────────────────── */
.star-picker { display: flex; gap: 2px; }
.star-btn {
  padding: 2px;
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  line-height: 0;
  transition: color var(--t-fast), transform var(--t-fast);
}
.star-btn svg { fill: none; stroke: currentColor; }
.star-btn:hover { color: #f59e0b; transform: scale(1.1); }
.star-btn.filled { color: #f59e0b; }
.star-btn.filled svg { fill: currentColor; }
.priority-stars { display: inline-flex; align-items: center; gap: 1px; vertical-align: middle; }
.priority-star-btn {
  padding: 1px;
  border: none;
  background: none;
  line-height: 0;
  cursor: pointer;
  transition: transform var(--t-fast);
}
.priority-star-btn:hover { transform: scale(1.15); }

/* ─── Info-Seite: eine durchgehende Liste mit Trennlinien statt Einzelkästen ── */
.info-block {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: 1.5rem;
}
.info-row {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--border);
}
.info-row:last-child { border-bottom: none; }
.info-row-icon {
  width: 30px; height: 30px;
  border-radius: var(--r-md);
  background: var(--accent-faint);
  color: var(--accent-text);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
[data-theme="dark"] .info-row-icon { color: var(--accent-light); }
.info-row-title { font-size: 0.85rem; font-weight: 700; margin-bottom: 2px; }
.info-row-desc  { font-size: 0.8rem; color: var(--text-muted); line-height: 1.5; }
.info-row-text  { font-size: 0.85rem; color: var(--text-secondary); line-height: 1.65; }

/* ─── Settings ─────────────────────────────────────────────────────────────── */
.settings-section { margin-bottom: 1rem; }
.settings-section-title {
  font-size: 0.7rem; font-weight: 700;
  color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 0.5rem; padding: 0 0.25rem;
}

.settings-row {
  display: flex; align-items: center;
  justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.settings-row-info h3 { font-size: 0.88rem; margin-bottom: 2px; }
.settings-row-info p { font-size: 0.78rem; color: var(--text-muted); max-width: 36ch; }

/* ─── Status-Kategorien verwalten (Settings) ──────────────────────────────── */
.status-settings-expand {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--t-spring);
}
.status-settings-expand.open { max-height: 900px; }

.import-info-popover {
  width: 280px;
  max-width: calc(100vw - 16px);
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: 0.75rem 0.875rem;
  z-index: 500;
  animation: popoverIn 0.15s ease;
}
.import-info-title { font-weight: 700; font-size: 0.78rem; margin-bottom: 0.4rem; color: var(--text-primary); }
.import-info-popover p {
  font-size: 0.72rem; line-height: 1.5; color: var(--text-secondary);
}
.import-info-popover p + p { margin-top: 0.5rem; }
.import-info-popover strong { color: var(--text-primary); }

.columns-popover {
  width: 190px;
  max-width: calc(100vw - 16px);
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: 0.5rem;
  z-index: 500;
  animation: popoverIn 0.15s ease;
}
.columns-popover-title {
  font-weight: 700; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); padding: 0.25rem 0.5rem 0.4rem;
}
.columns-popover-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  border-radius: var(--r-md);
  font-size: 0.82rem; color: var(--text-secondary);
  cursor: pointer;
}
.columns-popover-item:hover { background: var(--bg-hover); }
.columns-popover-item input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.status-kind-hint {
  font-size: 0.75rem; line-height: 1.5; color: var(--text-muted);
  margin-bottom: 0.75rem;
}
.status-manage-list {
  display: flex; flex-direction: column; gap: 0.625rem;
  margin-bottom: 0.75rem;
}
.status-manage-item {
  display: flex; flex-direction: column; gap: 0.375rem;
  padding-bottom: 0.625rem;
  border-bottom: 1px solid var(--border);
}
.status-manage-item:last-child { border-bottom: none; padding-bottom: 0; }
.status-manage-row, .status-add-row {
  display: flex; align-items: center; gap: 0.5rem;
}
.status-kind-row { padding-left: calc(30px + 0.5rem); /* unter dem Namensfeld einrücken */ }
.status-kind-label {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.72rem; color: var(--text-muted);
}
.status-kind-select {
  width: auto; padding: 0.25rem 1.75rem 0.25rem 0.55rem;
  font-size: 0.78rem;
}
.status-color-input {
  width: 30px; height: 30px; flex-shrink: 0;
  padding: 0; border: 1px solid var(--border-input); border-radius: var(--r-md);
  background: none; cursor: pointer;
}
.status-color-input::-webkit-color-swatch-wrapper { padding: 2px; }
.status-color-input::-webkit-color-swatch { border: none; border-radius: 5px; }
.status-name-input { flex: 1; min-width: 0; }
.status-count {
  flex-shrink: 0;
  min-width: 20px;
  padding: 0.1rem 0.4rem;
  border-radius: var(--r-full);
  background: var(--bg-subtle);
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  font-family: var(--font-mono);
}
.status-move-btns { display: flex; flex-direction: column; gap: 1px; flex-shrink: 0; }
.status-move-btns .btn { height: 15px; padding: 0; }
.status-add-row { padding-top: 0.375rem; border-top: 1px dashed var(--border); }

/* ─── Kalender ─────────────────────────────────────────────────────────────── */
.calendar-layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 0.875rem;
  align-items: start;
}
@media (max-width: 900px) { .calendar-layout { grid-template-columns: 1fr; } }

.calendar-toolbar {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 0.875rem;
}
.calendar-month-label {
  font-size: 0.92rem; font-weight: 700; color: var(--text-primary);
  min-width: 11ch; text-align: center;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
}
.calendar-weekday {
  font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); text-align: center; padding-bottom: 0.375rem;
}
.calendar-cell {
  min-height: 88px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0.3rem;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
  display: flex; flex-direction: column; gap: 2px;
}
.calendar-cell:hover { background: var(--bg-hover); border-color: var(--border-strong); }
/* Tage aus dem Vor-/Folgemonat sollen zuruecktreten, aber lesbar bleiben.
   Vorher wurde die ganze Zelle auf opacity 0.4 gesetzt - der Kontrast fiel damit
   auf 1.9:1, die Zahlen waren praktisch nicht mehr zu entziffern. Eine hoehere
   Opazitaet haette die Abstufung wieder aufgehoben. Stattdessen kennzeichnet jetzt
   eine eigene Flaeche den Fremdmonat: die Zelle tritt klar zurueck, die Zahl bleibt
   trotzdem lesbar. */
.calendar-cell.out-month { background: var(--bg-subtle); }
.calendar-cell.out-month .calendar-cell-num { color: var(--text-muted); font-weight: 500; }
.calendar-cell.today { border-color: var(--accent); background: var(--accent-faint); }
.calendar-cell-num { font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); }
.calendar-cell.today .calendar-cell-num { color: var(--accent-text); }
.calendar-cell-events { display: flex; flex-direction: column; gap: 2px; overflow: hidden; }
.calendar-event-pill {
  display: block; width: 100%; box-sizing: border-box;
  font-size: 0.62rem; font-weight: 600; padding: 0.1rem 0.4rem;
  border-radius: var(--r-sm); border: 1px solid;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.calendar-event-time { opacity: 0.75; margin-right: 3px; }
.calendar-more { font-size: 0.6rem; color: var(--text-muted); padding: 0 0.2rem; }

@media (max-width: 640px) {
  .calendar-cell { min-height: 64px; padding: 0.2rem; }
  .calendar-event-pill { font-size: 0.56rem; }
}

.calendar-upcoming #upcoming-events {
  display: flex; flex-direction: column; gap: 0.5rem;
  max-height: 560px; overflow-y: auto;
}
.upcoming-item {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 0.5rem; border-radius: var(--r-md);
  cursor: pointer; transition: background var(--t-fast);
}
.upcoming-item:hover { background: var(--bg-hover); }
.upcoming-body { flex: 1; min-width: 0; }
.upcoming-title { font-size: 0.82rem; font-weight: 600; color: var(--text-primary); }
.upcoming-sub { font-size: 0.72rem; color: var(--text-muted); margin-top: 1px; }
.upcoming-date { font-size: 0.68rem; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; padding-top: 2px; }
.upcoming-date--today { color: var(--accent-text); font-weight: 700; }
.stc-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }

/* ─── Offline-Backup: Export/Import als getrennte, klar beschriftete Gruppen ── */
.backup-io-label {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); margin-bottom: 0.375rem;
}
.backup-io-desc { font-size: 0.8rem; color: var(--text-muted); margin-bottom: 0.625rem; line-height: 1.45; }
.backup-io-buttons { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }

.persist-status {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.78rem;
  margin-top: 0.625rem;
}
.persist-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.persist-dot.ok      { background: #22c55e; }
.persist-dot.warn    { background: #f59e0b; }
.persist-dot.unknown { background: var(--border-strong); }

/* ─── Toasts ───────────────────────────────────────────────────────────────── */
#toast-root {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
  gap: 0.5rem; z-index: 99999;
  pointer-events: none;
}
@media (min-width: 769px) { #toast-root { bottom: 1.5rem; } }

.toast {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.65rem 1.1rem;
  border-radius: var(--r-full);
  font-size: 0.84rem; font-weight: 600;
  box-shadow: var(--shadow-lg);
  animation: toastIn 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  white-space: nowrap;
  max-width: 90vw;
  pointer-events: auto;
}
.toast-text { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.toast-action {
  flex-shrink: 0;
  background: none; border: none;
  font: inherit; font-weight: 700;
  color: inherit; text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  padding: 0; margin-left: 0.15rem;
}
.toast-action:hover { opacity: 0.8; }
.toast-out { animation: toastOut 0.25s ease forwards; }
@keyframes toastIn {
  from { transform: translateY(20px) scale(0.88); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes toastOut {
  from { transform: translateY(0) scale(1); opacity: 1; }
  to   { transform: translateY(-10px) scale(0.9); opacity: 0; }
}
.toast-success { background: #166534; color: #dcfce7; border: 1px solid #16a34a; }
.toast-error   { background: #7f1d1d; color: #fee2e2; border: 1px solid #dc2626; }
.toast-info    { background: var(--bg-elevated); color: var(--text-primary); border: 1px solid var(--border-strong); }
.toast-warning { background: #78350f; color: #fef3c7; border: 1px solid #d97706; }
[data-theme="light"] .toast-info { background: #1e293b; color: #f1f5f9; border-color: #334155; }

/* ─── Misc Utilities ───────────────────────────────────────────────────────── */
.hidden { display: none !important; }
.flex { display: flex; }
.items-center { align-items: center; }
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 0.75rem; }
.ml-auto { margin-left: auto; }
.mt-3 { margin-top: 0.75rem; }
.mt-4 { margin-top: 1rem; }
.w-full { width: 100%; }

/* Reminder banner in detail */
.reminder-alert {
  display: flex; align-items: center; gap: 0.5rem;
  background: rgba(239,68,68,.1);
  border: 1px solid rgba(239,68,68,.3);
  border-radius: var(--r-md);
  padding: 0.5rem 0.75rem;
  font-size: 0.78rem; font-weight: 600;
  color: var(--danger-text);
  margin-bottom: 0.75rem;
}
[data-theme="dark"] { --danger-text: #fca5a5; }
[data-theme="dark"] .reminder-alert { background: rgba(239,68,68,.12); }

/* Notes box */
.notes-box {
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0.75rem 0.875rem;
  font-size: 0.85rem; line-height: 1.6;
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Persist warning in sidebar */
.sidebar-warn {
  display: flex; align-items: center; gap: 0.5rem;
  width: 100%;
  background: rgba(245,158,11,.1);
  border: 1px solid rgba(245,158,11,.25);
  border-radius: var(--r-md);
  padding: 0.5rem 0.625rem;
  font-size: 0.72rem; font-weight: 600;
  font-family: inherit;
  color: #d97706;
  margin-bottom: 0.5rem;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.sidebar-warn:hover { background: rgba(245,158,11,.18); border-color: rgba(245,158,11,.4); }
[data-theme="dark"] .sidebar-warn { color: #fbbf24; }

/* Kanban sort popover */
.sort-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  z-index: 200;
  min-width: 150px;
  overflow: hidden;
  animation: popoverIn 0.15s ease;
}
@keyframes popoverIn {
  from { opacity: 0; transform: translateY(-6px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.sort-popover-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.55rem 0.875rem;
  font-size: 0.82rem; font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer; transition: all var(--t-fast);
}
.sort-popover-item:hover { background: var(--bg-hover); color: var(--text-primary); }
.sort-popover-item.active { color: var(--accent-text); }
[data-theme="dark"] .sort-popover-item.active { color: var(--accent-light); }
.sort-popover-item .check { margin-left: auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE FIXES & THEME CONSISTENCY
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Filter bar: stack on narrow screens ──────────────────────────────────── */
.filter-bar {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  align-items: center;
}
.filter-bar .form-select, .filter-bar .filter-status-btn {
  flex-shrink: 0;
  min-width: 0;
  max-width: 140px;
}
@media (max-width: 480px) {
  .filter-bar { gap: 0.4rem; }
  .filter-search-wrap { min-width: 100%; order: -1; }
  .filter-bar .form-select, .filter-bar .filter-status-btn { flex: 1; max-width: none; font-size: 0.8rem; }
}

/* ── Page header: don't let right side overflow on mobile ─────────────────── */
@media (max-width: 480px) {
  .page-header { gap: 0.625rem; }
  .page-header h1 { font-size: 1.4rem; }
  .page-header-subtitle { font-size: 0.78rem; }
  /* Stack view-switch + new button vertically if very tight */
  .page-header > div:last-child { gap: 6px; }
  .view-switch .view-btn { padding: 0.3rem 0.55rem; font-size: 0.72rem; }
  /* Frueher stand hier ".view-switch .view-btn span { display:none }". Die Regel traf
     durch ihre hoehere Spezifitaet die .view-label-*-Spans - aber nur den
     Tabelle-Knopf, weil "Kanban" seinen Text als nackten Textknoten fuehrt. Ergebnis
     war ein beschrifteter Knopf neben einem unbeschrifteten Icon. Beide Bezeichnungen
     sind kurz genug ("Liste", "Kanban"), also bleiben sie stehen. */
}

/* ── KPI cards: reduce font on tiny screens ──────────────────────────────── */
@media (max-width: 360px) {
  .kpi-value { font-size: 1.35rem; }
  .kpi-grid  { gap: 0.5rem; }
  .kpi-card  { padding: 0.875rem 0.75rem 0.75rem; }
}

/* ── Kanban: on mobile hide sort label text, show icon only ──────────────── */
@media (max-width: 600px) {
  .kanban-sort-btn .sort-label { display: none; }
  .kanban-board { gap: 0.5rem; }
  .kanban-card  { padding: 0.625rem 0.625rem 0.625rem 0.875rem; }
  .kanban-card-company  { font-size: 0.8rem; }
  .kanban-card-position { font-size: 0.7rem; }
  .kanban-col-title { font-size: 0.68rem; }
}

/* ── Table: tighter padding on mobile ────────────────────────────────────── */
@media (max-width: 640px) {
  th, td { padding: 0.6rem 0.75rem; }
  td { font-size: 0.82rem; }
}

/* ── Salary grid: 3 cols on medium, 1 col on small ──────────────────────── */
@media (max-width: 640px) and (min-width: 481px) {
  .salary-grid { grid-template-columns: repeat(3, 1fr); }
  .salary-value { font-size: 0.9rem; }
}

/* ── Modal: full-width inputs on mobile ─────────────────────────────────── */
@media (max-width: 480px) {
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .col-span-2 { grid-column: 1; }
  .modal-body { padding: 1rem; }
  .modal-header { padding: 1rem 1rem 0.75rem; }
  .modal-footer { padding: 0.75rem 1rem; }
}

/* ── Settings row: stack on small screens ───────────────────────────────── */
@media (max-width: 480px) {
  .settings-row { flex-direction: column; align-items: flex-start; gap: 0.625rem; }
  .settings-row > .btn,
  .settings-row > div:last-child { align-self: flex-start; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THEME CONSISTENCY - ensure every element reads from CSS vars correctly
   ══════════════════════════════════════════════════════════════════════════ */

/* Form inputs always use token backgrounds */
.form-input, .form-select, .form-textarea {
  background: var(--bg-input);
  color: var(--text-primary);
  border-color: var(--border-input);
}
.form-select option {
  background: var(--bg-elevated);
  color: var(--text-primary);
}

/* Cards respect theme */
.card { background: var(--bg-elevated); border-color: var(--border); }

/* Table head + body */
thead { background: var(--bg-subtle); }
tbody tr:hover { background: var(--bg-hover); }

/* Sidebar: all text descendants use token colors so nothing is hardcoded */
#sidebar { color: var(--text-primary); }
#sidebar .nav-logo-text { color: var(--text-primary); }
#sidebar .theme-toggle  { color: var(--text-muted); background: var(--bg-subtle); border-color: var(--border); }
#sidebar .sidebar-warn  { color: #d97706; }
[data-theme="dark"] #sidebar .sidebar-warn { color: #fbbf24; }

/* Bottom nav inherits theme vars (already token-based, but enforce bg) */
#bottom-nav { background: var(--bg-nav); border-color: var(--border); color: var(--text-muted); }

/* Popover respects dark theme */
.sort-popover {
  background: var(--bg-elevated);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.sort-popover-item { color: var(--text-secondary); }

/* Kanban cards */
.kanban-card { background: var(--bg-elevated); border-color: var(--border); }
.kanban-col-count { background: var(--bg-subtle); color: var(--text-muted); }
.kanban-sort-btn  { background: var(--bg-subtle); border-color: var(--border); color: var(--text-muted); }

/* Detail modal items */
.detail-item-label { color: var(--text-muted); }
.detail-item-value { color: var(--text-primary); }
.notes-box { background: var(--bg-subtle); border-color: var(--border); color: var(--text-secondary); }
.timeline-status { color: var(--text-primary); }
.timeline-ts     { color: var(--text-muted); }

/* Toast info variant: always readable in both modes */
.toast-info {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
}
[data-theme="light"] .toast-info {
  background: #1e293b;
  color: #f1f5f9;
  border-color: #334155;
}

/* Link pills */
.link-pill {
  background: var(--accent-faint);
  border-color: var(--border-strong);
  color: var(--accent-text);
}
[data-theme="dark"] .link-pill { color: var(--accent-light); }

/* Salary value: respect theme */
.salary-value { color: var(--text-primary); }
.salary-label { color: var(--text-muted); }
.salary-card  { background: var(--bg-elevated); border-color: var(--border); }

/* KPI sub-line */
.kpi-sub  { color: var(--text-muted); }
.kpi-label{ color: var(--text-muted); }
.kpi-card { background: var(--bg-elevated); border-color: var(--border); }

/* Chart cards */
.chart-card { background: var(--bg-elevated); border-color: var(--border); }

/* Reminder alert */
.reminder-alert { color: var(--danger-text); background: rgba(239,68,68,.1); border-color: rgba(239,68,68,.3); }
[data-theme="dark"] .reminder-alert { color: #fca5a5; background: rgba(239,68,68,.12); border-color: rgba(239,68,68,.25); }

/* Persist status */
.persist-status span { color: var(--text-muted); }

/* Page subtitle */
.page-header-subtitle { color: var(--text-muted); }

/* View switch */
.view-switch { background: var(--bg-subtle); border-color: var(--border); }
.view-btn.active { background: var(--bg-elevated); color: var(--accent-text); }
[data-theme="dark"] .view-btn.active { color: var(--accent-light); }

/* Smooth theme transition on all key elements */
#sidebar, #bottom-nav, .card, .kpi-card, .salary-card, .chart-card,
.modal-box, .table-wrap, .kanban-card, .form-input, .form-select,
.form-textarea, .sort-popover, .view-switch, .view-btn {
  transition:
    background var(--t-base),
    border-color var(--t-base),
    color var(--t-base),
    box-shadow var(--t-base);
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE APP-CARDS  (replaces table on ≤ 640 px)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Desktop: hide card list; Mobile: hide table scroll */
@media (min-width: 641px) { #app-list    { display: none !important; } }
@media (max-width: 640px) { .table-scroll { display: none !important; } }

.app-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.app-card {
  display: flex;
  align-items: stretch;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
  box-shadow: var(--shadow-xs);
}
.app-card:hover  { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.app-card:active { transform: scale(0.985); }

/* Left coloured accent stripe */
.app-card-accent {
  width: 4px;
  flex-shrink: 0;
}
/* Farbe pro individueller Status-Kategorie: `.app-card-accent.s-<i>` (injiziert, siehe injectStatusStyles). */

.app-card-body {
  flex: 1;
  min-width: 0;
  padding: 0.625rem 0.5rem 0.625rem 0.75rem;
}

.app-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 2px;
}

.app-card-company {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 5px;
}

.app-card-badge {
  flex-shrink: 0;
  font-size: 0.62rem !important;
  padding: 0.12rem 0.45rem !important;
}

.app-card-position {
  font-size: 0.78rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.375rem;
}

.app-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.app-card-chip {
  font-size: 0.67rem;
  font-weight: 500;
  background: var(--bg-subtle);
  color: var(--text-muted);
  padding: 2px 7px;
  border-radius: var(--r-full);
  white-space: nowrap;
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-card-chip--mono   { font-family: var(--font-mono); }
.app-card-chip--accent { color: var(--accent-text); background: var(--accent-faint); }
[data-theme="dark"] .app-card-chip--accent { color: var(--accent-light); }

.app-card-actions {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.375rem 0.5rem;
  flex-shrink: 0;
  border-left: 1px solid var(--border);
}

/* Statuswechsel-Button auf der mobilen Karte - eigener Pillen-Hintergrund statt
   nur eines eingefärbten Icons, damit die Tapfläche als Button erkennbar ist. */
.app-card-status-btn {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 22px;
  border: none; border-radius: var(--r-md);
  background: var(--accent-faint);
  color: var(--accent-text);
  cursor: pointer;
}
[data-theme="dark"] .app-card-status-btn { color: var(--accent-light); }
.app-card-status-btn:hover { background: var(--accent-faint2); }

.app-card-menu-btn {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 22px;
  border: none; border-radius: var(--r-md);
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}
.app-card-menu-btn:hover { background: var(--bg-hover); color: var(--text-primary); }

.card-menu-item-danger:hover { color: #dc2626 !important; }

/* ── Disable pull-to-refresh on iOS and Chrome Android ──────────────────────
   overscroll-behavior: none on html+body prevents the native refresh gesture  */
html, body {
  overscroll-behavior-y: none;
  overscroll-behavior-x: none;
}
/* Additionally needed for older iOS via webkit */
body { -webkit-overflow-scrolling: auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   LOGO WORDMARK
   ═══════════════════════════════════════════════════════════════════════════ */

.nav-logo-text {
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--text-primary) !important;
}
.nav-logo-job {
  font-weight: 800;
  color: var(--text-primary);
}
.nav-logo-tracker {
  font-weight: 400;
  color: var(--text-secondary);
}
.nav-logo-dot {
  font-weight: 800;
  color: var(--accent-text);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONFIRM MODAL
   ═══════════════════════════════════════════════════════════════════════════ */

#confirm-modal .modal-box {
  max-width: 360px;
}
#confirm-modal .modal-body {
  padding-top: 0;
}
#confirm-message {
  font-size: 0.875rem;
  color: var(--text-secondary);
  white-space: pre-line;
  line-height: 1.65;
  margin-top: 0.25rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   INSTALL BANNER
   ═══════════════════════════════════════════════════════════════════════════ */

.install-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10000;
  background: var(--bg-elevated);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  padding-bottom: calc(0.875rem + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 24px rgb(0 0 0 / .12);
  transform: translateY(100%);
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.install-banner.visible {
  transform: translateY(0);
}
@media (min-width: 769px) {
  /* On desktop: show as a small bottom-right card instead */
  .install-banner {
    left: auto;
    right: 1.5rem;
    bottom: 1.5rem;
    border-radius: var(--r-xl);
    border: 1px solid var(--border);
    max-width: 340px;
    transform: translateY(calc(100% + 2rem));
    box-shadow: var(--shadow-xl);
  }
}

.install-banner-logo {
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  background: var(--accent-faint);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.install-banner-text {
  flex: 1;
  min-width: 0;
}
.install-banner-title {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.install-banner-sub {
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.install-banner-actions {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-shrink: 0;
}

/* Hide banner when in standalone mode (already installed) */
@media (display-mode: standalone) {
  .install-banner { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   IOS INSTALL STEPS
   ═══════════════════════════════════════════════════════════════════════════ */

.install-step {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.625rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
  color: var(--text-secondary);
  line-height: 1.5;
}
.install-step:last-child {
  border-bottom: none;
}
.install-step-num {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--text-on-accent);
  font-size: 0.72rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 1px;
}
.install-step strong {
  color: var(--text-primary);
}

/* ── Also push bottom-nav up when install banner is visible on mobile ──────── */
@media (max-width: 768px) {
  .install-banner.visible ~ * #bottom-nav,
  body:has(.install-banner.visible) #bottom-nav {
    bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 72px);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE LIST SORT-BAR
   ═══════════════════════════════════════════════════════════════════════════ */

.list-sort-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.625rem;
  padding: 0 0.125rem;
}
.list-sort-bar-btns {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

.list-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.list-sort-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.78rem;
  font-weight: 600;
  font-family: var(--font-display);
  color: var(--text-secondary) !important;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  padding: 0.3rem 0.75rem 0.3rem 0.6rem;
  cursor: pointer;
  transition: all var(--t-fast);
  -webkit-appearance: none;
  appearance: none;
}
.list-sort-btn:hover {
  border-color: var(--border-strong);
  color: var(--text-primary) !important;
}

.list-cards {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Sort popover anchored to the button on mobile */
.sort-popover--mobile {
  right: 0;
  left: auto;
  min-width: 180px;
}

/* ── Filter bar compact on mobile ──────────────────────────────────────────── */
@media (max-width: 640px) {
  .filter-bar {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 0.4rem;
    align-items: center;
  }
  .filter-search-wrap {
    grid-column: 1 / -1;  /* full width on its own row */
    min-width: 0;
    order: -1;
  }
  .filter-bar .form-select, .filter-bar .filter-status-btn {
    font-size: 14px;
    padding: 0.55rem 0.6rem;
    min-height: 40px;
  }
}

/* ── App card: date chip wrapping fix ──────────────────────────────────────── */
.app-card-chip--mono {
  max-width: none;  /* allow full date+time to show */
  white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   KEYBOARD / INPUT ACCESSIBILITY
   ═══════════════════════════════════════════════════════════════════════════ */

/* When keyboard is open the modal should still be scrollable on iOS */
.modal-body:focus-within {
  /* Ensure modal-body gets proper scroll on keyboard open */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Large, comfortable label + input spacing on mobile */
@media (max-width: 640px) {
  .form-label {
    font-size: 0.82rem;
    margin-bottom: 4px;
  }
  .form-group {
    gap: 0.3rem;
  }
  .form-textarea {
    min-height: 100px;
    font-size: 16px; /* prevent iOS zoom */
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   KANBAN CARD - footer, indicators, status button
   ═══════════════════════════════════════════════════════════════════════════ */

.kanban-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 0.5rem;
  padding-top: 0.375rem;
  border-top: 1px solid var(--border);
}

.kanban-card-indicators {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.kanban-indicator {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 0.65rem;
  font-weight: 600;
  font-family: var(--font-mono);
  color: var(--text-muted);
  background: var(--bg-subtle);
  border-radius: var(--r-full);
  padding: 2px 6px 2px 4px;
}

.kanban-status-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: var(--r-sm);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  color: var(--text-muted) !important;
  cursor: pointer;
  transition: all var(--t-fast);
  flex-shrink: 0;
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-display);
}
.kanban-status-btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
  color: var(--text-primary) !important;
}

/* Status popover (reuses sort-popover styles, anchored correctly) */
.status-popover {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 300;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DETAIL MODAL - contact section, status button wrapper
   ═══════════════════════════════════════════════════════════════════════════ */

.detail-contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.625rem;
}
.detail-contact-grid .contact-email-row {
  grid-column: 1 / -1;
}

.detail-section-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 0.625rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   FORM - section divider label
   ═══════════════════════════════════════════════════════════════════════════ */

.form-section-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding-bottom: 0.375rem;
  border-bottom: 1px solid var(--border);
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE SCROLL - iOS top area fix (elements behind notch/status bar)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Ensure page content never hides under status bar on iOS */
.page {
  padding-top: max(2rem, env(safe-area-inset-top, 0px));
}
@media (max-width: 480px) {
  .page {
    padding-top: max(1rem, env(safe-area-inset-top, 0px));
  }
}

/* Sidebar on desktop: also respect top safe area */
#sidebar {
  padding-top: max(1.25rem, env(safe-area-inset-top, 1.25rem));
}

/* ═══════════════════════════════════════════════════════════════════════════
   WEEKLY GOAL PROGRESS
   ═══════════════════════════════════════════════════════════════════════════ */

.goal-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 1rem 1.25rem;
  margin-bottom: 0.875rem;
  box-shadow: var(--shadow-xs);
}

.goal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.625rem;
}

.goal-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.goal-value {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.88rem;
  font-family: var(--font-mono);
}

.goal-edit-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
  border-radius: var(--r-sm);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  color: var(--text-muted) !important;
  cursor: pointer;
  transition: all var(--t-fast);
  -webkit-appearance: none;
  appearance: none;
}
.goal-edit-btn:hover { background: var(--bg-hover); color: var(--text-primary) !important; }

.goal-bar-track {
  height: 8px;
  background: var(--bg-subtle);
  border-radius: var(--r-full);
  overflow: hidden;
  margin-bottom: 0.375rem;
}

.goal-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-light));
  border-radius: var(--r-full);
  transition: width 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.goal-bar-done {
  background: linear-gradient(90deg, #22c55e, #4ade80);
}

.goal-sub {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.goal-editor {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0.75rem 1rem;
  margin-bottom: 0.875rem;
  animation: popoverIn 0.15s ease;
}

/* ═══════════════════════════════════════════════════════════════════════════
   NOTIFICATION SETTINGS ROWS + TOGGLE SWITCH
   ═══════════════════════════════════════════════════════════════════════════ */

.notif-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.375rem 0;
}

/* iOS-style toggle switch */
.toggle {
  -webkit-appearance: none;
  appearance: none;
  width: 44px;
  height: 26px;
  border-radius: var(--r-full);
  background: var(--bg-subtle);
  border: 2px solid var(--border);
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: background var(--t-base), border-color var(--t-base);
}
.toggle::after {
  content: '';
  position: absolute;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: white;
  top: 2px; left: 2px;
  box-shadow: 0 1px 3px rgb(0 0 0 / .2);
  transition: transform var(--t-base), background var(--t-base);
}
.toggle:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.toggle:checked::after {
  transform: translateX(18px);
}
[data-theme="dark"] .toggle:checked { background: var(--accent-light); border-color: var(--accent-light); }

/* ── Timeline history note ───────────────────────────────────────────────── */
.timeline-note {
  font-size: 0.78rem;
  color: var(--text-secondary);
  background: var(--bg-subtle);
  border-left: 2px solid var(--border-strong);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 0.25rem 0.5rem;
  margin-top: 0.3rem;
  font-style: italic;
  line-height: 1.45;
}

/* Formularelemente erben die Schrift nicht von selbst - ohne diese Regel rendern
   Knoepfe, Eingaben und Auswahlfelder in der Systemschrift (Arial) statt in Outfit.
   Faellt erst auf, wenn man danach sucht, wirkt dann aber sofort inkonsistent. */
button, input, select, textarea { font-family: inherit; }

/* ── View-switch label: Tabelle on desktop, Liste on mobile ─────────────── */
.view-label-mobile  { display: none; }
.view-label-desktop { display: inline; }
@media (max-width: 640px) {
  .view-label-mobile  { display: inline; }
  .view-label-desktop { display: none; }
}

/* ── Status popover: ensure it always renders above card content and above
   an open modal (detail-modal's backdrop sits at z-index 9000) ───────────── */
[data-status-anchor] { position: relative; display: inline-flex; }
.status-popover {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  left: auto;
  z-index: 9500;
  min-width: 130px;
}

/* Card-/Zeilen-Aktionsmenü ("⋯"): braucht denselben Vorrang, da es auch aus
   der offenen Detailansicht heraus geöffnet wird (Backdrop bei z-index 9000). */
.card-menu-popover { z-index: 9500; }

/* ── history-note-group hidden by default, shown via JS ─────────────────── */
#f-history-note-group.hidden { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   KANBAN CARD - new compact layout (matching screenshot)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Replace old card styles */
.kanban-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 0;
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
  box-shadow: var(--shadow-xs);
  position: relative;
  overflow: visible;  /* allow popover to overflow */
}
.kanban-card::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  border-radius: var(--r-lg) 0 0 var(--r-lg);
}
.kanban-card:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.kanban-card.dragging { opacity: 0.35; transform: scale(0.97); }

/* Inner layout: handle + body */
.kc-layout {
  display: flex;
  align-items: stretch;
  min-width: 0;
}

/* Drag handle */
.kc-handle {
  /* Am Anfasser darf der Browser nicht scrollen - hier gehoert die Geste dem Drag. */
  touch-action: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  flex-shrink: 0;
  color: var(--border-strong);
  cursor: grab;
  border-radius: var(--r-lg) 0 0 var(--r-lg);
  transition: color var(--t-fast), background var(--t-base);
  touch-action: none;
}
.kc-handle:active { cursor: grabbing; }
.kanban-card:hover .kc-handle { color: var(--text-muted); background: var(--bg-hover); }

/* Content body */
.kc-body {
  flex: 1;
  min-width: 0;
  padding: 0.625rem 0.625rem 0.5rem 0.375rem;
}

.kc-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 1px;
}

.kc-company {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 1;
  min-width: 0;
}

.kc-person {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--bg-subtle);
  color: var(--text-muted);
  flex-shrink: 0;
  cursor: help;
  transition: background var(--t-fast);
}
.kc-person:hover { background: var(--bg-hover); color: var(--text-secondary); }

.kc-position {
  font-size: 0.75rem;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 0.375rem;
}

.kc-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.3rem;
}

.kc-date {
  font-size: 0.68rem;
  font-family: var(--font-mono);
  color: var(--text-muted);
}

.kc-source {
  font-size: 0.68rem;
  color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.kc-salary {
  font-size: 0.68rem;
  font-family: var(--font-display);
  color: var(--text-secondary);
  font-weight: 600;
}

/* Gehalts-Spalte in der Tabelle: eigene Regel statt das geteilte .td-mono zu ändern
   (das rendert auch Datum/Quelle/nächster Termin, die weiterhin Mono bleiben sollen) */
.td-mono.jt-money { font-family: var(--font-display); }

/* Note pill - shows the most recent history note inline */
.kc-note-pill {
  font-size: 0.72rem;
  color: var(--text-secondary);
  background: var(--bg-subtle);
  border-radius: var(--r-sm);
  padding: 0.2rem 0.5rem;
  margin-bottom: 0.375rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* Bottom row: event count + status button */
.kc-bottom {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 18px;
}

.kc-events {
  font-size: 0.67rem;
  color: var(--text-muted);
  font-weight: 500;
}

.kc-status-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border-radius: var(--r-sm);
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted) !important;
  cursor: pointer;
  transition: all var(--t-fast);
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-display);
  flex-shrink: 0;
}
.kanban-card:hover .kc-status-btn,
.kc-status-btn:hover {
  background: var(--bg-subtle);
  border-color: var(--border);
  color: var(--text-primary) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   TABLE - inline status dropdown button
   ═══════════════════════════════════════════════════════════════════════════ */

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  border-radius: var(--r-full);
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-display);
  transition: opacity var(--t-fast);
}
.status-pill:hover { opacity: 0.8; }
.status-pill:hover svg { opacity: 1 !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   CONTEXTUAL RESEARCH BUTTONS
   ═══════════════════════════════════════════════════════════════════════════ */

/* Inline text+icon button for salary/employer research, next to position */
.research-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.68rem;
  font-weight: 600;
  font-family: var(--font-display);
  color: var(--text-muted) !important;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  padding: 2px 8px 2px 6px;
  cursor: pointer;
  transition: all var(--t-fast);
  white-space: nowrap;
  -webkit-appearance: none;
  appearance: none;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.research-btn:hover {
  color: var(--accent-text) !important;
  border-color: var(--accent);
  background: var(--accent-faint);
}
[data-theme="dark"] .research-btn:hover { color: var(--accent-light) !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   NOTIFICATION SETTINGS UI
   ═══════════════════════════════════════════════════════════════════════════ */

/* Permission banners */
.notif-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border-radius: var(--r-md);
  padding: 0.625rem 0.875rem;
  font-size: 0.8rem;
  line-height: 1.5;
  margin-bottom: 0.75rem;
}
.notif-banner--warn   { background: rgba(245,158,11,.1); color: #d97706; border: 1px solid rgba(245,158,11,.25); }
.notif-banner--denied { background: rgba(239,68,68,.08); color: #dc2626; border: 1px solid rgba(239,68,68,.2); }
[data-theme="dark"] .notif-banner--warn   { color: #fbbf24; }
[data-theme="dark"] .notif-banner--denied { color: #fca5a5; }

/* Master toggle row */
.notif-master-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  cursor: pointer;
  padding: 0.25rem 0;
}
.notif-master-info { flex: 1; min-width: 0; }
.notif-master-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.88rem; /* wie .settings-row-info h3 - war vorher 0.95rem, größer als alle anderen Zeilentitel */
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 2px;
}
.notif-master-sub {
  font-size: 0.78rem;
  color: var(--text-muted);
}

/* Divider between sections */
.notif-section-divider {
  height: 1px;
  background: var(--border);
  margin: 0.875rem 0;
}

/* Feature group */
.notif-feature-group {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.notif-feature-label {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-muted);
  margin-bottom: 0.125rem;
}

/* Individual feature rows */
.notif-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.25rem 0;
}
.notif-row-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 0.875rem;
  color: var(--text-primary);
}
.notif-row-sub {
  font-size: 0.72rem;
  color: var(--text-muted);
}

/* Bell button: accent when reminder is set */
#d-bell-btn { transition: color var(--t-fast); }
#d-bell-btn:hover { color: var(--accent-text) !important; }


/* Hinweis in der Kanban-Werkzeugleiste, wenn das Board nicht alle Spalten zeigt -
   eine ausgeblendete Spalte soll nicht wie verlorene Daten wirken. */
.kanban-hidden-hint {
  font-size: .72rem;
  color: var(--text-muted);
  align-self: center;
  padding: .15rem .5rem;
  border: 1px solid var(--border);
  border-radius: 999px;
}
.kanban-hidden-hint.hidden { display: none; }


/* Design- und Gehalts-Schalter stehen nebeneinander am Fuss der Sidebar, nur als
   Icon. Sie teilen sich die Breite, damit die Reihe ruhig wirkt. */
.sidebar-toggles {
  display: flex;
  gap: 6px;
}
.sidebar-toggles .theme-toggle--icon {
  flex: 1;
  justify-content: center;
  gap: 0;
  padding-left: 0;
  padding-right: 0;
}
/* In der eingeklappten Sidebar ist ohnehin nur Platz fuer eine Spalte. */
#app.sidebar-collapsed .sidebar-toggles { flex-direction: column; }

/* ─── Dashboard: Verlauf (Sankey) ─────────────────────────────────────────── */
.page-header-actions { display: flex; align-items: center; gap: 8px; }

.sankey-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: .75rem;
}
.sankey-sub {
  font-size: .75rem;
  color: var(--text-muted);
  line-height: 1.45;
}
/* Ein Sankey braucht Breite. Statt es zu stauchen darf es hier scrollen -
   auf dem Handy ist das die einzige Darstellung, die lesbar bleibt. */
.sankey-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
}
.sankey-wrap svg {
  display: block;
  height: auto;
  max-width: none; /* nicht auf die Kartenbreite zusammenquetschen */
}
.sankey-empty {
  font-size: .82rem;
  color: var(--text-muted);
  text-align: center;
  padding: 2.5rem 1rem;
}
.sankey-ribbon {
  transition: opacity .15s ease;
}
.sankey-wrap:hover .sankey-ribbon { opacity: .55; }
.sankey-ribbon:hover { opacity: 1; }
.sankey-node { stroke: none; }
.sankey-label {
  font-family: 'Outfit', system-ui, sans-serif;
  /* Größe kommt vom <svg>-Element, das sie an den verfügbaren Platz anpasst. */
  font-size: inherit;
  fill: var(--text-secondary);
}
.sankey-count {
  font-weight: 700;
  fill: var(--text-primary);
}
/* Beschriftungen in der Mitte liegen auf den abgehenden Bändern - ein Rand in der
   Kartenfarbe hält sie lesbar. */
.sankey-label {
  paint-order: stroke;
  stroke: var(--bg-elevated);
  stroke-width: 4px;
  stroke-linejoin: round;
}
.sankey-note { fill: var(--text-muted); }
.sankey-hit { cursor: pointer; }
.sankey-hit:hover .sankey-node { filter: brightness(1.12); }

/* Nachweis fürs Amt (openNachweis in app.js) */
.nachweis-body { display: flex; flex-direction: column; gap: .875rem; padding-top: 1rem; }
.nw-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.nw-chip {
  -webkit-appearance: none; appearance: none;
  font: inherit; font-size: .75rem; font-weight: 600;
  padding: .3rem .7rem; border-radius: var(--r-full);
  background: var(--bg-subtle); color: var(--text-secondary);
  border: 1px solid var(--border); cursor: pointer;
}
.nw-chip:hover { border-color: var(--border-strong); }
.nw-chip.active { background: var(--accent-faint2); border-color: var(--accent); color: var(--accent-text); }
.nw-chip:focus-visible { outline: none; box-shadow: var(--shadow-glow); }
.nw-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
.nw-grid .form-label { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.nw-opt { font-weight: 400; color: var(--text-muted); text-transform: none; letter-spacing: 0; }
.nw-count { font-size: .85rem; font-weight: 600; }
.nw-count-empty { color: var(--text-muted); font-weight: 500; }

.nw-note { font-size: .72rem; color: var(--text-muted); line-height: 1.5; }
@media (max-width: 420px) { .nw-grid { grid-template-columns: 1fr; } }

/* Liste hinter einem Diagramm-Element (openChartList in ui.js) */
.chart-list { max-height: min(60vh, 520px); overflow-y: auto; margin: 0 -.25rem; }
.chart-list-row {
  -webkit-appearance: none; appearance: none;
  display: flex; align-items: center; gap: .75rem;
  width: 100%; padding: .6rem .5rem;
  background: transparent; border: 0; border-bottom: 1px solid var(--border);
  border-radius: var(--r-sm, 6px);
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.chart-list-row:last-child { border-bottom: 0; }
.chart-list-row:hover { background: var(--bg-hover); }
.chart-list-row:focus-visible { outline: none; box-shadow: var(--shadow-glow); }
.chart-list-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chart-list-company { font-weight: 600; font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-list-position { font-size: .75rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-list-date { font-family: var(--font-mono); font-size: .72rem; color: var(--text-muted); flex-shrink: 0; }
.chart-list-empty { font-size: .82rem; color: var(--text-muted); text-align: center; padding: 1.5rem 0; }
.sankey-mode-switch { margin-top: .5rem; width: max-content; }

@media (max-width: 640px) {
  .sankey-head { flex-direction: column; align-items: stretch; }
}
.sankey-actions { display: flex; gap: 6px; flex-shrink: 0; }
.sankey-actions .hidden { display: none; }
@media (max-width: 640px) {
  .sankey-actions { width: 100%; }
  .sankey-actions .btn { flex: 1; justify-content: center; }
}

/* Reihenfolge-Position der Statuskategorie. Steht bewusst ganz links bei den
   Pfeilen, mit denen sie sich ändern lässt - vorher gab es gar keine sichtbare
   Positionsangabe, weshalb die Anzahl-Zahl rechts als Reihenfolge missverstanden
   wurde. */
.status-position {
  min-width: 1.35rem;
  flex-shrink: 0;
  font-size: .78rem;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.status-position--new { opacity: .5; }

/* Anzahl der Bewerbungen - ausgeschrieben statt als nackte Zahl im Kreis, damit
   sie nicht mehr wie eine Positionsangabe aussieht. */
.status-usage {
  font-size: .75rem;
  color: var(--text-muted);
  white-space: nowrap;
  margin-left: auto;
}
.status-usage strong {
  font-weight: 700;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ── Tippziele auf Touch-Geraeten ────────────────────────────────────────────
   Gemessen lagen viele Knoepfe bei 20-29px Hoehe. Auf dem Handy ist das knapp:
   die gaengige Empfehlung liegt bei 44px, unter ~36px wird das Treffen muehsam.
   Angehoben wird die Mindestflaeche, nicht die Schrift - das Layout bleibt damit
   wie es ist, die Flaeche waechst nur nach innen. */
@media (pointer: coarse), (max-width: 640px) {
  .btn { min-height: 38px; }
  .btn.btn-sm { min-height: 36px; }
  .btn.btn-icon { min-width: 38px; min-height: 38px; }
  .view-btn { min-height: 34px; }
  .list-sort-btn { min-height: 36px; }
  .goal-edit-btn { min-width: 30px; min-height: 30px; }
  .jobportal-check { width: 20px; height: 20px; }
  /* Die ganze Zeile als Ziel, nicht nur das Kaestchen */
  .jobportal-item { min-height: 40px; }
  .columns-popover-item { min-height: 38px; }
  .sort-popover-item { min-height: 38px; }
  .status-color-input { min-width: 34px; min-height: 34px; }
}

/* Der Bereich mit dem Verlaufsdiagramm scrollt seitlich. Damit er auch per
   Tastatur erreichbar ist, bekommt er einen Fokus - sonst kommt man mit Tab nicht
   an den Inhalt rechts. */
.sankey-wrap:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Nur fuer Screenreader: sichtbar leere Zellen brauchen trotzdem eine Bezeichnung */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Nachtrag zu den Tippzielen: diese Elemente setzen ihre Groesse explizit und
   werden deshalb von den allgemeinen .btn-Regeln oben nicht erfasst. Vergroessert
   wird jeweils nur die Trefferflaeche, das Icon darin bleibt gleich gross. */
@media (pointer: coarse), (max-width: 640px) {
  .app-card-status-btn,
  .app-card-menu-btn { width: 36px; height: 36px; }
  .kc-status-btn     { width: 32px; height: 32px; }
  .star-btn          { min-width: 34px; min-height: 34px; }
  .kanban-sort-btn   { min-height: 32px; padding: 4px 8px; }
  .jobportal-item input[type="checkbox"] { width: 20px; height: 20px; }
}
