/* ==========================================================================
   Kanał - żywe posty z API.

   Metafora: posty leżą na szynie, tak jak oprawy na mosiężnych listwach
   w salonie. To jedyny moment na stronie z ruchem w poziomie, więc czyta się
   jak gest, a nie jak awaria layoutu.

   Zasady:
   - zero kart z cieniem i ramką - rozdziela hairline i światło,
   - szyna wychodzi poza .wrap do prawej krawędzi ekranu, żeby było widać,
     że ciąg dalszy istnieje (afordancja przewijania bez strzałek),
   - fiolet pojawia się w dwóch miejscach: kropka świeżości i pasek postępu,
   - obraz reaguje na hover, reszta stoi. Jeden ruch, nie pięć.
   ========================================================================== */

.kanal { overflow: hidden; }

/* --- Nagłówek ----------------------------------------------------------- */
@media (min-width: 1024px) {
  /* Etykieta stoi u góry kolumny, tak jak w pozostałych sekcjach serwisu.
     W vertical-rl osią główną flexa jest pion, więc flex-end sadza słowo
     przed obrotem na dole - rotate(180deg) wynosi je na górę. */
  .kanal .marked > .label {
    display: flex;
    justify-content: flex-end;
  }
}

.kanal__intro { display: grid; gap: clamp(1.75rem, 4vw, 2.5rem); }
.kanal__eyebrow { display: block; margin-bottom: clamp(1rem, 2.5vw, 1.5rem); }
.kanal__h { max-width: 16ch; }
.kanal__lead { max-width: 46ch; color: var(--muted); line-height: 1.75; }

@media (min-width: 900px) {
  .kanal__intro {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    align-items: end;
    column-gap: clamp(2.5rem, 5vw, 5rem);
  }
}

/* Znacznik świeżości. Kropka niesie stan, tekst niesie treść -
   nigdy sam kolor, bo daltonista dostałby pustą informację. */
/* display:flex bije regułę UA [hidden]{display:none}, więc oba elementy
   sterowane atrybutem hidden muszą go wyłączyć jawnie. Inaczej strona
   pokazywałaby pustą kropkę świeżości i martwe CTA. */
.kanal__status[hidden],
.kanal__cta[hidden] { display: none; }

.kanal__status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.25rem;
  font-size: 0.78rem;
  color: var(--muted);
}
.kanal__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--purple);
  flex: none;
}
/* powyżej 10 dni sekcja przestaje udawać świeżość - PRD 16.8 */
.kanal__status[data-stan="stale"] .kanal__dot { background: var(--hairline); }
.kanal__cta { margin-top: clamp(1.5rem, 3vw, 2rem); }

/* Strona, ktora wystawia caly kanal, oznacza sie main[data-kanal-max] - i wtedy
   "Zobacz wszystkie" nie ma czego pokazac, bo wszystko juz lezy na polce.
   Podstrona Aktualnosci niesie odeslanie na profil osobna sekcja (.aktprofil),
   wiec ten link byl tam trzecim linkiem w to samo miejsce na jednym
   przewinieciu. Na stronie glownej CTA zostaje: tam szyna pokazuje tylko
   poczatek kanalu i link jest jedynym wyjsciem na profil. */
main[data-kanal-max] .kanal__cta { display: none; }

/* --- Szyna -------------------------------------------------------------- */
/* Szyna startuje schowana. Klasę .is-rail zapala kanal.js w chwili, gdy kładzie
   na niej cokolwiek - szkielety ładowania albo gotowe karty - i gasi ją na
   każdej ścieżce awaryjnej. Stan domyślny jest więc jednocześnie stanem
   bez JS: widać komunikat, nie pustą listwę. */
.kanal__railwrap { display: none; }
.kanal.is-rail .kanal__railwrap { display: block; }
.kanal.is-rail .kanal__emptywrap { display: none; }

.kanal__railwrap {
  --pad: clamp(1.5rem, 3vw, 2.5rem);

  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  /* Szyna zaczyna się na krawędzi treści, a kończy dopiero za krawędzią ekranu -
     to jest cała afordancja przewijania, bez strzałek i kropek.
     Odejmujemy wewnętrzny padding pierwszej karty, żeby jej kadr stanął
     dokładnie na krawędzi treści, a nie o padding dalej. */
  /* max(0px, ...) bo na wąskich ekranach --pad bywa większy niż --gutter,
     a ujemny padding unieważnia całą deklarację i szyna traci wcięcie. */
  padding-left: max(
    0px,
    max(var(--gutter), (100vw - var(--measure)) / 2 + var(--gutter)) - var(--pad)
  );
}

.kanal__rail {
  display: flex;
  gap: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  padding-bottom: clamp(1.5rem, 3vw, 2.25rem);
  /* listwa półki */
  border-bottom: 1px solid var(--hairline);
  cursor: grab;
}
.kanal__rail::-webkit-scrollbar { display: none; }
.kanal__rail.is-drag { cursor: grabbing; scroll-snap-type: none; }
.kanal__rail:focus-visible { outline: 2px solid var(--purple); outline-offset: 6px; }

/* --- Karta postu -------------------------------------------------------- */
.kanal__item {
  flex: none;
  /* Wszystkie karty mają identyczną szerokość i identyczny padding po obu
     stronach. Wcześniej pierwsza miała padding-left: 0, więc jej kadr był
     szerszy, wyższy (aspect-ratio) i cała półka traciła wspólną linię. */
  width: clamp(15rem, 68vw, 21rem);
  scroll-snap-align: start;
  padding-inline: var(--pad, clamp(1.5rem, 3vw, 2.5rem));
  /* pionowy hairline między pozycjami - jak przegroda na półce */
  border-right: 1px solid var(--hairline);
}

.kanal__link { display: block; }

.kanal__frame {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--panel);
}
.kanal__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.kanal__link:hover .kanal__frame img { transform: scale(1.04); }

/* Post bez obrazu nie może zostawić dziury: kadr dostaje typograficzny znak
   z pierwszą literą kategorii. Kolumna zachowuje rytm szyny. */
.kanal__frame--void {
  display: grid;
  place-items: center;
  background: var(--panel-soft);
}
.kanal__void {
  font: 300 clamp(3rem, 9vw, 5rem)/1 var(--serif);
  color: var(--hairline);
}

.kanal__num {
  display: block;
  margin-top: 1.1rem;
  font: 400 0.7rem/1 var(--serif);
  color: var(--muted);
}

.kanal__cat {
  display: inline-block;
  margin-top: 0.85rem;
  padding-bottom: 0.3rem;
  font: 500 0.6rem/1 var(--sans);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--purple);
  /* linia dorysowuje się pod etykietą przy hoverze - jedyny dodatkowy ruch */
  background-image: linear-gradient(var(--purple), var(--purple));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 1px;
  transition: background-size 0.5s var(--ease);
}
.kanal__link:hover .kanal__cat { background-size: 100% 1px; }

.kanal__t {
  margin-top: 0.55rem;
  font: 300 clamp(1.05rem, 1rem + 0.35vw, 1.3rem)/1.32 var(--sans);
  color: var(--ink);
}
.kanal__x {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--muted);
}
.kanal__when {
  display: block;
  margin-top: 0.9rem;
  font-size: 0.72rem;
  color: var(--muted);
}

/* --- Pasek postępu ------------------------------------------------------ */
/* Zastępuje pasek przewijania: mówi ile jeszcze zostało, nie zajmując miejsca. */
.kanal__bar {
  height: 1px;
  margin-top: -1px;
  background: transparent;
  padding-right: var(--gutter);
}
.kanal__bar span {
  display: block;
  height: 1px;
  width: 0;
  background: var(--purple);
  transition: width 0.15s linear;
}

/* --- Szkielet ładowania ------------------------------------------------- */
/* Jeden przesuw gradientu, bez pulsowania - pulsowanie jest tanie. */
.kanal__skel .kanal__frame,
.kanal__skel .kanal__line {
  background: linear-gradient(90deg, var(--panel) 0%, var(--panel-soft) 50%, var(--panel) 100%);
  background-size: 300% 100%;
  animation: kanal-skel 1.6s var(--ease) infinite;
}
.kanal__line { height: 0.8rem; margin-top: 0.9rem; border-radius: 2px; }
.kanal__line--s { width: 40%; }
@keyframes kanal-skel { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* --- Stan pusty --------------------------------------------------------- */
/* Pusta półka nie jest kartą, więc nie stoi na torze szyny (ten ucieka o pełny
   gutter w lewo, poza kreskę .marked). Wraca na siatkę treści: lewa krawędź
   równa z nagłówkiem sekcji, prawa równa z .wrap. Zamiast 350px tekstu w polu
   1440px sekcja dostaje pełnowymiarową listwę - komunikat po lewej, wyjście
   po prawej - domkniętą tym samym hairlinem, którym domyka się półka z kartami. */
.kanal__emptywrap { margin-top: clamp(2.5rem, 6vw, 4.5rem); }

.kanal__empty {
  display: grid;
  gap: clamp(1.5rem, 3.5vw, 2.25rem);
  padding-block: clamp(2rem, 4.5vw, 3.25rem);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.kanal__empty-t {
  margin-top: clamp(0.9rem, 2vw, 1.25rem);
  font: 300 clamp(1.3rem, 1rem + 1.5vw, 2.15rem)/1.28 var(--sans);
  letter-spacing: -0.015em;
  max-width: 24ch;
  text-wrap: pretty;
}

.kanal__empty-btn { justify-self: start; }

@media (min-width: 768px) {
  /* Komunikat i wyjście stają na wspólnej linii bazowej po dwóch krańcach
     siatki - to jest ta "pełna szerokość", nie rozciągnięty akapit. */
  .kanal__empty {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
  .kanal__empty-btn { justify-self: end; }
}

@media (min-width: 1024px) {
  /* Tor pionowej etykiety .marked (3.5rem) plus jej odstęp - dokładnie ten sam
     skok, którym nagłówek sekcji odsuwa się od kreski. Bez tego blok siedział
     56px w lewo od "To, co właśnie dzieje się u nas". */
  .kanal__emptywrap { padding-left: calc(var(--gutter) + 3.5rem); }
}

@media (prefers-reduced-motion: reduce) {
  .kanal__rail { scroll-behavior: auto; }
  .kanal__skel .kanal__frame,
  .kanal__skel .kanal__line { animation: none; }
  .kanal__link:hover .kanal__frame img { transform: none; }
}

/* Dane przykładowe. Musi być widać na pierwszy rzut oka, że to nie są prawdziwe
   wpisy salonu - inaczej plakietka nie robi swojej roboty. */
.kanal__status[data-stan="sample"] {
  color: var(--ink);
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: var(--pill);
  align-self: start;
  width: fit-content;
}
.kanal__status[data-stan="sample"] .kanal__dot {
  background: repeating-linear-gradient(45deg, var(--purple) 0 2px, transparent 2px 4px);
}
