/*
 * Układ aplikacji: powłoka, nagłówek, ekran uwierzytelniania, lista projektów.
 * Układ tablicy Kanban znajduje się w osobnym pliku (board.css).
 */

/* =========================================================================
 * Powłoka aplikacji
 *
 * Wysokość ustalona na 100dvh, nie 100vh. Na urządzeniach mobilnych pasek
 * adresu przeglądarki chowa się przy przewijaniu, przez co 100vh jest
 * wyższe od faktycznie widocznego obszaru — dolna część układu chowa się
 * pod paskiem. Jednostka dvh odnosi się do obszaru rzeczywiście widocznego.
 * ====================================================================== */

.app-shell {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow: hidden;
}

/* Obszar treści — jedyny element z własnym przewijaniem. Przewijanie całej
   strony przy przyklejonym nagłówku wymagałoby pozycjonowania lepkiego
   i rezerwowania miejsca; ograniczenie go do jednego obszaru jest prostsze. */
.app-main {
    flex: 1;
    min-height: 0; /* pozwala elementowi zmniejszyć się poniżej treści */
    overflow: auto;
}

/* =========================================================================
 * Nagłówek
 * ====================================================================== */

.topbar {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-shrink: 0;

    height: 48px;
    padding: 0 var(--space-4);

    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.topbar__brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);

    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
}

/*
 * Znak aplikacji w pasku górnym.
 *
 * Wysokość zadana, szerokość wynikowa — plik ma proporcje 69×24 i nie może
 * się zniekształcić. Zadanie samej wysokości sprawia też, że znak skaluje się
 * razem z paskiem, gdyby ten kiedyś zmienił rozmiar.
 */
.topbar__logotype {
    height: 22px;
    width: auto;
    display: block;
}

/* Separator ścieżki nawigacyjnej. */
.topbar__divider {
    color: var(--text-subtle);
    user-select: none;
}

.topbar__title {
    font-size: var(--text-sm);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Element rozpychający — grupa po prawej stronie nagłówka. */
.topbar__spacer {
    flex: 1;
}

.topbar__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* =========================================================================
 * Menu użytkownika
 * ====================================================================== */

.menu {
    position: relative;
}

.menu__panel {
    position: absolute;
    top: calc(100% + var(--space-2));
    right: 0;
    z-index: var(--z-dropdown);

    min-width: 12rem;
    padding: var(--space-1);

    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-overlay);
}

.menu__header {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--space-1);
}

.menu__name {
    font-size: var(--text-sm);
    font-weight: 500;
}

.menu__email {
    font-size: var(--text-xs);
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
}

.menu__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-3);

    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    text-align: left;
    color: var(--text);
    /* Pozycją menu bywa też odnośnik (profil), a nie tylko przycisk. */
    text-decoration: none;
}

.menu__item:hover {
    background: var(--surface-hover);
}

.menu__item--danger {
    color: var(--danger);
}

/* =========================================================================
 * Powiadomienia
 * ====================================================================== */

.notifications__badge {
    position: absolute;
    top: 2px;
    right: 2px;

    min-width: 15px;
    height: 15px;
    padding: 0 3px;

    display: grid;
    place-items: center;

    background: var(--danger);
    color: white;
    border-radius: var(--radius-full);

    font-size: 9px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    /* Obramowanie w kolorze paska oddziela wskaźnik od ikony pod spodem. */
    box-shadow: 0 0 0 2px var(--surface);
}

/* Wskaźnik pozycjonowany względem przycisku. */
.notifications .btn--icon {
    position: relative;
}

.notifications__panel {
    width: 22rem;
    max-width: calc(100vw - var(--space-4) * 2);
    padding: 0;
}

.notifications__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border);
}

.notifications__list {
    /* Lista ograniczona wysokością — panel nie może wyjść poza ekran przy
       kilkudziesięciu powiadomieniach. */
    max-height: 24rem;
    overflow-y: auto;
    padding: var(--space-1);
}

.notifications__item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-2) var(--space-3);

    border-radius: var(--radius-sm);
    text-align: left;
    font-size: var(--text-sm);
    line-height: var(--leading-tight);
}

.notifications__item:hover {
    background: var(--surface-hover);
}

/*
 * Nieprzeczytane wyróżnione paskiem i tłem, nie samym pogrubieniem —
 * kolor akcentu przy krawędzi jest widoczny obwodowo, przy przebieganiu
 * listy wzrokiem.
 */
.notifications__item--unread {
    background: var(--accent-subtle);
    box-shadow: inset 2px 0 0 var(--accent);
}

.notifications__icon {
    flex-shrink: 0;
    font-size: var(--text-md);
    line-height: 1.2;
}

.notifications__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.notifications__time {
    font-size: var(--text-xs);
    color: var(--text-subtle);
}

.notifications__empty {
    padding: var(--space-5) var(--space-4);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* =========================================================================
 * Ekran uwierzytelniania
 * ====================================================================== */

.auth {
    display: grid;
    place-items: center;
    min-height: 100dvh;
    padding: var(--space-4);
}

.auth__box {
    width: 100%;
    max-width: 22rem;
}

.auth__header {
    margin-bottom: var(--space-6);
    text-align: center;
}

.auth__title {
    font-size: var(--text-xl);
    margin-bottom: var(--space-2);
}

.auth__subtitle {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.auth__form {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.auth__switch {
    margin-top: var(--space-5);
    text-align: center;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* Komunikat błędu dotyczący całego formularza (np. błędne dane logowania),
   w odróżnieniu od błędu przypisanego do pojedynczego pola. */
.auth__error {
    padding: var(--space-3);
    background: var(--danger-subtle);
    border: 1px solid var(--danger);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    color: var(--danger);
}

/* =========================================================================
 * Lista projektów
 * ====================================================================== */

.projects {
    max-width: 60rem;
    margin: 0 auto;
    padding: var(--space-6) var(--space-4);
}

.projects__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}

.projects__title {
    font-size: var(--text-lg);
}

/*
 * Siatka samodopasowująca się. `auto-fill` z `minmax` sprawia, że liczba
 * kolumn wynika z dostępnej szerokości — bez zapytań o media i bez progów
 * dobieranych ręcznie. Na wąskim ekranie powstaje jedna kolumna, na szerokim
 * trzy, a przejście następuje płynnie.
 */
.projects__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: var(--space-3);
}

.project-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);

    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);

    color: inherit;
    text-decoration: none;
    transition: border-color var(--duration-fast) var(--ease-out),
                background-color var(--duration-fast) var(--ease-out);
}

.project-card:hover {
    border-color: var(--border-strong);
    background: var(--surface-hover);
}

.project-card__name {
    font-size: var(--text-md);
    font-weight: 600;
}

.project-card__description {
    font-size: var(--text-sm);
    color: var(--text-muted);

    /* Ograniczenie do dwóch wierszy — karty w siatce muszą mieć zbliżoną
       wysokość, inaczej rzędy się rozjeżdżają. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.project-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: var(--space-2);

    font-size: var(--text-xs);
    color: var(--text-muted);
}

.project-card__meta {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

/* =========================================================================
 * Profil użytkownika
 *
 * Układ znany z serwisów społecznościowych: pas tła, awatar wchodzący na
 * jego dolną krawędź, pod nim nazwa i tablice. Wybór nie jest naśladownictwem
 * — ten układ jest po prostu ROZPOZNAWALNY, a strona profilu w narzędziu do
 * pracy nie jest miejscem na uczenie użytkownika nowej konwencji.
 *
 * Szerokość taka sama jak listy projektów (60 rem), żeby przejście między
 * tymi widokami nie przesuwało treści na boki.
 * ====================================================================== */

.profile {
    max-width: 60rem;
    margin: 0 auto;
    padding: var(--space-6) var(--space-4);
}

/*
 * Tło profilu.
 *
 * Bez zdjęcia zostaje delikatny gradient oparty na barwie awatara — profil
 * świeżego konta ma wyglądać na skończony, a nie na pusty prostokąt czekający
 * na uzupełnienie. Wysokość jest stała: przy wysokości wynikającej z proporcji
 * obrazu każde zdjęcie dawałoby inny układ strony.
 */
.profile__cover {
    position: relative;
    height: 10rem;

    border: 1px solid var(--border);
    border-radius: var(--radius-lg);

    background-color: var(--surface-sunken);
    /*
     * Barwa nakładana z przezroczystością, a nie podana wprost. Jasność
     * wynika wtedy z tła leżącego pod spodem, więc ta sama reguła daje pastel
     * w motywie jasnym i przygaszony odcień w ciemnym — bez drugiego zestawu
     * wartości do utrzymania.
     *
     * Przezroczystość jest NISKA rozmyślnie. Przy 0.3 tło konta o czerwonym
     * odcieniu wychodziło pełnym czerwonym prostokątem — plamą cięższą niż
     * cokolwiek innego w interfejsie i obcą wobec przyjętego kierunku
     * (stonowany, jeden kolor akcentu, monochromatyczny motyw ciemny).
     * Przy 0.12 barwa nadal rozróżnia profile, ale jest tłem, a nie tematem.
     */
    background-image: linear-gradient(
        120deg,
        hsl(var(--hue, 220) 55% 50% / 0.12),
        transparent 65%
    );
    background-size: cover;
    background-position: center;
}

.profile__cover--photo {
    /* Ze zdjęciem gradient byłby drugą warstwą tła i przebijał przez nie
       w miejscach przezroczystych — zdjęcie ma zostać samo. */
    background-image: none;
    border-color: transparent;
}

.profile__cover-actions {
    position: absolute;
    right: var(--space-3);
    bottom: var(--space-3);
    display: flex;
    gap: var(--space-2);
}

/*
 * Wiersz tożsamości leży W CAŁOŚCI POD tłem — na zdjęcie wchodzi wyłącznie
 * awatar, własnym ujemnym odstępem.
 *
 * Wcześniej ujemny odstęp obejmował cały wiersz i podnosił razem z awatarem
 * blok z nazwą. Przy nazwie, adresie i wierszu liczb blok ten ma około 76 px
 * wysokości, czyli tyle co awatar — więc wyrównany do dołu sięgał górą tam,
 * gdzie było jeszcze zdjęcie, i chował się pod nim. Wysokość tego bloku
 * zależy od długości nazwy i liczby pozycji, więc nie da się jej odjąć raz
 * na zawsze; jedynym stabilnym rozwiązaniem jest niepodnoszenie go wcale.
 *
 * `position: relative` jest tu KONIECZNE, a nie kosmetyczne. Tło jest
 * elementem pozycjonowanym (mieści przyciski w rogu), a element pozycjonowany
 * maluje się nad treścią niepozycjonowanego rodzeństwa — niezależnie od
 * kolejności w dokumencie. Bez tej deklaracji nazwa znikała pod zdjęciem
 * nawet wtedy, gdy nachodziła na nie tylko o kilka pikseli.
 */
.profile__identity {
    position: relative;

    display: flex;
    align-items: flex-start;
    gap: var(--space-4);
    flex-wrap: wrap;

    padding-top: var(--space-3);
    margin: 0 0 var(--space-6) var(--space-4);
}

.profile__avatar {
    position: relative;
    flex-shrink: 0;

    /* Podniesienie o 48 px przy średnicy 88 px daje nałożenie mniej więcej
       w połowie promienia — awatar wyraźnie siedzi na krawędzi zdjęcia,
       a nie ledwo jej dotyka. */
    margin-top: calc(-1 * var(--space-8));
}

/* Pierścień w kolorze tła strony oddziela awatar od zdjęcia pod nim —
   bez niego ciemne zdjęcie zlewa się z ciemnym awatarem. */
.profile__avatar .avatar {
    box-shadow: 0 0 0 4px var(--bg);
}

/*
 * Przycisk wgrania zdjęcia siedzi NA awatarze, w prawym dolnym rogu.
 * Umieszczenie go obok („Zmień zdjęcie") zabierałoby wiersz w nagłówku
 * profilu na czynność wykonywaną raz na rok.
 */
.profile__avatar-button {
    position: absolute;
    right: -2px;
    bottom: -2px;

    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;

    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;

    transition: background-color var(--duration-fast) var(--ease-out);
}

.profile__avatar-button:hover {
    background: var(--surface-hover);
}

.profile__headline {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    /* Zajmuje resztę wiersza, spychając przyciski do prawej krawędzi. */
    flex: 1 1 12rem;
}

.profile__name-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.profile__name {
    font-size: var(--text-lg);
    font-weight: 600;
}

.profile__email {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/*
 * Wiersz liczb. Kropki między pozycjami rysuje arkusz, a nie treść —
 * dzięki temu separator nie trafia do odczytu czytnika ekranu ani do
 * zaznaczenia kopiowanego tekstu.
 */
.profile__stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-1);

    font-size: var(--text-xs);
    color: var(--text-muted);
}

.profile__stats > span + span::before {
    content: '·';
    margin-right: var(--space-2);
}

.profile__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.profile__section {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.profile__section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.profile__section-title {
    font-size: var(--text-md);
    font-weight: 600;
}

/* Na wąskim ekranie nazwa i przyciski nie mieszczą się obok awatara —
   ustawiamy je pod nim, zamiast ściskać do nieczytelnej szerokości. */
@media (max-width: 40rem) {
    .profile__identity {
        align-items: flex-start;
        flex-direction: column;
        gap: var(--space-3);
    }

    /*
     * Po obróceniu osi `flex: 1 1 12rem` przestaje znaczyć „zajmij resztę
     * wiersza" i zaczyna znaczyć „zajmij co najmniej 12 rem WYSOKOŚCI, a potem
     * rośnij" — między adresem a przyciskami powstawała z tego pusta przestrzeń
     * na pół ekranu. W układzie pionowym blok ma mieć wysokość swojej treści.
     */
    .profile__headline {
        flex: 0 0 auto;
        width: 100%;
    }
}

/* =========================================================================
 * Układ pomocniczy
 * ====================================================================== */

.stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.row--between {
    justify-content: space-between;
}

.muted {
    color: var(--text-muted);
}

.text-sm  { font-size: var(--text-sm); }
.text-xs  { font-size: var(--text-xs); }
