/* Vessel Watch — Oberfläche
   Grundgedanke: Die Priorität trägt die Ansicht. Alles andere ordnet sich unter. */

:root {
  --bg: #0b1119;  --bg-2: #111a26;  --card: #14202e;  --line: #23324500;
  --border: #223145;
  --fg: #e8eef6;  --fg-dim: #93a6bd;  --fg-mute: #66788f;
  --accent: #38bdf8;  --accent-soft: #38bdf814;

  --p1: #4ade80;  --p1-soft: #4ade8016;   /* Prio 1 — Treffer      */
  --p2: #fbbf24;  --p2-soft: #fbbf2414;   /* Prio 2 — heiß         */
  --p3: #38bdf8;  --p3-soft: #38bdf812;   /* Prio 3 — beobachten   */
  --p4: #64748b;                          /* kein Signal           */
  --out: #7c8aa0;                         /* ausgeschlossen        */
  --mark: #f0a72a; --mark-soft: #f0a72a12;
  --fit: #a78bfa;
  --warn: #fbbf24; --bad: #f87171;
  --gold: #f4c04e;
  --green: #34d399;
  --p1-on: #05210f;      /* Schrift auf gefüllter P1-Fläche */
  --pin-ring: rgba(255,255,255,.85);   /* Ring um den Karten-Punkt */
  --pin-shadow: rgba(0,0,0,.5);
  --map-chip: rgba(12,18,26,.85);      /* Knöpfe/Labels auf der Karte */

  --r: 14px;
  --shadow: 0 1px 2px #0007, 0 10px 30px -14px #000a;
}
:root[data-theme="light"] {
  --bg: #f1f4f9;  --bg-2: #fff;  --card: #fff;  --border: #dde4ee;
  --fg: #131e2b;  --fg-dim: #4a5c72;  --fg-mute: #7a8a9f;
  --accent: #0369a1;  --accent-soft: #0369a10f;
  --p1: #15803d;  --p1-soft: #15803d10;
  --p2: #a16207;  --p2-soft: #a1620710;
  --p3: #0369a1;  --p3-soft: #0369a10d;
  --p4: #94a3b8;  --out: #94a3b8;
  --mark: #b45309; --mark-soft: #b453090d;
  --fit: #6d28d9;  --warn: #a16207; --bad: #b91c1c;
  --gold: #b7791f;
  --green: #15803d;
  --p1-on: #ffffff;
  --pin-ring: rgba(255,255,255,.95);
  --pin-shadow: rgba(15,23,42,.35);
  --map-chip: rgba(255,255,255,.92);
  --shadow: 0 1px 2px #0f172a0d, 0 10px 30px -16px #0f172a2e;
}

* { box-sizing: border-box; }
body {
  margin: 0; padding: 0 clamp(14px, 4vw, 44px) 70px;
  background: var(--bg); color: var(--fg);
  font: 15px/1.55 ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { margin: 0; font-weight: 640; letter-spacing: -.01em; }
.muted { color: var(--fg-mute); }
.small { font-size: 12.5px; }
.hidden { display: none !important; }

/* ------------------------------------------------------------- Kopfzeile */
.top {
  display: flex; align-items: center; gap: 24px; flex-wrap: wrap;
  padding: 20px 0 16px; margin-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 13px; margin-right: auto; }
.mark {
  font-size: 22px; width: 42px; height: 42px; display: grid; place-items: center;
  background: var(--accent-soft); border: 1px solid var(--border); border-radius: 11px;
}
h1 { font-size: 19px; }
.sub { margin: 1px 0 0; font-size: 12.5px; color: var(--fg-mute); }

.top-status { display: flex; gap: 10px; }
.ts-item {
  min-width: 62px; text-align: center; padding: 7px 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
}
.ts-item b { display: block; font-size: 19px; font-variant-numeric: tabular-nums; line-height: 1.15; }
.ts-item span { font-size: 10.5px; color: var(--fg-mute); text-transform: uppercase; letter-spacing: .06em; }
.ts-item:nth-child(1) b { color: var(--p1); }
.ts-item:nth-child(2) b { color: var(--p2); }
.ts-item:nth-child(3) b { color: var(--p3); }
.ts-item.age b { font-size: 14px; padding-top: 3px; color: var(--fg-dim); }

.top-actions { display: flex; gap: 8px; }
.btn {
  background: var(--bg-2); color: var(--fg); border: 1px solid var(--border);
  border-radius: 9px; padding: 8px 14px; font: inherit; font-size: 13.5px;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.btn:hover { border-color: var(--accent); }
.btn:disabled { opacity: .5; cursor: progress; }
.btn.icon { padding: 8px 11px; }
.btn.accent { border-color: var(--accent); color: var(--accent); }
.btn.accent:hover { background: var(--accent-soft); }

/* ---------------------------------------------------------------- Panels */
.panel {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r); box-shadow: var(--shadow);
  padding: 18px 20px; margin-bottom: 20px;
}
.panel-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.panel-head h2 { font-size: 16px; }

.rf-grid { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.rf-col h3 { font-size: 13.5px; margin-bottom: 5px; }
.rf-col > p { margin: 0 0 12px; font-size: 12.5px; line-height: 1.55; }
.rf-scopes { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; font-size: 13px; }
.rf-scopes label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.rf-scopes input { accent-color: var(--accent); }
.rf-btns { display: flex; gap: 8px; margin-bottom: 8px; }
.rf-plan { margin-bottom: 12px; }
.rf-sum { display: flex; gap: 14px; font-size: 13.5px; margin-bottom: 9px; flex-wrap: wrap; }
.rf-src { display: grid; grid-template-columns: 120px 1fr auto; gap: 10px; align-items: center;
          font-size: 12px; padding: 3px 0; }
.rf-bar { height: 5px; background: var(--border); border-radius: 3px; overflow: hidden; }
.rf-bar i { display: block; height: 100%; background: var(--p1); }
.rf-src.erhöht .rf-bar i { background: var(--p2); }
.rf-src.kritisch .rf-bar i { background: var(--bad); }

/* -------------------------------------------------------------- Zeitplan */
.timing-head { display: flex; justify-content: space-between; align-items: center;
               gap: 18px; flex-wrap: wrap; margin-bottom: 14px; }
.timing-head h2 { font-size: 16px; }
.range { display: flex; gap: 10px; }
.range label { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--fg-mute); }
input, select {
  background: var(--bg-2); color: var(--fg); border: 1px solid var(--border);
  border-radius: 8px; padding: 7px 10px; font: inherit; font-size: 13.5px;
}
input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.timing-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.leg { background: var(--bg-2); border: 1px solid var(--border); border-radius: 11px; padding: 13px 15px; }
.leg h3 { font-size: 13.5px; }
.leg .port { font-size: 11.5px; color: var(--fg-mute); margin: 2px 0 10px; }
.leg-row { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: 13px; }
.leg-row + .leg-row { border-top: 1px dashed var(--border); }
.leg-row b { font-variant-numeric: tabular-nums; }
.urgent { color: var(--bad); }

/* ----------------------------------------------------------------- Tabs */
.tabs { display: flex; gap: 3px; flex-wrap: wrap; margin-bottom: 18px; }
.tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--fg-dim); padding: 9px 15px; font: inherit; font-size: 14px;
  cursor: pointer; border-radius: 8px 8px 0 0;
}
.tab:hover { color: var(--fg); background: var(--accent-soft); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 620; }

.toolbar { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-bottom: 18px; }
.search { flex: 1 1 260px; }
.check { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--fg-dim); cursor: pointer; }
.check input { accent-color: var(--accent); }
.hint {
  font-size: 13px; line-height: 1.6; color: var(--fg-dim);
  background: var(--accent-soft); border-left: 3px solid var(--accent);
  padding: 10px 14px; border-radius: 0 9px 9px 0; margin: 0 0 16px;
}
.state { padding: 34px 20px; text-align: center; color: var(--fg-mute); font-size: 13.5px; }

/* --------------------------------------------------------- Prio-Gruppen */
.prio-group { margin-bottom: 26px; }
.pg-head { display: flex; align-items: baseline; gap: 11px; margin-bottom: 11px; }
.pg-bar { width: 3px; align-self: stretch; border-radius: 2px; }
.pg-title { font-size: 14.5px; font-weight: 650; }
.pg-count {
  font-size: 11.5px; font-weight: 600; padding: 1px 8px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--border); color: var(--fg-mute);
}
.pg-sub { font-size: 12.5px; color: var(--fg-mute); margin-left: auto; text-align: right; }

.sh-sec { margin-bottom: 22px; }
.sh-head { display: flex; align-items: baseline; gap: 11px; margin-bottom: 9px; }
.sh-title { font-size: 14px; font-weight: 650; }

.cards { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }

/* ---------------------------------------------------------------- Karten */
.ship {
  position: relative; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r); padding: 14px 16px 14px 18px; cursor: pointer;
  display: flex; flex-direction: column; gap: 9px;
  box-shadow: var(--shadow); transition: transform .13s, border-color .13s;
}
.ship::before {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--p4);
}
.ship:hover { transform: translateY(-1px); border-color: var(--accent); }
.ship.p1::before { background: var(--p1); }
.ship.p2::before { background: var(--p2); }
.ship.p3::before { background: var(--p3); }
.ship.p9::before { background: var(--out); }
.ship.p1 { background: linear-gradient(90deg, var(--p1-soft), transparent 55%), var(--card); }
.ship.p2 { background: linear-gradient(90deg, var(--p2-soft), transparent 55%), var(--card); }
.ship.p9 { opacity: .55; }
.ship.marked { border-color: var(--mark); background: var(--mark-soft); }

.s-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.s-name { font-size: 15.5px; font-weight: 650; letter-spacing: -.01em; }
.s-line { font-size: 11.5px; color: var(--fg-mute); margin-top: 1px; }
.s-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

.tag {
  font-size: 10.5px; font-weight: 650; padding: 2px 8px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap;
}
/* Schrift auf der gefüllten P1-Fläche als eigenes Token: im Dunkelmodus ist
   --p1 ein helles Grün (dunkle Schrift nötig), im Hellmodus ein dunkles
   (helle Schrift nötig). Fest verdrahtetes #05210f war hell unlesbar. */
.tag.p1 { background: var(--p1); color: var(--p1-on); }
.tag.p2 { background: var(--p2-soft); color: var(--p2); border-color: var(--p2); }
.tag.p3 { background: var(--p3-soft); color: var(--p3); border-color: var(--p3); }
.tag.p4 { background: transparent; color: var(--fg-mute); border-color: var(--border); }
.tag.p9 { background: transparent; color: var(--out); border-color: var(--border); }
.tag.forum { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }

.mark-btn { background: none; border: none; cursor: pointer; padding: 0 2px;
            font-size: 16px; line-height: 1; color: var(--fg-mute); transition: color .15s, transform .12s; }
.mark-btn:hover { color: var(--mark); transform: scale(1.16); }
.mark-btn.on { color: var(--mark); }
.fit-dot { color: var(--fit); font-size: 11px; cursor: help; }

/* Reiseband auf der Karte */
.route { display: flex; align-items: center; gap: 7px; font-size: 12.5px; flex-wrap: wrap; }
.route .from { color: var(--fg-dim); }
.route .arrow { color: var(--fg-mute); }
.route .to { font-weight: 620; }
.route .eta { color: var(--fg-mute); font-variant-numeric: tabular-nums; margin-left: auto; font-size: 11.5px; }

.facts { display: flex; gap: 14px; font-size: 11.5px; color: var(--fg-mute); flex-wrap: wrap; margin-top: 6px; }
.facts b { color: var(--fg-dim); font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---- Tiefgang-Block ---- */
.draught { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin-top: 8px; }
.dr-head { display: flex; align-items: baseline; gap: 6px; }
.dr-label { font-size: 11.5px; color: var(--fg-mute); }
.dr-val { color: var(--fg); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 14px; }
.dr-state {
  font-size: 10px; text-transform: uppercase; letter-spacing: .05em; font-weight: 700;
  padding: 1px 6px; border-radius: 999px; line-height: 1.5;
}
.dr-state.light { color: var(--fg-dim);  background: color-mix(in srgb, var(--fg-mute) 16%, transparent); }
.dr-state.mid   { color: var(--p2);      background: var(--p2-soft); }
.dr-state.full  { color: var(--p1);      background: var(--p1-soft); }

/* Änderungs-Badge: das zentrale „wann wurde geladen/gelöscht" */
.dr-change {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border); color: var(--fg-dim);
}
.dr-change .dr-arrow { font-size: 10px; line-height: 1; }
.dr-change .dr-delta { font-variant-numeric: tabular-nums; font-weight: 700; }
.dr-change .dr-when  { color: var(--fg-mute); font-weight: 500; font-size: 11px; }
.dr-change.loaded {
  color: var(--p1); border-color: color-mix(in srgb, var(--p1) 45%, transparent);
  background: var(--p1-soft);
}
.dr-change.unloaded {
  color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent);
  background: color-mix(in srgb, var(--bad) 9%, transparent);
}
.dr-change.stable { border-style: dashed; color: var(--fg-mute); background: transparent; }
.dr-change.stable .dr-kind { font-weight: 500; }

.spark { width: 64px; height: 18px; margin-left: auto; }
.spark polyline { fill: none; stroke: var(--fg-mute); stroke-width: 1.5; stroke-linejoin: round; }
.spark circle.now  { fill: var(--fg-dim); }
.spark circle.chg.up   { fill: var(--p1); }
.spark circle.chg.down { fill: var(--bad); }

.why { display: flex; flex-direction: column; gap: 2px; font-size: 11.5px; }
.why div { display: flex; gap: 6px; align-items: baseline; }
.why .y { color: var(--p1); }
.why .n { color: var(--fg-mute); }
.why .q { color: var(--fg-mute); }

/* ------------------------------------------------------------ Entdeckung */
.discover { margin-top: 8px; }
.ship.new { border-style: dashed; cursor: default; }
.routine { margin-top: 12px; font-size: 12.5px; color: var(--fg-mute); }
.routine summary { cursor: pointer; padding: 5px 0; }
.routine div { font-size: 11.5px; line-height: 1.7; padding-top: 4px; }

/* ---------------------------------------------------------- Schiffsakte */
.dossier {
  position: fixed; inset: 0; z-index: 900;
  background: #000a; backdrop-filter: blur(2px);
  display: flex; justify-content: flex-end;
}
.dossier-inner {
  width: min(660px, 100%); height: 100%; overflow-y: auto;
  background: var(--bg); border-left: 1px solid var(--border);
  padding: 26px clamp(18px, 3vw, 30px) 60px; position: relative;
}
.dossier-close { position: absolute; top: 18px; right: 20px; }
.d-name { font-size: 22px; font-weight: 650; }
.d-sub { color: var(--fg-mute); font-size: 13px; margin: 3px 0 18px; }
.d-sec { margin-bottom: 24px; }
.d-sec h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .07em;
            color: var(--fg-mute); margin-bottom: 9px; font-weight: 620; }

.d-fields { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.d-field { display: grid; grid-template-columns: 96px 1fr auto; gap: 12px;
           background: var(--card); padding: 8px 13px; font-size: 13px; align-items: baseline; }
.d-field .k { color: var(--fg-mute); font-size: 12px; }
.d-field .v { font-weight: 600; }
.d-field .src { font-size: 11px; color: var(--fg-mute); text-align: right; }

/* Reisestrahl */
.timeline { position: relative; padding-left: 18px; }
.timeline::before { content: ''; position: absolute; left: 4px; top: 6px; bottom: 6px;
                    width: 2px; background: var(--border); border-radius: 1px; }
.tl-item { position: relative; padding: 7px 0; font-size: 13px; }
.tl-item::before { content: ''; position: absolute; left: -18px; top: 13px;
                   width: 9px; height: 9px; border-radius: 50%;
                   background: var(--bg); border: 2px solid var(--fg-mute); }
.tl-item.tesla::before { border-color: var(--p1); background: var(--p1); }
.tl-item.load::before  { border-color: var(--p2); background: var(--p2); }
.tl-port { font-weight: 620; }
.tl-meta { font-size: 11.5px; color: var(--fg-mute); }
.tl-hint { font-size: 11.5px; font-weight: 620; }
.tl-hint.geladen { color: var(--p1); }
.tl-hint.gelöscht { color: var(--bad); }
.tl-hint.unverändert { color: var(--fg-mute); }

/* Tiefgangskurve */
.chart { width: 100%; height: 120px; background: var(--bg-2);
         border: 1px solid var(--border); border-radius: 10px; }
.chart polyline { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.chart .area { fill: var(--accent-soft); stroke: none; }
.chart circle { fill: var(--accent); }
.chart circle.chg.up   { fill: var(--p1); stroke: var(--card); stroke-width: 1.5; }
.chart circle.chg.down { fill: var(--bad); stroke: var(--card); stroke-width: 1.5; }
.chart text { fill: var(--fg-mute); font-size: 9px; }
.chart text.chg-lbl { font-size: 10px; font-weight: 700; text-anchor: middle; }
.chart text.chg-lbl.up   { fill: var(--p1); }
.chart text.chg-lbl.down { fill: var(--bad); }
.chart line { stroke: var(--border); stroke-width: 1; }

/* Klartext-Zusammenfassung über dem Detail-Chart */
.dr-summary {
  display: flex; align-items: center; gap: 6px; margin: 0 0 8px;
  font-size: 12.5px; font-weight: 600; color: var(--fg-dim);
}
.dr-summary .dr-arrow { font-size: 10px; }
.dr-summary.loaded   { color: var(--p1); }
.dr-summary.unloaded { color: var(--bad); }

/* Forum-Belegkasten */
.fbox { border-radius: 10px; padding: 11px 13px; border: 1px solid var(--border);
        background: var(--bg-2); display: flex; flex-direction: column; gap: 5px; }
.fbox.confirmed { border-color: var(--p1); background: var(--p1-soft); }
.fbox.suspected { border-color: var(--p2); background: var(--p2-soft); }
.fbox-head { display: flex; gap: 8px; align-items: center; font-size: 11.5px; flex-wrap: wrap; }
.fbox-label { font-weight: 700; }
.fbox.confirmed .fbox-label { color: var(--p1); }
.fbox.suspected .fbox-label { color: var(--p2); }
.fbox-who { color: var(--fg-mute); }
.vet { font-size: 9.5px; font-weight: 700; padding: 1px 6px; border-radius: 999px;
       background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent); }
.fbox p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--fg-dim); }
.fbox .caveat { color: var(--warn); }

/* Forumsbeiträge */
.post { background: var(--card); border: 1px solid var(--border); border-left: 3px solid var(--border);
        border-radius: 11px; padding: 12px 15px; margin-bottom: 10px; }
.post.veteran { border-left-color: var(--accent); }
.post.own { border-left-color: var(--mark); }
.post-head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.post-who { font-weight: 620; font-size: 13.5px; display: flex; gap: 7px; align-items: center; }
.post-meta { font-size: 11.5px; color: var(--fg-mute); }
.post p { margin: 6px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--fg-dim); }
.chips { display: flex; gap: 5px; flex-wrap: wrap; }
.chip { font-size: 11px; padding: 2px 7px; border-radius: 6px;
        background: var(--bg-2); border: 1px solid var(--border); color: var(--fg-dim); }
.chip.hit { color: var(--p1); border-color: var(--p1); }

/* KI-Befunde */
.ai-findings { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.finding { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; background: var(--bg-2); }
.finding-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 13px; }
.finding b { font-weight: 650; }
.finding p { margin: 5px 0 0; font-size: 12px; color: var(--fg-dim); line-height: 1.5; }
.finding q { font-size: 11.5px; color: var(--fg-mute); font-style: italic; }

/* Tabellen (Häfen) */
.tbl-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r); }
table { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 13px; }
th, td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--border); }
th { background: var(--bg-2); color: var(--fg-mute); font-size: 11px;
     text-transform: uppercase; letter-spacing: .05em; font-weight: 620; }
tbody tr:hover { background: var(--accent-soft); }
tbody tr:last-child td { border-bottom: none; }
td.num { font-variant-numeric: tabular-nums; }
.bar { display: flex; align-items: center; gap: 8px; min-width: 120px; }
.bar-track { flex: 1; height: 5px; background: var(--border); border-radius: 3px; overflow: hidden; }
.bar-track i { display: block; height: 100%; background: var(--accent); }
.bar-track i.full { background: var(--p1); }
.bar-track i.light { background: var(--p4); }

.port-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.ptab { background: var(--bg-2); border: 1px solid var(--border); border-radius: 999px;
        padding: 6px 14px; font: inherit; font-size: 13px; color: var(--fg-dim); cursor: pointer; }
.ptab:hover { border-color: var(--accent); }
.ptab.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }

#map { height: min(70vh, 660px); border-radius: var(--r); border: 1px solid var(--border); z-index: 0; }
:root[data-theme="dark"] .leaflet-tile { filter: brightness(.72) saturate(.8) contrast(1.06); }
.leaflet-popup-content-wrapper, .leaflet-popup-tip { background: var(--card); color: var(--fg); }

.foot-note { margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--border);
             color: var(--fg-mute); font-size: 12px; line-height: 1.6; max-width: 76ch; }

@media (max-width: 720px) {
  .top { gap: 14px; }
  .top-status { order: 3; width: 100%; }
}

/* Schiffsnamen nicht umbrechen lassen - die Karte gibt lieber etwas nach */
.s-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.s-top { align-items: center; }
/* min(100%, …) statt fester 360px: auf schmalen Handys ist der Container
   schmaler als die Mindestbreite, und eine starre minmax(360px) sprengt ihn
   (waagerechtes Scrollen). Die Media-Query oben lief hier ins Leere, weil
   diese Regel später steht und gleich spezifisch ist. */
.cards { grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr)); }
.s-right { flex-wrap: wrap; justify-content: flex-end; max-width: 55%; }
.tag { font-size: 10px; padding: 2px 7px; }

/* Eigene Einstufung */
.step-btn { background: none; border: 1px solid var(--border); border-radius: 6px;
            color: var(--fg-mute); cursor: pointer; font-size: 11px; line-height: 1;
            padding: 3px 5px; transition: color .15s, border-color .15s; }
/* Richtung auch farblich: hoch geht Richtung Treffer, runter Richtung Ablage */
.step-btn.up:hover   { color: var(--p1); border-color: var(--p1); }
.step-btn.down:hover { color: var(--p4); border-color: var(--p4); }
.tag.own { box-shadow: inset 0 0 0 1px var(--mark); }

/* Hafenlisten: Reederei-Marker und Herkunft neben dem Schiffsnamen */
.s-name-h { font-weight: 600; }
.lm { display: inline-block; margin-left: 7px; padding: 1px 6px; border-radius: 6px;
      font-size: 10.5px; font-weight: 600; vertical-align: middle; white-space: nowrap; }
.lm1 { background: var(--p1-soft); color: var(--p1); box-shadow: inset 0 0 0 1px var(--p1); }
.lm2 { background: var(--p2-soft); color: var(--p2); box-shadow: inset 0 0 0 1px var(--p2); }
.lm3 { background: transparent; color: var(--fg-mute); box-shadow: inset 0 0 0 1px var(--border); }
.orig { display: inline-block; margin-left: 7px; font-size: 10.5px; color: var(--fg-mute);
        vertical-align: middle; white-space: nowrap; }
.orig.fe { color: var(--p1); font-weight: 600; }

.prio-ctl { margin-top: 14px; padding: 12px 13px; background: var(--bg-2);
            border: 1px solid var(--border); border-radius: 10px; }
.pc-label { font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
            color: var(--fg-mute); margin-bottom: 8px; font-weight: 620; }
.pc-row { display: flex; gap: 6px; flex-wrap: wrap; }
.pc-btn { background: var(--card); border: 1px solid var(--border); border-radius: 8px;
          padding: 5px 11px; font: inherit; font-size: 12.5px; color: var(--fg-dim); cursor: pointer; }
.pc-btn:hover { border-color: var(--accent); color: var(--fg); }
.pc-btn.active { background: var(--mark-soft); border-color: var(--mark); color: var(--mark); font-weight: 620; }
.pc-info { display: flex; align-items: center; gap: 10px; margin-top: 9px;
           font-size: 12px; color: var(--fg-mute); }
.pc-reset { background: none; border: none; color: var(--accent); cursor: pointer;
            font: inherit; font-size: 12px; text-decoration: underline; padding: 0; }
.pc-note { margin-top: 7px; font-size: 12px; color: var(--fg-dim); line-height: 1.5; }

/* ==================================================== Forum-Export (Community) */
.ex-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
          flex-wrap: wrap; margin-bottom: 6px; }
.ex-bar-l h2 { margin: 0; font-size: 18px; }
.ex-bar-r { display: flex; align-items: center; gap: 12px; }

/* „Stand:"-Zeile über den Karten */
.ex-stand { font-size: 12px; color: var(--fg-mute); font-variant-numeric: tabular-nums; margin: 10px 0 0; }

/* Karten-Raster: jede Karte bringt ihre eigene Mini-Map mit */
.ex-cards { display: grid; gap: 14px;
            grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
            align-content: start; margin: 10px 0 26px; }

/* Karten wie im Tracking (Farbleiste + Verlauf), aber nicht klickbar */
.ex-card { cursor: default; padding: 15px 17px 16px 19px; gap: 11px; }
.ex-card:hover { transform: none; border-color: var(--border); }
.ex-card.p3 { background: linear-gradient(90deg, var(--p3-soft), transparent 55%), var(--card); }
/* NEU-Rahmen in der jeweiligen Prio-Farbe, nicht generell grün */
.ex-card.ex-new.p1 { border-color: color-mix(in srgb, var(--p1) 50%, var(--border)); }
.ex-card.ex-new.p2 { border-color: color-mix(in srgb, var(--p2) 50%, var(--border)); }
.ex-card.ex-new.p3 { border-color: color-mix(in srgb, var(--p3) 50%, var(--border)); }
.ex-newtag { font-size: 10px; font-weight: 800; letter-spacing: .06em;
             color: var(--fg-mute); background: color-mix(in srgb, var(--fg-mute) 15%, transparent);
             padding: 2px 7px; border-radius: 999px; }
.ex-card.p1 .ex-newtag { color: var(--p1); background: var(--p1-soft); }
.ex-card.p2 .ex-newtag { color: var(--p2); background: var(--p2-soft); }
.ex-card.p3 .ex-newtag { color: var(--p3); background: var(--p3-soft); }

/* Reise-Timeline: besuchte Häfen → aktiver Abschnitt (Progress + Schiff) → nächster
   Hafen → künftige Häfen. Ersetzt die alte „Hafen → Hafen → Ziel"-Zeile. */
.ex-voyage { display: flex; flex-direction: column; gap: 7px;
             padding: 11px 12px 9px; border-radius: 10px;
             background: color-mix(in srgb, var(--fg-mute) 8%, transparent); }
.vy-track { display: flex; align-items: flex-start; }

/* Hafen-Knoten: Punkt oben, Name darunter (mittig unter dem Punkt) */
.vy-port { display: flex; flex-direction: column; align-items: center; gap: 5px;
           flex: 0 0 auto; }
.vy-dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 1px;
          background: var(--fg-mute); box-sizing: border-box; }
.vy-name { font-size: 11px; font-weight: 600; color: var(--fg-dim);
           white-space: nowrap; letter-spacing: .2px; }

/* besucht / nächster / künftig */
.vy-port.visited .vy-dot { background: var(--fg-mute); }
.vy-port.visited .vy-name { color: var(--fg-mute); }
.vy-port.next .vy-dot { background: var(--fg);
          box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 22%, transparent); }
.vy-port.next .vy-name { color: var(--fg); font-weight: 800; }
.vy-port.future .vy-dot { background: transparent;
          border: 1.5px solid var(--fg-mute); }
.vy-port.future .vy-name { color: var(--fg-mute); }
/* Farb-Akzente ziehen: Shanghai gold, Zeebrugge/Koper grün (Punkt + Name) */
.vy-port.sha .vy-name { color: var(--gold); font-weight: 800; }
.vy-port.sha .vy-dot  { background: var(--gold); border-color: var(--gold); }
.vy-port.eu  .vy-name { color: var(--green); font-weight: 800; }
.vy-port.eu  .vy-dot  { background: var(--green); border-color: var(--green); }
.vy-port.future.sha .vy-dot,
.vy-port.future.eu  .vy-dot { background: transparent; }

/* Abschnitt zwischen zwei Häfen: Linie auf Höhe der Punktmitte (~6px) */
.vy-leg { flex: 1 1 auto; min-width: 26px; height: 11px; position: relative; }
.vy-leg::before { content: ''; position: absolute; left: 0; right: 0; top: 5px;
                  height: 2px; border-radius: 2px; background: var(--fg-mute); opacity: .5; }
.vy-leg.done::before { background: var(--fit); opacity: .9; }
.vy-leg.future::before { background: none; border-top: 2px dashed var(--fg-mute);
                  height: 0; opacity: .55; }
/* aktiver Abschnitt: graue Grundlinie + farbige Füllung bis zum Schiff */
.vy-leg.active::before { opacity: .35; }
/* Zurückgelegte Strecke als laufende Welle statt als glatter Balken.

   Umgesetzt als MASKE, nicht als Hintergrundbild: In einer Daten-URL lassen
   sich keine CSS-Variablen verwenden, die Wellenfarbe müsste also fest
   verdrahtet werden und würde beim Themawechsel nicht mitziehen. So liefert
   das SVG nur die Form, die Farbe bleibt var(--fit).

   Die Kachel ist 24 px breit und enthält EINE volle Schwingung - die Welle ist
   damit 24 px lang statt 12. Am rechten Rand trifft die Kurve Höhe und Steigung
   des linken wieder, deshalb ist die Wiederholung nahtlos und ein Versatz um
   exakt 24 px läuft rund.

   Höhe 10 px bei top:1px zentriert die Welle auf y=6 - dort sitzt auch die
   Mitte des Schiffsdreiecks (top:1px + 5px Rahmen). */
.vy-fill {
  position: absolute; left: 0; top: 1px; height: 10px;
  background: var(--fit); width: 0; transition: width .4s ease;
  --wave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 10' preserveAspectRatio='none'%3E%3Cpath d='M0 5 Q 6 1.6 12 5 T 24 5' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  -webkit-mask-image: var(--wave); mask-image: var(--wave);
  -webkit-mask-repeat: repeat-x; mask-repeat: repeat-x;
  -webkit-mask-size: 24px 10px; mask-size: 24px 10px;
  -webkit-mask-position: 0 0; mask-position: 0 0;
}
.vy-leg.active.indet .vy-fill { width: 50%;
           background: linear-gradient(90deg, var(--fit), transparent); }
/* Schiffs-Marker als scharfes CSS-Dreieck (kein Font-Glyph) auf der Linie */
.vy-ship { position: absolute; top: 1px; left: 50%; transform: translateX(-50%);
           width: 0; height: 0;
           border-top: 5px solid transparent; border-bottom: 5px solid transparent;
           border-left: 9px solid var(--fit);
           filter: drop-shadow(0 0 2px var(--bg)); }

.vy-eta { color: var(--fg-mute); font-size: 11.5px; align-self: flex-end;
          font-variant-numeric: tabular-nums; }

/* Tiefgang-Zeile im Export */
.ex-dr { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }
.ex-dr-cur { display: inline-flex; align-items: baseline; gap: 6px; }
.ex-dr-cur > b { color: var(--fg); font-variant-numeric: tabular-nums; font-weight: 700; font-size: 14px; }
/* Frische Änderung: fällt sie auf „heute", wird das Wort in der Bubble fett + gold
   hervorgehoben — so ist eine tagesaktuelle Be-/Entladung sofort erkennbar. */
.dr-change .dr-when .today { color: var(--gold); font-weight: 800; }

/* VIN-Endungen: dezente Tags zwischen Tiefgang und Keypoints */
.ex-vins { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; }
.ex-vins-lbl { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
               color: var(--fg-mute); margin-right: 2px; }
.ex-vin-tag { font-size: 10.5px; font-variant-numeric: tabular-nums; color: var(--fg-dim);
              background: color-mix(in srgb, var(--fg-mute) 12%, transparent);
              border: 1px solid var(--border); border-radius: 5px; padding: 0 5px; line-height: 17px; }

/* Keypoints */
.ex-keys { display: flex; flex-direction: column; gap: 4px; margin-top: 2px;
           border-top: 1px solid var(--border); padding-top: 9px; }
.ex-key { display: flex; gap: 7px; align-items: baseline; font-size: 12.5px; color: var(--fg-dim); }
.ex-key-ic { font-size: 10px; width: 12px; flex: none; text-align: center; }
.ex-key.up   { color: var(--p1); }
.ex-key.up   .ex-key-ic { color: var(--p1); }
.ex-key.down { color: var(--bad); }
.ex-key.down .ex-key-ic { color: var(--bad); }
.ex-key.new  { color: var(--p1); font-weight: 600; }
.ex-key.info .ex-key-ic { color: var(--accent); }
.ex-key.none { color: var(--fg-mute); }

/* Mini-Karte je Schiffskarte (eigene Position, verschiebbarer Punkt) */
.ex-cardmap { height: 180px; margin-top: 4px; border-radius: 9px; border: 1px solid var(--border);
              overflow: hidden; z-index: 0; background: var(--bg); }
/* Kacheln bringen ihren Hell-/Dunkel-Stil selbst mit (dark_all bzw. light_all,
   umgeschaltet in export-render.js) - keinen zusätzlichen Filter drüberlegen. */
.ex-cardmap .leaflet-tile { filter: none !important; }
/* parkend: runder Punkt (NICHT für den Pfeil, sonst Kreis um den Pfeil).
   Der Ring hebt den Punkt vom Untergrund ab und muss darum mit dem Thema
   kippen - auf hellen Kacheln war Weiß auf Weiß unsichtbar. */
.ex-pin:not(.sail) span { display: block; width: 14px; height: 14px; border-radius: 50%;
               border: 2px solid var(--pin-ring); box-shadow: 0 0 0 1px var(--pin-shadow); }
/* fahrend: gestreckter, gerichteter SVG-Pfeil (auf Kurs gedreht) */
.ex-pin.sail .arr { display: block; transform-origin: 50% 50%;
                    filter: drop-shadow(0 0 2px var(--pin-shadow)); }
.leaflet-tooltip.ex-label {
  background: var(--map-chip); color: var(--fg); border: 1px solid var(--border);
  border-radius: 6px; padding: 1px 7px; font-size: 12px; font-weight: 650;
  box-shadow: 0 2px 8px var(--pin-shadow); white-space: nowrap;
}
.leaflet-tooltip.ex-label::before { display: none; }

/* Zahnrad-Knopf auf der Karte */
.ex-gear { width: 30px; height: 30px; border: 0; border-radius: 6px; cursor: pointer;
           background: var(--map-chip); color: var(--fg); font-size: 15px; line-height: 1;
           box-shadow: 0 1px 4px var(--pin-shadow); }
.ex-gear:hover { filter: brightness(1.25); }

/* Steuer-Panel unter der Karte */
.ex-mappanel { display: none; margin-top: 6px; padding: 8px 10px; gap: 7px;
               border: 1px solid var(--border); border-radius: 8px; background: var(--bg-2);
               flex-direction: column; }
.ex-mappanel.open { display: flex; }
.mp-row { display: flex; align-items: center; gap: 8px; }
.mp-lbl { flex: none; width: 46px; font-size: 10.5px; color: var(--fg-mute);
          text-transform: uppercase; letter-spacing: .04em; }
.mp-btn { width: 28px; height: 24px; flex: none; border: 1px solid var(--border); border-radius: 6px;
          background: var(--card); color: var(--fg); cursor: pointer; font-size: 15px; line-height: 1; }
.mp-btn:hover { border-color: var(--accent); }
.mp-toggle { flex: 1; padding: 4px 6px; border: 1px solid var(--border); border-radius: 6px;
             background: var(--card); color: var(--fg-mute); cursor: pointer; font-size: 11.5px; font-weight: 600; }
.mp-toggle.on { color: var(--fg); border-color: var(--accent); background: var(--accent-soft); }
.mp-slider { flex: 1; accent-color: var(--accent); }
.mp-head { flex: none; width: 68px; text-align: right; font-size: 11.5px; color: var(--fg-dim);
           font-variant-numeric: tabular-nums; }


/* ==========================================================================
   Veröffentlichte Ansicht (site/) — Kopf, Umschalter, Animationen.
   Steht bewusst hier und nicht in einer zweiten Datei: publish.mjs kopiert
   diese style.css nach site/, damit die Kacheln online und lokal identisch
   sind. Die .pub-* Regeln greifen lokal einfach nie.
   ========================================================================== */

.pub { max-width: 1400px; margin: 0 auto; }

/* --- Übergreifende Leiste (steht über Schiffs-Seite UND Spiel) -------------

   Eigenständig und von der Seite darunter getrennt: kleine Wortmarke links,
   Bereichswechsel in der Mitte, Hell/Dunkel rechts. Bleibt beim Scrollen oben.
   Die Klassen sind NICHT auf .pub eingeschränkt, damit das Spiel den Block
   unverändert übernehmen kann. Dort heißen die Farbvariablen anders:
     --bg → --bg · --card → --panel · --bg-2 → --panel2 · --border → --line
     --fg → --txt · --fg-dim → --txt-dim · --accent und --shadow bleiben      */

.appbar {
  position: sticky; top: 0; z-index: 500;
  /* body hat seitliches Polster - die Leiste bricht per negativem Rand aus,
     damit sie über die volle Breite geht, und holt es innen wieder herein. */
  margin: 0 calc(-1 * clamp(14px, 4vw, 44px));
  padding: 0 clamp(14px, 4vw, 44px);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.appbar-in { display: flex; align-items: center; gap: 12px;
             max-width: 1400px; margin: 0 auto; min-height: 52px; }
.appbrand { display: inline-flex; align-items: center; gap: 7px; flex: 1 1 0;
            font-size: 13.5px; font-weight: 650; color: var(--fg-dim);
            letter-spacing: .2px; white-space: nowrap; }
.appbrand .ico { font-size: 16px; line-height: 1; }
/* Gleiches Gewicht wie die Wortmarke links, damit die Reiter mittig sitzen */
.appbar-r { flex: 1 1 0; display: flex; justify-content: flex-end; }

.pub .top { align-items: center; gap: 12px; padding: 20px 0 14px; margin-bottom: 16px; }
.logo { font-size: 26px; line-height: 1; flex: none; }
.titles { flex: 1 1 220px; min-width: 180px; }
.titles h1 { margin: 0; font-size: clamp(18px, 2.8vw, 23px); letter-spacing: -.3px; }
.pub .sub { margin: 2px 0 0; color: var(--fg-dim); font-size: 13px; max-width: 60ch; }
.pub .sub b { color: var(--green); font-weight: 650; }

/* Umschalter zwischen Schiffs-Seite und Spiel */
/* Der aktive Reiter darf sich NICHT auf einen Helligkeitsunterschied verlassen:
   im Hellmodus sind --bg-2 und --card beide reines Weiß, ein weißes Feld auf
   weißem Grund war schlicht unsichtbar. Stattdessen der Akzentrahmen, den auch
   die .mp-toggle.on-Knöpfe nutzen - der trägt in beiden Themen. */
.nav { display: flex; gap: 3px; flex: none; padding: 3px; border-radius: 11px;
       background: color-mix(in srgb, var(--fg-mute) 12%, transparent); }
.navlink { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
           padding: 6px 11px; border-radius: 8px; text-decoration: none;
           font-size: 13px; font-weight: 600; color: var(--fg-dim);
           border: 1px solid transparent;   /* hält die Größe stabil */
           transition: color .18s ease, background .18s ease,
                       border-color .18s ease, transform .18s ease; }
.navlink .ico { font-size: 14px; line-height: 1; }
.navlink:hover { color: var(--fg); transform: translateY(-1px); }
.navlink.on { color: var(--fg); background: var(--accent-soft);
              border-color: var(--accent); }
.navlink.on .ico { filter: none; }
.navlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Symbolknopf (Hell/Dunkel) - wie .iconbtn im Spiel */
.iconbtn { flex: none; background: var(--bg-2); color: var(--fg-dim);
           border: 1px solid var(--border); border-radius: 10px;
           padding: 7px 10px; font: inherit; font-size: 14px; line-height: 1.1;
           cursor: pointer; transition: color .18s ease, border-color .18s ease; }
.iconbtn:hover { border-color: var(--accent); color: var(--fg); }
.iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pub-standwrap { display: flex; align-items: center; gap: 7px; flex: none; }
.pub-standlbl { font-size: 11px; text-transform: uppercase; letter-spacing: .8px;
                color: var(--fg-mute); font-weight: 650; }
.pub-stand { background: var(--bg-2); color: var(--fg); border: 1px solid var(--border);
             border-radius: 9px; padding: 7px 10px; font: inherit; font-size: 13px;
             cursor: pointer; max-width: min(62vw, 320px); }
.pub-stand:hover { border-color: var(--accent); }
.pub-stand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pub-meta { margin: 14px 0 0; font-size: 12.5px; color: var(--fg-mute);
            font-variant-numeric: tabular-nums; }
.pub-empty { margin: 30px 0; color: var(--fg-mute); }

.pub-foot { margin-top: 34px; padding-top: 15px; border-top: 1px solid var(--border);
            color: var(--fg-mute); font-size: 11.5px; line-height: 1.7; max-width: 76ch; }
.pub-foot p { margin: 0 0 3px; }
.pub-attr a { color: var(--fg-dim); }

/* --------------------------------------------------------------- Bewegung

   Zurückhaltend gehalten: die Seite wird im Forum verlinkt und oft nur kurz
   überflogen. Alles unter .swapping ist der Wechsel zwischen zwei Ständen. */

/* Die Karte kommt von unten herein, mit leichtem Überschwingen am Ende
   (die 1.15 in der Kurve) - das gibt den federnden Anschlag. */
@keyframes pub-rise {
  from { opacity: 0; transform: translateY(28px) scale(.93); }
  55%  { opacity: 1; }
  to   { opacity: 1; transform: none; }
}
/* Gedeckelt bei 11, sonst wartet die letzte Karte bei vielen Schiffen ewig. */
.pub .ex-card {
  animation: pub-rise .6s cubic-bezier(.2,.9,.3,1.15) backwards;
  animation-delay: calc(min(var(--i, 0), 11) * 75ms);
}
/* Basisverzögerung je Karte, damit das Innenleben NACH seiner Karte startet */
.pub .ex-card { --d: calc(min(var(--i, 0), 11) * 75ms); }

@keyframes pub-pop {
  from { opacity: 0; transform: scale(.25); }
  70%  { opacity: 1; transform: scale(1.18); }
  to   { opacity: 1; transform: scale(1); }
}

/* Hafenpunkte poppen nacheinander auf. Im Track wechseln sich Punkt und
   Abschnitt ab, die Häfen sind also die ungeraden Kinder. */
.pub .vy-dot { animation: pub-pop .5s cubic-bezier(.3,1.5,.5,1) backwards; }
.pub .vy-port:nth-child(1) .vy-dot { animation-delay: calc(var(--d) + .22s); }
.pub .vy-port:nth-child(3) .vy-dot { animation-delay: calc(var(--d) + .34s); }
.pub .vy-port:nth-child(5) .vy-dot { animation-delay: calc(var(--d) + .46s); }
/* Greift nur noch bei handgesetzten Routen mit vier Häfen */
.pub .vy-port:nth-child(7) .vy-dot { animation-delay: calc(var(--d) + .58s); }

/* Balken wächst, Schiff fährt mit. Beide ohne to-Wert: der Endwert ist der
   inline gesetzte, die Kurve läuft also exakt bis zur echten Position. */
@keyframes pub-fill { from { width: 0; } }
@keyframes pub-glide { from { left: 0; } }
/* .vy-fill und .vy-ship bekommen weiter unten zusätzlich ihre Dauerbewegung
   (Welle bzw. Schaukeln). Beide Animationen stehen jeweils zusammen in EINER
   Regel - eine zweite Kurzschreibweise würde die Verzögerung von hier sonst
   wieder auf 0 zurücksetzen und die Staffelung zerstören. */

/* Der angesteuerte Hafen pulsiert - der Blick soll dort landen. */
@keyframes pub-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--fit) 60%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--fit) 0%, transparent); }
}
.pub .vy-port.next .vy-dot { animation: pub-pop .5s cubic-bezier(.3,1.5,.5,1) backwards,
                                        pub-pulse 2.4s ease-out 1.2s infinite; }

/* Tiefgang-Plakette und Keypoints laufen zeitversetzt nach */
.pub .dr-change { animation: pub-pop .45s cubic-bezier(.3,1.4,.5,1) backwards;
                  animation-delay: calc(var(--d) + .5s); }

@keyframes pub-slide { from { opacity: 0; transform: translateX(-10px); } }
.pub .ex-key { animation: pub-slide .45s ease-out backwards; animation-delay: calc(var(--d) + .62s); }
.pub .ex-key:nth-child(2) { animation-delay: calc(var(--d) + .72s); }
.pub .ex-key:nth-child(3) { animation-delay: calc(var(--d) + .82s); }
.pub .ex-key:nth-child(n+4) { animation-delay: calc(var(--d) + .92s); }

/* VIN-Tags kommen als kleine Kette */
.pub .ex-vin-tag { animation: pub-pop .38s cubic-bezier(.3,1.5,.5,1) backwards; }
.pub .ex-vin-tag:nth-child(2) { animation-delay: calc(var(--d) + .55s); }
.pub .ex-vin-tag:nth-child(3) { animation-delay: calc(var(--d) + .61s); }
.pub .ex-vin-tag:nth-child(4) { animation-delay: calc(var(--d) + .67s); }
.pub .ex-vin-tag:nth-child(5) { animation-delay: calc(var(--d) + .73s); }
.pub .ex-vin-tag:nth-child(6) { animation-delay: calc(var(--d) + .79s); }
.pub .ex-vin-tag:nth-child(7) { animation-delay: calc(var(--d) + .85s); }
.pub .ex-vin-tag:nth-child(n+8) { animation-delay: calc(var(--d) + .91s); }

/* „NEU" blinkt langsam, damit es zwischen den Karten auffällt */
@keyframes pub-blink { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
.pub .ex-newtag { animation: pub-blink 2.2s ease-in-out 1.4s infinite; }

/* ------------------------------------------------- Dauerbewegung (Leerlauf)

   Nach dem Einlauf soll die Seite nicht erstarren. Alles hier läuft endlos,
   aber langsam und klein - die Karten werden gelesen, nicht angestarrt. */

/* Laufende Ameisen auf der Strecken-Linie: die Striche wandern Richtung
   Schiff. dashArray ist 5 5, ein Versatz von 10 schließt den Kreis nahtlos.
   Trifft die Leaflet-SVG-Pfade in den Mini-Karten. */
@keyframes pub-ants { to { stroke-dashoffset: -10; } }
.pub .ex-cardmap .leaflet-overlay-pane path {
  animation: pub-ants 1.1s linear infinite;
}

/* Die Welle der zurückgelegten Strecke läuft nach rechts, also in
   Fahrtrichtung auf das Schiff zu. Ein Versatz um genau eine Kachelbreite
   (24 px) endet dort, wo er begann - der Übergang ist unsichtbar. */
@keyframes pub-wave {
  to { -webkit-mask-position: 24px 0; mask-position: 24px 0; }
}
.pub .vy-fill { animation: pub-fill 1.15s cubic-bezier(.25,.85,.3,1) backwards,
                           pub-wave 2.6s linear infinite;
                animation-delay: calc(var(--d) + .3s), calc(var(--d) + .3s); }

/* Das Schiff auf der Reiseleiste schaukelt leicht. translateX(-50%) muss in
   jedem Schritt mit, sonst springt das Dreieck aus der Mitte. */
@keyframes pub-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-1.5px); }
}
.pub .vy-ship { animation: pub-glide 1.15s cubic-bezier(.25,.85,.3,1) backwards,
                           pub-bob 2.8s ease-in-out infinite;
                animation-delay: calc(var(--d) + .3s), calc(var(--d) + 1.5s); }

/* Fahrende Schiffe auf der Karte atmen; parkende bleiben ruhig - so sieht man
   den Unterschied schon aus dem Augenwinkel. */
@keyframes pub-sail {
  0%, 100% { opacity: 1; }
  50%      { opacity: .72; }
}
.pub .ex-pin.sail .arr { animation: pub-sail 2.4s ease-in-out infinite; }

/* Der Prio-1-Chip bekommt gelegentlich einen Lichtstreif. */
@keyframes pub-shine { 0% { left: -60%; } 55%, 100% { left: 130%; } }
.pub .tag.p1 { position: relative; overflow: hidden; }
.pub .tag.p1::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent);
  animation: pub-shine 4.5s ease-in-out 2s infinite;
}

/* Die Prio-Leiste am Kartenrand pulst ganz leicht mit. */
@keyframes pub-edge { 0%, 100% { opacity: .85; } 50% { opacity: 1; } }
.pub .ex-card::before { animation: pub-edge 3.6s ease-in-out infinite; }

/* Anfassen: Karte hebt ab, VIN-Tags hüpfen */
.pub .ex-card { transition: transform .25s cubic-bezier(.2,.9,.3,1.15),
                            box-shadow .25s ease, border-color .2s ease; }
.pub .ex-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.pub .ex-vin-tag { transition: transform .18s cubic-bezier(.3,1.5,.5,1); }
.pub .ex-vin-tag:hover { transform: translateY(-3px) scale(1.12); }

/* Standwechsel: kurz weg, neu aufbauen, wieder da */
.pub .ex-cards { transition: opacity .2s ease, transform .2s ease; }
.pub .ex-cards.swapping { opacity: 0; transform: translateY(12px) scale(.99); }
.pub .ex-cards.swapping * { animation: none !important; }

@keyframes pub-spin { to { transform: rotate(360deg); } }
.pub .iconbtn.spin { animation: pub-spin .55s cubic-bezier(.3,.9,.3,1.1); }

/* Wer Bewegung abbestellt hat, bekommt keine - inklusive der Dauerläufer. */
@media (prefers-reduced-motion: reduce) {
  .pub * { animation: none !important; transition: none !important; }
  .pub .ex-cards.swapping { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------ schmale Geräte

   Die Reise-Timeline ist der engste Teil: vier Hafennamen nebeneinander, jeder
   mit white-space: nowrap. Auf dem Handy darf der Name umbrechen und kleiner
   werden, sonst drückt er die Karte auf. */
@media (max-width: 480px) {
  .vy-name { white-space: normal; font-size: 10px; line-height: 1.25;
             text-align: center; overflow-wrap: anywhere; }
  .vy-leg { min-width: 14px; }
  .ex-card { padding: 13px 13px 14px 15px; }
  .ex-cardmap { height: 150px; }
  /* Leiste schmaler; die Wortmarke gibt ihren Text auf, damit die Reiter
     mittig bleiben und nicht gequetscht werden. */
  .appbar-in { min-height: 46px; gap: 8px; }
  .brandtxt { display: none; }
  .navlink { padding: 6px 10px; font-size: 12.5px; }

  /* Seitenkopf: Titel über volle Breite, Stand-Auswahl darunter */
  .pub .top { gap: 9px; padding: 14px 0 12px; }
  .titles { flex: 1 1 100%; }
  .pub-standwrap { flex: 1 1 100%; }
  .pub-stand { flex: 1; max-width: none; }
  .s-right { max-width: 46%; }
}
