/* ════════════════════════════════════════════════════════════════
   EKRANY WEJŚCIA — logowanie i pierwsze hasło
   Makieta: docs/Nowy-Design-Kropka/Logowanie.dc.html
   Zmiana:  openspec/changes/redesign-login-ds

   Przestrzeń nazw `.lg-` — arkusz wyspy MUSI trzymać się z dala od
   gołych nazw `.kp-*`, które należą do katalogu
   static/kropka-ds/kp-components.css. Zawężenie prymitywu jest wolne
   i tak tu robimy: `.lg-submit.kp-btn--primary`.

   Ani jednej reguły przypiętej do klasy trybu ciemnego — wypełnienia
   liczą się z tokenów, więc motyw dzieje się sam.
   ════════════════════════════════════════════════════════════════ */

/* Stan „ukryty" atrybutem, nie klasą `.hidden` — blok extra_head stoi
   PRZED Tailwindem, więc reguła wyspy unieważniłaby utility. Sama reguła
   `[hidden] { display: none !important }` żyje wyłącznie w
   `static/kropka-ds/kp-components.css`, który ładuje się przed tym
   arkuszem — duplikat tutaj był zbędny. */

/* ── Scena ──────────────────────────────────────────────────────
   Tło w kropki to ŚWIADOMY wyjątek od reguły 7 DS („tło płaskie").
   Zakres: wyłącznie ekrany wejścia. Uzasadnienie i granice wyjątku:
   docs/DECYZJE.md → „Tło w kropki na ekranach wejścia".

   Kolor kropki liczony z --ink, nie wpisany wprost: w motywie ciemnym
   --ink jest jasny, więc kropki same odwracają się na jasne. */
.lg-root {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6) var(--sp-5);
  background-color: var(--paper);
  background-image: radial-gradient(
    color-mix(in srgb, var(--ink) 10%, transparent) 1px,
    transparent 1.2px
  );
  background-size: 22px 22px;
  background-position: -11px -11px;
}

/* ── Kropki reagujące na kursor ─────────────────────────────────
   Wzór wyżej jest STANEM SPOCZYNKOWYM i zostaje w CSS na zawsze: bez
   JavaScriptu oraz przy „ogranicz ruch" ekran wygląda dokładnie tak jak
   przedtem. Dopiero `static/users/login.js` dokłada płótno rysujące tę samą
   siatkę i wtedy gasi wzór klasą `--live` — inaczej kropki dublowałyby się,
   a nakładające się przezroczystości zrobiłyby ciemniejszy rdzeń.

   Płótno rysuje się z gołego canvasa, nie z elementów DOM: siatka 22px na
   pełnym oknie to kilka tysięcy punktów, a przy kursorze zmienia się ledwie
   setka. Powody odrzucenia wariantów (kropki w DOM, maska CSS) i granice
   wyjątku: docs/DECYZJE.md → „Tło w kropki na ekranach wejścia". */
.lg-root--live { background-image: none; }

.lg-dots {
  position: fixed;
  inset: 0;
  /* ROZMIAR PODANY WPROST, i to nie jest ozdobnik. `<canvas>` jest elementem
     ZASTĘPOWANYM, więc `inset: 0` przy `width: auto` go NIE rozciąga — zostaje
     przy rozmiarze własnym, czyli przy atrybutach `width`/`height`, które skrypt
     ustawia na `szerokość * devicePixelRatio`. Na ekranie o gęstości 2 pudełko
     wychodziło DWA RAZY większe od okna i rysunek pojawiał się dwa razy dalej
     od lewego górnego rogu niż wskaźnik. Przy gęstości 1 oba rozmiary
     przypadkiem się pokrywały, więc pomiar w przeglądarce tego nie złapał. */
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  /* JEDYNE źródło koloru kropki dla skryptu — `getComputedStyle(canvas).color`
     zwraca wartość już policzoną, więc w JS nie ma ani jednego literału barwy,
     a motyw ciemny podąża sam (w nim `--ink` jest jasny). */
  color: var(--ink);
}

/* Ekran wejścia wypisuje się z mobilnego paddingu powłoki.
   `base.html` daje `#main-content` na wąskich ekranach `padding: 4.5rem 26px
   4rem !important` — miejsce na przycisk hamburgera i nagłówek strony. Ekran
   wejścia nie ma ani jednego, ani drugiego (anonim nie dostaje paska bocznego),
   a doliczony padding zwężał kartę na 390px z 350px do 298px, czyli o 15%.

   `!important` jest tu WYŁĄCZNIE po to, żeby pokonać `!important` z base.html —
   bez tego reguła nie ma jak wygrać. Zakres domyka `:has(> .lg-root)`: żadna
   inna strona nie ma takiego dziecka. */
#main-content:has(> .lg-root) { padding: 0 !important; }

/* Wypozycjonowana, bo płótno `.lg-dots` też jest wypozycjonowane: element
   z `z-index: 0` maluje się PONAD nieustawionym potokiem, więc bez tej pary
   canvas przykryłby kartę. */
.lg-shell {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 428px;
}

/* ── Znak marki ─────────────────────────────────────────────── */

.lg-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

/* Kafelka znaku NIE MA już tutaj. Ten sam znak stoi w pasku bocznym, więc
   awansował do katalogu jako `.kp-brand-mark`, a ekrany wejścia wołają go
   partialem `components/brand_mark.html` z `size=36`. Zostawiona tu kopia
   byłaby drugą definicją tego samego kafelka — a ekranowy arkusz wchodzi
   w <head> PO katalogu, więc cicho by go nadpisała.

   Przy okazji naprawiony rozjazd z makietą: dawna reguła dawała kropkę
   Ø12px na kafelku 36px (33%), makieta rysuje 40%. Zaokrąglenie miało 10px
   (28%) zamiast 24%. Katalog trzyma oba w procentach. */

/* Krój TREŚCI, nie display — tak pisze go makieta (`var(--font-body)`
   w wadze 700), mimo że to napis nagłówkowy. */
.lg-brand-name {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 23px;
  letter-spacing: -0.8px;
  color: var(--ink);
}

/* ── Karta ──────────────────────────────────────────────────── */

.lg-card {
  padding: 30px 28px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-bento);
  box-shadow: var(--shadow-hero);
}

.lg-title {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 27px;
  letter-spacing: -0.7px;
  color: var(--ink);
}

.lg-lead {
  margin: 0 0 var(--sp-5);
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}

/* ── Banery komunikatów ─────────────────────────────────────────
   Komunikat mieszka W KARCIE, nie w pasku toastów — toasty są na tych
   dwóch trasach wyłączone w base.html, żeby ten sam tekst nie pojawił
   się dwa razy (decyzja D1). */

.lg-alerts {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-bottom: 18px;
}

/* Baner błędu formularza stoi pod separatorem „albo" i ma przylegać do formularza,
   którego dotyczy — ciaśniej niż komunikaty ogólnostronowe na górze karty.
   Patrz openspec reorder-login-sso-first, decyzja D2. */
.lg-alerts--form {
  margin-bottom: var(--sp-3);
}

.lg-alert {
  display: flex;
  gap: var(--sp-3);
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-sunken);
}

.lg-alert-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--muted);
}

.lg-alert-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lg-alert-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13.5px;
  letter-spacing: -0.2px;
  color: var(--ink);
}

.lg-alert-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}

.lg-alert--error   { background: var(--status-urgent-bg);  border-color: var(--status-urgent); }
.lg-alert--error   .lg-alert-dot { background: var(--status-urgent); }

.lg-alert--warning { background: var(--status-warning-bg); border-color: var(--status-warning); }
.lg-alert--warning .lg-alert-dot { background: var(--status-warning); }

.lg-alert--ok      { background: var(--status-ok-bg);      border-color: var(--status-ok); }
.lg-alert--ok      .lg-alert-dot { background: var(--status-ok); }

.lg-alert--info    { background: var(--status-info-bg);    border-color: var(--border); }
.lg-alert--info    .lg-alert-dot { background: var(--status-info); }

/* ── Formularz ──────────────────────────────────────────────── */

.lg-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.lg-group {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.lg-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
}

.lg-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: -0.1px;
  color: var(--ink-2);
}

/* Zawężenie prymitywu katalogu: metryka pola wejścia jest większa niż
   w tabelach i filtrach. 16px to nie estetyka — poniżej tej wartości
   iOS Safari przybliża widok przy wejściu w pole. */
/* Waga 400, nie katalogowe 500: makieta pisze w polu tekstem zwykłym.
   Katalog celuje w pola tabelaryczne, gdzie 500 daje czytelność w gęstym
   wierszu — na ekranie wejścia pole jest jedno i duże. */
.lg-input.kp-field {
  height: 48px;
  padding: 0 14px;
  border-radius: var(--r-card);
  font-size: 16px;
  font-weight: 400;
}

.lg-input.kp-field[aria-invalid="true"] {
  border-color: var(--status-urgent);
  background: var(--status-urgent-bg);
}

.lg-pass-wrap { position: relative; }

.lg-pass-wrap .lg-input.kp-field { padding-right: 50px; }
/* Edge dokłada do pól hasła WŁASNE oczko podglądu (`::-ms-reveal`) — obok naszego
   `.lg-pass-toggle` stały dwa przyciski robiące to samo. Chowamy wbudowane tylko tam,
   gdzie jest nasz przycisk; inne pola hasła zachowują podgląd przeglądarki. */
.lg-pass-wrap .lg-input::-ms-reveal,
.lg-pass-wrap .lg-input::-ms-clear { display: none; }

.lg-pass-toggle {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.lg-pass-toggle:hover { background: var(--bg-sunken); color: var(--ink); }

.lg-fieldnote {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--hint);
}

.lg-fieldnote--error { color: var(--status-urgent); }

/* ── Przyciski ──────────────────────────────────────────────────
   Oba zawężają prymityw katalogu do pełnej szerokości i wysokości 48px.
   Kolory, krój i stan `:active` zostają katalogowe. */

.lg-submit.kp-btn,
.lg-google.kp-btn,
.lg-central.kp-btn {
  width: 100%;
  height: 48px;
  justify-content: center;
  /* Padding katalogowy (9/16) jest po to, żeby przycisk objął tekst. Tutaj
     przycisk ma stałą wysokość i pełną szerokość, a treść jest wyśrodkowana,
     więc padding niczego nie zmienia. Wartość równa tej, którą raportuje
     makieta (domyślna przeglądarki dla <button>) — zapisana wprost, żeby
     raport zgodności nie szumiał na właściwości bez wpływu na wygląd. */
  padding: 1px 6px;
}

/* Metryka z makiety: CTA 15.5px z odstępem 9px, Google 15px z odstępem 10px. */
.lg-submit.kp-btn {
  font-size: 15.5px;
  gap: 9px;
  box-shadow: var(--shadow-soft);
}

/* Makieta rysuje główne CTA bez obramowania. Katalog daje 1px w kolorze
   przezroczystym — niewidoczne, ale wchodzi w wymiar i w pomiar. */
.lg-submit.kp-btn--primary {
  border-width: 0;
  border-style: none;
  /* Katalog gasi obramowanie kolorem przezroczystym; makieta nie ma go wcale,
     więc raportuje `currentColor`. Przy zerowej szerokości bez znaczenia dla
     wyglądu — zrównane, żeby raport zgodności nie szumiał. */
  border-color: currentColor;
}

.lg-google.kp-btn,
.lg-central.kp-btn {
  font-size: 15px;
  gap: 10px;
  box-shadow: var(--shadow-soft);
}

/* Centralne logowanie i Google stoją jeden pod drugim w tej samej kolumnie. */
.lg-social + .lg-social { margin-top: var(--sp-2); }

.lg-submit.kp-btn[disabled],
.lg-google.kp-btn[disabled] {
  cursor: default;
  opacity: 0.72;
}

.lg-spin {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--on-overlay) 35%, transparent);
  border-top-color: var(--on-overlay);
  animation: lg-spin 0.7s linear infinite;
}

.lg-google .lg-spin {
  border-color: var(--border);
  border-top-color: var(--muted);
}

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

@media (prefers-reduced-motion: reduce) {
  .lg-spin { animation: none; }
}

/* ── Separator „albo" ───────────────────────────────────────── */

/* Odstępy odwrócone względem redesign-login-ds: separator stoi teraz MIĘDZY blokiem
   Google a formularzem, więc większy oddech należy się stronie formularza. */
.lg-sep {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: 18px 0 22px;
}

.lg-sep::before,
.lg-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.lg-sep-word {
  font-size: 12px;
  color: var(--hint);
}

/* ── Warstwa Google ─────────────────────────────────────────── */

.lg-social {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

/* Podpisu pod przyciskiem Google tu NIE MA — zdanie o zgodzie na kalendarz
   zniknęło razem z klasą `.lg-social-note`. Powód: ten sam ekran zgody pokazuje
   samo Google zaraz po kliknięciu, więc produkt zapowiadał cudzy dialog. Makieta
   `Logowanie v2.dc.html` wciąż go rysuje — to zapisane odstępstwo (6) w
   `docs/Nowy-Design-Kropka/contracts/Logowanie.anchors.json`. */

/* ── Stopka karty i stopka strony ───────────────────────────── */

.lg-support {
  margin-top: 22px;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}

.lg-support-text {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}

.lg-support-text a { color: var(--link-ink); }

.lg-meta {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: var(--sp-5);
  font-size: 11.5px;
  color: var(--hint);
}

/* Kolejne przyciski pełnej szerokości (krok „Zabezpiecz konto”, noty po logowaniu) nie stykają się. */
.lg-submit.kp-btn + .lg-submit.kp-btn,
.lg-submit.kp-btn + .lg-google.kp-btn,
form + .lg-social,
.lg-social + .lg-submit.kp-btn {
  margin-top: var(--sp-3);
}

.lg-title + .lg-notice {
  margin-top: var(--sp-4);
}

/* ── Pasek ostrzeżenia na ekranie pierwszego hasła ──────────── */

.lg-notice {
  display: flex;
  gap: var(--sp-3);
  padding: 12px 14px;
  margin-bottom: 18px;
  border: 1px solid var(--status-warning);
  border-radius: var(--r-card);
  background: var(--status-warning-bg);
}

.lg-notice-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}

/* Tryb ciemny siedzi w warstwie tokenów — `static/kropka-ds/tokens-colors.css`,
   w bloku przypiętym do klasy motywu na <body>. Tam jest miejsce na wartości
   wpisane wprost; ten arkusz ich nie trzyma i nie ma ani jednej własnej reguły
   motywu (wypełnienia liczą się względem `var(--surface)`, więc podążają za nim
   same). Nie wpisuj tu nazwy tamtego selektora nawet w komentarzu — kontrola
   `test_entry_stylesheet_has_no_theme_class_rules` szuka jej jako podciągu
   w całym pliku i nie odróżnia reguły od komentarza.
   Bez ciasteczka `kropka_dark` ekran renderuje się JASNY — preferencja systemu
   nie ma tu głosu. Patrz openspec fix-login-default-light-theme, decyzja D1. */
