/* ============================================================
   WARIANT GRAFICZNY "CALLS" - zywe mockupy panelu bocznego
   frontend/task-04 (zastepuje side-PNG z frontend/task-03)
   -> frontend/task-05 (caly kreator w splicie + /done)
   -> frontend/task-06 (panele przebudowane wg narracji sprzedazowej;
      kazdy krok odpowiada na inne pytanie zakupowe - `.ai/project/wizard-narracja.md`.
      TEN DOKUMENT CZYTA SIE PRZED zmiana czegokolwiek w sekcjach step*)

   Ten plik jest ladowany WYLACZNIE gdy wariant jest aktywny
   (`theme == 'calls'` -> warunkowy <link> w layoutach Register/Common/*).
   Wersja domyslna nie pobiera go w ogole, wiec zadna regula stad nie ma
   fizycznej mozliwosci dotkniecia oryginalnego wizarda. Dlatego caly
   wczesniejszy blok `.theme-calls` zniknal z app.css - app.css jest znowu
   wylacznie o wersji domyslnej.

   PNG-i w /assets/img/calls/ zostaja w repo jako referencja wizualna
   (spec ux/task-01) - tlo `tillio-app-background-opt.png` dalej jest uzywane,
   side-grafiki step*_right.png juz nie (zastapione komponentami).
   ============================================================ */

body.theme-calls {
  /* Paleta wariantu - wyciagnieta z renderow ux/task-01. Wszystko, czego nie ma
     w tokens.css, siedzi tutaj jako zmienna: zero surowych hexow w regulach nizej. */
  --calls-panel-top:    #2a0a3a;
  --calls-panel-bottom: #0f0524;
  --calls-glow:         rgba(255, 10, 113, 0.45);

  --calls-ink:        var(--color-neutral-900);
  --calls-muted:      var(--color-neutral-500);
  --calls-faint:      var(--color-neutral-400);
  --calls-accent:     var(--color-primary-600);
  --calls-line:       #e9edf2;
  /* Kreska mocniejsza od `--calls-line` - do obrysow, ktore MUSZA byc widoczne same z siebie,
     bo nic nie wypelniaja (duch po przeniesionej kartce na kroku 5). `--calls-line` na bieli
     ginie z odleglosci metra, a duch, ktorego nie widac, nie opowiada zadnego ruchu. */
  --calls-line-strong: var(--color-neutral-200);
  --calls-surface:    var(--color-neutral-0);
  --calls-surface-2:  #f4f6fa;

  --calls-accent-wash: rgba(255, 10, 113, 0.10);

  --calls-ok:         #1fa45c;
  --calls-ok-soft:    #e6f7ee;
  --calls-busy:       var(--color-primary-600);
  --calls-busy-soft:  #ffe6f0;
  --calls-bar-idle:   rgba(255, 10, 113, 0.24);
  --calls-away:       #e08a12;
  --calls-away-soft:  #fdf1de;
  /* Cztery kolory czterech momentow w transkrypcji (frontend/task-06): obiekcja = away,
     kwota = info, sygnal zakupowy = ok, obietnica = accent. `info` jest jedynym nowym -
     reszta to kolory statusow, ktore juz w tym motywie znacza to samo. */
  --calls-info:       #2f6fd0;
  --calls-info-soft:  #e8f1fe;

  /* Ikony zetonow na kroku 4 stoja na SZKLE nad ciemnym gradientem, wiec `--calls-ok`
     i `--calls-accent` (dobrane pod biala karte) sa tam za ciemne. Rozjasnione warianty. */
  --calls-token-ok:   #7ee2a8;
  --calls-token-hot:  #ffb0cd;

  --calls-mark-plate: #1b2b45;

  /* Logo "tillio | Calls" - wartosci 1:1 z aplikacji Calls (App.vue).
     Apka ma DOMYSLNIE motyw ciemny (`[data-theme="light"]` to dopiero override), a nasz
     panel tez jest ciemny - bierzemy wiec komplet z motywu ciemnego apki, bez zadnej
     wlasnej inwersji. Motyw jasny apki dla porownania: logo-tillio-dark.svg,
     kreska rgba(0,0,0,.4), "Calls" #00a085. */
  --tc-logo-rule:       rgba(255, 255, 255, 0.6);
  --tc-logo-accent:     #00c9a7;

  /* Awatar ma dzis JEDEN kolor, bo w calym kreatorze jest JEDEN czlowiek z inicjalami:
     Marek Nowak (klient dzwoniacy na kroku 1, on sam mowi w transkrypcji na kroku 4).
     Tonow bylo szesc, bo krok 6 rysowal liste szesciu pracownikow - kazdy z innym
     kolorem awatara. Ta lista wypadla w frontend/task-08 (panel migotal i przykrywal
     tresc, ktora mial sprzedac), a razem z nia wypadly nieuzywane tony. Wracaja
     w momencie, w ktorym wroci drugi czlowiek z awatarem - nie wczesniej. */
  --calls-c2: #8257e6;

  /* PROMIENIE - TRZY POZIOMY I ANI JEDEN WIECEJ (frontend/task-07 pkt 3).
     Po task-06 kazda scenka miala swoj promien wpisany na piechote (9, 10, 12, 14, 20 px),
     wiec kartka sprawy, osoba w zespole i dymek czatu zaokraglaly sie inaczej mimo
     tej samej roli. Od task-07 obowiazuje przypisanie:

       --calls-radius     karta stojaca bezposrednio w panelu (notyfikacja, karta kontaktu,
                          transkrypcja, tablica, zespol, pulpit, karta /done),
       --calls-radius-s   element WEWNATRZ karty (kartka sprawy, wiersz osoby, komorka
                          liczby, wiersz AI, kolumna etapu, dymek czatu),
       --calls-radius-xs  mikroelement (chip, licznik, podswietlenie, etykieta typu).

     Zadnej surowej wartosci px w `border-radius` ponizej. Wyjatki sa trzy i wszystkie
     sa KSZTALTEM elementu, nie promieniem karty: `50%` (kola - awatary, kropki,
     przyciski), `999px` (pigulki) oraz slupki wykresow (fala 1.5 px, tydzien 3 px
     u dolu), ktore siedza na osi i nie moga byc od niej odklejone zaokragleniem. */
  --calls-radius:    20px;
  --calls-radius-s:  12px;
  --calls-radius-xs: 6px;
  --calls-shadow:   0 26px 52px rgba(9, 4, 26, 0.34), 0 8px 18px rgba(9, 4, 26, 0.18);
  --calls-shadow-s: 0 10px 24px rgba(9, 4, 26, 0.22);
  /* Cienie elementow LEZACYCH NA BIALEJ KARCIE (kartka sprawy na kroku 5). `--calls-shadow-s`
     jest wymierzony pod karte stojaca na ciemnym gradiencie i na bialym tle robi z kartki
     brudna plame. `--calls-lift` to ta sama kartka uniesiona nad tor docelowy - cien musi
     byc wyrazniej nizszy i szerszy, bo tylko on niesie informacje "to wisi w powietrzu". */
  --calls-shadow-xs: 0 1px 2px rgba(9, 4, 26, 0.05), 0 4px 10px rgba(9, 4, 26, 0.06);
  --calls-lift:      0 3px 6px rgba(9, 4, 26, 0.07), 0 14px 26px rgba(9, 4, 26, 0.16);
  --calls-font:     var(--font-sans);
}

/* Tlo strony (kroki modalowe + /done). TYMCZASOWO gradient zamiast screenshota apki:
   wygenerowany PNG rozjezdzal sie przy kadrowaniu `cover` i mial artefakty kwantyzacji.
   Docelowo wraca tu zrzut realnego Calls na bezpiecznych danych (ux/task-02).
   Sam gradient jest darmowy wydajnosciowo - zero dekodowania obrazu, zero repaintow
   przy scrollu (`fixed` na duzym PNG potrafil kosztowac wiecej niz cala reszta strony). */
body.theme-calls.body--app-bg {
  background:
    radial-gradient(1200px 680px at 12% -10%, rgba(255, 10, 113, 0.14) 0%, transparent 62%),
    radial-gradient(1000px 620px at 100% 8%, rgba(0, 201, 167, 0.12) 0%, transparent 58%),
    radial-gradient(900px 700px at 78% 108%, rgba(90, 40, 180, 0.13) 0%, transparent 60%),
    linear-gradient(160deg, #fdfbff 0%, #f4f1fa 46%, #eef0f8 100%);
  background-attachment: fixed;
}

/* ------------------------------------------------------------
   PANEL - gradient zamiast side-PNG.
   Specificity 0,3,1 = tyle co reguly PNG w app.css
   (`.fullscreen-split__visual--with-graphic[data-bg="stepN"]`), ale `body.theme-calls`
   dokłada trzecia klase, wiec wygrywa i to bez wzgledu na kolejnosc plikow.
   Gradient jest ten sam, ktory panel ma w wersji bazowej ("ten co mamy na gorze").
   ------------------------------------------------------------ */
body.theme-calls .fullscreen-split__visual--with-graphic[data-bg],
body.theme-calls .modal__visual--with-graphic[data-bg] {
  background:
    radial-gradient(ellipse at 30% 35%, var(--calls-glow) 0%, transparent 55%),
    linear-gradient(180deg, var(--calls-panel-top) 0%, var(--calls-panel-bottom) 100%);
}

/* ------------------------------------------------------------
   STAGE - logo u gory, mockup pod spodem
   ------------------------------------------------------------ */
.calls-stage {
  position: relative;
  z-index: 1;
  align-self: stretch;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 4vh, 44px);
  padding: clamp(40px, 7vh, 84px) 24px clamp(28px, 5vh, 56px);
  font-family: var(--calls-font);
  overflow: hidden;
}

/* ------------------------------------------------------------
   LOGO "tillio | Calls" - geometria i typografia 1:1 z aplikacja Calls
   (App.vue, slot #logo: .tc-logo / .tc-logo-img / .tc-logo-sep / .tc-logo-calls).
   Nazwy klas i wartosci zostaja takie same, zeby dalo sie je zestawic bez tlumaczenia.

   Jedyne, czego apka nie ma: `aspect-ratio` i `flex-shrink` na .tc-logo-img -
   zabezpieczenie przed `preserveAspectRatio="none"` w pliku SVG.
   ------------------------------------------------------------ */
/* Wartosci bazowe (kroki 4-7, waski panel modala) to rozmiar z apki +20% -
   w apce logo siedzi w pasku bocznym, u nas na duzym panelu i bylo za drobne. */
.tc-logo {
  display: flex;
  align-items: center;
  gap: 13px;
  flex-shrink: 0;
}
/* +20 px w dol na KAZDYM widoku (frontend/task-07 pkt 2) - operator uznal logo za
   przyklejone do gornej krawedzi panelu. Offset siedzi tutaj, a nie w `padding-top`
   stage'a, z dwoch powodow: (a) `.tc-logo` ma geometrie 1:1 z aplikacja Calls i marginesu
   w apce nie ma, wiec zmiana musi byc scisle nasza i widoczna w jednym miejscu,
   (b) padding stage'a jest `clamp(...vh...)` i doliczanie do niego 20 px psuje skalowanie
   na niskich oknach. Regula celuje w logo TYLKO wewnatrz panelu (`.calls-stage >`),
   wiec te same klasy uzyte gdziekolwiek indziej zostaja nietkniete. Dziala w obu skalach
   logo (kroki 1-3 maja 2x przez `.body--fullscreen`, kroki 4-7 i /done skale bazowa). */
.calls-stage > .tc-logo { margin-top: 20px; }
/* `aspect-ratio` z pliku (oficjalne assety: bialy 86x22, ciemny 129x32 - ten sam znak,
   inny eksport). Bez tego `preserveAspectRatio` w SVG potrafi znak sciskac. */
.tc-logo-img {
  display: block;
  height: 26px;
  width: auto;
  aspect-ratio: 86 / 22;
  flex-shrink: 0;
}
.tc-logo-sep {
  width: 1px;
  height: 26px;
  flex-shrink: 0;
  background: var(--tc-logo-rule);
}
.tc-logo-calls {
  font-family: 'Poppins', var(--font-sans);
  font-size: 24px;
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.019em;
  color: var(--tc-logo-accent);
  transform: translateY(1px);
}

/* Kroki 1-3 (layout fullscreen-split) maja panel na pol ekranu - tam 2x rozmiar apki. */
.body--fullscreen .tc-logo      { gap: 22px; }
.body--fullscreen .tc-logo-img  { height: 44px; }
.body--fullscreen .tc-logo-sep  { height: 44px; width: 2px; }
.body--fullscreen .tc-logo-calls { font-size: 40px; transform: translateY(2px); }

/* ------------------------------------------------------------
   MODAL - REGULY USPIONE (frontend/task-05).
   Od decyzji operatora wariant "calls" renderuje WSZYSTKIE ekrany kreatora
   w `fullscreen-split` (Step4-8 maja warunkowy `extends`), a modal zostal
   wersji domyslnej - ktora tego arkusza w ogole nie pobiera. Nic ponizej nie
   ma wiec dzis szansy sie odpalic.

   Zostawione swiadomie, nie przez zapomnienie: to komplet poprawek, ktore modal
   w wariancie kosztowal (stale proporcje ramki, scroll w kolumnie, safe center).
   Gdyby operator chcial modal z powrotem - wystarczy cofnac `extends`, zamiast
   odtwarzac te reguly od zera.

   Kontekst historyczny: bazowo `.modal__inner` ma `min-height`, wiec ramka rosla
   i kurczyla sie razem z dlugoscia formularza (krok 6 z lista uzytkownikow vs krok 7)
   - przy przejsciu miedzy krokami cala karta skakala. Tu: sztywna wysokosc + scroll
   WEWNATRZ kolumny formularza. Kolumna formularza oddawala 60 px na rzecz panelu
   z grafika (630 -> 570).
   ------------------------------------------------------------ */
body.theme-calls .modal {
  /* Ratio pilnuje `aspect-ratio` nizej, ale tylko dopoki wysokosc sie miesci. Gdy okno
     jest niskie, szerokosc musi zejsc razem z nia - inaczej karta by sie splaszczyla. */
  width: min(1086px, calc((100vh - 48px) * 1.5426));
}
body.theme-calls .modal__inner {
  /* PROPORCJE ZABLOKOWANE: 1086x704 z projektu. Kolumny w procentach (570/1086),
     wiec przy kazdej szerokosci formularz i panel trzymaja ten sam podzial. */
  grid-template-columns: 52.5% 1fr;
  aspect-ratio: 1086 / 704;
  height: auto;
  min-height: 0;
}
body.theme-calls .modal__form-col {
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  /* `safe` = centruj dopoki content sie miesci; gdy jest dluzszy, wyrownaj do gory.
     Samo `center` przy overflow obcina stepper u gory i przycisk na dole naraz. */
  justify-content: safe center;
}

/* Mobile: karta jest full-bleed i jednokolumnowa (media query w app.css),
   wiec zadne blokowanie proporcji nie ma tu sensu - wracamy do zachowania bazowego. */
/* ------------------------------------------------------------
   MOBILE (<= 980 px) - spokojnie: marka i gradient w tle, zero mockupow.
   Panel boczny jest tam ukryty przez app.css i TAK ZOSTAJE (decyzja operatora:
   "na telefonie nie bedzie fajerwerkow"). Bez tych regul telefon dostawal surowy
   formularz na bialym tle - zero marki, zero tla.
   ------------------------------------------------------------ */
.mobile-brand { display: none; }

@media (max-width: 980px) {
  /* Pasek marki: logo w wariancie ciemnym na jasnym tle, wysrodkowane. Bez gradientowego
     paska - to konkurowalo z formularzem zamiast go ramowac. */
  .mobile-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 22px 20px 4px;
  }
  /* Oficjalny plik ciemnej wersji ma inny viewBox (129x32) niz bialy (248.209x64),
     wiec `aspect-ratio` z reguly bazowej trzeba nadpisac - inaczej znak by sie sciskal. */
  .mobile-brand .tc-logo-img   { height: 28px; aspect-ratio: 129 / 32; }
  .mobile-brand .tc-logo-sep   { height: 28px; background: rgba(17, 39, 59, 0.28); }
  .mobile-brand .tc-logo-calls { font-size: 26px; }

  /* Delikatny gradient zamiast plaskiej bieli - tyle wystarczy, zeby strona nie
     wygladala jak goly dokument. Te same plamy swiatla co tlo wersji modalowej. */
  body.theme-calls.body--fullscreen,
  body.theme-calls.body--app-bg {
    background:
      radial-gradient(760px 420px at 10% -8%, rgba(255, 10, 113, 0.10) 0%, transparent 60%),
      radial-gradient(700px 420px at 100% 4%, rgba(0, 201, 167, 0.09) 0%, transparent 58%),
      linear-gradient(180deg, #fdfbff 0%, #f6f3fb 100%);
  }
  /* Kolumna formularza jest przezroczysta, zeby gradient byl widoczny; pasek marki
     zajal gorny zapas, wiec formularz startuje wyzej. */
  body.theme-calls .fullscreen-split__form {
    background: transparent;
    padding-top: 20px;
    min-height: 0;
  }
}

@media (max-width: 980px) {
  body.theme-calls .modal { width: 100%; }
  body.theme-calls .modal__inner {
    aspect-ratio: auto;
    min-height: 100vh;
  }
  body.theme-calls .modal__form-col { overflow-y: visible; }
}

/* ------------------------------------------------------------
   KOLUMNA FORMULARZA W SPLICIE (frontend/task-05)
   ------------------------------------------------------------ */

/* Kroki 4-7 niosa w splicie wiecej niz kroki 1-3: stepper na gorze plus dluzsze
   formularze (krok 4 to haslo z miernikiem i czterema regulami). `fullscreen-split__form`
   byla wymierzona pod krotki formularz kroku 1, wiec na niskim oknie przycisk "Dalej"
   schodzil pod krawedz bez potrzeby. Na wysokich oknach nie ruszamy nic - kroki 1-3
   maja zostac dokladnie takie, jakie operator zaakceptowal.

   `:has(.stepper)` celuje wylacznie w kroki 4-7: /done i kroki 1-3 steppera nie maja.
   Brak wsparcia dla `:has` = regula po prostu nie wchodzi, layout zostaje bazowy.
   `min-width: 769px` trzyma to poza mobile - tam app.css ma wlasne paddingi i wyrownanie
   do gory, a ta regula (wyzsza specyficznosc) niepotrzebnie by je nadpisala. */
@media (min-width: 769px) and (max-height: 880px) {
  body.theme-calls .fullscreen-split__form:has(.stepper) {
    padding-top: var(--space-2xl);
    padding-bottom: var(--space-2xl);
    gap: var(--space-2xl);
  }
}

/* Krok 6: w wierszu uzytkownika mieszcza sie e-mail, select roli i kosz. Kolumna ma
   508 px, wiec zapasu nie ma zadnego - przy bazowych 180 px selecta placeholder
   "Wpisz e-mail uzytkownika" (206 px) dostawal 194 px i gubil koncowke.

   166 px to zmierzony prog, przy ktorym mieszcza sie OBA napisy: select potrzebuje
   112 px na "Administrator" (najdluzsza opcja) i tyle wlasnie dostaje, a e-mail
   zyskuje 208 px. Ponizej - urywa sie rola, powyzej - placeholder.

   Tylko desktop: ponizej 768 px app.css lamie wiersz na dwie linie i tam sztywna
   szerokosc bylaby szkodliwa (mobile daje selectowi `flex: 1 1 0`). */
@media (min-width: 769px) {
  body.theme-calls .user-row .user-row__role { flex: 0 0 166px; }
}

/* Panel ma teraz jedna szerokosc na wszystkich ekranach - 42vw splitu (frontend/task-05).
   To duzo: netto ~526 px na 1366, ~758 px na 1920 i ~1027 px na 2560. Stad dalej clamp,
   ale inaczej ustawiony niz w czasach modala: `%` podnosi mockup na typowym laptopie,
   a gorny prog pilnuje, zeby na 2560 karta nie urosla w plakat. Wartosci sa per-ekran,
   bo kompozycje maja rozne naturalne szerokosci (step6 to dwie kolumny, step5 jedna karta). */
.calls-stage__mockup {
  position: relative;
  width: clamp(300px, 60%, 400px);
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 0;
}
.calls-stage__mockup--step1 { width: clamp(320px, 82%, 470px); }
.calls-stage__mockup--step4 { width: clamp(320px, 80%, 520px); }
/* step5 i step6 po przebudowie w task-08 niosa mniej obiektow, ale w wiekszej skali
   typograficznej (rowna krokom 1 i 4), wiec potrzebuja calej dostepnej szerokosci na
   1366 px: tam tor ma ok. 160 px, a "Pixelova Sp. z o.o." mierzy 118 px. Gorny prog
   pilnuje, zeby na 2560 karta nie urosla w plakat. */
.calls-stage__mockup--step5 { width: clamp(320px, 100%, 700px); }
.calls-stage__mockup--step6 { width: clamp(320px, 94%, 640px); }
/* step7 po zdjeciu Autopilota niesie JEDNA karte, wiec moze byc szerszy niz gdy niosl
   dwie (78% -> 84%): pulpit z jedna karta na 78% zostawial pas pustego gradientu
   po bokach szerszy niz sama karta na krokach 5 i 6. */
.calls-stage__mockup--step7 { width: clamp(300px, 84%, 520px); }
.calls-stage__mockup--done  { width: clamp(320px, 80%, 500px); }

.calls-scene {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
/* ------------------------------------------------------------
   PRYMITYWY WSPOLNE
   ------------------------------------------------------------ */
.calls-card {
  background: linear-gradient(180deg, var(--calls-surface) 0%, var(--calls-surface-2) 100%);
  border-radius: var(--calls-radius);
  box-shadow: var(--calls-shadow);
  color: var(--calls-ink);
}

.calls-icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

.calls-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--calls-muted);
  flex-shrink: 0;
}
.calls-dot--ok,
.calls-dot--live   { background: var(--calls-ok); }
.calls-dot--busy   { background: var(--calls-busy); }
.calls-dot--away   { background: var(--calls-away); }
.calls-dot--unread { background: var(--calls-accent); }
.calls-dot--ink    { background: var(--calls-faint); }

.calls-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: var(--font-weight-semibold);
  line-height: 1.5;
  white-space: nowrap;
}
.calls-badge--ok     { background: var(--calls-ok-soft);   color: var(--calls-ok); }
.calls-badge--busy   { background: var(--calls-busy-soft); color: var(--calls-busy); }
.calls-badge--away   { background: var(--calls-away-soft); color: var(--calls-away); }
.calls-badge--muted  { background: var(--calls-surface-2); color: var(--calls-muted); }
/* "gorący kontakt" (krok 1 i 4) - jedyna plakietka, ktora ma cos sprzedac, wiec pelny
   akcent zamiast washa. `--stage` to etap lejka: informacja, nie ocena - stad neutralnie. */
.calls-badge--hot    { background: var(--calls-accent);    color: var(--color-fg-white); }
.calls-badge--stage  { background: var(--calls-surface-2); color: var(--calls-muted); font-weight: var(--font-weight-medium); }
.calls-badge--ok .calls-dot { width: 6px; height: 6px; }
.calls-badge--hot .calls-icon,
.calls-badge--ok .calls-icon { width: 11px; height: 11px; }

.calls-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--calls-surface-2);
  color: var(--calls-muted);
  font-size: 11px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.calls-pill .calls-icon { width: 12px; height: 12px; color: var(--calls-accent); }

.calls-chip {
  padding: 2px 8px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-surface-2);
  color: var(--calls-faint);
  font-size: 11px;
  font-weight: var(--font-weight-semibold);
}

.calls-avatar {
  position: relative;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-fg-white);
  font-size: 13px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.calls-avatar--c2 { background: var(--calls-c2); }
.calls-avatar .calls-dot {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 11px;
  height: 11px;
  border: 2px solid var(--calls-surface);
}

.calls-round {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.calls-round .calls-icon { width: 18px; height: 18px; }
.calls-round--accept  { background: var(--calls-ok);      color: var(--color-fg-white); }
.calls-round--decline { background: var(--calls-accent);  color: var(--color-fg-white); }
.calls-round--decline .calls-icon { transform: rotate(135deg); }

/* Znak tillio (partial _mark.twig) */
.calls-mark { width: 100%; height: 100%; display: block; }
.calls-mark--dark   .calls-mark__plate { fill: var(--calls-mark-plate); }
.calls-mark--accent .calls-mark__plate { fill: var(--calls-accent); }
.calls-mark__glyph { fill: var(--color-fg-white); }
.calls-mark__glyph--soft { fill: var(--color-neutral-200); }

/* ------------------------------------------------------------
   step1 - "KTO DZWONI": notyfikacja + karta kontaktu (frontend/task-06)
   ------------------------------------------------------------ */
/* Trzy elementy, kazdy z oddechem (task-07 pkt 4). `gap` scenki obsluguje odstep
   karta kontaktu <-> karta SMS-a, a notyfikacja dostaje dodatkowe 10 px na dole:
   przy 14 px czytala sie jak naglowek karty kontaktu, a to sa dwie osobne rzeczy
   (przychodzace polaczenie vs kartoteka klienta). */
/* Trzy karty kroku 1 nie stoja w slupku: kazda ma inna szerokosc i inne przesuniecie
   w poziomie (rozstrzelone okna, ten sam pomysl co dwie tablice na kroku 5). Marginesy,
   nie `transform` - transform nie zmienia layoutu, wiec karty zachodzilyby na siebie
   w pionie zamiast po prostu stac krzywo. Ujemne marginesy wychodza poza kontener
   mockupu, ktory jest wezszy niz panel - jest na to miejsce. */
.calls-scene--who { gap: 18px; }
.calls-scene--who .calls-incall {
  width: 100%;
  margin-left: 26px;
  margin-right: -26px;
}
.calls-scene--who .calls-ctx {
  margin-left: -18px;
  margin-right: 18px;
}
.calls-scene--who .calls-miss {
  align-self: flex-end;
  width: 88%;
  margin-right: -34px;
  margin-top: 4px;
}

.calls-incall {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 15px;
  border-radius: var(--calls-radius);
  margin-bottom: 10px;
  animation: calls-toast-in 620ms cubic-bezier(0.22, 1.1, 0.36, 1) both;
}
.calls-incall__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.calls-incall__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  color: var(--calls-muted);
}
.calls-incall__label .calls-dot { width: 6px; height: 6px; animation: calls-blink 1.8s ease-in-out infinite; }
.calls-incall__name {
  font-size: 16px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-incall__meta {
  font-size: 11px;
  color: var(--calls-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-incall__actions { display: flex; gap: 8px; flex-shrink: 0; }
.calls-incall .calls-round { width: 34px; height: 34px; }
.calls-incall .calls-round .calls-icon { width: 15px; height: 15px; }

/* Karta kontaktu - to ona sprzedaje krok: wiesz z kim rozmawiasz, zanim odbierzesz. */
.calls-ctx { padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 12px; }
.calls-ctx__head { display: flex; align-items: center; gap: 10px; }
.calls-ctx__title {
  font-size: 14px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
}
.calls-ctx__head .calls-badge { margin-left: auto; }

.calls-ctx__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.calls-ctx__item { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }
.calls-ctx__icon {
  width: 26px;
  height: 26px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-surface-2);
  color: var(--calls-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.calls-ctx__icon .calls-icon { width: 13px; height: 13px; }
.calls-ctx__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.calls-ctx__key { font-size: 10.5px; color: var(--calls-faint); }
.calls-ctx__val {
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  line-height: 1.35;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

/* Wiersz "wylapane przez AI" - ten sam prymityw uzywa kroku 7 na linie insightu.
   Wash akcentu zamiast koloru pelnego: to podpowiedz, nie alarm. */
.calls-ai {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 10px;
  border-radius: var(--calls-radius-s);
  background: var(--calls-accent-wash);
}
.calls-ai__icon { color: var(--calls-accent); display: inline-flex; flex-shrink: 0; padding-top: 1px; }
.calls-ai__icon .calls-icon { width: 14px; height: 14px; }
.calls-ai__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calls-ai__text { font-size: 12px; line-height: 1.4; color: var(--calls-ink); }
.calls-ai__text b { font-weight: var(--font-weight-semibold); }
.calls-ai__src { font-size: 10px; color: var(--calls-muted); }

/* ------------------------------------------------------------
   step1 - NIEODEBRANE OBSLUZONE AUTOMATYCZNIE (frontend/task-07 pkt 4)

   Trzeci, celowo MNIEJSZY element panelu: mniejsza skala typografii i wciecie
   z obu stron (92% szerokosci, wysrodkowane) - hierarchia ma byc widoczna bez
   czytania. To domkniecie historii kroku: dwie karty wyzej mowia "wiesz, kto dzwoni",
   ta mowi "a jak nie odbierzesz, system i tak nie zgubi klienta".

   Promien z tokena (`--calls-radius` na karcie, `--calls-radius-s` na wierszu SMS-a),
   zero wlasnych wartosci - patrz tabelka promieni na gorze pliku.
   ------------------------------------------------------------ */
.calls-miss {
  width: 92%;
  align-self: center;
  padding: 12px 13px;
  border-radius: var(--calls-radius);
  display: flex;
  flex-direction: column;
  gap: 9px;
  animation: calls-toast-in 700ms cubic-bezier(0.22, 1.1, 0.36, 1) both;
  animation-delay: 120ms;
}
.calls-miss__head { display: flex; align-items: center; gap: 10px; }
.calls-miss__icon {
  width: 26px;
  height: 26px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-busy-soft);
  color: var(--calls-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.calls-miss__icon .calls-icon { width: 13px; height: 13px; }
.calls-miss__who { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.calls-miss__label { font-size: 10px; color: var(--calls-muted); }
.calls-miss__name {
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-miss__head .calls-badge { flex-shrink: 0; }

/* Wiersz SMS-a: tresc w cudzyslowie, bo to cytat z wiadomosci, ktora klient dostal -
   nie opis funkcji. Nadawca nie jest nazwany swiadomie (uzasadnienie w `_step1.twig`). */
.calls-miss__sms {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 10px;
  border-radius: var(--calls-radius-s);
  background: var(--calls-surface-2);
}
.calls-miss__sms-icon { color: var(--calls-muted); display: inline-flex; flex-shrink: 0; padding-top: 1px; }
.calls-miss__sms-icon .calls-icon { width: 13px; height: 13px; }
.calls-miss__sms-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calls-miss__sms-key {
  font-size: 9.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--calls-faint);
}
.calls-miss__sms-text { font-size: 11.5px; line-height: 1.4; color: var(--calls-ink); }

/* ------------------------------------------------------------
   step1 - dialer + toast: WARIANT ALTERNATYWNY, DZIS NIEUZYWANY.
   Styl trzymany razem z `_step1_dialer.twig` - patrz komentarz w tym pliku
   ("jak go przywrocic"). Bez tych regul powrot do dialera wymagalby napisania
   calej kompozycji od nowa, wiec zostaja mimo ze nic ich dzis nie odpala.
   ------------------------------------------------------------ */
.calls-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 14px 16px;
  border-radius: var(--calls-radius);
  animation: calls-toast-in 620ms cubic-bezier(0.22, 1.1, 0.36, 1) both;
}
.calls-toast__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calls-toast__label { font-size: 11px; color: var(--calls-muted); }
.calls-toast__value { font-size: 15px; font-weight: var(--font-weight-semibold); white-space: nowrap; }
.calls-toast__actions { display: flex; gap: 8px; margin-left: auto; }
.calls-toast .calls-round { width: 34px; height: 34px; }
.calls-toast .calls-round .calls-icon { width: 15px; height: 15px; }

.calls-dialer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 20px 26px;
}
.calls-dialer__label { font-size: 12px; color: var(--calls-ok); font-weight: var(--font-weight-medium); }
.calls-dialer__number {
  font-size: 23px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.calls-dialer__keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  margin-top: 6px;
}
.calls-key {
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--calls-surface-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
}
.calls-key__digit { font-size: 19px; font-weight: var(--font-weight-semibold); line-height: 1; }
.calls-key__letters { font-size: 7px; letter-spacing: 0.12em; color: var(--calls-faint); line-height: 1; }
.calls-dialer .calls-round--call {
  position: relative;
  width: 56px;
  height: 56px;
  margin-top: 12px;
  background: var(--calls-ok);
  color: var(--color-fg-white);
}
/* Halo jako skalowany pierscien (transform+opacity = kompozytor), NIE animowany
   box-shadow - ten przemalowuje element w kazdej klatce i Firefox na tym siada. */
.calls-dialer .calls-round--call::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--calls-ok);
  animation: calls-ring 2.6s ease-out infinite;
  pointer-events: none;
}
.calls-dialer .calls-round--call .calls-icon { width: 24px; height: 24px; }

/* ------------------------------------------------------------
   step2/3 - notyfikacja SMS
   ------------------------------------------------------------ */
.calls-scene--sms { align-items: center; padding: 40px 0; }

.calls-ripple {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1px;
  height: 1px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.calls-ripple span {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.13);
  transform: translate(-50%, -50%);
  animation: calls-ripple 5.4s ease-out infinite;
}
.calls-ripple span:nth-child(1) { width: 220px; height: 220px; }
.calls-ripple span:nth-child(2) { width: 340px; height: 340px; animation-delay: 1.8s; }
.calls-ripple span:nth-child(3) { width: 470px; height: 470px; animation-delay: 3.6s; }

.calls-notif {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--calls-radius);
  width: 100%;
  animation: calls-toast-in 620ms cubic-bezier(0.22, 1.1, 0.36, 1) both;
}
/* Kafel znaku: `--calls-radius-s` na kwadracie 40 px daje geometrie ikony aplikacji -
   czyli to, czym ten element jest w notyfikacji systemowej. */
.calls-notif__icon { width: 40px; height: 40px; border-radius: var(--calls-radius-s); overflow: hidden; flex-shrink: 0; }
.calls-notif__body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 3px; }
.calls-notif__head { display: flex; align-items: center; gap: 7px; }
.calls-notif__app { font-size: 13px; font-weight: var(--font-weight-semibold); }
.calls-notif__head .calls-dot { width: 6px; height: 6px; animation: calls-blink 2.4s ease-in-out infinite; }
.calls-notif__time { margin-left: auto; font-size: 12px; color: var(--calls-faint); font-variant-numeric: tabular-nums; }
.calls-notif__msg { font-size: 13px; color: var(--calls-ink); white-space: nowrap; }
.calls-notif__msg b { font-weight: var(--font-weight-semibold); letter-spacing: 0.03em; }

.calls-bubble {
  position: relative;
  color: rgba(255, 255, 255, 0.82);
  width: 132px;
  height: 132px;
  display: block;
  margin: 26px auto 0;
  align-self: flex-start;
  margin-left: 6%;
}
.calls-bubble .calls-icon { width: 100%; height: 100%; stroke-width: 1.4; }
.calls-bubble__dot {
  position: absolute;
  right: 12px;
  top: 2px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--calls-accent);
  box-shadow: 0 6px 16px rgba(255, 10, 113, 0.5);
  animation: calls-bob 3.4s ease-in-out infinite;
}

/* ------------------------------------------------------------
   step4 - TRANSKRYPCJA Z KLUCZOWYMI MOMENTAMI (frontend/task-06)

   Cztery typy momentow (objection / amount / signal / promise) maja jeden kolor
   uzyty w DWOCH miejscach: podswietlenie w tekscie i znacznik na osi fali. Dlatego
   ich kolory stoja obok siebie w jednej tabelce - rozjechanie sie ich zerwaloby
   zwiazek "ten pin = ten fragment rozmowy", ktory jest calym sensem tego panelu.
   ------------------------------------------------------------ */
.calls-scene--talk { gap: 14px; }

.calls-tr { padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 13px; }
.calls-tr__head { display: flex; align-items: center; gap: 11px; }
.calls-tr__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.calls-tr__name {
  font-size: 14.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-tr__meta { font-size: 11px; color: var(--calls-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.calls-tr__head .calls-badge { font-variant-numeric: tabular-nums; }
.calls-tr__head .calls-badge .calls-icon { width: 11px; height: 11px; }

/* Os nagrania: fala + znaczniki. `position: relative` na torze, `left: var(--x)`
   na pinach - procent osi idzie z Twiga razem z kolejnoscia momentow w rozmowie. */
.calls-tr__track { position: relative; display: block; padding-bottom: 9px; }
.calls-tr__axis {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  height: 1px;
  background: var(--calls-line);
}
.calls-tr__pin {
  position: absolute;
  bottom: 3px;
  left: var(--x);
  width: 11px;
  height: 11px;
  margin-left: -5.5px;
  border-radius: 50%;
  border: 2px solid var(--calls-surface);
  background: var(--calls-muted);
}
/* Pin obietnicy pulsuje - JEDYNY ruch w tym panelu i wylacznie na `opacity`.
   Nagranie jest skonczone i przeanalizowane, wiec nic tu nie ma prawa "leciec
   na zywo"; animowanego pisania tekstu nie ma w ogole (wymog operatora). */
.calls-tr__pin--promise { animation: calls-blink 2.8s ease-in-out infinite; }

.calls-tr__pin--objection { background: var(--calls-away); }
.calls-tr__pin--amount    { background: var(--calls-info); }
.calls-tr__pin--signal    { background: var(--calls-ok); }
.calls-tr__pin--promise   { background: var(--calls-accent); }

/* Fala: slupki maja PELNA wysokosc i sa skalowane transformem (`--amp` z Twiga, 0-100).
   Animowanie `height` przeliczalo layout kilka razy na klatke - to bylo najdrozsze
   miejsce calego motywu i wlasnie na nim Firefox sie zacinal. Tu fala jest statyczna. */
.calls-wave {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2px;
  height: 34px;
}
.calls-wave span {
  flex: 1 1 0;
  height: 100%;
  min-width: 2px;
  border-radius: 1.5px;
  background: var(--calls-bar-idle);
  transform-origin: bottom;
  transform: scaleY(calc(var(--amp) / 100));
}

/* Transkrypcja: kolumna rozmowcy + tekst. Podswietlenia sa CZESCIA tekstu, wiec
   zawijaja sie razem z nim - `box-decoration-break: clone` pilnuje, zeby fragment
   przelamany na dwie linie mial tlo i zaokraglenie po obu stronach. */
.calls-tr__lines {
  list-style: none;
  margin: 0;
  padding: 11px 0 0;
  border-top: 1px solid var(--calls-line);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
/* TRZY KOLUMNY: rozmowca | tekst | etykieta typu (frontend/task-07 pkt 5).
   Trzecia kolumna to `max-content`, wiec jej szerokosc bierze sie z NAJDLUZSZEJ etykiety
   ("obietnica -> zadanie") i jest wspolna dla wszystkich wierszy - wszystkie etykiety
   staja w jednej pionowej linii przy prawej krawedzi karty, takze te w wierszach, ktore
   etykiety nie maja. Tekst dostaje `minmax(0, 1fr)`: bez zera dlugie slowo rozpycha
   kolumne i etykiety wyjezdzaja za karte.
   `align-items: start` (nie `baseline`) - wiersz ma teraz do trzech linii tekstu,
   a etykieta ma stac przy PIERWSZEJ z nich, nie przy ostatniej. */
.calls-tr__line {
  display: grid;
  /* 74 px na kolumne rozmowcy: "HANDLOWIEC" przy 9.5 px i `letter-spacing: 0.06em`
     mierzy 70 px, wiec 68 px z task-06 sklejalo etykiete z tekstem, gdy tekst
     zaczynal sie od razu. Zmierzone w przegladarce, nie oszacowane. */
  grid-template-columns: 74px minmax(0, 1fr) max-content;
  gap: 8px;
  align-items: start;
}
.calls-tr__speaker {
  font-size: 9.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--calls-faint);
  padding-top: 4px;
}
.calls-tr__line--client .calls-tr__speaker { color: var(--calls-accent); }
.calls-tr__line--agent .calls-tr__speaker  { color: var(--calls-info); }
.calls-tr__text { font-size: 12px; line-height: 1.55; color: var(--calls-ink); }

.calls-tr__mark {
  background: var(--calls-surface-2);
  color: var(--calls-ink);
  font-weight: var(--font-weight-medium);
  padding: 1px 3px;
  border-radius: var(--calls-radius-xs);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* Etykieta stoi POZA tekstem (osobna komorka grida), wiec nie ma prawa wplynac
   na zawijanie <mark> - `box-decoration-break` na podswietleniu dziala jak dotad.
   `grid-column: 3` jest jawne: wiersze bez etykiety nie maja trzeciego dziecka,
   a auto-placement wsadzilby etykiete w kolumne 2, gdyby ktos kiedys dodal wiersz
   bez tekstu. */
.calls-tr__tag {
  grid-column: 3;
  justify-self: end;
  margin-top: 2px;
  padding: 2px 6px;
  border-radius: var(--calls-radius-xs);
  font-size: 8.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-fg-white);
  white-space: nowrap;
}
.calls-tr__mark--objection { background: var(--calls-away-soft); }
/* Kwota nie moze sie zlamac miedzy liczba a waluta ("74 500" / "zl" w dwoch liniach
   czyta sie jak dwie rozne dane) - to jedyne podswietlenie z `nowrap`. */
.calls-tr__mark--amount    { background: var(--calls-info-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.calls-tr__mark--signal    { background: var(--calls-ok-soft); }
.calls-tr__mark--promise   { background: var(--calls-busy-soft); }
.calls-tr__tag--objection { background: var(--calls-away); }
.calls-tr__tag--amount    { background: var(--calls-info); }
.calls-tr__tag--signal    { background: var(--calls-ok); }
.calls-tr__tag--promise   { background: var(--calls-accent); }

/* Zetony pod karta: co z rozmowy ZOSTAJE, kiedy sie skonczy. Stoja na ciemnym
   gradiencie, wiec sa szklane - bez `backdrop-filter`, ktory kosztuje osobna
   warstwe kompozytora, a pod spodem i tak jest gladki gradient. */
.calls-tokens { display: flex; flex-wrap: wrap; gap: 8px; }
.calls-token {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: var(--color-fg-white);
  font-size: 11.5px;
}
.calls-token b { font-weight: var(--font-weight-semibold); }
.calls-token .calls-icon { width: 13px; height: 13px; }
.calls-token--task .calls-icon { color: var(--calls-token-ok); }
.calls-token--hot .calls-icon  { color: var(--calls-token-hot); }

/* ------------------------------------------------------------
   step5 - JEDNA TABLICA, KTORA COS ROBI (frontend/task-08)

   Poprzednia wersja (task-07) miala DWIE tablice, szesc naglowkow kolumn i osiem kartek,
   kazda z wlasna obwodka i kolorowym paskiem z lewej - szesnascie obiektow w kadrze.
   Operator odrzucil ja jako "pomniejszony zrzut ekranu": panel pokazywal SPIS TRESCI,
   a kroki 1 i 4 (przyjete) pokazuja JEDNA SCENE. Zdjete zostaly: druga tablica
   (`--stacked`), kolumny jako pudelka z tlem (`.calls-col`), kropki i liczniki
   w naglowkach kolumn, kolorowe krawedzie kartek (`--lane`) i kartki-zgloszenia
   z notatka zamiast kwoty (`.calls-deal__note`).

   TERAZ SA TRZY RZECZY I ANI JEDNEJ WIECEJ:
     1. pasek zakladek = jednoczesnie naglowek karty (aktywna zakladka JEST tytulem
        tablicy, wiec osobny wiersz z nazwa i ikona nie jest juz potrzebny),
     2. trzy tory - naglowek + cienka kreska pod nim, zero tla i zero ramek,
     3. trzy kartki, z ktorych JEDNA jest w ruchu.

   KARTKA W RUCHU - JAK JEST ZROBIONA. Ruch niosa trzy rzeczy naraz i zadna z nich
   nie jest animacja:
     - duch (`.calls-ghost`) na starej pozycji w torze `Oferta` - przerywany obrys
       o wysokosci kartki, z szewronem w prawo,
     - kartka `--moved` uniesiona o 10 px nad torem `Finalizacja`, z cieniem
       `--calls-lift` (nizszym i szerszym niz na kartkach lezacych) i minimalnym
       obrotem - to cien niesie informacje "wisi w powietrzu", nie sam przesuw,
     - plakietka "przesunieta po rozmowie" na kartce.
   Delikatne unoszenie (`calls-deal-lift`) tylko dodaje zycia. Jest na `transform`,
   a `prefers-reduced-motion` zdejmuje animacje i zostawia SAM przesuw z reguly bazowej -
   kadr bez animacji dalej opowiada to samo.

   Miejsce na uniesienie jest wygospodarowane w `.calls-lane__cards` (`padding-top: 16px`)
   i to dlatego jest tam wiecej zapasu, niz wynikaloby z odstepow: bez niego kartka
   dotykalaby kreski toru i czytaloby sie to jak "wjechala w naglowek", a nie "wisi".
   ------------------------------------------------------------ */
.calls-scene--board { align-items: stretch; }

.calls-board {
  padding: 15px 15px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Pasek zakladek: cztery procesy w jednej linijce zamiast rysowania drugiej tablicy.
   Aktywna dostaje jedyny akcent w calym panelu; pozostale sa szare i nie konkuruja.
   `flex-wrap` jest zabezpieczeniem na waski panel (ok. 769-1000 px szerokosci okna) -
   pasek ma sie tam zlamac, a nie wyjechac poza karte. */
.calls-board__tabs { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
.calls-board__tab {
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--calls-faint);
  white-space: nowrap;
}
.calls-board__tab.is-active {
  background: var(--calls-accent-wash);
  color: var(--calls-accent);
  font-weight: var(--font-weight-semibold);
}
/* Licznik na bialej karcie: bazowy `--calls-faint` na tle `--calls-surface-2` jest tu
   praktycznie niewidoczny (ta sama pulapka, ktora zrodla `.calls-ask__chips` na /done). */
.calls-board__tabs .calls-chip { margin-left: auto; color: var(--calls-muted); }

/* `minmax(0, 1fr)` zamiast samego `fr`: `fr` ma minimum `auto`, wiec dluzsza nazwa
   klienta rozpychala tor ponad przydzial, a pozostale robily sie paskami. */
.calls-board__lanes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.calls-lane { display: flex; flex-direction: column; min-width: 0; }
/* Nazwy etapow na kolorowych tlach - kolor idzie ZA ETAPEM, nie za klientem (kartki
   zostaja neutralne, wiec panel nadal nie migocze). Kolejnosc czyta sie jak postep:
   chlodny start, ciepla srodkowa faza, zielony finisz. */
.calls-lane__name {
  display: block;
  padding: 5px 9px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-lane-wash, var(--calls-surface-2));
  color: var(--calls-lane-ink, var(--calls-muted));
  font-size: 11.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-lane:nth-child(1) { --calls-lane-wash: rgba(47, 128, 237, 0.12); --calls-lane-ink: #1f66c4; }
.calls-lane:nth-child(2) { --calls-lane-wash: rgba(224, 138, 18, 0.14); --calls-lane-ink: #b76c0d; }
.calls-lane:nth-child(3) { --calls-lane-wash: rgba(31, 164, 92, 0.14);  --calls-lane-ink: var(--calls-ok); }
/* `min-height` daje torom cialo. Tablica z trzema kartkami i bez zapasu pod nimi ma
   ok. 250 px wysokosci i na panelu 1080 px wyglada na wcieta; tor, ktory ma miejsce
   na kolejne sprawy, jest tez po prostu prawda o Kanbanie. */
.calls-lane__cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 18px;
  min-height: 230px;
}

.calls-deal {
  background: var(--calls-surface);
  border: 1px solid var(--calls-line);
  border-radius: var(--calls-radius-s);
  box-shadow: var(--calls-shadow-xs);
  padding: 10px 11px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.calls-deal__client {
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-deal__amount {
  font-size: 13.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Kartka zostaje BIALA. Wash akcentu, ktory miala w task-07, wypadl: akcent w tym panelu
   ma byc jeden (aktywna zakladka) plus plakietka, a rozowy spod kartki robil z niej
   trzeci rozowy obiekt w kadrze. Ze to ta wazna, mowi uniesienie i cien. */
.calls-deal--moved {
  position: relative;
  z-index: 1;
  box-shadow: var(--calls-lift);
  transform: translateY(-12px) rotate(-1.8deg);
  animation: calls-deal-lift 4.4s ease-in-out infinite;
}

/* Kartka WPADAJACA do "Kontaktu klienta": czesciowo WYSUNIETA POZA karte tablicy
   (w dol i w lewo), zeby czytalo sie jako "wlasnie tu wjezdza", a nie "stoi krzywo
   w srodku". `transform` nie zmienia layoutu, wiec tablica nie rosnie - kartka po prostu
   wychodzi za jej krawedz. Obrot w druga strone niz kartka przesuwana w "Finalizacji":
   na tablicy dzieja sie dwie rozne rzeczy i nie moga wygladac jak jedna.
   BEZ ANIMACJI (decyzja operatora): plywa juz kartka w "Finalizacji", dwie ruszajace
   sie rzeczy naraz robily z panelu karuzele. */
.calls-deal--incoming {
  position: relative;
  z-index: 2;
  box-shadow: var(--calls-lift);
  transform: translate(-42px, 34px) rotate(-7deg);
}
/* Plakietka "przesunieta po rozmowie" - to ona sprzedaje ten krok, wiec dostaje pelna
   szerokosc kartki i akcent. Zawijanie jest dozwolone (na 1366 px tor ma ok. 160 px,
   a napis siedzi na granicy) - stad `line-height`, a nie `nowrap`. */
.calls-deal__moved {
  display: flex;
  align-items: flex-start;
  gap: 5px;
  margin-top: 4px;
  padding-top: 7px;
  border-top: 1px dashed var(--calls-line);
  color: var(--calls-accent);
  font-size: 10px;
  font-weight: var(--font-weight-semibold);
  line-height: 1.35;
}
.calls-deal__moved .calls-icon { width: 11px; height: 11px; flex-shrink: 0; margin-top: 2px; }

/* Duch: puste miejsce po kartce, ktora wlasnie poszla w prawo. Wysokosc rowna kartce
   BEZ plakietki - to ta sama sprawa sprzed przeniesienia, a nie osobny obiekt.
   Obrys z `--calls-line-strong`, bo `--calls-line` na bieli jest niewidoczny. */
.calls-ghost {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-height: 58px;
  padding: 0 11px;
  border: 1.5px dashed var(--calls-line-strong);
  border-radius: var(--calls-radius-s);
  background: var(--calls-surface-2);
  color: var(--calls-faint);
}
.calls-ghost .calls-icon { width: 18px; height: 18px; }

/* ------------------------------------------------------------
   step6 - DWA WIDOKI TEJ SAMEJ LISTY (frontend/task-08)

   Poprzednia wersja (task-06) byla LISTA KATALOGOWA: szesc wierszy pracownikow, szesc
   kolorow awatarow, numery wewnetrzne, statusy - a najwazniejsze zdanie ("kto co widzi")
   bylo najmniejszym tekstem na karcie. Operator odrzucil ja z tego powodu. Zdjete
   zostaly w calosci: `.calls-team`, `.calls-tab`, `.calls-scope`, `.calls-person`,
   `.calls-add` i piec z szesciu tonow awatara.

   TERAZ: jedna karta, dwie kolumny, TA SAMA lista rozmow w obu. Roznice widac bez
   czytania - u handlowca dwie pozycje sa zaslonione. Markup renderuje jedna tablice
   `calls` dwa razy, wiec listy nie da sie przypadkiem rozjechac przy edycji danych.

   TON: to ma czytac sie jako OCHRONA DANYCH, a nie jako "system cos przed toba ukrywa".
   Stad zaslonieta pozycja jest SZARA i mala (zero czerwieni, zero ostrzezen), klodka
   siedzi w bialym kolku jak ikona statusu, a podpis mowi, CZYJA jest ta rozmowa,
   nie ze dostep zostal odebrany.

   JEDEN AKCENT NA CALY PANEL: plakietka `Wlasciciel`. To widok osoby, ktora wlasnie
   wypelnia formularz - tam ma trafic wzrok. Wszystko inne jest neutralnie szare.
   ------------------------------------------------------------ */
.calls-scene--views { align-items: stretch; }

/* ------------------------------------------------------------
   KROK 6, drugi kafelek - ZADANIA ZESPOLU
   Wezszy od karty z widokami i wysuniety w prawo poza jej obrys (ujemny prawy margines),
   z ujemnym gornym - podsuwa sie pod karte jak kartka wpadajaca na kroku 5. Bez animacji.
   ------------------------------------------------------------ */
.calls-tasks {
  align-self: flex-end;
  width: 78%;
  margin: -10px -30px 0 0;
  padding: 13px 15px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
  z-index: 2;
  box-shadow: var(--calls-lift);
}
.calls-tasks__head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  color: var(--calls-ink);
}
.calls-tasks__head .calls-icon { width: 14px; height: 14px; color: var(--calls-accent); }
.calls-tasks__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }

.calls-task {
  display: grid;
  grid-template-columns: 1fr max-content;
  align-items: center;
  gap: 4px 8px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--calls-line);
}
.calls-task:last-child { padding-bottom: 0; border-bottom: none; }
.calls-task__title { font-size: 12px; font-weight: var(--font-weight-semibold); color: var(--calls-ink); }
.calls-task__meta {
  grid-column: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--calls-muted);
}
/* Inicjaly zamiast awatarow ze zdjeciami - ta sama konwencja co w reszcie paneli.
   Kolorowe kolka z biala czcionka: szare na jasnej karcie po prostu znikaly.
   Trzy stonowane barwy (nie akcent panelu) - awatary maja byc rozroznialne,
   a nie konkurowac z plakietkami "z rozmowy" / "zrobione". */
.calls-task__who {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--calls-avatar, var(--calls-surface-2));
  color: var(--color-fg-white);
  font-size: 8.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
}
.calls-task__who--a { --calls-avatar: #6d4bd1; }
.calls-task__who--b { --calls-avatar: #2f7fd6; }
.calls-task__who--c { --calls-avatar: #17998c; }
.calls-task__tag {
  grid-row: 1;
  grid-column: 2;
  padding: 2px 8px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-accent-wash);
  color: var(--calls-accent);
  font-size: 10px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.calls-task__tag--done { background: var(--calls-ok-soft); color: var(--calls-ok); }
/* Zrobione: tytul przygaszony, zeby oko szlo do tych dwoch, ktore czekaja. */
.calls-task--done .calls-task__title { color: var(--calls-muted); }

/* Na niskim oknie (1366x768 i podobne) dwie karty kroku 6 nie mieszcza sie w panelu -
   scena wychodzila 27 px poza ekran. Scisniete odstepy zamiast mniejszej typografii:
   drobniejszy tekst byl grzechem starej wersji tego kroku i nie wraca. */
@media (max-height: 820px) {
  .calls-views { padding: 11px 0 12px; }
  .calls-view { gap: 7px; }
  .calls-tasks { padding: 10px 15px 11px; gap: 7px; margin-top: -18px; }
  .calls-tasks__list { gap: 6px; }
  .calls-task { padding-bottom: 6px; }
  .calls-scene--views { gap: 10px; }
}

.calls-views {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 17px 0 18px;
}
/* Padding siedzi na kolumnach, a nie na karcie: dzieki temu kreska miedzy widokami
   (`border-left`) idzie przez CALA wysokosc karty, a nie tylko przez tresc. */
.calls-view { display: flex; flex-direction: column; gap: 9px; min-width: 0; padding: 0 16px; }
.calls-view--owner { border-left: 1px solid var(--calls-line); }

.calls-view__head { display: flex; align-items: center; gap: 8px; }
.calls-view__title {
  font-size: 13px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-view__role {
  margin-left: auto;
  flex-shrink: 0;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--calls-surface-2);
  color: var(--calls-muted);
  font-size: 10.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}
.calls-view--owner .calls-view__role { background: var(--calls-accent-wash); color: var(--calls-accent); }

/* `min-height` na dwie linie trzyma poczatki obu list na jednej wysokosci - inaczej
   przy waskim panelu jedno zdanie zawija sie, drugie nie, i porownanie sie rozjezdza. */
.calls-view__scope {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  min-height: 2.7em;
  font-size: 11px;
  line-height: 1.35;
  color: var(--calls-muted);
}
.calls-view__scope .calls-icon { width: 12px; height: 12px; margin-top: 2px; color: var(--calls-faint); flex-shrink: 0; }

/* Wiersze bez ramek i bez cieni - to lista, a nie osiem kartek. Rozdziela je wlosowa
   kreska, dokladnie tak jak transkrypcje na kroku 4 rozdziela `border-top` listy. */
.calls-view__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
/* Klient nad czasem, a nie obok niego: przy panelu 1366 px kolumna ma ok. 230 px,
   a "Amberis Sp. z o.o." plus "11:52 - nieodebrana" w jednej linii potrzebuja 250 px
   i nazwa ucinala sie wielokropkiem. Skracanie nazw klientow odpada - to ten sam zestaw
   firm co na krokach 1, 4 i 5 (zasada 4), wiec musza sie czytac tak samo.
   `min-height` rowna dla wiersza normalnego i zaslonietego: obie listy maja stac
   wiersz w wiersz, inaczej porownanie "to samo, a widac inaczej" przestaje dzialac. */
.calls-call {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  min-height: 56px;
  padding: 10px 8px;
  border-bottom: 1px solid var(--calls-line);
}
.calls-call:last-child { border-bottom: 0; }
.calls-call__client {
  max-width: 100%;
  font-size: 12.5px;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-call__meta {
  font-size: 11px;
  color: var(--calls-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.calls-call--covered {
  flex-direction: row;
  align-items: center;
  gap: 9px;
  background: var(--calls-surface-2);
  border-radius: var(--calls-radius-xs);
  border-bottom-color: transparent;
}
.calls-call__lock {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--calls-surface);
  color: var(--calls-faint);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.calls-call__lock .calls-icon { width: 11px; height: 11px; }
.calls-call__note { font-size: 11.5px; color: var(--calls-muted); min-width: 0; }

/* Podsumowanie zespolu - jedyny wiersz, ktorego handlowiec nie ma. Liczba idzie
   z dlugosci listy, wiec nie da sie jej rozjechac z liczba wierszy wyzej. */
.calls-view__total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 4px;
  padding: 10px 8px 0;
  border-top: 1px solid var(--calls-line);
  font-size: 11.5px;
  color: var(--calls-muted);
}
.calls-view__total b {
  color: var(--calls-ink);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------
   step7 - PULPIT + INSIGHT (frontend/task-06; Autopilot zdjety w frontend/task-07 pkt 7)

   Karta Autopilota wylatuje w calosci razem ze swoim stylem i z plakietka `.calls-soon`
   ("nie robi wow, a sprzedaje funkcje konkurencji, ktorej jeszcze nie mamy" - operator).
   Po jej zdjeciu w calym kreatorze nie ma ANI JEDNEJ rzeczy z roadmapy, wiec nie ma tez
   plakietki "wkrotce" - gdyby cokolwiek z roadmapy mialo tu wrocic, plakietke trzeba
   napisac od nowa i jest ona obowiazkowa (zasada 1 narracji).

   KOMPOZYCJA PO ZDJECIU: w task-06 ten panel byl scisniety pod dwie karty (na 1366x768
   wychodzil poza ekran o 31 px - docinane paddingi, wykres 92 -> 78 px). Teraz karta jest
   jedna, wiec odzyskane miejsce wraca do pulpitu: wieksze paddingi, wieksze odstepy
   miedzy sekcjami i wykres z powrotem na 92 px. Bez tego po Autopilocie zostalaby
   dziura w dolnej polowie panelu.
   ------------------------------------------------------------ */
.calls-scene--stats { gap: 14px; }

.calls-today {
  padding: 20px 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.calls-today__title { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: var(--font-weight-semibold); }
.calls-today__sub { font-size: 12px; color: var(--calls-muted); margin-bottom: 10px; }

/* Liczba glowna: 118 przychodzacych. Wszystkie liczby nizej sa jej czescia
   (96 + 22 = 118, 81% + 19% = 100%) - patrz komentarz w `_step7.twig`. */
.calls-hero { display: flex; align-items: baseline; gap: 9px; margin-bottom: 12px; }
.calls-hero__value {
  font-size: 42px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.calls-hero__label { font-size: 12px; color: var(--calls-muted); }

.calls-split { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
.calls-split__cell {
  border: 1px solid var(--calls-line);
  border-radius: var(--calls-radius-s);
  padding: 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.calls-split__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--calls-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.calls-split__label .calls-icon { width: 12px; height: 12px; flex-shrink: 0; color: var(--calls-faint); }
.calls-split__row { display: flex; align-items: center; gap: 7px; }
.calls-split__value { font-size: 20px; font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; line-height: 1; }
.calls-split__row .calls-badge { margin-left: auto; }

.calls-stat {
  border: 1px solid var(--calls-line);
  border-radius: var(--calls-radius-s);
  padding: 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}
.calls-stat__label { font-size: 13px; font-weight: var(--font-weight-semibold); }
.calls-stat__row { display: flex; align-items: center; gap: 8px; }
.calls-stat__value { margin-left: auto; font-size: 18px; font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; }

.calls-today .calls-ai { margin-top: 14px; }

.calls-chart { display: flex; align-items: flex-end; gap: 6px; height: 92px; margin-top: 6px; }
.calls-chart__col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 100%; }
/* Slupki: dni ktore juz byly + dzisiaj na akcencie, reszta tygodnia przygaszona.
   W poniedzialek akcent ma tylko jeden slupek - dlatego "przygaszony" to nadal
   czytelny roz, a nie prawie-biel (inaczej wykres wygladalby na pusty). */
/* Zero `transition` na wysokosci: slupki maja stala wysokosc z Twiga (`--h`), a JS
   zmienia im tylko klase (kolor). Przejscie na `height` bylo martwe i jednoczesnie
   lamalo zasade "animujemy wylacznie transform i opacity" - zdjete w task-06. */
/* Slupek jest zaokraglony mocniej u gory niz u dolu (u dolu siedzi na osi) - stad
   dwie wartosci, a nie jeden token: to kształt slupka, nie promien karty. */
.calls-chart__bar {
  width: 100%;
  height: var(--h);
  border-radius: var(--calls-radius-xs) var(--calls-radius-xs) 3px 3px;
  background: var(--calls-bar-idle);
}
.calls-chart__col.is-past .calls-chart__bar {
  background: linear-gradient(180deg, var(--calls-accent) 0%, rgba(255, 10, 113, 0.55) 100%);
}
.calls-chart__col.is-today .calls-chart__bar {
  background: linear-gradient(180deg, var(--calls-accent) 0%, rgba(255, 10, 113, 0.72) 100%);
  box-shadow: 0 0 0 2px rgba(255, 10, 113, 0.16);
}
.calls-chart__day { font-size: 10px; color: var(--calls-faint); }
.calls-chart__col.is-today .calls-chart__day { color: var(--calls-accent); font-weight: var(--font-weight-semibold); }

/* ------------------------------------------------------------
   done (/done) - ROZMOWA Z AI O SWOICH ROZMOWACH (frontend/task-06)

   Zastapila karte "workspace gotowy": numer i workspace, ktore ta karta pokazywala,
   znikly z kroku 5 razem z uzasadnieniem (nie mamy ich przy rejestracji), wiec
   podsumowywanie ich na koncu bylo by obiecywaniem tego samego czeku bez pokrycia.
   ------------------------------------------------------------ */
.calls-scene--done { align-items: stretch; }

.calls-ask {
  position: relative;
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Wjazd karty: transform + opacity, jedna klatka na starcie i koniec. */
  animation: calls-toast-in 640ms cubic-bezier(0.22, 1.1, 0.36, 1) both;
}

.calls-ask__head { display: flex; align-items: center; gap: 12px; }
.calls-ask__seal {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--calls-accent-wash);
  color: var(--calls-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.calls-ask__seal .calls-icon { width: 19px; height: 19px; }
.calls-ask__titles { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calls-ask__title {
  font-size: 16.5px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.01em;
}
.calls-ask__sub { font-size: 11.5px; color: var(--calls-muted); line-height: 1.35; }

/* Czat: pytanie po prawej (jak w kazdym komunikatorze), odpowiedz po lewej.
   `max-width` na 88% - dymek na pelna szerokosc karty przestaje czytac sie jak dymek. */
.calls-chat { display: flex; flex-direction: column; gap: 8px; }
.calls-msg {
  display: block;
  max-width: 88%;
  padding: 9px 12px;
  border-radius: var(--calls-radius-s);
  font-size: 12px;
  line-height: 1.5;
}
/* Ogonek dymka: jeden rog schodzi do promienia mikro (`--calls-radius-xs`) i pokazuje,
   z ktorej strony dymek "wychodzi". To jedyne miejsce, gdzie promien jest asymetryczny -
   i jest to kształt dymka, nie odstepstwo od tabelki promieni. */
.calls-msg--me {
  align-self: flex-end;
  background: var(--calls-accent);
  color: var(--color-fg-white);
  border-bottom-right-radius: var(--calls-radius-xs);
}
.calls-msg--ai {
  align-self: flex-start;
  background: var(--calls-surface-2);
  color: var(--calls-ink);
  border-bottom-left-radius: var(--calls-radius-xs);
}
/* Kwoty w odpowiedzi sa pogrubione, bo to one sa odpowiedzia - reszta zdania
   jest uzasadnieniem. Te same liczby co na kroku 4 i 5. */
.calls-msg--ai b { font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; }

/* Wykonane akcje (SMS + zadanie) - asystent nie tylko odpowiada, ale i dziala.
   Karteczka w dymku, nie osobny dymek: to jest CZESC odpowiedzi, a nie kolejna
   wiadomosc. Lewa krawedz koloruje typ akcji (wysylka vs zadanie). */
.calls-act {
  display: block;
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: var(--calls-radius-xs);
  background: var(--calls-surface);
  border: 1px solid var(--calls-line);
  border-left: 3px solid var(--calls-line);
}
.calls-act--sms  { border-left-color: var(--calls-ok); }
.calls-act--task { border-left-color: var(--calls-accent); }
.calls-act__head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.calls-act--sms .calls-act__head  { color: var(--calls-ok); }
.calls-act--task .calls-act__head { color: var(--calls-accent); }
.calls-act__head .calls-icon { width: 12px; height: 12px; }
.calls-act__body {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--calls-muted);
}
.calls-act__body b { color: var(--calls-ink); font-weight: var(--font-weight-semibold); }

/* Przypis pod karta - na ciemnym panelu, wiec biel z niska nieprzezroczystoscia. */
/* Bez `max-width`: przypis ma isc na pelna szerokosc scenki (a ta jest szeroka jak karta),
   inaczej lamal sie w polowie zdania. Szerokosc scenki rzadzi zawijaniem, nie licznik znakow. */
.calls-note {
  margin: 12px 0 0;
  align-self: stretch;
  color: rgba(255, 255, 255, 0.62);
  font-size: 10.5px;
  line-height: 1.4;
  text-align: center;
  text-wrap: balance;
}

/* Karta /done urosla o druga wymiane (polecenie + dwie akcje) i przypis MCP, wiec
   na 1366x768 wychodzila poza ekran. Scena dostaje wariant kompaktowy: mniejsze
   dymki i ciasniejsze akcje. Zadnych zmian w tresci - tylko geometria. */
.calls-scene--done .calls-msg { padding: 7px 11px; font-size: 11.5px; line-height: 1.45; }
.calls-scene--done .calls-chat { gap: 6px; }
.calls-scene--done .calls-act { margin-top: 6px; padding: 6px 9px; }
.calls-scene--done .calls-act__body { font-size: 11px; margin-top: 3px; }
.calls-scene--done .calls-ask__foot { padding-top: 10px; }

.calls-ask__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--calls-line);
}
.calls-ask__foot-label { font-size: 10.5px; color: var(--calls-muted); }
.calls-ask__chips { display: flex; flex-wrap: wrap; gap: 5px; }
/* Zrodla musza CZYTAC sie jak plakietki, nie jak ciag slow: bazowy `.calls-chip` ma tlo
   `--calls-surface-2`, ktore na bialej karcie jest praktycznie niewidoczne (tam, gdzie chip
   siedzi na szarym naglowku tablicy, wystarcza - tu nie). Obwodka + ciemniejszy tekst. */
.calls-ask__chips .calls-chip {
  border: 1px solid var(--calls-line);
  color: var(--calls-ink);
  padding: 3px 9px;
}

/* Tryb zgloszen (pending): konta jeszcze nie ma, wiec pieczatka schodzi z akcentu
   na neutralna, a podtytul mowi wprost "po uruchomieniu konta". Sama rozmowa zostaje -
   pokazuje MOZLIWOSC produktu, a nie stan tego konkretnego konta. */
.calls-ask--pending .calls-ask__seal { background: var(--calls-surface-2); color: var(--calls-muted); }

/* ------------------------------------------------------------
   /setup - PANEL FAZY URUCHAMIANIA KONTA (backend/task-15)
   ------------------------------------------------------------
   Karta dopisuje kolejne pozycje w rytm etapow z lewej kolumny, wiec czekanie jest
   dowodem, ze przestrzen realnie powstaje. Po sukcesie klient laduje na /done, gdzie
   panel pokazuje juz rozmowe z AI (`_done.twig`). */
.calls-build { padding: 17px 18px 18px; display: flex; flex-direction: column; gap: 12px; }
.calls-build__head { display: flex; align-items: center; gap: 11px; }
.calls-build__seal {
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: var(--calls-surface-2);
  color: var(--calls-muted);
  display: grid;
  place-items: center;
  font-size: 17px;
}
.calls-build__titles { display: flex; flex-direction: column; }
.calls-build__title { font-size: 15px; font-weight: var(--font-weight-semibold); }
.calls-build__sub { font-size: 12px; color: var(--calls-muted); }

/* Wysokosc jest zarezerwowana z gory (wiersze siedza w DOM od poczatku, tylko
   niewidoczne) - karta nie podskakuje przy dopisywaniu kolejnych pozycji. */
.calls-build__rows { display: flex; flex-direction: column; }
.calls-build__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 0;
  border-top: 1px solid var(--calls-line);
  font-size: 13px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.calls-build__row.is-in { opacity: 1; transform: none; }
.calls-build__label { color: var(--calls-muted); }
.calls-build__value {
  margin-left: auto;
  font-weight: var(--font-weight-semibold);
  max-width: 62%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.calls-build__value--muted { font-weight: var(--font-weight-regular); color: var(--calls-faint); }
.calls-build__pill {
  margin-left: auto;
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--calls-ok-soft);
  color: var(--calls-ok);
}
.calls-build__pill--pro { background: var(--calls-accent-wash); color: var(--calls-accent); }
.calls-build__avatars { display: flex; margin-left: auto; }
.calls-build__avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  margin-left: -6px;
  border: 2px solid var(--calls-surface);
  display: grid;
  place-items: center;
  font-size: 8.5px;
  font-weight: var(--font-weight-semibold);
  color: #fff;
}
.calls-build__avatar:first-child { margin-left: 0; }
.calls-build__avatar--more { background: var(--calls-faint); }

/* Rotacja funkcji co 7 s - czekanie ma sprzedawac, a nie tylko uspokajac. */
.calls-promo { position: relative; min-height: 92px; align-self: stretch; }
.calls-promo__item {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.5s ease;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 13px 15px;
  border-radius: var(--calls-radius-s);
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: #fff;
}
.calls-promo__item.is-in { opacity: 1; }
.calls-promo__eyebrow {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--tc-logo-accent);
}
.calls-promo__text { font-size: 13px; line-height: 1.45; }

/* ------------------------------------------------------------
   ANIMACJE - swiadomie oszczedne, to tlo formularza a nie atrakcja
   ------------------------------------------------------------ */
@keyframes calls-toast-in {
  from { opacity: 0; transform: translateY(-14px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes calls-ring {
  0%        { opacity: 0.5; transform: scale(1); }
  55%, 100% { opacity: 0; transform: scale(1.62); }
}
@keyframes calls-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
/* `calls-wave` (falujace slupki) zniknelo razem z karta aktywnej rozmowy - fala na
   kroku 4 jest teraz statyczna obwiednia nagrania, ktore juz sie skonczylo. */
@keyframes calls-ripple {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.75); }
  25%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.12); }
}
@keyframes calls-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
/* Kartka przenoszona miedzy torami na kroku 5. Amplituda 4 px - to ma byc oddech
   uniesionej kartki, a nie lot. Obrot powtorzony w obu klatkach, bo keyframe nadpisuje
   caly `transform`; bez tego kartka prostowalaby sie w polowie cyklu.
   Przy `prefers-reduced-motion` animacja znika, a kartka zostaje uniesiona regula
   bazowa - duch i cien niosa te sama informacje bez ruchu. */
@keyframes calls-deal-lift {
  0%, 100% { transform: translateY(-12px) rotate(-1.8deg); }
  50%      { transform: translateY(-16px) rotate(-1.8deg); }
}

@media (prefers-reduced-motion: reduce) {
  .calls-stage *,
  .calls-stage *::before,
  .calls-stage *::after {
    animation: none !important;
    transition: none !important;
  }
  /* Confetti nie da sie "zatrzymac" sensownie - kawalek bez ruchu to smiec na ekranie.
     W wariancie chowamy je w calosci. Wersja domyslna zostaje jak byla: ta regula
     jest w arkuszu wariantu, ktorego bez cookie przegladarka w ogole nie pobiera. */
}
