/* ==========================================================================
   sekcja „home_teachers" — Prowadzący na stronie głównej
   ==========================================================================
   Kontrakt DOM: patrz nagłówek sections/home_teachers.php.
   Mobile-first: 360px to układ bazowy (jedna karta + zapowiedź następnej,
   strzałki na kadrze zdjęcia), od 1024px kontener strony, cztery karty
   i zapowiedź piątej, bez strzałek.

   Wszystkie wartości pochodzą z tokenów --ds-* (DESIGN-SYSTEM.md). Odstępstwa
   od paczki projektowej — każde świadome i opisane w miejscu, w którym stoi:
     1. promień karty 14px (--ds-radius-lg), nie 28px z paczki — promień karty
        z systemu (CLAUDE.md, reguła 17);
     2. skala pisma z --ds-text-* (H2 23/31px), nie 24/46px z paczki — system
        ma świadomie niższą skalę i jedno miejsce na jej zmianę (reguła 9);
     3. badge na pełnej bieli zamiast rgba(255,255,255,.94) + backdrop-filter
        — patrz komentarz przy .ht-badge;
     4. inne stopy gradientu pod nazwiskiem — patrz komentarz przy .ht-scrim;
     5. podniesienie karty na hover to --ds-hover-lift (1px), nie 3px z paczki;
     6. strzałki zostają TAKŻE od 1024px (paczka je tam ukrywa, zostawiając
        trackpad i autoprzewijanie) — decyzja Tomka. Bez nich użytkownik zwykłej
        myszy nie miał na desktopie żadnego sposobu na przewinięcie toru:
        pionowe kółko nie przewija kontenera w poziomie;
     7. tor da się przeciągać kursorem — wzorzec przeniesiony 1:1 z sekcji
        courses_slider (`.xsell__viewport`), łącznie z nazwą klasy `is-dragging`;
     8. na mobile bieżąca karta stoi WYŚRODKOWANA, nie w linii nagłówka
        (paczka wyrównywała ją do lewej) — decyzja Tomka. Zapowiedź jest przez
        to z obu stron, po ~42px na 360px, zamiast 56px tylko z prawej.
   ========================================================================== */

.ht {
  /* Geometria toru w jednym miejscu. Na mobile wysokość pasa strzałek wylicza
     się z szerokości karty; na desktopie --ht-card-w staje się wartością
     procentową, więc --ht-media-h dostaje tam własną definicję (patrz blok
     @media na końcu pliku). */
  --ht-card-w: 276px;
  /* Wysokość kadru 3:4 — pas, w którym pionowo środkują się strzałki.
     Osobny token, bo na desktopie --ht-card-w jest wartością procentową,
     a procent w `height` rozwiązałby się względem wysokości, nie szerokości. */
  --ht-media-h: calc(var(--ht-card-w) * 4 / 3);
  --ht-gap: var(--ds-space-3);
  /* Ile tor wystaje poza kontener, żeby karty dojeżdżały do krawędzi ekranu.
     Musi się równać poziomemu paddingowi .container-ms. */
  --ht-edge: var(--ds-space-4);
  /* Wcięcie toru, które ustawia bieżącą kartę na środku kadru: połowa tego,
     co po niej zostaje. `100%` to szerokość kontenera (bloku zawierającego),
     a kadr toru jest o dwa --ht-edge szerszy, bo tor wystaje poza kontener.
     UWAGA: tej zmiennej NIE wolno użyć w `scroll-padding` — tam procent
     rozwiązuje się względem samego kadru przewijania (szerszego o 2 × edge),
     więc dałaby inną liczbę niż w `padding`. Snap wyśrodkowania nie potrzebuje
     zresztą scroll-paddingu — patrz komentarz przy .ht-card. */
  --ht-pad: calc((100% + 2 * var(--ht-edge) - var(--ht-card-w)) / 2);
  --ht-track-pad-top: 6px;

  background-color: var(--ds-color-canvas);
  padding-block: var(--ds-section-y);
  /* `clip`, nie `hidden`: przycina wystający tor, nie robiąc z sekcji
     kontenera przewijania (hidden na jednej osi wymusza auto na drugiej).
     `hidden` zostaje jako zapas dla Safari < 16, które `clip` pomija — bez
     żadnego z nich zaokrąglenie subpiksela na wystającym torze potrafi dodać
     stronie poziomy pasek przewijania. */
  overflow-x: hidden;
  overflow-x: clip;
}

/* ── Nagłówek ──────────────────────────────────────────────────────────── */

.ht-head {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-2);
}

/* Nadtytuł w kolorze marki, nie w atramencie — ta sama decyzja co
   w .hr-eyebrow (home_reviews). Lc 90 na bieli przy progu 85 (13px w wadze
   600 liczy się jak 15px). */
.ht-eyebrow {
  margin: 0;
  color: var(--ds-color-primary-ink);
}

.ht-title {
  margin: 0;
  color: var(--ds-color-ink);
  text-wrap: pretty;   /* nagłówek dwuwierszowy — `balance` zostawia tu sierotę */
}

.ht-lead {
  margin: 0;
  font-size: var(--ds-text-body);
  line-height: 1.6;
  color: var(--ds-color-ink-secondary);
}

/* ── Tor kart ──────────────────────────────────────────────────────────── */

.ht-viewport {
  position: relative;
  margin-top: var(--ds-space-6);
}

.ht-track {
  display: flex;
  gap: var(--ht-gap);
  list-style: none;
  /* Ujemny margines ciągnie tor pod krawędzie ekranu, a --ht-pad wciska treść
     tak, żeby karta wypadła na środku kadru. Bez scroll-paddingu: przy
     wyśrodkowanym snapie to padding wyznacza pozycję zatrzymania. */
  padding: var(--ht-track-pad-top) var(--ht-pad) 10px;
  margin: 0 calc(-1 * var(--ht-edge));
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* Pasek przewijania zabrany świadomie: rolę „tu się przewija" niesie
     zapowiedź następnej karty i strzałki, a systemowy pasek na Androidzie
     przecinał dolną krawędź karty. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.ht-track::-webkit-scrollbar { display: none; }

/* Przeciąganie myszką (obsługa w .js) — ten sam wzorzec co w courses_slider.
   Łapka pokazuje się tylko tam, gdzie jest kursor: palcem tor przewija się
   natywnie, więc na dotyku i bez JS-a nic się nie zmienia. */
@media (hover: hover) {
  .ht[data-ht-js] .ht-track { cursor: grab; }
  .ht[data-ht-js] .ht-track.is-dragging { cursor: grabbing; user-select: none; }
}

/* Na czas gestu snap musi zniknąć. Inaczej każde przypisanie scrollLeft
   z pointermove jest natychmiast korygowane do najbliższego punktu
   zatrzymania i tor zamiast jechać za kursorem — kleji się do kart.
   Po puszczeniu snap wraca i dociąga tor do najbliższej karty, czyli robi
   dokładnie to, po co tu jest. (courses_slider tego nie potrzebuje — jego
   tor nie ma snapa.) */
.ht-track.is-dragging {
  scroll-snap-type: none;
  scroll-behavior: auto;
}

.ht-card {
  flex: none;
  width: var(--ht-card-w);
  /* `center` razem z --ht-pad daje wyśrodkowanie, które NIE rusza siatki
     pozycji, na której stoi JS. Karta zatrzymuje się tam, gdzie jej środek
     spotyka się ze środkiem kadru, a skoro padding wynosi dokładnie
     (kadr − karta) / 2, to wypada na wielokrotności kroku — czyli tam, gdzie
     wcześniej zatrzymywała ją wersja wyrównana do lewej. Dzięki temu
     realign()/step()/wrap() zostają bez zmiany. */
  scroll-snap-align: center;
  /* Promień karty z systemu (14px), nie 28px z paczki — CLAUDE.md, reguła 17.
     overflow: hidden przycina kadr zdjęcia do tego promienia. */
  border-radius: var(--ds-radius-lg);
  overflow: hidden;
}

/* ── Kadr zdjęcia ──────────────────────────────────────────────────────── */

.ht-media {
  position: relative;
  aspect-ratio: 3 / 4;
  background-color: var(--ds-color-canvas-soft);
}

.ht-img,
.ht-ph {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.ht-img {
  object-fit: cover;
  display: block;
}

.ht-badge {
  position: absolute;
  left: var(--ds-space-3);
  top: var(--ds-space-3);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Pełna biel, nie rgba(255,255,255,.94) z paczki, i bez backdrop-filter.
     Dwa powody. Kontrast: pod badge'em leży zdjęcie o nieznanej jasności,
     a na przezroczystej bieli nad ciemnym kadrem --subj-deep spada do
     Lc 76–88 — poniżej progu i w sposób, którego nie da się policzyć z góry.
     Na pełnej bieli para trzyma Lc 84,1–96,0 przy progu 80 (13px w wadze 600
     liczy się jak 15px), niezależnie od zdjęcia. Wydajność: backdrop-filter
     to najdroższy filtr na przeciętnym Androidzie, a tu leżałby w jedenastu
     kartach przewijanego toru (CLAUDE.md → „Stabilność i wydajność"). */
  background-color: var(--ds-color-surface);
  color: var(--subj-deep);
  font-family: var(--ds-font-body);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-eyebrow);
  line-height: 1.2;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  border-radius: var(--ds-radius-full);
  padding: 5px 10px 5px 11px;
  /* Ledwie widoczny pierścień — biała pigułka na jasnym kadrze inaczej
     rozpływa się w zdjęciu (ta sama sztuczka co w .icon-tile). */
  box-shadow: inset 0 0 0 1px rgba(19, 26, 43, 0.08);
}

.ht-badge-dot {
  width: 6px;
  height: 6px;
  flex: none;
}

.ht-scrim {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  /* Wyższy scrim niż w paczce (52px światła nad nazwiskiem, nie 34px) — daje
     zejściu gradientu tyle miejsca, żeby nie czytało się jako doklejony pasek. */
  padding: 52px var(--ds-space-3) var(--ds-space-3);
  /* Stopy też inne niż w paczce. Tam gradient dochodził do .82 dopiero na samej
     dolnej krawędzi, więc górna część glifów nazwiska leżała na alfie ~.26 —
     nad jasnym kadrem biel dawała tam Lc 44,7 przy progu 70 (17px w wadze 600).
     Tu, nad kadrem CAŁKOWICIE BIAŁYM (najgorsze możliwe zdjęcie), najsłabszy
     punkt pod tekstem trzyma Lc 89,3 dla nazwiska w jednej linii i Lc 75,4 dla
     nazwiska w dwóch. Drugi przypadek liczy się, bo nazwiska nie skracamy
     wielokropkiem — dłuższe zawija się do dwóch linii, a scrim rośnie razem
     z nim (stopy są procentowe, więc gradient skaluje się sam).
     Nazwisko jest nagłówkiem karty: jego czytelność nie może zależeć od tego,
     jak jasne okaże się zdjęcie, którego jeszcze nie ma. */
  background-image: linear-gradient(
    180deg,
    rgba(19, 26, 43, 0) 0%,
    rgba(19, 26, 43, 0.30) 30%,
    rgba(19, 26, 43, 0.66) 52%,
    rgba(19, 26, 43, 0.88) 78%,
    rgba(19, 26, 43, 0.92) 100%
  );
}

.ht-name {
  margin: 0;
  color: var(--ds-color-on-primary);
  /* Bez `nowrap` i bez wielokropka: ucięte nazwisko prowadzącego to gorszy
     błąd niż druga linia. Scrim rośnie razem z tekstem, a jego gradient jest
     opisany procentowo, więc kontrast trzyma się i przy dwóch liniach
     (Lc 75,4 przy progu 70 — patrz komentarz przy .ht-scrim). */
  text-wrap: balance;
}

/* ── Treść karty ───────────────────────────────────────────────────────── */

.ht-body {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-3);
  flex: 1;
  padding: var(--ds-space-4);
}

.ht-line {
  margin: 0;
  font-size: var(--ds-text-body);
  line-height: 1.55;
  color: var(--ds-color-ink-secondary);
}

.ht-link {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  /* Cały wiersz jest celem dotykowym — 52px, jak główne CTA (reguła 15). */
  min-height: 52px;
  padding-top: var(--ds-space-3);
  border-top: 1px solid var(--ds-color-hairline);
  color: inherit;
}

.ht-tile { border-radius: var(--ds-radius-sm); }
.ht-ic { width: 22px; height: 22px; }

.ht-meta {
  flex: 1;
  min-width: 0;
}

.ht-subject {
  display: block;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-title);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ds-color-ink);
  /* Jedyny sygnał „to jest link" w karcie poza strzałką — stąd zwykłe
     podkreślenie, nie animowany .lnk. */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ht-level {
  display: block;
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-caption);
  line-height: 1.35;
  color: var(--ds-color-ink-muted);
}

.ht-chev {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--ds-color-primary);
  transition: transform var(--ds-duration-link) var(--ds-ease-out-soft);
}

.ht-link:hover .ht-subject { color: var(--ds-color-primary-ink); }
.ht-link:hover .ht-chev { transform: translateX(3px); }

/* ── Strzałki (mobile/tablet) ──────────────────────────────────────────── */

/* Bez JS strzałki nie robią nic, więc ich nie ma. Znacznik data-ht-js
   dostawia skrypt (assets/js/home_teachers.js). */
.ht-nav { display: none; }

.ht[data-ht-js] .ht-nav {
  position: absolute;
  inset-inline: 0;
  top: var(--ht-track-pad-top);
  /* Pas o wysokości kadru — strzałki lądują w jego pionowym środku, czyli
     na zdjęciu, nie na tekście. Zachodzenie na kadr jest w karuzelach normą
     (tak samo rozwiązuje to .xsell__nav w courses_slider). */
  height: var(--ht-media-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: var(--ds-space-2);
  pointer-events: none;
  /* Karta dostaje na hover `transform`, czyli własny kontekst stosu — z-index
     zdejmuje pytanie o to, kto się na kogo nakłada. */
  z-index: 2;
}

.ht-arrow {
  pointer-events: auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid var(--ds-color-hairline);
  border-radius: var(--ds-radius-md);
  background-color: var(--ds-color-surface);
  color: var(--ds-color-ink);
  box-shadow: var(--ds-shadow-md);
  transition: transform var(--ds-duration-base) var(--ds-ease-out-soft);
}

.ht-arrow > svg { width: 20px; height: 20px; }
.ht-prev > svg { transform: rotate(180deg); }
.ht-arrow:active { transform: scale(var(--ds-press-scale)); }

/* ── Desktop ───────────────────────────────────────────────────────────── */

@media (min-width: 1024px) {
  .ht {
    --ht-gap: 22px;
    --ht-edge: 0px;   /* na desktopie zapowiedź piątej karty ucina krawędź kontenera */
    /* Cztery karty w kadrze nie mają czego środkować — tor wraca do
       wyrównania z lewą krawędzią kontenera, czyli z nagłówkiem. */
    --ht-pad: 0px;
    /* Cztery pełne karty plus zapowiedź piątej — niezależnie od szerokości
       okna. Karta na sztywno 300px z projektu przy .container-ms (treść 1280px
       na ekranie 1440px) zostawiałaby piątej karcie 14px, czyli zapowiedź
       przestaje istnieć, a to ona mówi, że tor się przewija. Dlatego szerokość
       liczy się z kontenera: (treść − trzy odstępy − 52px na czwarty odstęp
       i wystający skrawek) / 4. Skrawek wychodzi z tego ~30px, czyli tyle,
       ile pokazuje podgląd desktopowy z projektu (32px przy kontenerze 1320px).
       Podłoga 268px trzyma czytelną kartę na wąskim desktopie — poniżej niej
       w kadrze staje mniej niż cztery karty, i tak ma być. */
    --ht-card-w: max(268px, calc((100% - 3 * var(--ht-gap) - 52px) / 4));
  }

  .ht-head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--ds-space-16);
  }

  .ht-intro {
    max-width: 700px;
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
  }

  .ht-lead {
    max-width: 520px;
    font-size: var(--ds-text-body-lg);
    line-height: 1.6;
  }

  .ht-viewport { margin-top: var(--ds-space-10); }
  .ht-track { padding-bottom: 12px; }
  .ht-card { scroll-snap-align: start; }

  .ht-card {
    transition:
      transform var(--ds-duration-base) var(--ds-ease-out-soft),
      box-shadow var(--ds-duration-base) var(--ds-ease-out-soft);
  }
  .ht-card:hover {
    transform: var(--ds-hover-lift);
    box-shadow: var(--ds-shadow-md);
  }

  .ht-badge { left: var(--ds-space-4); top: var(--ds-space-4); }
  .ht-scrim { padding: 56px var(--ds-space-4) var(--ds-space-4); }
  .ht-body { padding: var(--ds-space-4) var(--ds-space-4) var(--ds-space-5); }

  /* Ta sama wysokość kadru co wyżej, ale policzona z `vw`, nie z `%` — żeby
     została LENGTH-em nadającym się do arytmetyki w `height`. Szerokości karty
     świadomie NIE liczymy z vw: vw zawiera szerokość pionowego paska
     przewijania (~15px), a te 15px zabrałyby zapowiedź piątej karty. Na samej
     pozycji strzałki ta sama niedokładność to najwyżej 2–3px, czyli nic. */
  .ht {
    --ht-media-h: calc(
      max(268px, (min(1320px, 100vw) - 40px - 3 * var(--ht-gap) - 52px) / 4) * 4 / 3
    );
  }

  /* Strzałki zostają na desktopie (odstępstwo 6 z nagłówka pliku); stoją wyżej
     niż na mobile tylko dlatego, że kadr jest wyższy — pozycja liczy się
     z tokenu. Rozmiar 44px i ikona 22px jak w .xsell__nav, żeby dwie karuzele
     na tej samej stronie nie miały dwóch różnych strzałek.
     `:active` powtórzone PO `:hover`: ten blok @media stoi dalej w pliku, więc
     bez powtórzenia stan wciśnięcia przegrywałby z podniesieniem na hover. */
  .ht-arrow > svg { width: 22px; height: 22px; }
  .ht-arrow:hover { transform: var(--ds-hover-lift); box-shadow: var(--ds-shadow-lg); }
  .ht-arrow:active { transform: scale(var(--ds-press-scale)); box-shadow: var(--ds-shadow-md); }
}
