/* Fabryka Atletów — nadpisania Vuexy. Ładowane po core.css. */

:root,
[data-bs-theme='light'] {
  --bs-primary: #fd8202;
  --bs-primary-rgb: 253, 130, 2;
  --bs-primary-contrast: #16161d;
  --bs-primary-bg-subtle: #fff1e0;
  --bs-primary-border-subtle: #ffd6a8;
  --bs-primary-text-emphasis: #8a4600;
  /* Czysty pomarańcz na białym daje 2,3:1 — linki i tekst schodzą o dwa tony. */
  --bs-link-color: #a85500;
  --bs-link-color-rgb: 168, 85, 0;
  --bs-link-hover-color: #8a4600;
}

[data-bs-theme='dark'] {
  --bs-primary: #fd8202;
  --bs-primary-rgb: 253, 130, 2;
  --bs-primary-contrast: #16161d;
  --bs-primary-bg-subtle: #3d2510;
  --bs-primary-border-subtle: #6b3f13;
  --bs-primary-text-emphasis: #ffb562;
  --bs-link-color: #fd9b34;
  --bs-link-color-rgb: 253, 155, 52;
  --bs-link-hover-color: #ffb562;
}

[data-bs-theme='light'] .text-primary {
  color: #a85500 !important;
}

/* Sygnet w sidebarze. */
.app-brand-logo img {
  width: 34px;
  height: auto;
}

/* Cztery reguły z demo.css szablonu — bez nich logo klei się do górnej krawędzi menu,
   a treść wchodzi pod przypięty navbar. Reszta demo.css dotyczy stron przykładowych. */
.menu .app-brand.demo {
  height: 64px;
}
.app-brand-text.demo {
  font-size: 1.375rem;
}
.layout-navbar-fixed .layout-wrapper:not(.layout-without-menu) .layout-page {
  padding-top: 64px !important;
}
.layout-navbar-fixed .layout-wrapper:not(.layout-horizontal):not(.layout-without-menu) .layout-page {
  padding-top: 72px !important;
}

/* Awatar we flexowym wierszu ściska się do owalu, gdy tekst obok jest długi. */
.avatar,
.avatar-initial {
  flex-shrink: 0;
}

/* Ekran obecności: nieobecni gasną, żeby wzrok trafiał w to, co odbiega od normy. */
.obecnosc-wiersz:has(input[value='nieobecny']:checked) {
  opacity: 0.55;
}
.obecnosc-wiersz .obecnosc-stany {
  margin-inline-start: auto;
}
/* Na telefonie przyciski stanu idą pod nazwisko i biorą całą szerokość — trener celuje kciukiem. */
@media (max-width: 575.98px) {
  .obecnosc-wiersz .obecnosc-stany {
    inline-size: 100%;
  }
  .obecnosc-wiersz .obecnosc-stany .btn {
    flex: 1;
  }
}

/* --------------------------------------------------- wybrany stan obecności

   Domyślny `btn-outline` z szablonu daje po zaznaczeniu ledwie widoczne tło — na sali,
   na telefonie, w słońcu, nie da się jednym rzutem oka sprawdzić, kogo już odhaczono
   (Rafał, 26.08.2026). Wybrany stan dostaje więc pełne wypełnienie, grubszą czcionkę
   i obwódkę odcinającą go od sąsiadów.

   Kolor nie jest jedynym nośnikiem: zaznaczony przycisk jako jedyny pokazuje nazwę stanu
   także na wąskim ekranie, gdzie pozostałe zostają samą ikoną. */
.obecnosc-stany .btn-check:checked + .btn {
  font-weight: 600;
  box-shadow: inset 0 0 0 2px rgb(0 0 0 / 0.25);
}

.obecnosc-stany .btn-check:checked + .btn-outline-primary {
  color: #fff;
  background-color: var(--bs-primary);
  border-color: var(--bs-primary);
}

.obecnosc-stany .btn-check:checked + .btn-outline-success {
  color: #fff;
  background-color: var(--bs-success);
  border-color: var(--bs-success);
}

.obecnosc-stany .btn-check:checked + .btn-outline-warning {
  color: #000;
  background-color: var(--bs-warning);
  border-color: var(--bs-warning);
}

.obecnosc-stany .btn-check:checked + .btn-outline-secondary {
  color: #fff;
  background-color: var(--bs-secondary);
  border-color: var(--bs-secondary);
}

@media (max-width: 575.98px) {
  .obecnosc-stany .btn-check:checked + .btn span {
    display: inline !important;
  }
}

/* W trakcie zapisu w tle grupa gaśnie — bez tego dwa szybkie kliknięcia wyglądają tak samo
   jak jedno, które nie doszło. */
.obecnosc-stany.jest-zapis {
  opacity: 0.6;
  pointer-events: none;
}

/* ==========================================================================
   Kalendarz Iron Queens

   Do 992 px: pasek dni i jeden dzień pod nim. Powyżej: wszystkie dni obok siebie.
   Bez JavaScriptu widać wszystkie dni pod sobą — skrypt dokłada `iq-js` i dopiero
   wtedy chowamy niewybrane.
   ========================================================================== */

.iq-pasek {
  display: flex;
  gap: 0.5rem;
  padding: 0 1.25rem 0.75rem;
  overflow-x: auto;
  /* Suwak jest widoczny, bo od 28.08.2026 pasek sięga pół roku i bez niego nic nie mówiło,
     że dni jest więcej niż widać. Cienki, bo to nawigacja, nie treść. */
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
}

.iq-pasek::-webkit-scrollbar {
  block-size: 6px;
}

.iq-pasek::-webkit-scrollbar-thumb {
  background: var(--bs-border-color);
  border-radius: 3px;
}

.iq-chip {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  gap: 0.125rem;
  align-items: center;
  /* Mieści „15.09" i licznik „12/18" — na 3.25rem, gdy w kafelku stał sam numer dnia,
     data łamała się na dwie linie i pasek dni robił się dwa razy wyższy. */
  inline-size: 4.25rem;
  padding: 0.5rem 0;
  text-decoration: none;
  color: var(--bs-body-color);
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  scroll-snap-align: center;
}

.iq-chip:hover {
  border-color: var(--bs-primary);
  color: var(--bs-body-color);
}

.iq-chip.is-wybrany {
  color: var(--bs-primary-contrast);
  background: var(--bs-primary);
  border-color: var(--bs-primary);
}

/* Dzień, który już minął, zostaje w pasku — obecność odznacza się po zajęciach. */
.iq-chip.is-minelo {
  opacity: 0.6;
}

/* Kafelek „wstecz" i „dziś": ta sama bryła co dni, ale bez numeru, żeby nie udawał daty. */
.iq-chip--nawigacja {
  justify-content: center;
  color: var(--bs-secondary-color);
  border-style: dashed;
}

.iq-chip__dzien {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.iq-chip__data {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Licznik zapisanych: trener widzi z paska, gdzie będzie tłoczno, a gdzie pusto. */
.iq-chip__licznik {
  font-size: 0.6875rem;
  opacity: 0.75;
}

.iq-dzien__tytul {
  margin-block-end: 0.5rem;
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bs-secondary-color);
}

.iq-termin {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  padding: 0.75rem;
  text-decoration: none;
  color: var(--bs-body-color);
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
}

.iq-termin + .iq-termin {
  margin-block-start: 0.375rem;
}

.iq-termin:hover {
  border-color: var(--bs-primary);
  color: var(--bs-body-color);
}

.iq-termin__godzina {
  flex: 0 0 3.25rem;
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.iq-termin__nazwa {
  flex: 1 1 auto;
  min-inline-size: 0;
  font-weight: 500;
}

.iq-termin__miejsca {
  flex: 0 0 auto;
  font-size: 0.8125rem;
}

/* Odwołany termin zostaje w kalendarzu — prowadzący ma widzieć, że tych zajęć nie ma.
   Przygaszony, ale klikalny: pod nim siedzi ślad operacji i cofnięcie zmiany. */
.iq-termin.is-odwolany .iq-termin__godzina,
.iq-termin.is-odwolany .iq-termin__nazwa {
  text-decoration: line-through;
  color: var(--bs-secondary-color);
}

/* Jeden dzień naraz na każdej szerokości. Siatka wszystkich dni obok siebie działała
   na desktopie, ale dawała dwa różne ekrany do nauczenia się — a prowadząca patrzy raz
   na telefon na sali, raz na laptopa w domu (decyzja Rafała, 21.08.2026). */
.iq-js .iq-dzien {
  display: none;
}

.iq-js .iq-dzien.is-wybrany {
  display: block;
}

.iq-dzien--dzis .iq-dzien__tytul {
  color: var(--bs-primary);
}

@media (min-width: 992px) {
  /* Na szerokim ekranie wiersz zajęć nie rozjeżdża się na całą stronę — czytelnie jest
     wtedy, gdy godzina, nazwa i licznik są blisko siebie. */
  .iq-kalendarz {
    max-inline-size: 46rem;
  }
}

/* Na wąskim ekranie nazwa zajęć i liczba zapisanych schodzą pod siebie — inaczej
   „nikt się nie zapisał" wypycha godzinę poza kartę. */
@media (max-width: 575.98px) {
  .iq-termin {
    flex-wrap: wrap;
  }

  .iq-termin__nazwa {
    flex: 1 1 60%;
  }

  /* `flex-shrink: 1`, nie `0`: przy podstawie 100% i marginesie 4 rem element z zablokowanym
     kurczeniem był szerszy od linii o cały ten margines i **rozpychał stronę w poziomie**.
     Poziomy pasek przewijania zjadał wtedy dolną krawędź okna, przez co dolna nawigacja
     wyglądała na uciętą w połowie (zgłoszone 27.08.2026) — jeden objaw, dwa różne skutki. */
  .iq-termin__miejsca {
    flex: 1 1 100%;
    min-inline-size: 0;
    margin-inline-start: 4rem;
  }

  /* Strzałka schodzi: cały wiersz jest odnośnikiem, a w zawiniętym układzie zajmowała
     osobną linijkę i rozciągała kartę o 20 px. */
  .iq-termin > i {
    display: none;
  }
}

/* Pasek demo — ma być widoczny, żeby nikt nie wziął tych danych za prawdziwe. */
.fa-demo-bar {
  background: var(--bs-primary-bg-subtle);
  border: 1px solid var(--bs-primary-border-subtle);
  color: var(--bs-primary-text-emphasis);
  font-size: 0.8125rem;
}

/* ==========================================================================
   Tabele na telefonie: kafelki zamiast poziomego przewijania

   Do 768 px wiersz przestaje być wierszem. Powód jest praktyczny, nie estetyczny:
   `.table-responsive` przesuwa się w bok, więc żeby zobaczyć status, trzeba stracić
   z oczu nazwisko — przy siedmiu kolumnach to dwa, trzy przesunięcia na każdy wiersz,
   a panel otwiera się na telefonie w sali, nie przy biurku.

   Nazwy kolumn dokłada `fa-crm.js` do `data-etykieta`, bo nagłówek tabeli tu znika.
   ========================================================================== */

@media (max-width: 767.98px) {
  /* Motyw daje karcie 1,5 rem paddingu z każdej strony. Na telefonie to prawie 50 px zjedzone
     z szerokości ekranu, zanim pokaże się cokolwiek — treść robi się węższa, niż musi, a nagłówek
     karty odjeżdża od danych, których dotyczy. */
  .card-header,
  .card-body {
    padding: 1rem;
  }

  /* `pb-0` na `.card-body` trzyma opis tuż nad tabelą i na desktopie ma rację: tabela niesie
     własny padding w komórkach. W kafelkach tego paddingu nie ma, więc opis kleił się do
     pierwszego kafelka. Odstęp dokładamy pod spodem, zamiast przebijać `!important` z utility. */
  .card-body + .table-responsive {
    margin-block-start: 1rem;
  }

  /* Nie ma czego przewijać, gdy nic nie wystaje poza szerokość. */
  .table-responsive {
    overflow-x: visible;
  }

  .table thead {
    display: none;
  }

  .table,
  .table tbody,
  .table td {
    display: block;
    inline-size: auto;
  }

  /* `:not([hidden])` niesie wyszukiwarkę nad tabelą: chowa ona wiersze atrybutem `hidden`,
     a `display: block` przebiłoby to i wróciłyby wszystkie. */
  .table tbody tr:not([hidden]) {
    display: block;
    padding: 0.875rem 1rem;
    border: 1px solid var(--bs-border-color);
  }

  .table tbody tr:not([hidden]) ~ tr:not([hidden]) {
    margin-block-start: 0.75rem;
  }

  .table td {
    padding: 0.25rem 0;
    border: 0;
  }

  /* Etykieta i wartość obok siebie: kafelek czyta się wtedy jak lista „nazwa — wartość”,
     a nie jak drugi rząd danych bez nagłówka. */
  .table td[data-etykieta] {
    display: grid;
    grid-template-columns: minmax(0, 7rem) minmax(0, 1fr);
    gap: 0.75rem;
    align-items: baseline;
    /* Bez tego odznaka statusu rozciąga się na całą kolumnę: element gridu domyślnie
       wypełnia komórkę, a `.badge` w tabeli był szeroki na własną treść. */
    justify-items: start;
  }

  .table td[data-etykieta]::before {
    content: attr(data-etykieta);
    color: var(--bs-secondary-color);
    font-size: 0.8125rem;
  }

  /* Komórka bywa dwuelementowa: nazwisko i data urodzenia pod nim, telefon i e-mail jeden
     pod drugim. Bez tego drugi element trafia w następny rząd siatki, czyli **pod etykietę**,
     i wygląda jak osobna dana bez nazwy. Wszystkie dzieci idą więc do kolumny wartości
     i układają się w niej pionowo.

     `min-inline-size: 0` jest tu obowiązkowe: element gridu i flexa domyślnie nie kurczy się
     poniżej swojej treści, więc długi e-mail rozpychał kafelek poza ekran zamiast się złamać. */
  .table td[data-etykieta] > * {
    grid-column: 2;
    min-inline-size: 0;
    overflow-wrap: anywhere;
  }

  /* Pierwsza komórka wiersza niesie to, co identyfikuje rekord — nazwisko, numer zamówienia,
     datę zajęć. W kafelku jest więc **nagłówkiem**, nie kolejną parą „etykieta: wartość”:
     bez tego kafelek nie ma się o co zaczepić wzrokiem i czyta się jak lista pól.
     Etykieta znika (jest oczywista z treści), tekst idzie na pełną szerokość, a hairline
     oddziela nagłówek od danych pod nim. */
  .table tbody td:first-child[data-etykieta] {
    display: block;
    padding-block-end: 0.625rem;
    margin-block-end: 0.5rem;
    border-block-end: 1px solid var(--bs-border-color);
    font-size: 1.0625rem;
    line-height: 1.35;
  }

  .table tbody td:first-child[data-etykieta]::before {
    content: none;
  }

  /* Nagłówek kafelka nie musi świecić kolorem linku: cały kafelek dotyczy tej osoby, więc
     kolor niczego tu nie rozróżnia, a nad pomarańczowym telefonem i e-mailem robił trzeci
     pomarańczowy wiersz z rzędu. Waga pisma wystarczy, cel dotknięcia zostaje ten sam. */
  .table tbody td:first-child[data-etykieta] a {
    color: var(--bs-body-color);
    font-weight: 600;
  }

  /* Wyrównanie do prawej albo do środka miało sens w kolumnie. Kolumny nie ma, więc kwota
     odjeżdżała na prawą krawędź kafelka razem ze swoją etykietą.

     `!important`, bo klasy wyrównania Bootstrapa też je mają — inaczej ta reguła przegrywa.
     Dotyczy wyłącznie komórek z etykietą: kolumna przycisków zostaje przy prawej krawędzi,
     gdzie w kafelku wygląda jak stopka, a nie jak zgubiona dana. */
  .table td[data-etykieta].text-end,
  .table td[data-etykieta].text-center {
    text-align: start !important;
  }

  .table td.jest-pusta {
    display: none;
  }

  /* Komórka bez nagłówka to zwykle kolumna z przyciskami — w kafelku staje na końcu,
     jak stopka, i nie udaje danych. */
  .table td:not([data-etykieta]) {
    margin-block-start: 0.5rem;
  }

  /* Szerokości z tabeli (np. `max-width: 320px` na nazwie produktu) w kafelku tylko ścieśniają
     tekst. Nadpisujemy stylem wprost, bo to też jest styl wprost. */
  .table td[style] {
    max-inline-size: none !important;
  }

  /* Wielokropek zamiast reszty nazwy jest kompromisem kolumny: tam nie było miejsca na
     „Zajęcia grupowe w Studiu, subskrypcja miesięczna". W kafelku miejsce jest, więc nazwa
     ma się zawinąć, a nie urwać. */
  .table td.text-truncate {
    overflow: visible;
    white-space: normal;
    text-overflow: clip;
  }

  /* Wiersz-komunikat („Nie ma jeszcze żadnej listy”) zostaje jednym akapitem. */
  .table td[colspan] {
    padding: 0;
  }
}

/* ---------------------------------------------------------------- dolny pasek (telefon)

   Nawigacja pod kciukiem zamiast hamburgera w górnym rogu (27.08.2026). Panel otwiera się
   w hali, jedną ręką, więc cztery pozycje, po które trener sięga najczęściej, stoją na dole.
   Powyżej 768 px pasek znika i wraca zwykłe menu boczne — tam ekran jest szeroki, a wskaźnik
   nie jest kciukiem. */

.fa-pasek {
  display: none;
}

@media (max-width: 767.98px) {
  .fa-pasek {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 1030;
    display: flex;
    background: var(--bs-body-bg);
    border-block-start: 1px solid var(--bs-border-color);
    /* Pasek gestu w iOS i przyciski Androida zjadają dolną krawędź — bez tego ostatni
       rząd ikon ląduje pod nimi i pierwsze dotknięcie trafia w system, nie w panel. */
    padding-block-end: env(safe-area-inset-bottom);
  }

  .fa-pasek__poz {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.125rem;
    /* 3,25rem plus etykieta daje ponad 48 px wysokości celu — tyle, ile potrzeba,
       żeby trafiać bez celowania. */
    min-block-size: 3.25rem;
    padding-block: 0.4rem;
    color: var(--bs-secondary-color);
    text-decoration: none;
    font-size: 0.6875rem;
    line-height: 1.2;
  }

  .fa-pasek__poz i {
    font-size: 1.375rem;
  }

  .fa-pasek__poz--aktywna {
    color: var(--bs-primary);
  }

  /* Kreska nad aktywną pozycją, nie samo przebarwienie ikony: w słońcu na hali różnica
     koloru bywa niewidoczna, kształt widać zawsze. */
  .fa-pasek__poz--aktywna::before {
    content: '';
    position: absolute;
    inset-block-start: 0;
    inline-size: 2.25rem;
    block-size: 2px;
    border-radius: 0 0 2px 2px;
    background: var(--bs-primary);
  }

  .fa-pasek__poz {
    position: relative;
  }

  /* Miejsce pod pasek, żeby nie zasłaniał końca treści. Bez tego ostatni wiersz listy i przycisk
     pod nim chowają się za paskiem i nie da się ich dotknąć (zgłoszone 27.08.2026).

     ⚠️ **`!important` jest tu konieczne, nie wygodne.** Szablon trzyma
     `.container-p-y:not([class^="pb-"], [class*=" pb-"]) { padding-bottom: 1.5rem !important }`,
     więc żadna specyficzność tego nie przebije — sprawdzone po kolei: dwie klasy, trzy klasy
     i wstrzyknięty `<style>` dawały ten sam wynik. Przeciw `!important` w cudzym arkuszu
     działa wyłącznie `!important` przy wyższej specyficzności.

     Nie na `.content-wrapper`: tam szablon wstrzykuje `padding-bottom` stylem inline, więc
     reguła z pliku i tak by przegrała. Kontener treści jest nasz i nikt go skryptem nie dotyka. */
  .content-wrapper > .container-xxl.container-p-y {
    padding-bottom: 4.5rem !important;
  }

  /* Niewidzialny pasek szablonu do otwierania menu gestem od lewej krawędzi. Ma `z-index: 1036`,
     czyli **więcej niż nasz pasek** (1030), i pełną wysokość okna — zasłaniał przez to lewe 40 px
     dolnej nawigacji, a tam stoi pierwsza pozycja (zgłoszone 27.08.2026).

     Skracamy go zamiast obniżać `z-index`, bo kolejność warstw jest tu poprawna: gest ma mieć
     pierwszeństwo nad treścią. Nie ma go mieć nad przyciskami, więc po prostu kończymy go
     nad paskiem — swipe działa na całej reszcie wysokości. */
  .drag-target {
    block-size: calc(100% - 4rem);
  }

  /* Stopka „CRM Fabryka Atletów / Kokos Media” na telefonie nie niesie nic, a zabiera
     wysokość dokładnie tam, gdzie stoi pasek. */
  .content-footer {
    display: none;
  }
}

/* Strzałka zwijaka obraca się razem ze stanem karty — bez tego jedyną informacją o tym,
   czy sekcja jest otwarta, jest sama jej zawartość, a przy zwiniętej nie ma czego czytać. */
.fa-zwijak {
  transition: transform 0.15s ease;
}

[aria-expanded='false'] .fa-zwijak {
  transform: rotate(-90deg);
}

/* Wiersz osoby na listach terminu: awatar plus nazwisko i licznik trzymają się razem, a akcja
   (przycisk „Dopisz" albo cztery stany obecności) stoi po prawej. Na telefonie akcja spada pod
   spód zamiast wyjeżdżać poza kartę — `min-inline-size` decyduje, kiedy to nastąpi.

   Bez tego wiersz albo się nie zawijał i przyciski uciekały za krawędź, albo zawijał w środku
   danych i każdy wariant (brak pakietu, gość, ponad pakiet) wyglądał inaczej. */
.wiersz-osoba__dane {
  min-inline-size: 14rem;
}
