/* SailLog base styles — mobile first, no framework (ADR-0005).
   Navigation: sidebar (desktop) + slide-out menu (mobile), per docs/ui/01-Navigation.md. */

:root {
  --c-bg: #f4f6f8;
  --c-surface: #ffffff;
  --c-ink: #1d2733;
  --c-muted: #6b7785;
  --c-accent: #14618a;
  --c-accent-ink: #ffffff;
  --c-border: #dce3ea;
  --c-primary: #14618a;
  --c-danger: #c0392b;
  --radius: 18px;
  --gap: 16px;
  --maxw: 1100px;
  --sidebar-w: 260px;
  --appbar-h: 96px;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Display modes (#53 / IDEA-0026). Dusk = dimmed warm; Night = red-on-black (no blue/white,
   preserves night vision — marine standard). UI chrome only for the first step (not the map). */
:root[data-theme="dusk"] {
  --c-bg: #221d19;
  --c-surface: #2f2823;
  --c-ink: #f0e2d2;
  --c-muted: #b39e8a;
  --c-accent: #b5713a;
  --c-accent-ink: #1a1410;
  --c-border: #463b33;
  --c-primary: #b5713a;
}

:root[data-theme="night"] {
  /* Red-on-black for night vision, but legible (#129): the old --c-muted (#b23c3c) and especially
     --c-accent (#240000, near-black) made icons / the + FAB / active tabs almost invisible. */
  --c-bg: #000000;
  --c-surface: #140808;
  --c-ink: #ff6a6a;
  --c-muted: #d07a7a;
  --c-accent: #b32d2d;
  --c-accent-ink: #ffe3e3;
  --c-border: #4a1a1a;
  --c-primary: #ff6a6a;
}

* {
  box-sizing: border-box;
}

/* Touch-Polish (PO 2026-07-03): UI-Chrome (Labels, Gruppentitel, Segmente, Chips, Buttons) ist NICHT
   markierbar — kein blaues Text-Highlight beim Tippen/Langdrücken. Inhalte (Notizen, Eingaben) bleiben
   markierbar. AB#262: auch die reine „nur Text"-Zeile `.settings-row` (valueRow ohne Aktion, z. B.
   Version/Stand/Herausgeber) ist nicht markierbar — am GETEILTEN Baustein gesetzt, gilt damit überall. */
.ffield__label,
.settings-row,
.settings-row__label,
.settings-group__title,
.segmented__btn,
.chip,
button {
  -webkit-user-select: none;
  user-select: none;
}

html,
body {
  margin: 0;
  padding: 0;
}

/* Rechts-Wisch/Push-Menü schiebt den Inhalt bis zu --sidebar-w nach rechts; ohne Kappen wächst das
   Dokument über die Bildschirmbreite → iOS macht Shrink-to-fit (Zoom-out). `overflow-x: clip` auf html
   klammert das (und kappt auch die verschobene fixe Bottom-Nav). ABER: permanent auf html/body gesetzt
   bricht `overflow-x: clip` auf iOS Safari das `position: sticky` von Kopfleiste/Meldungsbalken auf
   (WebKit-Bug) → Header/Nav/Balken scrollten mit (AB#257, Regression von #69/#207/#187). Deshalb NUR
   transient klammern — solange das Menü offen ist (`menu-push`) oder am Finger klebt (`menu-dragging`);
   dann ist Sticky ohnehin irrelevant. Im Ruhezustand kein Clip → Sticky funktioniert wieder. */
html:has(#app.menu-push),
html:has(#app.menu-dragging) {
  overflow-x: clip;
}

body {
  background: var(--c-bg);
  color: var(--c-ink);
  line-height: 1.45;
}

#app {
  min-height: 100vh;
}

/* App bar */
.appbar {
  /* Sticky so the menu/user/sync stay reachable on every page while scrolling (#69). Fixed height
     (+ notch inset via padding) lets the page sub-headers stick directly beneath it. */
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  height: calc(var(--appbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 16px 6px;
  background: var(--c-accent);
  color: var(--c-accent-ink);
}

/* Header: obere Zeile (≡ · Marke · Törnname · 🔍), untere Zeile (Datepicker rechts, unter der Lupe). */
.appbar__top {
  display: flex;
  align-items: center;
  gap: 10px;
}
.appbar__bottom {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 32px;
  /* US #310 (PO 2026-07-14): Zeit-Pille ganz links (bündig unter dem Burger), Datum rechts (margin-left:auto
     an .appbar__datewrap). Daher keine Einrückung mehr. */
  padding-left: 0;
}

.appbar__menu {
  background: transparent;
  border: none;
  color: var(--c-accent-ink);
  line-height: 0;
  padding: 4px 8px;
  cursor: pointer;
}

.appbar__brand {
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.5px;
}

.appbar__trip {
  /* Grow so the search/avatar sit on the right (ADR-0024 §1); truncate a long Törn name. */
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Jetzt der einzige Titel im Header (AB#247) → prominent wie zuvor die Marke „SailLog". */
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.3px;
}

/* Global search icon, header top-right (#110) */
.appbar__search {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  color: var(--c-accent-ink);
  line-height: 0;
  padding: 4px 8px;
  cursor: pointer;
}

/* Inline header search (#151) — overlays the app-bar content when open: a rounded field (magnifier ·
   input · small × to clear) + a big × outside the field to close. Hidden until opened. */
.appbar-search {
  display: none;
}

.appbar-search--open {
  display: flex;
  align-items: center;
  gap: 10px;
  position: absolute;
  left: 0;
  right: 0;
  top: env(safe-area-inset-top);
  height: var(--appbar-h);
  padding: 0 12px;
  background: var(--c-accent);
  z-index: 5;
}

.appbar-search__field {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  height: 40px;
  padding: 0 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
}

.appbar-search__icon {
  flex: 0 0 auto;
  opacity: 0.85;
}

.appbar-search__input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--c-accent-ink);
  font: inherit;
  outline: none;
}

.appbar-search__input::placeholder {
  color: var(--c-accent-ink);
  opacity: 0.7;
}

.appbar-search__clear {
  flex: 0 0 auto;
  display: none;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.28);
  color: var(--c-accent-ink);
  cursor: pointer;
}

.appbar-search__close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.16);
  color: var(--c-accent-ink);
  cursor: pointer;
}

.appbar__user {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.15);
  border: none;
  color: var(--c-accent-ink);
  border-radius: 999px;
  padding: 5px 12px 5px 10px;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.appbar__user:hover {
  background: rgba(255, 255, 255, 0.28);
}

.appbar__user-name {
  font-weight: 600;
}

/* Cloud-sync status indicator (09-Sync-API → letzter Sync / Stand) */
.appbar__sync {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--c-accent-ink);
  opacity: 0.85;
  font-size: 0.8rem;
  white-space: nowrap;
}

.appbar__sync + .appbar__user-wrap {
  margin-left: 12px;
}

.appbar__sync--error {
  opacity: 0.55;
}

.appbar__sync--busy .appbar__sync-icon {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (max-width: 520px) {
  /* Tight phones: keep the icon, drop the time text to save space. */
  .appbar__sync-label {
    display: none;
  }
}

/* User avatar button + dropdown menu (00-Design-Language → User menu) */
.appbar__user-wrap {
  position: relative;
  margin-left: auto;
}

.appbar__user--avatar {
  margin-left: 0;
  padding: 2px;
  background: transparent;
}

.appbar__user--avatar:hover {
  background: rgba(255, 255, 255, 0.2);
}

.avatar--sm {
  width: 32px;
  height: 32px;
}

/* Sync-status dot on the avatar (#65) */
.avatar--dotted {
  position: relative;
}

.avatar-dot {
  position: absolute;
  top: -1px;
  right: -1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--c-primary, #14618a);
  box-sizing: content-box;
}

.avatar-dot--hidden {
  display: none;
}

.avatar-dot--pending {
  background: #e0a91e;
}

.avatar-dot--offline {
  background: #9aa3ad;
}

.avatar-dot--syncing {
  background: #cfe6f2;
  animation: saillog-dot-pulse 1s ease-in-out infinite;
}

@keyframes saillog-dot-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.usermenu__status {
  padding: 0 10px 8px;
  font-size: 0.78rem;
}

.avatar--sm .avatar__initials {
  font-size: 0.8rem;
}

.usermenu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--c-surface);
  color: var(--c-ink);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  padding: 6px;
  display: none;
  z-index: 60;
}

.usermenu--open {
  display: block;
}

.usermenu__header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 10px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--c-border);
}

.usermenu__id {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.usermenu__name {
  font-weight: 600;
  line-height: 1.2;
}

.usermenu__role {
  font-size: 0.8rem;
  color: var(--c-muted, #6b7280);
}

.usermenu__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: 10px 10px;
  border-radius: 8px;
  cursor: pointer;
}

.usermenu__item:hover {
  background: var(--c-bg);
}

/* Identity gate (setup / login), full-screen before the shell */
.auth {
  max-width: 460px;
  margin: 0 auto;
  padding: 32px 20px 48px;
  display: grid;
  gap: 10px;
}

.auth__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--c-accent);
  font-weight: 700;
  font-size: 1.2rem;
  margin-bottom: 8px;
}

.auth__title {
  margin: 0;
  font-size: 1.5rem;
}

.auth__hint {
  margin: 0 0 8px;
  color: var(--c-muted);
}

.auth__list {
  display: grid;
  gap: 8px;
}

.auth__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 10px;
}

.auth__name {
  font-weight: 600;
}

.auth__pin {
  width: 96px;
  text-align: center;
  letter-spacing: 4px;
}

.auth__form {
  margin-top: 4px;
}

.auth__error {
  margin: 4px 0 0;
  color: #b3402f;
  font-size: 0.9rem;
  min-height: 1.2em;
}

.auth__actions {
  margin-top: 8px;
}

/* Layout: outlet full width on mobile; sidebar is off-canvas. */
.layout {
  position: relative;
}

/* Sidebar — slide-out on mobile. Sits below the app bar and scrolls independently; on iOS the
   layout viewport (URL bar / home indicator) used to cut off the lowest entries (#70), so size it
   with the dynamic viewport (dvh) and pad the bottom for the safe area. */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--sidebar-w);
  /* Full *visible* viewport height: 100vh is wrong on iOS (it's the larger layout viewport, so the
     bottom entries fall below the fold and can't be scrolled to). dvh / -webkit-fill-available give
     the actual visible height (#70). Content is padded below the app bar and above the home bar. */
  height: 100vh;
  height: 100dvh;
  /* Push-Menü: die App-Leiste liegt nicht mehr über dem Menü → Einträge starten ganz oben (nur Safe-Area),
     das Settings/Profil-Footer klebt unten (via flex:1 auf .sidebar__links). */
  padding: calc(env(safe-area-inset-top) + 12px) 12px calc(env(safe-area-inset-bottom) + 16px);
  background: var(--c-surface);
  border-right: 1px solid var(--c-border);
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
  overscroll-behavior: contain;
  transform: translateX(-100%);
  transition: transform 0.22s ease;
  /* ÜBER Kopfleiste (40) und Fußmenü (40): so liegen erster/letzter Menüeintrag nie hinter der Chrome,
     selbst wenn das „Push" (das Header/Footer nach rechts schiebt) mal nicht greift. Unter Dropdowns/
     Statusstreifen (60). Geschlossen ist die Sidebar ohnehin links außerhalb (translateX -100%). */
  z-index: 45;
}

/* The module list scrolls; the avatar footer below it stays pinned (ADR-0024 §8 / #117).
   `flex: 1 1 0` (basis 0, not auto) so the scroller reliably grows to fill on iOS Safari too —
   with basis auto it sometimes sized to content and left the footer floating mid-drawer. */
.sidebar__links {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ＋ Erstellen in the sidebar (#191) — only on desktop/iPad, where the bottom-nav ＋ is hidden.
   On phones the bottom-nav carries the central ＋, so this stays hidden (see @media ≥900px). */
.sidebar__create {
  display: none;
}

.sidebar__create-icon {
  flex: 0 0 auto;
}

/* Avatar pinned bottom-left → Settings (Claude-app style). */
.sidebar__user {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 12px;
  padding: 10px 12px;
  border: none;
  border-radius: 10px;
  background: var(--c-bg);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.sidebar__user:hover {
  background: var(--c-border);
}

.sidebar__user-id {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.sidebar__user-name {
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar__user-role {
  font-size: 0.8rem;
  color: var(--c-muted);
}

.sidebar__user-gear {
  flex: 0 0 auto;
  color: var(--c-muted);
}

/* Settings hub (ADR-0024 §9 / #118) — grouped iOS-style rows, each icon + chevron → sub-page. */
.settings-group {
  margin-bottom: 0;
}

/* Shared group header (the Boot/Reservierungen reference) — small, LIGHT grey, sentence case (NOT
   uppercase/bold, which read as "too big"). The space ABOVE each group lives here alone now: the
   parent gap (16) + group margin-bottom (was 8) + this margin-top (was 20) stacked to ~44px between
   sections, which read as too far apart (PO: ~205→~137px). margin-bottom is dropped (the parent gap
   separates groups) and the top inset trimmed so consecutive groups sit ~30px apart. */
.settings-group__title {
  margin: 12px 0 6px 16px;
  /* A touch larger than before (0.76→0.88rem) for legibility, still light grey + sentence case so it
     doesn't read as "too big" / heavy like the old uppercase-bold headings (PO 2026-06-30). */
  font-size: 0.88rem;
  font-weight: 400;
  color: var(--c-muted);
}

/* Aufklappbare Gruppe (Accordion, US #270) — der Kopf ist ein antippbarer Button IM STIL des Gruppen-Titels
   (grau, 0.88rem), plus optionaler Zahl/Status-Zusatz und ein Chevron, das sich beim Auf-/Zuklappen dreht. */
.accordion__head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin: 12px 0 6px 0;
  padding: 2px 16px;
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
  text-align: left;
  color: var(--c-muted);
}
.accordion__title {
  font-size: 0.88rem;
  font-weight: 400;
}
.accordion__meta {
  font-size: 0.82rem;
  color: var(--c-muted);
  opacity: 0.85;
}
.accordion__chevron {
  margin-left: auto; /* Chevron rechtsbündig */
  flex: 0 0 auto;
  transition: transform 0.18s ease;
  transform: rotate(0deg); /* zu = ▾ (zeigt nach unten) */
}
.accordion__head[aria-expanded="true"] .accordion__chevron {
  transform: rotate(180deg); /* auf = ▴ */
}
.accordion__body[hidden] {
  display: none;
}

/* ── US #296: Gruppenkarten-Optik (`card:true`) ──────────────────────────────────
   Aus der rohen grauen Überschrift wird eine echte Karten-Zeile: Farbpunkt · Titel (Gewicht) + kleine
   Meta-Zeile (opt. Mini-Fortschritt) · Zähler-Pille rechts · Chevron. Mehrere in EINEM Rahmen via
   `accordionCard(...)` — Kategorien = Zeilen INNERHALB des Rahmens, Items expandieren im selben Rahmen. */
.accordion-card {
  padding: 0;
  overflow: hidden; /* klammert die Zeilen an die runden Kartenecken */
}
.accordion-card .accordion {
  margin: 0;
}
.accordion-card > .accordion:not(:first-child) > .accordion__head--card {
  box-shadow: inset 0 1px 0 var(--c-border); /* Haarlinie zwischen Kategorien */
}
/* Geöffnete Gruppe (PO 2026-07-10): durchgehender Trennstrich (edge-to-edge, ganz links bis ganz rechts)
   zwischen Kopf und Inhalt — bewusst NICHT eingerückt wie die Zeilentrenner darin. */
.accordion__head--card[aria-expanded="true"] {
  box-shadow: inset 0 -1px 0 var(--c-border);
}
.accordion-card > .accordion:not(:first-child) > .accordion__head--card[aria-expanded="true"] {
  box-shadow: inset 0 1px 0 var(--c-border), inset 0 -1px 0 var(--c-border);
}
.accordion__head--card {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin: 0;
  padding: 12px 14px;
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
  text-align: left;
  color: var(--c-ink);
}
.accordion__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.accordion__main {
  flex: 1 1 auto;
  min-width: 0; /* erlaubt Ellipsis am Titel */
}
.accordion__head--card .accordion__title {
  display: block; /* Block-Kontext nötig, sonst greift text-overflow:ellipsis am inline-span NICHT */
  min-width: 0;
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: inherit;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; /* lange Titel schneiden ab statt umzubrechen */
}
.accordion__sub {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 2px;
  font-size: 0.78rem;
  color: var(--c-muted);
}
.accordion__prog {
  flex: 0 0 auto;
  width: 64px;
  height: 4px;
  border-radius: 3px;
  background: var(--c-border);
  overflow: hidden;
}
.accordion__prog i {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--c-accent);
}
.accordion__pill {
  flex: 0 0 auto;
  font-size: 0.78rem;
  font-weight: 650;
  padding: 4px 10px;
  border-radius: 999px;
  white-space: nowrap;
  color: var(--c-accent);
  background: rgba(20, 97, 138, 0.12); /* Fallback (Tag-Theme) */
  background: color-mix(in srgb, var(--c-accent) 13%, transparent);
}
.accordion__pill--done {
  color: #1f7a3d;
  background: rgba(31, 122, 61, 0.13);
  background: color-mix(in srgb, #1f7a3d 15%, transparent);
}
.accordion__head--card .accordion__chevron {
  margin-left: 0; /* Pille + Chevron bleiben zusammen rechts (main schiebt via flex) */
  color: var(--c-muted);
}
.accordion__badge {
  flex: 0 0 auto; /* rote Gruppen-Zähler-Badge (US #295), rechts vor der Chevron */
}
.accordion--dimmed .accordion__title {
  color: var(--c-muted); /* Erledigt: Titel gedämpft */
}
.accordion--dimmed .accordion__dot {
  opacity: 0.5;
}

/* Expandierte Einkaufs-Items sitzen im selben Rahmen und nutzen den geteilten listRow-Baustein (runder Haken
   als leadingControl · Titel + 2. Zeile · Menge als grauer Wert-Text vor der Chevron). Kein eigenes Item-CSS. */

/* ── US #297: Farbe als Listen-Attribut — segmented [Auto | Manuell] + 4×4-Flyout ────────────────────
   „Manuell" trägt einen Swatch der aktuellen Farbe und ist selbst der Auslöser (Tap → Flyout unter der Pille). */
.segmented__btn--manual {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.segmented__swatch {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 auto;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
/* 4×4-Palette im Flyout (schwebendes Kärtchen wie beim Kompass): kompaktes Raster mit festen Swatches;
   gewählte Farbe = Ring + Haken (nicht „gefüllt", das Swatch ist schon farbig). */
.color-flyout {
  padding: 12px;
}
.color-grid {
  display: grid;
  grid-template-columns: repeat(4, 42px);
  gap: 12px;
}
.color-swatch {
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.color-swatch__tick {
  color: #fff;
  opacity: 0;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45));
}
.color-swatch--on {
  box-shadow: 0 0 0 3px var(--c-surface), 0 0 0 5px var(--c-ink);
}
.color-swatch--on .color-swatch__tick {
  opacity: 1;
}

/* Icon-Attribut je Listen-Eintrag (US #302) — Auslöser = PILLE RECHTS (wie das Auto/Manuell-Segmented,
   PO 2026-07-11): aktuelles Icon + Chevron. Tap öffnet das SCROLLBARE Flyout mit allen Register-Icons. */
.ffield--icon .iconpick {
  margin-left: auto; /* rechtsbündig wie das Segmented darunter */
}
.iconpick {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 4px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  cursor: pointer;
  background: var(--c-bg);
  color: var(--c-ink);
}
/* Das gewählte Icon in einer kleinen weißen Pille (PO 2026-07-11), analog zum Farb-Swatch im colorField. */
.iconpick__badge {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 24px;
  border-radius: 999px;
  background: #fff;
  color: #1c2733; /* dunkles Icon auf Weiß, hell/dunkel-fest */
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.iconpick__chevron {
  color: var(--c-muted);
}
.icon-flyout {
  padding: 12px;
  max-height: min(58vh, 420px); /* Flyout scrollt, damit ALLE Icons erreichbar sind (PO 2026-07-11) */
  overflow-y: auto;
}
.icon-grid {
  display: grid;
  grid-template-columns: repeat(4, 44px);
  gap: 10px;
}
.icon-swatch {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: var(--c-ink);
  background: var(--c-chip, rgba(127, 127, 127, 0.14));
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.icon-swatch--on {
  box-shadow: 0 0 0 2px var(--c-surface), 0 0 0 4px var(--c-accent, #2f9fb8);
}

/* Vertical stack with the standard gap — for detail pages that group several cards under one body
   element (so the cards keep the same spacing as direct .detail__body children). */
.stack {
  display: grid;
  /* Spalte auf die Containerbreite kappen (wie .detail__body): sonst wächst die implizite auto-Spalte
     auf max-content der Eingabefelder → Formularzeilen liefen rechts über den Rand (iPhone, #156-Muster). */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
}

/* Higher specificity than today.css `.card { padding:16px }` (which loads later) so grouped cards
   really have no inner padding — otherwise the first/last rows look taller than the middle (#125). */
.card.settings-card {
  padding: 0;
  overflow: hidden;
}

.settings-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  /* Uniform height + spacing across every migrated settings/import/export/Törn list (#125). Kompakter
     (PO 2026-07-04): kleinere Schrift + engere Zeilen, damit mehr auf den Schirm passt. */
  min-height: 41px;
  padding: 8px 16px;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 1rem;
  text-align: left;
  cursor: pointer;
  position: relative;
}

/* iOS inset separator (#125, IMG_1825): the hairline starts at the label (past the leading icon)
   and runs continuously to the right edge — not full-bleed, not too short. Drawn as ::after so the
   inset can differ for icon vs. icon-less rows; the last row in a card has none. */
.settings-row:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 16px;
  right: 0;
  bottom: 0;
  border-bottom: 1px solid var(--c-border);
}

.settings-row:has(.settings-row__icon):not(:last-child)::after {
  left: 48px;
}

.settings-row:hover {
  background: var(--c-bg);
}

/* Statische Kennzahl-Zeile (US #309, Bank/Bargeld): kein Tap-Verhalten — kein Zeiger, kein Hover. */
.settings-row--static {
  cursor: default;
}
.settings-row--static:hover {
  background: transparent;
}

/* US #309 Rev6.1: Donut oben im Kontostand-Accordion, Waage-Icon im Gruppenkopf, feste divergingBar-Breite. */
.kitty-donut {
  padding: 12px 16px 8px;
}
/* Trennstrich zwischen Donut-Legende und der Bank-Zeile (PO 2026-07-13) — nur wenn Bank/Bargeld folgen
   (bei normaler Crew ist der Donut das letzte Element → kein hängender Strich). */
.kitty-donut:not(:last-child) {
  border-bottom: 1px solid var(--c-border);
}
.accordion__icon {
  flex: 0 0 auto;
  color: var(--c-muted);
}
/* Name/verdict wächst/schrumpft; der Balken hat FESTE Breite und sitzt (dahinter nur die Chevron) bei ALLEN
   Zeilen links/rechts bündig — auch im Familien-Kopf (.accordion__head--card). Höhere Spezifität als
   .chart-bar__track (today.css), damit das feste flex greift. */
.saldo-row .saldo-row__text {
  flex: 1 1 auto;
  min-width: 0;
}
.saldo-row .saldo-row__bar,
.accordion__head--card .saldo-row__bar {
  flex: 0 0 40%;
  margin: 0 6px;
}

/* US #302 Teil 4: Marker-Token in den gepflegten Listen (Liste = Karte). Farbe+Icon = farbiger runder
   Marker mit weißem Icon (Mini-Vorschau des Kartenmarkers); nur Farbe (Einkaufskat/Familien) = Farbpunkt. */
.list-marker {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: #fff;
}
.list-marker__icon {
  color: #fff;
}
.list-marker--dot {
  width: 15px;
  height: 15px;
}
/* Ausgeblendete Art (nicht auf Karte): Token leicht abgedunkelt (US #302 Teil 4). */
.list-marker--dim {
  opacity: 0.45;
}

.settings-row__icon {
  flex: 0 0 auto;
  color: var(--c-muted);
}

.settings-row__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.settings-row__label {
  font-weight: 500;
  line-height: 1.25;
  /* Keep rows single-line so every row is the same height (#125). */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.settings-row__sub {
  font-size: 0.8rem;
  color: var(--c-muted);
}

.settings-row__chevron {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--c-muted);
}

/* iOS-style form fields (ADR-0029 / #143) — inline label · input fills · clear-×, in grouped cards. */
.ffield {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  /* Kompakter (PO 2026-07-04): kleinere Schrift + engere Zeilen. */
  min-height: 47px;
  padding: 6px 16px;
  font-size: 1rem;
  border: none;
  border-bottom: 1px solid var(--c-border);
  background: transparent;
}
/* Schriftgröße auch bei den Tap-Feldern (pickerField/dateField) und Werten/Eingaben erzwingen — dort
   zog die .ffield-Größe nicht überall durch (PO 2026-07-04). */
.ffield__label,
.ffield__value,
.ffield__input,
.ffield--tap {
  font-size: 1rem;
}

.ffield:last-child {
  border-bottom: none;
}

/* Swap-Slot: ein Feld, das zur Laufzeit gegen eine Variante getauscht wird (z. B. das Listen-Datum, das
   zwischen manueller Auswahl und „vom Wegpunkt" umschaltet, US #315). Der Wrapper macht die innere .ffield
   zum :last-child → die Trennlinie fiele fälschlich weg. Border wiederherstellen — außer der Slot ist WIRKLICH
   das letzte Feld der Gruppe. */
.ffield-group > .ffield-swap > .ffield {
  border-bottom: 1px solid var(--c-border);
}
.ffield-group > .ffield-swap:last-child > .ffield {
  border-bottom: none;
}

.ffield--stacked {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}
/* NUR gestapelte Segment-Pillen rechtsbündig statt volle Breite (Slider/Multiline bleiben voll!) —
   dürfen bei vielen Optionen auf 2 Zeilen umbrechen (PO 2026-07-04). */
.ffield--stacked:has(.segmented) {
  align-items: flex-end;
}
.ffield--stacked:has(.segmented) .ffield__label--top {
  align-self: flex-start;
}
.ffield--stacked .segmented {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.ffield__label {
  flex: 0 0 38%;
  max-width: 150px;
  min-width: 0;
  /* Dark + medium so every form label reads the same weight as the value-row/picker labels (PO 2026-07-01). */
  color: var(--c-ink);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* pickerField — a select rendered as a tappable .ffield row (opens the picker page). */
.ffield--tap {
  width: 100%;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.ffield__value {
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  color: var(--c-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ffield__label--top {
  flex: none;
  max-width: none;
}

.ffield__control {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.ffield__input {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  border: none;
  background: none;
  padding: 6px 0;
  font: inherit;
  color: var(--c-ink);
  text-align: right;
}

.ffield__input:focus {
  outline: none;
}

select.ffield__input {
  text-align-last: right;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}

.ffield__input--multiline {
  /* Borderless like the single-line field (ADR-0029 2026-06-29 / #192) — only the shared row
     separator divides fields, no box/contour around the textarea. */
  text-align: left;
  resize: vertical;
  border: none;
  padding: 6px 0;
}

.ffield__clear {
  flex: 0 0 auto;
  display: none;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: none;
  border-radius: 50%;
  background: var(--c-muted);
  color: var(--c-surface);
  cursor: pointer;
}

.ffield__chevron {
  flex: 0 0 auto;
  color: var(--c-muted);
}

.ffield-help {
  /* Hugs the group above (small top gap, like iOS group footers, IMG_1929). */
  margin: 4px 16px 2px;
  font-size: 0.8rem;
  color: var(--c-muted);
}

/* Toggle (Schiebeschalter) + Slider — shared form controls (ADR-0032). */
.ffield__label--grow {
  flex: 1 1 auto;
  max-width: none;
}
.switch {
  position: relative;
  flex: 0 0 auto;
  display: inline-block;
  /* An die Segment-Pille angeglichen (PO 2026-07-05): gleiche Höhe, breiterer Schieber. Breite an den
     30px-Knopf angepasst → je 3px Rand, Schiebeweg 22px passt genau. */
  width: 58px;
  height: 30px;
}
.switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}
.switch__track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--c-border);
  transition: background 0.15s ease;
}
.switch input:checked + .switch__track {
  background: var(--c-accent);
}
.switch__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  /* Breiterer, pillenförmiger Schieber (wie ein Segment-Knopf) statt kleiner Kreis. */
  width: 30px;
  height: 24px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  transition: transform 0.15s ease;
  pointer-events: none;
}
.switch input:checked ~ .switch__knob {
  transform: translateX(22px);
}
/* Ausgegrauter Schalter-Platzhalter (AB#264 §C „Nach Nutzung sortieren", Funktion folgt): sichtbar,
   aber nicht bedienbar — Zeile gedimmt, kein Zeiger/Klick. */
.ffield--disabled {
  opacity: 0.5;
}
.ffield--disabled .switch input {
  cursor: default;
  pointer-events: none;
}
.ffield__sliderhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.ffield__slidervalue {
  color: var(--c-muted);
  font-variant-numeric: tabular-nums;
}
/* Slider + range slider (ADR-0032) — ONE identical look; only the thumbs catch the pointer. */
.slider {
  position: relative;
  height: 28px;
}
.slider--single .slider__input {
  pointer-events: auto;
}
.slider__track {
  position: absolute;
  top: 12px;
  left: 0;
  right: 0;
  height: 5px;
  border-radius: 999px;
  background: var(--c-border);
}
.slider__fill {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--c-accent);
}
.slider__input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 28px;
  margin: 0;
  background: none;
  -webkit-appearance: none;
  appearance: none;
  pointer-events: none;
}
.slider__input::-webkit-slider-runnable-track {
  background: none;
}
.slider__input::-moz-range-track {
  background: none;
}
.slider__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--c-border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
  pointer-events: auto;
}
.slider__input::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--c-border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
  pointer-events: auto;
}

/* Picker page (ADR-0032) — a select opens a full-screen option list instead of a dropdown.
   Self-contained (own header + body) so the card radius is fully controlled here. */
.picker-overlay {
  /* Start below the app bar (and, on desktop, right of the sidebar) so the header + left menu stay
     visible — a full inset:0 overlay hid the whole app shell (PO 2026-07-01). */
  position: fixed;
  /* Direkt unter der Kopfleiste UND dem global angehefteten Meldungsbalken einrasten — dieselbe Formel
     wie detail__header (AB#207/#243). Zuvor fehlte `--notice-h`, wodurch die „‹"-Zeile bei aktiver Meldung
     nicht bündig unter dem Header saß und die Vorseite oben durchscheinen konnte. */
  top: calc(var(--appbar-h) + env(safe-area-inset-top) + var(--notice-h, 0px));
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  background: var(--c-bg);
}
@media (min-width: 900px) {
  .picker-overlay {
    left: var(--sidebar-w);
  }
}
/* Tab strip that scrolls horizontally instead of wrapping (scoped: doesn't touch filter .chips). */
.tabscroll {
  overflow-x: auto;
  margin-bottom: 10px;
  scrollbar-width: none;
  /* US 2026-07-11: NATIVER Touch-Scroll übernimmt horizontal (die Menü-Geste greift auf .tabscroll
     nicht mehr, s. HSWIPE_SEL, darum war er früher „unzuverlässig"). touch-action: auto lässt den
     Browser die Richtung selbst sperren — horizontal scrollt die Pillen, vertikal die Seite. */
  touch-action: auto;
  overscroll-behavior-x: contain;
}
.tabscroll::-webkit-scrollbar {
  display: none;
}

/* Kleiner Karten-Ausschnitt im Wegpunkt-Detail (Scheibe B #266): rundes Kärtchen, Land/Meer erkennbar,
   nicht interaktiv — Tippen öffnet die ganze Karte. */
.wp-minimap {
  height: 180px;
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  background: #dfe6ea; /* neutraler Platzhalter, bis die Kacheln geladen sind */
  /* Leaflet vergibt intern hohe z-index (Panes bis ~700) — die würden beim Hochscrollen ÜBER die sticky
     Kopfleiste (z 20/40) blitzen (PO 2026-07-11, IMG_2082). Eigener Stapel-Kontext (isolation) mit z-index 0
     kapselt alle Karten-Ebenen unter den Header. */
  position: relative;
  z-index: 0;
  isolation: isolate;
}
.wp-minimap .leaflet-container {
  height: 100%;
  width: 100%;
  background: transparent;
}
/* Bedienbarer Ausschnitt (Import-Zuordnung, PO 2026-07-12): höher + Greif-Cursor. */
.wp-minimap--interactive {
  height: 240px;
  cursor: grab;
}
/* In der Zuordnungs-Liste gewählte Zeile grün markieren (PO 2026-07-12), damit die Auswahl sichtbar ist. */
.listrow--chosen {
  background: rgba(31, 122, 61, 0.14);
  box-shadow: inset 3px 0 0 #1f7a3d;
}
/* Farbtupfer der Route-Farbe in der Ansicht (Routen-Detail, PO 2026-07-12). */
.route-color-dot {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid var(--c-border);
  vertical-align: middle;
}
/* Karten-Kopf der Verknüpfen-Seite (PO 2026-07-12): oben die Textzeile (Name · Art · Datum), darunter eine
   BEDIENBARE Karte (Zoom + Verschieben) mit Vollbild-Knopf — hält den Kontext, welcher Wegpunkt verknüpft
   wird. Der Karten-Container kapselt seine Leaflet-Ebenen (isolation) unter der Sticky-Kopfleiste. */
.wp-maphead {
  border-radius: 12px;
  overflow: hidden;
  background: var(--c-card, #fff);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  margin-bottom: 12px;
}
.wp-maphead__cap {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
}
.wp-maphead__captext {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
/* Kopfzeile über der Karte als Chevron-rechts-Knopf → Felder-Seite (PO 2026-07-12). */
.wp-maphead__cap--link {
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.wp-maphead__cap--link:hover {
  background: var(--c-bg);
}
.wp-maphead__chev {
  flex: 0 0 auto;
  color: var(--c-muted, #6b7785);
}
.wp-maphead__name {
  font-weight: 600;
}
.wp-maphead__sub {
  font-size: 0.85em;
  color: var(--c-muted, #6b7785);
}
.wp-headmap {
  height: 240px;
  background: #dfe6ea; /* neutraler Platzhalter bis die Kacheln geladen sind */
  position: relative;
  isolation: isolate;
}
/* Höhen-Umschalter (PO 2026-07-12): aufgeklappt = Quadrat (Höhe = Breite). */
.wp-headmap.wp-headmap--square {
  height: auto;
  aspect-ratio: 1 / 1;
}
/* Chevron-Knopf links neben dem Vollbild-Knopf (identische Optik wie .map-fs-btn). */
.wp-headmap__sq {
  position: absolute;
  top: 10px;
  right: 52px;
  z-index: 500;
  background: var(--c-surface);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
/* Im Vollbild ist der Höhen-Umschalter sinnlos → ausblenden. */
.route-map--fullscreen .wp-headmap__sq {
  display: none;
}
/* US #325: Ortungs-Knopf (Fadenkreuz) links neben dem Höhen-Umschalter — gleiche Optik. */
.wp-headmap__loc {
  position: absolute;
  top: 10px;
  right: 94px;
  z-index: 500;
  background: var(--c-surface);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.wp-headmap .leaflet-container {
  height: 100%;
  width: 100%;
  background: transparent;
}
/* Vollbild-„Sucher": bleibt fest in der Bildschirmmitte, die Karte schiebt sich darunter durch (PO
   2026-07-12). Der große Schatten dimmt dezent den Bereich AUSSERHALB, damit der Ausschnitt heraussticht. */
.wp-headmap__vp {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border: 2px dashed #b3402f;
  border-radius: 4px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.14);
  pointer-events: none;
  z-index: 450;
}
.tabscroll .chips {
  flex-wrap: nowrap;
  width: max-content;
  margin-bottom: 0;
}
.tabscroll .chip {
  flex: 0 0 auto;
}
.picker-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 52px;
  /* KEIN safe-area-inset hier: der Overlay-`top` enthält es bereits — sonst doppelter Versatz und der
     „‹"-Inhalt startet zu weit unten (AB#243). */
  padding: 0 10px;
  background: var(--c-bg);
}
.picker-head__back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px 4px;
  border: none;
  background: none;
  font: inherit;
  font-size: 1.1rem;
  color: var(--c-accent);
  cursor: pointer;
}
.picker-head__close {
  padding: 8px;
  border: none;
  background: none;
  color: var(--c-ink);
  cursor: pointer;
}
.picker-body {
  padding: 8px 16px 24px;
}
.settings-row__check {
  flex: 0 0 auto;
  color: var(--c-accent);
}

/* Media fields (ADR-0032) — square avatar variant, circular crop overlay, Beleg gallery. */
.avatar--square {
  border-radius: var(--radius);
}
.cropper__viewport--circle {
  position: relative;
}
.cropper__viewport--circle::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}
.media-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 12px 16px;
}
.media-thumb {
  position: relative;
  width: 72px;
  height: 72px;
}
.media-thumb__img {
  width: 100%;
  height: 100%;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  object-fit: cover;
}
.media-thumb__del {
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0; /* Button-Default-Padding weg → ✕ mittig */
  line-height: 0;
  border: none;
  border-radius: 50%;
  background: #b3402f; /* rot (PO 2026-07-09), wie .attach__x */
  color: #fff;
  cursor: pointer;
}
.media-add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border: 1.5px dashed var(--c-border);
  border-radius: var(--radius);
  background: none;
  color: var(--c-muted);
  cursor: pointer;
}

/* Inline avatar crop (IMG_1940) — crop happens in place, not in a modal window. */
.avatarfield__cropwrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 6px 0;
}
.avatarfield__crop {
  position: relative;
  width: 240px;
  max-width: 100%;
  height: 240px;
  overflow: hidden;
  background: #000;
  touch-action: none;
}
.avatarfield__crop--circle {
  border-radius: 50%;
}
.avatarfield__crop .cropper__canvas {
  display: block;
  width: 240px;
  height: 240px;
}
.avatarfield__actions {
  display: flex;
  gap: 28px;
}

/* Free rectangle cropper (ADR-0032) — Belege: drag interior to move, edges/corners to resize. */
.rectcropwrap {
  padding: 8px 0;
}
.rectcrop {
  position: relative;
  width: 100%;
  height: min(60vh, 380px);
  overflow: hidden;
  background: #000;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.rectcrop__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}
.rectcrop__box {
  position: absolute;
  box-sizing: border-box;
  touch-action: none; /* Ziehen am Rahmen/Griff scrollt NICHT die Seite dahinter (PO 2026-07-09) */
  border: 1px solid #fff;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
  cursor: move;
}
.rectcrop__h {
  position: absolute;
  touch-action: none; /* Griff-Ziehen scrollt die Seite dahinter nicht (PO 2026-07-09) */
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
}
/* Vergrößerte, unsichtbare Trefferfläche fürs Antippen am Handy (PO iPhone: Griffe waren zu klein zum
   Treffen → jeder Zug wurde zum Verschieben). e.target bleibt der Griff-Span, data-h wird korrekt gelesen. */
.rectcrop__h::before {
  content: "";
  position: absolute;
  inset: -13px;
}
/* Griffe sitzen INNEN am Rahmen (nicht außen): sonst schneidet der Bühnenrand (overflow:hidden) sie ab,
   wenn der Rahmen das ganze Bild füllt → am Handy nicht greifbar (PO 2026-07-10). Innen bleiben sie immer
   sichtbar + antippbar, egal wie groß der Rahmen ist. */
.rectcrop__h--nw {
  left: 0;
  top: 0;
  cursor: nwse-resize;
}
.rectcrop__h--ne {
  right: 0;
  top: 0;
  cursor: nesw-resize;
}
.rectcrop__h--se {
  right: 0;
  bottom: 0;
  cursor: nwse-resize;
}
.rectcrop__h--sw {
  left: 0;
  bottom: 0;
  cursor: nesw-resize;
}
.rectcrop__h--n {
  left: calc(50% - 9px);
  top: 0;
  cursor: ns-resize;
}
.rectcrop__h--s {
  left: calc(50% - 9px);
  bottom: 0;
  cursor: ns-resize;
}
.rectcrop__h--w {
  left: 0;
  top: calc(50% - 9px);
  cursor: ew-resize;
}
.rectcrop__h--e {
  right: 0;
  top: calc(50% - 9px);
  cursor: ew-resize;
}
.rectcrop__actions {
  display: flex;
  justify-content: center;
  gap: 28px;
  padding: 12px 0 4px;
}

/* Coordinates field (ADR-0032) — inline error + read-only (GPS on) state. */
.ffield-help--err {
  color: #b3402f;
}
.ffield--readonly .ffield__input {
  color: var(--c-muted);
}

/* Photo gallery add tile + full-screen viewer (ADR-0025) — grid reuses .gallery-grid/.gallery-tile. */
.gallery-tile--add {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px dashed var(--c-border);
  background: none;
  color: var(--c-muted);
}
.photo-viewer {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  background: #000;
}
.photo-viewer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 52px;
  padding: env(safe-area-inset-top) 8px 0;
}
.photo-viewer__act {
  padding: 10px;
  border: none;
  background: none;
  color: #fff;
  cursor: pointer;
}
.photo-viewer__stage {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
.photo-viewer__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  touch-action: pan-y;
}
.photo-viewer__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  cursor: pointer;
}
.photo-viewer__nav--prev {
  left: 8px;
}
.photo-viewer__nav--next {
  right: 8px;
}
.photo-viewer__foot {
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
}
.photo-viewer__caption {
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font: inherit;
}
.photo-viewer__caption::placeholder {
  color: rgba(255, 255, 255, 0.6);
}

/* Document file field (ADR-0032) — image thumbnail OR PDF icon + name + open link. */
.filefield__control {
  justify-content: flex-end;
}
.filefield__preview {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px 12px;
}
.filefield__img {
  width: 72px;
  height: 72px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  object-fit: cover;
}
.filefield__icon {
  flex: 0 0 auto;
  color: var(--c-muted);
}
.filefield__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filefield__open {
  margin-left: auto;
  color: var(--c-accent);
}

/* Date/time picker-style field (ADR-0032) — transparent native input overlays the row (tap = picker). */
.ffield--date {
  position: relative;
}
.ffield__dateinput {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  opacity: 0;
  cursor: pointer;
}

/* Round checkbox (ADR-0032) — multi-select / "erledigt" tick. */
.ffield--check {
  cursor: pointer;
}
.check__input {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
}
.check__box {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: 1.5px solid var(--c-border);
  border-radius: 50%;
  color: transparent;
}
.check__input:checked + .check__box {
  border-color: var(--c-accent);
  background: var(--c-accent);
  color: #fff;
}
/* Standalone round checkbox control (checkbox()) — e.g. a listRow leadingControl. */
.check-lead {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* Segmented control (ADR-0032) — 2–3 inline choices, active segment raised (iOS style). */
/* Passen Label + Pillen nicht in eine Zeile (z. B. Status: Offen·Angefragt·Bestätigt), brechen die
   Pillen auf eine 2. Zeile um (rechtsbündig) statt über den rechten Rand zu ragen (PO 2026-07-05). */
.ffield--segmented {
  flex-wrap: wrap;
}
/* 2-Zeilen-Umbruch NUR nach tatsächlicher Breite (AB#206): Label in natürlicher Breite (nicht auf die
   festen 38% fixiert) + Segmented als Ganzes nicht schrumpfend → flex-wrap schiebt die Pille erst auf
   Zeile 2, wenn Label + Pille real nicht nebeneinander passen — unabhängig von der Anzahl der Optionen. */
.ffield--segmented .ffield__label {
  flex: 0 0 auto;
  max-width: none;
}
.ffield--segmented .segmented {
  flex: 0 0 auto;
  margin-left: auto;
}
.segmented {
  display: inline-flex;
  flex: 0 1 auto;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--c-bg);
}
.segmented__btn {
  padding: 4px 14px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--c-muted);
  font: inherit;
  /* Begrenzte Zeilenhöhe, damit die Pillen-Zeile nicht höher wird als normale Feldzeilen (PO 2026-07-04). */
  line-height: 1.15;
  white-space: nowrap;
  cursor: pointer;
}
.segmented__btn--on {
  background: var(--c-surface);
  color: var(--c-ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}
/* Icon-Pillen-Feld (US #287 Rev9): Label oben, Pillen darunter über die volle Breite; viele Pillen dürfen
   auf eine 2. Zeile umbrechen (PO 2026-07-09). */
/* Wie seaStateField/.ffield--segmented (PO 2026-07-09): Label links, Pille RECHTS (margin-left:auto),
   inhaltsbreit; passt Label+Pille nicht in eine Zeile → Pille bricht auf Zeile 2 (rechtsbündig). */
.ffield--icons {
  flex-wrap: wrap;
}
.ffield--icons .ffield__label {
  flex: 0 0 auto;
  max-width: none;
}
.segmented--icons {
  display: inline-flex;
  flex: 0 1 auto; /* nur so breit wie die inneren Pillen brauchen */
  flex-wrap: nowrap; /* US #299: wie seaStateField/cloudField — NICHT umbrechen, bei Überlauf scrollen */
  margin-left: auto; /* nach rechts schieben */
  justify-content: flex-end;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.segmented--icons::-webkit-scrollbar {
  display: none;
}
.segmented__btn--icon {
  padding: 3px 6px; /* exakt wie .segmented__btn--okta (seaStateField), PO 2026-07-09 */
  display: inline-flex;
  align-items: center;
}
/* Leeres Pflicht-Metadatenfeld (US #287 Rev18): orange Sternchen am Label — nicht-blockierender Marker. */
.meta-row--req .ffield__label::after,
.meta-row--req .settings-row__label::after {
  content: " *";
  color: #e0a458;
  font-weight: 700;
}
/* Noch nicht verdrahtete Maßeinheiten (Muster IMG_2008): ausgegraut + nicht bedienbar. */
.segmented__btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Theme selector (ADR-0032, IMG_1929) — one list card; no tile/preview frame (soft shadow so the
   white "Tag" mock stays visible); phone-shaped previews; radio-style round checks. */
.theme-card {
  padding: 12px;
  border-bottom: 1px solid var(--c-border);
}
/* Im Showcase liefert bereits `.spec__ctl` eine border-bottom als Zeilentrenner — die eigene der
   `.theme-card` würde sich dazu addieren (2px, „zu dick"). Dort also unterdrücken; auf der echten
   Anzeige-Seite (kein spec__ctl) bleibt die border-bottom die einzige, 1px dünne Trennlinie. */
.spec__ctl .theme-card {
  border-bottom: none;
}
/* Automatik AN → nur die Checkboxen deaktiviert; die Vorschau-Icons bleiben voll sichtbar, und der
   aktive Haken wechselt von Blau auf Grau statt alles abzudunkeln (PO 2026-07-05). */
.theme-card--locked .theme-tiles {
  pointer-events: none;
}
.theme-card--locked .theme-tile--active .theme-tile__check {
  border-color: var(--c-muted);
  background: var(--c-muted);
}
.theme-tiles .theme-tile {
  border: none;
  background: none;
  padding: 4px;
}
.theme-tiles .theme-tile--active {
  border-color: transparent;
}
.theme-tiles .theme-prev {
  justify-content: flex-start;
  border: none;
  border-radius: 14px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}
.theme-tile__check {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin: 2px auto 0;
  border: 1.5px solid var(--c-border);
  border-radius: 50%;
  background: transparent;
  color: transparent;
}
.theme-tile--active .theme-tile__check {
  border-color: var(--c-accent);
  background: var(--c-accent);
  color: #fff;
}

/* A value row that doesn't navigate (no chevron, no hover/press). */
.settings-row--static {
  cursor: default;
}

/* (The in-card Bordkasse search #142 was removed — the single header search drives lists now #151.) */
.settings-empty {
  padding: 14px 16px;
}

/* Trailing grey value on a settings/drill row — Bordkasse totals (#136) and the hub value rows
   (Profil/Sprache/Anzeige/Törn/Boot/Crew/Über, #149). Single-line + ellipsis so it never wraps a
   row taller than the rest (#125). */
.settings-row__value {
  /* The value truncates first so it can NEVER squeeze/cut the title (#167): capped width + it
     shrinks before the label (which keeps flex: 1). */
  flex: 0 1 auto;
  min-width: 0;
  max-width: 55%;
  color: var(--c-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Net settlement figure on a Bordkasse member row (gets back / pays in). */
.exp-net {
  font-size: 0.85rem;
}

.exp-net--pos {
  color: #1f7a3d;
}

.exp-net--neg {
  color: #b3402f;
}

.settings-row--danger,
.settings-row--danger .settings-row__icon {
  color: #b3402f;
}

.settings-row--inline,
.settings-row--inline:hover {
  cursor: default;
  background: transparent;
}

/* Erscheinung — three Tag/Dämmerung/Nacht preview tiles (mini-mockup + label, ADR-0024 §9 / #118). */
.theme-tiles {
  display: flex;
  gap: 10px;
}

.theme-tile {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px;
  border: 2px solid var(--c-border);
  border-radius: 12px;
  background: var(--c-surface);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.theme-tile--active {
  border-color: var(--c-accent);
}

.theme-tile__label {
  font-size: 0.82rem;
}

.theme-prev {
  width: 100%;
  aspect-ratio: 16 / 10;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  padding: 8px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.theme-prev__bar {
  display: block;
  height: 5px;
  border-radius: 3px;
}

/* Profile header — large avatar with a pencil/camera badge (ADR-0024 §9 / #118). */
.profile-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 12px 0 4px;
}

.avatar-wrap {
  position: relative;
  display: inline-block;
}

.avatar-badge {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}

.profile-head__name {
  font-size: 1.3rem;
  font-weight: 600;
}

.profile-head__meta {
  color: var(--c-muted);
}

/* avatarField als Personen-Kopf (ADR-0032 / #56): zentrierte Spalte, optional Name + Rolle darunter,
   optionaler Bleistift-Badge unten links (Kamera bleibt unten rechts). */
.avatarfield {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.avatarfield__name {
  font-size: 1.3rem;
  font-weight: 600;
}
.avatarfield__role {
  color: var(--c-muted);
}

/* Inline Tag / Dämmerung / Nacht segmented control (Erscheinung). */
.seg {
  display: inline-flex;
  margin-left: auto;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  overflow: hidden;
}

.seg__btn {
  padding: 6px 10px;
  border: none;
  border-left: 1px solid var(--c-border);
  background: var(--c-surface);
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.seg__btn:first-child {
  border-left: none;
}

.seg__btn--active {
  background: var(--c-accent);
  color: var(--c-accent-ink);
}

/* (Removed the iOS-only `-webkit-fill-available` height override: it applies ONLY in iOS Safari
   (-webkit-touch-callout is iOS-only), and there it broke the flex column — the pinned avatar
   footer floated mid-drawer and the lower module rows were clipped, while Chrome/Android (which
   ignores the @supports) was fine. Modern iOS (16+) handles the dynamic toolbar via 100dvh above.) */

.sidebar--open {
  transform: translateX(0);
}

.sidebar__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--c-ink);
  font-size: 1rem;
}

/* Unread badge (#63): number-in-a-circle, accent colour */
.nav-badge {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  border-radius: 999px;
  background: #b3402f;
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.nav-badge--hidden {
  display: none;
}

/* Per-row unread dot (#63, lifetime #99) — iOS-Messages style: an accent dot + a small left indent
   on a list row that changed since the user last left the section. Both persist for the whole visit
   (a deliberate "this just changed" hint) and are cleared on the next entry. The row reserves the
   inset so the dot never clips (lists sit in cards AND directly in .module). */
.unread-row {
  position: relative;
  padding-left: 16px;
}

.unread-row::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: var(--c-accent);
}

/* Central quick-create FAB in the bottom nav (ADR-0024 §2/§3, #111) — raised accent circle. */
.botnav__create {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  /* Protrude further above the top edge of the bar (PO liked the FAB sticking out). */
  margin: -28px 10px 0;
  border: none;
  border-radius: 50%;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.32);
  cursor: pointer;
}

.botnav__create:active {
  transform: scale(0.96);
}

/* Grau/disabled ＋ (ADR-0024 §3 / #236): Screens ohne Anlege-Aktion zeigen dasselbe ＋, nur gedämpft
   und nicht klickbar — KEIN eigenes Verbotssymbol. Gilt für Bottom-Nav und Sidebar. */
.botnav__create[aria-disabled="true"],
.sidebar__create[aria-disabled="true"] {
  opacity: 0.38;
  box-shadow: none;
  cursor: default;
  pointer-events: none;
}

/* Bottom action sheet (quick-create, #111/#112) */
.sheet-wrap {
  position: fixed;
  inset: 0;
  z-index: 1300;
}

.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 80vh;
  overflow-y: auto;
  padding: 4px 16px calc(16px + env(safe-area-inset-bottom));
  background: var(--c-surface);
  color: var(--c-ink);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.3);
  transform: translateY(100%);
  transition: transform 0.25s ease;
}

.sheet-wrap--open .sheet-backdrop {
  opacity: 1;
}

.sheet-wrap--open .sheet {
  transform: translateY(0);
}

.sheet__handle {
  width: 40px;
  height: 4px;
  margin: 8px auto 12px;
  border-radius: 2px;
  background: var(--c-border);
}

.sheet__title {
  margin: 0 0 10px;
  font-size: 1.1rem;
}
/* Kurzer Hinweistext unter dem Sheet-Titel (PIN-/Bestätigen-Dialog). */
.sheet__hint {
  margin: 0 0 12px;
  color: var(--c-muted);
  font-size: 0.9rem;
}
/* Roter „Löschen"-Knopf im Tipp-zum-Bestätigen-Dialog (US #300). */
.btn--danger {
  background: #b3402f;
  border-color: #b3402f;
  color: #fff;
}

.sheet__actions {
  display: grid;
  gap: 2px;
}

/* Reminder picker (#172) — datetime input above the action buttons. */
.remind-field {
  padding: 4px 0 14px;
}
.remind-field .remind-input {
  width: 100%;
}

.sheet__action {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 14px 8px;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--c-ink);
  font: inherit;
  font-size: 1rem;
  text-align: left;
  cursor: pointer;
}

.sheet__action:hover {
  background: var(--c-bg);
}

.sheet__action--primary {
  background: var(--c-bg);
  font-weight: 600;
}

.sheet__action-icon {
  flex: 0 0 auto;
  color: var(--c-accent);
}

/* Nachricht center connection state (#114) */
.notif-state--live {
  color: #1f7a3d;
  font-weight: 600;
}

.notif-state--poll {
  color: #a4571a;
}

.notif-state--offline {
  color: var(--c-muted);
}

/* Swipe-to-act list rows (ADR-0024 §4 / #113): tap = edit, swipe-left = delete, swipe-right = done.
   The content pane slides to reveal the coloured action behind it. */
.swipe {
  position: relative;
  overflow: hidden;
  list-style: none;
}

.swipe__bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: 0 20px;
  color: #fff;
  opacity: 0;
}

.swipe__bg--delete {
  justify-content: flex-end;
  background: #b3402f;
}

.swipe__bg--done {
  justify-content: flex-start;
  background: #1f7a3d;
}

/* Crew "swipe right to call" (#137 follow-up): blue when a number exists, greyed when it doesn't. */
.swipe__bg--call {
  background: #2f6fb0;
}

.swipe__bg--call-off {
  background: var(--c-muted);
}

/* Öffnen/Schreiben (Link/E-Mail per Rechts-Wisch, AB#225): Akzentfarbe, damit das weiße Icon sichtbar
   ist (ohne Farbklasse hat der Lead-Knopf keinen Hintergrund → weißes Icon unsichtbar). */
.swipe__bg--open {
  background: var(--c-accent);
}

/* Distinkte Farben je Wisch-Aktion (AB#272 §4): Link = Violett/Indigo, E-Mail = Orange — vom Telefon-Blau
   und Check-Grün klar abgegrenzt, in allen Anzeige-Modi. */
.swipe__bg--link {
  background: #6a4fbf;
}
.swipe__bg--mail {
  background: #c8791c;
}
/* US #300: „Entsperren"-Wisch (Lösch-Aktionen) — amberfarben (Achtung/Freigabe), lock-open-Icon. */
.swipe__bg--lock {
  background: #b8860b;
}
/* „Ersetzen" (Bild/Beleg/… per Rechts-Wisch, #278): einheitliches Teal für ALLE Anhang-Ersetzen-Gesten. */
.swipe__bg--replace {
  background: #177f80;
}

/* Generisches Ausgrauen eines Lead-Knopfes (AB#225): NACH allen Farbklassen definiert, damit es sie
   überschreibt — so lässt sich per Toggle jede Wisch-Aktion ausgrauen (leeres Feld → No-op). */
.swipe__bg--off {
  background: var(--c-muted);
}

/* UI-Text NICHT markierbar (AB#225 §7 / AB#262): Zeilen/Kacheln/Chips/Labels lassen sich weder am PC
   noch am iPhone versehentlich selektieren. Echte Eingaben (input/textarea) bleiben natürlich markierbar. */
.listrow,
.swipe__content,
.tile,
.chip,
.settings-row,
.sheet__action,
.ffield__label,
.ffield__value,
.eta {
  -webkit-user-select: none;
  user-select: none;
}
input,
textarea,
[contenteditable="true"] {
  -webkit-user-select: text;
  user-select: text;
}

/* Bordkasse lock/unlock (Kassier swipe-right, ADR-0018 / #150): amber. */
.swipe__bg--lock {
  background: #8a6d3b;
}

.swipe__content {
  position: relative;
  background: var(--c-surface);
  /* Let vertical scroll through while we capture horizontal swipes. */
  touch-action: pan-y;
  cursor: pointer;
  z-index: 1; /* over the revealed action buttons */
}

/* Right-aligned action buttons revealed by a partial swipe-left (ADR-0031 §1 / #168). Wie .swipe__lead
   im Ruhezustand auf 0 Breite eingeklappt (nicht nur von der Zeile verdeckt): sonst lugt der Streifen
   beim VOLLEN Rechts-Wisch am rechten Rand hervor, sobald die Zeilenfläche über seine linke Kante zieht
   (er stapelt via Quellreihenfolge über dem Lead-Streifen → das 🗑 blitzte durch, AB#272). Die Breite
   wird beim Aufdecken explizit gesetzt (openActions / Links-Wisch-Drag), close() klappt sie zurück. */
.swipe__actions {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  width: 0;
  overflow: hidden;
}

/* Leading action revealed by a swipe-right (partial = held & tappable; toggle erledigt). Grows with
   the drag; the colour comes from the caller's rightClass (.swipe__bg--done/--call/--lock). */
.swipe__lead {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  display: flex;
  width: 0;
  overflow: hidden;
}
/* Selektoren mit .swipe__action verschränkt (höhere Spezifität), sonst überschreibt die WEITER UNTEN
   stehende Regel `.swipe__action { flex: 0 0 64px }` diese hier bei gleicher Spezifität via Quell-
   reihenfolge — dann bleibt der Primär-Knopf fix und streckt sich NICHT (AB#272-Regression). */
.swipe__action.swipe__lead-btn {
  flex: 0 0 64px; /* mehrere Lead-Icons nebeneinander (AB#272): feste Breite je Knopf */
}
/* Die PRIMÄRE (erste) Lead-Aktion streckt sich mit dem Zug und hält ihr Icon an der äußeren Kante —
   Parität zum Löschen beim Links-Wisch (AB#272 §1). */
.swipe__action.swipe__lead-btn--primary {
  flex: 1 0 64px;
  justify-content: flex-start;
  padding-left: 22px;
}

.swipe__action {
  flex: 0 0 64px;
  border: none;
  display: inline-flex;
  align-items: center;
  /* As the row is dragged past the buttons, the outermost (delete) stretches to fill, so keep its
     icon pinned to the right where the finger is, not centred in the growing area (IMG_1856). */
  justify-content: center;
  color: #fff;
  cursor: pointer;
  overflow: hidden;
}

.swipe__action--more {
  background: #6b7280;
}

/* The outermost action stretches with the drag (full-swipe affordance, ADR-0031 §1 / IMG_1856). */
.swipe__action--delete {
  flex: 1 0 64px;
  background: #b3402f;
  justify-content: flex-end;
  padding-right: 22px;
}

/* Pushed detail / edit page chrome (ADR-0024 §4 / #113 / #118) — "‹ Titel" drill-up on the left,
   ✕ exit + Save-on-change on the right. Sticky (ADR-0027 §6): pinned just below the app bar while
   the body scrolls, so ‹ is reachable at any scroll position. */
/* The pushed page itself. Two reasons it overrides `.module` (selector is `.module.detail` so it
   wins by specificity regardless of stylesheet order):
   1. `overflow: visible` — `.module` sets `overflow-x: hidden`, which forces `overflow-y` to `auto`
      and makes it a scroll container; that traps `position: sticky` so the chrome bar pins to the
      module instead of the viewport (i.e. never stays under the app bar). Visible un-traps it.
   2. flex column, NOT the `.module` grid — a sticky header inside a grid is constrained to its
      1-row grid area (it can't pin and bleeds over the list). Flex lets the header truly stick.
   Pull the page up by the outlet's top padding so the chrome bar sits flush beneath the app bar. */
.module.detail {
  display: flex;
  flex-direction: column;
  /* Das Modul selbst clippt NICHT — der horizontale Überlauf wird am `.detail__body` gekappt (s. u.).
     WICHTIG: `.module` (today.css) setzt `overflow-x: hidden`; das würde den randlosen Meldungs-Balken
     abschneiden. Höhere Spezifität (.module.detail) hebt es hier auf, damit der Balken bis zum Rand ragt. */
  overflow-x: visible;
  margin-top: calc(-1 * var(--gap));
}

.detail__body {
  display: grid;
  /* Kappt breite Zeilen horizontal (das Modul clippt nicht mehr, s. o.). Der Body ist inhaltshoch,
     daher kappt das erzwungene vertikale Clip nichts — die Seite scrollt normal weiter. */
  overflow-x: clip;
  /* Pin the single column to the container width: a default `auto` track grows to its content's
     max-content size, so a wide row (long value/title) pushed the cards past the right edge
     (IMG_1831). minmax(0,1fr) caps it at the viewport and lets children shrink + ellipsize (#156). */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
}

/* Grid/flex children won't shrink below content width by default → a long unbroken value pushes the
   page wider than the screen. min-width:0 lets them shrink so ellipsis truncation kicks in (#156). */
.detail__body > * {
  min-width: 0;
}

.detail__header {
  position: sticky;
  /* Unter dem global angehefteten Meldungsbalken einrasten (AB#207): dessen Höhe kommt aus --notice-h
     (0, wenn kein Balken sichtbar ist). */
  top: calc(var(--appbar-h) + env(safe-area-inset-top) + var(--notice-h, 0px));
  z-index: 20;
  /* Spalte: obere Zeile (‹ zurück · Aktionen) + darunter der Meldungs-Balken — beide sticky, damit der
     Balken immer voll sichtbar unter der Rücknavigation bleibt. Solider Hintergrund deckt scrollende
     Listenzeilen darunter ab. Der Abstand nach unten kommt aus dem Flex-`gap` von .module. */
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 8px 0;
  background: var(--c-bg);
}
.detail__toprow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
/* Der Balken bricht randlos aus dem Seiten-Padding aus (volle Breite). Kein negativer Rand nach unten —
   der würde den ersten Inhalt (Kontostand) überlagern. */
.detail__header > .notice-bar {
  margin: 0 calc(-1 * var(--gap));
}

.detail__actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
}

.detail-act {
  display: inline-flex;
  padding: 6px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--c-ink);
  line-height: 0;
  cursor: pointer;
}

.detail-act:hover {
  background: var(--c-bg);
}

.detail-act--save {
  color: var(--c-accent);
}

/* Eingeschalteter Toggle in der Kopfzeile (z. B. „Bearbeiten"-Stift, AB#209): Akzent + gefüllter Grund. */
.detail-act--on {
  color: #fff;
  background: var(--c-accent);
}
.detail-act--on:hover {
  background: var(--c-accent);
}

.detail-back {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 8px 6px 0;
  margin-left: -4px;
  background: none;
  border: none;
  color: var(--c-accent);
  font: inherit;
  font-size: 1.25rem;
  font-weight: 600;
  cursor: pointer;
}

.detail-back__icon {
  flex: 0 0 auto;
}

/* Stale-build self-heal banner (#184) — a deployed update is available but this PWA is still running
   old cached modules. Pinned at the top above everything; one tap unregisters the SW + reloads. */
.update-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: calc(env(safe-area-inset-top) + 8px) 12px 8px;
  background: var(--c-accent);
  color: #fff;
  font-size: 0.9rem;
}

.update-banner__btn {
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 8px;
  padding: 5px 12px;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.detail-back__title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Square photo cropper overlay (#118) — pan + zoom to choose the avatar crop. */
.cropper {
  position: fixed;
  inset: 0;
  z-index: 1300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.72);
}

.cropper__card {
  width: min(360px, 100%);
  background: var(--c-surface);
  color: var(--c-ink);
  border-radius: 14px;
  overflow: hidden;
}

.cropper__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--c-border);
}

.cropper__title {
  font-weight: 600;
}

.cropper__btn {
  display: inline-flex;
  padding: 6px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--c-ink);
  line-height: 0;
  cursor: pointer;
}

.cropper__btn--ok {
  color: var(--c-accent);
}

.cropper__viewport {
  display: flex;
  justify-content: center;
  background: #000;
}

.cropper__canvas {
  width: 320px;
  height: 320px;
  /* Capture drags for panning instead of scrolling the page. */
  touch-action: none;
  cursor: grab;
}

/* Gesture hint replaces the old zoom slider (pan + pinch / wheel now do the zoom). */
.cropper__hint,
.avatarfield__hint {
  padding: 10px 14px 4px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--c-muted);
}

/* Receipt photo on an expense (#120) — capture button + tappable thumbnail in the detail page. */
.receipt-field {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.receipt-thumb {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--c-border);
  cursor: pointer;
}

/* Real-time "N photos pending from <member>" hint (#108) — a transient pill above the bottom-nav. */
.media-hint {
  position: fixed;
  left: 50%;
  bottom: calc(72px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 1200;
  max-width: 90vw;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-size: 0.88rem;
  text-align: center;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}

.sidebar__link .nav-badge {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
}

.botnav__iconwrap {
  position: relative;
  display: inline-flex;
}

.botnav__iconwrap .nav-badge {
  position: absolute;
  top: -6px;
  right: -10px;
}

.sidebar__icon {
  flex: 0 0 auto;
  color: var(--c-muted);
}

.sidebar__link:hover,
.sidebar__link:active {
  background: var(--c-bg);
}

/* Keyboard focus on a drawer item is visible (#186). */
.sidebar__link:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: -2px;
}

/* Active wins over hover (else hover greys out the selected item) */
.sidebar__link--active,
.sidebar__link--active:hover {
  background: var(--c-accent);
  color: var(--c-accent-ink);
}

.sidebar__link--active .sidebar__icon {
  color: var(--c-accent-ink);
}

/* Section header (── An Bord ── / ── Skipper ──) */
.sidebar__section {
  margin: 12px 8px 2px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--c-muted);
}

/* Expandable submenu (Einstellungen) */
.sidebar__group {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  margin-top: 12px;
  border: none;
  background: transparent;
  color: var(--c-ink);
  font: inherit;
  font-size: 1rem;
  text-align: left;
  border-radius: 8px;
  cursor: pointer;
}

.sidebar__group:hover {
  background: var(--c-bg);
}

.sidebar__group .sidebar__icon {
  color: var(--c-muted);
}

.sidebar__chevron {
  margin-left: auto;
  color: var(--c-muted);
  transition: transform 0.18s ease;
}

.sidebar__group-wrap--open .sidebar__chevron {
  transform: rotate(180deg);
}

.sidebar__sub {
  display: none;
  flex-direction: column;
  gap: 2px;
  padding-left: 12px;
}

.sidebar__group-wrap--open .sidebar__sub {
  display: flex;
}

.sidebar__link--sub {
  font-size: 0.95rem;
  padding: 10px 14px;
}

/* Backdrop behind the slide-out menu */
.backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  /* ÜBER Kopfleiste und Fußmenü (beide z 40), damit beim Öffnen/Ziehen des Push-Menüs AUCH Header und
     Fußmenü abgedunkelt werden (wandern zwar mit, wurden aber nicht abgedunkelt). Unter der Sidebar (45). */
  z-index: 42;
}

.backdrop--show {
  opacity: 1;
  pointer-events: auto;
}

/* Reusable tab sub-navigation (00-SailLog-Design-Language → Layout & Mobile Patterns) */
.tabbar {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 4px;
}

.tabbar__tab {
  flex: 0 0 auto;
  border: none;
  background: transparent;
  color: var(--c-muted);
  font: inherit;
  font-size: 0.95rem;
  padding: 10px 12px;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}

.tabbar__tab--active {
  color: var(--c-accent);
  border-bottom-color: var(--c-accent);
  font-weight: 600;
}

/* Content shown below a tab bar */
.tab-panel {
  display: grid;
  gap: var(--gap);
  margin-top: var(--gap);
}

/* Content outlet */
.outlet {
  display: block;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: var(--gap);
}

.muted {
  color: var(--c-muted);
  margin: 0;
}

.error {
  max-width: var(--maxw);
  margin: 24px auto;
  padding: 16px;
  border: 1px solid #e0b4b4;
  background: #fcf0f0;
  color: #7d2b2b;
  border-radius: var(--radius);
}
/* Boot-Absturz-Rettung (weißer Schirm) — sichtbare Meldung + „Cache leeren"-Knopf. */
.error--fatal {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: flex-start;
  margin: 24px 16px;
}
.error--fatal .btn--primary {
  padding: 10px 16px;
  border: none;
  border-radius: 999px;
  background: var(--c-accent);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

/* Transient confirmation toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translate(-50%, 20px);
  background: #1d2733;
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 0.9rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 50;
}

.toast--show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* Undo toast (ADR-0031 §1 / #168): message + a tappable „Rückgängig" action. */
.toast--action {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.toast__action {
  border: none;
  background: none;
  color: #6ab7ff;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  padding: 0;
}

/* Destruktive Aktion in einer Auswahl-Pille (z. B. „Verwerfen", AB#244) — rot statt blau. */
.toast__action--danger {
  color: #ff8a8a;
}

/* Desktop: persistent sidebar, no hamburger, no backdrop. */
/* Mobile bottom quick-nav (00-Design-Language → Bottom quick-nav). Hidden on desktop. */
.botnav {
  display: none;
}

.botnav__link {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 2px;
  text-decoration: none;
  color: var(--c-muted);
  font-size: 0.72rem;
  line-height: 1.1;
}

.botnav__link--active {
  color: var(--c-accent);
  font-weight: 600;
}

/* Active tab = filled icon, not just a recoloured outline (ADR-0024 §2 / #111). */
.botnav__icon--solid {
  display: none;
}

.botnav__link--active .botnav__icon--outline {
  display: none;
}

.botnav__link--active .botnav__icon--solid {
  display: inline-block;
}

@media (max-width: 899.98px) {
  .botnav {
    display: flex;
    align-items: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    /* Promote to its own compositing layer so iOS Safari keeps it pinned to the bottom while a long
       list scrolls (a bare position:fixed bar jitters/lags during the toolbar transition) — #187. */
    transform: translateZ(0);
    will-change: transform;
    /* Taller bar; the labels sit higher so the rounded display corners / home indicator never clip
       the text under the icons (PO 2026-06-27). */
    min-height: 84px;
    background: var(--c-surface);
    border-top: 1px solid var(--c-border);
    /* Extra bottom inset on top of the safe area lifts the labels clear of the rounded corners. */
    padding-bottom: calc(env(safe-area-inset-bottom) + 12px);
    padding-left: max(4px, env(safe-area-inset-left));
    padding-right: max(4px, env(safe-area-inset-right));
  }

  .outlet {
    padding-bottom: calc(116px + env(safe-area-inset-bottom));
  }

}

@media (min-width: 900px) {
  .appbar__menu {
    display: none;
  }

  .appbar__bottom {
    padding-left: 0; /* kein Burger → 2. Zeile bündig mit dem Rand (wie „SailLog") */
  }

  .layout {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    align-items: start;
  }

  .sidebar {
    /* Sticky UNTER Kopfleiste UND Meldungsbalken: ohne `--notice-h` überdeckte die Sidebar beim Scrollen
       den „Neue Version"-Balken (PO 2026-07-10, Bild 2). */
    position: sticky;
    top: calc(var(--appbar-h) + var(--notice-h, 0px));
    transform: none;
    /* dvh statt vh: auf dem iPad ist 100vh das GRÖSSERE Layout-Viewport → der Profil/Settings-Footer fiel
       unter den sichtbaren Rand (PO iPad, IMG_0209). Höhe = sichtbares Viewport − Kopfleiste − Balken. */
    height: calc(100dvh - var(--appbar-h) - var(--notice-h, 0px));
    /* Static in the grid below the sticky app bar — drop the mobile top inset. */
    padding: 16px 12px;
    /* KEIN overflow-y:auto auf der GANZEN Sidebar (das ließ Menü + Footer zusammen scrollen). overflow:hidden
       → nur `.sidebar__links` (flex:1 + eigenes overflow-y:auto) scrollt; ＋ und Profil/Settings-Footer
       bleiben unten GEPINNT (PO: „Profil/Settings immer an gleicher Stelle, nur die Einträge scrollen"). */
    overflow: hidden;
  }

  .backdrop {
    display: none;
  }

  .outlet {
    margin: 0;
  }

  /* ＋ Erstellen shown in the sidebar on desktop/iPad (the bottom-nav ＋ is hidden here) — #191.
     A round FAB pinned at the bottom, just above the avatar/Settings footer, so the quick-create
     sheet opens right below it (no top→bottom finger travel, IMG_0198). */
  .sidebar__create {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    align-self: flex-start;
    width: 48px;
    height: 48px;
    margin: 4px 0 10px;
    border: none;
    border-radius: 50%;
    background: var(--c-accent);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  }

  .sidebar__create:hover {
    filter: brightness(1.05);
  }

  .sidebar__create:active {
    transform: scale(0.96);
  }
}

/* ── Tagesstrecke (day's leg) — ADR-0032 catalog ────────────────────────────────
   Two progress templates: .dayroute (continuous distance bar) + .stagelist (stop
   timeline). Colours use the theme tokens so both stay legible on Tag/Dämmerung/Nacht. */
.dayroute {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Align with the standard row inset (settings-row is 10px 16px) so the card content doesn't hug
     the edge — the .card.settings-card wrapper itself has padding:0. */
  padding: 12px 16px;
}
.dayroute__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
/* Ausklappbare Tagesstrecke: Chevron im Kopf blendet die stageList darunter ein (PO 2026-07-02). */
.dayroute__headright {
  display: flex;
  align-items: center;
  gap: 8px;
}
.dayroute--expandable .dayroute__head {
  cursor: pointer;
}
.dayroute__chevron {
  color: var(--c-muted);
  transition: transform 0.15s ease;
}
.dayroute--open .dayroute__chevron {
  transform: rotate(90deg);
}
.dayroute__detail {
  margin-top: 10px;
}
.dayroute__detail[hidden] {
  display: none;
}
.dayroute__title {
  font-weight: 600;
  color: var(--c-ink);
}
.dayroute__pct {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--c-accent);
}
.dayroute__bar {
  position: relative;
  height: 22px;
  margin: 2px 0;
}
.dayroute__track {
  position: absolute;
  top: 8px;
  left: 0;
  right: 0;
  height: 6px;
  border-radius: 999px;
  background: var(--c-border);
  overflow: hidden;
}
.dayroute__fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  border-radius: 999px;
  background: var(--c-accent);
}
.dayroute__marker {
  position: absolute;
  top: 50%;
  width: 26px;
  height: 26px;
  /* Kein margin-left mehr: der Marker wird per left-Kante positioniert (AB#210), damit er an den
     Balkenenden nicht mehr um seinen Radius übersteht. */
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--c-surface);
  color: var(--c-accent);
  border: 2px solid var(--c-accent);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}
.dayroute__ends {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--c-ink);
}
.dayroute__meta {
  font-size: 0.82rem;
  color: var(--c-muted);
}

/* Vertical stop list — reads as a normal settings list (inset separators), leading dot = progress.
   Row inset mirrors .settings-row (16px) so it aligns with every other list in the app. */
.stagelist__item {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 12px;
  padding: 0 16px;
  min-height: 58px;
}
/* iOS-style inset separator, aligned to where the name starts (past the 20px dot rail + 12px gap). */
.stagelist__item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 48px;
  right: 0;
  bottom: 0;
  border-bottom: 1px solid var(--c-border);
}
.stagelist__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 20px;
  flex: 0 0 20px;
}
.stagelist__line {
  flex: 1 0 6px;
  width: 2px;
  background: var(--c-border);
}
.stagelist__line--done {
  background: var(--c-accent);
}
.stagelist__line--hidden {
  visibility: hidden;
}
.stagelist__dot {
  flex: 0 0 auto;
  z-index: 1;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  box-sizing: border-box;
}
.stagelist__dot--done {
  background: var(--c-accent);
  color: var(--c-accent-ink);
}
.stagelist__dot--current {
  background: var(--c-surface);
  border: 3px solid var(--c-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 22%, transparent);
}
.stagelist__dot--todo {
  background: var(--c-surface);
  border: 2px solid var(--c-border);
}
.stagelist__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  flex: 1;
}
.stagelist__name {
  font-weight: 500;
  color: var(--c-ink);
  line-height: 1.2;
}
.stagelist__item--todo .stagelist__name {
  color: var(--c-muted);
  font-weight: 400;
}
.stagelist__item--current .stagelist__name {
  color: var(--c-accent);
  font-weight: 600;
}
.stagelist__meta {
  font-size: 0.8rem;
  color: var(--c-muted);
}
/* Lifted while dragging — opaque surface, above its neighbours, follows the finger via inline
   transform (set in dayRoute.ts). No transition on the dragged row so it tracks the finger 1:1. */
.stagelist__item--dragging {
  z-index: 3;
  background: var(--c-surface);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
  cursor: grabbing;
}
.stagelist__item--dragging::after {
  border-bottom-color: transparent;
}
/* Reorder grip (☰) — only in editable mode. */
.stagelist__grip {
  flex: 0 0 auto;
  align-self: center;
  display: grid;
  place-items: center;
  width: 40px;
  margin-right: -8px;
  border: none;
  background: transparent;
  color: var(--c-muted);
  cursor: grab;
  touch-action: none;
}
.stagelist__grip:active {
  cursor: grabbing;
}

/* Geteilter Umsortier-Griff (AB#264) für listRow-Listen (Stammdaten-Verwaltung; später Crew) — gleiche
   Optik wie der stageList-Griff, sitzt im trailingControl-Slot der Zeile (rechts, vor dem Chevron). */
.reorder-grip {
  flex: 0 0 auto;
  align-self: center;
  display: grid;
  place-items: center;
  width: 36px;
  border: none;
  background: transparent;
  color: var(--c-muted);
  cursor: grab;
  touch-action: none; /* vertikales Ziehen am Griff scrollt die Seite nicht */
}
.reorder-grip:active {
  cursor: grabbing;
}
/* Angehobene Zeile während des Ziehens: über die Nachbarn heben + Schatten (die .swipe kappt zwar
   Inhalte via overflow:hidden, ihr EIGENER box-shadow liegt außerhalb der Box und bleibt sichtbar). */
.swipe.reorder--dragging {
  position: relative;
  z-index: 3;
  background: var(--c-surface);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
}

/* Anhang-Komponente (US #275): ein Kern für alle Bild-/Datei-Anhänge — Quelle · optionaler Zuschnitt ·
   Vorschau (Thumbnail/PDF-Chip) + Entfernen · 1/mehrere. Presets setzen nur Form/Anzahl/Medientyp. */
.attach {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.attach__crop {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.attach__crop-label {
  font-size: 13px;
  color: var(--c-muted);
  flex: 0 0 auto;
}
.attach__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: flex-start;
}
.attach__cell {
  position: relative;
}
.attach__thumb {
  width: 72px;
  height: 72px;
  overflow: hidden;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  display: grid;
  place-items: center;
}
.attach__thumb--rounded {
  border-radius: 12px;
}
.attach__thumb--square {
  border-radius: 4px;
}
.attach__thumb--round {
  border-radius: 50%;
}
.attach__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.attach__thumb--pdf {
  width: auto;
  min-width: 72px;
  max-width: 170px;
  border-radius: 12px;
  padding: 0 12px;
  justify-items: start;
}
.attach__pdf {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.attach__pdf-clip {
  color: var(--c-muted);
  flex: 0 0 auto;
}
.attach__pdf-name {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Dokument-Datei-Slot (US #280) — EIN Bild/PDF mit Beleg-Bedienung (tippen öffnet, im Edit Wisch). */
.doc-fileslot {
  padding: 10px;
}
.doc-preview__img {
  max-width: 100%;
  border-radius: 8px;
  display: block;
}
.doc-fileslot__tap {
  cursor: zoom-in;
}
.doc-fileslot__pdf {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 2px;
  min-width: 0;
}
.doc-fileslot__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.attach__x {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 20px;
  height: 20px;
  padding: 0; /* Button-Default-Padding weg → ✕ mittig im Kreis (PO 2026-07-09) */
  line-height: 0;
  border: none;
  border-radius: 50%;
  background: #b3402f;
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.attach__fav {
  position: absolute;
  left: -6px;
  bottom: -6px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--c-surface);
  color: var(--c-muted);
  border: 1px solid var(--c-border);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.attach__fav--on {
  background: #c8791c;
  color: #fff;
  border-color: #c8791c;
}
.attach__add {
  width: 72px;
  height: 72px;
  border: 1.5px dashed var(--c-border);
  border-radius: 12px;
  background: transparent;
  color: var(--c-muted);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.attach__add:active {
  background: var(--c-surface);
}
/* Kachel ist jetzt ein <button> (Tap → Detail, US #278): Button-Defaults zurücksetzen. */
.attach__tile {
  padding: 0;
  cursor: pointer;
  font: inherit;
}
.attach__ph {
  color: var(--c-muted);
}
/* Nur-Ansehen + leer (US #278.1): Hinweis mit Kachel-Höhe, damit die Galerie nicht zum Streifen schrumpft. */
.attach__empty {
  display: grid;
  place-items: center;
  min-height: 72px;
  width: 100%;
  color: var(--c-muted);
  font-size: 13px;
}

/* Beleg-Detailseite (US #278): Scan groß + Aktionen (Ersetzen/Löschen) darunter. */
.receipt-detail {
  padding: 0;
  overflow: hidden;
}
.receipt-detail__scan {
  display: grid;
  place-items: center;
  min-height: 200px;
  max-height: 60vh;
  background: var(--c-surface);
  padding: 8px;
}
.receipt-detail__img {
  max-width: 100%;
  max-height: 58vh;
  border-radius: 8px;
  cursor: zoom-in;
}
.receipt-detail__actions {
  display: flex;
  gap: 10px;
  padding: 12px;
  border-top: 1px solid var(--c-border);
}
.receipt-act {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 10px;
  border: 1px solid var(--c-border);
  border-radius: 12px;
  background: var(--c-surface);
  color: var(--c-ink, inherit);
  cursor: pointer;
  font: inherit;
}
.receipt-act--danger {
  color: #b3402f;
  border-color: #b3402f;
}

/* View-first (AB#276 Phase 2): Formular im Nur-Ansehen — alle Controls pointer-inert (nichts editierbar).
   Die Swipe-Panes (.swipe__content) stehen NICHT in der Liste → bleiben aktiv; inerte Felder reichen den
   Pointer an den Pane durch, sodass Wisch-Aktionen (Anrufen · Link · E-Mail · Anhang) weiter funktionieren.
   Der zentrale ✎-Knopf schaltet in den Bearbeiten-Modus. */
.form--view input,
.form--view textarea,
.form--view select,
.form--view .ffield--tap,
.form--view .segmented,
.form--view .switch {
  pointer-events: none;
}
.form--view .ffield__chevron {
  display: none; /* im Nur-Ansehen kein „tippbar"-Chevron */
}
/* View-first: die Segmented-Buttons sind hart `disabled` (lockFormView) → sonst 0.4 ausgegraut. Die
   AKTIVE Pille bleibt aber voll lesbar, damit man den Wert im Nur-Ansehen klar erkennt (nur nicht ändern). */
.form--view .segmented__btn--on:disabled {
  opacity: 1;
}
/* Editable stop = a swipeRow <li> (swipe-left to delete). The .swipe has overflow:hidden and the pane
   sits above, so a divider on the <li> gets clipped/hidden — draw it on the INNER .stagelist__item
   instead (same trick as .listrow::after). Every stop keeps its separator (incl. before the add row). */
.stagelist__srow .stagelist__item::after {
  content: "";
  position: absolute;
  left: 48px;
  right: 0;
  bottom: 0;
  border-bottom: 1px solid var(--c-border);
}
/* ── Anatomie-Overlay (Showcase-Tab) — numbered markers on a live specimen + a legend that maps the
   number to the BEM name and the real CSS class. Diagram only; never used on a real screen. */
.anat-block {
  margin: 2px 0 10px;
}
.anat-specimen {
  padding: 8px;
  border: 1px dashed var(--c-border);
  border-radius: var(--radius);
  background: var(--c-bg);
}
.anat-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  margin-right: 6px;
  border-radius: 999px;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1;
  vertical-align: middle;
}
.anat-num--legend {
  margin-right: 8px;
}
.anat-legend {
  margin: 8px 2px 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* Each legend row is a button: hover/tap → the matching part lights up in the specimen. */
.anat-legend__row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}
.anat-legend__row:hover {
  background: color-mix(in srgb, var(--c-accent) 7%, transparent);
}
.anat-legend__row.is-active {
  background: color-mix(in srgb, var(--c-accent) 14%, transparent);
}
.anat-legend__cls {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  color: var(--c-accent);
  background: color-mix(in srgb, var(--c-accent) 8%, transparent);
  padding: 1px 6px;
  border-radius: 6px;
  font-size: 0.8rem;
  white-space: nowrap;
}
.anat-legend__name {
  color: var(--c-muted);
}
/* Global inspector flyout — follows the cursor, shows BEM name + CSS class. Dev aid, never shipped. */
.anat-flyout {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--c-ink);
  color: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  max-width: 280px;
}
.anat-flyout__name {
  font-weight: 700;
  font-size: 0.82rem;
}
.anat-flyout__cls {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.74rem;
  opacity: 0.85;
}

/* The highlighted part in the specimen — outline doesn't shift layout; a soft ring makes thin bars
   (slider track/fill) and small glyphs (icons) clearly visible. */
.anat-hi {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 5px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--c-accent) 20%, transparent);
  position: relative;
  z-index: 4;
}

/* Name-Tag RECHTS neben jeder Showcase-Zeile — die kanonische Factory-Bezeichnung (gemeinsame Sprache).
   Dev doc only, never shipped. Das Grid hält die Zeilen (Spalte 1) als EINE zusammenhängende Karte, das
   Tag (Spalte 2) steht daneben, pro Zeile ausgerichtet → Look-and-Feel bleibt erhalten. */
.spec-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) max-content;
  align-items: stretch;
  column-gap: 14px;
}
.spec {
  display: contents;
}
.spec__ctl {
  grid-column: 1;
  min-width: 0; /* sonst schrumpft ein Eingabefeld nicht mit → rechts abgeschnitten (Grid-Item min-width:auto) */
  background: var(--c-surface);
  border-left: 1px solid var(--c-border);
  border-right: 1px solid var(--c-border);
  border-bottom: 1px solid var(--c-border);
  overflow: hidden;
}
.spec-grid > .spec:first-child .spec__ctl {
  border-top: 1px solid var(--c-border);
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
}
.spec-grid > .spec:last-child .spec__ctl {
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}
/* Block-Variante (specBlock): kein Karten-Rahmen — der Block bringt seine eigene/keine Karte mit. */
.spec__ctl--block {
  background: none;
  border: none;
  overflow: visible;
}
/* Icon-Zeilen (US #299): das Icon soll nicht am Zellenrand kleben — Innenabstand wie eine Listenzeile.
   Betrifft NUR die Icon-Zellen (`.spec-ico`), nicht die randlos gefüllten Formular-Controls. */
.spec-ico {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 0 16px;
}
.spec__name {
  grid-column: 2;
  justify-self: start;
  align-self: center;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--c-accent);
  background: color-mix(in srgb, var(--c-accent) 12%, transparent);
  border-radius: 6px;
  padding: 1px 8px;
  white-space: nowrap;
  cursor: help; /* Hover → Parameter-Doku (setupDocHover) */
}
/* Familien-Präfix im Namen-Tag: „container › section", „field › toggleRow" — Familie gedämpft. */
.spec__fam {
  opacity: 0.55;
  font-weight: 500;
}
/* Herkunfts-Badge im Icon-Katalog: „Tabler" (übernommen) / „eigen" (selbst gezeichnet). Opake
   Hintergründe, damit sie auf dem accent-getönten Namen-Tag klar lesbar bleiben. */
.spec__src {
  margin-left: 8px;
  padding: 0 6px;
  border-radius: 5px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  vertical-align: middle;
}
.spec__src--tabler {
  background: #e2edf5;
  color: #15679a;
}
.spec__src--custom {
  background: #f6e7de;
  color: #b4531f;
}

/* Tages-Dropdown (Vorschlag): Kalender-Pille + Anker-Menü (freies Datum · Trennstrich · Törntage). */
.dropdown-wrap {
  position: relative;
  display: inline-block;
}
.dropdown-menu[hidden] {
  display: none;
}
.dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 240px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 6px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 12px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: none;
  background: none;
  border-radius: 8px;
  font: inherit;
  color: var(--c-ink);
  text-align: left;
  cursor: pointer;
}
.dropdown-item span {
  flex: 1;
}
.dropdown-item:hover {
  background: color-mix(in srgb, var(--c-accent) 10%, transparent);
}
.dropdown-item__check {
  margin-left: auto;
  color: var(--c-accent);
}
.dropdown-divider {
  height: 1px;
  background: var(--c-border);
  margin: 5px 6px;
}

/* Header-Datepicker (PO 2026-07-03): Kalender-Icon in der 2. Header-Zeile, unter der Lupe (gleicher
   Rechts-Abstand über padding 8px). Links davon Datum, davor die Route. Flyout rechtsbündig darunter. */
/* US #310 (PO 2026-07-14): Zeit-Pille ganz links, Datum rechts in derselben Zeile. */
.appbar__timefilter {
  flex: 0 0 auto;
  min-width: 0;
}
/* Auf der accent-farbenen Header-Leiste eigene Kontraste: inaktiv = umrandet (accent-ink), aktiv = gefüllt
   in accent-ink mit accent-farbiger Schrift (hebt sich klar ab, statt in der gleichfarbigen Leiste zu
   verschwinden). Das Dropdown bleibt der neutrale Surface-Popover. */
.appbar__timefilter .time-pille__seg,
.appbar__timefilter .time-pille__more {
  background: transparent;
  border-color: var(--c-accent-ink);
  opacity: 0.92;
  color: var(--c-accent-ink);
}
.appbar__timefilter .time-pille__seg--on {
  background: var(--c-accent-ink);
  border-color: var(--c-accent-ink);
  color: var(--c-accent);
}
.appbar__datewrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-left: auto; /* Datum an den rechten Rand */
  flex: 0 1 auto;
  min-width: 0;
}
/* Schmale Geräte (iPhone): der Routenname neben dem Datum entfällt gänzlich (PO 2026-07-14). */
@media (max-width: 600px) {
  .appbar__date-route {
    display: none;
  }
}
.appbar__date {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  color: var(--c-accent-ink);
  line-height: 0;
  padding: 4px 8px;
  cursor: pointer;
}
.appbar__date-day {
  flex: 0 0 auto;
  font-size: 0.95rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--c-accent-ink);
}
.appbar__date-route {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.85rem;
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.appbar__date-route:empty {
  display: none;
}
/* Kalender-Zeile im Menü (unter Home) — sieht aus wie ein sidebar__link; ein transparentes Datumsfeld
   liegt darüber und öffnet den nativen Standard-Datepicker. */
.sidebar__date {
  position: relative;
  width: 100%;
  cursor: pointer;
}
.sidebar__dateinput {
  /* Unsichtbar, aber TAPPBAR und über der ganzen Zeile: am Handy öffnet ein Tipp direkt den nativen
     Standard-Datepicker (iOS braucht das echte Antippen des Feldes; showPicker() gibt's dort erst ab
     iOS 16). Am PC ergänzt der Klick-Handler der Zeile showPicker(). pointer-events: auto (Standard). */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: none;
  opacity: 0;
  cursor: pointer;
}
/* Trennstrich zwischen Menügruppen (PO 2026-07-04). */
.sidebar__divider {
  height: 1px;
  flex: 0 0 auto;
  background: var(--c-border);
  margin: 8px 12px;
}
.appbar__date-menu {
  left: 0;
  right: auto;
  color: var(--c-ink);
}
/* „Beliebiger Tag": transparentes Datumsfeld über der ganzen Zeile → öffnet direkt den nativen Kalender. */
.dropdown-item--free {
  position: relative;
}
.dropdown-item__dateinput {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  border: none;
  background: none;
  cursor: pointer;
}
/* Zweizeiliger Tag-Eintrag im Flyout: Datum (fett) + Route (grau). */
.dropdown-item__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
  text-align: left;
}
.dropdown-item__title {
  font-weight: 500;
}
.dropdown-item__sub {
  font-size: 0.8rem;
  color: var(--c-muted);
}

/* Wind-Kompass (Vorschlag): Scheibe mit Grad-Strichen + Himmelsrichtungen; tippen wählt die Richtung. */
.wind-compass {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 14px;
}
.wind-compass__svg {
  width: 230px;
  height: 230px;
  max-width: 82vw;
  touch-action: none;
  cursor: pointer;
}
.wind-compass__label {
  font-weight: 600;
}
/* Haupthimmelsrichtung (N/O/S/W) groß, N zusätzlich fett; Zwischenhimmelsrichtung (NO/SO/…) kleiner. */
.wind-compass__label--card {
  font-size: 18px;
}
.wind-compass__label--n {
  font-weight: 800;
}
.wind-compass__label--inter {
  font-size: 10px;
}
.wind-compass__deg {
  font-size: 13px;
  font-weight: 600;
}
/* Manueller Griff im Slider-Knopf-Look (weiß, Rand, Schatten). */
.wind-compass__grip {
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3));
}
.wind-compass__value {
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--c-ink);
}
.wind-compass__status:empty {
  display: none; /* leerer Status nimmt keinen Platz (kein Gap im Flyout) */
}

/* Bewölkung/Seegang/Kompass: Glyph-Pillen. Padding so knapp, dass die Pille (Glyph 20px + 2×3px = 26px)
   genauso hoch ist wie eine Text-Pille (~26px) → die Feldzeile bleibt gleich hoch wie alle anderen
   (PO 2026-07-04, vorher 5px → Zeile war ~4px höher). */
.segmented__btn--okta {
  padding: 3px 6px;
}
/* Bewölkung-Feld: Label so breit wie sein Text (statt fixe 38%), damit die fünf Okta-Symbole rechts
   danebenpassen und das Segment in Portrait UND Landscape konsistent rechts sitzt (PO 2026-07-03). */
.ffield--okta .ffield__label {
  flex: 0 0 auto;
  max-width: none;
}
.okta-glyph,
.sea-glyph {
  display: block;
}

/* Parameter-Doku-Flyout: Hover auf einen Namen-Tag zeigt alle möglichen Parameter. Dev doc only. */
.spec-doc {
  position: fixed;
  z-index: 9999;
  max-width: 340px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--c-ink);
  color: #fff;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.32);
  pointer-events: none;
  font-size: 0.78rem;
  line-height: 1.4;
}
.spec-doc__head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.spec-doc__name {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-weight: 700;
  font-size: 0.84rem;
}
.spec-doc__composite {
  font-size: 0.68rem;
  opacity: 0.85;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 5px;
  padding: 1px 6px;
}
.spec-doc__summary {
  margin: 0 0 8px;
  opacity: 0.9;
}
.spec-doc__params {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 3px 10px;
}
.spec-doc__param {
  display: contents;
}
.spec-doc__pname {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.72rem;
  color: #8fc4ec;
  white-space: nowrap;
}
.spec-doc__pdesc {
  opacity: 0.88;
}

/* Screen-Bauplan (UI-Schaukasten „Bauplan"-Tab) — the ASCII tree of a screen as a code block.
   Dev doc only, never shipped. Monospace + preserved whitespace so the box-drawing lines up. */
.blueprint-tree {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-surface);
  color: var(--c-ink);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.76rem;
  line-height: 1.55;
  white-space: pre;
  overflow-x: auto;
}

/* "Stopp hinzufügen" row — same height/inset as a list row, accent-coloured like an add affordance. */
.stagelist__add {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 50px;
  padding: 10px 16px;
  border: none;
  background: transparent;
  color: var(--c-accent);
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.stagelist__add:active {
  background: color-mix(in srgb, var(--c-accent) 8%, transparent);
}
/* Leading "+" as a filled accent circle with a white glyph (aligns under the dot rail, 20px wide). */
.stagelist__add-plus {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--c-accent);
  color: var(--c-accent-ink);
}

/* Migration marker — the "Claude star" (catalogGap.ts). Dev-Backlog-Marker: die catalogGap()-Aufrufe
   bleiben greppbar/geloggt, aber im laufenden App ist das ★ AUSGEBLENDET (PO 2026-07-09 — der PO/Nutzer
   soll den Entwickler-Marker nicht sehen). Zum Wieder-Einblenden während einer Migration: display ändern. */
/* Erinnerungs-Foto-Viewer (#279): großes Foto mit Blättern per Chevron-Kreis links/rechts (zuverlässiger
   als Wischen, PO 2026-07-09). Bild selbst nicht ziehbar (sonst zeigt der Browser ein Geister-Abbild). */
.viewer__photo {
  position: relative;
}
.viewer__img {
  display: block;
  max-width: 100%;
  margin: 0 auto;
  -webkit-user-drag: none;
  -webkit-touch-callout: none; /* iOS: kein Lang-Druck-Abbild, das das Wischen im Edit blockiert (#279) */
  -webkit-user-select: none;
  user-select: none;
}
/* Im Bearbeiten (swipeField) das Foto die volle Breite füllen lassen, damit es nicht schmäler als der
   aufgezogene Wisch-Balken wirkt (PO 2026-07-09). Im Ansehen bleibt es natürlich zentriert. */
.swipe--field .viewer__img {
  width: 100%;
  height: auto;
}
.viewer__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  z-index: 2;
  cursor: pointer;
}
.viewer__nav:disabled {
  opacity: 0.3;
  pointer-events: none;
}
.viewer__nav--prev {
  left: 8px;
}
.viewer__nav--next {
  right: 8px;
}

.catalog-gap {
  display: none;
}
.catalog-gap--legacy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  margin: 0 4px;
  padding: 0 3px;
  border-radius: 50%;
  background: #e0a458;
  color: #1a1410;
  font-size: 0.78rem;
  line-height: 1;
  vertical-align: middle;
  cursor: help;
}

/* Meldungs-/Warnungs-Balken (PO 2026-07-03) — einheitlich direkt unter der Rücknavigation. Nachrichten
   blau (info), Warnungen rot (warn); je optionale Aktions-Pille + ✕. Mehrere Meldungen stapeln sich. */
.notice-bar {
  display: flex;
  flex-direction: column;
  gap: 0; /* Balken bündig gestapelt, randlos */
}
.notice-bar:empty {
  display: none;
}
/* Globaler Balken: sticky direkt unter der Kopfleiste, bleibt beim Scrollen stehen (AB#207). z über dem
   Seiteninhalt und der ‹-Leiste; letztere rückt via --notice-h darunter, sodass nichts überlappt. */
.notice-bar--sticky {
  position: sticky;
  top: calc(var(--appbar-h) + env(safe-area-inset-top));
  z-index: 30;
}
.notice {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 46px; /* alle Meldungen gleich hoch */
  /* Links bündig unter dem ‹ (Outlet 16px − 4px Back-Versatz = 12px); rechts Padding 16px + 6px im
     ✕-Button = ✕ bündig unter dem Header-✕. */
  padding: 6px var(--gap) 6px calc(var(--gap) - 4px);
  border-radius: 0;
  font-size: 0.9rem;
}
.notice__icon {
  flex: 0 0 auto;
}
.notice__text {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap; /* immer einzeilig */
  overflow: hidden;
  text-overflow: ellipsis;
}
.notice__action {
  flex: 0 0 auto;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  white-space: nowrap;
  cursor: pointer;
}
.notice__close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px; /* wie .detail-act → ✕ bündig unter dem Header-✕ (16px Padding + 6px = 22px) */
  border: none;
  background: none;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
}
.notice__close:hover {
  opacity: 1;
}
.notice--info {
  background: #e7f0f6; /* Fallback pale blue */
  background: color-mix(in srgb, var(--c-accent) 13%, var(--c-surface));
  color: var(--c-accent);
}
.notice--warn {
  background: #fbe9e9; /* Fallback pale red */
  background: color-mix(in srgb, var(--c-danger) 13%, var(--c-surface));
  color: var(--c-danger);
}

/* Willkommens-Splash nach dem Login (PO 2026-07-03): Vollbild, Avatar + „Hallo, <Name>", 3 s. */
.welcome {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  padding: env(safe-area-inset-top) 24px env(safe-area-inset-bottom);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.welcome--in {
  opacity: 1;
}
.welcome__avatar {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.16);
  border: 3px solid var(--c-accent-ink);
}
.welcome__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.welcome__usericon {
  color: var(--c-accent-ink);
}
.welcome__hello {
  margin: 0;
  font-size: 1.7rem;
  font-weight: 700;
}

/* Push-Menü (PO 2026-07-03, Bild 1993): Der Burger schiebt den GANZEN Bildschirm nach rechts; das Menü
   (fixe Sidebar) steht dann links über die volle Höhe. Nur auf Handy/Tablet (< 900px) — Desktop hat das
   Menü ohnehin fix als Spalte. */
@media (max-width: 899px) {
  body {
    /* Klammert das horizontale Scrollen durch den nach rechts geschobenen Push-Menü-Inhalt. WICHTIG:
       `clip`, NICHT `hidden` — `overflow-x: hidden` erzwingt per CSS-Regel `overflow-y: auto`, macht den
       BODY zum Scroll-Container und bricht damit das `position: sticky` von Kopfleiste/Meldungsbalken
       (AB#257, der wiederkehrende „Sticky-Header weg"). `clip` klammert horizontal, ohne einen
       Scroll-Container zu erzeugen (overflow-y bleibt visible) → Sticky funktioniert. */
    overflow-x: clip;
  }
  .appbar,
  .outlet,
  .botnav,
  #app > .notice-bar {
    transition: transform 0.24s ease;
  }
  #app.menu-push .appbar,
  #app.menu-push .outlet,
  #app.menu-push .botnav,
  #app.menu-push > .notice-bar {
    transform: translateX(var(--sidebar-w));
  }

  /* Während des Fingerziehens (PO 2026-07-03): Übergänge aus, damit Menü + Inhalt exakt dem Finger
     folgen. Beim Loslassen wird die Klasse entfernt → der Übergang schnappt sanft auf die Zielposition. */
  #app.menu-dragging .sidebar,
  #app.menu-dragging .appbar,
  #app.menu-dragging .outlet,
  #app.menu-dragging .botnav,
  #app.menu-dragging > .notice-bar,
  #app.menu-dragging .backdrop {
    transition: none;
  }
}

/* iOS-Statusleiste (PO 2026-07-03): Die oberste Zone mit Uhrzeit/Notch in der App-/Menüfarbe halten.
   Ein fixer, voll-breiter Streifen in Höhe der Safe-Area — bleibt IMMER blau, auch wenn das Push-Menü
   Header/Inhalt nach rechts schiebt (er wandert nicht mit). Liegt über allem, blockiert aber keine Tipps.
   Auf dem Desktop/im Browser ist die Safe-Area 0 → der Streifen ist unsichtbar. */
.status-shim {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: env(safe-area-inset-top);
  background: var(--c-accent);
  z-index: 60;
  pointer-events: none;
}

/* US #310 — Karten-Anzeige-Flyout (Steuerknopf → layout-grid): Kachel-Raster im unteren Sheet.
   Kachel = Icon + Text; AN → gut sichtbarer blauer Rahmen (#2f6fb0), sonst dezenter Rahmen. */
.map-layers-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 4px 0 6px;
}
.map-layer-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 8px;
  border: 2px solid var(--c-border);
  border-radius: 12px;
  background: var(--c-surface);
  color: var(--c-text, inherit);
  cursor: pointer;
  min-height: 68px;
  text-align: center;
}
.map-layer-tile--on {
  border-color: #2f6fb0; /* blauer Aktiv-Rahmen (PO #310) */
  box-shadow: 0 0 0 1px #2f6fb0 inset;
}
.map-layer-tile--disabled {
  opacity: 0.45;
  cursor: default;
}
.map-layer-tile__label {
  font-size: 12px;
  line-height: 1.2;
  word-break: break-word;
}

/* US #310 — „Alle · Am Tag"-Pille oben mittig über der Karte (Tagesfilter). */
.map-dayscope {
  position: absolute;
  top: calc(var(--notice-h, 0px) + 66px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  background: var(--c-surface);
  border-radius: 999px;
  padding: 3px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.28);
}
.map-dayscope .chips {
  margin: 0;
}

/* US #308/#311 — Position-Setzen im Karten-Kopf: fixer Mitte-Pin (Art-Icon, keine Umrandung) +
   „Übernehmen"-Knopf. Der Pin sitzt fest in der Mitte; die Karte schiebt sich darunter durch. */
.wp-headmap { position: relative; }
.wp-headmap__pin {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -100%); /* Spitze/Unterkante des Symbols auf der Karten-Mitte */
  z-index: 1000;
  pointer-events: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}
.wp-headmap__pinicon { stroke-width: 2.4; }
/* US #325 (Korrektur): Reservierungsart-Symbol als Karten-MARKER auf der Position (read-only/verknüpft) —
   gleiche Optik wie der Setz-Pin (kein Kreis, kräftige Farbe), aber an der Position verankert. */
.res-art-marker {
  color: #d9480f;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}
.wp-headmap__set {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  z-index: 1000;
}
