/* TASK-52: marginesy bezpieczeństwa podane przez system (SafeAreaPlugin.java).
   Zera to wartość startowa - dopóki wtyczka nie odpowie, obowiązuje samo
   env(). CSS bierze zawsze WIĘKSZĄ z dwóch wartości, więc żaden telefon nie
   traci: ten, który podaje poprawne env(), działa jak dotąd, a ten, który
   zwraca zero (nawigacja gestami), dostaje wartość z WindowInsetsCompat. */
:root {
  /* POPRAWKI SILNIKA NAWIGACJI pkt 1: zielony cyfry kafelka prędkości "w normie"
     (TASK-138, #00E676 z treści zadania) jako JEDNO źródło prawdy. Tego samego
     odcienia używa linia trasy przed nami na mapie (mapView.kolorTrasyPrzedNami),
     więc zmiana tutaj zmienia oba miejsca. */
  --kolor-predkosc-ok: #00e676;
  /* KAFELKI JAZDY: cztery kafelki zamiast osmiu - panel w pionie jeden rzad
     (bylo 20% ekranu, dwa rzedy), w poziomie jedna kolumna (bylo 26%). Wszystko,
     co stoi nad/obok panelu, liczy sie od tych dwoch wartosci. */
  --hud-wysokosc: 11%;
  --hud-szerokosc: 15%;
  /* TASK-86: wspólne minimalne rozmiary dotyku (obsługa w rękawicach
     motocyklowych) - zoom/kontrolne/przełączniki mają różne progi zależnie
     od tego, jak krytyczne i jak często dotykane są w trakcie jazdy. */
  --touch-zoom: 60px;
  /* TASK-142: szerokość kolumny +/- jako JEDNO źródło prawdy - używa jej i
     sam przycisk (.zoom-btn), i odsunięcie panelu manewru w poziomie
     (.manoeuvre-row w media query landscape). Bez tego dwie liczby mogłyby
     się rozjechać przy każdej przyszłej zmianie rozmiaru przycisku. */
  --zoom-col-w: clamp(var(--touch-zoom), 8vh, 64px);
  --touch-control: 64px;
  --touch-toggle: 48px;
  /* TASK-109: wysokość PAUZA/WSTECZ/ZAKOŃCZ dopasowana do banera manewru
     (.manoeuvre-panel) - policzone z jego własnego CSS: padding 12px+12px +
     max(.manoeuvre-arrow 48px, .manoeuvre-text ~58px złożone z .manoeuvre-distance
     34px/1.1 + .manoeuvre-label 17px) ≈ 82px. Ta sama wartość w obu
     orientacjach - zawartość banera (a więc jego wysokość) się nie zmienia
     między portretem a landscape, tylko jego szerokość (max-width). */
  --maneuver-banner-h: 82px;
  /* TASK-109 (dodatek, zgłoszenie użytkownika PO pierwszej weryfikacji na
     urządzeniu w obu orientacjach): PAUZA/WSTECZ/ZAKOŃCZ dopasowane 1:1 do
     --maneuver-banner-h wizualnie wypadły za duże - obniżone o 30%
     (82 × 0.7 = 57.4 ≈ 57px) względem TEGO stanu, w OBU orientacjach.
     Osobna zmienna (nie zmniejszamy --maneuver-banner-h samego) - to nadal
     wysokość NAPRAWDĘ banera manewru, niezmieniona; przyciski celowo dostają
     własny, mniejszy rozmiar. */
  --ride-btn-h: 57px;
  --sa-top: 0px;
  --sa-right: 0px;
  --sa-bottom: 0px;
  --sa-left: 0px;
}
/* TASK-45: całkowita blokada zaznaczania tekstu w interfejsie.

   Interfejs NaviTour to strona w WebView, nie widoki natywne, więc
   odpowiednikiem `android:textIsSelectable="false"` jest tutaj CSS - żaden
   przycisk czy etykieta nie jest obiektem TextView, do którego dałoby się
   przyłożyć ten atrybut.

   Dwie właściwości, bo odpowiadają za dwie różne rzeczy:
     `user-select: none`      - nie da się zaznaczyć tekstu,
     `-webkit-touch-callout`  - przytrzymanie nie wywołuje systemowego menu
                                (Kopiuj / Zaznacz wszystko / Udostępnij), czyli
                                dokładnie tego ActionMode z opisu zadania.
   Sam `user-select` nie wystarcza: bez `touch-callout` menu i tak potrafi się
   pokazać przy dłuższym przytrzymaniu.

   Blokada jest globalna (gwiazdka), a nie wyliczana po klasach przycisków -
   inaczej każdy nowy element interfejsu trzeba by pamiętać, żeby dopisać.
   Wyjątek dla pól edycyjnych jest niżej. */
* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* JEDYNY wyjątek: pola wyszukiwarki i pola liczbowe (dystans/czas pętli) muszą
   zachować pełną edycję razem z zaznaczaniem, kursorem i menu wklejania -
   bez tego nie dałoby się poprawić literówki w adresie ani wkleić nazwy. */
input,
textarea,
[contenteditable='true'] {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: "Segoe UI", Roboto, Tahoma, sans-serif;
  background: #1e2530;
  color: #e8ecf1;
  overflow: hidden;
}

/* TASK-52: body jako kolumna flex.

   Wcześniej wysokość obszaru roboczego była liczona jako calc(100% - 46px),
   czyli od SZTYWNO WPISANEJ wysokości belki górnej. Ta belka rośnie jednak
   o wcięcie paska stanu, a to zależy od telefonu (i od tego, czy jest wycięcie
   na aparat) - więc na urządzeniu z wyższym paskiem stanu obszar roboczy był
   o tyle za wysoki i dolne przyciski wychodziły poza ekran.

   Flex liczy tę różnicę sam: belka bierze tyle, ile potrzebuje, a reszta
   dostaje dokładnie to, co zostało - niezależnie od wielkości wcięć. */
body {
  display: flex;
  flex-direction: column;
}

.topbar {
  flex: 0 0 auto;
}

#screenContainer {
  flex: 1 1 auto;
  min-height: 0; /* bez tego zawartość rozpycha kolumnę zamiast się przewijać */
}

/* Siatka (nie flex) - INFO ma stać na ŚRODKU paska niezależnie od tego, ile
   miejsca zajmuje tytuł po lewej i odznaka wersji + zamknięcie po prawej,
   a to prostym flexem "space-between" się nie da (środkowy element nie jest
   wtedy wycentrowany względem CAŁEJ szerokości, tylko względem przestrzeni
   między sąsiadami). */
.topbar {
  display: grid;
  /* TASK-45: minmax(0, 1fr) zamiast samego 1fr. Po dołożeniu przycisku Ustawień
     zawartość przestała się mieścić w szerokości ekranu, a kolumny z "1fr" nie
     schodzą poniżej szerokości swojej treści - efekt był taki, że plakietka
     wersji NACHODZIŁA na przycisk Ustawień. minmax(0, 1fr) pozwala kolumnom
     skurczyć się poniżej treści, więc elementy układają się obok siebie. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  /* TASK-52: wcięcia boczne, nie tylko górne. W ORIENTACJI POZIOMEJ pasek
     stanu znika z góry, a wycięcie na aparat i pasek gestów lądują przy
     krawędzi lewej albo prawej - zależnie od tego, w którą stronę obrócono
     telefon. Sam odstęp górny nie chroni wtedy przed niczym. */
  padding-top: max(14px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  padding-bottom: 14px;
  padding-left: calc(16px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  padding-right: calc(16px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  background: #161b24;
  border-bottom: 1px solid #2c3644;
}

.topbar h1 {
  margin: 0;
  /* TASK-35: 34px na sztywno przycinało "NaviTour" na węższych telefonach
     (grid nie pozwala elementowi skurczyć się poniżej rozmiaru treści bez
     min-width:0 - patrz niżej). clamp() skaluje tytuł do szerokości ekranu
     zamiast trzymać stały rozmiar zaprojektowany pod jedno urządzenie. */
  font-size: clamp(22px, 7.5vw, 34px);
  color: #ffffff;
  justify-self: start;
  /* Bez tego grid liczy minimalną szerokość kolumny wg NIEZAWINIĘTEGO tekstu
     i wypycha resztę paska poza ekran - to był realny błąd zgłoszony ze
     zrzutem (napis "Zamknij aplikację" wychodził poza krawędź telefonu). */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#btnInfo {
  justify-self: center;
}

.topbar-right {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0; /* TASK-35: to samo zabezpieczenie co przy h1 - patrz komentarz tam */
}

.version-badge {
  font-size: 11px;
  color: #6b7688;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 999px;
  padding: 2px 10px;
  flex-shrink: 0;
}

/* Zamknięcie całej aplikacji - dotąd jedyna droga wyjścia była systemowa
   (przycisk "wstecz" tylko minimalizuje, patrz app.js), więc nie było
   żadnego szybkiego sposobu, żeby faktycznie zakończyć proces.
   TASK-30: samo "✕" bywało mylone z zamknięciem OKNA (np. modala) zamiast
   całej aplikacji - stąd jawny napis zamiast samego symbolu.
   TASK-35: font-size przez clamp() - na wąskich telefonach "Zamknij aplikację"
   nie mieści się przy pełnym rozmiarze obok tytułu i INFO; zamiast obcinać
   napis poza ekran, kurczy się razem z dostępnym miejscem. */
/* TASK-97: przebudowa na DWIE linijki tekstu ("Zamknij" / "aplikację" -
   patrz <br> w index.html) zamiast jednej kurczącej się przez clamp() do
   granicy czytelności. Gabaryt (szerokość i pole) mniejszy o ok. 35-40% niż
   poprzednia jednoliniowa wersja, a rozmiar czcionki jest teraz ustalony
   (12-13px), nie goni za miejscem obok tytułu/INFO/Ustawień. */
.close-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 6px 10px;
  border: 1px solid #5a2c2c;
  background: #2a1a1a;
  color: #ff8a80;
  border-radius: 14px;
  font-size: clamp(12px, 3.2vw, 13px);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  min-width: 0;
  white-space: normal;
}

/* TASK-35: na bardzo wąskich ekranach nawet skurczony tytuł + INFO + odznaka
   wersji + "Zamknij aplikację" się nie mieszczą - odznaka wersji jest tu
   najmniej istotna (widoczna też w oknie INFO), więc znika pierwsza. */
@media (max-width: 360px) {
  .version-badge {
    display: none;
  }
}

.layout {
  display: flex;
  flex-direction: column;
  height: 100%; /* TASK-52: wysokość daje flex na body, patrz wyżej */
  /* TASK-52: STAŁA REZERWA 34 px USUNIĘTA.

     Historia: env(safe-area-inset-bottom) na telefonie użytkownika zwracało 0
     przy nawigacji gestami, przez co fioletowy przycisk "Rejestruj przejazd"
     wchodził częściowo pod systemowy pasek. Obejściem była rezerwa +34 px
     doliczana ZAWSZE - także na telefonach, które env() podają poprawnie,
     gdzie po prostu marnowała pasek ekranu i sumowała się z prawdziwym insetem.

     Teraz --sa-bottom pochodzi wprost z WindowInsetsCompat (SafeAreaPlugin.java),
     czyli z tego samego źródła, z którego env() się wywodzi, tylko czytanego
     bez pośrednictwa WebView. Zgadywanie przestało być potrzebne: bierzemy
     większą z dwóch wartości i tyle, ile system faktycznie zajmuje.

     Boczne odstępy też są insetami, a nie stałą: w POZIOMIE wycięcie na aparat
     i pasek gestów są przy krawędzi lewej albo prawej, zależnie od strony obrotu. */
  padding-top: 10px;
  padding-bottom: max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px));
  padding-left: calc(10px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  padding-right: calc(10px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  gap: 10px;
  overflow-y: auto;
}

.screen-intro {
  margin: 4px 0 8px;
  font-size: 13px;
  color: #a7b0bd;
}

/* --- przyciski wspólne --- */

.action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  /* TASK-92: 15px/600 -> 18px/700 (dostępność - czytelność na Dashboardzie),
     min-height dodany, żeby większy tekst nie ścieśniał kontenera.
     TASK-94: 18px -> 20px - napisy dalej nie wypełniały powiększonych
     przycisków (dużo pustej przestrzeni pionowej przy min-height 64px). */
  padding: 16px 14px;
  min-height: var(--touch-control);
  border: none;
  border-radius: 10px;
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
  color: #fff;
  flex-shrink: 0;
  background: #1565c0;
}

/* TASK-146: ZNALEZIONA USTERKA (nie zgłoszona - wyszła przy weryfikacji innej
   sprawy). `.action-btn { display: flex }` to reguła AUTORSKA - bije domyślne
   `[hidden] { display: none }` przeglądarki (to jest reguła przeglądarki, nie
   autorska, więc przegrywa przy tej samej specyficzności niezależnie od
   kolejności w pliku). Efekt: `btnGo.hidden = true` w JS ustawiał atrybut
   poprawnie, ale przycisk i tak zostawał na ekranie, w pełni klikalny -
   dotyczyło to całego panelu wyniku planowania (btnGo/btnSave/btnExportGpx/
   btnDiscardRoute domyślnie mają `hidden` w znaczniku). Skutek na urządzeniu:
   "Jedziemy" i "Zapisz do zaplanowanych" widoczne i wyglądające na aktywne,
   ZANIM jakakolwiek trasa została wyznaczona - dotknięcie nie robiło NIC
   (handler ma `if (!state.currentRoute) return;`), bez żadnego komunikatu.
   Reszta pliku ma już ten sam wzorzec dla dziesiątek innych klas
   (.status-box[hidden], .loop-panel[hidden] itd.) - tu akurat brakowało. */
.action-btn[hidden] {
  display: none;
}

.action-btn:active {
  transform: scale(0.98);
}

.action-btn:disabled {
  background: #3a4250 !important;
  color: #7a8494;
}

.plan-btn {
  background: #1565c0;
}

.export-btn {
  background: #2e7d32;
}

.secondary-btn {
  background: #2c3644;
}

.link-btn {
  background: none;
  border: none;
  color: #64b5f6;
  /* TASK-92: 13px -> 17px, czytelność na Dashboardzie ("Zmień pojazd"). */
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  /* TASK-86: link inline, więc pełny 48px target odpadał - powiększenie
     paddingu to najwięcej, co da się bez zaburzenia otoczenia tekstu. */
  padding: 10px;
}

.icon-btn {
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 10px;
  color: #e8ecf1;
  font-size: 22px;
  /* TASK-86: 50 -> 56px, obsługa w rękawicach motocyklowych. */
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.icon-btn:active {
  transform: scale(0.95);
}

/* --- wybór pojazdu --- */

.vehicle-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.vehicle-card {
  display: flex;
  align-items: stretch;
  border-radius: 12px;
  border: 1px solid #2c3644;
  background: #232b38;
  overflow: hidden;
}

.vehicle-card-main {
  flex: 1;
  padding: 20px;
  border: none;
  background: transparent;
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.vehicle-card-main:active {
  transform: scale(0.98);
}

.vehicle-default-star {
  width: 52px;
  border: none;
  border-left: 1px solid #2c3644;
  background: transparent;
  color: #5a6678;
  font-size: 22px;
  cursor: pointer;
}

.vehicle-default-star.is-default {
  color: #ffca28;
}

/* --- ekran planowania --- */

.plan-screen {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
  min-height: 0;
}

.plan-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* Wybrany pojazd ma być widoczny na pierwszy rzut oka - stąd większa czcionka,
   intensywna zieleń i obwódka odcinająca go od reszty nagłówka. */
.plan-header strong {
  font-size: 19px;
  font-weight: 700;
  color: #00e676;
  border: 2px solid #00e676;
  border-radius: 8px;
  padding: 6px 12px;
  background: rgba(0, 230, 118, 0.1);
  line-height: 1.2;
}

.point-inputs {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}

.point-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.point-input {
  flex: 1;
  padding: 13px 14px;
  border-radius: 10px;
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #e8ecf1;
  font-size: 20px;
  min-width: 0;
}

/* TASK-140: pola START i PUNKT POŚREDNI mają być o 30% niższe niż META - są
   to pola drugorzędne (start jest zwykle "tu, gdzie stoję" - patrz przycisk
   📍, punkt pośredni bywa w ogóle pusty), więc mniej ekranu dla nich zostawia
   więcej miejsca na META, którą użytkownik faktycznie wpisuje ręcznie najczęściej.

   Wartości zmierzone empirycznie w przeglądarce (nie wyliczone z line-height,
   bo domyślne 'normal' różni się między silnikami renderowania): pole META
   z padding 13px/font-size 20px renderuje się na 50px wysokości; padding
   7.5px + font-size 16px daje 35px, czyli DOKŁADNIE 70% - zmierzone
   getBoundingClientRect(), nie przybliżone. */
.point-input-compact {
  padding: 7.5px 14px;
  font-size: 16px;
}

/* TASK-32: pole zablokowane na czas aktywnej sesji (patrz sessionLockBanner
   w planScreen.js) - wyraźnie stłumione, żeby od razu było widać, że nie da
   się w nim teraz nic zmienić, a nie że po prostu nie reaguje. */
.point-input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.session-lock-banner {
  margin: 0 0 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(198, 40, 40, 0.16);
  border: 1px solid #c62828;
  color: #ffcdd2;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
}

.session-lock-banner[hidden] {
  display: none;
}

.pick-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 3px solid #2c3644;
  background: #1a212c;
  color: transparent;
  cursor: pointer;
  flex-shrink: 0;
}

.pick-start {
  border-color: #2e7d32;
}

.pick-end {
  border-color: #c62828;
}

.pick-active {
  box-shadow: 0 0 0 3px rgba(100, 181, 246, 0.5);
}

.search-results {
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  max-height: 300px;
  overflow-y: auto;
  margin: -2px 0 2px 52px;
}

/* TASK-139: wiersz wyniku to teraz trzy części - nazwa (pogrubiona), kontekst
   adresowy pod nią i dystans po prawej. Wcześniej była to jedna długa linia z
   całym adresem, w której nie dało się odróżnić dwóch miejscowości o tej samej
   nazwie. `align-items: center` trzyma badge dystansu na środku wysokości
   wiersza niezależnie od tego, czy kontekst zajmuje jedną linię, czy dwie. */
.search-result-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 12px;
  font-size: 17px;
  line-height: 1.35;
  color: #c3cad4;
  cursor: pointer;
  border-bottom: 1px solid #2c3644;
}

/* Kolumna nazwa+kontekst ma się kurczyć zamiast wypychać badge poza ekran. */
.search-result-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.search-result-name {
  font-weight: 700;
  color: #e8ecf1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-result-ctx {
  font-size: 13px;
  color: #8e9bad;
  /* Dłuższy kontekst zawija się do dwóch linii, potem wielokropek - pełny
     adres bywa długi, ale wiersz nie może rosnąć bez końca. */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Dystans w linii prostej od bieżącej pozycji - to on rozstrzyga, który z
   kilku "Józefowów" jest tym właściwym, więc musi być czytelny na pierwszy
   rzut oka i nie może się kurczyć. */
.search-result-dist {
  flex-shrink: 0;
  align-self: center;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(33, 150, 243, 0.18);
  border: 1px solid rgba(33, 150, 243, 0.55);
  color: #90caf9;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

.search-result-item:last-child {
  border-bottom: none;
}

.search-result-item:active {
  background: #232b38;
}

/* TASK-15: pasek ulubionych miejsc.
   TASK-132: ZGŁOSZENIE UŻYTKOWNIKA - przy 12 możliwych slotach (TASK-126)
   przewijanie w poziomie (`overflow-x: auto`, jeden długi wiersz) stało się
   uciążliwe - kafelki na końcu listy były niewidoczne bez przewinięcia.
   Zamienione na siatkę wielorzędową: `flex-wrap: wrap` pozwala kafelkom
   przechodzić do kolejnego wiersza zamiast ciągnąć się w nieskończoność w
   bok - ile wierszy faktycznie powstanie (1-4 przy 12 kafelkach), zależy
   samoczynnie od szerokości ekranu, bez żadnej logiki w JS. Działa
   identycznie w pionie i w poziomie - to WŁAŚCIWOŚĆ zwykłego zawijania
   flex, nie osobna reguła per orientację. */
.fav-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  flex-shrink: 0;
}

.fav-bar[hidden] {
  display: none;
}

/* TASK-132: stała, kompaktowa geometria kafelka - jednolita szerokość
   niezależnie od nazwy (limit 10 znaków wymuszony w miejscu wpisywania,
   patrz index.html/#favNameInput ORAZ places.js/MAX_NAME_LEN - to drugie
   jako zabezpieczenie dla nazw sprzed tego limitu, np. zsynchronizowanych
   ze starszej wersji aplikacji na innym telefonie). `max-width` + ellipsis
   to właśnie to zabezpieczenie: nawet gdyby jakaś nazwa była dłuższa,
   kafelek i tak nie rozciągnie siatki. */
.fav-chip {
  flex-shrink: 0;
  max-width: 128px;
  padding: 11px 14px;
  border-radius: 999px;
  border: 1px solid #4a4023;
  background: #2a2413;
  color: #ffd54f;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

/* TASK-16: znacznik przy podpowiedzi pochodzącej z historii odwiedzin. */
.search-result-recent {
  color: #64b5f6;
  margin-right: 8px;
  font-weight: 700;
}

.map-wrap {
  position: relative;
  flex: 1;
  min-height: 160px;
  border-radius: 10px;
  overflow: hidden;
  background: #10151d;
}

#map {
  position: absolute;
  inset: 0;
}

/* --- przełącznik trybu trasy i panel pętli --- */

.mode-switch {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

/* Wyraźnie większe niż reszta przełączników - to pierwszy wybór, jaki
   użytkownik podejmuje na ekranie planowania (zgłoszone jako za mało widoczne). */
.mode-btn {
  flex: 1;
  padding: 17px 10px;
  border-radius: 10px;
  border: 2px solid #2c3644;
  background: #232b38;
  color: #c3cad4;
  /* TASK-94: 17px -> 20px, spójnie z .action-btn (był już blisko progu z
     TASK-86, teraz dobity do tego samego docelowego rozmiaru). */
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
  /* TASK-120 cz.1: przycisk niesie teraz DWA napisy - drobny nagłówek
     ("Zaplanuj trasę") nad głównym, dużym tekstem trybu - patrz
     .mode-btn-kicker/.mode-btn-main niżej. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.mode-btn-kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.72;
}

.mode-btn-main {
  font-size: 21px;
  font-weight: 800;
  line-height: 1.15;
}

/* TASK-175: "ptaszek" na wybranym trybie trasy.
   Dotąd o tym, który tryb jest włączony, mówił WYŁĄCZNIE kolor przycisku -
   ktoś, kto widzi aplikację pierwszy raz, musiał to wywnioskować, zamiast po
   prostu zobaczyć.

   Znacznik stoi INLINE, przed nazwą trybu, a nie jako plakietka w rogu:
   przycisk jest wąski (dwa w rzędzie) i przy dłuższej nazwie ("Pętla (tam i
   z powrotem)") tekst się zawija - plakietka w rogu wchodziłaby wtedy na
   napis.

   Miejsce na znacznik jest REZERWOWANE TAKŻE na nieaktywnym przycisku
   (visibility zamiast display/content), więc przełączenie trybu nie przesuwa
   napisów ani o piksel.

   Kolor: jaskrawa zieleń, na życzenie użytkownika - ma się RZUCAĆ W OCZY, a nie
   wtapiać w przycisk. Tła są dwa skrajnie różne (granat pod "Start – Meta",
   pomarańcz pod "Pętlą"), więc sama zieleń na jednym z nich siadałaby - stąd
   ciemna poświata, która odcina znacznik od obu. */
.mode-btn-main::before {
  content: '✓\00a0';
  visibility: hidden;
  font-size: 1.45em;
  line-height: 1;
  vertical-align: -0.08em;
  font-weight: 900;
  color: #00e676;
  text-shadow: 0 0 3px rgba(0, 0, 0, 0.65);
}
.mode-btn.mode-active .mode-btn-main::before {
  visibility: visible;
}

.mode-active {
  border-color: #1565c0;
  background: #17314f;
  color: #fff;
}

/* === TASK-111: KAFELKI DASHBOARDU - wspólna geometria, unikalny kolor akcentu ===
 *
 * Cztery główne wejścia ekranu głównego (Start→Meta, Pętla, Zapisane trasy,
 * Mapy offline) mają teraz IDENTYCZNĄ geometrię - ten sam promień (16px),
 * tę samą grubość obramowania (2px), tę samą wysokość (var(--touch-control))
 * i ten sam cień - a różnią się WYŁĄCZNIE kolorem akcentu. Wcześniej dzieliły
 * się na dwie wizualnie niepowiązane grupy: duże .mode-btn z obramowaniem i
 * drobne .quick-links bez niego.
 *
 * DLACZEGO Start→Meta i Pętla NIE są po prostu wypełnione kolorem na stałe,
 * jak dwa pozostałe kafelki: to PRZEŁĄCZNIK (dokładnie jeden z dwóch trybów
 * jest aktywny), więc stałe wypełnienie skasowałoby jedyny sygnał, KTÓRY tryb
 * jest w tej chwili wybrany. Zamiast tego kolor akcentu niesie stan: nieaktywny
 * = ciemne tło + obramowanie i napis w kolorze akcentu, aktywny = pełne
 * wypełnienie akcentem. Zapisane trasy/Mapy offline to zwykłe akcje (nie mają
 * stanu), więc są wypełnione od razu.
 */
.mode-btn,
.quick-links .action-btn {
  border-radius: 16px;
  border-width: 2px;
  border-style: solid;
  min-height: var(--touch-control);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  transition: transform 0.08s, background 0.08s, border-color 0.08s;
}

.mode-btn:active,
.quick-links .action-btn:active {
  transform: scale(0.97);
}

/* --- Start → Meta: niebieski (dotychczasowy styl bazowy, bez zmian koloru) --- */
.mode-btn[data-routemode='ab'] {
  border-color: #1565c0;
  color: #90caf9;
}

.mode-btn[data-routemode='ab'].mode-active {
  background: #1565c0;
  border-color: #1565c0;
  color: #ffffff;
}

/* --- Pętla: ciepły bursztyn. Tekst CIEMNY (#1a1200), nie biały: biel na
   bursztynie #ff8f00 daje kontrast ok. 2:1 (poniżej nawet minimum AA),
   a niemal czarny ok. 11:1 - z zapasem ponad próg AAA (7:1), o który prosi
   zadanie "czytelność w pełnym słońcu". W stanie NIEAKTYWNYM tło jest
   ciemne, więc tam napis musi być odwrotnie - jasnobursztynowy. --- */
.mode-btn[data-routemode='loop'] {
  border-color: #ff8f00;
  color: #ffcc80;
}

.mode-btn[data-routemode='loop'].mode-active {
  background: #ff8f00;
  border-color: #ff8f00;
  color: #1a1200;
}

/* --- Zapisane trasy: fiolet (ten sam odcień co "Rejestruj przejazd" i
   pływająca ikona powrotu - patrz .record-btn/OverlayPlugin), z pomarańczową
   obwódką (TASK-140) - dotychczasowa #8e24aa to fiolet o ton jaśniejszy od
   tła, więc obramowanie było ledwo odróżnialne od wypełnienia. Pomarańcz
   #ff8f00 to ten sam akcent co tryb "Pętla" wyżej - żaden nowy kolor w
   palecie, tylko ponowne użycie już istniejącego. --- */
.quick-links #btnSavedRoutes {
  background: #6a1b9a;
  border-color: #ff8f00;
  color: #ffffff;
}

/* --- Mapy offline: zieleń (ten sam odcień co "Jedziemy"/eksport GPX) --- */
.quick-links #btnOfflineMaps {
  background: #2e7d32;
  border-color: #388e3c;
  color: #ffffff;
}

.loop-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  padding: 10px;
  flex-shrink: 0;
}

.loop-panel[hidden] {
  display: none;
}

.loop-by-switch {
  display: flex;
  gap: 6px;
}

.loop-by-btn {
  flex: 1;
  padding: 9px;
  border-radius: 8px;
  border: 2px solid #2c3644;
  background: #232b38;
  color: #c3cad4;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.loop-by-active {
  border-color: #1565c0;
  background: #17314f;
  color: #fff;
}

.loop-field {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.loop-field[hidden] {
  display: none;
}

.loop-input {
  width: 90px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #10151d;
  color: #e8ecf1;
  font-size: 20px;
  font-weight: 600;
}

.loop-unit,
.loop-note {
  font-size: 14px;
  color: #8d97a6;
}

/* Róża kierunków: układ 3x3, w którym pozycja przycisku odpowiada kierunkowi
   świata (NW N NE / W Losowo E / SW S SE). Kwadratowe pola (aspect-ratio),
   żeby całość czytało się jak kompas, a nie jak lista. */
.dir-rose {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

.dir-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Bez aspect-ratio: przyciski mają wypełniać szerokość ekranu, a wysokość
     bierze się ze stałego paddingu (kwadratowe niepotrzebnie marnowały miejsce). */
  padding: 18px 4px;
  border-radius: 8px;
  border: 2px solid #2c3644;
  background: #232b38;
  color: #c3cad4;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}

/* Środek róży - wyróżniony, bo to zarazem ustawienie domyślne. */
.dir-chip-auto {
  font-size: 13px;
  border-color: #6b5a1a;
  background: #2a2413;
}

.dir-active {
  border-color: #f9a825;
  background: #3a2f0c;
  color: #ffd54f;
}

.riding-styles {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  padding: 10px;
}

.section-label {
  grid-column: 1 / -1;
  font-size: 15px;
  font-weight: 600;
  color: #8d97a6;
}

.style-btn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  padding: 12px;
  border-radius: 10px;
  border: 2px solid #2c3644;
  background: #232b38;
  color: #c3cad4;
  cursor: pointer;
}

.style-btn:active {
  transform: scale(0.98);
}

.style-active {
  border-color: #1565c0;
  background: #17314f;
  color: #ffffff;
}

.style-name {
  font-size: 16px;
  font-weight: 600;
}

.style-hint {
  font-size: 12px;
  line-height: 1.25;
  color: #7f8b9c;
}

.style-active .style-hint {
  color: #9fc4ea;
}

.surface-toggles {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  padding: 8px 10px;
}

.toggle-row {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 16px;
  line-height: 1.3;
  color: #c3cad4;
  padding: 4px 0;
}

.toggle-row input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  accent-color: #1565c0;
}

.toggle-locked {
  color: #6b7688;
}

.route-summary {
  flex-shrink: 0;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
}

.status-box {
  flex-shrink: 0;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12px;
  line-height: 1.4;
}

.status-box[hidden] {
  display: none;
}

/* Wskaźnik pracy przy wyznaczaniu trasy - bez niego kilkusekundowe czekanie
   na serwer wygląda, jakby kliknięcie nic nie zrobiło. */
.status-box .status-spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-right: 8px;
  vertical-align: -3px;
  border: 2px solid rgba(165, 214, 167, 0.35);
  border-top-color: #a5d6a7;
  border-radius: 50%;
  animation: status-spin 0.8s linear infinite;
}

/* Wskaźnik pracy na środku ekranu - główna informacja, że aplikacja liczy.
   Sam pasek stanu i wskaźnik na przycisku okazały się za mało widoczne.
   Półprzezroczysty, żeby przez cały czas było widać mapę pod spodem. */
.busy-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 14, 20, 0.42);
  pointer-events: none; /* nie blokujemy mapy - to tylko informacja */
}

.busy-overlay[hidden] {
  display: none;
}

.busy-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

/* Jedna trzecia krótszego boku ekranu - widoczne niezależnie od orientacji. */
.busy-spinner {
  width: 33vmin;
  height: 33vmin;
  border: 7px solid rgba(255, 255, 255, 0.22);
  border-top-color: rgba(77, 163, 255, 0.95);
  border-radius: 50%;
  animation: status-spin 1s linear infinite;
}

.busy-text {
  font-size: 17px;
  font-weight: 600;
  color: #ffffff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.8);
}

/* Ten sam wskaźnik na przycisku, który uruchomił liczenie - to tam patrzy
   użytkownik zaraz po kliknięciu, więc tu jest naprawdę widoczny. */
.action-btn.btn-busy {
  opacity: 0.85;
}

.btn-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 10px;
  vertical-align: -3px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #ffffff;
  border-radius: 50%;
  animation: status-spin 0.8s linear infinite;
}

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

/* Użytkownicy z włączoną redukcją ruchu dostają statyczny wskaźnik. */
@media (prefers-reduced-motion: reduce) {
  .status-box .status-spinner,
  .btn-spinner,
  .busy-spinner {
    animation: none;
  }
}

.status-box.ok {
  background: #1b3a24;
  border: 1px solid #2e7d32;
  color: #a5d6a7;
}

.status-box.error {
  background: #3a1b1b;
  border: 1px solid #c0392b;
  color: #f5b7b1;
}

.result-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.result-actions .action-btn {
  flex: 1;
}

/* TASK-95 (skorygowane na życzenie użytkownika): "Zaplanuj trasę" usunięty
   z tego rzędu (trasa liczy się teraz automatycznie) - Zapisz/GPX są
   jedynymi dwoma głównymi przyciskami, więc dostają całą zwolnioną
   przestrzeń WSZERZ. WYSOKOŚĆ celowo NIE jest już podbita ponad zwykły
   .action-btn (84px było za wysokie w ocenie użytkownika) - zostaje ta sama
   co "Jedziemy" (.go-btn) i "Rejestruj przejazd" (.record-btn), czyli
   bazowe min-height z .action-btn (var(--touch-control)), bez nadpisania tutaj.
   Kolory: Zapisz niebieski (jak domyślny .action-btn/.plan-btn), GPX żółty
   (bursztyn, z ciemnym tekstem dla kontrastu - białe litery na żółtym tle
   źle się czytają). */
.save-btn {
  background: #1565c0;
}

/* Etykieta "Eksport do" / "GPX" w dwóch wierszach - pierwszy mniejszy i
   zwykłej grubości (kontekst), drugi duży i pogrubiony (sedno akcji). Kolumna
   zamiast wiersza tylko dla TEGO przycisku - reszta .action-btn zostaje
   pozioma (ikona + tekst w jednej linii). */
.gpx-btn {
  background: #f9a825;
  color: #1a212c;
  flex-direction: column;
  gap: 2px;
}

.gpx-btn-line1 {
  font-size: 13px;
  font-weight: 500;
  opacity: 0.85;
}

.gpx-btn-line2 {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: 0.5px;
}

/* Usunięcie wyznaczonej trasy - wąski przycisk, bo to akcja rzadka i bezpieczna
   (przejazd się nie zaczął, więc nie ma czego zapisywać). */
.discard-btn {
  background: #4a2020;
  flex: 0 0 52px !important;
}

/* --- mapa pełnoekranowa i przejazd --- */

.map-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 900;
  border-radius: 0;
  min-height: 0;
}

/* TASK-104 (dodatek, zgłoszenie): ciemnoszare tło + jasnoszary tekst mało
   rzucały się w oczy na tle mapy. Ten sam czerwony język co .close-badge
   ("Zamknij aplikację" w górnym pasku) - spójne oznaczenie "to zamyka
   coś", zamiast neutralnej, łatwej do przeoczenia szarości. */
/* TASK-147 cz.4: ZGLOSZENIE - w POZIOMIE przycisk "Zamknij mape" (wybor
   startu/mety na pelnym ekranie) chowal sie pod systemowym paskiem nawigacji
   Androida. W poziomie pasek stoi przy LEWEJ albo PRAWEJ krawedzi, zaleznie od
   strony obrotu telefonu, a ten przycisk byl dosuniety do prawej na sztywno
   (`right: 12px`). Ten sam blad mialy: przycisk "Przejedz jeszcze raz", karta
   statystyk sladu, pasek podgladu trasy, tytul zbiorczego podgladu i dymek
   informacyjny - poprawione tym samym wzorcem, zeby problem nie wracal po
   kawalku. Elementy, ktore zapas juz mialy (.side-controls, .ride-buttons w
   poziomie, .toolbar-handle), zostaly nietkniete. */
.map-close-btn {
  position: absolute;
  top: max(12px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  right: calc(12px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  z-index: 1000;
  padding: 10px 14px;
  /* TASK-86: obsługa w rękawicach motocyklowych. */
  min-height: var(--touch-control);
  border: 1px solid #5a2c2c;
  border-radius: 8px;
  background: #2a1a1a;
  color: #ff8a80;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.map-close-btn:active {
  transform: scale(0.95);
}

.map-close-btn[hidden] {
  display: none;
}

/* Legenda na dole po lewej: u góry po lewej kolidowała z przyciskami zoomu
   Leafleta (+/-), a prawy dolny róg zajmuje podpis "OpenStreetMap contributors". */
/* Legenda: większa niż wcześniej (12 -> 15 px) i wyraźnie półprzezroczysta,
   żeby nie zasłaniała mapy - krycie ok. 30%, nie 70% jak dotąd. */
.map-legend {
  position: absolute;
  /* TASK-58: dolny pasek nawigacji systemowej.

     ZGŁOSZENIE ze zrzutów z Samsunga S9+ i Hammera: legenda mapy i przycisk
     powrotu do pozycji były UCIĘTE dolną krawędzią ekranu.

     PRZYCZYNA: aplikacja rysuje się od krawędzi do krawędzi (TASK-33), więc
     mapa sięga pod systemowy pasek nawigacji - i tak ma być, bo inaczej
     zostawałby czarny pas. Ale KONTROLKI leżące na mapie miały zaczepienie
     "bottom" podane w gołych pikselach, bez żadnego wcięcia. Na telefonie
     z paskiem gestów (cienkim) to jeszcze uchodziło, na telefonie z pełnym
     paskiem trzyprzyciskowym - nie.

     Wcięcia dolnego NIE dodawaliśmy tu wcześniej dlatego, że przy TASK-52
     przerabiane były tylko te miejsca, które JUŻ używały env() - a te reguły
     nie używały go w ogóle, więc przeszły niezauważone. */
  bottom: calc(10px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  left: calc(10px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  z-index: 800;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 13px 16px;
  border-radius: 10px;
  /* Krycie podniesione z 0.3 - przy tak niskim tło znikało na jasnych
     fragmentach mapy (pola, zabudowa) i tekst stawał się nieczytelny.
     Cień tekstu to dodatkowe zabezpieczenie na wypadek bardzo jasnego tła. */
  background: rgba(12, 16, 22, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 17px;
  color: #e4e8ee;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

.legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.legend-swatch {
  width: 30px;
  height: 6px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* TASK-40: duży przycisk PAUZA w miejscu legendy (zniknęła na czas jazdy -
   patrz .map-wrap.riding .map-legend niżej). Ten sam kąt ekranu, ale
   przycisk zamiast biernego odczytu - łatwy do trafienia kciukiem w
   rękawicy motocyklowej bez zdejmowania oczu z drogi. Domyślnie ukryty;
   pokazuje się WYŁĄCZNIE w trybie jazdy (.map-wrap.riding niżej), tak samo
   jak reszta kontrolek przejazdu. */
.pause-big-btn {
  display: none;
  position: absolute;
  /* TASK-58: jak wyżej - nad paskiem nawigacji systemowej. */
  bottom: calc(10px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  left: calc(10px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  z-index: 850;
  /* TASK-109 (ZASTĘPUJE TASK-105 - patrz BACKLOG.md): dotychczasowe 96px
     ("jedyny, celowo POWIĘKSZONY przycisk w apce") ustępuje WPROST
     zamówionej spójności z Wstecz/Zakończ - ta sama --ride-btn-h co
     .ride-btn, w OBU orientacjach (portret i landscape - poprzednia,
     landscape-specific reguła zmniejszająca PAUZĘ do --touch-toggle,
     wprowadzona w TASK-107, usunięta - patrz media query landscape niżej).
     TASK-109 (dodatek): --ride-btn-h zamiast --maneuver-banner-h - patrz
     komentarz przy definicji zmiennej w :root (30% mniej niż baner manewru,
     na dodatkowe życzenie po weryfikacji 1:1 na urządzeniu). */
  min-width: var(--ride-btn-h);
  height: var(--ride-btn-h);
  padding: 6px 10px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border-radius: 10px;
  border: 2px solid #f9a825;
  background: rgba(20, 26, 36, 0.94);
  color: #f9a825;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}

.map-wrap.riding .pause-big-btn {
  /* `display: none` bazowe (wyżej) chowa przycisk poza jazdą - tu jedyna
     zmieniana właściwość to samo display; flex-direction/align-items/gap są
     już zdefiniowane w bazowej regule .pause-big-btn (nieaktywne, dopóki
     display jest none) i zaczynają obowiązywać, gdy ta reguła włączy flex. */
  display: flex;
}

/* TASK-109: ten sam wzorzec ikona-nad-etykietą co .ride-btn-icon/.ride-btn-label. */
.pause-btn-icon {
  font-size: 28px;
  line-height: 1;
}

.pause-btn-label {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1;
}

/* TASK-40: modal pauzy - pełnoekranowy, dwa duże kafelki. Wyżej niż
   pozostałe nakładki jazdy (ride-buttons/hud sięgają do z-index 1000), żeby
   nic z mapy nie prześwitywało i nie dało się dotknąć przypadkiem pod spodem. */
.pause-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1600;
  background: rgba(8, 11, 16, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.pause-modal-overlay[hidden] {
  display: none;
}

.pause-modal-box {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.pause-modal-box h3 {
  margin: 0 0 4px;
  text-align: center;
  font-size: 26px;
  color: #f9a825;
}

.pause-tile {
  padding: 28px 20px;
  border-radius: 18px;
  border: none;
  font-size: 26px;
  font-weight: 700;
  line-height: 1.4;
  cursor: pointer;
}

.pause-tile-resume {
  background: #2e7d32;
  color: #ffffff;
}

.pause-tile-end {
  background: #c62828;
  color: #ffffff;
}

/* Panel manewru: kompaktowa "plakietka" w lewym górnym rogu, NIE pasek na
   całą szerokość (ten był ledwo widoczny i zasłaniał zbyt dużo mapy).
   Tło ciemniejsze niż pierwotne 30% krycia + cień tekstu, żeby białe napisy
   nie znikały na jasnych fragmentach mapy (pola, zabudowa, woda). */
/* TASK-54: wspólny wiersz "panel manewru + znak ograniczenia prędkości".
   Pozycjonowanie przeniesione tutaj z .manoeuvre-panel, żeby znak trzymał się
   strzałki, zamiast być drugim, niezależnie ustawionym elementem, który przy
   dłuższej nazwie ulicy wychodziłby poza ekran. */
.manoeuvre-row {
  /* TASK-142: wcięcie od lewej krawędzi jako ZMIENNA - w pionie 10px (bez
     zmian), w poziomie powiększone o kolumnę +/- (patrz media query
     landscape). Odejmowane również od max-width niżej, żeby przesunięcie w
     prawo nie wepchnęło panelu pod przyciski jazdy. */
  --manoeuvre-left-inset: 10px;
  position: absolute;
  /* Wiersz obejmuje tylko swoją treść (panel + znak), a nie całą szerokość
     mapy - inaczej znak lądowałby przy prawej krawędzi, pod przyciskami jazdy. */
  width: max-content;
  /* ZNALEZIONE POMIAREM przy 320x480: górna granica musi zostawić miejsce na
     KOLUMNĘ IKON przy prawej krawędzi, inaczej panel manewru wchodzi na nią
     (zmierzone: panel sięgał x=310, ikony zaczynają się na x=266), a znak
     ograniczenia prędkości był wypychany na x=334 - poza 320-pikselowy ekran.
     Odejmujemy szerokość ikony (ta sama wartość clamp co w .side-controls)
     plus odstępy, więc rezerwacja skaluje się razem z przyciskami. */
  /* Ile miejsca trzeba zostawić po prawej. Zmierzone, nie zgadnięte:
       - przyciski jazdy ("← Wstecz" / "■ Zakończ") - TASK-109: min-width
         --ride-btn-h (57px) każdy + 10px gap = 124px - i leżą
         dokładnie w tym samym, GÓRNYM prawym rogu co ten panel,
       - kolumna ikon ma clamp(44px, 8vh, 64px) i na niskich ekranach sięga
         aż do góry.
     Bierzemy większą z tych dwóch wartości plus odstępy.

     TU BYŁ ZGŁOSZONY BŁĄD WYŚWIETLANIA. Panel miał sztywne max-width: 330px,
     więc na ekranie o szerokości 360 px zajmował 10-340, a przyciski jazdy
     zaczynają się na 232 - nachodzenie o 57 px. Na telefonie użytkownika
     (480 px CSS) mieściło się o włos (340 < 352) i dlatego problem widać było
     dopiero na telefonie o mniejszej rozdzielczości.

     TASK-117 (DRUGI ZGŁOSZONY BŁĄD tego samego rodzaju, znak ograniczenia
     prędkości pod "← Wstecz"): sztywne `max(124px, clamp(44px,8vh,64px))`
     zakładało, że "← Wstecz"/"■ Zakończ" mają dokładnie swoje min-width
     (57px) - fałszywe założenie, bo `.ride-btn` nie ma górnego ograniczenia
     szerokości, więc pogrubiony podpis rozciąga przycisk POZA min-width
     (zmierzone: 81-90px, nie 57px). Rezerwacja jest teraz MIERZONA wprost z
     rzeczywiście wyrenderowanych elementów (patrz planScreen.js,
     updateManoeuvreReserve) i wstawiana jako `--manoeuvre-reserve-px` -
     odporna na dowolną przyszłą zmianę czcionki/długości podpisu/DPI, bez
     kolejnej rundy zgadywania stałej w tym pliku. Wartość `154px` w
     `var(..., 154px)` to fallback na czas MIĘDZY pierwszym odrysowaniem a
     pierwszym przebiegiem JS (ta sama liczba co poprzednie sztywne
     124px+30px, żeby na tę jedną klatkę nie było GORZEJ niż wcześniej). */
  max-width: calc(
    100% - var(--manoeuvre-reserve-px, 154px) - var(--manoeuvre-left-inset) -
      max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)) -
      max(env(safe-area-inset-right, 0px), var(--sa-right, 0px))
  );
  /* TASK-33: bez tego panel wisiał 10px od GÓRNEJ KRAWĘDZI EKRANU (mapa
     pełnoekranowa sięga pod pasek stanu), więc na części telefonów chował
     się częściowo pod zegarkiem/ikonami systemowymi.
     TASK-52: dochodzi jeszcze wcięcie boczne - w poziomie wycięcie na aparat
     jest przy krawędzi LEWEJ albo prawej, zależnie od strony obrotu. */
  top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: calc(var(--manoeuvre-left-inset) + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  z-index: 860;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  pointer-events: none;
}

.manoeuvre-row[hidden] {
  display: none;
}

/* TASK-128: ZGŁOSZENIE UŻYTKOWNIKA (ze zrzutem ekranu z prawdziwej jazdy) -
   strzałka renderowała się w osobnym, wąskim, w pełni zaokrąglonym "kapsule",
   a odległość/nazwa ulicy pojawiały się OBOK, POZA tłem panelu, na gołej
   mapie. Zbudowana od nowa próba odtworzenia tego na desktopowym Chrome
   (identyczny DOM, ta sama klasa, ręcznie wywołane te same aktualizacje co
   planScreen.js) wyszła POPRAWNIE - podejrzenie pada więc na kombinację
   `display:flex` (wiersz) -> `.manoeuvre-text` (kolumna) ->
   `.manoeuvre-label` (`-webkit-line-clamp`), znaną w sieci jako źródło
   niestabilnego layoutu w niektórych wariantach systemowego Android WebView
   (inny silnik niż desktopowy Chrome, mimo tej samej bazy Blink/Chromium).
   Naprawa NIE próbuje zgadywać dokładnej przyczyny w konkretnym WebView -
   usuwa ZAMIAST TEGO całą kruchą konstrukcję ("wiersz, którego szerokość
   zależy od treści") na rzecz DUŻEGO, STAŁEGO rozmiaru, którego żadna
   kombinacja treści nie może rozsunąć: panel jest teraz PIONOWĄ, WYŚRODKOWANĄ
   kolumną (strzałka na górze, odległość, nazwa ulicy pod spodem) o STAŁEJ
   szerokości - bardziej kwadratowy kształt, zgodnie z zamówieniem, i przy
   okazji odporny na ten sam błąd nawet, gdyby wrócił na innym telefonie. */
.manoeuvre-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 6px;
  /* Stała szerokość (nie `max-width` na kurczliwym flex-row jak dotąd) -
     panel ma teraz DOKŁADNIE ten sam rozmiar niezależnie od długości nazwy
     ulicy czy tego, co się z konkretną kombinacją treści source WebView
     akurat pomyli. */
  width: 148px;
  min-height: 148px;
  padding: 16px 12px;
  box-sizing: border-box;
  border-radius: 20px;
  background: rgba(18, 18, 18, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

.manoeuvre-panel[hidden] {
  display: none;
}

/* TASK-54: znak B-33 (ograniczenie prędkości) - biały krąg w czerwonej
   obwódce, dokładnie jak znak drogowy. Rozmiar przez clamp(), bo ma być
   czytelny rzutem oka na dużym telefonie, ale nie może zjeść zbyt dużo miejsca
   na małym.
   TASK-120 cz.10: PRZENIESIONY z wiersza obok panelu manewru na samodzielną,
   wyśrodkowaną pozycję - portret: dół ekranu (strefa bez żadnych innych
   stałych elementów - side-controls/ride-buttons trzymają się prawej
   krawędzi), poziom: góra ekranu (media query niżej). */
/* TASK-189 (ZGLOSZENIE, POTWIERDZONE POMIAREM): w PIONIE znak stal u dolu i
   chowal sie CALY pod panelem osmiu kafelkow.
   Zmierzone na urzadzeniu (mapa 384x832 px CSS): znak y 745-797, panel HUD
   y 651-817 - czyli wszystkie 52 px znaku pod kafelkami, nie czesc.
   Znak idzie wiec na GORE mapy, w wolna szczeline miedzy kafelkiem manewru
   (konczy sie na x 158) a przyciskami WSTECZ/ZAKONCZ (zaczynaja sie na x 223);
   znak ma 52-74 px szerokosci i jest wysrodkowany, czyli x 166-218 - miesci sie
   miedzy nimi z zapasem po obu stronach. Ten sam `top` co przyciski jazdy, zeby
   gorny rzad byl rowny.
   POZIOM ZOSTAJE BEZ ZMIAN - tam znak juz jest u gory i uzytkownik potwierdzil,
   ze uklad jest prawidlowy (patrz regula w bloku landscape nizej, ktora ta
   nadpisuje). */
.speed-limit-sign {
  position: absolute;
  top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: 50%;
  transform: translateX(-50%);
  z-index: 900;
  width: clamp(52px, 13vw, 74px);
  height: clamp(52px, 13vw, 74px);
  border-radius: 50%;
  background: #ffffff;
  border: clamp(6px, 1.6vw, 9px) solid #d32f2f;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
  pointer-events: auto;
}

.speed-limit-sign[hidden] {
  display: none;
}

.speed-limit-sign span {
  color: #111111;
  font-weight: 800;
  /* Bez cienia - na znaku drogowym cyfra jest płaska i czarna; cień
     odziedziczony po panelu manewru robił z niej rozmytą plamę. */
  text-shadow: none;
  font-size: clamp(20px, 5.4vw, 30px);
  line-height: 1;
  letter-spacing: -0.5px;
}

/* Strzałka i odległość do manewru to jedyna informacja odczytywana w ruchu -
   są więc wyraźnie największym elementem na mapie (strzałka 26 -> 48 px,
   odległość 17 -> 34 px). Nazwa ulicy pod spodem może zostać mniejsza:
   czyta się ją na postoju albo kątem oka, nie w trakcie samego manewru. */
.manoeuvre-arrow {
  font-size: 48px;
  line-height: 1;
  color: #7ec8ff;
  flex-shrink: 0;
}

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

.manoeuvre-distance {
  font-size: 34px;
  font-weight: 700;
  line-height: 1.1;
}

.manoeuvre-label {
  font-size: 17px;
  color: #dbe1ea;
  /* Nazwa ulicy bywa bardzo długa ("Generała Leopolda Okulickiego") - TASK-120
     cz.8: teraz zawija się do MAKSYMALNIE 2 linii (zamiast ucinać do jednej),
     dopiero trzecia i kolejne linie znikają pod wielokropkiem. */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  /* Było sztywne 240px. Na ekranie szerokim na 320 px sama ta wartość
     wystarczała, żeby panel przekroczył szerokość ekranu - razem ze strzałką,
     odstępami i wypełnieniem panelu robiło się z tego 314 px. Wartość względna
     dopasowuje się do tego, ile miejsca faktycznie zostało. */
  max-width: 100%;
}

/* 0.156.0: TABLICA KIERUNKOWA w panelu manewru - numery dróg i kierunki z drogowskazu
   (dane z silnika tras, patrz src/tablicaKierunkowa.js). Wygląd jak na drodze: zielone
   tło tablicy, numer drogi na czerwonym polu. Szerokość musi zmieścić się w panelu
   (148px minus 2 × 12px wypełnienia = 124px), dlatego numery zawijają się do kolejnego
   rzędu, a kierunki mają najwyżej dwie linie - trzecia znika pod wielokropkiem, tak samo
   jak długa nazwa ulicy w .manoeuvre-label wyżej. */
.manoeuvre-board {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  margin-top: 5px;
  padding: 4px 5px;
  border-radius: 5px;
  background: #1b4d2e;
  text-shadow: none;
}

.manoeuvre-board[hidden] {
  display: none;
}

.road-refs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 3px;
}

/* ZGLOSZENIE: "znaczki na tablicach kierunkowych - gdzie mamy jechac - maja byc
   troszke wieksze, bo sa zbyt male". Numer drogi i kierunki dorownuja teraz nazwie
   ulicy w panelu (.manoeuvre-label, 17px) zamiast byc od niej o polowe mniejsze.
   Panel ma STALA szerokosc 148px (patrz .manoeuvre-panel), czyli 124px na tresc -
   numery i tak zawijaja sie do kolejnego rzedu, a kierunki maja obciecie do dwoch
   linii, wiec wiekszy napis nie moze rozepchnac panelu. */
.road-ref {
  padding: 0 5px;
  border-radius: 3px;
  background: #c62828;
  color: #ffffff;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.5;
}

/* Przy rondzie (tablica dostaje klasę przy-rondzie, patrz ustawTablice w planScreen.js)
   schodzi do jednej linii kierunków - rysunek ronda z numerem zjazdu ma zostać
   najwyraźniejszą rzeczą w panelu, a nie ustąpić miejsca drogowskazowi. */
.manoeuvre-board.przy-rondzie .road-dest {
  -webkit-line-clamp: 1;
}

.road-dest {
  color: #ffffff;
  font-size: 15px;
  line-height: 1.25;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* Menu po długim przytrzymaniu palca na mapie. */
.point-menu {
  position: absolute;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  min-width: 190px;
  overflow: hidden;
  border-radius: 10px;
  border: 1px solid #2c3644;
  background: #232b38;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
}

.point-menu[hidden] {
  display: none;
}

.point-menu button {
  padding: 14px 16px;
  /* TASK-86: obsługa w rękawicach motocyklowych. */
  min-height: var(--touch-control);
  border: none;
  border-bottom: 1px solid #2c3644;
  background: none;
  color: #e8ecf1;
  font-size: 16px;
  text-align: left;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.point-menu button:last-child {
  border-bottom: none;
}

.point-menu button:active {
  background: #2c3644;
  transform: scale(0.97);
}

.go-btn {
  background: #2e7d32;
}

/* Trochę większy niż inne akcje - zgłoszone jako "za nisko/za mały". */
.record-btn {
  background: #6a1b9a;
  padding: 17px 14px;
  font-size: 16px;
  /* TASK-120 cz.1: bezpieczny margines od dołu (patrz .quick-links niżej)
     PRZENIESIONY stąd na .quick-links - to ono jest teraz OSTATNIM elementem
     ekranu (Zapisane trasy/Mapy offline przeniesione pod ten przycisk), więc
     to jego margines chroni przed paskiem nawigacyjnym. Zwykły `gap` z
     .layout wystarcza między tym przyciskiem a kolejnym rzędem.
  */
}

/* Przyciski przejazdu jako mała nakładka w prawym górnym rogu mapy -
   wcześniej "Zakończ przejazd" był szerokim paskiem przez pół ekranu.
   TASK-105: "Wstecz" i "Zakończ" OBOK SIEBIE w jednym poziomym rzędzie -
   dotąd (`flex-direction: column`) stały jeden pod drugim w pionie;
   POZIOMO stawały się dopiero w landscape (patrz media query niżej, teraz
   w dużej mierze zbędna - oba warianty są sobie równe). */
.ride-buttons {
  position: absolute;
  top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  /* TASK-147 cz.4: zapas takze w regule bazowej. W poziomie nadpisuje ja
     wlasna regula (ta juz zapas miala), ale bazowa obowiazuje wszedzie indziej
     - a "wszedzie indziej" to takze przyszle uklady, o ktorych dzis nie wiemy. */
  right: calc(10px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  z-index: 1000;
  display: flex;
  flex-direction: row;
  gap: 10px;
}

.ride-buttons[hidden] {
  display: none;
}

/* TASK-109 (ZASTĘPUJE TASK-105 - patrz BACKLOG.md): dotychczasowy kwadrat
   48px ("ODROBINĘ MNIEJSZY od okrągłych ikon akcji") ustępuje wprost
   zamówionej wysokości - pochodnej banera manewru (--maneuver-banner-h,
   82px), żeby przycisk był łatwiejszy do trafienia w rękawicy. Etykieta
   ("WSTECZ"/"ZAKOŃCZ") WRACA - była trwale schowana od TASK-105, teraz
   znów widoczna, w układzie PIONOWYM (ikona nad tekstem, patrz
   .ride-btn-icon/.ride-btn-label), bo to WYSOKOŚĆ, nie szerokość, ma się
   wywodzić z banera - przycisk zostaje wąski (min-width, nie width).
   TASK-109 (dodatek): --ride-btn-h (57px, 30% mniej niż --maneuver-banner-h)
   zamiast pełnej wysokości banera - na dodatkowe życzenie po weryfikacji
   1:1 na urządzeniu w obu orientacjach, patrz komentarz w :root. */
.ride-btn {
  min-width: var(--ride-btn-h);
  height: var(--ride-btn-h);
  padding: 6px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border: 2px solid #2c3644;
  border-radius: 9px;
  font-weight: 700;
  color: #fff;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.ride-btn-icon {
  font-size: 26px;
  line-height: 1;
}

.ride-btn-label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1;
}

.ride-btn:active {
  transform: scale(0.95);
}

.stop-ride-btn {
  background: rgba(198, 40, 40, 0.94);
  border-color: #c62828;
}

.minimize-ride-btn {
  background: rgba(33, 43, 58, 0.94);
}

/* Pasek "przejazd wciąż trwa" na ekranie głównym po zminimalizowaniu widoku
   jazdy - jedyny ślad, że w tle nadal liczy się dystans/czas, i jedyna droga
   powrotu do pełnoekranowego widoku (poza "Zaplanuj trasę"/inne akcje, które
   są zablokowane, dopóki przejazd trwa). */
.active-ride-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: rgba(198, 40, 40, 0.16);
  border: 1px solid #c62828;
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 600;
  color: #ffcdd2;
}

.active-ride-banner[hidden] {
  display: none;
}

.active-ride-resume-btn {
  flex-shrink: 0;
  padding: 8px 14px;
  border: none;
  border-radius: 8px;
  background: #c62828;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.pause-badge {
  position: absolute;
  top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(249, 168, 37, 0.95);
  color: #1e1a08;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.pause-badge[hidden] {
  display: none;
}

/* Dojechanie do celu: prowadzenie się skończyło, ale rejestracja przejazdu
   trwa dalej (o jej zakończeniu decyduje użytkownik). Zielony, na środku
   u góry - tam, gdzie do tej pory pojawiały się wskazówki manewrów, więc
   wzrok trafia tam sam. */
.arrival-badge {
  position: absolute;
  top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 10px 20px;
  border-radius: 999px;
  background: rgba(46, 125, 50, 0.96);
  color: #ffffff;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: 0.5px;
}

.arrival-badge[hidden] {
  display: none;
}

/* Brak sygnału GPS (tunel) - pozycja i dystans są szacowane z ostatniej
   prędkości, więc użytkownik musi wiedzieć, że nie patrzy na pomiar. */
.gps-badge {
  position: absolute;
  top: max(52px, calc(max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)) + 42px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(120, 60, 180, 0.95);
  color: #ffffff;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.gps-badge[hidden] {
  display: none;
}

/* TASK-68: dymek "Przekroczyłeś prędkość!" - pokazuje się jednorazowo przy
   wejściu w przekroczenie >= 10 km/h (patrz pokazAlertPredkosci w
   planScreen.js) i znika sam po 3 s. Ten sam wzorzec pigułki co
   arrival-badge/gps-badge (position/top/z-index), osobny odstęp pionowy
   żeby nie nachodził na te dwa, gdy akurat wszystkie trzy są widoczne naraz. */
.speed-alert-banner {
  position: absolute;
  top: max(94px, calc(max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)) + 84px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 8px 18px;
  border-radius: 999px;
  background: rgba(211, 47, 47, 0.96);
  border: 1px solid #ffffff40;
  color: #ffffff;
  font-size: 15px;
  font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.speed-alert-banner[hidden] {
  display: none;
}

/* TASK-78: pierwsza wersja (bottom: 28px, ta sama krawędź co .map-legend i
   .pause-big-btn) kolidowała z obiema - w trybie podglądu zasłaniała
   legendę, w trybie jazdy w landscape nachodziła na Pauzę, a w portrait
   chowała się pod nieprzezroczystym panelem HUD (dolne 20% ekranu, z-index
   950 - wyżej niż tu było). ZGŁOSZENIE: wycentrować w pionie zamiast
   kotwiczyć do dołu - to i rozwiązuje kolizję (środek ekranu jest wolny od
   legendy/HUD/Pauzy w KAŻDYM trybie i orientacji), i nie wymaga osobnych
   reguł na portret/landscape/jazdę/podgląd, jak ma to .side-controls. */
.zoom-controls {
  position: absolute;
  left: calc(10px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  top: 50%;
  transform: translateY(-50%);
  /* Wyżej niż HUD (950), duży przycisk Pauza (850) i legenda (800) - żaden
     z nich nie może przechwycić dotknięcia, nawet gdyby się gdzieś zazębił. */
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.zoom-btn {
  /* TASK-86: dolna granica podniesiona do var(--touch-zoom) (60px) - obsługa
     w rękawicach motocyklowych, patrz BACKLOG.md.
     TASK-105: subtelna przezroczystość (krycie 90%) - mapa pod przyciskiem
     lepiej widoczna, a przy tak wysokim kryciu czytelność samego przycisku
     (obwódka/ikona +/-) praktycznie się nie zmienia. */
  width: var(--zoom-col-w);
  height: var(--zoom-col-w);
  border-radius: 50%;
  border: 2px solid #2c3644;
  background: rgba(20, 26, 36, 0.96);
  color: #64b5f6;
  font-size: clamp(22px, 4vh, 32px);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  opacity: 0.9;
  transition: transform 0.08s, background 0.08s;
}

.zoom-btn:active {
  background: rgba(100, 181, 246, 0.28);
  transform: scale(0.95);
}

/* Powrót do własnej pozycji. Prawy dolny róg mapy jest wolny (podpis
   OpenStreetMap jest niżej), a w trakcie przejazdu przycisk przesuwa się
   nad panel wskaźników. */
/* TASK-38: kolumna przycisków przy prawej krawędzi mapy jako elastyczny
   łańcuch pionowy (flex + gap) - pozycja, orientacja, głos, pogoda, rodzaj
   trasy, licząc od dołu. `column-reverse` sprawia, że PIERWSZY element w DOM
   (◎ powrót do pozycji) ląduje na SAMYM DOLE, a ostatni (🛣️ rodzaj trasy) na
   samej górze - dokładnie taka kolejność wizualna, jak wcześniej przy ręcznie
   liczonych "bottom: Npx". Odstęp między przyciskami pilnuje `gap`, więc
   dodanie/usunięcie przycisku albo zmiana wysokości ekranu nigdy nie
   powoduje nakładania się ikon - w przeciwieństwie do poprzedniej wersji,
   gdzie każdy przycisk miał osobno wyliczoną, sztywną pozycję pikselową. */
.side-controls {
  position: absolute;
  /* TASK-58: to jest przycisk ◎ ucięty na zrzutach użytkownika. */
  right: calc(10px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  bottom: calc(28px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  z-index: 850;
  display: flex;
  flex-direction: column-reverse;
  gap: 14px;
  /* TASK-91: animacja autoukrycia paska (patrz .toolbar-autohidden niżej i
     planScreen.js - scheduleToolbarAutoHide). Poza jazdą klasa nigdy nie jest
     dokładana, więc na dashboardzie/planowaniu ta reguła jest bez znaczenia. */
  transition: transform 0.3s ease, opacity 0.3s ease;
  /* ZGŁOSZENIE UŻYTKOWNIKA (różne rozdzielczości): sam `gap` pilnuje odstępów,
     ale NIE pilnuje, czy łańcuch w ogóle mieści się na ekranie. Przycisków
     przybywa z każdym zadaniem (doszedł 2D/3D, czeka przełącznik podkładu),
     a na niskim ekranie 7 ikon po 44 px z odstępami to już 378 px - więcej,
     niż zostaje miejsca nad dolną krawędzią.

     `wrap-reverse` sprawia, że nadmiar przechodzi do KOLEJNEJ KOLUMNY w lewo
     (a nie poza ekran), a `max-height` daje przeglądarce granicę, względem
     której ma to policzyć. Dzięki temu dołożenie kolejnej ikony w przyszłości
     nie wymaga niczego przeliczać - układ sam się dostosuje. */
  flex-wrap: wrap-reverse;
  max-height: calc(
    100dvh - max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)) -
      max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) - 96px
  );
  align-content: flex-start;
}

/* TASK-91: stan schowany - sam kierunek (w prawo w pionie, w dół w poziomie)
   dopisany w media queries orientacji niżej, bo pokrywa się z tym, GDZIE
   .side-controls w ogóle stoi w danej orientacji (patrz reguły
   .map-wrap.riding .side-controls).
   TASK-109 (ZNALEZIONY BŁĄD): selektor był zawężony do `.riding` - dopóki
   scheduleToolbarAutoHide() sam działał tylko podczas jazdy, było to bez
   znaczenia (komentarz niżej to jeszcze pamięta), ale teraz autoukrywanie
   uruchamia się też w swobodnym przeglądaniu (poza `.riding`) - JS dokładał
   klasę `toolbar-autohidden` poprawnie, ale bez `.riding` żadna reguła CSS
   jej nie honorowała, więc pasek wizualnie się nie chował. `.map-fullscreen`
   obejmuje oba przypadki (side-controls i tak jest widoczny WYŁĄCZNIE tam). */
.map-wrap.map-fullscreen .side-controls.toolbar-autohidden {
  pointer-events: none;
  opacity: 0;
}

/* TASK-91/127/129: uchwyt przywracania paska ikon. Domyślnie niewidoczny
   (`display:none`) - pasek startuje rozwinięty na początku każdego przejazdu
   (patrz planScreen.js).
   TASK-127: PRZEPROJEKTOWANY - dawny kwadratowy klocek zastąpiony smukłym,
   wydłużonym grotem. Element `<button>` sam w sobie ZOSTAJE zwykłym,
   przezroczystym prostokątem - to jest CAŁA strefa dotyku (4x dłuższa niż
   dawny klocek, patrz media queries niżej), tak żeby trafienie w rękawicy
   motocyklowej było równie łatwe mimo smuklejszego wyglądu.
   TASK-129: ZNALEZIONY BŁĄD w poprzedniej wersji (zgłoszony ze zrzutami
   ekranu) - widoczny grot był rysowany jako `border` + `clip-path` na
   PROSTOKĄTNYM `::after`. `clip-path` przycina WYGLĄD do trójkąta, ale
   `border` jest rysowany na oryginalnych, PROSTOKĄTNYCH krawędziach PRZED
   przycięciem - po przycięciu widoczne są więc tylko te fragmenty obwódki,
   które akurat leżały na krawędziach prostokąta pokrywających się z
   podstawą trójkąta; ukośne krawędzie grotu (świeżo wycięte przez
   clip-path) w ogóle NIE MAJĄ obwódki - stąd zgłoszenie "nie ma białej
   obwódki dookoła". Naprawa: `::after` rysuje grot jako WŁAŚCIWY kształt
   SVG (`<polygon>` z fill I stroke), którego stroke z definicji podąża za
   RZECZYWISTYM konturem wielokąta, nie za jego opakowującym prostokątem -
   dokładnie ta właściwość, której brakowało `clip-path`+`border`. */
.toolbar-handle {
  position: absolute;
  display: none;
  z-index: 850;
  border: none;
  padding: 0;
  background: transparent;
  cursor: pointer;
}

.toolbar-handle::after {
  content: '';
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  transition: filter 0.08s;
}

.toolbar-handle:active::after {
  filter: brightness(1.5);
}

/* TASK-109 (ZNALEZIONY BŁĄD, zgłoszony przez użytkownika): zawężone do
   `.riding` z tego samego powodu co niegdyś .toolbar-autohidden (patrz
   BACKLOG.md) - JS (showToolbarAndResetTimer) dokładał klasę poprawnie także
   w swobodnym przeglądaniu, ale bez `.riding` reguła CSS jej nie honorowała,
   więc po autoukryciu ikon poza jazdą trójkąt przywracający W OGÓLE się nie
   pokazywał - schowane ikony nie dały się już z powrotem wyciągnąć. */
.map-wrap.map-fullscreen .toolbar-handle.toolbar-handle-visible {
  display: block;
}

/* TASK-40: rozmiar podniesiony z 58 do 64 px (minimum 64×64 dp na potrzeby
   jazdy w rękawicach motocyklowych - grubsza rękawica potrzebuje wyraźnie
   większego pola dotyku niż standardowe 48px). Grubsza obwódka i mocniejsze
   tło dla kontrastu z mapą pod spodem. */
.recenter-btn,
.north-btn,
.voice-btn,
.weather-btn,
.theme-btn,
.dimension-btn,
.basemap-btn,
.style-switch-btn,
.past-tracks-btn,
.fuel-btn,
.skip-wp-btn,
.group-panel-btn {
  /* TASK-45: rozmiar zależny od WYSOKOŚCI ekranu, nie stały. Ikon w kolumnie
     jest już sześć, więc na niższych ekranach (telefon w poziomie, mniejsze
     modele) stałe 64 px wypychało dolne przyciski poza kadr. 8vh daje na
     typowym telefonie w pionie dokładnie dotychczasowe 64 px.
     TASK-86: dolna granica podniesiona z 44px do var(--touch-control) (64px)
     - 44px było poniżej progu pewnego trafienia w rękawicy motocyklowej. */
  width: clamp(var(--touch-control), 8vh, 64px);
  height: clamp(var(--touch-control), 8vh, 64px);
  border-radius: 50%;
  border: 2px solid #2c3644;
  background: rgba(20, 26, 36, 0.96);
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.08s, background 0.08s;
}

.recenter-btn:active,
.north-btn:active,
.voice-btn:active,
.weather-btn:active,
.theme-btn:active,
.dimension-btn:active,
.basemap-btn:active,
.style-switch-btn:active,
.past-tracks-btn:active,
.fuel-btn:active,
.skip-wp-btn:active,
.group-panel-btn:active {
  transform: scale(0.95);
}

.recenter-btn {
  color: #64b5f6;
  font-size: clamp(20px, 4vh, 32px);
  line-height: 1;
}

/* Po ręcznym przesunięciu mapy przycisk podświetla się, że podążanie jest wstrzymane. */
.recenter-off {
  color: #f9a825;
  border-color: #f9a825;
}

/* Orientacja mapy: kierunek jazdy do góry / stała północ. */
.north-btn {
  color: #64b5f6;
  font-size: 21px;
  font-weight: 700;
}

.north-btn[hidden] {
  display: none;
}

/* Ikona dzień/noc jest grafiką wektorową wypełniającą cały przycisk, a nie
   znakiem tekstowym - stąd zerowe wypełnienie i wyśrodkowanie przez flex.
   `overflow: hidden` razem z zaokrągleniem przycisku przycina grafikę do koła,
   więc krawędź jest gładka nawet gdyby SVG wystawał o pół piksela. */
.theme-btn {
  padding: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.theme-btn svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* TASK-49: przełącznik widoku 2D/3D. Napis pokazuje stan bieżący, a nie akcję -
   podświetlenie odróżnia widok przechylony od płaskiego rzutem oka. */
.dimension-btn {
  color: #64b5f6;
  font-size: clamp(14px, 2.6vh, 19px);
  font-weight: 700;
}

.dimension-btn.dimension-on {
  color: #7ee081;
  border-color: #7ee081;
}

/* TASK-104: przycisk warstw mapy - otwiera menu wyboru podkładu (standardowa/
   satelitarna ESRI/topograficzna OpenTopoMap/CyclOSM na rowerze). Następca
   TASK-49 (satelita bez skonfigurowanego źródła, stąd dawna klasa
   "basemap-on") - teraz zawsze widoczny, wszystkie podkłady są realnie
   dostępne bez klucza API. */
.basemap-btn {
  color: #64b5f6;
  font-size: clamp(18px, 3.4vh, 26px);
}

.basemap-btn.basemap-active {
  color: #ffd54f;
  border-color: #ffd54f;
}

.dimension-btn[hidden] {
  display: none;
}

/* TASK-104: menu wyboru podkładu - ten sam wygląd co #styleSwitchMenu
   (.style-switch-item/.style-switch-active, dzielone bez zmian), ale
   POZYCJONOWANE W JS (patrz pozycjonujMenuWarstw w planScreen.js) zamiast
   sztywnym "bottom: Npx" - #btnBasemap stoi w innym miejscu kolumny
   #sideControls niż #btnStyleSwitch, więc jeden zaszyty offset nie
   pasowałby do obu przycisków. `position: fixed` bo offsety liczone są
   względem viewportu (window.innerWidth/innerHeight), nie względem
   najbliższego pozycjonowanego przodka. */
.basemap-menu {
  position: fixed;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
  border-radius: 12px;
  background: rgba(20, 26, 36, 0.97);
  border: 1px solid #2c3644;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  /* TASK-105 (poprawka zgłoszona przez użytkownika): górna granica
     szerokości, żeby menu nigdy nie wyszło poza ekran na wąskim telefonie -
     patrz komentarz przy pozycjonuj() w savedRoutesScreen.js. */
  max-width: calc(100vw - 24px);
}

.basemap-menu[hidden] {
  display: none;
}

/* Nawigacja głosowa: zapowiadanie skrętów. */
.voice-btn {
  color: #5a6678;
  font-size: 26px;
}

.voice-btn.voice-on {
  color: #43a047;
  border-color: #43a047;
}

/* TASK-74: pokaż/ukryj różowy ślad przejechanych tras. Ikona to rysunek
   krętej trasy (SVG, stroke="currentColor") - wyłączony stan jest
   wyszarzony jak nieaktywne ikony, włączony przechodzi na ten sam róż
   (#E91E63) co sam ślad na mapie. */
.past-tracks-btn {
  color: #5a6678;
  padding: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.past-tracks-btn svg {
  display: block;
  width: 68%;
  height: 68%;
}

.past-tracks-btn.past-tracks-on {
  color: #e91e63;
  border-color: #e91e63;
}

/* Pogoda na trasie. Dostępna w każdej chwili, także w trakcie jazdy, bo
   pogoda zmienia się szybciej niż trwa dłuższa trasa. */
.weather-btn {
  color: #e8ecf1;
  font-size: clamp(18px, 3.5vh, 28px);
  line-height: 1;
}

/* Na trasie wykryto opady - przycisk sam o tym informuje, bez wchodzenia w mapę. */
.weather-btn.weather-alert {
  border-color: #f9a825;
  box-shadow: 0 0 0 2px rgba(249, 168, 37, 0.35);
}

.weather-btn.weather-busy {
  opacity: 0.55;
}

/* TASK-43: znacznik pogodowy na trasie - ikona + temperatura na
   półprzezroczystej "pigułce", żeby czytał się i na jasnej, i na ciemnej
   mapie. Kolor obwódki oznacza powagę: bursztynowy = deszcz, niebieski =
   śnieg, szary = zwykły punkt bez opadów (nie ma czego ostrzegać). */
.weather-marker {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(12, 16, 22, 0.82);
  border: 2px solid #5a6472;
  font-size: 18px;
  line-height: 1;
  white-space: nowrap;
  /* TASK-171 (ZNALEZIONE NA URZĄDZENIU): ikony pogody stoją NA TRASIE, więc
     jedna z nich siada dokładnie na znaczniku startu albo mety - a że są od
     nich większe, przechwytywały dotyk i znacznika NIE DAŁO SIĘ PRZECIĄGNĄĆ
     (zamiast tego przesuwała się mapa; zmierzone: przesunięcie palca i
     przesunięcie mapy zgadzały się co do piksela). Nie mają własnej obsługi
     dotknięcia - są czysto informacyjne - więc nie mają po co go łapać.
     `cursor: pointer` zniknął razem z tym: sugerował klikalność, której nigdy
     nie było. */
  pointer-events: none;
}

.weather-marker.weather-rain {
  border-color: #f9a825;
}

.weather-marker.weather-snow {
  border-color: #90caf9;
}

.weather-marker-temp {
  font-size: 13px;
  font-weight: 600;
  color: #ffffff;
}

/* TASK-43: przy oddalonej mapie (updateWeatherMarkerZoom w mapView.js) etykiety
   leżą gęsto obok siebie - zostaje sama ikona, temperatura wraca po przybliżeniu. */
.weather-labels-compact .weather-marker {
  padding: 5px;
}

.weather-labels-compact .weather-marker-temp {
  display: none;
}

/* TASK-43: podczas jazdy panel manewru jest najważniejszy - etykiety pogodowe
   (tak jak legenda, TASK-40) ustępują mu miejsca zamiast go zasłaniać. */
.map-wrap.riding .weather-marker {
  display: none;
}

/* TASK-44: znacznik ulubionego miejsca na mapie - gwiazdka + nadana nazwa,
   NA STAŁE widoczny (w odróżnieniu od etykiet pogodowych - żadnego chowania
   nazwy przy oddaleniu, ulubione mają zostać czytelne na typowym zoomie).
   Złota obwódka odróżnia go wizualnie od pomarańczowych punktów pośrednich
   i czerwonych/zielonych markerów start/meta. */
.favourite-marker {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(12, 16, 22, 0.88);
  border: 2px solid #ffb300;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
}

.favourite-marker-name {
  font-size: 13px;
  font-weight: 700;
  color: #ffd54f;
}

/* Podczas jazdy ustępuje miejsca panelowi manewru - ten sam wzorzec co
   legenda (TASK-40) i etykiety pogodowe (TASK-43). */
.map-wrap.riding .favourite-marker {
  display: none;
}

.north-active {
  color: #f9a825;
  border-color: #f9a825;
}

/* Mały podgląd mapy na ekranie planowania służy WYŁĄCZNIE do pokazania
   przebiegu trasy - dotknięcie go otwiera mapę na pełnym ekranie. Sterowanie
   (pogoda, głos, orientacja, powrót do pozycji) i legenda są tam zbędne:
   przy wysokości okienka rzędu 160-370 px zasłaniały właśnie tę trasę, którą
   użytkownik chce obejrzeć, a część i tak wypadała poza kadr (overflow:
   hidden). Wszystkie te elementy pojawiają się dopiero na pełnym ekranie,
   czyli tam, gdzie są rzeczywiście używane - w czasie jazdy i nawigacji. */
/* TASK-12: zmiana rodzaju trasy w trakcie jazdy - piąty przycisk w kolumnie
   ikon (nad pogodą).
   TASK-96: widoczny nie tylko podczas przejazdu, ale w CAŁYM pełnym ekranie
   (także w czystym podglądzie zaplanowanej trasy, przed kliknięciem
   "Jedziemy") - kafelki profilu pod mapą są wtedy niedostępne (leżą POD
   nakładką pełnoekranowej mapy). `.side-controls` (rodzic tego przycisku)
   i tak jest widoczny wyłącznie w `.map-fullscreen` (patrz reguła
   `.map-wrap:not(.map-fullscreen) .side-controls` wyżej), więc ten przycisk
   nie potrzebuje już własnego, dodatkowego warunku - zachowuje się jak
   pozostałe ikony w tej kolumnie. */
.style-switch-btn {
  color: #e8ecf1;
  font-size: 26px;
}

.style-switch-menu {
  position: absolute;
  /* TASK-58: menu wysuwa się nad kolumną ikon, więc przesuwa się razem z nią. */
  right: calc(76px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  bottom: calc(300px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  z-index: 1100;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
  border-radius: 12px;
  background: rgba(20, 26, 36, 0.97);
  border: 1px solid #2c3644;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45);
}

.style-switch-menu[hidden] {
  display: none;
}

.style-switch-item {
  padding: 12px 16px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #232b38;
  color: #e8ecf1;
  font-size: 15px;
  font-weight: 600;
  /* TASK-105 (poprawka zgłoszona przez użytkownika): było `nowrap` - przy
     długiej etykiecie ("Rowerowo-turystyczna (CyclOSM)") i menu przyciśniętym
     do krawędzi ekranu (patrz .basemap-menu max-width) tekst NIE zawijał się,
     tylko wypychał kontener poza ekran. Krótsze etykiety nadal mieszczą się
     w jednej linii - zmiana widoczna tylko tam, gdzie faktycznie potrzebna. */
  white-space: normal;
  cursor: pointer;
}

.style-switch-active {
  border-color: #1565c0;
  background: #17314f;
  color: #fff;
}

.map-wrap:not(.map-fullscreen) .side-controls,
.map-wrap:not(.map-fullscreen) .map-legend,
/* TASK-80: przyciski +/- (TASK-78) trafiły przypadkiem też na mini-mapę
   dashboardu - powinny być dostępne wyłącznie na pełnym ekranie/w nawigacji,
   tak jak reszta kontrolek mapy w tej regule. */
.map-wrap:not(.map-fullscreen) .zoom-controls {
  display: none;
}

/* TASK-80: nakładka blokująca gesty na mini-mapie dashboardu - patrz
   komentarz przy markupie w planScreen.js. Widoczna (i klikalna) TYLKO poza
   pełnym ekranem; na pełnym ekranie znika całkowicie, żeby nie zasłaniać
   markerów/menu punktu ani nie przechwytywać gestów mapy. */
.mini-map-overlay {
  position: absolute;
  inset: 0;
  z-index: 700;
  cursor: pointer;
  /* Bez tła - ma być niewidoczna, tylko przechwytuje dotyk. */
  background: transparent;
}

.map-wrap.map-fullscreen .mini-map-overlay {
  display: none;
}

/* TASK-40: legenda znika także w trybie jazdy (nie tylko poza pełnym ekranem) -
   miejsce po niej zajmuje .pause-big-btn. Poza jazdą (podgląd trasy na pełnym
   ekranie) legenda zostaje bez zmian. */
.map-wrap.riding .map-legend {
  display: none;
}

/* TASK-30: powiększony obszar dotyku - poprzednia wersja (padding 3px, font
   11px) była za mała jak na jedyny sposób dotarcia do historii zmian i
   informacji o programie, łatwo było chybić przy jeździe. */
/* TASK-45: rozmiary płynne (clamp), tym samym wzorcem co .close-badge z
   TASK-35. Po dołożeniu przycisku Ustawień belka zrobiła się ciasna, a na
   węższych telefonach niż testowy stałe 18 px odstępu wypychałoby zawartość
   poza ekran. Teraz przyciski same się zwężają, zamiast wychodzić poza kadr. */
.info-badge {
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #64b5f6;
  border-radius: 999px;
  min-width: 0;
  /* TASK-97: 40px -> var(--touch-toggle) (48px), sam wspólny próg toggle-tier
     co reszta ikon z audytu TASK-86 - "stałe, bezpieczne wymiary pól dotykowych". */
  min-height: var(--touch-toggle);
  padding: 8px clamp(10px, 3.5vw, 18px);
  font-size: clamp(13px, 4vw, 16px);
  font-weight: 700;
  white-space: nowrap;
  flex-shrink: 0;
  cursor: pointer;
}

.pick-waypoint {
  border-color: #e65100;
}

/* Edytor kolejności punktów pośrednich */
.waypoint-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 50vh;
  overflow-y: auto;
  margin-bottom: 14px;
}

.wp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  padding: 8px 10px;
}

.wp-index {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #e65100;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.wp-label {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: #c3cad4;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wp-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.wp-btn {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #232b38;
  color: #e8ecf1;
  font-size: 15px;
  cursor: pointer;
}

.wp-btn:disabled {
  opacity: 0.35;
}

.wp-del {
  color: #ef9a9a;
  border-color: #7f2020;
}

/* Znacznik pojazdu (rower/motocykl z góry) obracany zgodnie z kierunkiem jazdy. */
.vehicle-marker-wrap {
  background: none;
  border: none;
}

/* TASK-02: rozmiar 2x (34 -> 68 px). Musi odpowiadać width/height w SVG
   pojazdów (mapView.js), inaczej znacznik byłby skalowany dwa razy. */
.vehicle-marker {
  width: 68px;
  height: 68px;
  transform-origin: 50% 50%;
  transition: transform 0.3s ease-out;
}

/* HUD przejazdu: w pionie pasek u dołu (ok. 1/5 ekranu), w poziomie panel z prawej. */
.hud {
  position: absolute;
  z-index: 950;
  display: grid;
  gap: 2px;
  background: rgba(16, 21, 29, 0.92);
  border-top: 1px solid #2c3644;
  color: #ffffff;
}

.hud[hidden] {
  display: none;
}

.hud-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 2px;
  min-width: 0;
  /* KAFELKI JAZDY: napis nigdy nie wychodzi poza kafelek (dopasowanie w
     planScreen.dopasujKafel, to jest ostatnia zapora). */
  min-height: 0;
  overflow: hidden;
}

.hud-item[hidden] {
  display: none;
}

/* Wartości muszą być czytelne rzutem oka z kierownicy, nie z ręki - stąd
   rozmiar znacznie większy niż w typowym interfejsie dotykowym (22 -> 32 px).
   Podpisy pod nimi były szare (#8d97a6) i przy 10 px praktycznie niewidoczne
   w słońcu; teraz jaśniejsze i większe, ale nadal wyraźnie słabsze od samej
   wartości, żeby wzrok trafiał najpierw w liczbę. */
.hud-value {
  /* KAFELKI JAZDY: --skala ustawia dopasowanie (planScreen.dopasujKafel) - sam
     mnoznik, zeby systemowa wielkosc tekstu liczyla sie tylko raz. */
  font-size: calc(32px * var(--skala, 1));
  font-weight: 700;
  line-height: 1.05;
  white-space: nowrap;
}

/* TASK-68: dwustopniowy alert predkosci - kolorujemy CALY kafelek (tlo +
   ramke), nie tylko liczbe, zeby bylo widac kątem oka, bez wpatrywania się
   w HUD. Kolor znika sam, gdy delta wraca do zera lub ponizej (patrz
   updateSpeedAlert w planScreen.js) - transition tlumaczy tam i z powrotem. */
/* TASK-138: STREFA ZIELONA - jazda w granicach limitu. Trzeci stan kafelka
   prędkości, dotąd brakujący (były tylko żółty i czerwony, a "w normie"
   nie miało żadnego oznaczenia). Kolor #00E676 wprost z treści zadania. */
/* KAFELKI JAZDY: podpis, ktory nie miesci sie w jednej linii nawet po
   zmniejszeniu, przechodzi do drugiej (planScreen.dopasujKafel). */
.hud-label.hud-label-zawijana {
  white-space: normal;
  line-height: 1.05;
}

.hud-speed-ok {
  background: rgba(0, 230, 118, 0.26);
  border: 2px solid var(--kolor-predkosc-ok);
  border-radius: 8px;
  /* Poświata na życzenie: kafelek prędkości ma się SAM znajdować wzrokiem
     wśród kilku sąsiednich kafelków HUD, nie być tylko "pokolorowany". */
  box-shadow: 0 0 10px rgba(0, 230, 118, 0.45);
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Sama liczba też na zielono - to ona jest odczytywana w ruchu, więc to ona
   musi nieść sygnał, nie tylko ramka wokół niej. */
.hud-speed-ok .hud-value {
  color: var(--kolor-predkosc-ok);
}

.hud-speed-warn {
  background: rgba(255, 160, 0, 0.35);
  border: 2px solid #ffa000;
  border-radius: 8px;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.hud-speed-danger {
  background: rgba(211, 47, 47, 0.4);
  border: 2px solid #e53935;
  border-radius: 8px;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.hud-label {
  font-size: calc(14px * var(--skala, 1));
  color: #c3ccd9;
  text-align: center;
  line-height: 1.15;
  white-space: nowrap;
}

@media (orientation: portrait) {
  .hud {
    left: 0;
    right: 0;
    /* TASK-33: "0" znaczyło dosłownie dolną krawędź EKRANU - pod paskiem
       gestów/przyciskami nawigacji Androida wartości HUD-a (prędkość, dystans)
       bywały częściowo zasłonięte. Wstawka nie zmienia wysokości 20% (ta
       liczy się od tej nowej, podniesionej podstawy), tylko odsuwa panel
       znad systemowego paska. */
    bottom: max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px));
    height: var(--hud-wysokosc);
    /* KAFELKI JAZDY: cztery kafelki w jednym rzedzie - predkosc pierwsza z
       lewej, jak dotad. */
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 1fr;
  }

  /* Podczas przejazdu HUD zajmuje dolne 20% ekranu (plus wstawka bezpieczna
     powyżej) - legenda i CAŁY łańcuch przycisków muszą się przesunąć nad
     niego, inaczej zniknęłyby pod panelem. TASK-38: jedna reguła na kontener
     zamiast pięciu osobnych na każdy przycisk - flex+gap sam pilnuje, żeby
     nic się nie nałożyło, niezależnie od tego, ile przycisków jest akurat
     widocznych. */
  /* TASK-40: legenda jest ukryta w trybie jazdy (patrz reguła globalna wyżej),
     więc w jej miejscu przesuwa się teraz .pause-big-btn - tym samym wzorcem. */
  .map-wrap.riding .pause-big-btn {
    bottom: calc(var(--hud-wysokosc) + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 10px);
  }

  .map-wrap.riding .side-controls {
    bottom: calc(var(--hud-wysokosc) + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 10px);
    /* Kolumna rośnie w GÓRĘ od dolnej krawędzi, a w prawym GÓRNYM rogu leżą
       przyciski jazdy ("← Wstecz" / "■ Zakończ", wysokie na 107 px). Przy
       siedmiu ikonach na ekranie 360x640 najwyższa z nich sięgała y=84 i
       lądowała na nich. Górna granica zatrzymuje łańcuch pod przyciskami,
       a nadmiar przechodzi do drugiej kolumny w lewo (flex-wrap wyżej). */
    max-height: calc(
      80dvh - 147px - max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px))
    );
  }

  /* TASK-40: przeliczone po powiększeniu przycisków 58->64px (4 odstępy po
     64+10=74px do piątego/najwyższego przycisku łańcucha, patrz .side-controls). */
  .map-wrap.riding .style-switch-menu {
    bottom: calc(var(--hud-wysokosc) + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 306px);
  }

  /* TASK-91: w pionie pasek stoi przy PRAWEJ krawędzi (patrz .side-controls
     bazowe) - chowa się więc w prawo, za tę krawędź. Trójkąt wskazuje kierunek
     wysunięcia z powrotem (w lewo, w głąb ekranu - patrz .toolbar-handle::after).
     TASK-109: `.map-fullscreen` zamiast `.riding` - w portrecie side-controls
     stoi w TYM SAMYM miejscu (prawa krawędź) niezależnie od jazdy, patrz
     komentarz przy bazowej regule .toolbar-autohidden wyżej w pliku. */
  .map-wrap.map-fullscreen .side-controls.toolbar-autohidden {
    transform: translateX(120%);
  }

  /* TASK-127: PIONOWY uchwyt przy prawej krawędzi - podstawa grotu biegnie
     wzdłuż krawędzi (WYSOKOŚĆ, ok. 4x dłuższa niż dawne 64px), wysunięcie w
     stronę mapy jest teraz smukłe (SZEROKOŚĆ, była 56px). */
  .toolbar-handle {
    right: calc(10px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
    top: 50%;
    transform: translateY(-50%);
    width: 26px;
    height: 256px;
  }

  /* TASK-129: grot skierowany w LEWO, rysowany jako właściwy SVG <polygon>
     (fill + stroke podążający za konturem - patrz komentarz przy bazowej
     regule .toolbar-handle::after) - trzy wierzchołki: cała podstawa po
     prawej stronie (x=25, wpasowana w viewBox 0-26 tak, żeby 2px stroke się
     zmieścił bez ucięcia), ostrze na środku lewej krawędzi (x=1). viewBox
     "0 0 26 256" 1:1 z rozmiarem CSS wyżej - stroke-width w jednostkach SVG
     odpowiada więc dokładnie prawdziwym pikselom, bez zniekształcenia. */
  .toolbar-handle::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 256'%3E%3Cpolygon points='25,1 25,255 1,128' fill='rgba(33,33,33,0.5)' stroke='rgba(255,255,255,0.85)' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}

@media (orientation: landscape) {
  /* 0.182.0 (ZGLOSZENIE 24.09): "na glownym ekranie w poziomie mapa jest na cala szerokosc -
     przy przewijaniu palec ciagle na nia trafia. Niech ma 70% szerokosci, na srodku ekranu."
     ZMIERZONE przed zmiana: 865 px z 900 px ekranu.

     Wysokosc zostaje bez zmian, a w PIONIE nic sie nie zmienia (ta regula dotyczy wylacznie
     orientacji poziomej).

     `:not(.map-fullscreen)` jest tu KONIECZNE: ta sama mapa po dwukrotnym dotknieciu (i w czasie
     jazdy) rozwija sie na caly ekran - tam zwezenie byloby bledem.

     Potrzebne sa OBIE wlasciwosci: `.map-wrap` ma `flex: 1` w kolumnie ekranu planowania, wiec
     samo `width` nie wystarczy - bez `align-self` element i tak rozciaga sie na cala szerokosc. */
  .plan-screen .map-wrap:not(.map-fullscreen) {
    width: 70%;
    align-self: center;
  }

  /* TASK-41: `fullSensor` dopuszcza teraz też odwrócony poziom (270°). Wycięcie
     na aparat/pasek systemowy, które w jednym z dwóch układów poziomych ląduje
     po fizycznie PRAWEJ stronie ekranu, w drugim ląduje po LEWEJ - dlatego
     wszystko zaczepione o prawą krawędź dolicza `max(env(safe-area-inset-right, 0px), var(--sa-right, 0px))`.
     Sam układ logiczny (HUD i przyciski zawsze po prawej w CSS) NIE zależy od
     tego, który to fizycznie obrót - przeglądarka sama podstawia właściwą
     wartość wycięcia dla aktualnej orientacji. */
  .hud {
    top: 0;
    bottom: 0;
    right: 0;
    padding-right: max(env(safe-area-inset-right, 0px), var(--sa-right, 0px));
    /* TASK-58: pasek sięga od góry do dołu, więc wcięcia dokładamy jako
       wypełnienie - inaczej ostatni wiersz odczytów chowa się pod paskiem
       nawigacji, a pierwszy pod paskiem stanu. */
    padding-top: max(env(safe-area-inset-top, 0px), var(--sa-top, 0px));
    padding-bottom: max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px));
    width: var(--hud-szerokosc);
    /* KAFELKI JAZDY: jedna kolumna czterech kafelkow - predkosc na gorze. */
    grid-template-columns: 1fr;
    grid-auto-rows: 1fr;
    border-top: none;
    border-left: 1px solid #2c3644;
    box-sizing: border-box;
  }

  /* W poziomie panel zajmuje prawą krawędź, więc przyciski przejazdu muszą
     odsunąć się w lewo, żeby się z nim nie nakładały.
     TASK-76: odstęp 10px + własny padding przycisków dawał razem wyraźną,
     "martwą" szczelinę między blokiem sterującym a panelem telemetrii -
     zmniejszony do 3px, żeby przyciski dosunęły się bezpośrednio do
     krawędzi panelu i tworzyły z nim jeden spójny blok pod kciukiem. */
  .map-wrap.riding .ride-buttons {
    right: calc(var(--hud-szerokosc) + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)) + 3px);
    /* TASK-107: Wstecz/Zakończ "bliżej siebie" z treści zadania - odstęp
       bazowy (10px, .ride-buttons) zmniejszony w tej ciasnej orientacji. */
    gap: 6px;
  }

  /* TASK-91/TASK-105: "← Wstecz"/"■ Zakończ" są teraz kwadratami 48px w
     KAŻDEJ orientacji (patrz bazowa .ride-btn wyżej) - w landscape zostaje
     tylko dosunięcie do panelu telemetrii (.ride-buttons wyżej), bez
     osobnego, większego rozmiaru jak dawniej (64px, wymiar motocyklowy
     TASK-86) - dwa progi rozmiaru dla tego samego przycisku, zależne od
     orientacji, tylko myliłyby, bez realnej korzyści dla ergonomii. */

  /* TASK-03: w poziomie ekran jest niski, a wszystko - przyciski funkcyjne
     (Wstecz/Pauza/Zakończ) i kolumna ikon - tłoczyło się przy tej samej prawej
     krawędzi. Ikony układamy więc w POZIOMY rząd przy dolnej krawędzi: funkcje
     zostają na górze, ikony na dole, między nimi cała wysokość ekranu.
     TASK-38: `row-reverse` zamiast pięciu osobnych "right: calc(26%+Npx)" -
     pierwszy element w DOM (◎ powrót do pozycji) ląduje przy prawej krawędzi
     łańcucha (najbliżej paska HUD), tak jak wcześniej, ale teraz odstępy
     pilnuje `gap`, nie ręcznie zsynchronizowane wielokrotności 68px. */
  .map-wrap.riding .side-controls {
    flex-direction: row-reverse;
    right: calc(var(--hud-szerokosc) + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)) + 10px);
    bottom: max(10px, max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
    /* ZNALEZIONE POMIAREM przy 640x320: w poziomie łańcuch ikon układa się
       w RZĄD u dołu i rośnie w lewo. Po dodaniu przycisku 2D siedem ikon
       sięgało do x=96, a duży przycisk PAUZA zajmuje 10-124 - czyli skrajna
       ikona lądowała NA nim. Lewa granica odsuwa rząd za przycisk pauzy,
       a zawijanie przenosi nadmiar do rzędu wyżej zamiast pod spód pauzy. */
    /* TASK-142: 124px zakładało, że PAUZA ma szerokość równą swojemu min-width
       (--ride-btn-h) - ten sam błąd co opisany w TASK-117 przy .manoeuvre-row.
       To fałsz: .pause-big-btn ma układ kolumnowy (ikona nad podpisem "PAUZA")
       BEZ ograniczenia szerokości, więc podpis rozciąga go do 73px (zmierzone
       przy 1040x480). Szerokość jest teraz MIERZONA w JS (patrz
       updateManoeuvreReserve w planScreen.js) i podstawiana jako
       --pause-clearance-px; fallback 95px = 10 + 73 + 12, policzone ze
       ZMIERZONEJ szerokości.

       ZNALEZIONA PRZY OKAZJI REGRESJA: ta reguła istniała w tym pliku DWA RAZY
       z tym samym selektorem i w tym samym media query (124px tutaj, 79px
       niżej). Późniejsza wygrywała po cichu, kasując zmierzoną wartość z
       TASK-03 - potwierdzone odczytem CSSOM w przeglądarce: obie reguły były
       na liście, a obowiązywała ta z 79px, przez co skrajna ikona rzędu
       lądowała NA przycisku PAUZA (zmierzona kolizja 4x57 px). Zostaje JEDNA,
       scalona reguła. */
    left: calc(
      var(--pause-clearance-px, 95px) + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px))
    );
    max-height: none;
    flex-wrap: wrap-reverse;
    justify-content: flex-start;
    align-content: flex-end;
  }

  /* TASK-109 miał tu osobną regułę na landscape (74% - 30px - 120px - ...),
     bo rezerwacja bazowa liczona była na sztywno od PEŁNEJ szerokości, a w
     poziomie panel HUD zabiera prawą ćwiartkę ekranu. Ta stała (120px = 2×
     zakładane --ride-btn-h) była DOKŁADNIE tym samym błędem co reguła
     bazowa (patrz TASK-117 wyżej: realna szerokość .ride-btn to 81-90px, nie
     57px) - tylko z inną liczbą, więc cichcem kasowała naprawę w landscape.
     Usunięta: reguła bazowa `.manoeuvre-row { max-width: ... }` teraz liczy
     rezerwację z JS-owego pomiaru rzeczywistych pozycji (updateManoeuvreReserve
     w planScreen.js, uwzględnia --ride-buttons, --side-controls I --hud), co
     działa poprawnie w OBU orientacjach bez osobnej reguły. */

  /* TASK-119 cz.5: znak ograniczenia prędkości - w poziomie MNIEJSZY (ok.
     36-40px) niż w pionie (52-74px), bo landscape jest niski - zostaje
     nawet teraz, gdy znak stoi samodzielnie (TASK-120 cz.10 niżej): duży,
     sztywny krąg na środku góry i tak zabierałby zbyt dużo z tego niskiego
     paska, gdzie już stoją pause/arrival/gps/speed-alert (patrz te klasy
     wyżej w pliku, ten sam wzorzec "pigułki na środku góry").
     TASK-120 cz.10: znak przeniesiony z wiersza obok panelu manewru na
     samodzielną pozycję - góra-środek w poziomie (dół-środek w pionie to
     bazowa reguła .speed-limit-sign wyżej). Odsunięty NIŻEJ od samej
     krawędzi niż w pionie, żeby zostawić miejsce nad nim na wspomniane
     pigułki, gdyby akurat któraś była widoczna. */
  /* TASK-142: ZGŁOSZONY BŁĄD, POTWIERDZONY POMIAREM w przeglądarce przy
     1040x480 (rozdzielczość CSS telefonu użytkownika) oraz 800x360 i 640x360:
     kafelek manewru (lewy górny róg, y 10-179 przy dwuwierszowej nazwie ulicy)
     nachodził na kolumnę +/- (wyśrodkowaną w pionie, y 173-307) - zmierzone
     nachodzenie 60x6 px przy wysokości 480 px i 60x66 px przy 360 px. W
     PIONIE kolizji nie ma (zmierzone przy 480x1040: zero), dlatego poprawka
     siedzi wyłącznie w tym bloku. Kolumna +/- zostaje przy lewej krawędzi
     (była tam już wcześniej), a odsuwa się kafelek - zgodnie z treścią
     zadania. 18px to odstęp między nimi. */
  .manoeuvre-row {
    --manoeuvre-left-inset: calc(10px + var(--zoom-col-w) + 18px);
  }

  .speed-limit-sign {
    /* TASK-142: było sztywne 64px - zmierzone nachodzenie na "Wstecz/Zakończ"
       (dolna krawędź 67px) o 3px w pionie przy 800x360 i 640x360. Wysokość
       przycisków jazdy jest znana ze zmiennej, więc liczymy z niej zamiast
       zgadywać kolejną stałą: 10px (ich odsunięcie od góry) + --ride-btn-h +
       14px odstępu. */
    top: calc(10px + var(--ride-btn-h) + 14px + max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
    bottom: auto;
    width: clamp(36px, 8vw, 44px);
    height: clamp(36px, 8vw, 44px);
    border-width: clamp(4px, 1vw, 6px);
  }

  .speed-limit-sign span {
    font-size: clamp(14px, 3.6vw, 18px);
  }

  /* TASK-40: przeliczone po powiększeniu przycisków 58->64px (patrz komentarz
     w wariancie portretowym wyżej). */
  .map-wrap.riding .style-switch-menu {
    right: calc(var(--hud-szerokosc) + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)) + 306px);
    bottom: max(84px, calc(max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 74px));
  }

  /* TASK-91: w poziomie, W TRAKCIE JAZDY, pasek stoi u DOŁU (patrz
     .map-wrap.riding .side-controls wyżej, pozycja zależna od HUD, widocznego
     tylko podczas jazdy) - chowa się więc w dół. Trójkąt skierowany w górę
     wskazuje kierunek wysunięcia z powrotem. Ta sama pozycja prawo/dół co
     pasek, żeby uchwyt wizualnie zastąpił dokładnie to miejsce, z którego
     pasek zniknął. */
  .map-wrap.riding .side-controls.toolbar-autohidden {
    transform: translateY(120%);
  }

  /* TASK-109: swobodne przeglądanie w landscape (BEZ .riding) nie ma
     dedykowanej reguły pozycji - .side-controls dziedziczy bazową, PORTRETOWĄ
     pozycję (prawa krawędź, kolumna pionowa, patrz reguła bazowa .side-controls
     na początku pliku), bo tam nie ma HUD-a (widocznego wyłącznie podczas
     jazdy), względem którego trzeba by się przesuwać. Kierunek chowania w tym
     przypadku jest więc taki sam jak w portrecie (w prawo), NIE w dół jak
     podczas jazdy - stąd osobna reguła zamiast rozszerzenia tej wyżej. */
  .map-wrap.map-fullscreen:not(.riding) .side-controls.toolbar-autohidden {
    transform: translateX(120%);
  }

  /* TASK-127/128: POZIOMY uchwyt przy dolnej krawędzi. TASK-128 - ZGŁOSZENIE
     UŻYTKOWNIKA: "wielkość trójkąta w wersji pionowej jest idealna... w
     wersji poziomej jest już inna wielkość - dopasuj, żeby była DOKŁADNIE
     taka sama". Poprzednia wersja rozciągała `width:auto` na całą dostępną
     przestrzeń (znacznie szerzej niż portretowe 256px) i miała inną
     wysokość (22px zamiast 26px) - teraz DOKŁADNIE te same wymiary co w
     portrecie (256×26, tylko obrócone: podstawa pozioma zamiast pionowej),
     wyśrodkowane w dostępnej przestrzeni między przyciskiem PAUZA a panelem
     HUD (te same `left`/`right` co dotąd wyznaczały granice, teraz jako
     granice do WYŚRODKOWANIA stałej szerokości, nie do rozciągnięcia -
     `margin: 0 auto` przy jawnej `width` właśnie to robi). */
  /* TASK-129: ZNALEZIONY BŁĄD, zgłoszony ze zrzutem ekranu - `bottom: max(10px,
     safe-area-inset-bottom)` stawiał grot ZBYT BLISKO dolnej krawędzi w
     landscape: na telefonach z gestową nawigacją Androida (przesuwny,
     półprzezroczysty pasek u dołu, "wyciągany do góry jako okno") ten
     pasek bywa RYSOWANY NAD treścią WebView bez odpowiadającego mu
     `env(safe-area-inset-bottom)` (albo z wartością zbyt małą, żeby dać
     realny odstęp) - grot renderował się DOKŁADNIE pod nim, częściowo
     zasłonięty i niewidoczny. Naprawiono podniesieniem dolnego marginesu
     minimalnego z 10px do 34px - bezpieczny odstęp NAD tym paskiem
     niezależnie od tego, czy system poprawnie zgłasza jego wysokość przez
     `env()`, czy nie. */
  .toolbar-handle {
    right: calc(var(--hud-szerokosc) + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)) + 10px);
    /* TASK-142: ta sama poprawka co przy .side-controls wyżej - 79px brało
       szerokość PAUZY z jej min-width zamiast z pomiaru. */
    left: calc(
      var(--pause-clearance-px, 95px) + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px))
    );
    bottom: max(34px, calc(max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 24px));
    /* ZGLOSZENIE (po obnizeniu strzalki pozycji w 0.137.0): "przesun trojkat w
       bok, w strone panelu po prawej stronie obok kafelkow, i troszke go
       zmniejsz".
       POWOD: strzalka pozycji stoi teraz o wlasna wysokosc nizej i stala w tym
       samym miejscu co grot - wysrodkowany miedzy PAUZA a panelem kafelkow
       wypadal dokladnie pod nia i przecinal ja bialym konturem.
       "margin-left: auto" dosuwa grot do PRAWEJ granicy pasma (czyli tuz obok
       panelu kafelkow), zostawiajac srodek mapy - i strzalke - wolny. Granica
       "left" zostaje jako zabezpieczenie: na waskim ekranie grot nie wejdzie na
       przycisk PAUZA. */
    width: 170px;
    height: 24px;
    margin: 0 0 0 auto;
  }

  /* TASK-129: grot skierowany w GÓRĘ, rysowany jako SVG <polygon> (patrz
     komentarz przy bazowej regule .toolbar-handle::after oraz przy analogicznej
     regule portretowej wyżej) - podstawa na dolnej krawędzi (y=23, wpasowana w
     viewBox 0-24 dla 2px stroke), ostrze na środku górnej krawędzi (y=1).
     viewBox "0 0 170 24" 1:1 z rozmiarem CSS wyżej - inaczej grot byłby
     rozciągnięty, a kontur miałby różną grubość na bokach i na podstawie. */
  .toolbar-handle::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 170 24'%3E%3Cpolygon points='1,23 169,23 85,1' fill='rgba(33,33,33,0.5)' stroke='rgba(255,255,255,0.85)' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  /* TASK-109 (ZASTĘPUJE TASK-107 - patrz BACKLOG.md): landscape-specific
     zmniejszenie PAUZY (do --touch-toggle, 48px, z ukrytą etykietą) cofnięte
     - zadanie wprost każe zsynchronizować wysokość PAUZA/Wstecz/Zakończ z
     banerem manewru W OBU orientacjach, więc bazowa reguła .pause-big-btn
     (--ride-btn-h) i .pause-btn-label (widoczna) obowiązują tu bez zmian -
     nic do nadpisania w tym bloku. */

  /* TASK-135: ZGŁOSZENIE UŻYTKOWNIKA - w poziomie zielona karta statystyk
     (bazowo dwukolumnowa siatka na całą szerokość) rozciągała się przez pół
     ekranu i zasłaniała mapę ze śladem. Tutaj zamienia się w JEDEN smukły,
     półprzezroczysty pasek zadokowany przy dolnej krawędzi: pozycje leżą w
     jednym rzędzie, rozdzielone pionowymi kreskami, ze SKRÓCONYMI etykietami
     (patrz .stat-short i pokazStatystyki w savedRoutesScreen.js).
     `overflow-x: auto` jest zabezpieczeniem, nie głównym trybem pracy - przy
     skróconych etykietach kluczowe pozycje (dystans, czas, V śr, pojazd,
     godziny) mieszczą się bez przewijania, a ewentualny ogon telemetrii
     (przyspieszenie/hamowanie/pochylenie) da się dosunąć palcem zamiast go
     tracić. `right` zostawia miejsce na kompaktowy przycisk obok. */
  .map-wrap .track-stats {
    right: calc(12px + 156px + 10px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
    bottom: max(10px, max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    overflow-x: auto;
    /* Pasek przewijania ukryty - zjadał część i tak niskiego paska, a sam
       gest przesunięcia palcem działa bez niego. */
    scrollbar-width: none;
    gap: 0;
    padding: 0 4px;
    min-height: 52px;
    border-radius: 12px;
    /* Color(0xCC004D40) wprost z treści zadania - szmaragdowy, przepuszczający mapę. */
    background: rgba(0, 77, 64, 0.8);
    border: 1px solid rgba(76, 175, 80, 0.75);
  }

  .map-wrap .track-stat {
    flex-direction: row;
    align-items: baseline;
    gap: 6px;
    padding: 0 11px;
    /* Bez tego pozycje kurczą się, byle zmieścić się w pasku, a bazowy
       `text-overflow: ellipsis` na wartości ucina je do "2.." czy "M..." -
       dane stają się bezużyteczne. Naturalna szerokość + przewijanie paska
       (overflow-x wyżej) to jedyny układ, w którym każda widoczna wartość
       jest CAŁA. */
    flex-shrink: 0;
    /* Separator między pozycjami - kreska, nie odstęp, żeby przy ciasnym
       upakowaniu wciąż było widać, gdzie kończy się jedna dana. */
    border-left: 1px solid rgba(255, 255, 255, 0.22);
  }

  .map-wrap .track-stats::-webkit-scrollbar {
    display: none;
  }

  .map-wrap .track-stat:first-child {
    border-left: none;
  }

  .map-wrap .track-stat span {
    font-size: 11px;
    white-space: nowrap;
  }

  .map-wrap .track-stat strong {
    font-size: 15px;
  }

  /* Skróty zastępują pełne etykiety/wartości - patrz komentarz przy .stat-short. */
  .map-wrap .track-stats .stat-full {
    display: none;
  }

  .map-wrap .track-stats .stat-short {
    display: inline;
  }

  /* TASK-135: "Jedź ponownie" traci pełnoekranową belkę na rzecz zwięzłej
     pigułki zadokowanej przy prawej krawędzi, w jednej linii z paskiem
     statystyk (ta sama dolna krawędź i wysokość). NAZWA PRZYCISKU BEZ ZMIAN -
     zadanie wprost tego zabrania. `left: auto` kasuje bazowe rozciąganie
     left+right; pozycję pionową ustala tu CSS, dlatego umiescRedriveBtn()
     w JS czyści w poziomie swój inline `bottom` (inline wygrywa z arkuszem). */
  .map-wrap .redrive-btn {
    left: auto;
    right: calc(12px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
    bottom: max(10px, max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
    width: 160px;
    min-height: 52px;
    height: 52px;
    padding: 8px 10px;
    font-size: 14px;
    /* Jedna linia - inaczej podpis łamie się na dwie i pigułka rośnie ponad
       wysokość paska obok, psując równą, zadokowaną krawędź. */
    white-space: nowrap;
    border-radius: 12px;
  }
}

.maplibregl-map {
  background: #10151d;
}

.vehicle-marker-wrap {
  pointer-events: none;
}

.maplibregl-popup-content {
  background: rgba(20, 26, 36, 0.92);
  color: #e8edf5;
  border: 1px solid #2c3644;
  font-size: 13px;
}

.maplibregl-popup-tip {
  border-top-color: rgba(20, 26, 36, 0.92) !important;
  border-bottom-color: rgba(20, 26, 36, 0.92) !important;
}

.maplibregl-ctrl-attrib {
  font-size: 10px;
}

.route-label {
  background: rgba(20, 26, 36, 0.92);
  border: 1px solid #2c3644;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 5px;
  white-space: nowrap;
}

.route-label::before {
  display: none;
}

.route-label-start {
  color: #a5d6a7;
  border-color: #2e7d32;
}

.route-label-end {
  color: #ef9a9a;
  border-color: #c62828;
}

/* --- zapisane trasy --- */

.saved-routes-screen {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* TASK-111: 14px/#9aa7b8 -> 16px/#eceff1 - ciemnoszary napis na ciemnym tle
   zlewał się z otoczeniem (dokładnie zgłoszona wada "wyblakłe napisy"). */
.detail-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  color: #eceff1;
  font-size: 16px;
  font-weight: 500;
}

.detail-select {
  flex: 1;
  /* TASK-111: powiększone pole wyboru szczegółowości - było 8px/14px, czyli
     poniżej progu wygodnego dotyku i na granicy czytelności w słońcu. */
  padding: 12px 12px;
  min-height: var(--touch-toggle);
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #232b38;
  color: #ffffff;
  font-size: 16px;
  font-weight: 500;
}

/* === TASK-111: EKRAN "MAPY OFFLINE" - kontrast i typografia ===
 *
 * Wszystko poniżej jest ZAKRESOWANE do `.offline-maps-screen`, celowo: klasy
 * `.saved-item`/`.saved-item-main`/`.saved-item-meta` są WSPÓŁDZIELONE z listą
 * zapisanych tras (savedRoutesScreen.js), która ma własną, dopracowaną
 * typografię z TASK-102 (trzyliniowy kafelek) - zmiana globalna zepsułaby
 * tamten ekran przy okazji naprawiania tego. */

/* Wstęp u góry ekranu: było 13px/#a7b0bd - ta sama wada co reszta. */
.offline-maps-screen .screen-intro {
  font-size: 15px;
  color: #cfd8e3;
  line-height: 1.4;
}

/* Nazwa regionu/kraju: było 14px (.saved-item-main strong) -> 20px/700. */
.offline-maps-screen .saved-item-main strong {
  font-size: 20px;
  font-weight: 700;
  color: #ffffff;
  /* Domyślna reguła .saved-item-main strong obcina nazwę wielokropkiem w
     jednej linii - przy większej czcionce dłuższe nazwy regionów by na tym
     ucierpiały, więc tu pozwalamy im się zawinąć. */
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

/* Rozmiar paczki / status pobierania: było 11px/#6b7688 (najgorzej widoczny
   element całego ekranu) -> 16px/500 w jasnym #eceff1. */
.offline-maps-screen .saved-item-meta {
  font-size: 16px;
  font-weight: 500;
  color: #eceff1;
  line-height: 1.35;
}

.offline-maps-screen .saved-item {
  /* Więcej powietrza pod powiększony, potencjalnie zawijany tekst. */
  padding: 14px 16px;
  gap: 12px;
}

.offline-maps-screen .saved-item-main {
  gap: 6px;
}

/* Ikony akcji (pobierz/usuń/zaktualizuj/przerwij): 48px to i tak było
   minimum z TASK-86, ale bez wyraźnego obrysu ginęły na tle kafelka -
   TASK-111 podbija je do 52px i daje 2px jasną ramkę. */
.offline-maps-screen .saved-item-actions .icon-btn {
  width: 52px;
  height: 52px;
  font-size: 24px;
  border: 2px solid #56637a;
  color: #ffffff;
}

/* Pasek postępu pobierania (TASK-111) - do tej pory postęp był wyłącznie
   tekstem z procentami. Wysokość 10px (wyraźnie widoczny kątem oka, nie
   włos), jasnozielone wypełnienie na ciemnym torze. */
.offline-progress {
  width: 100%;
  height: 10px;
  border-radius: 5px;
  background: #10151d;
  border: 1px solid #2c3644;
  overflow: hidden;
}

.offline-progress[hidden] {
  display: none;
}

.offline-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: 4px;
  background: #43a047;
  transition: width 0.2s linear;
}

/* Przycisk powrotu na ekranach podrzędnych - wyraźniejszy niż zwykły link,
   bo to główna droga wyjścia z ekranu. */
/* TASK-121 cz.4: czerwony akcent na życzenie - jeden, spójny wygląd
   przycisku cofania na każdym ekranie listy/formularza (savedRoutesScreen.js,
   offlineMapsScreen.js), zawsze w tym samym miejscu (lewy górny róg paska
   nagłówka), żeby był natychmiast rozpoznawalny niezależnie od tła pod nim. */
.back-btn {
  padding: 9px 16px;
  border-radius: 999px;
  border: 1.5px solid #ff5252;
  background: #232b38;
  color: #ff5252;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.08s, background 0.08s;
}

.back-btn:active {
  transform: scale(0.95);
  background: #331b1b;
}

/* Skróty (zapisane trasy / mapy offline) na ekranie głównym - obok siebie,
   żeby nie wypychać w dół przycisków wyznaczania trasy i przejazdu. */
.quick-links {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  /* TASK-120 cz.1: ZNALEZIONY BŁĄD - po przeniesieniu tego rzędu na sam dół
     ekranu (pod #btnRecord) przyciski były częściowo zasłonięte przez pasek
     nawigacyjny/gestów telefonu. Padding na .layout (kontener przewijany) NIE
     działa tutaj - to ten sam, już raz zdiagnozowany przypadek co przy
     .record-btn (patrz historia wyżej): .plan-screen ma height:100%, więc
     margines MUSI siedzieć na samym OSTATNIM elemencie, żeby był realnym
     odstępem od fizycznego dołu ekranu. Teraz to jest ten element. */
  margin-bottom: calc(max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) + 36px);
}

.quick-links .action-btn {
  /* .action-btn ma width:100% - w wierszu flex bez tego każdy przycisk
     próbowałby zająć całą szerokość ekranu, przez co drugi wypadał poza
     widoczny obszar (niewidoczny, ale wciąż "działający" - efekt
     nieklikalnego przycisku). flex:1 + min-width:0 dzieli wiersz po równo
     i pozwala tekstowi się zawinąć zamiast rozpychać przycisk. */
  flex: 1;
  min-width: 0;
  width: auto;
  /* TASK-111: geometria UJEDNOLICONA z kafelkami Start→Meta/Pętla
     (.mode-btn) - patrz wspólny blok "kafelki Dashboardu" niżej. Dawne
     padding:11px/font-size:14px robiły z tych dwóch przycisków wyraźnie
     drobniejszy, "drugorzędny" wiersz, mimo że to równorzędne wejścia w
     główne funkcje aplikacji. */
  padding: 17px 10px;
  font-size: 20px;
}

.tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 4px;
}

.tab-btn {
  flex: 1;
  padding: 8px 10px;
  background: #232b38;
  border: 1px solid #2c3644;
  border-radius: 8px;
  color: #9aa7b8;
  font-size: 14px;
  font-weight: 600;
}

.tab-btn-active {
  background: #2f7d4f;
  border-color: #2f7d4f;
  color: #fff;
}

/* TASK-102: odstęp między kafelkami podniesiony 8px -> 12px - wyraźniejsza
   granica między pozycjami przy większych, wieloliniowych kafelkach niżej
   (łatwiejszy trafiony wybór konkretnej trasy w rękawicy). */
.saved-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Wspólny kontener kafelka - dzielony też przez offlineMapsScreen.js (lista
   regionów map offline), dlatego bazowe wymiary zostają BEZ ZMIAN. TASK-102
   dokłada wyższy, trzyliniowy wariant tylko dla listy tras - patrz modyfikator
   .saved-item-track niżej, żeby nie zmieniać nieproszenie innego ekranu. */
.saved-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: #232b38;
  border: 1px solid #2c3644;
  border-radius: 10px;
  padding: 10px 12px;
  transition: background 0.15s, border-color 0.15s;
}

/* TASK-120 cz.2: ulubiona trasa - delikatny zielony odcień całego kafelka,
   ten sam odcień co reszta "pozytywnych" akcentów w aplikacji (Jedziemy,
   Mapy offline). Delikatny, nie krzykliwy - to oznaczenie, nie ostrzeżenie. */
.saved-item.is-favorite {
  background: #1b2e1e;
  border-color: #2e7d32;
}

.saved-item-name-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  /* Bez tego .saved-item-name (flex item) nie zawijałby się poniżej swojej
     naturalnej szerokości - dokładnie ten sam mechanizm co min-width:0 na
     .manoeuvre-panel wyżej w tym pliku. */
  min-width: 0;
}

.fav-toggle-btn {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: #9aa5b5;
  font-size: 22px;
  line-height: 1;
  padding: 0;
  /* Strefa dotyku większa niż sama gwiazdka - łatwa do trafienia bez
     przypadkowego dotknięcia sąsiedniej nazwy trasy. */
  width: 32px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.08s, color 0.08s;
}

.fav-toggle-btn:active {
  transform: scale(0.85);
}

.fav-toggle-btn.is-favorite {
  color: #ffca28;
}

.saved-item-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.saved-item-main strong {
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.saved-item-meta {
  font-size: 11px;
  color: #6b7688;
}

/* TASK-102: modyfikator kafelka NA LIŚCIE TRAS (przejechanych/planowanych) -
   min-height podniesiony do 88px (żądany zakres 80-96dp) i padding do
   14px/16px (12-16dp), żeby powiększony, trzyliniowy tekst niżej miał gdzie
   oddychać zamiast być stłoczony. offlineMapsScreen.js NIE dodaje tej klasy,
   więc jego lista zostaje przy dotychczasowych, mniejszych wymiarach. */
.saved-item-track {
  padding: 14px 16px;
  min-height: 88px;
}

.saved-item-track .saved-item-main {
  gap: 4px;
  /* TASK-113: cały nagłówek (nazwa/pojazd+dystans/data+czas) jest teraz
     klikalny - otwiera ten sam podgląd co ikonka 🗺 obok - stąd kursor i
     wyraźny "wcisk" (jak przyciski Glove-Friendly z TASK-86), żeby dotknięcie
     dawało natychmiastową informację zwrotną. */
  cursor: pointer;
  transition: transform 0.08s;
}

.saved-item-track .saved-item-main:active {
  transform: scale(0.97);
}

/* TASK-102: Linia 1 - pełna nazwa trasy. 14px/nowrap+ellipsis (jak wyżej,
   .saved-item-main strong) -> 18-20px/pogrubione, ZAWIJANE zamiast obcinane
   "..." - "Start – Punkt – Meta" z TASK-92 bywa dłuższe niż mieściło się w
   jednej, wąskiej linii. */
/* 0.201.0: maly, staly numer przejazdu przed nazwa (#151, polaczona: #156 (+157, +158)) - nie ma
   zabierac miejsca nazwie, wiec drobny i szary. */
.saved-item-nr {
  flex-shrink: 0;
  align-self: center;
  padding: 1px 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  color: #9aa4b1;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.saved-item-name {
  font-size: clamp(18px, 5vw, 20px);
  font-weight: 700;
  color: #f4f6f9;
  line-height: 1.25;
  white-space: normal;
  overflow-wrap: break-word;
  min-width: 0;
}

/* TASK-102: Linia 2 - pojazd i dystans. Nowy, wyraźnie jaśniejszy kolor niż
   dawne .saved-item-meta (#6b7688 zlewało się z tłem #232b38 - dokładnie
   zgłoszona wada) i SemiBold zamiast zwykłej wagi. */
.saved-item-vehicle {
  font-size: clamp(16px, 4.5vw, 17px);
  font-weight: 600;
  color: #cfd8e3;
}

/* 0.167.0: znacznik polaczonej podrozy (laczeniePrzejazdow.js) - tylko na jej kafelku. */
/* 0.170.0: trasa zaimportowana z pliku GPX (zaimportowane.js). */
.saved-item-zaimportowana {
  font-size: clamp(14px, 4vw, 15px);
  font-weight: 600;
  color: #ffcc80;
}

.przejechana-pole {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  margin: 6px 0 14px;
  border-radius: 8px;
  border: 1px solid #3a4453;
  background: #1a212c;
  color: #e8ecf1;
  font-size: 17px;
  color-scheme: dark;
}

.przejechana-etykieta {
  display: block;
  font-weight: 700;
  color: #cfd8e3;
}

.przejechana-info {
  margin: -8px 0 14px;
  font-size: 14px;
  color: #9fb0c3;
}

.saved-item-polaczona {
  font-size: clamp(15px, 4.2vw, 16px);
  font-weight: 600;
  color: #a5d6a7;
}

/* TASK-102: Linia 3 - data, godzina i czas przejazdu. Jaśniejszy kolor niż
   linia 2 byłby mylący (sugerowałby wyższą rangę informacji niż pojazd/
   dystans), ale wciąż WYRAŹNIE jaśniejszy od starego #6b7688. */
.saved-item-datetime {
  font-size: clamp(15px, 4.2vw, 16px);
  font-weight: 500;
  color: #a9b4c2;
}

/* TASK-97: nagłówek miesięczny na liście zapisanych tras ("Sierpień 2026")
   - wysoki kontrast, żeby granica między miesiącami była jednoznaczna nawet
   przy szybkim przewijaniu w rękawicach/w słońcu. Pierwszy nagłówek listy
   nie potrzebuje dodatkowego odstępu od góry (.saved-list ma już swój gap). */
.month-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 6px;
  font-size: 13px;
  font-weight: 700;
  color: #cfd6e0;
  letter-spacing: 0.02em;
}

.month-divider::after {
  content: '';
  flex: 1 1 auto;
  height: 2px;
  background: #3a4557;
  border-radius: 1px;
}

.saved-list > .month-divider:first-child {
  margin-top: 0;
}

/* Bazowy wariant (rząd) - nadal używany przez offlineMapsScreen.js, gdzie
   kafelek ma zwykle JEDEN przycisk akcji (pobierz/anuluj/usuń region). Lista
   zapisanych tras (savedRoutesScreen.js) dostaje siatkę 2x2 przez modyfikator
   .saved-item-actions-grid niżej - osobna klasa, żeby czwarty przycisk nie
   rozciągał tego prostszego, jednoprzyciskowego widoku. */
.saved-item-actions {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}

/* TASK-106: siatka 2x2 zamiast pojedynczego rzędu - czwarty przycisk
   ("Przejedź jeszcze raz") już się nie zmieściłby obok pozostałych trzech na
   wąskim telefonie bez zawijania. Kolejność w DOM (patrz trackItemHtml)
   odpowiada kolejności w gridzie przy domyślnym grid-auto-flow:row: góra
   load+reride, dół export+delete - zgodnie z treścią zadania. `.saved-item`
   ma `align-items:center`, więc rozciąga się do wysokości tego bloku bez
   dodatkowych reguł. */
.saved-item-actions-grid {
  display: grid;
  grid-template-columns: repeat(2, var(--touch-toggle));
  grid-template-rows: repeat(2, var(--touch-toggle));
  gap: 8px;
  flex-shrink: 0;
}

/* Na liście zapisanych tras mieszczą się cztery przyciski w siatce obok
   nazwy trasy, więc zostają mniejsze niż powiększone przyciski ekranu
   planowania. TASK-86: dolna granica podniesiona do var(--touch-toggle)
   (48px) - 46px było poniżej progu dla obsługi w rękawicach. */
.saved-item-actions .icon-btn,
.saved-item-actions-grid .icon-btn {
  width: var(--touch-toggle);
  height: var(--touch-toggle);
  font-size: 20px;
}

/* TASK-27: zielone okno podsumowania - pełna szerokość mapy, pływające
   (przeciągalne w pionie za górny pasek z tytułem), znika samo po 10 s albo
   od razu po "Zamknij okno". Pasek podsumowania pod formularzem zostaje bez
   zmian (widoczny cały czas) - to jest dodatkowa, rzucająca się w oczy
   informacja od razu po wyznaczeniu, żeby nie trzeba było jej szukać wzrokiem.
   Krycie 90% (10% przezroczystości).
   TASK-96 (skorygowane): DOMYŚLNA pozycja to góra ekranu zamiast środka -
   przeciąganie (patrz .route-toast-title niżej) zostaje w pełni zachowane,
   na wyraźne życzenie użytkownika. */
.route-toast {
  position: fixed;
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  width: calc(100vw - 24px);
  top: calc(12px + max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  z-index: 2000;
  padding: 22px 24px 18px;
  border-radius: 16px;
  background: rgba(27, 94, 32, 0.9);
  border: 2px solid #4caf50;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
  color: #ffffff;
  text-align: center;
  /* pointer-events: auto (domyślne) - okno przyjmuje dotknięcia: przeciąganie
     za tytuł i przycisk "Zamknij okno". */
  transition: opacity 0.35s ease;
  touch-action: none;
}

.route-toast[hidden] {
  display: none;
}

.route-toast-hiding {
  opacity: 0;
}

.route-toast-title {
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 12px;
  cursor: grab;
  /* Mały "uchwyt" wizualny nad tytułem - sygnalizuje, że to miejsce da się
     złapać i przeciągnąć, tak jak systemowe dolne arkusze (bottom sheets). */
  position: relative;
  padding-top: 10px;
}

.route-toast-title::before {
  content: '';
  position: absolute;
  top: -2px;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.4);
}

.route-toast-body {
  font-size: 17px;
  line-height: 1.6;
}

/* TASK-31: dymek podpowiedzi po długim przytrzymaniu (patrz tooltips.js).
   Ciemne tło + wysoki z-index - musi być czytelny nad mapą i nad nakładkami
   pełnoekranowymi jazdy (te sięgają do z-index 1000). */
.tooltip-bubble {
  /* Dymek pogody niesie kilka linii danych (temperatura, opady, gdzie i co),
     a treść jest wstawiana przez textContent - bez tego znaki nowej linii
     zlałyby się w jeden akapit. */
  white-space: pre-line;
  position: fixed;
  z-index: 5000;
  max-width: 280px;
  padding: 8px 12px;
  border-radius: 8px;
  background: rgba(16, 21, 29, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
  color: #ffffff;
  font-size: 13px;
  line-height: 1.4;
  text-align: center;
  pointer-events: none;
}

.route-toast-close {
  margin-top: 16px;
  padding: 10px 20px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.12);
  color: #ffffff;
  font-size: 15px;
  font-weight: 600;
}

/* Foldery pojazdów w "Trasy ukończone" (Motocykle/Samochody/Rowery) - duże,
   łatwe do trafienia przyciski (jak karty wyboru pojazdu), NIE wąskie
   linijki tekstu jak zwykłe pozycje listy - to jest główna nawigacja tego
   ekranu, więc musi się rzucać w oczy tak samo jak "Zapisane trasy"/"Mapy
   offline" na ekranie głównym. */
.folder-card {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  background: #232b38;
  border: 1px solid #2c3644;
  border-radius: 12px;
  padding: 20px 18px;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.folder-card-icon {
  font-size: 34px;
  flex-shrink: 0;
}

.folder-card-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.folder-card-text strong {
  font-size: 19px;
}

.folder-card-meta {
  font-size: 13px;
  color: #9aa7b8;
}

.folder-chevron {
  font-size: 28px;
  color: #6b7688;
  flex-shrink: 0;
}

/* Pasek nad listą wewnątrz jednej grupy: powrót do folderów + podgląd
   wszystkich przejazdów naraz na jednej mapie. */
.group-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.show-all-btn {
  width: auto;
  padding: 10px 16px;
  font-size: 13px;
}

/* Podpis nad przyciskiem "Wstecz" w podglądzie "pajęczyny" tras - żeby było
   widać, której grupy pojazdów dotyczą nałożone na siebie ślady. */
/* TASK-05: panel statystyk w podglądzie śladu. Ta sama zieleń i krycie co
   zielone okno po wyznaczeniu trasy, żeby oba czytało się jak jeden element
   aplikacji. Nie łapie dotknięć - mapa pod spodem ma pozostać przesuwalna. */
/* TASK-121 cz.3: jedyne wejście do trybu nawigacji z czysto oglądowego
   podglądu śladu - duży, wyraźny, zielony (tak jak "Jedziemy" na ekranie
   planowania), żeby jednoznacznie odróżniać się od neutralnych .track-viewer-btn
   w górnym pasku. Pozycja (bottom) jest DOMIERZANA w JS (umiescRedriveBtn w
   savedRoutesScreen.js) - patrz komentarz tam, dlaczego stała tu by nie starczyła. */
.redrive-btn {
  position: absolute;
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  right: calc(12px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  z-index: 1000;
  padding: 16px;
  min-height: 60px;
  border: none;
  border-radius: 14px;
  background: #2e7d32;
  color: #ffffff;
  font-size: 19px;
  font-weight: 800;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.redrive-btn:active {
  transform: scale(0.97);
  background: #1b5e20;
}

.redrive-btn[hidden] {
  display: none;
}

.track-stats {
  position: absolute;
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  right: calc(12px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  bottom: max(12px, max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  z-index: 1000;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px 16px;
  padding: 16px 18px;
  border-radius: 14px;
  background: rgba(27, 94, 32, 0.9);
  border: 2px solid #4caf50;
  color: #ffffff;
  pointer-events: none;
}

.track-stats[hidden] {
  display: none;
}

/* 0.200.0 (ZGLOSZENIE 29.09): w pionie "Jedz ponownie / Jedz ta trasa" na samym dole ekranu, tabela
   podsumowania nad nim (bottom domierza ulozDolPodgladu), a po 5 s tabela zwija sie do zielonego
   trojkata. W poziomie bez zmian - patrz blok @media nizej. */
.redrive-btn {
  bottom: max(12px, max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
}

.track-stats.zwiniete {
  display: none;
}

.track-stats-toggle {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;
  width: 64px;
  height: 36px;
  border: 2px solid #4caf50;
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  background: #2e7d32;
  color: #ffffff;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.track-stats-toggle[hidden] {
  display: none;
}

/* ZGLOSZENIE: punkty rekordow w podgladzie przejechanej trasy (mapView.
   renderTrackRecords). Element znacznika to sama kropka - BEZ position:
   MapLibre ustawia znacznikom position:absolute i wlasne przesuniecie, a
   nadpisanie tego zepsuloby polozenie punktu. Napis jest zawieszony na kropce
   absolutnie: nad nia przy predkosci, pod nia przy pochyleniu. Punktem
   odniesienia jest wnetrze kropki (bez 3 px obwodki), stad 3 px w przesunieciach.
   Nad kropke napis trafia przesunieciem, nie przez bottom: - patrz TASK-58
   (test_task58_60.js), ktory slusznie wylapuje kazde bottom: bez wciecia. */
.track-record {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 3px solid #ffffff;
  box-sizing: border-box;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}

.track-record-predkosc {
  background: #ffd600;
}

.track-record-pochylenie {
  background: #00b0ff;
}

.track-record-label {
  position: absolute;
  left: 50%;
  top: -3px;
  transform: translate(-50%, calc(-100% - 6px));
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 3px 9px 4px;
  border-radius: 10px;
  border: 2px solid #ffd600;
  background: rgba(13, 17, 23, 0.88);
  color: #ffffff;
  white-space: nowrap;
  line-height: 1.2;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

.track-record-pochylenie .track-record-label {
  top: calc(100% + 9px);
  transform: translateX(-50%);
  border-color: #00b0ff;
}

.track-record-caption {
  font-size: 11px;
  font-weight: 600;
  color: #c3cad4;
}

.track-record-value {
  font-size: 15px;
  font-weight: 800;
}

.track-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* TASK-135: skrócone warianty etykiet/wartości (patrz pokazStatystyki w
   savedRoutesScreen.js) - w PIONIE niewidoczne, w poziomie zastępują pełne.
   <i> bez kursywy: to tylko neutralny pojemnik na dwa warianty tekstu. */
.stat-full,
.stat-short {
  font-style: normal;
}

.stat-short {
  display: none;
}

.track-stat span {
  font-size: 12px;
  opacity: 0.85;
}

.track-stat strong {
  font-size: 17px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* TASK-85: tytuł przeniesiony NIŻEJ, pod pasek przycisków (patrz
   .track-viewer-topbar) - przy trzech większych przyciskach obok siebie na
   wąskim telefonie nie mieściłby się już w tym samym wierszu bez nachodzenia.
   TASK-131: `top` NIE jest już stałym wyliczeniem "+68px" (zakładało JEDEN
   wiersz przycisków - patrz komentarz przy .track-viewer-topbar niżej) -
   patrz umiescTytulPodgladu() w savedRoutesScreen.js, ta sama zasada co
   umiescRedriveBtn() (DOMIERZANA pozycja z rzeczywiście wyrenderowanej
   wysokości paska, nie zgadywana stała). Fallback 68px zostaje jako wartość
   startowa na czas między pierwszym odrysowaniem a pierwszym przebiegiem JS. */
.all-tracks-title {
  position: absolute;
  top: calc(max(12px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px))) + 68px);
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  z-index: 1000;
  padding: 10px 14px;
  border-radius: 8px;
  background: rgba(20, 26, 36, 0.92);
  color: #e8ecf1;
  font-size: 14px;
  font-weight: 600;
}

/* TASK-85: pasek przycisków podglądu trasy - ten sam wygląd co dawny
   .map-close-btn, tylko w wierszu flex zamiast osobno pozycjonowanych, żeby
   zmieściły się obok siebie bez nachodzenia.
   TASK-131: ZNALEZIONY BŁĄD, zgłoszony ze zrzutami ekranu - pasek miał
   TYLKO `right`, bez `left` ani zawijania, więc rósł w LEWO od prawej
   krawędzi bez żadnego ograniczenia. Dopóki był to komentarz z TASK-85
   ("Zamknij + GPX + Obraz", trzy przyciski), mieścił się. TASK-104/127
   dołożyły po drodze przycisk podkładu mapy i przycisk motywu (razem już
   PIĘĆ przycisków dla pojedynczego przejazdu) - piąty przycisk wypychał
   pierwszy ("Zamknij") poza LEWĄ krawędź ekranu, obcięty. Naprawa: `left`
   ogranicza pasek do szerokości ekranu (jak już wcześniej `right`), a
   `flex-wrap` pozwala nadmiarowym przyciskom zjechać do drugiego wiersza
   zamiast wypychać się poza kadr - `justify-content: flex-end` zostawia je
   dosunięte do prawej krawędzi w obu wierszach, tak jak dotychczas. */
.track-viewer-topbar {
  position: absolute;
  top: max(12px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  right: calc(12px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  z-index: 1000;
  display: flex;
  /* 0.200.0 (ZGLOSZENIE 29.09): JEDEN rzad, "Zamknij" w prawym gornym rogu - rozmiar napisu
     domierza savedRoutesScreen.dopasujPasekPodgladu (--pasek-czcionka / --pasek-odstep). */
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: 6px;
}

.track-viewer-topbar .track-viewer-btn {
  flex-shrink: 0;
  min-height: 44px;
  padding: 7px var(--pasek-odstep, 9px);
  font-size: var(--pasek-czcionka, 15px);
}

.track-viewer-topbar .track-viewer-theme-btn {
  width: 44px;
  min-height: 44px;
  padding: 0;
}

.track-viewer-btn {
  /* 0.164.0 (ZGLOSZENIE 21.09): "te przyciski przy otwartej trasie zaplanowanej mozesz troszke
     zmniejszyc, one nie musza byc takie duze - wtedy uloza sie w dwoch rzedach i bedzie
     wygodniej". Bylo 14px 18px / 56px / 17px - siedem przyciskow zajmowalo TRZY rzedy i
     zaslanialo gore mapy. Po zmniejszeniu mieszcza sie w dwoch.
     TASK-86 (obsluga w rekawicach) zostaje uszanowane: 46px to nadal wygodny cel dotyku,
     wyraznie powyzej 40px, a pasek bierze mniej mapy. */
  padding: 9px 13px;
  min-height: 46px;
  border: none;
  border-radius: 10px;
  background: rgba(20, 26, 36, 0.92);
  color: #e8ecf1;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.08s, background 0.08s;
}

.track-viewer-btn:active {
  transform: scale(0.95);
}

/* TASK-121 cz.4: "✕ Zamknij" tego podglądu jest funkcjonalnie tym samym
   "wróć", co .back-btn na listach - ten sam czerwony akcent, żeby całe
   "cofanie" w aplikacji rozpoznawało się jednym spojrzeniem, niezależnie od
   tego, czy tekstem jest "← Wstecz" czy "✕ Zamknij". */
.track-viewer-btn.back-accent {
  color: #ff5252;
  border: 1.5px solid #ff5252;
  background: rgba(20, 26, 36, 0.92);
}

.track-viewer-btn:disabled {
  opacity: 0.6;
}

/* TASK-127: przycisk motywu w podglądzie trasy niesie tę samą OKRĄGŁĄ ikonę
   SVG co #btnTheme na ekranie planowania (patrz theme.js/THEME_ICON_SVG) -
   bez tej reguły dziedziczyłby prostokątny padding/tekstowy układ reszty
   .track-viewer-btn, który spłaszczałby okrągłą ikonę. */
.track-viewer-theme-btn {
  /* 0.163.0: razem z reszta paska - patrz .track-viewer-btn. */
  padding: 0;
  width: 46px;
  min-height: 46px;
  background: transparent;
  flex-shrink: 0;
}

/* 0.164.0: lista ulubionych do wyboru z menu mapy. Kafle tej samej wielkosci co .fav-sheet-tile
   (obsluga w rekawicach), przewijalne, gdy miejsc jest wiecej niz wchodzi na ekran. */
.fav-pick-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 46vh;
  overflow-y: auto;
  margin: 12px 0;
}

.fav-pick-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 12px 14px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.06);
  color: #e8ecf1;
  font-size: 17px;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.fav-pick-item:active {
  transform: scale(0.98);
}

.fav-pick-item-odleglosc {
  margin-left: auto;
  font-size: 15px;
  font-weight: 600;
  opacity: 0.75;
  white-space: nowrap;
}

/* --- modale --- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
}

/* TASK-119 cz.1: #confirmModal bywa otwierany Z WNĘTRZA innego już otwartego
   modala (np. "Wymuś pełną synchronizację" z Ustawień, settingsModal.js) -
   ten drugi zostaje celowo widoczny w tle (użytkownik ma wrócić do niego po
   potwierdzeniu). Wszystkie modale dzielą jednak DOKŁADNIE ten sam z-index
   (1000) przez wspólną klasę .modal-overlay - przy remisie o kolejności
   rysowania decyduje pozycja w DOM, a #settingsModal leży w HTML PO
   #confirmModal, więc wygrywał on, mimo że pojawił się jako PÓŹNIEJSZY
   (bardziej "na wierzchu") dialog. #confirmModal to jedyny modal w tej
   aplikacji, który z założenia bywa wywoływany Z WNĘTRZA innych - stąd
   podniesiony, nie generyczny, z-index. */
#confirmModal {
  z-index: 1100;
}

.modal-overlay[hidden] {
  display: none;
}

/* TASK-46: okna potwierdzeń powiększone pod obsługę w grubych rękawicach
   motocyklowych - to samo podejście co przy oknie akcji ulubionego (TASK-44)
   i modalu pauzy (TASK-40). Dotyczy WSZYSTKICH okien potwierdzeń, bo każde
   z nich może wyskoczyć w trakcie jazdy albo na postoju w rękawicach. */
.modal-box {
  background: #232b38;
  border: 1px solid #2c3644;
  border-radius: 14px;
  padding: 24px;
  max-width: 460px;
  width: 100%;
  /* TASK-52: ZNALEZIONE NA URZĄDZENIU, w orientacji POZIOMEJ.

     Okna z kafelkami (wybór akcji ulubionego miejsca, wybór sposobu startu,
     drogi płatne) są wysokie, a w poziomie ekran ma niecałe 400 px wysokości.
     Dolny przycisk ("Anuluj / Zamknij") wychodził wtedy poza ekran i nie dało
     się go dotknąć - a zadanie wymaga wprost, żeby WSZYSTKIE przyciski mieściły
     się wewnątrz bezpiecznego obszaru.

     Ograniczenie wysokości do wysokości ekranu MINUS wcięcia systemowe, plus
     przewijanie wewnątrz okna. Dzięki temu okno nigdy nie wystaje, a jego
     zawartość pozostaje w całości dostępna niezależnie od orientacji.

     100dvh (a nie 100vh): na Androidzie pasek adresu/gestów potrafi zmieniać
     wysokość widoku, a vh zostaje przy wartości sprzed zmiany. */
  max-height: calc(
    100dvh - max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)) -
      max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)) - 24px
  );
  box-sizing: border-box;
  /* ZGŁOSZENIE UŻYTKOWNIKA: na telefonie o mniejszej rozdzielczości okno
     aktualizacji otwierało się i "nic się nie działo".

     PRZYCZYNA (odtworzona przy 360x640): samo ograniczenie wysokości okna NIE
     WYSTARCZA. Okno mieściło się w ekranie i przewijało, ale przyciski leżą
     na KOŃCU przewijanej treści - a treść okna aktualizacji to zlepek
     wszystkich notatek o wydaniu (zmierzone: 1715 znaków). Przycisk
     "Zainstaluj teraz" wypadał wtedy na y=1164 przy ekranie wysokim na 640 px.
     Użytkownik nie miał jak go nacisnąć, bo nawet nie było widać, że jest
     cokolwiek do przewinięcia.

     NAPRAWA: okno jest kolumną flex - przewija się WYŁĄCZNIE tekst, a rząd
     przycisków jest przypięty na dole i zostaje widoczny zawsze, niezależnie
     od długości komunikatu i od rozdzielczości ekranu. Ten sam wzorzec, który
     od dawna działa w oknach INFO/Ustawienia (.modal-box-wide). */
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Tytuł i rząd przycisków nie kurczą się i nie przewijają - to jedyne dwie
   rzeczy, które MUSZĄ być widoczne, cokolwiek jest w środku. */
.modal-box > h2,
.modal-box > .modal-actions,
.modal-box > .fav-sheet-secondary {
  flex-shrink: 0;
}

/* Przewijalny środek okna: sam tekst, lista kafelków, pola formularza.
   `min-height: 0` jest tu konieczne - bez niego element flex nie kurczy się
   poniżej swojej treści i przewijanie nie zadziała wcale. */
.modal-box > p,
.modal-box > .fav-sheet-tiles,
.modal-box > .settings-body,
.modal-box > .waypoint-list {
  overflow-y: auto;
  min-height: 0;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Tło okna też respektuje wcięcia - inaczej samo okno mieści się w kadrze,
   ale jest wyśrodkowane względem obszaru sięgającego pod paski systemowe,
   więc optycznie ucieka w dół. */
.modal-overlay {
  padding-top: max(env(safe-area-inset-top, 0px), var(--sa-top, 0px));
  padding-bottom: max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px));
  padding-left: max(env(safe-area-inset-left, 0px), var(--sa-left, 0px));
  padding-right: max(env(safe-area-inset-right, 0px), var(--sa-right, 0px));
  box-sizing: border-box;
}

.modal-box h2 {
  margin: 0 0 12px;
  font-size: clamp(19px, 5.5vw, 23px);
  color: #fff;
}

.modal-box p {
  margin: 0 0 20px;
  font-size: clamp(14px, 4vw, 16px);
  color: #c3cad4;
  line-height: 1.5;
  white-space: pre-line;
}

/* TASK-41: adres/współrzędne pod polem nazwy w oknie zapisu ulubionego -
   mniejsze i przygaszone niż zwykły tekst modalu, bo to tylko kontekst,
   nie treść do przeczytania w pierwszej kolejności. */
.fav-name-address {
  margin: 0 0 10px !important;
  font-size: 12px !important;
  color: #7c8899 !important;
}

.fav-name-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  margin-bottom: 18px;
  border-radius: 8px;
  border: 1px solid #3a4453;
  background: #1a212c;
  color: #ffffff;
  font-size: 16px;
}

.fav-name-input:focus {
  outline: none;
  border-color: #4fa3e3;
}

/* TASK-44: wielkoformatowy panel akcji ulubionego miejsca - "glove-friendly",
   duże kafelki zamiast wąskich przycisków dawnego .fav-menu (zastąpionego
   tym panelem). Otwierany identycznie z paska pod wyszukiwarkami i z gwiazdki
   bezpośrednio na mapie. */
.fav-sheet-title {
  font-size: 17px;
  font-weight: 700;
  color: #fff;
  margin: 0 0 2px;
}

.fav-sheet-address {
  font-size: 12px;
  color: #7c8899;
  margin: 0 0 16px;
}

.fav-sheet-tiles {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}

.fav-sheet-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 12px 18px;
  border-radius: 12px;
  border: 2px solid #2c3644;
  background: #232b38;
  color: #e8ecf1;
  font-size: 18px;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.fav-sheet-tile-icon {
  font-size: 26px;
  line-height: 1;
}

/* Wiodący kafelek - najczęstsza akcja (ustaw jako cel i wyznacz trasę). */
.fav-sheet-tile-primary {
  border-color: #2e7d32;
  background: #1f3a22;
  color: #ffffff;
}

.fav-sheet-secondary {
  display: flex;
  gap: 8px;
}

.fav-sheet-secondary button {
  flex: 1;
  padding: 12px 10px;
  /* TASK-86: obsługa w rękawicach motocyklowych. */
  min-height: var(--touch-toggle);
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #c3cad4;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.fav-sheet-secondary button:active {
  transform: scale(0.95);
}

.fav-sheet-remove {
  color: #ff8a80 !important;
  border-color: #5a2c2c !important;
}

.modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: flex-end;
}

/* Przyciski potwierdzeń: dwukrotnie większe pole dotyku niż poprzednio
   (10/13 px -> 64 px wysokości i 18 px czcionki). `flex: 1 1 150px` sprawia,
   że rozciągają się na całą szerokość okna i zawijają do kolejnych rzędów -
   przy trzech przyciskach ("Jedź dalej" / "Zakończ bez zapisu" / "Zakończ
   i zapisz") każdy zostaje duży zamiast ścisnąć się w jeden ciasny rząd. */
.modal-btn {
  border: none;
  border-radius: 12px;
  flex: 1 1 150px;
  min-height: 64px;
  padding: 14px 20px;
  font-size: clamp(15px, 4.5vw, 18px);
  font-weight: 700;
  cursor: pointer;
}

.modal-btn-secondary {
  background: #1a212c;
  color: #c3cad4;
}

/* TASK-07: przycisk potwierdzenia jest zielony, nie żółty. Żółty czytało się
   jak ostrzeżenie, a to jest akcja zatwierdzająca ("Zakończ i zapisz").
   Kolor zgodny z zielenią używaną w aplikacji dla rzeczy udanych/zapisanych. */
.modal-btn-primary {
  background: #2e7d32;
  color: #ffffff;
}

/* Potwierdzenie akcji NIEODWRACALNEJ (kasowanie trasy). Zielony przycisk
   potwierdzenia z TASK-07 pasuje do zatwierdzania, ale przy usuwaniu
   sygnalizowalby "wszystko w porzadku" - stad osobny, czerwony wariant. */
.modal-btn-danger-solid {
  background: #c62828;
  color: #ffffff;
}

.modal-btn-danger {
  background: #7f2020;
  color: #f5b7b1;
}

.modal-btn-danger[hidden] {
  display: none;
}

/* 0.166.2: ciemnozielony wariant przycisku "alt" - rownorzedna, bezpieczna alternatywa
   (np. "Wyznacz na nowo dla: <pojazd>"). Ciemniejszy niz zielone potwierdzenie
   (.modal-btn-primary), zeby oba przyciski dalo sie odroznic jednym spojrzeniem. */
.modal-btn-alt-zielony {
  background: #1b4d1f;
  color: #c8e6c9;
}

.modal-btn-alt-zielony[hidden] {
  display: none;
}

/* Okna z dużą treścią (INFO, edytor punktów pośrednich). Bez ograniczenia
   wysokości okno rozciągało się poza ekran: treści nie dało się przewinąć,
   a przycisk „Zamknij” wypadał poza widok. */
.modal-box-wide {
  max-width: 460px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}

.modal-box-wide > h2,
.modal-box-wide > p {
  flex-shrink: 0;
}

/* Przyciski muszą zostać widoczne niezależnie od długości treści. */
.modal-actions {
  flex-shrink: 0;
}

.modal-actions-wrap {
  flex-wrap: wrap;
}

.info-modal-body {
  flex: 1;
  min-height: 0; /* bez tego element flex nie kurczy się i nie przewija */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  font-size: 13px;
  line-height: 1.55;
  color: #c3cad4;
  margin-bottom: 14px;
}

.info-modal-body p {
  margin: 0 0 10px;
}

.info-modal-body h3 {
  margin: 16px 0 6px;
  font-size: 14px;
  color: #ffffff;
}

.info-modal-body h3:first-child {
  margin-top: 0;
}

.info-modal-body ul {
  margin: 0 0 10px;
  padding-left: 20px;
}

.info-modal-body li {
  margin-bottom: 5px;
}

.update-check-result {
  margin: -4px 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: #17314f;
  border: 1px solid #1565c0;
  font-size: 13px;
  color: #d6e4f5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.update-check-result[hidden] {
  display: none;
}

.update-download-btn {
  padding: 6px 14px;
  font-size: 13px;
  flex-shrink: 0;
}

/* Nagłówek wydania nad jego listą zmian (ekran INFO pokazuje dwa ostatnie). */
.changelog-version {
  color: #f9a825;
  font-weight: 700;
  margin: 14px 0 4px;
}

/* Nagłówek okna INFO: nazwa programu i numer wersji na środku (0.208.1). */
.modal-box-wide > h2.info-naglowek {
  text-align: center;
}

.info-naglowek-wersja {
  color: #f9a825;
  font-weight: 700;
  white-space: nowrap;
}

/* --- ekran startowy --- */

/* Zasłania całą aplikację na czas inicjalizacji (wczytanie bundla, odczyt
   pobranych map, pierwsza pozycja GPS). Kolor tła zgodny z grafiką, żeby
   przy jej doczytywaniu nie było widać skoku. Gaszony przez app.js: klasa
   "splash-hidden" wygasza go płynnie, a po zakończeniu przejścia element
   dostaje "hidden" i przestaje przechwytywać dotyk. */
.splash {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 24px;
  background: #0d1218;
  opacity: 1;
  transition: opacity 0.45s ease-out;
}

.splash[hidden] {
  display: none;
}

.splash-hidden {
  opacity: 0;
  pointer-events: none;
}

.splash-title {
  margin: 0;
  font-size: 44px;
  font-weight: 800;
  letter-spacing: 2px;
  color: #ffffff;
  text-align: center;
}

/* Grafika jest kwadratowa (1024x1024). Ograniczamy ją jednocześnie szerokością
   ekranu i jego wysokością, żeby w poziomie nie wypchnęła napisów poza kadr. */
.splash-logo {
  width: min(72vw, 52vh);
  height: auto;
  max-width: 420px;
}

.splash-copyright {
  margin: 0;
  font-size: 17px;
  color: #9aa6b6;
  text-align: center;
}

/* TASK-184: wersja i data kompilacji NA DOLE ekranu startowego.
   Pozycjonowana bezwzględnie, a nie jako kolejny element kolumny - inaczej
   dołożyłaby się do wyśrodkowanej grupy (tytuł + logo + copyright) i
   przesunęła ją w górę, czego zadanie nie obejmuje ("nic więcej nie zmieniaj").
   Wyciszona kolorem: to informacja do sprawdzenia, a nie element oprawy. */
.splash-version {
  position: absolute;
  /* TASK-52/58 (konwencja projektu, przypomniana przez wlasne testy): kazdy
     element pozycjonowany bezwzglednie odsuwamy od krawedzi o WCIECIA
     BEZPIECZENSTWA, i to ZAWSZE para env() + var(--sa-*) - na telefonie
     uzytkownika samo env() zwracalo zero, przez co napis wchodzilby pod pasek
     gestow i wyciecie na aparat (w poziomie sa one z boku, nie u dolu). */
  left: calc(16px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  right: calc(16px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  bottom: calc(18px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  margin: 0;
  font-size: 13px;
  color: #6b7683;
  text-align: center;
}

/* ============ TASK-45: Ustawienia, motyw dzień/noc ============ */

/* Oba przyciski (INFO i Ustawienia) w jednej, wyśrodkowanej komórce belki. */
.topbar-center {
  display: flex;
  align-items: center;
  gap: clamp(4px, 1.5vw, 8px);
  min-width: 0;
}

/* Rozmiar płynny jak reszta belki (patrz .info-badge). Wysokość zostaje >= 40 px
   niezależnie od szerokości ekranu - to jest minimum na pewne trafienie palcem,
   więc kurczy się szerokość i czcionka, a nie pole dotyku. */
.settings-badge {
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #e8ecf1;
  border-radius: 999px;
  min-width: 0;
  /* TASK-97: 40px -> var(--touch-toggle) (48px), patrz komentarz przy .info-badge. */
  min-height: var(--touch-toggle);
  padding: 6px clamp(7px, 2.5vw, 12px);
  font-size: clamp(15px, 4.5vw, 19px);
  line-height: 1;
  flex-shrink: 0;
  cursor: pointer;
}

/* Przełącznik motywu na bocznym pasku mapy - okrągły, jak pozostałe ikony. */
.theme-btn {
  color: #e8ecf1;
  font-size: clamp(17px, 3.3vh, 26px);
  line-height: 1;
}

/* TASK-99: dolny margines wewnątrz przewijanego obszaru - bez niego ostatnia
   sekcja (jej notatka statusu, np. #setBackupNote/#syncNote) stykała się
   bezpośrednio z górną krawędzią paska `.modal-actions` ("Zamknij"), przez co
   sprawiała wrażenie "przysłoniętej"/ściśniętej pod przyciskiem, zwłaszcza po
   przewinięciu listy do samego końca. Ten sam margines chroni KAŻDĄ sekcję,
   która akurat wyląduje na końcu listy, nie tylko tę obecną. */
.settings-body {
  flex: 1;
  overflow-y: auto;
  padding-right: 4px;
  padding-bottom: 12px;
}

.settings-section {
  padding: 14px 0;
  border-top: 1px solid #2c3644;
}

.settings-section:first-child {
  border-top: none;
  padding-top: 0;
}

.settings-title {
  font-size: 13px;
  font-weight: 700;
  color: #7c8899;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 10px;
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 15px;
  color: #e8ecf1;
  margin-bottom: 8px;
}

/* TASK-113: pole liczbowe w Ustawieniach (własna średnia prędkość roweru).
   Osobna klasa, a nie .settings-select - to input, nie lista wyboru, i ma być
   wąski (dwie cyfry + jednostka obok), zamiast rozciągać się na resztę wiersza. */
.settings-number-field {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.settings-number {
  width: 76px;
  padding: 10px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #232b38;
  color: #ffffff;
  font-size: 17px;
  font-weight: 700;
  text-align: center;
  /* Próg dotyku jak reszta przełączników w Ustawieniach (TASK-86). */
  min-height: var(--touch-toggle);
}

.settings-unit {
  font-size: 14px;
  color: #a9b4c2;
}

.settings-value {
  font-weight: 700;
  color: #64b5f6;
}

/* TASK-105: wybór domyślnego podkładu mapy per grupa pojazdów - natywny
   <select> zamiast siatki przycisków (jak reszta Ustawień) - lista ma 3-4
   pozycje na TRZY osobne wiersze naraz, więc przyciski szybko zajęłyby
   więcej miejsca niż reszta ekranu Ustawień razem wzięta. Stylowany pod
   ciemny motyw aplikacji, ale zostaje NATYWNYM elementem (własny,
   dostępny picker systemowy - czytelny nawet na najmniejszym ekranie). */
.settings-select {
  min-height: var(--touch-toggle);
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #e8ecf1;
  font-size: 15px;
  font-weight: 600;
  max-width: 60%;
}

/* Suwak z dużym uchwytem - do trafienia kciukiem w rękawicy. */
.settings-slider {
  width: 100%;
  height: 36px;
  margin: 0 0 12px;
  accent-color: #64b5f6;
}

.settings-toggle {
  align-items: flex-start;
  justify-content: flex-start;
  cursor: pointer;
}

.settings-toggle input {
  /* TASK-86: 26 -> 30px - realny obszar dotyku to cały wiersz <label>, ale
     ikona jest za mała żeby ją szybko rozpoznać w rękawicy. */
  width: 30px;
  height: 30px;
  margin: 0;
  flex-shrink: 0;
  accent-color: #2e7d32;
}

/* TASK-113 (poprawka po obejrzeniu na telefonie): selektor był zawężony do
   `.settings-toggle`, czyli wyłącznie do wierszy z przełącznikiem. Nowy wiersz
   "Domyślna prędkość średnia" (pole liczbowe, nie przełącznik) wypadał poza
   niego - jego opis kleił się w JEDNEJ LINII z etykietą, zamiast być osobną,
   przygaszoną linijką jak u wszystkich sąsiadów. `.settings-row` obejmuje też
   wiersze z przełącznikiem (mają OBIE klasy), więc nic się dla nich nie zmienia. */
.settings-row small {
  display: block;
  font-size: 12px;
  color: #7c8899;
  margin-top: 3px;
}

.settings-theme-switch {
  display: flex;
  gap: 10px;
  margin-bottom: 12px;
}

.settings-theme-btn {
  flex: 1;
  min-height: 52px;
  /* TASK-86: dopisany jawny padding - dotąd tylko min-height, bez paddingu,
     przez co pole dotyku było niespójne z resztą przycisków. */
  padding: 12px 16px;
  border-radius: 10px;
  border: 2px solid #2c3644;
  background: #1a212c;
  color: #c3cad4;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.08s, background 0.08s;
}

.settings-theme-btn:active {
  transform: scale(0.95);
}

.settings-theme-btn.settings-theme-active {
  border-color: #64b5f6;
  background: #16324a;
  color: #ffffff;
}

/* TASK-117: "Wymuś pełną synchronizację" - narzędzie "na wypadek problemu",
   nie codzienna czynność jak zwykłe "Synchronizuj trasy teraz" obok (to
   dlatego stoi POZA .settings-theme-switch, w osobnym wierszu, pełnej
   szerokości) - stąd przygaszona kolorystyka zamiast pełnego kontrastu
   pozostałych przycisków tej sekcji, żeby wzrokiem nie konkurował o
   pierwszeństwo z akcjami używanymi na co dzień. */
.settings-theme-btn-secondary {
  width: 100%;
  margin-top: 10px;
  border-color: #4a3520;
  background: #241a10;
  color: #c9a876;
}

.settings-note {
  font-size: 12px;
  color: #ffcc80;
  background: #2a2413;
  border: 1px solid #4a4023;
  border-radius: 8px;
  padding: 8px 10px;
  line-height: 1.4;
}

/* TASK-45: nieudane sprawdzenie aktualizacji ma WYGLĄDAĆ na błąd, a nie
   ginąć w tym samym stylu co komunikat "masz najnowszą wersję". */
.update-check-result.update-check-error {
  color: #ff8a80;
  border-color: #5a2c2c;
}

/* Komunikat okna potwierdzenia bywa wielolinijkowy (notatki o wydaniu) -
   bez zachowania znaków nowej linii zlewał się w jedną ścianę tekstu. */
#confirmModalText {
  white-space: pre-line;
}

/* --- TASK-62: karta podsumowania przejazdu --- */

/* Zielona, bo to jest domknięcie udanego przejazdu, a nie ostrzeżenie -
   ten sam kolor co pływająca plansza po wyznaczeniu trasy, żeby oba
   "dobre" komunikaty czytały się tak samo. */
.ride-summary-box {
  background: linear-gradient(180deg, #1c5c33 0%, #16482a 100%);
  border-color: #2f8f52;
}

.ride-summary-body {
  /* Telemetrii bywa sporo, a w orientacji poziomej ekran ma niecałe 400 px -
     środek karty przewija się więc sam, a przyciski zostają przypięte
     (patrz reguły .modal-box wyżej). */
  overflow-y: auto;
  min-height: 0;
  margin-bottom: 14px;
}

.summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.summary-label {
  color: #cfe8d8;
  font-size: 14px;
}

.summary-value {
  color: #ffffff;
  font-size: 18px;
  font-weight: 700;
  white-space: nowrap;
}

/* Dystans i prędkość maksymalna to liczby, których szuka się pierwsze -
   stąd wyraźnie większe od reszty. */
.summary-row-main .summary-value {
  font-size: 26px;
}

.summary-lean {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 0 4px;
}

.lean-gauge {
  width: 92px;
  height: 53px;
  flex-shrink: 0;
}

.summary-lean-values {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 16px;
  font-weight: 700;
}

/* Kolory zgodne z kreskami wskaźnika obok - bez tego trzeba by zgadywać,
   która kreska jest którą wartością. */
.lean-left {
  color: #7ec8ff;
}

.lean-right {
  color: #ffb74d;
}

.summary-note {
  margin-top: 10px;
  font-size: 13px;
  line-height: 1.45;
  color: #cfe8d8;
}

/* Telemetria w historii tras - ten sam układ, mniejsza skala. */
.track-telemetry {
  margin-top: 6px;
  font-size: 12px;
  color: #a7b0bd;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}

.track-telemetry strong {
  color: #dbe1ea;
  font-weight: 700;
}

/* TASK-137: pole "Zapamiętaj logowanie na tym urządzeniu" w oknie logowania.
   Odstęp od przycisków - bez niego etykieta przykleja się do "Zaloguj". */
.login-remember {
  margin: 4px 0 12px;
}

/* 0.198.0: "Pomin - korzystaj bez konta" - pod przyciskami logowania, na cala szerokosc. */
.login-skip {
  display: block;
  width: 100%;
  margin-top: 12px;
  /* .modal-btn ma flex: 1 1 150px - w pionowym .modal-box rozciagalo to przycisk na pol ekranu
     (zmierzone na S5 Neo). Poza rzedem przyciskow: bez rozciagania. */
  flex: 0 0 auto;
}
.login-skip[hidden] {
  display: none;
}

/* TASK-140: wskazówka po otwarciu mapy ikonką 🗺 przy PUSTYM polu startu/mety.
   Lewy dolny róg mapy - prawą stronę zajmuje pionowy pasek ikon
   (.side-controls, bottom 28px), górny prawy przycisk "Zamknij". `right`
   zostawia pasowi ikon jego kolumnę, więc wskazówka nigdy na niego nie
   nachodzi niezależnie od długości tekstu. */
.map-pick-hint {
  position: absolute;
  left: calc(12px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  right: calc(92px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  bottom: calc(28px + max(env(safe-area-inset-bottom, 0px), var(--sa-bottom, 0px)));
  z-index: 900;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid #4a6fa5;
  background: rgba(20, 32, 48, 0.92);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  color: #dce8f7;
  font-size: 15px;
  line-height: 1.35;
}

.map-pick-hint[hidden] {
  display: none;
}

/* TASK-140: informacja o trwającym szukaniu po fragmencie nazwy (Overpass
   potrafi odpowiadać kilkanaście sekund - bez tego lista jest pusta i wygląda
   jak brak wyników). */
.search-result-busy {
  padding: 14px 16px;
  color: #9fb3c8;
  font-size: 14px;
  font-style: italic;
}

/* TASK-141: pole tekstowe ksywki w Ustawieniach - ten sam wzorzec co
   .settings-number, tylko szersze (imię/ksywka, nie 2-3 cyfry). */
.settings-text {
  width: 140px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #232b38;
  color: #ffffff;
  font-size: 17px;
  font-weight: 600;
  text-align: right;
  min-height: var(--touch-toggle);
}

/* TASK-141: znaczniki kolegów w "Jeździe w grupie" - strzałka (jak własny
   znacznik pojazdu, ale mniejsza - N osób na raz nie może zasłonić mapy) +
   pigułka z ksywką/prędkością pod spodem. */
/* TASK-158: sam kontener zostaje przezroczysty dla dotyku (jego pudełko flex
   bywa szersze niz to, co widac - inaczej zjadalby dotkniecia obok kolegi),
   ale WIDOCZNE czesci musza byc klikalne: dotkniecie kolegi otwiera okno
   wysylki wiadomosci. Zdarzenie i tak babelkuje przez kontener z
   pointer-events:none, wiec nasluch na `wrap` dziala bez zmian. */
/* ZGLOSZENIE (etykiety wspoljadacych): element znacznika to sama kropka (36 px),
   kotwica w jej srodku. z-index: kropki i pigulki kolegow NAD strzalka wlasnej
   pozycji (ten sam kontener znacznikow MapLibre; strzalka ma z-index domyslny i
   sama sie nie zmienia). */
.group-marker-wrap {
  background: none;
  border: none;
  pointer-events: none;
  width: 36px;
  height: 36px;
  z-index: 5;
  transition: opacity 0.4s ease;
}

/* TASK-186: PULSUJACY ZOLTY PUNKT zamiast strzalki kierunku.
   Wprost ze zgloszenia: "niech to beda mrugajace punkty, na przyklad w kolorze
   zoltym, niech one beda wieksze niz punkt startu i mety, mrugajacy, pulsujacy
   punkt z napisem nazwy uzytkownika".
   Znaczniki startu i mety maja 26 px (DRAGGABLE_MARKER_PX w mapView.js) - kropka
   kolegi ma 36 px, czyli jest od nich wyraznie wieksza, tak jak w zgloszeniu.
   Nawet w najwezszej fazie pulsowania (skala 0.78 = 28 px) nadal je przewyzsza,
   wiec "wieksza" jest prawda przez CALY cykl animacji, a nie tylko w szczycie. */
/* JAZDA W GRUPIE (ZGLOSZENIE): kolor kropki jest PRZYPISANY UCZESTNIKOWI i
   wstawiany z JS (patrz GROUP_MEMBER_COLORS w mapView.js) - wartosc ponizej to
   tylko wyglad zastepczy, gdyby kolor nie dotarl. */
.group-marker-dot {
  pointer-events: auto;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #ffd400;
  border: 3px solid #1b1f26;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
  animation: group-dot-pulse 1.4s ease-in-out infinite;
}

/* Pulsowanie SAMA SKALA I KRYCIEM, bez cienia rosnacego w nieskonczonosc:
   znacznikow bywa kilka naraz, a kazdy animowany cien to osobna warstwa do
   przerysowania w kazdej klatce - na slabszym telefonie (patrz zgloszenie o
   kafelkach) to realny koszt. */
@keyframes group-dot-pulse {
  0%   { transform: scale(1);    opacity: 1; }
  50%  { transform: scale(0.78); opacity: 0.55; }
  100% { transform: scale(1);    opacity: 1; }
}

/* Kto nie chce animacji w systemie, ten jej nie dostaje - punkt zostaje
   widoczny, po prostu nie pulsuje. */
@media (prefers-reduced-motion: reduce) {
  .group-marker-dot {
    animation: none;
  }
}

/* ZGLOSZENIE (etykiety wspoljadacych): pigulka przyczepiona do srodka kropki i
   przesuwana z JS (mapView.setGroupBadge, uklad z etykietyMapy.ulozEtykietyGrupy):
   pod, nad, z boku albo po skosie - tak, zeby byla w kadrze i nie nachodzila na
   inne etykiety. Domyslnie pod kropka. Przejscie sprawia, ze przy zmianie strony
   napis PLYNIE na nowe miejsce, zamiast przeskakiwac. */
.group-marker-badge {
  /* Zaczepiona w srodku kropki (znacznik ma 36 x 36 px); gdzie stoi wzgledem kropki,
     ustawia mapView.setGroupBadge wedlug ukladu etykiet grupy. */
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, 22px);
  transition: transform 0.25s ease;
  pointer-events: auto;
  /* TASK-186: obwodka w kolorze przypisanym uczestnikowi (ustawiana z JS) -
     przy kilku kolegach naraz sama zolta kropka nie powiedzialaby, kto jest kto. */
  border: 2px solid transparent;
  /* ZGLOSZENIE: "napisy na mapie zwiazane z uczestnikami pokoju maja byc troszke
     wieksze - to jednak nieduzy telefon zamontowany na motocyklu". Pigulka rosnie
     razem z wypelnieniem, a uklad etykiet dostaje jej wymiar POMIAREM
     (badgeW/badgeH w mapView -> etykietyMapy.ulozEtykietyGrupy), wiec wieksza
     pigulka sama w sobie nie zaczyna nachodzic na sasiednie. */
  padding: 4px 9px;
  border-radius: 11px;
  background: rgba(13, 17, 23, 0.82);
  color: #ffffff;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}

/* TASK-141: ekran "Jazda w grupie". */
.group-ride-screen {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
}

.group-nickname-input,
.group-code-input {
  width: 100%;
  text-align: left;
  font-size: 22px;
  letter-spacing: 1px;
}

.group-code-input {
  text-transform: uppercase;
  letter-spacing: 4px;
  text-align: center;
}

.group-join-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.group-join-row .group-code-input {
  flex: 1;
}

.group-room-code {
  align-self: center;
  /* TASK-149 cz.1: czcionka o STALEJ szerokosci znaku. Kod dyktuje sie
     koledze stojacemu obok, wiec litery musza byc jednakowo szerokie i
     jednoznaczne - w czcionce proporcjonalnej "I" i "1" bywaja nie do
     odroznienia z odleglosci wyciagnietej reki. Alfabet po stronie serwera
     i tak nie zawiera I/O/0/1 (patrz groupRooms.js), ale stala szerokosc
     dodatkowo porzadkuje odczyt. */
  font-family: ui-monospace, 'Roboto Mono', 'DejaVu Sans Mono', monospace;
  font-size: 40px;
  font-weight: 800;
  letter-spacing: 6px;
  color: #ffffff;
  background: #1a212c;
  border: 2px solid #2c3644;
  border-radius: 12px;
  padding: 12px 24px;
}

.group-qr-wrap {
  align-self: center;
  background: #ffffff;
  padding: 10px;
  border-radius: 12px;
}

.group-qr-wrap svg {
  display: block;
  width: 140px;
  height: 140px;
}

.group-qr-details {
  align-self: center;
  color: #9fb3c8;
}

.group-qr-details summary {
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  padding: 6px 0;
}

.group-qr-details .group-qr-wrap {
  margin-top: 10px;
}

.group-room-hint {
  text-align: center;
  color: #9fb3c8;
  font-size: 14px;
}

.group-member-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.group-member-row {
  display: flex;
  justify-content: space-between;
  padding: 10px 14px;
  background: #1a212c;
  border: 1px solid #2c3644;
  border-radius: 8px;
  color: #ffffff;
  font-weight: 600;
}

.group-member-empty {
  text-align: center;
  color: #9fb3c8;
  padding: 10px;
}

/* Pełnoszerokościowy przycisk niebezpiecznej akcji ("Opuść grupę") - ten sam
   .action-btn co reszta, tylko czerwony (wzorzec .modal-btn-danger-solid). */
.danger-btn {
  background: #c62828;
}

/* TASK-141: przycisk + wysuwany panel listy uczestników grupy podczas jazdy. */
.group-panel-btn {
  color: #ffffff;
  font-size: clamp(16px, 3vh, 22px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.1;
}

.group-panel-btn[hidden] {
  display: none;
}

#groupPanelCount {
  font-size: 13px;
  font-weight: 700;
}

.group-panel {
  position: absolute;
  right: calc(80px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  top: calc(12px + max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  z-index: 950;
  width: min(280px, 70vw);
  max-height: 60vh;
  overflow-y: auto;
  background: rgba(13, 17, 23, 0.95);
  border: 1px solid #2c3644;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.group-panel[hidden] {
  display: none;
}

.group-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid #2c3644;
  color: #ffffff;
  font-weight: 700;
}

.group-panel-close {
  background: none;
  border: none;
  color: #9fb3c8;
  font-size: 18px;
  padding: 4px 8px;
  cursor: pointer;
}

.group-panel-list {
  display: flex;
  flex-direction: column;
}

.group-panel-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 14px;
  background: none;
  border: none;
  border-bottom: 1px solid #1a212c;
  color: #ffffff;
  text-align: left;
  cursor: pointer;
  width: 100%;
}

.group-panel-row:active {
  background: #1a212c;
}

.group-panel-name {
  font-weight: 700;
}

.group-panel-meta {
  font-size: 13px;
  color: #9fb3c8;
}

/* TASK-149 cz.2: dwa duze, jednoznaczne kafelki wyboru na ekranie grupy. */
.group-big-tile {
  min-height: 64px;
  font-size: 18px;
}

/* Pole kodu w oknie "Dolacz do grupy" - jedyna tresc tego okna, wiec moze byc
   naprawde duze. Stala szerokosc znaku i rozstrzelenie jak przy wyswietlaniu
   kodu (.group-room-code), zeby wpisywany tekst wygladal tak samo jak ten,
   ktory kolega ma na swoim ekranie. */
.group-code-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 12px 0;
  padding: 14px 12px;
  font-family: ui-monospace, 'Roboto Mono', 'DejaVu Sans Mono', monospace;
  font-size: 32px;
  font-weight: 800;
  letter-spacing: 8px;
  text-align: center;
  text-transform: uppercase;
  color: #ffffff;
  background: #1a212c;
  border: 2px solid #2c3644;
  border-radius: 12px;
}

.group-join-hint {
  margin: 0;
  color: #b6c2d1;
  font-size: 14px;
}

/* Wlasny wiersz na liscie uczestnikow - wyrozniony, zeby od razu bylo widac,
   ktory to Ty (patrz renderMembers w groupRideScreen.js). */
.group-member-self {
  border-left: 3px solid #26a69a;
  padding-left: 9px;
  font-weight: 700;
}

/* TASK-149 cz.4: warstwa etykiet uczestnikow poza kadrem mapy. Sama warstwa
   NIE lapie dotkniec (pointer-events: none) - inaczej przezroczysty prostokat
   na calej mapie blokowalby przesuwanie jej palcem. Dotkniecia lapia wylacznie
   same etykiety, ktore wlaczaja to sobie z powrotem. */
.group-far-labels {
  position: absolute;
  inset: 0;
  z-index: 860;
  pointer-events: none;
}

.group-far-label {
  position: absolute;
  /* Wspolrzedne z JS wskazuja SRODEK etykiety (miejsce wokol strzalki jazdy,
     patrz etykietyMapy.ulozWokolStrzalki) - przesuwamy o pol wymiaru. */
  transform: translate(-50%, -50%);
  pointer-events: auto;
  /* ZGLOSZENIE (etykiety przy strzalce): dwa wiersze - ksywka nad dystansem ze
     strzalka kierunku. Waska etykieta miesci sie takze z boku strzalki na
     telefonie w pionie. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  max-width: 40vw;
  padding: 4px 10px 5px;
  border: 2px solid #4dd0e1;
  border-radius: 14px;
  background: rgba(15, 22, 32, 0.92);
  color: #e6f4f7;
  /* ZGLOSZENIE (wielkosc napisow uczestnikow): etykieta kolegi spoza kadru rosnie
     razem z pigulka przy kropce - obie niosa te sama tresc, wiec roznica rozmiarow
     miedzy nimi bylaby widoczna jako niedorobka. */
  font-size: 16px;
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  cursor: pointer;
}

/* Plynna zmiana miejsca (uklad kilka razy na sekunde) - wlaczana dopiero po
   pierwszym ustawieniu etykiety, zeby nowa nie przejezdzala przez caly ekran. */
.group-far-label.group-far-label-plynna {
  transition: left 0.2s linear, top 0.2s linear;
}

/* Etykieta kolegi, ktorego kropka jest w kadrze (wtedy ma pigulke przy kropce).
   visibility, nie display - wymiary etykiety musza byc mierzalne do ukladu. */
/* ZGLOSZENIE: uczestnik offline (zamknal aplikacje, nadal w pokoju) - szara kropka
   bez pulsowania, szara pigulka i etykieta z dopiskiem "offline". Kolor obwodek i
   kropek ustawia JS (KOLOR_OFFLINE w obecnoscGrupy.js). */
.group-marker-offline .group-marker-dot {
  animation: none;
}
.group-marker-offline .group-marker-badge {
  color: #c3c8cf;
}
.group-marker-offline-tag,
.group-far-offline {
  margin-left: 6px;
  font-weight: 700;
  color: #aeb4bd;
}
.group-far-label.group-far-label-offline {
  color: #c3c8cf;
}
.group-panel-row.group-panel-offline .group-panel-name,
.group-panel-row.group-panel-offline .group-panel-meta {
  color: #9aa1ab;
}

.group-far-label.group-far-label-ukryta {
  visibility: hidden;
  pointer-events: none;
}

.group-far-nazwa {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.group-far-linia {
  display: flex;
  align-items: center;
  font-size: 15px;
}

.group-far-label:active {
  transform: translate(-50%, -50%) scale(0.94);
}

.group-far-dist {
  color: #4dd0e1;
  font-weight: 800;
}

/* JAZDA W GRUPIE (ZGLOSZENIE): kolor uczestnika przy jego ksywce - ten sam, co
   kropka na mapie. Obwodka etykiety dostaje go z JS. */
.group-far-kropka {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  border-radius: 50%;
  vertical-align: middle;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.45);
}

/* JAZDA W GRUPIE (ZGLOSZENIE): mala strzalka kierunku przy ksywce osoby, ktorej
   punktu nie widac na mapie. Rozmiar celowo niewielki - ma doprecyzowac kierunek,
   a nie konkurowac z ksywka. Obrot wstawia JS (patrz renderGroupFarLabels). */
.group-far-strzalka {
  width: 13px;
  height: 13px;
  margin-left: 6px;
  transform-origin: 50% 50%;
  fill: #4dd0e1;
}

.group-panel-kropka {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
  border-radius: 50%;
  vertical-align: middle;
}

/* TASK-150: okrag niepewnosci przy pozycji ZGRUBNEJ (maszty GSM/Wi-Fi).
   Rysowany jako dziecko kropki pozycji i wysrodkowany wzgledem niej - kropka
   ma `anchor: center`, wiec srodek okregu pokrywa sie ze srodkiem kropki.
   Celowo BARDZO delikatny: ma informowac o niepewnosci, a nie zaslaniac mapy. */
.accuracy-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(150, 160, 170, 0.18);
  border: 1px solid rgba(190, 200, 210, 0.45);
  pointer-events: none;
}

/* TASK-155: lista grup, do ktorych naleze (do czterech). Aktywna - ta, w
   ktorej akurat jade - jest wyroznieniem, reszta to jedno dotkniecie od
   przelaczenia. */
.group-rooms-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 4px 0;
}

.group-rooms-title {
  margin: 0;
  color: #b6c2d1;
  font-size: 13px;
}

.group-room-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.group-room-switch {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 52px;
  padding: 8px 14px;
  border: 1px solid #2c3644;
  border-radius: 10px;
  background: #161d27;
  color: #e6edf5;
  cursor: pointer;
}

.group-room-active .group-room-switch {
  border-color: #26a69a;
  background: #14231f;
}

.group-room-switch[disabled] {
  cursor: default;
  opacity: 1;
}

.group-room-kod {
  font-family: ui-monospace, 'Roboto Mono', 'DejaVu Sans Mono', monospace;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 3px;
}

.group-room-stan {
  font-size: 13px;
  color: #9fb0c3;
}

.group-room-active .group-room-stan {
  color: #4db6ac;
  font-weight: 700;
}

.group-room-leave {
  min-width: 48px;
  border: 1px solid #5a2c2c;
  border-radius: 10px;
  background: #2a1a1a;
  color: #ff8a80;
  font-size: 16px;
  cursor: pointer;
}

/* Uczestnik jadacy w innej swojej grupie - obecny, ale nie na tej mapie. */
.group-panel-elsewhere .group-panel-meta {
  color: #9fb0c3;
  font-style: italic;
}

/* TASK-156: WIADOMOSC PRZYCHODZACA (wersja wewnatrz aplikacji).
   Uklad ustalony z uzytkownikiem: w POZIOMIE przy LEWEJ krawedzi na jedna
   trzecia szerokosci, w PIONIE u GORY na jedna trzecia wysokosci - w obu
   przypadkach strzalka kierunku zostaje widoczna. Biale tlo, czerwony napis,
   znak ostrzegawczy: ma rzucac sie w oczy przy jednym spojrzeniu.
   `pointer-events: none` - komunikat nie lapie dotkniec, zeby kierowca nie
   trafil w niego zamiast w mape; znika sam po szesciu sekundach. */
/* ZNALEZIONE NA URZADZENIU: `position: absolute` wiazalo okno z kontenerem
   mapy, wiec na pulpicie (mala mini-mapa) komunikat byl PRZYCINANY i widac
   bylo sam bialy prostokat bez tekstu. `fixed` wiaze go z ekranem - tam, gdzie
   ma byc niezaleznie od tego, gdzie akurat stoi mapa. */
.group-msg-incoming {
  position: fixed;
  z-index: 1200;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 14px 18px;
  border: 4px solid #d50000;
  border-radius: 18px;
  /* 90% krycia (10% przezroczystosci) - zgodnie z ustaleniem: pod komunikatem
     widac zarys mapy, ale napis zostaje w pelni czytelny. */
  background: rgba(255, 255, 255, 0.9);
  pointer-events: none;
}

/* ZNALEZIONE NA URZADZENIU: okno bylo widoczne, mimo ze JS ustawial `hidden`.
   Atrybut `hidden` chowa element regula PRZEGLADARKI (`display: none`), a
   `display: flex` z reguly WYZEJ jest regula autora - i autor wygrywa. Bez tej
   linii przez natywne okno przeswitywal drugi, pusty prostokat ze znakiem
   ostrzegawczym (widoczny na zrzucie jako "zdublowany trojkat").
   To nie pierwszy raz w tym projekcie - patrz .map-close-btn[hidden] wyzej. */
.group-msg-incoming[hidden] {
  display: none;
}

/* PION: u gory, na calej szerokosci, jedna trzecia wysokosci. */
@media (orientation: portrait) {
  .group-msg-incoming {
    left: 10px;
    right: 10px;
    top: max(10px, max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
    height: 33vh;
  }
}

/* POZIOM: przy lewej krawedzi, jedna trzecia szerokosci, wysrodkowane pionowo. */
/* POZIOM: przy lewej krawedzi, jedna trzecia szerokosci - ale PRAWIE PELNA
   WYSOKOSC (zgloszenie po pierwszym tescie: "niech zaslania nie tylko jedna
   trzecia szerokosci, ale i prawie pelna wysokosc"). */
@media (orientation: landscape) {
  .group-msg-incoming {
    left: calc(10px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
    top: 50%;
    transform: translateY(-50%);
    width: 33vw;
    height: 88vh;
  }
}

/* Napisy maja WYPELNIAC okno i byc czytelne zza kierownicy - stad rozmiary
   liczone z wielkosci okna (vmin), a nie stale w pikselach. */
.group-msg-sign {
  font-size: clamp(38px, 7vmin, 72px);
  line-height: 1;
  color: #d50000;
}

.group-msg-incoming-text {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #d50000;
  font-size: clamp(30px, 7.5vmin, 76px);
  font-weight: 900;
  text-align: center;
  line-height: 1.1;
}

.group-msg-incoming-from {
  color: #b71c1c;
  font-weight: 800;
  font-size: clamp(18px, 3.4vmin, 38px);
}

/* TASK-156: okno wyboru tresci - cztery duze kafelki obok siebie. */
.group-msg-modal {
  position: absolute;
  inset: 0;
  z-index: 1300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: rgba(8, 12, 18, 0.82);
}

.group-msg-modal[hidden] {
  display: none;
}

.group-msg-box {
  width: 100%;
  max-width: 900px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.group-msg-box h3 {
  margin: 0;
  color: #e6edf5;
  font-size: 18px;
  text-align: center;
}

.group-msg-tiles {
  display: grid;
  /* Cztery obok siebie tam, gdzie sie mieszcza (poziom); na waskim ekranie
     dwa na dwa - kafelek musi zostac duzy, bo klika sie go w rekawicy. */
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

@media (max-width: 640px) {
  .group-msg-tiles {
    grid-template-columns: repeat(2, 1fr);
  }
}

.group-msg-tile {
  min-height: 96px;
  padding: 12px 10px;
  border: 3px solid #d50000;
  border-radius: 14px;
  background: #ffffff;
  color: #d50000;
  font-size: 19px;
  font-weight: 800;
  line-height: 1.15;
  cursor: pointer;
}

.group-msg-tile:active {
  transform: scale(0.96);
  background: #ffe9e9;
}

/* TASK-170: "duszek" pod palcem przy przeciąganiu linii trasy - pokazuje, gdzie
   powstanie nowy punkt pośredni. Kolor jak punkty pośrednie, żeby od razu było
   widać, czym się stanie po puszczeniu. */
.route-ghost-marker {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(255, 167, 38, 0.9);
  border: 3px solid #e65100;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
  pointer-events: none;
}

/* TASK-178: ikona stacji paliw na mapie. Wysoki kontrast na obu motywach -
   ciemny krążek z jasnym rysunkiem dystrybutora - bo to element, w który trzeba
   trafić palcem w ruchu, a mapa pod spodem bywa raz jasna, raz nocna. */
.fuel-marker {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(12, 16, 22, 0.9);
  border: 2px solid #ffb300;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}
.fuel-marker svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: #ffb300;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* TASK-191: punkt ładowania aut elektrycznych. Ten sam krążek i ten sam rozmiar
   co stacja paliw (jeden cel dla palca, jedna warstwa), ale ZIELONY zamiast
   bursztynowego i z błyskawicą zamiast dystrybutora - dwa niezależne sygnały
   naraz (kolor i kształt), żeby rozróżnienie działało też przy słońcu na
   ekranie i u osób słabiej rozróżniających barwy.
   Wypełnienie zamiast obrysu: błyskawica w skali 20 px czyta się jako plama,
   nie jako kreski. */
.charge-marker {
  border-color: #24c27a;
}
.charge-marker svg {
  fill: #24c27a;
  stroke: none;
}

/* TASK-178: przyciski "stacje paliw" i "pomiń punkt pośredni" w kolumnie ikon.
   Rozmiar, tło i zachowanie przy dotknięciu dziedziczą po .past-tracks-btn
   (dopisane do tamtych selektorów) - tutaj zostaje tylko to, co je odróżnia:
   rysunek sterowany currentColor i kolor stanu włączonego. */
.fuel-btn,
.skip-wp-btn {
  padding: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* ZGŁOSZENIE UŻYTKOWNIKA: przy wyłączonej warstwie dystrybutora "w ogóle nie
   było widać" - ikona zlewała się z ciemnym krążkiem. Przyczyna: regułę
   nadającą kolor rysunku ma tylko .past-tracks-btn, a .fuel-btn nie dostawał
   żadnego, więc dziedziczył niemal czarny kolor tekstu przycisku.
   Stan wyłączony jest teraz WYRAŹNIE widoczny, ale wyciszony - tak, żeby od
   razu było wiadomo, że warstwa nie działa. */
.fuel-btn {
  color: #93a0b4;
}
.fuel-btn svg,
.skip-wp-btn svg {
  width: 58%;
  height: 58%;
  display: block;
  margin: 0 auto;
}
.fuel-btn.fuel-on {
  color: #ffb300;
  border-color: #ffb300;
}
/* Pominięcie punktu to akcja jednorazowa, nie przełącznik - stąd stały,
   wyróżniający się kolor zamiast stanu wł/wył. */
.skip-wp-btn {
  color: #ffa726;
  border-color: #7a5b2a;
}

/* =====================================================================
   TASK-198: lista urządzeń Bluetooth w Ustawieniach.
   ===================================================================== */
.bt-trigger-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.bt-trigger-row small {
  display: block;
  margin-top: 2px;
  color: #8a94a3;
  font-size: 12px;
}

/* =====================================================================
   TASK-199: wyszukiwarka miejsca wprost z mapy (menu pineski -> "Szukaj").

   Panel leży NAD mapą, przy górnej krawędzi - a nie w miejscu dotknięcia,
   jak menu pineski. Powód jest praktyczny: zaraz po otwarciu wyskakuje
   klawiatura, która zjada dolną połowę ekranu, a lista podpowiedzi musi się
   zmieścić między polem a klawiaturą. Panel postawiony przy dolnej krawędzi
   znikałby pod nią.
   ===================================================================== */
.ride-search {
  position: absolute;
  z-index: 1200;
  top: calc(8px + max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: calc(8px + max(env(safe-area-inset-left, 0px), var(--sa-left, 0px)));
  right: calc(8px + max(env(safe-area-inset-right, 0px), var(--sa-right, 0px)));
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: 12px;
  border: 1px solid #2c3644;
  background: #232b38;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.55);
}

.ride-search[hidden] {
  display: none;
}

.ride-search-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ride-search-title {
  font-size: 15px;
  font-weight: 600;
  color: #e8ecf1;
}

.ride-search-close {
  min-width: var(--touch-control);
  min-height: var(--touch-control);
  border: none;
  background: none;
  color: #c3cad4;
  font-size: 20px;
  cursor: pointer;
}

.ride-search-roles {
  display: flex;
  gap: 6px;
}

.ride-search-role {
  flex: 1;
  /* TASK-86: obsługa w rękawicach motocyklowych. */
  min-height: var(--touch-control);
  padding: 8px 4px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #c3cad4;
  font-size: 14px;
  cursor: pointer;
}

.ride-search-role-active {
  border-color: #64b5f6;
  background: #24405c;
  color: #e8ecf1;
}

.ride-search-role:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Lista wyników na dashboardzie ma wcięcie z lewej (miejsce na ikonę pola) -
   tutaj żadnej ikony nie ma, więc wcięcie tylko zwężałoby wiersze. */
.ride-search .search-results {
  margin: 0;
  max-height: 40vh;
}

.ride-search-note {
  font-size: 12px;
  line-height: 1.35;
  color: #8a94a3;
}

.ride-search-note[hidden] {
  display: none;
}

/* =====================================================================
   TASK-202: dziennik zdarzen automatyki Bluetooth w Ustawieniach.
   Monospace i maly rozmiar, bo to surowe wiersze diagnostyczne
   (czas | rodzaj | urzadzenie | co zrobiono), a nie tekst do czytania ciagiem.
   ===================================================================== */
/* 0.157.0: wynik "Sprawdź połączenie" - jeden wiersz na każde połączenie aplikacji.
   Kolor tylko jako dodatek do znaku ✓ / ✕, żeby wynik dało się odczytać także przy
   słabym oświetleniu i bez rozróżniania kolorów. */
.connection-results {
  margin-top: 6px;
  padding: 8px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #10151c;
}

.connection-results[hidden] {
  display: none;
}

.connection-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 10px;
  padding: 4px 0;
  border-bottom: 1px solid #1c2430;
}

.connection-row:last-child {
  border-bottom: none;
}

.connection-name {
  font-size: 14px;
  color: #dbe1ea;
}

.connection-row.ok .connection-name {
  color: #7fd18a;
}

.connection-row.zle .connection-name {
  color: #ff8a80;
}

.connection-detail {
  font-size: 12px;
  color: #9aa5b5;
}

.bt-log {
  max-height: 40vh;
  overflow-y: auto;
  margin-top: 6px;
  padding: 8px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #10151c;
}

.bt-log[hidden] {
  display: none;
}

.bt-log-line {
  font-family: ui-monospace, "Roboto Mono", monospace;
  font-size: 11px;
  line-height: 1.5;
  color: #c3cad4;
  word-break: break-word;
  padding: 2px 0;
  border-bottom: 1px solid #1c2430;
}

.bt-log-line:last-child {
  border-bottom: none;
}

.bt-log-empty {
  font-size: 12px;
  line-height: 1.45;
  color: #ffcc80;
}

/* Ulubione nachodzace na inny znacznik zwijaja sie do samej gwiazdki
   (mapView.rozsunUlubione, etykietyMapy.ukladUlubionych). */
.favourite-marker.favourite-marker-kompakt {
  padding: 5px 7px;
}
.favourite-marker.favourite-marker-kompakt .favourite-marker-name {
  display: none;
}

/* 0.152.2: uczestnik grupy, ktory stoi od 5 min (obecnoscGrupy.czyZatrzymany) - dopisek
   "zatrzymal sie" w pigulce na mapie i w etykiecie przy krawedzi. Bursztynowy, zeby nie mylil
   sie z szarym "offline" (aplikacja kolegi dziala). */
.group-marker-postoj-tag,
.group-far-postoj {
  margin-left: 6px;
  font-weight: 700;
  color: #f5b841;
}

/* 0.153.0: Ustawienia -> Kolor wyznaczonej trasy (pelna paleta, kolorTrasyUstawienia.js). */
.kolor-trasy-naglowek {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.kolor-trasy-probka {
  flex: 0 0 72px;
  height: 12px;
  border-radius: 6px;
  border: 2px solid #f5f5f5;
}
.kolor-trasy-hex {
  font-size: 14px;
  font-weight: 700;
  color: #cfd6df;
}
.kolor-trasy-paleta {
  position: relative;
  height: 150px;
  border-radius: 10px;
  /* 0.185.1 (ZGLOSZENIE 25.09): "przewijam ekran w poziomie i nie moge przewinac, bo zaczynam
     wybierac kolor". Paleta jest WEZSZA niz menu (jest gdzie postawic palec obok) i - dopoki nie
     zostanie wlaczona dwukrotnym tapnieciem - przepuszcza przewijanie w pionie (touch-action). */
  width: 78%;
  max-width: 320px;
  margin: 0 auto;
  touch-action: pan-y;
  cursor: crosshair;
  /* w pionie jasnosc (95% u gory -> 5% u dolu, jak kolorTrasy.kolorZPalety), w poziomie barwa */
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.9) 100%),
    linear-gradient(to right, #ff0000 0%, #ffff00 16.67%, #00ff00 33.33%, #00ffff 50%, #0000ff 66.67%, #ff00ff 83.33%, #ff0000 100%);
}
/* Paleta wlaczona dwuklikiem: od teraz lapie ruch palca (wybor koloru), a nie przewijanie. */
.kolor-trasy-paleta.paleta-aktywna {
  touch-action: none;
  outline: 2px solid #64b5f6;
  outline-offset: 2px;
}

.kolor-trasy-paleta-podpis {
  font-size: 12px;
  color: #7c8899;
  text-align: center;
  margin: 4px 0 8px;
}

.kolor-trasy-znacznik {
  position: absolute;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  border: 3px solid #ffffff;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
.kolor-trasy-nasycenie {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 0;
  font-size: 14px;
}
.kolor-trasy-nasycenie input[type='range'] {
  flex: 1;
  height: 14px;
  border-radius: 7px;
  -webkit-appearance: none;
  appearance: none;
}
.kolor-trasy-opis {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  color: #9aa1ab;
  line-height: 1.4;
}

/* 0.154.0: rysunek ronda z duza cyfra zjazdu w miejscu strzalki manewru (src/rondo.js).
   Kolor drogi po rondzie = kolor strzalki (currentColor), cyfra biala w srodku pierscienia. */
.manoeuvre-arrow .rondo-svg {
  display: block;
  width: 88px;
  height: 88px;
}

/* 0.154.0: ZGLOSZENIE - w poziomie pasek podsumowania przejechanej trasy mial JEDEN rzad, czesc
   pozycji (np. nowe drogi) byla ucieta, a przesunac sie go nie dalo: bazowa karta ma
   `pointer-events: none`, wiec palec trafial w mape pod paskiem, a nie w pasek. Teraz pozycje
   zawijaja sie w kolejne rzedy (zwykle dwa; przy pelnej telemetrii trzy) i pasek rosnie w gore,
   az pokaze wszystko. Gdyby i 40% wysokosci ekranu nie wystarczylo - przewija sie palcem w pionie.
   Rzedy od gory (flex-start): przy wysrodkowaniu nadmiar uciekal NAD pasek, poza zasieg
   przewijania. Pion bez zmian (tam karta jest dwukolumnowa i miesci wszystko). */
@media (orientation: landscape) {
  .map-wrap .track-stats {
    flex-wrap: wrap;
    align-content: flex-start;
    row-gap: 2px;
    padding: 4px;
    max-height: 40vh;
    overflow-x: hidden;
    overflow-y: auto;
    pointer-events: auto;
    touch-action: pan-y;
    overscroll-behavior: contain;
  }

  .map-wrap .track-stats .track-stat {
    padding-top: 4px;
    padding-bottom: 4px;
  }

  /* 0.156.0: tablica kierunkowa w panelu manewru schodzi w poziomie do JEDNEJ linii
     kierunków - mapa jest wtedy niska, a panel i tak zajmuje sporą jej część. Numery dróg
     zostają w całości. */
  .road-dest {
    -webkit-line-clamp: 1;
  }
}

/* 0.155.0: edycja zapisanej trasy zaplanowanej - pasek nad formularzem planowania. */
.pasek-edycji-trasy {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 12px;
  border: 2px solid #ffa726;
  background: rgba(255, 167, 38, 0.12);
  color: inherit;
}

.pasek-edycji-tekst {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  line-height: 1.35;
}

.pasek-edycji-podpowiedz {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  opacity: 0.8;
}

.pasek-edycji-koniec {
  flex-shrink: 0;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid #ffa726;
  background: transparent;
  color: inherit;
  font-weight: 700;
}

/* 0.155.0: zaznaczanie tras na liscie zapisanych (usuwanie wielu naraz). Pole wyboru duze - do
   trafienia w rekawicy; pasek przyklejony u gory listy, zeby przy dlugiej liscie byl pod reka. */
.zaznaczanie-pasek {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 10px;
  padding: 8px 10px;
  border-radius: 12px;
  background: #1a212c;
  border: 1px solid #2c3644;
}

.zaznaczanie-wszystkie,
.zaznaczanie-usun {
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid #3a4658;
  background: #232c39;
  color: #e8ecf1;
  font-weight: 700;
  font-size: 15px;
}

.zaznaczanie-usun {
  margin-left: auto;
  background: #7f2020;
  border-color: #c62828;
  color: #ffffff;
}

.zaznaczanie-usun:disabled {
  opacity: 0.4;
}

/* 0.167.0: laczenie zaznaczonych przejazdow w jedna podroz - bezpieczne dzialanie (nic nie znika,
   powstaje nowa trasa), wiec ciemnozielony, jak "Wyznacz na nowo". */
.zaznaczanie-polacz {
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid #4caf50;
  background: #1b4d1f;
  color: #ffffff;
  font-weight: 700;
  font-size: 15px;
}

.zaznaczanie-polacz:disabled {
  opacity: 0.4;
}

.zaznaczanie-licznik {
  font-size: 15px;
  font-weight: 700;
  color: #e8ecf1;
}

.zaznacz-trase {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  margin: 0 8px 0 0;
  accent-color: #e53935;
}

.saved-item.zaznaczony {
  outline: 2px solid #e53935;
  outline-offset: -2px;
}

/* 0.155.0: numerowane punkty posrednie w podgladzie zapisanej trasy zaplanowanej (mapView.pokazPunktyTrasy). */
.punkt-trasy-podglad {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  cursor: pointer;
}

/* 0.177.1: okno zamykania po przejezdzie - komunikat o NIEZAPISANEJ trasie. Wiekszy i w kolorze
   ostrzezenia, bo uzytkownik ma na jego przeczytanie kilka sekund i jest to jedyne miejsce, gdzie
   powod sie pojawia (pasek statusu znika razem z zamykana aplikacja). */
#autoCloseMessage {
  font-size: 14px;
  line-height: 1.45;
}

#autoCloseMessage.auto-close-warning {
  color: #d9534f;
  font-weight: 600;
  font-size: 15px;
}

/* 0.188.0: okno zamknietego odcinka (formularz zapisu albo szczegoly). Ten sam uklad co okno
   wiadomosci grupy. [hidden] jawnie - `display: flex` z tej reguly przebilby atrybut hidden
   (TASK-157: tak powstal "drugi, pusty prostokat" w oknie wiadomosci). */
.zamkniecie-modal {
  position: absolute;
  inset: 0;
  z-index: 1300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: rgba(8, 12, 18, 0.82);
}

.zamkniecie-modal[hidden],
.zamkniecie-formularz[hidden],
.zamkniecie-przyciski .action-btn[hidden] {
  display: none;
}

.zamkniecie-box {
  width: 100%;
  max-width: 520px;
  max-height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  border-radius: 14px;
  background: #1b2430;
  border: 2px solid #e53935;
}

.zamkniecie-box h3 {
  margin: 0;
  color: #e6edf5;
  font-size: 18px;
  text-align: center;
}

.zamkniecie-info {
  margin: 0;
  color: #cfd8e3;
  font-size: 15px;
  line-height: 1.45;
  white-space: pre-line;
}

.zamkniecie-formularz {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.zamkniecie-etykieta {
  color: #9fb0c3;
  font-size: 14px;
}

.zamkniecie-pole {
  width: 100%;
  box-sizing: border-box;
  padding: 12px;
  border-radius: 10px;
  border: 1px solid #3a4a5c;
  background: #0f1620;
  color: #e6edf5;
  font-size: 16px;
}

.zamkniecie-pojazdy {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.zamkniecie-pojazd {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 10px;
  border-radius: 10px;
  background: #0f1620;
  color: #e6edf5;
  font-size: 15px;
}

.zamkniecie-pojazd input {
  width: 22px;
  height: 22px;
}

.zamkniecie-przyciski {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

@media (max-width: 380px) {
  .zamkniecie-pojazdy {
    grid-template-columns: 1fr;
  }
}

/* 0.200.0: w poziomie tabela jest waskim paskiem obok przycisku (TASK-135) - bez zwijania. */
@media (orientation: landscape) {
  .map-wrap .track-stats.zwiniete {
    display: flex;
  }

  .track-stats-toggle {
    display: none;
  }
}

/* 0.204.0: wiersz "Czas bez jazdy" chowany atrybutem hidden - .settings-row ma display:flex,
   ktory bez tej reguly przykrywal hidden (wiersz byl widoczny przy kazdym wariancie). */
#koniecPrzejazduCzasWiersz[hidden] {
  display: none;
}

/* 0.205.0: zakladki Ustawien (screens/zakladkiUstawien.js) - duze przyciski do trafienia w rekawicy. */
.settings-zakladki {
  display: flex;
  gap: 4px;
  margin: 0 0 10px;
}
.settings-zakladka {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  padding: 6px 2px;
  border-radius: 8px;
  border: 1px solid #2c3644;
  background: #1a212c;
  color: #c9d2dc;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.settings-zakladka.aktywna {
  background: #2e7d32;
  border-color: #2e7d32;
  color: #fff;
}
.settings-section.poza-zakladka {
  display: none !important;
}
.settings-section.pierwsza-w-zakladce {
  border-top: none;
}

/* 0.206.0: kosz przejazdow (savedRoutesScreen - renderKosz). */
.kosz-card {
  opacity: 0.85;
}
.kosz-akcje {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.kosz-akcje .action-btn {
  flex: 1 1 0;
  min-height: 44px;
}
/* Kafelek kosza: dane na gorze, przyciski pod spodem (.saved-item uklada elementy w rzedzie). */
.saved-item.kosz-item {
  display: block;
}

/* 0.207.0: rozmowa glosowa w pokoju - przycisk przy uczestniku i pasek trwajacej rozmowy. */
.group-msg-tile.group-msg-rozmowa {
  grid-column: 1 / -1;
  min-height: 64px;
  border-color: #2e7d32;
  color: #fff;
  background: #2e7d32;
}
.group-msg-tile.group-msg-rozmowa:active {
  background: #1b5e20;
}
.rozmowa-pasek {
  position: fixed;
  top: calc(8px + max(env(safe-area-inset-top, 0px), var(--sa-top, 0px)));
  left: 50%;
  transform: translateX(-50%);
  z-index: 9000;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 16px);
  padding: 6px 6px 6px 14px;
  border: 2px solid #2e7d32;
  border-radius: 16px;
  background: rgba(18, 24, 33, 0.94);
  color: #fff;
  font-weight: 700;
  font-size: 16px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
}
.rozmowa-pasek[hidden] {
  display: none;
}
.rozmowa-tekst {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.rozmowa-btn {
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 10px;
  background: #455a64;
  color: #fff;
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
}
.rozmowa-btn-koniec {
  background: #c62828;
}

/* 0.207.0: okno "Wyslij do" (wiadomosci i Rozmawiaj) na CALYM ekranie - wewnatrz malej mapy ekranu
   glownego bylo przyciete (widac bylo czesc kafelkow), a z przyciskiem Rozmawiaj jest jeszcze wyzsze. */
.group-msg-modal {
  position: fixed;
  z-index: 8500;
  overflow-y: auto;
}

/* 0.209.0: nakladka predkosci w podgladzie przejazdu - przycisk w gornym pasku i legenda. */
.track-viewer-btn.track-viewer-btn-wlaczony {
  background: #f9a825;
  color: #111;
}

.track-viewer-btn.track-viewer-btn-nieaktywny {
  opacity: 0.45;
}

.predkosci-legenda {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  padding: 6px 8px;
  border-radius: 8px;
  background: rgba(20, 26, 36, 0.82);
  color: #fff;
  font-size: 12px;
  line-height: 1.25;
  pointer-events: none;
}

.predkosci-legenda[hidden] {
  display: none;
}

.predkosci-legenda-tytul {
  font-weight: 700;
  margin-bottom: 3px;
  text-align: center;
}

.predkosci-legenda-wiersz {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.predkosci-legenda-wiersz span {
  display: inline-block;
  width: 14px;
  height: 8px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.5);
}

/* 0.210.0: okres rozowego sladu - kolko przytrzymania (4 s), napis okresu na przycisku i okno wyboru. */
.past-tracks-btn {
  position: relative;
}

.slad-postep {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(rgba(249, 168, 37, 0.95) calc(var(--postep, 0) * 360deg), transparent 0);
  -webkit-mask: radial-gradient(circle, transparent 60%, #000 62%);
  mask: radial-gradient(circle, transparent 60%, #000 62%);
  opacity: 0;
  pointer-events: none;
}

.past-tracks-btn.slad-przytrzymanie .slad-postep {
  opacity: 1;
}

.slad-okres {
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  padding: 0 4px;
  border-radius: 6px;
  background: #f9a825;
  color: #111;
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  white-space: nowrap;
  pointer-events: none;
}

.slad-okres[hidden] {
  display: none;
}

.okres-sladow-box {
  max-width: 420px;
  max-height: 88vh;
  overflow-y: auto;
}

.modal-box p.okres-sladow-opis {
  margin-bottom: 12px;
  font-size: 14px;
  color: #b8c2d0;
}

.okres-opcje,
.okres-lata {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.okres-opcje .okres-opcja {
  flex: 1 1 45%;
}

.okres-lata .okres-opcja {
  flex: 0 1 auto;
  min-width: 72px;
}

.okres-opcja.okres-opcja-aktywna {
  background: #f9a825;
  color: #111;
  border-color: #f9a825;
}

.okres-naglowek {
  margin: 14px 0 6px;
  font-weight: 700;
  color: #dbe1ea;
}

.okres-zakres {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.okres-zakres label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #dbe1ea;
}

.okres-zakres input[type='date'] {
  min-height: 42px;
  padding: 4px 6px;
  border-radius: 8px;
  border: 1px solid #5a6678;
  background: #1c2430;
  color: #fff;
  font-size: 15px;
  color-scheme: dark;
}

.modal-box p.okres-blad {
  margin: 8px 0 0;
  color: #ff5252;
}

/* 0.210.1: "Wstecz" Zapisanych tras w gornym pasku, obok "Zamknij aplikacje" - ta sama wysokosc. */
.topbar-back {
  min-height: 40px;
  padding: 6px 12px;
  font-size: clamp(12px, 3.4vw, 14px);
  white-space: nowrap;
}

.topbar-back[hidden] {
  display: none;
}

/* 0.210.1: w pionie pasek nie miesci naraz tytulu, INFO, Ustawien, "Wstecz" i "Zamknij aplikacje"
   (przy 360 px "Wstecz" nachodzil na Ustawienia). Na ekranie z "Wstecz" INFO i Ustawienia ustepuja -
   sa na ekranie glownym. */
@media (max-width: 479px) {
  .topbar.topbar-z-wstecz .topbar-center {
    display: none;
  }

  /* Bez srodkowej komorki prawa grupa wskoczylaby w srodkowa kolumne siatki. */
  .topbar.topbar-z-wstecz .topbar-right {
    grid-column: 3;
  }
}

/* 0.210.2: pobrany region w Mapach offline - jasniejsze tlo, tym jasniejsze, im pelniejsza pobrana wersja. */
.saved-item.offline-pobrane-low {
  background: #2e3746;
  border-color: #3b4657;
}

.saved-item.offline-pobrane-medium {
  background: #3a4455;
  border-color: #4a5568;
}

.saved-item.offline-pobrane-full {
  background: #4a5568;
  border-color: #5c687c;
}
