/* Minimal layout — function-over-form per project constraints.
 * Cosmetic tokens below keep the chrome coordinated; semantic colors
 * (accent = route/selection, severity dots, start/end pills) are unchanged. */

:root {
  --brand:      #141416;   /* near-black chrome (header / neutral pins) */
  --brand-2:    #1d1d1f;
  --accent:        #6366f1;   /* indigo — route / selection / focus */
  --accent-soft:   #eef0fe;   /* tint behind selected items */
  --accent-border: #b9bdf5;   /* soft accent border */
  --wp-status-open:      #1d1d1f;  /* neutral dark — open, no metadata yet */
  --wp-status-open-prefilled: #2980b9;  /* blue — open with untouched prefill */
  --wp-status-open-edited:    #b7791f;  /* amber — open with local edits */
  --wp-status-erledigt:  #27ae60;  /* green — included in document */
  --wp-status-ignoriert: #9ca3af;  /* muted grey — set aside */
  --bg:         #f5f5f7;
  --surface:    #ffffff;
  --border:     #e3e8ee;   /* softer than the old #ddd hairlines */
  --text:       #1f2933;
  --text-muted: #6b7480;
  --radius:     8px;       /* one radius everywhere */
  --shadow-sm:  0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md:  0 4px 14px rgba(16, 24, 40, 0.10);
  --focus-ring: 0 0 0 3px rgba(99, 102, 241, 0.28);
  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);  /* slight overshoot — reads "macOS" */
  --photo-thumb-h: 240px;  /* waypoint photo thumbnail height (preview overlay matches) */
  --hairline:   rgba(0, 0, 0, 0.07);  /* translucent dividers instead of hard #ddd/#eee lines */
  --shadow-lg:  0 12px 32px rgba(16, 24, 40, 0.16), 0 2px 8px rgba(16, 24, 40, 0.08);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
body {
  display: flex; flex-direction: column; height: 100vh; color: var(--text);
  background: var(--bg);  /* fallback; the landing shows #landing-bg behind */
}

/* --- Landing backdrop: a real OSM map, blurred and faded under a tinted
 * gradient. Lives behind everything (z-index: -2); only visible on the
 * landing since the review/wizard layouts paint opaque content on top. --- */
#landing-bg {
  position: fixed; inset: 0; z-index: -2;
  overflow: hidden; pointer-events: none; background: var(--bg);
}
#landing-map {
  position: absolute; inset: -32px;  /* bleed so blurred edges stay off-screen */
  animation: landing-drift 48s ease-in-out infinite alternate;
}
#landing-map .leaflet-tile-pane { filter: blur(3px) saturate(1.12) brightness(1.02); }
#landing-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(1200px 700px at 82% -12%, rgba(99, 102, 241, 0.34), transparent 56%),
    radial-gradient(900px 560px at 8% 112%, rgba(45, 212, 191, 0.14), transparent 52%),
    linear-gradient(150deg,
      rgba(243, 244, 251, 0.66) 0%,
      rgba(228, 231, 251, 0.74) 48%,
      rgba(245, 245, 247, 0.92) 100%);
}
#landing-credit {
  position: fixed; right: 8px; bottom: 6px; z-index: -1;
  font-size: 10px; color: rgba(60, 70, 90, 0.5);
  pointer-events: none; letter-spacing: 0.01em;
}
@keyframes landing-drift { from { transform: scale(1); } to { transform: scale(1.07); } }

/* Non-landing views are opaque so the landing backdrop never shows through
 * their translucent chrome (e.g. the frosted review toolbar). */
.review-map-screen, .route-assembly { background: var(--bg); }
header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 1rem; color: white;
  background: linear-gradient(180deg, rgba(43, 43, 46, 0.92), rgba(29, 29, 31, 0.92));
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-bottom: 2px solid var(--accent);
}
.brand { display: flex; align-items: center; gap: 0.7rem; min-width: 0; }
.brand-logo { height: 22px; width: auto; display: block; }
.brand-divider { width: 1px; height: 1.05rem; background: rgba(255, 255, 255, 0.28); flex-shrink: 0; }
header h1 { font-size: 1.1rem; margin: 0; font-weight: 700; letter-spacing: -0.01em; }
#header-context {
  display: flex; align-items: center; gap: 0.5rem;
  font-size: 0.85rem; color: rgba(255, 255, 255, 0.86);
}
.header-survey {
  display: inline-flex; align-items: center; gap: 0.25rem;
  min-width: 0;
}
.header-survey-name {
  min-width: 0; max-width: 32ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.header-survey-close {
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: rgba(255, 255, 255, 0.74);
  font-size: 1rem; line-height: 1; box-shadow: none;
}
.header-survey-close:hover {
  background: rgba(255, 255, 255, 0.14); color: white;
}
.header-divider {
  width: 1px; height: 1.05rem; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.28);
}
/* The account menu trigger: reads as the signed-in address, behaves as a
 * button. Transparent until hovered so it does not compete with Verwaltung. */
.header-user {
  display: inline-flex; align-items: center; gap: 0.3rem; min-width: 0;
  padding: 0.25rem 0.5rem; border: 0; box-shadow: none;
  background: transparent; color: inherit; font: inherit;
}
.header-user:hover { background: rgba(255, 255, 255, 0.14); color: white; }
.header-user-email {
  min-width: 0; max-width: 28ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.header-user-caret { font-size: 0.8rem; line-height: 1; opacity: 0.9; }
.header-admin { margin-left: 0; }

/* A two-item menu does not need the 520px the wizard-sized modals use. */
.account-modal { min-width: 0; width: min(420px, 90vw); }
.account-modal .body { display: flex; flex-direction: column; gap: 0.25rem; }
.account-email { margin: 0; font-weight: 600; }
.account-role { margin: 0; color: var(--text-muted); font-size: 0.85rem; }
.account-actions { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.75rem; }
.account-action { text-align: left; }

main { flex: 1; overflow: hidden; }

button {
  font: inherit; padding: 0.4rem 0.9rem; border: 1px solid transparent;
  background: #f0f1f3; cursor: pointer; border-radius: var(--radius);
  transition: background 0.12s, box-shadow 0.12s, border-color 0.12s, transform 0.08s var(--ease-spring);
}
button:hover { background: #e7e8ec; }
button:active { transform: scale(0.97); }
button.primary {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
  box-shadow: var(--shadow-sm);
}
button.primary:hover {
  background: #5357d8;
  border-color: #5357d8;
}
button.primary:disabled {
  background: #d8dbe0;
  color: #7a828c;
  border-color: #d8dbe0;
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}
button.danger { color: #c0392b; }

input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--focus-ring);
}

/* --- Start screen --- */
.auth-screen {
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}
.auth-panel {
  width: min(360px, 100%);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.auth-panel h2 { margin: 0 0 0.25rem; font-size: 1.1rem; }
.auth-input {
  font: inherit;
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
/* One full-width primary button: the form has a single obvious action, and
   which one it is follows the mode the form is in. */
.auth-actions { display: flex; gap: 0.5rem; }
.auth-actions button { flex: 1; }
/* Switching between signing in and registering is the subordinate action, so
   it is a link rather than a second button competing with the one above. */
.auth-switch {
  align-self: center;
  padding: 0.1rem 0.25rem;
  background: none;
  border: none;
  font-size: 0.85rem;
  color: var(--accent);
  text-decoration: underline;
}
.auth-switch:hover { background: none; text-decoration: none; }
.auth-switch:disabled { color: var(--muted, #6b7280); cursor: not-allowed; }
.auth-error { min-height: 1.2rem; color: #c0392b; font-size: 0.85rem; }
.password-form { display: grid; gap: 0.5rem; }

/* --- Admin panel --- */
.admin-modal { width: min(680px, 92vw); max-width: 680px; }
.admin-tabs {
  display: flex;
  gap: 0.25rem;
  padding: 0.6rem 1rem 0;
  border-bottom: 1px solid var(--hairline);
  background: #f8f9fa;
}
.admin-tab {
  position: relative;
  padding: 0.6rem 0.85rem 0.7rem;
  border: 0;
  border-radius: 7px 7px 0 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  box-shadow: none;
}
.admin-tab:hover { background: rgba(99, 102, 241, 0.07); }
.admin-tab.active { color: var(--accent); background: white; }
.admin-tab.active::after {
  content: "";
  position: absolute;
  right: 0.65rem;
  bottom: -1px;
  left: 0.65rem;
  height: 2px;
  background: var(--accent);
}
.admin-loading { margin: 1rem 0; color: var(--text-muted); }
.admin-section { margin: 0.5rem 0 1rem; }
.admin-section h3 {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  color: var(--muted, #6b7280);
}
.admin-invite-form { display: flex; gap: 0.5rem; align-items: center; }
.admin-invite-form .auth-input { flex: 1; }
.admin-role-select {
  font: inherit;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: white;
}
.admin-list { list-style: none; margin: 0; padding: 0; }
.admin-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--hairline);
}
.admin-list li:last-child { border-bottom: none; }
.admin-row-actions { display: flex; gap: 0.35rem; }
.admin-mini-btn {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.25rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #f3f4f6;
  cursor: pointer;
}
.admin-mini-btn.admin-danger { color: #c0392b; border-color: #e3b4ae; }
.admin-help {
  margin: -0.15rem 0 0.65rem; color: var(--text-muted); font-size: 0.83rem; line-height: 1.4;
}
.admin-group-create {
  display: grid; grid-template-columns: minmax(10rem, 1fr) auto;
  gap: 0.45rem; align-items: center;
}
.admin-group-list { display: grid; gap: 0.65rem; margin-top: 0.75rem; }
.admin-group-card {
  padding: 0.7rem; border: 1px solid var(--border); border-radius: var(--radius);
  background: rgba(118, 118, 128, 0.04);
}
.admin-group-header,
.admin-group-add-member {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
}
.admin-group-members-label {
  margin-top: 0.35rem; font-size: 0.78rem; font-weight: 600; color: var(--text-muted);
}
.admin-group-members li { font-size: 0.84rem; }
.admin-group-members .empty-note { justify-content: flex-start; }
.admin-group-add-member { justify-content: flex-end; margin-top: 0.5rem; }
.admin-project-sharing-list { display: grid; gap: 0.6rem; margin-top: 0.85rem; }
.admin-project-sharing-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(118, 118, 128, 0.04);
}
.admin-project-sharing-description { display: grid; gap: 0.18rem; min-width: 0; }
.admin-project-sharing-description small {
  color: var(--text-muted); font-size: 0.78rem; line-height: 1.35;
}
.admin-group-auto-select { flex: 0 0 auto; max-width: 17rem; }

@media (max-width: 620px) {
  .admin-invite-form { display: grid; grid-template-columns: 1fr 1fr; }
  .admin-invite-form .auth-input { grid-column: 1 / -1; width: 100%; box-sizing: border-box; }
  .admin-invite-form .admin-role-select,
  .admin-invite-form .primary { width: 100%; }
  .admin-group-create { grid-template-columns: 1fr; }
  .admin-group-header { align-items: flex-start; }
  .admin-project-sharing-row { align-items: stretch; flex-direction: column; }
  .admin-group-auto-select { max-width: none; width: 100%; }
}

/* `main` clips its overflow so the map views can own their own scrolling, so
 * the start screen has to be its own scroll container -- otherwise a long
 * project list is simply cut off at the bottom of the window. */
.start-screen { padding: 2rem; max-width: 720px; margin: 0 auto; height: 100%; overflow-y: auto; }
.start-screen h2 { font-size: 1rem; color: #555; text-transform: uppercase; letter-spacing: 0.05em; margin-top: 2rem; }
/* Two columns once a project exists: every project by name on the left, only
 * the one being read expanded in the middle. */
.start-screen-split {
  max-width: 1080px;
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: 1.75rem;
  align-items: start;
}
.start-main { min-width: 0; }
/* Sticks while the middle column scrolls: switching projects should not mean
 * scrolling back up to a list that has run off the top. */
.project-sidebar { position: sticky; top: 0; min-width: 0; }
.project-sidebar h2 { margin-top: 0; }
.project-nav { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.3rem; }
/* Two controls share the row: the chevron unfolds the project's surveys, the
   rest of the row opens the project in the middle column. The surface and the
   hover/selected states belong to the row so the pair reads as one item. */
.project-nav-row {
  display: flex; align-items: stretch; border-radius: 10px;
  border: 1px solid transparent; background: rgba(255, 255, 255, 0.5);
}
.project-nav-row:hover { background: rgba(255, 255, 255, 0.85); border-color: var(--border); }
.project-nav-row.is-current {
  background: var(--accent-soft); border-color: var(--accent-border);
  /* Accent bar as well as the tint: which project the middle column is
     showing has to be readable at a glance, not inferred from a pale wash. */
  box-shadow: inset 3px 0 0 var(--accent);
}
.project-nav-toggle {
  flex-shrink: 0; width: 26px; padding: 0; border: none; background: transparent;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); cursor: pointer; border-radius: 10px 0 0 10px;
}
.project-nav-toggle svg { width: 13px; height: 13px; transition: transform 0.14s var(--ease-spring); }
.project-nav-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }
.project-nav-toggle:hover { background: rgba(0, 0, 0, 0.06); color: var(--brand-2); }
.project-nav-item {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.5rem; text-align: left;
  padding: 0.5rem 0.7rem 0.5rem 0.15rem; border: none; border-radius: 0 10px 10px 0;
  background: transparent; color: var(--text); cursor: pointer;
}
.project-nav-item:hover { background: transparent; }
.project-nav-text { min-width: 0; flex: 1; }
.project-nav-name {
  font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.project-nav-row.is-current .project-nav-name { font-weight: 600; }
/* Unfolded contents. Indented under the chevron, flat and quiet: this is a
   place to read what a project holds, not a second copy of its card. */
.project-nav-surveys {
  list-style: none; margin: 0.15rem 0 0.1rem; padding: 0 0 0 1.35rem;
  display: flex; flex-direction: column; gap: 0.1rem;
}
.project-nav-surveys[hidden] { display: none; }
.project-nav-survey {
  width: 100%; text-align: left; padding: 0.3rem 0.55rem;
  border: none; border-radius: 7px; background: transparent;
  font-size: 0.87rem; color: var(--text-muted); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.project-nav-survey:hover { background: rgba(255, 255, 255, 0.85); color: var(--text); }
.project-nav-meta { font-size: 0.78rem; color: var(--text-muted); }
/* Upload marker: the collapsed row draws no survey, so this dot is the only
 * place an interrupted upload can show up. */
.project-nav-upload { flex-shrink: 0; width: 9px; height: 9px; border-radius: 50%; }
.project-nav-upload-active { background: var(--accent); }
.project-nav-upload-error { background: var(--wp-status-open-edited); }
.start-screen-split .new-project-btn { width: 100%; margin-top: 1rem; }
/* Narrow windows drop to one column: the list above, the open project below. */
@media (max-width: 860px) {
  .start-screen-split { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
  .project-sidebar { position: static; }
}
.recent-list { list-style: none; padding: 0; }
.recent-list li {
  border: 1px solid var(--border); background: var(--surface); padding: 0.75rem 1rem; margin-bottom: 0.5rem;
  border-radius: var(--radius); display: flex; justify-content: space-between; align-items: center; cursor: pointer;
  box-shadow: var(--shadow-sm); transition: transform 0.15s var(--ease-spring), border-color 0.12s, box-shadow 0.12s;
}
.recent-list li:hover { border-color: var(--accent); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.recent-list .name { font-weight: 500; }
.recent-list .meta { font-size: 0.85rem; color: #888; }
.empty-note { color: #888; font-style: italic; }
/* Projects this build cannot read (a rollback). Framed as a notice, not
 * an error: nothing is lost and it clears when the newer build returns. */
.start-unavailable-note {
  margin-top: 2rem; padding: 0.75rem 1rem; border-radius: 8px;
  background: rgba(245, 176, 65, 0.14); border: 1px solid rgba(180, 120, 20, 0.35);
  color: #6b4a05; font-size: 0.9rem; line-height: 1.5;
}

.project-list { display: flex; flex-direction: column; gap: 1.25rem; }
/* Per-project route-mode switch. Sits in the card body, not the header
 * icon row: it needs its label to be readable at a glance. */
.project-prefill-toggle {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0.25rem 0 0.75rem; font-size: 0.88rem; color: #444; cursor: pointer;
}
.project-prefill-toggle input { cursor: pointer; margin: 0; }
/* macOS-style frosted card: translucent surface over the blurred landing
 * map, large radius, hairline edge, soft shadow. */
.project-card {
  border: 1px solid rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.66);
  -webkit-backdrop-filter: saturate(1.8) blur(22px);
  backdrop-filter: saturate(1.8) blur(22px);
  border-radius: 14px;
  padding: 1rem 1.25rem 1.1rem;
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
/* Title row: text column on the left, share icon on the right. */
.project-header {
  margin-bottom: 0.65rem;
  display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem;
}
.project-header-text { min-width: 0; }
.project-title { font-weight: 600; font-size: 1.05rem; }
.project-meta { font-size: 0.85rem; color: var(--text-muted); }
/* Title-row icon actions (share + edit + delete). */
.project-header-actions { flex-shrink: 0; display: inline-flex; align-items: center; gap: 0.15rem; }
.project-share-icon, .project-edit-icon, .project-delete-icon {
  flex-shrink: 0; width: 32px; height: 32px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; border-radius: 8px;
  color: var(--text-muted); cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.project-share-icon svg, .project-edit-icon svg, .project-delete-icon svg { width: 18px; height: 18px; }
.project-share-icon:hover, .project-edit-icon:hover { background: rgba(0, 0, 0, 0.06); color: var(--brand-2); }
.project-share-icon:active, .project-edit-icon:active { background: rgba(0, 0, 0, 0.1); }
.project-delete-icon:hover { background: rgba(220, 38, 38, 0.1); color: #dc2626; }
.project-delete-icon:active { background: rgba(220, 38, 38, 0.18); }
/* Survey rows sit visually *inside* the card: a flatter, tinted inset
 * surface distinct from the frosted card behind them. */
.project-surveys { margin: 0.5rem 0 0.75rem; }
.project-surveys li {
  background: rgba(118, 118, 128, 0.07);
  border: 1px solid transparent;
  box-shadow: none;
}
.project-surveys li:hover {
  background: var(--surface);
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
/* Per-survey row actions: edit + delete. */
.survey-row-actions { display: inline-flex; align-items: center; gap: 0.35rem; }
.survey-edit-icon, .survey-delete-icon {
  width: 28px; height: 28px; padding: 0; border: none; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-muted); cursor: pointer;
  opacity: 1; transition: background 0.12s, color 0.12s;
}
.survey-edit-icon svg, .survey-delete-icon svg { width: 16px; height: 16px; }
.survey-edit-icon:hover { background: rgba(0, 0, 0, 0.06); color: var(--brand-2); }
.survey-delete-icon:hover { background: rgba(220, 38, 38, 0.12); color: #dc2626; }
.project-add {
  background: transparent; border: 1px dashed var(--border); color: var(--brand-2);
  padding: 0.5rem 0.9rem; border-radius: var(--radius); cursor: pointer;
  font-size: 0.95rem; transition: background 0.12s, border-color 0.12s;
}
.project-add:hover { background: var(--bg); border-color: var(--accent); }
.project-add-resurvey { margin-top: 0.4rem; }
.new-project-btn { margin-top: 1.75rem; }
.resurvey-field { display: flex; flex-direction: column; gap: 0.3rem; margin: 0.7rem 0; }
.resurvey-field > span { font-size: 0.85rem; color: var(--muted, #5f6b76); font-weight: 600; }
.resurvey-field select, .resurvey-field input { padding: 0.4rem 0.55rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: 0.95rem; }

/* Upload progress stays visible on Projects, route editing and review. */
.upload-progress-slot:empty { display: none; }
.project-surveys .upload-progress-slot { margin-top: 0.5rem; }
.review-map-wrap > .upload-progress-slot {
  position: absolute; top: 1rem; left: 4rem; right: 1rem; z-index: 1000; max-width: 32rem;
}
.upload-banner {
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  border-radius: var(--radius); padding: 0.6rem 0.75rem; margin-bottom: 0.75rem;
}
.upload-banner-text { font-size: 0.85rem; color: var(--text); margin-bottom: 0.4rem; }
.upload-bar {
  height: 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.08); overflow: hidden;
}
.upload-bar-fill {
  height: 100%; background: var(--accent); border-radius: 3px;
  transition: width 0.25s ease;
}
.upload-banner-error { background: #fff4f4; border-color: #f3c0c0; }
.upload-resume-btn {
  margin-top: 0.2rem; padding: 0.35rem 0.7rem; font-size: 0.85rem;
  border: 1px solid #dc2626; color: #dc2626; background: transparent;
  border-radius: var(--radius); cursor: pointer;
}
.upload-resume-btn:hover { background: rgba(220, 38, 38, 0.08); }
/* Thumbnail placeholder while a photo's bytes are still uploading. */
.wp-photo-thumb.thumb-pending, .selection-preview-thumb.thumb-pending {
  background: repeating-linear-gradient(
    45deg, rgba(0,0,0,0.04), rgba(0,0,0,0.04) 8px,
    rgba(0,0,0,0.08) 8px, rgba(0,0,0,0.08) 16px);
}

/* --- Modal base (shared by wizard + dialogs) --- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.22);
  /* Leaflet's panes and controls occupy z-index levels up to 1000 in this same
   * stacking context, so a modal below that is painted *behind* the map on
   * every screen that shows one — visible only as a blurred header while the
   * modal itself hides under the map. This floor has to clear the map and the
   * review chrome layered on top of it (toolbar 1200, waypoint panel 1250,
   * selection preview 1350) while staying under the loading overlay (1500)
   * and the alert/confirm dialogs (2600), which must cover a modal. */
  z-index: 1400;
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  animation: fade-in 0.18s ease;
}
.modal {
  background: white; border-radius: 12px; min-width: 520px; max-width: 70vw; max-height: 80vh;
  display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--shadow-lg);
  animation: pop-in 0.22s var(--ease-spring);
}
.modal h2 { margin: 0; padding: 1rem 1.25rem; background: #ecf0f1; border-bottom: 1px solid var(--hairline); font-size: 1rem; }
.modal h2.wizard-route-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding: 0.65rem 1rem;
}
.wizard-route-header-title { flex: 0 0 auto; }
.wizard-route-name-editor {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
  font-size: 0.75rem;
  font-weight: 500;
  color: #5b6570;
}
.wizard-route-name-editor span {
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.wizard-route-name-editor .wizard-survey-name {
  width: min(390px, 38vw);
  padding: 0.38rem 0.55rem;
  border: 1px solid #8aa0b8;
  border-radius: 4px;
  background: white;
  color: #243447;
  font-size: 0.92rem;
  font-weight: 600;
}
.wizard-route-name-editor .wizard-survey-name:focus {
  outline: 2px solid rgba(99, 102, 241, 0.25);
  border-color: var(--accent);
}
.modal .body { flex: 1; overflow: auto; padding: 0.5rem 1rem; }
.modal .footer { padding: 0.75rem 1rem; border-top: 1px solid var(--hairline); display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }

/* --- Alert / confirm dialogs (dialogs.js) --- */
.dialog-backdrop { z-index: 2600; }
.dialog-modal { min-width: 0; width: min(440px, 90vw); }
.dialog-modal .dialog-message {
  margin: 0;
  padding: 0.6rem 0.25rem;
  white-space: pre-line;
  line-height: 1.5;
  color: #243447;
}
.dialog-input {
  font: inherit;
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.dialog-field {
  display: grid;
  gap: 0.35rem;
  margin-top: 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
}
.dialog-select,
.manage-access-group-select,
.manage-access-group-role {
  color: var(--text);
  background: white;
}
.dialog-footer { justify-content: flex-end; }
button.dialog-danger { background: #c0392b; border-color: #c0392b; }
button.dialog-danger:hover { background: #a93226; }
.manage-access-list { list-style: none; margin: 0; padding: 0; }
.manage-access-list li {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.45rem 0.25rem; border-bottom: 1px solid var(--hairline); font-size: 0.88rem;
}
.manage-access-list li:last-child { border-bottom: none; }
.manage-access-who { min-width: 0; overflow-wrap: anywhere; }
.manage-access-group { background: rgba(118, 118, 128, 0.04); }
.manage-access-group-field { padding-top: 0.6rem; border-top: 1px solid var(--hairline); }
.manage-access-add-group { justify-self: start; }

.info-disclosure {
  display: inline-block;
  margin: 0;
}
.info-disclosure-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.45rem;
  height: 1.45rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.82);
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
}
.info-disclosure-trigger::-webkit-details-marker { display: none; }
.info-disclosure-trigger:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: white;
}
.info-disclosure-icon {
  font-size: 0.82rem;
  font-weight: 800;
  font-family: ui-serif, Georgia, serif;
  font-style: italic;
  line-height: 1;
}
.info-disclosure-text {
  margin: 0.45rem 0 0;
  color: var(--text-muted);
  font-size: 0.8rem;
  line-height: 1.4;
  max-width: 42rem;
}

/* --- Hosted project upload sheet --- */
.upload-sheet-modal {
  min-width: 0;
  width: min(640px, 92vw);
}
.upload-sheet-body { padding: 1rem 1.25rem 1.15rem; }
.upload-sheet-intro {
  margin: 0 0 1rem;
}
.upload-sheet-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
}
.upload-sheet-card {
  min-width: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  gap: 0.7rem;
  padding: 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fbfbfc;
}
.upload-sheet-card.is-complete {
  border-color: rgba(34, 197, 94, 0.45);
  background: #f4fbf6;
}
.upload-sheet-card.is-complete .upload-sheet-step { background: #16a34a; }
.upload-sheet-step {
  width: 1.55rem;
  height: 1.55rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: white;
  font-weight: 700;
  font-size: 0.82rem;
}
.upload-sheet-card-text { min-width: 0; }
.upload-sheet-card-text strong {
  display: block;
  color: var(--text);
  margin-bottom: 0.2rem;
}
.upload-sheet-card-text span {
  display: block;
  color: var(--text-muted);
  font-size: 0.86rem;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.upload-sheet-card button {
  grid-column: 1 / -1;
  justify-self: stretch;
}
.upload-sheet-footer { justify-content: space-between; }
.upload-sheet-state {
  min-width: 0;
  color: var(--text-muted);
  font-size: 0.86rem;
  text-align: right;
}
@media (max-width: 640px) {
  .upload-sheet-grid { grid-template-columns: 1fr; }
  .upload-sheet-footer {
    align-items: stretch;
    flex-direction: column-reverse;
  }
  .upload-sheet-state { text-align: left; }
}

/* --- Create-survey wizard modal --- */
.wizard-modal { min-width: 560px; max-width: 640px; }
.wizard-modal-wide {
  width: 100vw; max-width: 100vw;
  height: 100vh; max-height: 100vh;
  border-radius: 0;
}

/* --- Loading feedback: full-screen overlay (slow photo analysis and survey
 * reopen, which re-reads hundreds of photos). --- */
@keyframes spin { to { transform: rotate(360deg); } }
.loader-spinner {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--border); border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
.loader-block {
  display: flex; flex-direction: column; align-items: center; gap: 0.85rem;
  padding: 2.5rem 1rem; text-align: center; color: var(--text);
}
.loader-message { font-weight: 500; }
.loader-sub { color: var(--text-muted); font-size: 0.82rem; max-width: 22rem; }
.loading-overlay {
  position: fixed; inset: 0; z-index: 1500;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;
  background: rgba(245, 245, 247, 0.72);
  backdrop-filter: blur(6px) saturate(160%); -webkit-backdrop-filter: blur(6px) saturate(160%);
  animation: fade-in 0.15s ease;
}
.loading-overlay-text { font-weight: 600; font-size: 0.98rem; color: var(--text); }
.loading-overlay-sub {
  color: var(--text-muted); font-size: 0.84rem; margin-top: -0.4rem;
  max-width: 24rem; text-align: center; line-height: 1.4;
}
.loading-progress {
  width: min(320px, 72vw); height: 7px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.1); overflow: hidden;
}
.loading-progress-fill {
  height: 100%; width: 0; border-radius: inherit;
  background: var(--accent); transition: width 0.2s ease;
}
.loading-progress-indeterminate .loading-progress-fill {
  width: 42%;
  animation: loading-progress-sweep 1.1s ease-in-out infinite;
}
@keyframes loading-progress-sweep {
  0% { transform: translateX(-115%); }
  100% { transform: translateX(260%); }
}
.wizard-intro { margin: 0 0 1rem; }
/* Body copy on a wizard step that has no cards to carry it. */
.wizard-step-note { margin: 0 0 1.25rem; color: #444; font-size: 0.92rem; line-height: 1.45; }
.wizard-input-warning {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  width: 100%;
  margin: 0 0 1rem;
  padding: 0.65rem 0.75rem;
  border: 1px solid #e8bd72;
  border-left: 4px solid #d97706;
  border-radius: 6px;
  background: #fff8eb;
  color: #65420b;
  font: inherit;
  text-align: left;
  box-shadow: none;
}
.wizard-input-warning.expanded { align-items: flex-start; }
.wizard-input-warning-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: #d97706;
  color: white;
  font-weight: 700;
}
.wizard-input-warning-content {
  min-width: 0;
  flex: 1;
}
.wizard-input-warning-header {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}
.wizard-input-warning-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  flex: 1;
  padding: 0.15rem 0;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
}
.wizard-input-warning-toggle:hover {
  background: transparent;
}
.wizard-input-warning-arrow {
  flex: 0 0 auto;
  /* The bare "›" glyph is only ~8px wide, a near-impossible click target, so
     near-misses landed outside the button and did nothing. Pad the box into a
     comfortable target and offset with negative margin so the layout is
     unchanged. The toggle lives on the parent button, so the larger arrow box
     forwards its clicks for free. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4rem;
  padding: 0.3rem 0.25rem;
  margin: -0.3rem -0.1rem;
  color: #a85e00;
  font-size: 1.25rem;
  line-height: 1;
  transform: rotate(0deg);
  transition: transform 0.15s ease;
}
.wizard-input-warning-toggle[aria-expanded="true"] .wizard-input-warning-arrow {
  transform: rotate(90deg);
}
.wizard-input-warning-title {
  font-weight: 700;
}
.wizard-input-warning-details {
  margin: 0.55rem 0 0 1.7rem;
  font-size: 0.86rem;
  line-height: 1.4;
}
.wizard-input-warning-details[hidden] { display: none; }
.wizard-input-warning-review {
  flex: 0 0 auto;
  padding: 0.3rem 0.7rem;
  border: 1px solid #d97706;
  border-radius: 5px;
  background: white;
  color: #8a4d00;
  font-size: 0.78rem;
  font-weight: 700;
}
.wizard-input-warning-review:hover {
  background: #fff0d8;
  border-color: #b85f00;
}

.off-kmz-preview-backdrop {
  /* This preview opens from inside the creation wizard, whose shared backdrop
   * is level 1400. Keep it above that wizard but below the loading overlay at
   * 1500, so its map and controls remain visible and clickable. */
  z-index: 1450;
  background: rgba(20, 20, 24, 0.42);
}
.off-kmz-preview-modal {
  width: min(94vw, 1180px);
  height: min(88vh, 820px);
  min-width: 0;
  max-width: none;
  max-height: none;
}
.off-kmz-preview-head {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.9rem 1.05rem;
  border-bottom: 1px solid var(--hairline);
  background: #fff8eb;
}
.off-kmz-preview-heading {
  flex: 1;
  min-width: 0;
}
.off-kmz-preview-heading h2 {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #65420b;
  font-size: 1.1rem;
}
.off-kmz-preview-heading p {
  margin: 0.35rem 0 0;
  color: #6f5634;
  font-size: 0.86rem;
  line-height: 1.38;
}
.off-kmz-preview-close {
  padding: 0.05rem 0.45rem;
  border: 0;
  background: transparent;
  color: #7a5a25;
  font-size: 1.7rem;
  line-height: 1;
}
.off-kmz-preview-close:hover { background: transparent; color: #c0392b; }
.off-kmz-preview-body {
  flex: 1 1 0;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 270px;
  gap: 0;
}
.off-kmz-preview-map {
  min-height: 0;
  background: #eaeaea;
}
.off-kmz-preview-aside {
  overflow-y: auto;
  padding: 1rem;
  border-left: 1px solid var(--hairline);
  background: #fafafc;
}
.off-kmz-preview-aside h3 {
  margin: 0 0 0.45rem;
  font-size: 0.98rem;
}
.off-kmz-preview-aside p {
  margin: 0 0 0.9rem;
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1.38;
}
.off-kmz-preview-list {
  margin: 0;
  padding-left: 1.25rem;
}
.off-kmz-preview-list li {
  margin-bottom: 0.45rem;
  padding: 0.4rem 0.55rem;
  margin-left: -0.55rem;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.1s, box-shadow 0.1s;
}
.off-kmz-preview-list li:hover,
.off-kmz-preview-list li.hovered {
  background: #fff4e6;
  box-shadow: inset 0 0 0 1px #f0b878;
}
.off-kmz-preview-list span {
  display: block;
  color: var(--text-muted);
  font-size: 0.78rem;
}
.off-kmz-preview-footer {
  display: flex;
  justify-content: flex-end;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--hairline);
  background: white;
}
.off-kmz-preview-legend .swatch-line-off-main {
  width: 1.4rem; height: 5px; background: #1f5f8b;
}
.off-kmz-preview-legend .swatch-line-off-context {
  width: 1.4rem; height: 3px; background: #6366f1;
}
.off-kmz-preview-legend .swatch-dot-off-photo {
  width: 0.8rem; height: 0.8rem; border-radius: 50%;
  background: #d97706; border: 2px solid white; box-shadow: 0 0 0 1px #d97706;
}

.wizard-choice-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.wizard-choice {
  position: relative; display: flex; flex-direction: column; gap: 0.35rem;
  padding: 1.1rem 1rem; border: 1.5px solid #c4cdd8; border-radius: var(--radius);
  background: white; text-align: left; font: inherit; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s var(--ease-spring), border-color 0.1s, background 0.1s, box-shadow 0.1s;
}
.wizard-choice:hover:not(:disabled) { border-color: var(--accent); background: #f8f9fa; box-shadow: var(--shadow-md); transform: translateY(-2px); }
.wizard-choice:disabled { opacity: 0.45; cursor: not-allowed; }
.wizard-choice-main { border-left: 3px solid var(--accent); }
.wizard-choice-custom { border-left: 3px solid #3498db; }
.wizard-choice-title { font-weight: 600; font-size: 1.05rem; }
.wizard-choice-desc { color: #444; font-size: 0.92rem; line-height: 1.35; }
.wizard-choice-meta { color: #888; font-size: 0.82rem; margin-top: auto; }

.wizard-modal-wide .body {
  padding: 0;
  flex: 1;
  min-height: 0;
}
.wizard-modal-wide .footer {
  flex-shrink: 0;
}
.wizard-modal-fullscreen .body {
  padding: 0;
  flex: 1;
  min-height: 0;
}
.wizard-modal-fullscreen .wizard-alt-layout {
  grid-template-columns: minmax(0, 1fr) 360px;
  min-height: 0;
}
.wizard-alt-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 0;
  height: 100%;
  min-height: 0;
}
.wizard-chain-map-pane {
  position: relative;
  min-height: 0;
  background: #ddd;
}
.wizard-chain-map-toolbar {
  position: absolute; top: 0.75rem; left: 4rem; z-index: 500;
  display: flex; gap: 0.4rem; flex-wrap: wrap;
  pointer-events: none;
}
.wizard-chain-map-toolbar .wizard-chain-zoom-btn {
  pointer-events: auto;
  padding: 0.35rem 0.65rem; border-radius: 999px;
  border: 1px solid rgba(0,0,0,0.08); background: rgba(255,255,255,0.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow: var(--shadow-sm);
  font-size: 0.82rem;
}
.wizard-chain-map-toolbar .wizard-chain-zoom-btn:hover { background: white; }
.wizard-chain-map { background: #ddd; min-height: 0; height: 100%; }
.map-loading-veil {
  position: absolute; inset: 0; z-index: 1000;
  background: var(--surface-bg, #f5f5f7);
  display: flex; align-items: center; justify-content: center;
  transition: opacity 0.4s ease;
}
.map-loading-veil.fading { opacity: 0; pointer-events: none; }
.osm-retina-layer { transition: opacity 0.25s ease; }
.wizard-chain-aside {
  border-left: 1px solid var(--hairline); padding: 0.8rem 1rem; overflow-y: auto;
  display: flex; flex-direction: column; gap: 0.6rem;
}
.wizard-chain-aside #upload-banner-slot:empty { display: none; }
.wizard-chain-aside[hidden] { display: none; }
.wizard-chain-header {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
}
.wizard-chain-header h3 {
  margin: 0; font-size: 0.8rem; color: #555;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.wizard-chain-count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 3.2rem; padding: 0.2rem 0.45rem;
  border-radius: 999px; background: #e8f1ff; color: #1f4f8b;
  border: 1px solid #b9d2f4;
  font-size: 0.78rem; font-weight: 600; flex-shrink: 0;
}
.wizard-alt-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.wizard-alt-list[hidden] { display: none; }
.wizard-alt-entry {
  border-radius: 6px;
}
.wizard-alt-card {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  width: 100%;
  padding: 0.7rem 0.75rem;
  border: 1px solid #d9e2ea;
  border-radius: 6px;
  background: #fbfdff;
  text-align: left;
}
.wizard-alt-card:hover {
  border-color: #8aa0b8;
  background: #f5f9ff;
}
.wizard-alt-card.hovered {
  border-color: var(--accent);
  background: #eef4ff;
}
.wizard-alt-card.selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px rgba(99, 102, 241, 0.15);
}
.wizard-alt-card.partial {
  border-color: var(--accent-border);
  background: #f4f5fe;
}
.wizard-alt-card-body {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.wizard-alt-card-title {
  font-weight: 600;
  font-size: 0.95rem;
  color: #243447;
}
.wizard-alt-card-meta {
  font-size: 0.8rem;
  color: #6b7280;
}
.wizard-draft-section {
  padding: 0.7rem;
  border: 1px solid #d9e2ea;
  border-radius: 6px;
  background: #f8fafc;
}
.wizard-draft-header {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
}
.wizard-draft-header h3 {
  margin: 0; font-size: 0.8rem; color: #555;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.wizard-draft-selected-name {
  margin-top: 0.2rem;
  color: #243447;
  font-size: 0.92rem;
  font-weight: 650;
  line-height: 1.25;
}
.wizard-draft-toggle {
  padding: 0.25rem 0.5rem; background: white;
  border: 1px solid #b7c4cf; border-radius: 4px; font-size: 0.78rem;
}
.wizard-draft-toggle:disabled { opacity: 0.45; }
.wizard-draft-status {
  margin: 0.45rem 0 0; color: #4b5563; font-size: 0.82rem;
}
.wizard-draft-edit-hint {
  margin: 0.35rem 0 0;
  color: #667085;
  font-size: 0.78rem;
  line-height: 1.35;
}
.wizard-draft-error {
  margin: 0.45rem 0 0; padding: 0.45rem 0.55rem;
  border-left: 3px solid #c0392b; background: #fff1ef;
  color: #8f251c; font-size: 0.8rem;
}
.wizard-create-hint {
  color: #8f251c; font-size: 0.85rem; font-weight: 500;
  margin-right: auto; padding-left: 0.5rem;
}
.wizard-draft-list {
  list-style: none; margin: 0.6rem 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.3rem;
}
.wizard-draft-item {
  display: grid; grid-template-columns: 1.5rem minmax(0, 1fr) auto;
  align-items: center; gap: 0.45rem;
  padding: 0.4rem 0.45rem; background: white;
  border: 1px solid var(--border); border-radius: 4px;
}
.wizard-draft-order {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; border-radius: 50%;
  background: var(--accent); color: white; font-size: 0.72rem; font-weight: 600;
}
.wizard-draft-name {
  overflow: hidden; text-overflow: ellipsis;
  color: #243447; font-size: 0.82rem;
}
.wizard-draft-remove {
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: #a93226;
  line-height: 1;
}
.wizard-draft-remove:hover {
  border-color: #d39a90;
  background: #fff1ef;
}
.wizard-draft-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.65rem;
  padding-top: 0.55rem;
  border-top: 1px solid rgba(198, 117, 48, 0.25);
}
.wizard-draft-remove-route {
  padding: 0.28rem 0.5rem;
  border: 1px solid #d39a90;
  border-radius: 4px;
  background: rgba(255,255,255,0.8);
  color: #a93226;
  font-size: 0.76rem;
}
.wizard-draft-remove-route:hover { background: #fff1ef; }

.wizard-shared-choice {
  position: absolute;
  z-index: 1100;
  top: 1rem;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: min(360px, calc(100% - 2rem));
  padding: 0.8rem;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
}
.wizard-shared-choice[hidden] { display: none; }
.wizard-shared-choice-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.wizard-shared-choice-header h3 {
  margin: 0;
  color: #243447;
  font-size: 0.9rem;
}
.wizard-shared-choice-close {
  padding: 0 0.25rem;
  border: 0;
  background: transparent;
  color: #687584;
  font-size: 1.25rem;
  line-height: 1;
}
.wizard-shared-choice-help {
  margin: 0.25rem 0 0.6rem;
}
.wizard-shared-choice-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.wizard-shared-choice-option {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  width: 100%;
  padding: 0.55rem 0.65rem;
  border: 1px solid #cfd9e4;
  background: #f8faff;
  text-align: left;
}
.wizard-shared-choice-option:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.wizard-shared-choice-option strong {
  color: #243447;
  font-size: 0.86rem;
}
.wizard-shared-choice-option span {
  color: #6b7280;
  font-size: 0.75rem;
}

.wizard-survey-name {
  width: 100%; padding: 0.4rem 0.6rem; border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 0.95rem;
}

/* --- Route assembly (leg-based) --- */
.route-assembly { display: grid; grid-template-columns: 1fr 380px; height: 100%; }
.route-assembly #map { background: #ddd; }
.route-assembly aside { display: flex; flex-direction: column; border-left: 1px solid var(--hairline); background: white; overflow: hidden; }
.route-assembly aside .section { padding: 0.6rem 1rem; border-bottom: 1px solid var(--hairline); flex-shrink: 0; }
.route-assembly aside .section h3 { margin: 0 0 0.4rem; font-size: 0.85rem; color: #555; text-transform: uppercase; letter-spacing: 0.05em; }
.route-assembly aside .section p { margin: 0; font-size: 0.8rem; color: #777; }
.route-assembly aside ul { list-style: none; padding: 0; margin: 0; }

.route-assembly aside .list-section {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}
.route-assembly aside .list-section ul {
  flex: 1 1 auto;
  min-height: 60px;
  max-height: none;
  overflow-y: auto;
  padding-right: 4px;
}

.route-assembly aside #legs-route {
  border: 1px solid var(--border); border-radius: var(--radius); background: #fafafa;
  padding: 0.25rem; min-height: 80px;
}
.route-assembly aside .empty-hint {
  font-size: 0.8rem; color: #999; font-style: italic; margin: 0.4rem 0 0;
}

.route-assembly aside li {
  padding: 0.4rem 0.5rem; border: 1px solid transparent; margin-bottom: 0.2rem; border-radius: 3px;
  display: flex; gap: 0.5rem; align-items: center; cursor: pointer;
  background: white;
}
.route-assembly aside li:hover { background: #eaf3ff; border-color: #0066cc; }

.route-assembly aside li.leg-item { background: var(--accent-soft); border-color: #a5a9f3; }
.route-assembly aside li.leg-item:hover { background: #dfe2fc; }
.route-assembly aside li .order-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--accent); color: white;
  font-size: 0.75rem; font-weight: 600; flex-shrink: 0;
}

.route-assembly aside li .segment-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.route-assembly aside li .vert-count { color: #888; font-size: 0.75rem; flex-shrink: 0; }
.route-assembly aside .route-edit-hint {
  margin: 0 0 0.5rem;
}
.route-assembly aside .route-edit-status {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 1.4rem;
  margin: -0.1rem 0 0.45rem;
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 600;
}
.route-assembly aside .route-edit-status[hidden] { display: none; }
.route-assembly aside .route-edit-spinner {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border-width: 2px;
}
.route-assembly[aria-busy="true"] .route-segment-hit-target { cursor: progress; }
.route-assembly aside li .leg-remove {
  flex-shrink: 0; width: 1.4rem; height: 1.4rem; padding: 0; border-radius: 50%;
  border: 1px solid #d9a5a5; background: white; color: #a93226; font-size: 0.8rem;
  line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.route-assembly aside li .leg-remove:hover { background: #a93226; color: white; border-color: #a93226; }
.route-assembly aside li .leg-remove:disabled,
.route-assembly aside li .leg-trim-reset:disabled {
  cursor: progress;
  opacity: 0.45;
}
/* An end segment only partly inside the survey. The count shown is the
   surveyed length, so it needs to look different from a segment that is
   simply that short — the dotted rule reads as "cut", and the title carries
   the full length. */
.route-assembly aside li .vert-count.leg-length-trimmed {
  color: #4f46e5; border-bottom: 1px dotted #4f46e5; cursor: help;
}
.route-assembly aside li .leg-trim-reset {
  flex-shrink: 0; width: 1.4rem; height: 1.4rem; padding: 0; border-radius: 50%;
  border: 1px solid #b8bcf0; background: white; color: #4f46e5; font-size: 0.85rem;
  line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.route-assembly aside li .leg-trim-reset:hover { background: #4f46e5; color: white; border-color: #4f46e5; }

.route-assembly aside .footer { padding: 1rem; border-top: 1px solid var(--hairline); display: flex; justify-content: space-between; gap: 0.5rem; flex-shrink: 0; }

/* Leaflet overrides */
.leaflet-container { background: #eaeaea; }
.leaflet-container .leaflet-interactive:focus {
  outline: none;
}
.leaflet-top.leaflet-left {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}
.leaflet-top.leaflet-left .leaflet-control {
  margin-right: 0;
}
.map-overview-control {
  overflow: hidden;
}
.map-overview-control-button {
  height: 30px;
  padding: 0 0.72rem;
  border: 0;
  background: #fff;
  color: #1f2937;
  cursor: pointer;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
  line-height: 30px;
}
.map-overview-control-button:hover {
  background: #f4f7fb;
}

/* Slow Leaflet's zoom animation globally. Leaflet drives the *zoom* portion
   of every fitBounds/setView/wheel zoom with this CSS transition (the JS
   `duration` option only affects panning), defaulting to a brisk 0.25s that
   reads as abrupt. Easing it to 0.55s makes every zoom — hover, selection,
   trackpad, zoom buttons — feel smooth and deliberate. Tiles keep Leaflet's
   own (transition: none) rule, so only the map layer eases. */
.leaflet-zoom-anim .leaflet-zoom-animated {
  transition: transform 0.55s cubic-bezier(0, 0, 0.25, 1);
}
.wizard-chain-map .leaflet-overlay-pane path.leaflet-interactive,
.wizard-chain-map .leaflet-overlay-pane path.wizard-route-visual {
  vector-effect: non-scaling-stroke;
}
.route-segment-hit-target,
.route-segment-blocked-hit-target,
.route-segment-visual {
  vector-effect: non-scaling-stroke;
}
.route-segment-endpoint {
  pointer-events: none;
  vector-effect: non-scaling-stroke;
}
.route-segment-hit-target {
  cursor: pointer;
}
.route-segment-blocked-hit-target {
  /* Informational, not clickable: it reveals why the segment is refused, so it
     must not borrow the addable "pointer" cursor. */
  cursor: help;
}
.wizard-chain-map .leaflet-overlay-pane svg.leaflet-zoom-animated {
  /* Leaflet's will-change hint makes Chrome cache this SVG as a bitmap and
     enlarge that bitmap during zoom. Let Chrome keep it as vector artwork so
     route strokes stay sharp while sharing the exact tile transform. */
  will-change: auto;
}
.review-camera-controlled.leaflet-zoom-anim .leaflet-zoom-animated {
  transition: transform 2.4s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Keep pins crisp during the camera flight. flyTo repositions each marker every
   frame, but the long zoom transition above makes each frame linger — so the
   pins smear into a trail. Dropping the transition on the marker icons lets
   Leaflet snap their complete 36 px symbols to each frame, so they stay legible
   throughout the flight. Tiles/route keep the eased zoom via
   .leaflet-zoom-animated. */
.review-camera-controlled .leaflet-marker-icon {
  transition: none !important;
}
/* Filled route-foot circles cannot be inverse-scaled like line weights, so
   suppress them while Leaflet stretches its existing SVG between zooms. */
.review-camera-controlled .waypoint-route-foot {
  opacity: 0;
}

/* Map legend (top-right corner). */
.map-legend {
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  font-size: 0.75rem;
  line-height: 1.4;
}
.map-legend h4 {
  margin: 0 0 0.3rem; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.05em; color: #555;
}
.map-legend div { display: flex; align-items: center; gap: 0.5rem; }
.map-legend .swatch { display: inline-block; flex-shrink: 0; }
.map-legend .swatch-line-selected { width: 1.4rem; height: 7px; background: var(--accent); }
/* Leaflet keeps every tooltip on a single line, so a full sentence — the
 * reason a segment cannot be added — runs past the edge of the map pane and is
 * clipped by it. Segment names are short enough to be unaffected by the cap. */
.leaflet-tooltip {
  white-space: normal;
  /* Leaflet's tooltip pane is a zero-size positioned box, so without an
   * explicit width `normal` shrink-wraps to the longest single word and the
   * sentence becomes a tall sliver. `max-content` restores the natural line,
   * and the cap is what makes it wrap instead of leaving the pane. */
  width: max-content;
  max-width: min(24rem, 45vw);
  line-height: 1.35;
}

.route-map-legend {
  min-width: 12rem;
  max-width: 16rem;
}
.route-map-legend .swatch-line-route-current {
  width: 1.4rem; height: 5px; background: #6366f1;
}
.route-map-legend .swatch-line-route-main {
  width: 1.4rem; height: 4px; background: #475569; opacity: 0.9;
}
.map-legend .swatch-line-route-addable {
  width: 1.4rem;
  height: 3px;
  background: repeating-linear-gradient(to right, #0057b8 0 3px, transparent 3px 6px);
}
/* The route editor's wider gaps match its SVG dashArray and butt line caps.
   Keep the alternative chooser's existing swatch separate from this style. */
.route-map-legend .swatch-line-route-addable {
  width: 34px; height: 3px; opacity: 0.95;
  background: repeating-linear-gradient(to right, #0057b8 0 6px, transparent 6px 14px);
}
.route-map-legend .swatch-segment-endpoint {
  width: 8px; height: 8px; border-radius: 50%;
  background: #fff; border: 1.25px solid #475569;
}
/* Matches SEGMENT_STYLE_TRIMMED_OFF: the stretch of an end segment the
   surveyor moved Anfang or Ende past, still drawn so its exclusion is
   visible rather than silent. */
.route-map-legend .swatch-line-route-trimmed {
  width: 34px; height: 4px; opacity: 0.4;
  background: repeating-linear-gradient(to right, #6366f1 0 2px, transparent 2px 9px);
}
.route-map-legend .swatch-line-route-blocked {
  width: 1.4rem;
  height: 3px;
  background: repeating-linear-gradient(to right, #b42318 0 2px, transparent 2px 6px);
}
.route-map-legend .route-map-legend-note {
  margin: 0.2rem 0 0;
  color: #666;
  font-style: italic;
}
.wizard-map-legend { min-width: 11rem; }
.wizard-map-legend .swatch-line-picker-main { width: 1.4rem; height: 5px; background: #6d7f90; opacity: 0.8; }
.wizard-map-legend .swatch-line-picker-variant { width: 1.4rem; height: 6px; background: #8e44ad; opacity: 0.95; }
.wizard-map-legend .swatch-line-picker-variant-thin { width: 1.4rem; height: 6px; background: #16a085; opacity: 0.95; }
/* Waypoint-pin legend swatches mirror the pin colours (see .wp-pin). */
.wp-map-legend { max-width: 17rem; }
.wp-map-legend div { align-items: flex-start; }
.map-legend .swatch-dot-wp {
  width: 0.8rem; height: 0.8rem; border-radius: 50%;
  border: 2px solid white; box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
  background: var(--wp-status-open); margin-top: 0.1rem;
}
.map-legend .swatch-dot-wp[data-status="open"][data-info-state="prefilled"] { background: var(--wp-status-open-prefilled); }
.map-legend .swatch-dot-wp[data-status="open"][data-info-state="edited"] { background: var(--wp-status-open-edited); }
.map-legend .swatch-dot-wp[data-status="erledigt"] { background: var(--wp-status-erledigt); }
.map-legend .swatch-dot-wp[data-status="ignoriert"] { background: var(--wp-status-ignoriert); }
.map-legend .swatch-dot-wp[data-outside-route="true"] {
  opacity: 0.5;
  outline: 2px dashed var(--wp-status-ignoriert);
  outline-offset: 1px;
}

/* --- Review --- */
/* --- Review (map-centric) --- */
.review-map-screen {
  height: 100%; display: flex; flex-direction: column;
  padding: 0; max-width: none; margin: 0;
}
.review-toolbar {
  position: relative;
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding: 0.5rem 1rem; border-bottom: 1px solid var(--hairline, rgba(0,0,0,0.07));
  background: rgba(250, 250, 252, 0.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  /* Leaflet panes/controls occupy z-index levels up to 1000. Keep the
   * complete toolbar stacking context above them so dropdown panels are not
   * invisibly painted underneath the map after their trigger is clicked. */
  z-index: 1200;
  overflow: visible;
}
/* Back + map actions sit together on the left; everything after this group is
   pushed to the right edge. */
.review-toolbar-lead { margin-right: auto; }

/* Read-only project access. The badge and the notice say it once in words;
   the locked controls stay on screen so a viewer still sees what was chosen. */
.read-only-badge {
  display: inline-flex;
  align-items: center;
  margin-left: 0.5rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid #f0d58a;
  border-radius: 999px;
  background: #fff3cd;
  color: #7a5600;
  font-size: 0.85rem;
  font-weight: 650;
  vertical-align: middle;
  cursor: help;
}
.read-only-notice {
  margin: 0.5rem 0 0;
  padding: 0.45rem 0.65rem;
  border-left: 3px solid #d9a400;
  background: #fff3cd;
  color: #5c4100;
  font-size: 0.85rem;
  line-height: 1.35;
}
.route-assembly aside > .read-only-notice { margin: 0.6rem 1rem 0; }
.read-only-control:disabled { cursor: not-allowed; opacity: 0.45; }
/* A locked status, severity or "Im Dokument" tick is still the answer the
   surveyor gave, so the chosen one stays fully legible. */
.read-only-control:disabled:is(.is-active, .active, :checked) { opacity: 1; }
:is(input[type="text"], textarea).read-only-control:disabled {
  opacity: 1;
  background: #f3f4f6;
  color: var(--text);
  -webkit-text-fill-color: var(--text);
}
.review-toolbar-action {
  min-height: 2.55rem;
  padding: 0.52rem 1rem;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.86);
  color: var(--brand-2);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 650;
  line-height: 1.1;
  list-style: none;
  user-select: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s, box-shadow 0.12s;
}
.review-toolbar-action:hover {
  background: #fff;
  border-color: #8f98ee;
  box-shadow: var(--shadow-md);
}
.review-filter-panel {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.55rem;
  padding: 0.22rem 0.35rem 0.22rem 0.65rem;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.86);
  box-shadow: var(--shadow-sm);
  white-space: nowrap;
}
.review-filter-heading {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--brand-2);
  font-size: 0.78rem;
  font-weight: 750;
}
.review-filter-heading::before {
  content: "";
  width: 0.78rem;
  height: 0.72rem;
  flex: 0 0 auto;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 62% 48%, 62% 100%, 38% 82%, 38% 48%);
}
.review-filter-field {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding-left: 0.6rem;
  border-left: 1px solid var(--border);
}
.review-filter-label {
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 700;
}
.review-filter-toggle {
  display: inline-flex;
  align-items: stretch;
  overflow: hidden;
  border: 1px solid #cbd2dc;
  border-radius: 7px;
  background: #f2f4f7;
}
.review-filter-option {
  border: 0;
  border-left: 1px solid #d7dce4;
  background: #fff;
  color: var(--text);
  border-radius: 0;
  padding: 0.36rem 0.58rem;
  min-height: 2rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 650;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, box-shadow 0.12s;
}
.review-filter-option:first-child { border-left: 0; }
.review-filter-option:hover {
  background: var(--accent-soft);
}
.review-filter-option.is-active {
  background: var(--accent);
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
}
.review-filter-option.is-active:hover {
  background: #5357d8;
}
.review-filter-option:focus-visible {
  position: relative;
  z-index: 1;
  outline: none;
  box-shadow: var(--focus-ring);
}
.review-filter-count {
  min-width: 1.15rem;
  padding: 0.08rem 0.3rem;
  border-radius: 999px;
  background: #eef1f5;
  color: var(--text-muted);
  text-align: center;
  font-size: 0.72rem;
  font-weight: 750;
}
.review-filter-option.is-active .review-filter-count {
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
}
/* Independent severity filter, standing next to the status group rather than
   inside it: it combines with whichever status is selected. Its own border
   makes the checkbox-shaped control a distinct click target. */
.review-severity-filter {
  min-height: 2.1rem;
  padding: 0.34rem 0.58rem;
  border: 1px solid #cbd2dc;
  border-radius: 7px;
  font-size: 0.82rem;
  white-space: nowrap;
}
.review-filter-check {
  position: relative;
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
  border: 1.5px solid #8a94a3;
  border-radius: 4px;
  background: #fff;
}
.review-severity-filter.is-active .review-filter-check {
  border-color: #fff;
  background: #fff;
}
.review-severity-filter.is-active .review-filter-check::after {
  content: "";
  position: absolute;
  left: 0.26rem;
  top: 0.08rem;
  width: 0.25rem;
  height: 0.5rem;
  border: solid var(--accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
/* The checkbox shape makes the independent on/off behaviour visible; the
   pressed treatment then matches the selected status button. */
.review-severity-filter.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.review-severity-filter.is-active:hover {
  background: #5357d8;
}
.review-toolbar-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
.review-toolbar-primary:hover {
  background: #5357d8;
  border-color: #5357d8;
}
.review-road-status {
  display: grid;
  gap: 0.3rem;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 20rem;
  color: var(--text-muted);
  font-size: 0.72rem;
}
.review-road-status[hidden] { display: none; }
.review-road-status.is-error { color: #a33a31; }
.review-road-status-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.review-road-status-message {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.review-road-status-spinner {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  border-width: 2px;
}
.review-road-status-detail {
  color: var(--text-muted);
  font-size: 0.68rem;
}
.review-progress-bar {
  width: 100%;
  height: 7px;
  overflow: hidden;
  border: none;
  border-radius: 999px;
  background: #e2e8f0;
  accent-color: var(--accent);
}
.review-progress-bar::-webkit-progress-bar {
  border-radius: 999px;
  background: #e2e8f0;
}
.review-progress-bar::-webkit-progress-value {
  border-radius: 999px;
  background: var(--accent);
}
.review-progress-bar::-moz-progress-bar {
  border-radius: 999px;
  background: var(--accent);
}
.review-map-wrap { position: relative; flex: 1; min-height: 0; }
#review-map { width: 100%; height: 100%; background: #eaeaea; }
.review-map-wrap.is-adding-waypoint .leaflet-container,
.review-map-wrap.is-adding-waypoint .leaflet-interactive,
.review-map-wrap.is-moving-waypoint .leaflet-container {
  cursor: crosshair;
}
/* Leaflet's panes and controls occupy z-index levels up to 1000 in this same
 * stacking context, so anything meant to float over the map has to clear that
 * — below 1000 it is painted underneath the tiles and simply never seen. Stay
 * under the toolbar (1200) and the waypoint modal (1250). */
.review-add-waypoint-hint {
  position: absolute; top: 1rem; left: 50%; z-index: 1100;
  transform: translateX(-50%);
  padding: 0.45rem 0.75rem;
  background: rgba(36, 52, 71, 0.86); color: white;
  border-radius: var(--radius);
  font-size: 0.86rem; font-weight: 700;
  pointer-events: none;
  box-shadow: var(--shadow-md);
}
/* In the toolbar rather than over the map: the waypoint editor covers the
   map's bottom-right corner, where this button used to live. */
.review-add-waypoint {
  font-size: 0.85rem;
  white-space: nowrap;
}
.review-add-waypoint:hover { background: #f0f7ff; border-color: var(--accent); }
.review-add-waypoint.is-active {
  background: var(--accent); color: white; border-color: var(--accent);
}
.review-add-waypoint:disabled {
  opacity: 0.62; cursor: wait; transform: none;
}
.review-waypoint-move-controls {
  position: absolute;
  top: 1rem;
  left: 50%;
  z-index: 1100;  /* over Leaflet's panes — see .review-add-waypoint-hint */
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 0.65rem;
  max-width: calc(100% - 2rem);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid rgba(36, 52, 71, 0.18);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.review-waypoint-move-hint { font-size: 0.86rem; font-weight: 700; white-space: nowrap; }
.review-waypoint-move-controls button { white-space: nowrap; }

/* Dev-only reset: tucked into the bottom-right corner, greyed and quiet so
 * it never competes with the primary flow. Reveals its destructive red only
 * on hover. Hidden entirely when there are no surveys (see showStartScreen). */
.reset-state {
  position: fixed; right: 1.25rem; bottom: 1.5rem; z-index: 5;
  margin: 0; padding: 0; border: none;
}
.reset-state-btn {
  padding: 0.3rem 0.65rem; background: rgba(255, 255, 255, 0.6);
  color: var(--text-muted); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer;
  font: inherit; font-size: 0.76rem; opacity: 0.7;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  transition: opacity 0.12s, color 0.12s, border-color 0.12s, background 0.12s;
}
.reset-state-btn:hover:not(:disabled) {
  opacity: 1; background: #fff; color: #c0392b; border-color: #e0a09a;
}
.reset-state-btn:disabled { opacity: 0.6; cursor: wait; }

/* Numbered waypoint pins on the review map.
 * Base colour encodes the waypoint's review status (open/erledigt/ignoriert);
 * .wp-pin-open adds a selection ring without recolouring, so the active pin
 * keeps showing its status. */
.wp-pin-icon { background: transparent; border: none; }
.wp-pin {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--wp-status-open); color: white; border: 3px solid white;
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.85rem; font-weight: 700; font-variant-numeric: tabular-nums;
  cursor: pointer; transition: background 0.1s, opacity 0.1s, filter 0.1s, box-shadow 0.1s;
}
.wp-pin[data-status="open"][data-info-state="prefilled"] { background: var(--wp-status-open-prefilled); }
.wp-pin[data-status="open"][data-info-state="edited"] { background: var(--wp-status-open-edited); }
.wp-pin[data-status="erledigt"] { background: var(--wp-status-erledigt); }
.wp-pin[data-status="ignoriert"] { background: var(--wp-status-ignoriert); opacity: 0.72; }
/* A waypoint the route's moved Anfang / Ende leaves out of the document. Its
   status is untouched — that stays the surveyor's call — so it is marked by
   its own attribute: faded like an excluded pin, with a dashed ring saying
   the reason is the route rather than a decision about the waypoint. */
.wp-pin[data-outside-route="true"] {
  opacity: 0.5;
  outline: 2px dashed var(--wp-status-ignoriert);
  outline-offset: 2px;
}
.wp-pin.wp-pin-filtered {
  opacity: 0.34;
  filter: grayscale(0.45);
  cursor: default;
  box-shadow: 0 1px 3px rgba(0,0,0,0.22);
}
.wp-pin:hover {
  filter: brightness(1.15);
  opacity: 1;
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.28), 0 1px 4px rgba(0,0,0,0.4);
}
.wp-pin.wp-pin-filtered:hover {
  filter: grayscale(0.45);
  opacity: 0.42;
}
.wp-pin-open {
  opacity: 1;
  box-shadow: 0 0 0 6px rgba(99, 102, 241, 0.45), 0 1px 4px rgba(0, 0, 0, 0.4);
}
/* The selected pin (and the one being moved) is draggable — say so with the
   cursor, since nothing else advertises that the pin can be picked up. */
.leaflet-marker-draggable .wp-pin { cursor: grab; }
.leaflet-dragging .leaflet-marker-draggable .wp-pin { cursor: grabbing; }
/* Drop targets while a photo is being dragged over the map.
 * Eligible pins are lifted as a set so the surveyor can see where a photo may
 * go at all; the one under the pointer then gets an unmistakable state. Both
 * keep the waypoint number readable, and both are purely additive — the pin's
 * status colour still means what it always did. */
.wp-pin { position: relative; }
/* Both scoped to an actual drag, and the target rule out-specifies the eligible
   one: they land on the same pin the moment the pointer reaches it, so the
   stronger state has to win on specificity rather than on source order. */
body.is-dragging-photo .wp-pin.wp-pin-drop-eligible {
  opacity: 1;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.9), 0 2px 8px rgba(0, 0, 0, 0.45);
  transform: scale(1.08);
}
body.is-dragging-photo .wp-pin.wp-pin-droptarget {
  background: var(--wp-status-erledigt);
  transform: scale(1.35);
  box-shadow:
    0 0 0 4px #fff,
    0 0 0 9px rgba(39, 174, 96, 0.9),
    0 4px 14px rgba(0, 0, 0, 0.45);
  z-index: 1;
}
/* The cue names the target in words. Pinned below the pin and centred on it,
   so it never sits over the number. */
.wp-pin-drop-cue {
  position: absolute;
  top: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  background: var(--wp-status-erledigt);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* Route start / end labels — small pills that sit on the documented
 * KMZ endpoints regardless of whether photos exist there. Kept lighter
 * than the numbered waypoint pins so they read as context. */
.route-endpoint-icon { background: transparent; border: none; overflow: visible; }
/* Centred on the anchor point by transform rather than by the icon box, so a
 * longer label ("Anfang") still sits on the route end instead of drifting off
 * it by the overflow. */
.route-endpoint {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: white;
  padding: 0.18rem 0.45rem; border-radius: 3px;
  border: 2px solid white; white-space: nowrap;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.route-endpoint-start { background: #27ae60; }  /* green */
.route-endpoint-end { background: #c0392b; }    /* red */
/* Before clustering these two pills are handles: dragging one moves where the
   survey begins or ends along its own end segment. The grab cursor and the
   grip dots say so; after clustering the route is frozen and they go back to
   being plain labels. */
.route-endpoint-draggable { cursor: grab; padding-left: 0.7rem; }
.route-endpoint-draggable::before {
  content: ""; position: absolute; left: 0.22rem; top: 50%;
  width: 2px; height: 8px; transform: translateY(-50%);
  background-image: radial-gradient(circle, white 1px, transparent 1px);
  background-size: 2px 3px; opacity: 0.85;
}
.leaflet-dragging .route-endpoint-draggable { cursor: grabbing; }

/* Waypoint modal — lives as a side panel on the right so the map (and
 * every other pin) stays visible while the user reviews one waypoint.
 * It must also sit above the review toolbar/settings dropdown, which in turn
 * sits above Leaflet. */
.wp-modal-backdrop {
  z-index: 1250;
  background: transparent;
  display: block;
  pointer-events: none;  /* clicks pass through to the map */
  /* This backdrop spans the whole viewport but must NOT blur the map —
   * it only hosts the side panel. Cancel the blur inherited from
   * .modal-backdrop so the selected waypoint and its surroundings stay sharp. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.wp-modal {
  position: fixed;
  right: 0; top: 0; bottom: 0;
  width: clamp(440px, 50vw, 760px);
  max-width: none;
  max-height: none;
  display: flex; flex-direction: column;
  pointer-events: auto;
  border-radius: 12px 0 0 0; overflow: hidden;
  box-shadow: -8px 0 28px rgba(16, 24, 40, 0.18);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-right: none;
  border-bottom: none;
  transition: opacity 0.15s, transform 0.15s;
  animation: slide-in-right 0.24s var(--ease-spring);
}
.wp-modal-backdrop.wp-modal-swap,
.wp-modal-backdrop.wp-modal-swap .wp-modal {
  animation: none;
}
body.modal-collapsed .wp-modal {
  /* During a photo drag, fade the modal a bit so the pin under the
   * cursor is unmistakable, but stay visible enough that the surveyor
   * can see what they're dragging from. */
  opacity: 0.45;
  pointer-events: none;
}

/* --- Photo drag-and-drop: reorder within a waypoint, move to a neighbour --- */
.wp-photo-card.dragging {
  opacity: 0.4;
  cursor: grabbing;
}

/* Edge rails for moving a photo into the previous/next waypoint. Hidden
 * until a photo drag begins, then slid in over the modal's left/right edge. */
.wp-move-rail {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 64px;
  z-index: 6;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  color: var(--brand-2);
  font-weight: 600;
  font-size: 0.82rem;
  background: rgba(99, 102, 241, 0.10);
  border: 2px dashed rgba(99, 102, 241, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  transition: background 0.12s, border-color 0.12s;
}
.wp-move-rail-left { left: 0; border-radius: 12px 0 0 12px; border-right: none; }
.wp-move-rail-right { right: 0; border-radius: 0 12px 12px 0; border-left: none; }
.wp-move-rail-label {
  padding: 0 0.4rem;
  line-height: 1.35;
}
body.is-dragging-photo .wp-move-rail {
  display: flex;
  pointer-events: auto;
}
.wp-move-rail.droptarget {
  background: rgba(99, 102, 241, 0.24);
  border-color: var(--accent);
  border-style: solid;
}

/* Floating preview that follows the pointer/finger during a drag. */
.wp-drag-ghost {
  position: fixed;
  z-index: 3000;
  width: 96px;
  height: 96px;
  margin: 0;
  transform: translate(-50%, -50%) rotate(-3deg);
  border-radius: 10px;
  overflow: hidden;
  pointer-events: none;
  box-shadow: var(--shadow-lg);
  border: 2px solid white;
  opacity: 0.92;
}
.wp-drag-ghost img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Over the map the preview stands off the pointer and shrinks: at full size,
   centred, it covers a 36 px pin and all of its drop feedback at exactly the
   moment that feedback is needed. */
.wp-drag-ghost.over-map {
  width: 64px;
  height: 64px;
  opacity: 0.72;
  /* Up and to the right of the pointer: below it is where the target pin's
     "Hier ablegen" cue sits, and the point of standing the preview off the
     pointer is that neither the pin nor its cue ends up underneath it. */
  transform: translate(22px, -88px) rotate(-3deg);
}
/* A finger hides what is under it, so on touch the preview sits above the
   contact point whether or not it has reached the map yet. */
.wp-drag-ghost.touch { transform: translate(-50%, -150%) rotate(-3deg); }
.wp-drag-ghost.touch.over-map { transform: translate(-50%, -190%) rotate(-3deg); }

/* A press-hold drag must not select text or pop the iOS callout. Cards opt out
 * of selection; their text controls opt back in so editing still works. */
.wp-photo-card { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.wp-photo-card input, .wp-photo-card textarea {
  -webkit-user-select: text; user-select: text;
}
body.is-dragging-photo { -webkit-user-select: none; user-select: none; }

.wp-modal-head {
  display: grid;
  grid-template-rows: auto auto auto;
  gap: 0.55rem;
  padding: 0.65rem 0.9rem;
  background: rgba(236, 240, 241, 0.9);
  backdrop-filter: blur(6px) saturate(150%);
  -webkit-backdrop-filter: blur(6px) saturate(150%);
  border-bottom: 1px solid var(--hairline, rgba(0,0,0,0.07)); flex-shrink: 0;
}
.wp-modal-title-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.65rem;
}
.wp-modal-nav-row,
.wp-modal-position-row,
.wp-modal-photo-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.wp-modal-position-row {
  padding-top: 0.5rem;
  border-top: 1px solid var(--hairline);
}
.wp-modal-position-status { color: var(--muted); font-size: 0.82rem; }
.wp-modal-position-hint {
  margin-right: auto;
  color: var(--text-muted);
  font-size: 0.78rem;
}
.wp-modal-position-hint::before { content: "· "; }
.wp-modal-simulation-field {
  display: grid;
  grid-template-columns: auto minmax(12rem, 1fr);
  align-items: start;
  gap: 0.55rem;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
}
.wp-modal-simulation-field > span { padding-top: 0.45rem; }
.wp-modal-simulation-editor {
  display: grid;
  gap: 0.4rem;
  min-width: 0;
}
.wp-modal-simulation-rows {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.4rem 0.45rem;
  min-width: 0;
}
.wp-modal-simulation-row { display: contents; }
.wp-modal-simulation-input {
  width: 100%;
  min-width: 0;
  padding: 0.42rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font: inherit;
  font-weight: 400;
  line-height: 1.35;
}
.wp-modal-simulation-add,
.wp-modal-simulation-remove {
  padding: 0.42rem 0.6rem;
  border: 1px solid #aaa;
  border-radius: 5px;
  background: white;
  color: var(--text);
  cursor: pointer;
  font: inherit;
  font-weight: 500;
  white-space: nowrap;
}
.wp-modal-simulation-add:hover:not(:disabled),
.wp-modal-simulation-remove:hover { background: #f0f7ff; border-color: var(--accent); }
.wp-modal-simulation-add:disabled { opacity: 0.45; cursor: not-allowed; }
.wp-modal-simulation-remove {
  color: #8f251c;
}
.wp-modal-simulation-field a,
.wp-modal-simulation-legacy a {
  color: #0563c1;
  overflow-wrap: anywhere;
}
.wp-modal-simulation-legacy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.7rem;
  color: var(--muted);
  font-size: 0.78rem;
}
.wp-modal-simulation-legacy-text { overflow-wrap: anywhere; }
.wp-modal-simulation-links { display: grid; gap: 0.2rem; font-weight: 400; }
.wp-modal-simulation { display: grid; gap: 0.4rem; }
.wp-modal-simulation-error { color: #a12b20; font-weight: 400; }
.wp-modal-nav-row {
  padding-top: 0.5rem;
  border-top: 1px solid var(--hairline);
}
.wp-modal-photo-toolbar {
  padding-top: 0.55rem;
  border-top: 1px solid var(--hairline);
}
.wp-modal-nav { display: flex; align-items: center; gap: 0.4rem; }
.wp-nav-btn {
  padding: 0.28rem 0.65rem; background: white; border: 1px solid #aaa;
  border-radius: 5px; font: inherit; cursor: pointer;
  min-width: 7.2rem;
}
.wp-nav-btn:hover:not(:disabled) { background: #f0f7ff; border-color: var(--accent); }
.wp-nav-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.wp-modal-num {
  align-self: center;
  grid-column: 1;
  grid-row: 1;
  font-weight: 700;
  color: var(--brand-2);
  font-size: 1.05rem;
  white-space: nowrap;
}
.wp-modal-location-field {
  grid-column: 1 / -1;
  grid-row: 3;
  display: grid;
  gap: 0.22rem;
  min-width: 0;
}
.wp-modal-location-label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 700;
}
.wp-modal-location-kind {
  padding: 0.05rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.72);
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 600;
}
.wp-modal-location {
  width: 100%;
  min-width: 0;
  padding: 0.36rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
}
.wp-modal-count {
  color: #555;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  margin-right: auto;
}
.wp-modal-toggle {
  padding: 0.25rem 0.6rem; background: white; border: 1px solid #aaa;
  border-radius: 5px; cursor: pointer; font: inherit; font-size: 0.82rem;
}
.wp-modal-toggle:hover { background: #f0f7ff; border-color: var(--accent); }
.wp-modal-status {
  grid-column: 1 / -1;
  grid-row: 2;
  justify-self: start;
  display: inline-flex; align-items: center; gap: 0.2rem;
  padding: 0.1rem;
  border: 1px solid #aaa; border-radius: 6px;
  background: white;
}
.wp-modal-status-btn {
  padding: 0.25rem 0.7rem; background: white; border: none;
  border-radius: 5px; cursor: pointer; font: inherit;
  font-size: 0.82rem; color: #333;
  display: inline-flex; align-items: center; gap: 0.4rem;
  transition: background 0.1s, color 0.1s;
}
.wp-modal-status-btn::before {
  content: ""; width: 0.7rem; height: 0.7rem; border-radius: 50%;
  background: var(--wp-status-dot, currentColor); flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.wp-modal-status-btn[data-status="open"]      { --wp-status-dot: var(--wp-status-open); }
.wp-modal-status-btn[data-status="erledigt"]  { --wp-status-dot: var(--wp-status-erledigt); }
.wp-modal-status-btn[data-status="ignoriert"] { --wp-status-dot: var(--wp-status-ignoriert); }
.wp-modal-status-btn:hover:not(.is-active):not(:disabled) { background: #f5f6f8; }
.wp-modal-status-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.wp-modal-status-btn.is-active {
  background: var(--wp-status-dot); color: white; font-weight: 600;
}
.wp-modal-status-btn.is-active::before { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6); }
.wp-evidence-input { display: none; }
.wp-add-evidence {
  color: #176b4d;
  border-color: #5aa889;
}
.wp-add-evidence:hover:not(:disabled) {
  background: #edf8f3;
  border-color: #176b4d;
}
.wp-add-evidence:disabled { opacity: 0.6; cursor: wait; }
.wp-modal-delete {
  grid-column: 3;
  grid-row: 1;
  padding: 0.36rem 0.6rem; background: white; color: #c0392b;
  border: 1px solid #c0392b; border-radius: 5px;
  cursor: pointer; font: inherit; font-size: 0.82rem;
  white-space: nowrap;
}
.wp-modal-delete:hover { background: #fdecea; }
.wp-modal-close {
  grid-column: 4;
  grid-row: 1;
  align-self: center;
  background: transparent; border: none; cursor: pointer;
  font-size: 1.5rem; line-height: 1; color: #555; padding: 0 0.3rem;
}
.wp-modal-close:hover { color: #c0392b; }

.wp-modal-body {
  flex: 1 1 0; overflow-y: auto; padding: 1rem;
  background: rgba(250, 250, 252, 0.86);
  backdrop-filter: blur(6px) saturate(150%);
  -webkit-backdrop-filter: blur(6px) saturate(150%);
}
.wp-modal-empty { color: #888; font-style: italic; text-align: center; padding: 2rem 1rem; }

.wp-photo-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}
.wp-photo-card {
  position: relative;
  background: white; border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; cursor: grab;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s var(--ease-spring), border-color 0.1s, box-shadow 0.1s;
}

/* Compact cards and the final preview share one crop viewport. Explicit
 * dimensions prevent a root SVG's intrinsic aspect ratio making it wider
 * than the photo; cover and slice then have the same scale and origin. */
.photo-preview-media {
  position: relative;
  overflow: hidden;
  flex: 0 0 auto;
}
.wp-photo-media { height: var(--photo-thumb-h); }
.photo-preview-media > img,
.photo-preview-media > .wp-photo-annot-preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.photo-preview-media > img {
  display: block;
  object-fit: cover;
  object-position: center;
}
/* A cropped photo. `object-fit: cover` centres on the *whole* image, so it
   cannot frame an off-centre rectangle; annotation_crop.js sizes and offsets
   the element instead, and the image then fills it exactly — same framing the
   overlay SVG gets from its narrowed viewBox. */
.photo-preview-media > img.photo-crop-framed {
  inset: auto;
  object-fit: fill;
  max-width: none;
}
.wp-photo-annot-preview {
  pointer-events: none; z-index: 1;
}
.wp-photo-card.excluded .wp-photo-annot-preview { opacity: 0.45; }

/* Small launcher for the single-image annotation editor, top-right of the thumb. */
.wp-photo-annotate-btn {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  padding: 0.15rem 0.45rem; min-width: 1.7rem;
  font-size: 0.8rem; line-height: 1.3; font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, 0.85); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  transition: background 0.12s, border-color 0.12s;
}
.wp-photo-annotate-btn:hover { background: white; border-color: var(--accent); }

/* --- Single-image annotation editor (Phase 2) --- */
.annot-editor-backdrop {
  position: fixed; inset: 0; z-index: 2000;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  animation: fade-in 0.18s ease;
}
.annot-editor-panel {
  display: flex; flex-direction: column;
  width: min(92vw, 1100px); max-height: 92vh;
  background: var(--surface); border-radius: 12px;
  box-shadow: var(--shadow-lg); overflow: hidden;
  animation: pop-in 0.22s var(--ease-spring);
}
.annot-editor-head {
  position: relative;
  z-index: 2;
  display: flex; align-items: baseline; gap: 0.6rem;
  padding: 0.7rem 1rem; border-bottom: 1px solid var(--hairline);
  background: var(--surface);
}
.annot-editor-title { font-weight: 600; }
.annot-editor-filename {
  color: var(--text-muted); font-size: 0.85rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.annot-editor-toolbar {
  position: relative;
  z-index: 2;
  border-bottom: 1px solid var(--hairline);
  background: #fafbfc;
}
.annot-toolbar-row {
  display: flex; align-items: stretch; gap: 0.75rem;
  min-width: 0; padding: 0.55rem 1rem;
}
.annot-toolbar-primary { flex-wrap: wrap; }
.annot-toolbar-actions {
  align-items: flex-end;
  flex-wrap: wrap;
  padding-block: 0.45rem;
  border-top: 1px solid var(--hairline);
  background: var(--surface);
}
.annot-toolbar-section {
  display: flex; flex-direction: column; gap: 0.3rem;
  min-width: 0;
}
.annot-toolbar-section[hidden] { display: none; }
.annot-toolbar-section + .annot-toolbar-section {
  padding-left: 0.75rem;
  border-left: 1px solid var(--hairline);
}
.annot-toolbar-section.is-inapplicable .annot-toolbar-label { opacity: 0.5; }
.annot-toolbar-label {
  padding-left: 0.1rem;
  color: var(--text-muted);
  font-size: 0.65rem;
  font-weight: 650;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.annot-toolbar-controls {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem;
}
.annot-toolbar-selection { flex: 0 0 auto; }
.annot-toolbar-drawing { flex: 1 1 34rem; }
.annot-toolbar-colors { flex: 0 0 auto; }
.annot-toolbar-widths { flex: 0 0 auto; }
.annot-tool, .annot-action { white-space: nowrap; }
.annot-tool {
  border-color: transparent;
  background: #eef0f3;
}
.annot-toolbar-selection .annot-tool {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.annot-selection-icon { width: 1rem; height: 1rem; flex: 0 0 auto; }
.annot-tool.active {
  color: white;
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: var(--shadow-sm);
}
.annot-tool.active:hover { background: #5357d8; }
.annot-toolbar-curve-actions .annot-action {
  border-color: var(--border);
  background: var(--surface);
}
.annot-undo {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border-color: var(--border);
  background: var(--surface);
}
.annot-undo-icon {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.annot-toolbar-delete-actions {
  margin-left: auto;
  padding-left: 0.75rem;
  border-left: 1px solid var(--hairline);
}
.annot-toolbar-delete-actions :is(.annot-delete-selected, .annot-clear-all):not(:disabled) {
  color: #a93226;
  border-color: rgba(169, 50, 38, 0.35);
  background: #fff7f6;
}
.annot-toolbar-delete-actions :is(.annot-delete-selected, .annot-clear-all):hover:not(:disabled) {
  border-color: rgba(169, 50, 38, 0.55);
  background: #fceceb;
}
.annot-editor-toolbar button:disabled {
  cursor: not-allowed;
  opacity: 0.45;
  transform: none;
}
.annot-area-draft-fill { fill-opacity: 0.1; pointer-events: none; }
/* 2px matches AREA_STROKE_PX in annotation_model.js, which the finished
   outline is drawn at: the draft and the mark it becomes are the same
   hairline, fixed in screen pixels at any zoom. */
.annot-area-draft-edges, .annot-area-draft-guide {
  fill: none; stroke-width: 2px; stroke-linejoin: round;
  vector-effect: non-scaling-stroke; pointer-events: none;
}
.annot-area-draft-guide { stroke-dasharray: 6 5; }
.annot-area-corner, .annot-area-close-target {
  fill: white; stroke: #1d1d1f; stroke-width: 2px;
  vector-effect: non-scaling-stroke; pointer-events: none;
}
.annot-area-close-target { fill: none; stroke: white; stroke-dasharray: 3 3; }
.annot-area-close-target.active { fill: rgba(255, 255, 255, 0.25); stroke-dasharray: none; }
.annot-color {
  width: 1.7rem; height: 1.7rem; padding: 0; border-radius: 50%;
  border: 2px solid rgba(0, 0, 0, 0.15); cursor: pointer;
}
.annot-color.active { border-color: var(--accent); box-shadow: var(--focus-ring); }
.annot-width {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 1.7rem; padding: 0;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); cursor: pointer;
}
.annot-width-icon { width: 1.6rem; height: 0.8rem; stroke: currentColor; stroke-linecap: round; }
.annot-width.active {
  color: white; border-color: var(--accent); background: var(--accent);
  box-shadow: var(--shadow-sm);
}
.annot-editor-stage {
  position: relative;
  z-index: 0;
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  background: #1d1d1f; padding: 0.6rem;
  overflow: hidden;
}
.annot-editor-surface {
  width: 100%; height: 100%;
  max-width: 100%; max-height: 100%;
  display: block;
  touch-action: none; cursor: crosshair;
}
.annot-editor-surface.is-selecting { cursor: default; }
.annot-editor-surface.is-selecting .annot-mark {
  cursor: move;
  pointer-events: bounding-box;
}
.annot-selection-box {
  fill: rgba(255, 255, 255, 0.08);
  stroke: #fff;
  stroke-width: 4px;
  stroke-dasharray: 12 9;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.annot-mark.selected {
  filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.85));
}
/* Drag handles of the selected curve. Purely visual: which one a pointer grabs
   is decided by distance in annotate_editor.js, over a radius wider than the
   dot, so they take no pointer events of their own. */
.annot-curve-handle {
  fill: #fff;
  stroke: #1d1d1f;
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.annot-curve-handle.bend { fill: var(--accent, #6366f1); }
.annot-curve-handle.active {
  stroke: #fff;
  stroke-width: 3px;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
}
/* Rotation grip of the selected ellipse, on its stalk. Same deal: drawn only,
   grabbed by proximity. */
.annot-rotate-handle {
  fill: var(--accent, #6366f1);
  stroke: #fff;
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.annot-rotate-handle.active {
  stroke-width: 3px;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
}
/* Stroke-width grip, on every selected mark. Square where the path and rotation
   grips are round: an ellipse shows both at once, and in every drawing tool a
   round grip is a point on the shape while a square one changes a property of
   the whole of it. */
.annot-stroke-handle {
  fill: #fff;
  stroke: var(--accent, #6366f1);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.annot-stroke-handle.active {
  fill: var(--accent, #6366f1);
  stroke: #fff;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
}
.annot-sign-resize-handle {
  fill: #fff;
  stroke: var(--accent, #6366f1);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.annot-sign-resize-handle.active {
  fill: var(--accent, #6366f1);
  stroke: #fff;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
}
.annot-handle-stalk {
  stroke: #fff;
  /* Width and dashes in screen pixels, like the handles: a width in the photo's
     own units would be sub-pixel on a small image and invisible. */
  stroke-width: 2px;
  stroke-dasharray: 6 5;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
/* Crop overlay. Drawn above the marks so a mark outside the rectangle reads as
   excluded rather than vanishing — the editor stays in whole-photo coordinates
   precisely so the surveyor can see that. Drawn only, like every other handle
   here: what a pointer grabbed is decided by distance in annotation_crop.js. */
.annot-crop-layer { pointer-events: none; }
.annot-crop-shade { fill: rgba(0, 0, 0, 0.55); }
.annot-crop-outline {
  fill: none;
  stroke: #fff;
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
}
.annot-crop-handle {
  fill: #fff;
  stroke: #1d1d1f;
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
}
.annot-crop-handle.active {
  fill: var(--accent, #6366f1);
  stroke: #fff;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.6));
}
.annot-dimension-input-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.annot-dimension-field {
  position: absolute;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.annot-dimension-input {
  display: block;
  box-sizing: border-box;
  padding: 0.22rem 0.38rem;
  border: 1px solid #1d1d1f;
  border-radius: 0;
  background: #fff;
  color: var(--annot-dimension-color, #e31b23);
  font-family: Arial, sans-serif;
  font-weight: 700;
  text-align: center;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.28);
  pointer-events: auto;
}
.annot-dimension-input::placeholder {
  color: currentColor;
  opacity: 0.7;
}
.annot-dimension-input:focus {
  border-color: #1d1d1f;
}
.annot-dimension-field.selected .annot-dimension-input {
  outline: 3px solid rgba(255, 255, 255, 0.95);
  outline-offset: 2px;
  padding-inline: 1.9rem 1.4rem;
}
.annot-dimension-move, .annot-dimension-resize {
  position: absolute;
  display: none;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: rgba(29, 29, 31, 0.88);
  color: white;
  line-height: 1;
  touch-action: none;
  user-select: none;
}
.annot-dimension-field.selected .annot-dimension-move,
.annot-dimension-field.selected .annot-dimension-resize {
  display: flex;
}
.annot-dimension-move {
  left: 4px;
  top: 50%;
  width: 1.45rem;
  height: calc(100% - 8px);
  min-height: 1.45rem;
  transform: translateY(-50%);
  cursor: move;
  font-size: 1rem;
}
.annot-dimension-resize {
  right: 3px;
  bottom: 3px;
  width: 1.15rem;
  height: 1.15rem;
  cursor: nwse-resize;
  font-size: 0.78rem;
}
.annot-editor-footer {
  position: relative;
  z-index: 2;
  display: flex; justify-content: flex-end; gap: 0.5rem;
  padding: 0.7rem 1rem; border-top: 1px solid var(--hairline);
  background: var(--surface);
}
.annot-ai-btn { margin-right: auto; }  /* push to the left, away from Fertig */
.annot-ai-result {
  position: relative;
  z-index: 2;
  padding: 0.6rem 1rem 0.9rem; border-top: 1px solid var(--hairline);
  font-size: 0.85rem; max-height: 12rem; overflow-y: scroll;
  scrollbar-gutter: stable;
  background: var(--surface);
}
.annot-ai-loading {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.5rem 0.7rem;
}
.annot-ai-loading-text { font-weight: 600; }
.annot-ai-spinner { width: 20px; height: 20px; border-width: 2px; }
.annot-ai-progress {
  grid-column: 1 / -1;
  width: min(280px, 100%);
}
.annot-ai-note { margin-bottom: 0.4rem; }
.annot-ai-note .info-disclosure-trigger {
  border-color: rgba(161, 92, 0, 0.28);
  color: #a15c00;
}
.annot-ai-note .info-disclosure-text {
  color: #a15c00;
  font-size: 0.78rem;
}
.annot-ai-row {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.15rem 0;
}
.annot-ai-src { color: var(--muted, #6b7280); }
.annot-ai-val { font-weight: 600; }
.annot-ai-err { color: #c0392b; }
.annot-ai-use {
  font: inherit; font-size: 0.78rem; padding: 0.15rem 0.5rem; margin-left: auto;
  border: 1px solid var(--border); border-radius: var(--radius); background: #f3f4f6; cursor: pointer;
}
.annot-ai-reason {
  color: var(--muted, #6b7280);
  font-size: 0.78rem;
  line-height: 1.4;
  margin: 0.15rem 0 0.45rem;
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  background: #f8fafc;
}
.wp-photo-card:hover { border-color: var(--accent); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.wp-photo-card:active { cursor: grabbing; }
.wp-photo-card.excluded { border-color: #c8cfd5; }
.wp-photo-card.excluded .wp-photo-thumb {
  opacity: 0.45;
  filter: grayscale(0.25);
}
.wp-photo-card.excluded .wp-photo-meta { opacity: 0.6; }
.wp-photo-card.excluded .wp-photo-overlay {
  background: #fff;
}
.wp-photo-card.manual-evidence { border-top: 3px solid #2f8f6b; }
.wp-photo-thumb {
  background: #eee;
}
.wp-photo-overlay {
  display: flex; justify-content: space-between; align-items: center;
  padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--hairline);
  background: #fcfcfc;
}
.wp-photo-include {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: 0.8rem; color: #555; user-select: none;
}
.wp-severity-picker { display: flex; gap: 0.2rem; }
.wp-severity-picker .severity-dot {
  width: 1.1rem; height: 1.1rem; border-radius: 50%;
  padding: 0; border: 2px solid transparent; cursor: pointer;
}
.wp-severity-picker .severity-dot.active { border-color: var(--accent); }
.wp-photo-measures {
  margin: 0.4rem 0.6rem; padding: 0.4rem 0.5rem;
  border: 1px solid var(--border); border-radius: 6px; resize: vertical;
  font: inherit; font-size: 0.85rem; min-height: 3rem;
}
.wp-photo-measures-counters {
  margin: 0.1rem 0.6rem 0.4rem;
  border: 1px solid var(--border); border-radius: 6px;
  background: #fbfcfd;
}
.wp-photo-measures-counters > summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: 0.35rem 0.55rem;
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.82rem; color: #444;
}
.wp-photo-measures-counters > summary::-webkit-details-marker { display: none; }
.wp-photo-measures-counters > summary::before {
  content: "▸"; font-size: 0.7rem; color: #888;
  transition: transform 0.12s ease;
}
.wp-photo-measures-counters[open] > summary::before { transform: rotate(90deg); }
.wp-photo-measures-counters-badge {
  margin-left: auto;
  min-width: 1.4rem; height: 1.2rem; padding: 0 0.35rem;
  border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.72rem; font-weight: 600;
  background: transparent; color: transparent;
}
.wp-photo-measures-counters-badge.active {
  background: var(--accent); color: white;
}
.wp-photo-measures-counter-grid {
  padding: 0.15rem 0.55rem 0.5rem;
  display: grid; gap: 0.18rem;
}
.wp-photo-measures-counter-row {
  display: grid;
  grid-template-columns: 1fr auto 1.5rem auto;
  align-items: center; gap: 0.3rem;
  font-size: 0.8rem; color: #555;
}
.wp-photo-measures-counter-row.active { color: #222; }
.wp-photo-measures-counter-label {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wp-photo-measures-counter-btn {
  width: 1.5rem; height: 1.5rem; padding: 0;
  border: 1px solid var(--border); border-radius: 4px;
  background: white; cursor: pointer; font-size: 0.95rem; line-height: 1;
  color: #444;
}
.wp-photo-measures-counter-btn:hover:not(:disabled) {
  border-color: var(--accent); color: var(--accent);
}
.wp-photo-measures-counter-btn:disabled {
  opacity: 0.4; cursor: default;
}
.wp-photo-measures-counter-count {
  text-align: center; font-variant-numeric: tabular-nums;
  font-weight: 600; font-size: 0.85rem;
}
.wp-photo-measures-counter-row.active .wp-photo-measures-counter-count {
  color: var(--accent);
}
.wp-photo-meta {
  padding: 0.3rem 0.6rem 0.5rem;
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem 0.5rem;
  font-size: 0.72rem; color: #888;
}
.wp-photo-filename {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1; min-width: 0;
}
.wp-photo-time { white-space: nowrap; }
.wp-photo-source {
  white-space: nowrap;
  padding: 0.12rem 0.38rem;
  border-radius: 999px;
  background: #e8f5ef;
  color: #176b4d;
  border: 1px solid #b7ddcd;
  font-weight: 600;
}
/* --- Re-survey inheritance bucket ("Aus vorheriger Aufnahme") --- */
.wp-inherited {
  border: 1px solid #b7d3ea;
  background: #eef5fb;
  border-radius: 10px;
  padding: 0.6rem 0.7rem;
  margin-bottom: 0.9rem;
}
.wp-inherited-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.15rem;
}
.wp-inherited-title { font-weight: 600; color: #1c5c8f; }
.wp-inherited-count { font-size: 0.8rem; color: #3a7cae; }
.wp-inherited-hint { font-size: 0.8rem; color: #3a7cae; margin-bottom: 0.5rem; }
.wp-inherited-note {
  background: #fff;
  border: 1px solid #d7e3ee;
  border-radius: 8px;
  padding: 0.45rem 0.5rem;
  margin-top: 0.45rem;
}
.wp-inherited-note-row { display: flex; gap: 0.55rem; align-items: flex-start; }
.wp-inherited-thumb {
  width: 46px; height: 46px; flex: none;
  object-fit: cover; border-radius: 6px; background: #eef1f4;
}
.wp-inherited-note-body { flex: 1; min-width: 0; }
.wp-inherited-sev { display: flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; }
.wp-inherited-sev-dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.wp-inherited-measures { font-size: 0.82rem; color: #4a5560; margin-top: 0.2rem; line-height: 1.35; }
.wp-inherited-actions { display: flex; flex-direction: column; gap: 0.3rem; align-items: flex-end; flex: none; }
.wp-inherited-apply, .wp-inherited-keep, .wp-inherited-undo {
  white-space: nowrap;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  border: 1px solid #85b7eb;
  background: #fff;
  color: #185fa5;
  font-size: 0.8rem;
  cursor: pointer;
}
.wp-inherited-keep { border-color: #cdd6de; color: #55606b; }
.wp-inherited-undo { border-color: #cdd6de; color: #55606b; }
.wp-inherited-apply:disabled { opacity: 0.5; cursor: default; }
.wp-inherited-applied { font-size: 0.82rem; color: #176b4d; font-weight: 600; }
.wp-inherited-menu {
  margin-top: 0.45rem;
  border: 1px solid #d7e3ee;
  border-radius: 8px;
  overflow: hidden;
}
.wp-inherited-menu-head { font-size: 0.78rem; color: #7a8794; padding: 0.3rem 0.5rem; border-bottom: 1px solid #eef1f4; }
.wp-inherited-menu-row {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  padding: 0.35rem 0.5rem; border: 0; background: #fff; cursor: pointer;
  font-size: 0.85rem; text-align: left;
}
.wp-inherited-menu-row:hover:not(:disabled) { background: #eef5fb; }
.wp-inherited-menu-row:disabled { cursor: default; color: #9aa4ad; }
.wp-inherited-menu-thumb { width: 24px; height: 24px; object-fit: cover; border-radius: 4px; background: #eef1f4; }
.wp-inherited-menu-label { flex: 1; }
.wp-inherited-menu-taken { font-size: 0.78rem; color: #9aa4ad; }

.wp-photo-remove {
  margin-left: auto;
  padding: 0.12rem 0.35rem;
  border: 0;
  background: transparent;
  color: #b13a2f;
  font: inherit;
  cursor: pointer;
}
.wp-photo-remove:hover { background: #fdecea; color: #8f251c; }

/* Final read-only handoff preview. It reuses the modal replacement path but
 * intentionally covers the map: this is a document-level check, not another
 * waypoint editing surface. */
.wp-modal-backdrop.selection-preview-backdrop {
  z-index: 1350;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  background: rgba(20, 20, 24, 0.46);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
}
.selection-preview-modal {
  width: min(95vw, 1280px);
  height: min(92vh, 940px);
  min-width: 0;
  max-width: none;
  max-height: none;
  border: 1px solid rgba(255, 255, 255, 0.34);
}
.selection-preview-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.15rem;
  border-bottom: 1px solid var(--hairline);
  background: #f3f4f6;
}
.selection-preview-heading { flex: 1; min-width: 0; }
.selection-preview-modal .selection-preview-heading h2 {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  font-size: 1.1rem;
}
.selection-preview-heading p {
  margin: 0.2rem 0 0;
  color: var(--text-muted);
  font-size: 0.86rem;
}
.selection-preview-close {
  flex: 0 0 auto;
  padding: 0.1rem 0.45rem;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.7rem;
  line-height: 1;
}
.selection-preview-close:hover { color: #c0392b; background: transparent; }
.selection-preview-body {
  flex: 1 1 0;
  overflow-y: auto;
  padding: 1.1rem;
  background:
    linear-gradient(rgba(250, 250, 252, 0.96), rgba(250, 250, 252, 0.96)),
    repeating-linear-gradient(135deg, #eef0f4 0 1px, transparent 1px 12px);
}
.selection-preview-group + .selection-preview-group { margin-top: 1.5rem; }
.selection-preview-group-head {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  margin: 0 0 0.65rem;
}
.selection-preview-group-head h3 {
  margin: 0;
  font-size: 0.98rem;
}
.selection-preview-location {
  min-width: 0;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 0.84rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.selection-preview-group-count {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.8rem;
  white-space: nowrap;
}
.selection-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.8rem;
}
.selection-preview-card {
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.selection-preview-media {
  height: 190px;
  background: #e5e7eb;
}
.selection-preview-number {
  position: absolute;
  left: 0.55rem;
  bottom: 0.5rem;
  z-index: 2;
  padding: 0.22rem 0.45rem;
  border-radius: 999px;
  background: rgba(20, 20, 24, 0.82);
  color: white;
  font-size: 0.74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}
.selection-preview-details { padding: 0.65rem 0.7rem 0.7rem; }
.selection-preview-road {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.5rem;
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 650;
}
.selection-preview-road-missing {
  color: var(--text-muted);
  font-style: italic;
  font-weight: 400;
}
.road-confidence-low {
  display: inline-flex;
  margin-left: 0.35rem;
  padding: 0.1rem 0.35rem;
  border-radius: 999px;
  background: #fff3cd;
  color: #7a5600;
  font-size: 0.65rem;
  font-style: normal;
  font-weight: 700;
  white-space: nowrap;
}
.selection-preview-severity {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  font-size: 0.78rem;
  font-weight: 600;
}
.selection-preview-severity-dot {
  width: 0.72rem;
  height: 0.72rem;
  flex: 0 0 auto;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 50%;
}
.selection-preview-measures {
  min-height: 2.4em;
  margin: 0.55rem 0;
  color: var(--text);
  font-size: 0.82rem;
  line-height: 1.35;
  white-space: pre-wrap;
}
.selection-preview-measures-empty {
  color: var(--text-muted);
  font-style: italic;
}
.selection-preview-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem 0.45rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--hairline);
  color: var(--text-muted);
  font-size: 0.7rem;
}
.selection-preview-filename {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.selection-preview-empty {
  max-width: 440px;
  margin: 14vh auto 0;
  padding: 2rem;
  border: 1px dashed #c7cdd5;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.76);
  text-align: center;
}
.selection-preview-empty h3 { margin: 0 0 0.45rem; }
.selection-preview-empty p {
  margin: 0;
  color: var(--text-muted);
  line-height: 1.45;
}
.selection-preview-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.55rem;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--hairline);
  background: #fff;
}
.selection-preview-language {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-muted);
  font-size: 0.85rem;
}
.selection-preview-language-select {
  min-width: 5rem;
  padding: 0.38rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: white;
  color: var(--text);
  font: inherit;
}
.selection-preview-road-pending {
  flex: 1 1 220px;
  color: var(--text-muted);
  font-size: 0.85rem;
  text-align: right;
}
.selection-preview-footer button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.selection-preview-generation-status {
  flex: 1 1 240px;
  min-width: 190px;
  max-width: 340px;
  display: grid;
  gap: 0.35rem;
  margin-inline: 0.3rem auto;
}
.selection-preview-generation-label {
  color: var(--text-muted);
  font-size: 0.78rem;
  line-height: 1.25;
}
.selection-preview-generation-progress { height: 7px; }

.wp-photo-redaction-btn {
  margin: .55rem .65rem 0;
  border: 1px solid #d8a61d;
  background: #fff8dc;
  color: #604900;
  font-size: .78rem;
}
.wp-photo-redaction-btn.is-reviewed { border-color: #6eaa7a; background: #eef8f0; color: #245c30; }
.wp-photo-redaction-btn.has-error { border-color: #c0392b; background: #fff0ee; color: #8a2116; }
.redaction-preview-overlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.redaction-box { fill: rgba(26, 93, 153, .23); stroke: #0d5f9f; stroke-width: 5; vector-effect: non-scaling-stroke; }
.redaction-box-face { fill: rgba(190, 63, 52, .24); stroke: #b72d22; }
.redaction-box.is-selected { stroke: #ffd400; stroke-width: 8; }
.redaction-box.is-draft { stroke-dasharray: 12 8; }
.redaction-editor-backdrop { z-index: 1500; }
.redaction-editor-panel { width: min(1100px, 96vw); max-height: 96vh; display: flex; flex-direction: column; }
.redaction-editor-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 1rem 1.2rem .5rem; }
.redaction-editor-head h2, .redaction-editor-head p { margin: 0; }
.modal .redaction-editor-head h2 { padding: 0; border: 0; background: transparent; font-size: 1.05rem; }
.redaction-editor-head p { color: var(--muted); margin-top: .2rem; }
.redaction-editor-instructions { margin: 0; padding: 0 1.2rem .7rem; color: var(--muted); }
.redaction-editor-toolbar { display: flex; gap: .5rem; padding: .7rem 1.2rem; border-block: 1px solid var(--border); }
.redaction-editor-toolbar button.is-active { background: #244f73; color: white; }
.redaction-editor-toolbar button:last-child { margin-left: auto; }
.redaction-editor-stage { min-height: 320px; flex: 1; overflow: hidden; background: #20242a; }
.redaction-editor-surface { width: 100%; height: 100%; touch-action: none; cursor: crosshair; }
.redaction-editor-footer { display: flex; justify-content: flex-end; gap: .6rem; padding: .8rem 1.2rem; }
.selection-preview-redaction-pending { color: #8a5f00; font-size: .85rem; max-width: 260px; }

.add-waypoint {
  display: block; width: 100%; margin: 0 0 1rem;
  padding: 0.75rem; background: white; color: var(--brand-2);
  border: 2px dashed #bbb; cursor: pointer; font: inherit;
}
.add-waypoint:hover { border-color: var(--accent); background: #f0f7ff; }

.wp-photo-road {
  display: grid;
  gap: 0.28rem;
  padding: 0.65rem 0.75rem 0;
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 600;
}
.wp-photo-road input {
  min-width: 0;
  padding: 0.42rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font: inherit;
  font-size: 0.82rem;
}
.wp-photo-road-auto {
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 400;
}

/* --- Structured report editor --- */
.review-report-button {
  background: #1f7a5a;
  border-color: #1f7a5a;
  color: white;
  white-space: nowrap;
}
.review-report-button:hover { background: #19674b; border-color: #19674b; }
.review-report-issues-button { white-space: nowrap; }
.report-editor-loading,
.report-editor-failed {
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 0.8rem;
  padding: 2rem;
}
.report-editor-failed { align-items: flex-start; max-width: 680px; margin: auto; }
.report-editor-screen {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #eef1f5;
}
.report-editor-toolbar {
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.96);
  box-shadow: var(--shadow-sm);
  z-index: 3;
}
.report-editor-title { min-width: 190px; margin-right: auto; }
.report-editor-title h1 { margin: 0; font-size: 1rem; }
.report-save-status { display: block; margin-top: 0.18rem; color: var(--text-muted); font-size: 0.72rem; }
.report-save-retry { margin-top: 0.25rem; padding: 0.15rem 0.45rem; font-size: 0.72rem; }
.report-editor-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 0.55rem; }
.report-pdf-action {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.18rem;
}
.report-required-summary { color: #78510c; font-size: 0.7rem; }
.report-required-summary[hidden] { display: none; }
.report-required-summary > summary {
  align-self: flex-start;
  cursor: pointer;
  font-weight: 650;
  list-style-position: inside;
}
.report-required-summary > summary:hover { color: #5f3e06; }
.report-required-body {
  position: absolute;
  top: calc(100% + 0.3rem);
  right: 0;
  z-index: 12;
  width: max-content;
  max-width: min(360px, calc(100vw - 2rem));
  padding: 0.65rem;
  border: 1px solid #e8d8ae;
  border-radius: 8px;
  background: #fffdf8;
  box-shadow: var(--shadow-md);
}
.report-required-body p { margin: 0; line-height: 1.35; }
.report-required-fields { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.5rem 0; }
button.report-required-link {
  padding: 0.24rem 0.45rem;
  border-color: #d8c48f;
  background: white;
  color: #5f3e06;
  font-size: 0.72rem;
}
.report-required-optional { color: var(--text-muted); font-size: 0.68rem; }
.report-field.report-language-field {
  min-width: 0;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
}
.report-language-field .report-field-label { margin: 0; }
.report-language-field .report-input { width: auto; }
.report-editor-layout {
  min-height: 0;
  flex: 1;
  display: grid;
  grid-template-columns: minmax(520px, 0.95fr) minmax(460px, 1.05fr);
  gap: 1px;
  background: var(--border);
}
.report-form {
  min-width: 0;
  overflow: auto;
  padding: 1rem;
  background: #eef1f5;
}
.report-form-section {
  max-width: 940px;
  margin: 0 auto 1rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.report-section-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-bottom: 0.9rem;
}
.report-section-head h2 { margin: 0; font-size: 1.05rem; }
.report-section-help[open] { flex-basis: 100%; }
.report-section-head .info-disclosure-text,
.report-help .info-disclosure-text { font-size: 0.8rem; }
.report-help { margin: 0.28rem 0 0; }
.report-field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

/* The parts of the report form that belong to the project rather than to this
 * survey. Marked with a rule down the left rather than a box, so a section that
 * is half shared and half this survey's still reads as one section. */
.report-project-group {
  /* Visible against the white section, or the marker says nothing: var(--border)
     is a hairline colour and disappeared here. */
  border-left: 3px solid #c3ccd8;
  padding-left: 0.75rem;
  margin-top: 0.4rem;
}
.report-project-group-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.55rem;
}
.report-project-badge {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
}
.report-project-hint { color: var(--text-muted); font-size: 0.78rem; }
.report-project-hint .info-disclosure-trigger,
.report-field-hint .info-disclosure-trigger {
  width: 1.25rem;
  height: 1.25rem;
}
.report-project-hint .info-disclosure-text { font-size: 0.78rem; }
/* Locked fields stay fully readable -- the surveyor needs to see what the
   project says even where they cannot change it here -- and show that they are
   inert through their background instead. The same treatment as a read-only
   survey's controls above; dimming the text was not legible enough to tell the
   locked state from the unlocked one at a glance. */
.report-project-locked :is(.report-input, select):disabled {
  opacity: 1;
  background: #f3f4f6;
  color: var(--text);
  -webkit-text-fill-color: var(--text);
  border-style: dashed;
}
.report-project-locked .report-field-label { color: var(--text-muted); }
.report-project-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6rem;
}
/* A correction waiting to be accepted or ignored. Amber, which is what an
   edited-but-unresolved state already means elsewhere in this app. */
.report-project-drift {
  margin-top: 0.7rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid #e8d8ae;
  border-radius: 8px;
  background: #fdf8ec;
}
.report-project-drift p { margin: 0 0 0.5rem; font-size: 0.82rem; line-height: 1.4; }
.report-field { min-width: 0; display: flex; flex-direction: column; gap: 0.3rem; }
.report-field-wide { grid-column: 1 / -1; }
.report-field-heading { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; }
.report-field-label { color: #424b57; font-size: 0.74rem; font-weight: 650; }
.report-required-badge {
  color: #78510c;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.report-input {
  width: 100%;
  min-width: 0;
  padding: 0.52rem 0.58rem;
  border: 1px solid #cfd5dc;
  border-radius: 6px;
  background: white;
  color: var(--text);
  font: inherit;
  font-size: 0.86rem;
}
/* No stepper arrows on the report's numeric fields. They are a hazard here
 * rather than a convenience: the boxes are narrow, the arrows sit exactly where
 * the caret is aimed, and one stray click silently changes a cargo dimension
 * that ends up in a client document. Typing is the only way to set these. */
.report-input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
.report-input[type="number"]::-webkit-outer-spin-button,
.report-input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
.report-field.has-error .report-input,
.report-column-chip.has-error .report-input {
  border-color: #c0392b;
  background: #fff8f7;
  box-shadow: 0 0 0 1px rgba(192, 57, 43, 0.12);
}
.report-field-error {
  color: #a93226;
  font-size: 0.7rem;
  line-height: 1.3;
}
.report-column-chip .report-field-error { flex-basis: 100%; }
textarea.report-input { resize: vertical; line-height: 1.42; }
.report-field-hint { align-self: flex-start; color: var(--text-muted); font-size: 0.7rem; }
.report-field-hint .info-disclosure-text { font-size: 0.7rem; }
.report-localized { display: grid; gap: 0.35rem; margin-top: 0.8rem; }
.report-localized-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.75rem; }
.report-localized-grid .report-field-label { color: var(--accent); }
.report-row-head,
.report-inline-row,
.report-card-actions {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}
.report-row-head { justify-content: space-between; margin: 0.6rem 0; }
.report-row-head h3 { margin: 0; font-size: 0.9rem; }
.report-inline-row { align-items: end; margin-top: 0.6rem; }
.report-inline-row .report-field { flex: 1; }
.report-assessment-columns {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.2rem;
}
.report-assessment-columns > button { margin-left: auto; }
.report-column-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  padding: 0 0.15rem 0 0.3rem;
  border: 1px solid #cfd5dc;
  border-radius: 999px;
  background: white;
}
.report-column-chip:focus-within { border-color: var(--accent); }
.report-column-chip.has-error {
  flex-wrap: wrap;
  border-color: #c0392b;
  border-radius: 8px;
}
.report-column-chip.has-error .report-field-error { width: 100%; padding: 0 0.25rem 0.25rem; }
/* The project-owned look for a chip: the inner input carries no border of its
   own, so the dashed, greyed state has to sit on the chip. */
.report-project-locked .report-column-chip { background: #f3f4f6; border-style: dashed; }
.report-project-locked .report-column-chip .report-input:disabled { background: transparent; }
.report-column-chip .report-input {
  width: auto;
  padding: 0.3rem 0.2rem;
  border: 0;
  border-radius: 999px;
  font-size: 0.8rem;
}
.report-column-chip .report-input:focus { outline: none; }
.report-chip-remove {
  padding: 0 0.28rem;
  border: 0;
  background: none;
  font-size: 1rem;
  line-height: 1;
}
.report-subsection { margin-top: 1rem; padding-top: 0.85rem; border-top: 1px solid var(--border); }
.report-subsection > h3 { margin: 0; font-size: 0.9rem; }
.report-repeat-card,
.report-figure-card,
.report-derived-card {
  margin-top: 0.75rem;
  padding: 0.8rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #fafbfc;
}
.report-repeat-card > .report-field { margin-top: 0.7rem; }
.report-measurement-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
  margin-top: 0.75rem;
}
.report-measurement {
  margin: 0;
  padding: 0.55rem;
  border: 1px solid var(--border);
  border-radius: 6px;
}
.report-measurement legend { padding: 0 0.25rem; color: #424b57; font-size: 0.74rem; font-weight: 650; }
.report-measurement-choices {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 2fr);
  gap: 0.35rem;
  align-items: stretch;
}
.report-measurement-option {
  min-width: 0;
  padding: 0.4rem;
  border: 1px solid transparent;
  border-radius: 6px;
  transition: border-color 120ms ease, background 120ms ease;
}
.report-measurement-option.is-active {
  border-color: #aebce8;
  background: #f4f6ff;
}
.report-measurement-option:focus-within {
  border-color: #7187dc;
  background: #f7f8ff;
}
.report-measurement-range {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem;
}
.report-measurement-or {
  align-self: center;
  color: var(--text-muted);
  font-size: 0.68rem;
  font-weight: 650;
  text-transform: uppercase;
}
.report-assessment-rows { display: grid; gap: 0.6rem; margin-top: 0.7rem; }
.report-assessment-row {
  display: grid;
  grid-template-columns: minmax(9rem, 0.35fr) minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
  padding: 0.65rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: white;
}
.report-assessment-row h4 { margin: 0.45rem 0 0; color: #424b57; font-size: 0.8rem; }
.report-assessment-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.6rem; }
.report-dimension-states { display: grid; gap: 0.45rem; margin-top: 0.8rem; }
.report-state-row { display: grid; grid-template-columns: minmax(100px, 1fr) 1fr 1fr; gap: 0.5rem; align-items: center; }
.report-checkbox { display: inline-flex; align-items: center; gap: 0.42rem; color: #424b57; font-size: 0.78rem; }
.report-checkbox input { width: 16px; height: 16px; }
.report-empty { margin: 0.55rem 0; color: var(--text-muted); font-size: 0.82rem; }
.report-empty-help { margin: 0.55rem 0; }
.report-photo-count { margin: 0.35rem 0 0; color: var(--text-muted); font-size: 0.8rem; }
.project-report-intro {
  display: block;
  width: calc(100% - 2rem);
  max-width: 940px;
  margin: 1rem auto 0;
}
.report-figure-list { display: grid; }
.report-figure-card {
  position: relative;
  display: grid;
  grid-template-columns: 2rem 180px minmax(0, 1fr);
  gap: 0.8rem;
}
.report-figure-preview,
.report-map-preview { width: 100%; max-height: 190px; object-fit: contain; border-radius: 5px; background: #eef1f5; }
.report-figure-preview { grid-column: 2; }
.report-figure-body { grid-column: 3; min-width: 0; }
.report-drag-handle {
  align-self: center;
  width: 2rem;
  min-width: 2rem;
  padding: 0.35rem 0;
  border: 0;
  background: transparent;
  color: #6b7480;
  cursor: grab;
  font-size: 1.45rem;
  line-height: 1;
  touch-action: none;
  user-select: none;
}
.report-drag-handle:hover,
.report-drag-handle:focus-visible { color: var(--accent); background: #eef0ff; }
.report-drag-handle:active,
.report-drag-handle.is-active-drag-handle { cursor: grabbing; }
.report-drag-handle[aria-disabled="true"] { cursor: not-allowed; }
.report-figure-card.is-dragging { opacity: 0.45; }
.report-figure-card.drop-before::before,
.report-figure-card.drop-after::after {
  position: absolute;
  right: 0;
  left: 0;
  z-index: 2;
  height: 3px;
  border-radius: 999px;
  background: var(--accent);
  content: "";
}
.report-figure-card.drop-before::before { top: -0.48rem; }
.report-figure-card.drop-after::after { bottom: -0.48rem; }
.report-form-section[data-additional-placement] .report-section-head > button { margin-left: auto; }
.report-additional-card {
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #fafbfc;
}
.report-additional-summary {
  padding: 0.75rem 0.8rem;
  color: #424b57;
  cursor: pointer;
  font-size: 0.86rem;
  font-weight: 650;
}
.report-additional-body {
  padding: 0 0.8rem 0.8rem;
  border-top: 1px solid var(--border);
}
.report-card-actions { margin-top: 0.65rem; justify-content: flex-end; }
.report-upload-control { display: inline-flex; }
.report-derived-card h3 { margin: 0 0 0.45rem; font-size: 0.88rem; }
.report-derived-card p { margin: 0; line-height: 1.45; }
.report-photo-row { display: flex; justify-content: space-between; align-items: center; gap: 0.8rem; padding: 0.5rem 0; border-bottom: 1px solid var(--border); font-size: 0.78rem; }
.report-derived-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.report-derived-table th,
.report-derived-table td { padding: 0.35rem 0.45rem; border-bottom: 1px solid var(--border); text-align: left; }
.report-derived-table td { width: 5rem; text-align: right; font-variant-numeric: tabular-nums; }
.report-preview-pane {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0.85rem;
  background: #d7dce3;
}
/* A banner, not a replacement. It sits above the draft and leaves it on the
 * screen, because the draft is what the surveyor is correcting the form
 * against; `margin: auto` on `.report-preview-empty` would centre it over the
 * space the draft needs. */
.report-preview-stale {
  flex: none;
  margin: 0 0 0.5rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid #e3b7ae;
  border-radius: 8px;
  background: #fff8f7;
  color: #6c4a43;
}
.report-preview-stale strong { display: block; font-size: 0.8rem; }
.report-preview-stale p { margin: 0.25rem 0 0.45rem; font-size: 0.76rem; line-height: 1.45; }
.report-preview-meta { margin: 0.45rem 0; color: #596574; font-size: 0.72rem; }
.report-preview-frame { min-height: 0; flex: 1; width: 100%; border: 0; border-radius: 5px; background: white; }
.report-preview-tabs { display: flex; gap: 0.3rem; margin-bottom: 0.6rem; }
.report-preview-title {
  margin: 0;
  color: #4f5966;
  font-size: 0.78rem;
  font-weight: 600;
}
.report-preview-view { min-height: 0; flex: 1; display: flex; flex-direction: column; }
.report-issue-history { display: grid; gap: 0.6rem; margin-top: 0.8rem; }
.report-issue-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.25rem 0.8rem;
  align-items: center;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: #fafbfc;
}
.report-issue-card-head { display: flex; align-items: center; gap: 0.5rem; }
.report-issue-card-head h3 { margin: 0; font-size: 0.88rem; }
.report-issue-language {
  padding: 0.12rem 0.35rem;
  border-radius: 4px;
  background: #e5e9f8;
  color: #394ca2;
  font-size: 0.64rem;
  font-weight: 700;
}
.report-issue-state,
.report-current-revision {
  padding: 0.14rem 0.42rem;
  border-radius: 999px;
  background: #e8f5ee;
  color: #176447;
  font-size: 0.66rem;
  font-weight: 700;
}
.report-current-revision { display: inline-flex; margin-top: 0.18rem; }
.report-issue-state.closed { background: #e9edf2; color: #596574; }
.report-issue-toolbar-status {
  display: block;
  margin-top: 0.18rem;
  color: #176447;
  font-size: 0.72rem;
  font-weight: 650;
}
.report-issue-reason { margin: 0; font-size: 0.8rem; }
.report-issue-meta { margin: 0; color: var(--text-muted); font-size: 0.7rem; }
.report-issue-download { grid-column: 2; grid-row: 1 / span 3; }
.report-issue-next { margin: 1rem 0 0.65rem; font-size: 0.9rem; }
.report-issue-actions { display: flex; justify-content: flex-end; gap: 0.55rem; margin-top: 0.8rem; }
.report-issue-success,
.report-issue-limit,
.report-issue-progress {
  margin: 0.7rem 0;
  padding: 0.65rem 0.75rem;
  border-radius: 6px;
  font-size: 0.8rem;
  line-height: 1.4;
}
.report-issue-success { background: #e8f5ee; color: #176447; }
.report-issue-limit { background: #fff4df; color: #78510c; }
.report-issue-progress { background: #e9f1ff; color: #244a7c; }
.report-issues-screen { min-height: 100%; background: #eef1f5; }
.report-issues-body { max-width: 900px; margin: 0 auto; padding: 1.2rem; }
.report-issues-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  justify-content: flex-end;
  background: rgba(24, 31, 43, 0.35);
}
.report-issues-drawer {
  width: min(520px, 92vw);
  height: 100%;
  overflow: auto;
  padding: 1rem;
  border-left: 1px solid var(--border);
  background: #f7f8fa;
  box-shadow: -10px 0 30px rgba(24, 31, 43, 0.16);
  animation: slide-in-right 0.18s ease-out;
}
.report-issues-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.report-issues-drawer-head h2 { margin: 0; }
.report-issue-workflow {
  margin: 0.9rem 0 0.55rem;
  color: #394451;
  font-size: 0.82rem;
  line-height: 1.45;
}
/* --- Motion ---
 * Discrete entrance animations on overlays. Spring easing (slight
 * overshoot) is what reads as "macOS" vs. a flat linear ease. */
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes pop-in {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes slide-in-right {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Respect the OS "reduce motion" setting — kills animations and
 * transitions for users who opt out, without touching layout. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  /* A loading spinner conveys "still working" — essential motion, so keep it
   * turning even under reduce-motion (the message text carries meaning too). */
  .loader-spinner {
    animation-duration: 0.9s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ------------------------------------------------------------------ *
 * Smartphones / narrow screens. Stacks the split map+panel layouts and
 * turns the right-hand side modals into full-screen sheets so a survey
 * can be reviewed and its photos managed (with touch) on a phone.
 * ------------------------------------------------------------------ */
@media (max-width: 640px) {
  header { padding: 0.5rem 0.75rem; }
  header h1 { font-size: 1rem; }

  /* Generic modals (file browser, wizard chooser, dialogs) fit the viewport
   * instead of overflowing their desktop min-widths. */
  .modal { min-width: 0; width: 96vw; max-width: 96vw; max-height: 90vh; }
  .wizard-modal { min-width: 0; max-width: 96vw; }
  .wizard-route-name-editor .wizard-survey-name { width: min(220px, 60vw); }

  /* Route assembly: stack the map above the segment panel. */
  .route-assembly { grid-template-columns: 1fr; grid-template-rows: 42vh 1fr; }
  .route-assembly aside { border-left: none; border-top: 1px solid var(--hairline); }

  /* The filter gets full-width rows so its segmented buttons remain useful
   * touch targets rather than overflowing a narrow screen. */
  .review-filter-panel {
    display: grid;
    grid-template-columns: 1fr;
    flex: 1 1 100%;
    gap: 0.4rem;
    padding: 0.5rem 0.6rem;
    white-space: normal;
  }
  .review-filter-field {
    display: grid;
    grid-template-columns: 3.5rem minmax(0, 1fr);
    padding: 0.4rem 0 0;
    border-top: 1px solid var(--border);
    border-left: 0;
  }
  .review-filter-toggle { width: 100%; }
  .review-filter-toggle .review-filter-option {
    flex: 1 1 0;
    justify-content: center;
    padding-right: 0.25rem;
    padding-left: 0.25rem;
  }
  .review-severity-filter { justify-self: start; }

  /* The waypoint modal becomes a full-screen sheet. The map-pin drop target
   * sits behind it, so on phones the edge rails are the move-to-neighbour
   * path; photos stack one per row for comfortable touch dragging. */
  /* The waypoint sheet carries both `modal` and `wp-modal`; override the
   * generic `.modal` caps above so `inset: 0` can fill the whole screen. */
  .wp-modal {
    inset: 0;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    border-radius: 0;
  }
  .wp-modal-title-row {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .wp-modal-num { grid-column: 1; grid-row: 1; }
  .wp-modal-close { grid-column: 2; grid-row: 1; }
  .wp-modal-status {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: stretch;
  }
  .wp-modal-status-btn {
    flex: 1 1 0;
    justify-content: center;
  }
  .wp-modal-delete {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: start;
  }
  .wp-modal-location-field {
    grid-column: 1 / -1;
    grid-row: 4;
  }
  .wp-modal-simulation-field { grid-template-columns: 1fr; }
  .wp-modal-simulation-field > span { padding-top: 0; }
  .wp-modal-simulation-rows { grid-template-columns: 1fr; }
  .wp-modal-simulation-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }
  .wp-modal-simulation-add,
  .wp-modal-simulation-remove { justify-self: start; }
  .wp-modal-nav-row,
  .wp-modal-photo-toolbar {
    flex-wrap: wrap;
  }
  .wp-modal-count {
    flex-basis: 100%;
  }
  .wp-photo-grid { grid-template-columns: 1fr; }
  .wp-move-rail { width: 52px; font-size: 0.74rem; }

  /* Selection-preview sheet also goes full-screen. */
  .selection-preview-modal { position: fixed; inset: 0; width: auto; height: auto; border-radius: 0; max-width: none; max-height: none; }

  .report-editor-toolbar { align-items: stretch; flex-wrap: wrap; }
  .report-editor-title { order: -1; flex-basis: 100%; }
  .report-editor-actions { flex: 1 1 100%; flex-wrap: wrap; }
  .report-editor-layout { display: block; overflow: auto; }
  .report-form { overflow: visible; padding: 0.6rem; }
  .report-preview-pane { min-height: 70vh; }
  .report-issues-drawer { width: 100%; }
  .report-field-grid,
  .report-localized-grid,
  .report-measurement-grid,
  .report-assessment-row,
  .report-assessment-grid { grid-template-columns: 1fr; }
  .report-assessment-row h4 { margin-top: 0; }
  .report-measurement-choices { grid-template-columns: 1fr; }
  .report-measurement-or {
    display: flex;
    align-items: center;
    gap: 0.45rem;
  }
  .report-measurement-or::before,
  .report-measurement-or::after {
    content: "";
    height: 1px;
    flex: 1;
    background: var(--border);
  }
  .report-figure-card { grid-template-columns: 2rem minmax(0, 1fr); }
  .report-figure-preview,
  .report-figure-body { grid-column: 2; }
  .report-figure-card > .report-drag-handle { grid-row: 1 / span 2; }
  .report-photo-row { align-items: flex-start; flex-direction: column; }
}

/* Shown in the waypoint panel when the route's moved start / end leaves this
   waypoint out of the document. Explains the absence without offering to
   change the status: moving the pin back is the undo, and nothing here was
   written onto the waypoint. */
.wp-modal-outside-note {
  margin: 0.5rem 0 0;
  padding: 0.45rem 0.65rem;
  border-left: 3px dashed var(--wp-status-ignoriert);
  background: #f4f5f7;
  color: #3f4652;
  font-size: 0.85rem;
  line-height: 1.35;
}
