/* app-profil.css: zawartosc widoku Profil, zbudowana Z MAKIETY (05.09.2026).
 *
 * Kontrakt: .planning/design/KONTRAKT-PROFIL-2026-09-04.md.
 * Obraz:    .planning/design/makiety/nauka-profil-mobile-dark.png, prawa ramka.
 * Notatka:  .planning/design/FALA-PROFIL-2026-09-05.md (co wziete z obrazu,
 *           co zmienione bo fakt, co zmierzone).
 *
 * Zasady, ktore ten plik respektuje bez wyjatkow:
 * 1. Zaden kolor, promien ani odstep nie jest literalem. Wszystko przez var()
 *    z css/base.css, bo ten sam token rysuje 292 strony tresci.
 * 2. Kolor niesie KATEGORIE na kaflach liczb i przy naglowkach kart narzedzi
 *    (--kat-*, --reward), tak jak na pulpicie Nauki. Zasada „jeden akcent"
 *    dotyczy przyciskow i stanow; jedyny zielony przycisk tego ekranu to
 *    wyjscie z profilu bledow, i to tylko wtedy, gdy profil istnieje.
 * 3. Cele dotyku maja co najmniej 44 px (WCAG 2.2 AA 2.5.8), a stan nigdy nie
 *    jest niesiony samym kolorem.
 * 4. Styl nie przychodzi z JavaScriptu. Polityka produkcyjna to
 *    `style-src 'self'` bez 'unsafe-inline': atrybut `style` jest blokowany,
 *    wiec stany ida klasami, a pasek XP dostaje szerokosc przez CSSOM.
 *
 * DWA UKLADY. Ponizej 900 px jedna kolumna w kolejnosci z obrazu: tozsamosc,
 * siatka liczb, Konto, Kopia zapasowa, Zamrazarka, a dopiero pod nimi postep
 * i reszta. Od 900 px powloka daje szyne po lewej, wiec tresc rozklada sie na
 * kolumne glowna i kolumne kontekstowa (--ctx-w).
 *
 * Ten plik jest ladowany PO css/journey.css i css/panel.css. Rownej
 * specyficznosci wygrywa plik pozniejszy, wiec nadpisania kafli i naglowkow
 * kart nie potrzebuja `!important`.
 */

/* ================= SZKIELET ================= */

.profil {
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  /* Ta sama miara kolumny tresci co Start i Nauka. */
  max-width: 560px;
  margin: 0 auto var(--sp-6);
}

.profil-main,
.profil-side {
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  min-width: 0;
}

/* Naglowek jak na obrazie: tytul duzym pismem i jedno zdanie pod nim. */
.profil-head { margin: 6px 0 2px; }

.profil-head__title {
  margin: 0;
}

.profil-head__lead {
  margin: 4px 0 0;
  color: var(--text-dim);
  font-size: var(--fs-body-sm);
  line-height: 1.4;
}

/* Naglowki kart na tym ekranie sa tlustym pismem w zwyklym rejestrze
   (obraz: „Konto", „Kopia zapasowa"), a nie wersalikami w monospace
   z panelu partii. Ten sam zabieg co w Analizie (kontrakt 04.09). */
.profil .card-head { align-items: center; margin-bottom: var(--sp-3); }
.profil .card-head h2 {
  margin: 0;
  color: var(--text);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
}
.profil .card-head .hint { font-size: var(--fs-micro); }

.profil-card__title {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
}

/* Cel dotyku na tym ekranie ma co najmniej 44 px (WCAG 2.2 AA 2.5.8).
   Pomiar z 01.09.2026: cztery przyciski dziedziczone z kart pulpitu
   mialy 43 px. Poprawka jest ZAWEZONA do Profilu swiadomie: `.btn` rysuje
   wszystkie piec ekranow. */
.profil .btn { min-height: 44px; }

/* ================= KARTA TOZSAMOSCI ================= */

/* Uklad z obrazu: awatar po lewej na dwa wiersze, obok nazwa i podpis,
   „Edytuj" przy prawej krawedzi, pod nazwa tarcza poziomu z licznikiem XP
   i paskiem. */
.profil-id {
  container-type: inline-size;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "mark text  edit"
    "mark level level";
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  padding: var(--sp-4);
}

/* Znak tozsamosci to ZAOKRAGLONY KWADRAT, nie kolo (kolo nalezy do ikon
   akcji). Czlowiek nie ma zdjecia: w srodku stoi inicjal nazwy albo znak
   marki, na tle w akcencie, tak jak portret na obrazie stoi na zieleni. */
.profil-id__mark {
  grid-area: mark;
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border: 1px solid color-mix(in srgb, var(--accent) 38%, var(--border));
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--accent) 22%, var(--bg-sunken));
  color: var(--accent-strong);
  font: 700 32px var(--font-mono);
  text-transform: uppercase;
  line-height: 1;
}

.profil-id__text { grid-area: text; min-width: 0; align-self: end; }

.profil-id__name {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* Podpis: prawdziwe pasmo Elo zadan, bo rang gracza nie mamy. */
.profil-id__meta {
  margin: 2px 0 0;
  color: var(--text-dim);
  font-size: var(--fs-meta);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.profil-id__edit {
  grid-area: edit;
  align-self: start;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 6px 10px;
  color: var(--text);
  font-size: var(--fs-micro);
  font-weight: 600;
}
.profil-id__edit-ico { width: 15px; height: 15px; }

/* Najwezszy telefon (320 px daje polu tresci karty 256 px): „Edytuj" zostaje sama
   ikona z etykieta dostepnosci, a awatar maleje, zeby pasmo
   „Sredniozaawansowany" zmiescilo sie obok w jednej linii. Zapytanie
   o kontener zamiast progu okna, bo skala progow tego pliku to 900 px
   plus jeden opisany wyjatek 480 px, a to jest cecha karty, nie ekranu. */
@container (max-width: 300px) {
  .profil-id__mark { width: 60px; height: 60px; font-size: 26px; }
  .profil-id__edit { padding: 6px 10px; }
  .profil-id__edit span { display: none; }
  .profil-id__meta { font-size: var(--fs-micro); }
}

/* Wiersz poziomu: tarcza z numerem, licznik „x / y XP", pasek. */
.profil-id__level {
  grid-area: level;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
  align-self: start;
}

.profil-lvl {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 44px;
  color: var(--accent);
}
.profil-lvl > * { grid-area: 1 / 1; }
.profil-lvl__shield { width: 40px; height: 44px; }
.profil-lvl__num {
  color: var(--text);
  font: 700 15px var(--font-mono);
  line-height: 1;
  transform: translateY(-1px);
}

.profil-xp { display: grid; gap: 6px; min-width: 0; }

.profil-xp__line {
  margin: 0;
  color: var(--text-dim);
  font: 600 var(--fs-meta) var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.profil-xp__now { color: var(--accent-strong); font-weight: 700; }

.profil-xp__bar {
  width: 100%;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  overflow: hidden;
}
.profil-xp__fill {
  width: 0;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--accent);
  transition: width var(--dur-slow) var(--ease);
}

/* ================= SIATKA LICZB DWA NA DWA ================= */

/* Kafel z obrazu: kolorowa ikona po lewej, duza liczba, etykieta pod nia.
   Ikona stoi na wypelnionym kaflu koloru kategorii, tym samym chwytem co
   „Polecane dla Ciebie" na pulpicie Nauki (css/nauka-pulpit.css). */
.profil .dashboard-stats {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-3);
  margin: 0;
}

.profil .dashboard-stat {
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0 10px;
  min-height: 60px;
  padding: 10px var(--sp-3);
  border-radius: var(--radius-lg);
}

.profil button.dashboard-stat:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.profil .dashboard-stat-icon {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  color: var(--kat-ink);
  font-size: 0;
}
.profil .dashboard-stat-icon svg { width: 20px; height: 20px; }

.profil .dashboard-stat--partie .dashboard-stat-icon { background: var(--kat-gra); }
.profil .dashboard-stat--zadania .dashboard-stat-icon { background: var(--kat-zadania); }
.profil .dashboard-stat--seria .dashboard-stat-icon { background: var(--kat-seria); }
.profil .dashboard-stat--monety .dashboard-stat-icon { background: var(--reward); color: var(--reward-ink); }

.profil .dashboard-stat-value {
  align-self: end;
  font: 700 22px var(--font-mono);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.profil .dashboard-stat-label {
  align-self: start;
  color: var(--text-dim);
  font-size: var(--fs-micro);
  line-height: 1.3;
  overflow-wrap: anywhere;
}

/* ================= KARTY NARZEDZI: KONTO, KOPIA, ZAMRAZARKA ================= */

/* Ikona w kolorze kategorii przy naglowku, naglowek, najwyzej dwa zdania,
   przycisk albo dwa. Stan wyjatkowy to plakietka przy naglowku po prawej. */
.profil-tool { display: grid; gap: var(--sp-2); padding: var(--sp-4); }

.profil-tool__head {
  display: grid;
  /* Trzecia kolumna moze sie kurczyc: plakietka kopii lamie sie na dwie
     linie w kolumnie kontekstowej 300 px, zamiast najezdzac na tytul. */
  grid-template-columns: auto max-content minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-3);
  min-height: 28px;
}
.profil-tool__head > :last-child { justify-self: end; }

.profil-tool__ico { display: grid; place-items: center; width: 26px; height: 26px; }
.profil-tool__ico svg { width: 24px; height: 24px; }
.profil-tool__ico--konto { color: var(--kat-zadania); }
.profil-tool__ico--kopia { color: var(--danger); }
.profil-tool__ico--mroz { color: var(--kat-zadania); }

.profil-tool__title {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  white-space: nowrap;
}

.profil-tool__line { margin: 0; font-size: var(--fs-body-sm); line-height: 1.5; }
.profil-tool__line--dim { color: var(--text-dim); font-size: var(--fs-micro); line-height: 1.45; }
.profil-tool__line:empty { display: none; }

.profil-tool__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  color: var(--text-dim);
  font: 650 var(--fs-micro) var(--font-mono);
  letter-spacing: 0;
  white-space: nowrap;
}
/* Plakietka kopii moze sie zlamac (kolumna kontekstowa 300 px przy 1000 px),
   tytul karty nie. */
.profil-data__badge { min-width: 0; white-space: normal; text-align: right; }

/* Duza liczba przy naglowku (zapas zamrazarek), jak „0" na obrazie. */
.profil-tool__count {
  color: var(--kat-zadania);
  font: 700 22px var(--font-mono);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.profil-tool__actions {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
}
.profil-tool__actions--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.profil-tool__btn {
  width: 100%;
  min-height: 44px;
  font-weight: 600;
}

/* ---- Konto ---- */

/* Znacznik „Wkrotce" nalezy WYLACZNIE do stanu bez konta. */
.profil-konto:not([data-state="local"]) .profil-konto__soon { display: none; }

/* ⚠️ WYLACZONY PRZYCISK JAKO ZAPOWIEDZ, NIE USTERKA. `.btn:disabled` z base.css
   daje `opacity: .45`, czyli wyglad „chwilowo nie mozesz". Tutaj znaczy „tego
   jeszcze nie ma": pelna czytelnosc tekstu i obwodka przerywana. */
.profil-konto[data-state="local"] .profil-konto__cta {
  opacity: 1;
  border-style: dashed;
  border-color: color-mix(in srgb, var(--accent) 34%, var(--border));
  background: transparent;
  color: var(--text-dim);
  cursor: default;
}

.profil-konto__state { display: grid; gap: var(--sp-1); }
/* `hidden` musi wygrac z `display: grid` z klasy: base.css nie ma globalnej
   reguly [hidden], wiec kazdy nosnik z wlasnym display ma swoja. */
.profil-konto__state[hidden] { display: none; }

.profil-konto[data-state="syncing"] .profil-konto__cta { opacity: .6; }

/* ---- Kopia zapasowa ---- */

/* Plakietka stanu kopii jak na obrazie: znak w kolku i tekst, bez pigulki. */
.profil-data__badge {
  padding: 0;
  border: 0;
  background: none;
  font: 600 var(--fs-label) var(--font-ui);
  line-height: 1.2;
}

.profil-data__when-mark {
  display: grid;
  place-items: center;
  width: 14px;
  height: 14px;
  border-radius: var(--radius-pill);
  background: var(--bg-raised);
  color: var(--text-dim);
  font: 700 10px var(--font-mono);
}

/* Bez kopii i z kopia starsza niz 30 dni plakietka jest OSTRZEZENIEM:
   rola jest czytelna bez koloru (niesie ja tresc i znak „!"), kolor tylko
   wzmacnia (WCAG 1.4.1). */
.profil-data[data-backup="none"] .profil-data__badge,
.profil-data[data-backup="stale"] .profil-data__badge { color: var(--danger); }
.profil-data[data-backup="none"] .profil-data__when-mark,
.profil-data[data-backup="stale"] .profil-data__when-mark {
  background: var(--danger);
  color: var(--bg-raised);
}
/* Ze swieza kopia znak „!" nie ma czego wzmacniac. */
.profil-data[data-backup="ok"] .profil-data__when-mark { display: none; }

.profil-data__btn { min-height: 48px; }

/* Pole pliku zostaje w drzewie (klika w nie prawdziwy przycisk), ale nie
   zajmuje miejsca i nie wchodzi w kolejnosc fokusa. */
.profil-data__file {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.profil-data__status {
  margin: 0;
  color: var(--text);
  font-size: var(--fs-meta);
  line-height: 1.5;
}

/* Pusty komunikat nie moze zostawiac dziury pod przyciskami, ale NIE WOLNO
   go chowac przez `display: none`: to region `aria-live` i musi byc
   w drzewie dostepnosci ZANIM wpadnie do niego tekst. */
.profil-data__status:empty { height: 0; overflow: hidden; }

/* ---- Zamrazarka serii ---- */

.profil-freeze { display: grid; }
/* `hidden` z JS (awaria magazynu w renderFreeze) musi wygrac z `display: grid`. */
.profil-freeze[hidden] { display: none; }
.profil-freeze__btn { justify-self: stretch; }

/* Jedno zdanie stanu w kartach postepu i bledow: czytelne, nie przypis. */
.profil-progress__body > .hint,
.profil [data-role="dashboard-error-profile"] .dashboard-card-body > .hint {
  font-size: var(--fs-micro);
  line-height: 1.5;
}

/* ================= KARTA DZIENNIKA POMIARU ================= */

/* Dziennik pomiaru (faza 36, D-08 do D-10): dwa zdania widoczne, cala reszta
   pod `hidden`. Wszystko idzie tokenami z css/base.css: zaden literal koloru
   ani atrybut `style=` (polityka produkcyjna to `style-src 'self'`). */

/* Zielen jest tu KATEGORIA („dowod i zaufanie"), nie akcja: niesie ja
   niekliknialny znak liniowy, a zaden przycisk tej karty nie jest zielony. */
.profil-tool__ico--pomiar { color: var(--kat-kurs); }

/* Ten sam zabieg co przy plakietce kopii (w. 332): `.profil-tool__title` ma
   `white-space: nowrap`, wiec w kolumnie kontekstowej 300 px ustapic musi
   plakietka, a tytul „Dziennik pomiaru" jest dluzszy od „Kopia zapasowa". */
.profil-pomiar__badge { min-width: 0; white-space: normal; text-align: right; }

/* Liczby w zdaniach karty: mono i cyfry o rownej szerokosci, zeby przerysowanie
   nie przesuwalo reszty wiersza. */
.profil-pomiar__n {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Awaria magazynu chowa cala karte z renderMeasurement; `hidden` musi wtedy
   wygrac z `display: grid` z `.profil-tool`, jak przy zamrazarce (w. 447). */
.profil-pomiar[hidden] { display: none; }

.profil-pomiar__all { display: grid; gap: var(--sp-2); }
/* `hidden` musi wygrac z `display: grid` z klasy; precedens w. 377. */
.profil-pomiar__all[hidden] { display: none; }

.profil-pomiar__table { width: 100%; border-collapse: collapse; }
.profil-pomiar__table th,
.profil-pomiar__table td {
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--border);
  text-align: left;
}
.profil-pomiar__table thead th {
  color: var(--text-dim);
  font: 700 var(--fs-micro)/1.2 var(--font-mono);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.profil-pomiar__table td {
  font: 400 var(--fs-body-sm) var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.profil-pomiar__table tbody th {
  font-size: var(--fs-body-sm);
  font-weight: 400;
  color: var(--text);
}

.profil-pomiar__list {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.profil-pomiar__entry {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-1) var(--sp-3);
  align-items: baseline;
}
.profil-pomiar__time {
  color: var(--text-dim);
  font: 400 var(--fs-micro) var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.profil-pomiar__name { font-size: var(--fs-body-sm); }
.profil-pomiar__fields {
  grid-column: 2;
  color: var(--text-dim);
  font: 400 var(--fs-micro) var(--font-mono);
  overflow-wrap: anywhere;
}

/* Dziecko siatki `.profil-pomiar__all` rozciagnaloby sie na pelna szerokosc;
   tu przycisk ma miec szerokosc z tresci. */
.profil-pomiar__more { justify-self: start; }
.profil-pomiar__more[hidden] { display: none; }

/* Przycisk-link w OSOBNYM wierszu siatki, wzorzec `.consent-reopen`: bez tla
   i obwodki, podkreslenie, a cel dotyku 44 px z wysokosci wlasnego wiersza
   (w srodku akapitu rozepchnalby zdanie o prywatnosci). */
.profil-pomiar__link {
  justify-self: start;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: 400 var(--fs-micro)/1.45 var(--font-ui);
  text-align: left;
  text-decoration: underline;
  cursor: pointer;
}

/* Stan pusty: jedno zdanie i jedno wyjscie do Zadan, nie ma czego pokazywac
   ani kasowac. ⚠️ Przedrostek stoi przy OBU czlonach: przecinek rozdziela
   selektory, wiec samo `[data-action="pomiar-clear"]` schowaloby kazdy taki
   przycisk w dokumencie. */
.profil-pomiar[data-state="empty"] [data-action="pomiar-toggle"],
.profil-pomiar[data-state="empty"] [data-action="pomiar-clear"] { display: none; }

/* ================= TWOJ POSTEP: KRZYWA ELO ZADAN ================= */

.profil-progress { display: grid; }
.profil-progress__body { display: grid; gap: var(--sp-2); }
.profil-progress__body .btn { justify-self: start; }

.profil-curve {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: stretch;
  gap: var(--sp-2);
}

.profil-curve__scale {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: var(--text-dim);
  font: 650 var(--fs-micro) var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.profil-curve__svg {
  display: block;
  width: 100%;
  height: 84px;
  overflow: visible;
}

.profil-curve__area { fill: color-mix(in srgb, var(--accent) 14%, transparent); stroke: none; }

.profil-curve__line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.profil-curve__dot { fill: var(--accent-strong); stroke: var(--bg-raised); stroke-width: 2; }

.profil-curve__foot { margin: 0; color: var(--text-dim); font-size: var(--fs-micro); line-height: 1.45; }

/* ================= PROFIL BLEDOW: WIERSZE Z UDZIALEM ================= */

.profil-errors {
  display: grid;
  gap: var(--sp-2);
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.profil-errors__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px var(--sp-2);
}

.profil-errors__name {
  font-size: var(--fs-body-sm);
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profil-errors__count {
  color: var(--text-dim);
  font: 650 var(--fs-micro) var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.profil-errors__share {
  grid-column: 1 / -1;
  appearance: none;
  width: 100%;
  height: 4px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  color: var(--text-dim);
}

.profil-errors__share::-webkit-progress-bar { border-radius: var(--radius-pill); background: var(--bg-sunken); }
.profil-errors__share::-webkit-progress-value { border-radius: var(--radius-pill); background: var(--text-dim); }
.profil-errors__share::-moz-progress-bar { border-radius: var(--radius-pill); background: var(--text-dim); }

/* Jedyne zielone wezwanie ekranu: wyjscie z profilu bledow do zadan
   na najczestszy blad. Stoi tylko wtedy, gdy profil istnieje. */
.profil-next { display: grid; width: 100%; }
.profil-next[hidden] { display: none; }
.profil-next__go { justify-self: start; min-height: 44px; }

/* ================= USTAWIENIA I RESZTA ================= */

.profil-links { display: grid; gap: var(--sp-3); padding: var(--sp-4); }

.profil-links__list {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.profil-link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 56px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-sunken);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease), background-color var(--dur-base) var(--ease);
}

.profil-link:hover { border-color: var(--accent); }
.profil-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.profil-link__text { display: grid; gap: 2px; min-width: 0; }
.profil-link__text strong { font-size: var(--fs-body-sm); font-weight: 650; }
.profil-link__text small { color: var(--text-dim); font-size: var(--fs-micro); line-height: 1.4; }

.profil-link__ico { flex: none; width: 20px; height: 20px; color: var(--text-dim); }
.profil-link:hover .profil-link__ico { color: var(--accent); }

/* ================= WESPRZYJ PROJEKT (D-04 fazy 22) ================= */

.profil-support {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-3);
  min-height: 56px;
  padding: var(--sp-4);
  border: 1px solid color-mix(in srgb, var(--crown) 40%, var(--border));
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--crown) 10%, var(--bg-raised));
  color: var(--text);
  text-decoration: none;
  transition: border-color var(--dur-base) var(--ease);
}

.profil-support:hover { border-color: var(--crown); }
.profil-support:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.profil-support__ico {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--crown) 16%, var(--bg-sunken));
  color: var(--crown);
}

.profil-support__ico svg { width: 22px; height: 22px; }

.profil-support__text { display: grid; gap: 2px; min-width: 0; }
.profil-support__text strong { font-size: var(--fs-body-sm); font-weight: 700; }
.profil-support__text small { color: var(--text-dim); font-size: var(--fs-micro); line-height: 1.45; }

/* ================= KARTY DZIEDZICZONE Z PULPITU ================= */

.profil .dashboard-card { margin-top: 0; }

/* Cel nauki jest KONTEKSTEM, nie wezwaniem: karta bez zielonej obwodki. */
.profil .dashboard-goal {
  border-color: var(--border);
  background: var(--bg-raised);
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-4);
}
.profil .dashboard-goal > strong { font-size: 16px; letter-spacing: -.01em; }

.profil-goal__toggle { justify-self: start; min-height: 44px; }

.profil-goal__choices { display: grid; gap: var(--sp-2); }

.profil-goal__choice {
  appearance: none;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-3);
  min-height: 44px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-sunken);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease);
}
.profil-goal__choice:hover { border-color: var(--accent); }
.profil-goal__choice:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.profil-goal__choice.is-current { border-color: var(--accent); }

/* ⚠️ `css/journey.css` maluje KAZDY `span` w `.dashboard-goal` na kolor
   przygaszony; wewnatrz kafla kierunku obie role dostaja swoje wartosci. */
.profil .dashboard-goal .profil-goal__choice span {
  margin-top: 0;
  color: inherit;
  font-size: inherit;
}
.profil-goal__choice-mark { flex: none; color: var(--accent-strong); font-size: 20px; line-height: 1; }
.profil-goal__choice strong { display: block; font-size: var(--fs-body-sm); font-weight: 650; }
.profil-goal__choice small { display: block; margin-top: 2px; color: var(--text-dim); font-size: var(--fs-micro); line-height: 1.4; }

.profil .dashboard-achievement-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Wiersz partii w karcie „Twoje partie". */
.profil-game {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  width: 100%;
  padding: var(--sp-2) 0;
  border-top: 1px solid var(--border);
}

.profil-game:first-child { border-top: 0; padding-top: 0; }

.profil-game__main { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); min-width: 0; }
.profil-game__date { color: var(--text-dim); font-size: var(--fs-micro); }
.profil-game__btn { min-height: 44px; }

.profil-games__list { display: grid; width: 100%; }

/* ================= UKLAD MOBILNY (ponizej 900 px) ================= */

@media (max-width: 899px) {
  /* Obie kolumny rozsypuja sie na pojedyncze karty, zeby karty narzedzi
     z kolumny kontekstowej mogly stanac MIEDZY siatka liczb a postepem,
     dokladnie jak na obrazie, bez ruszania DOM. */
  .profil-main,
  .profil-side { display: contents; }

  /* Kazde dziecko dostaje jawny `order`. Bez tego karty wstawiane przez
     JavaScript (order domyslnie 0) wskoczylyby PRZED naglowek. Przy rownym
     `order` decyduje drzewo. Kolejnosc z obrazu: tozsamosc, siatka, Konto,
     Kopia, Dziennik, Zamrazarka; nizej postep, cel, profil bledow i reszta. */
  .profil-head { order: 0; }
  .profil-id { order: 1; }
  .profil .dashboard-stats { order: 2; }
  .profil-konto { order: 3; }
  .profil-data { order: 4; }
  .profil-pomiar { order: 5; }
  .profil-freeze { order: 6; }
  .profil-progress { order: 7; }
  .profil .celebration-card { order: 8; }
  .profil .dashboard-goal { order: 8; }
  .profil .dashboard-card { order: 9; }
  .profil [data-role="dashboard-weak-card"] { order: 10; }
  .profil-main > .card:has([data-role="dashboard-plan"]) { order: 11; }
  .profil-links { order: 12; }
  .profil-support { order: 13; }

  /* Cztery kafle liczbowe jako JEDEN blok o rownych polach (kontrakt makiet
     2.12, grupa E): wiersz z etykieta lamana na dwie linie („Rozwiazane
     zadania" przy 320 px) nie moze byc wyzszy od drugiego. `1fr` w wierszach
     o wysokosci automatycznej rozciaga wszystkie do najwyzszego. */
  .profil .dashboard-stats { grid-auto-rows: 1fr; }
}

@media (max-width: 480px) {
  /* Jedyny prog ponizej 900 px, ktory ten plik zostawia, i dotyczy
     WYLACZNIE dwoch przyciskow kopii na najwezszym ekranie. Siatka liczb
     zostaje w dwoch kolumnach: zmierzone przy 360 px, najwezszym ekranie,
     jaki serwis obsluguje, podpisy mieszcza sie bez lamania. Przy 320 px
     dwa przyciski „Zapisz kopie" i „Wczytaj kopie" obok siebie maja po
     122 px, wiec schodza jeden pod drugi. */
  .profil-tool__actions--two { grid-template-columns: minmax(0, 1fr); }
}

/* ================= UKLAD DESKTOPOWY (od 900 px) ================= */

@media (min-width: 900px) {
  .profil {
    grid-template-columns: minmax(0, 1fr) var(--ctx-w);
    grid-template-areas:
      "head head"
      "main side";
    gap: var(--sp-4) var(--sp-5);
    max-width: none;
    align-items: start;
  }

  .profil-head { grid-area: head; margin-top: 0; }
  .profil-main { grid-area: main; }
  .profil-side { grid-area: side; }

  .profil-main,
  .profil-side { gap: var(--sp-4); }


  /* CZTERY kafle w jednym rzedzie. */
  .profil .dashboard-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .profil .dashboard-achievement-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .profil-id { gap: var(--sp-2) var(--sp-4); padding: var(--sp-4) var(--sp-5); }
  .profil-id__mark { width: 92px; height: 92px; font-size: 40px; }
  .profil-id__name { font-size: 24px; }
  .profil-id__level { max-width: 520px; }

  /* Krzywa dostaje wiecej pola: kolumna glowna ma 781 px przy 1440 px. */
  .profil-curve__svg { height: 110px; }
}

/* Pasmo posrednie: kolumna kontekstowa ma 300 px (patrz app-desktop.css),
   a kolumna glowna 537 px, wiec cztery kafle z ikona 40 px i liczba 22 px
   zaczynaja sciskac etykiety. Zmierzone przy 1000 px: „Rozwiazane zadania"
   nie miesci sie w jednej linii w 134 px, wiec kafle schodza na dwa rzedy. */
@media (min-width: 900px) and (max-width: 1179px) {
  .profil .dashboard-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .profil .dashboard-achievement-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .profil-curve__svg { height: 92px; }
}

/* ================= DIALOG POTWIERDZENIA IMPORTU ================= */

/* Wczytanie kopii ZASTEPUJE caly stan urzadzenia, wiec pytanie musi zmiescic
   dwie kolumny liczb: co zniknie i co wejdzie na to miejsce. Sam dialog
   dziedziczy ramy z css/layout.css (.confirm-dialog, .confirm-card). */
.data-confirm { width: min(94vw, 520px); }

.data-confirm__card { text-align: left; }

.data-confirm__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}

.data-confirm__col {
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-sunken);
}

/* Rola kolumny jest czytelna BEZ koloru: niesie ja naglowek slowami.
   Obwodka tylko wzmacnia. */
.data-confirm__col--losing { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.data-confirm__col--gaining { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }

.data-confirm__col-label {
  margin: 0 0 var(--sp-2);
  color: var(--text-dim);
  font: 650 var(--fs-label) var(--font-mono);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}

.data-confirm__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px var(--sp-2);
  margin: 0;
}

.data-confirm__list dt { color: var(--text-dim); font-size: var(--fs-micro); overflow-wrap: break-word; }
.data-confirm__list dd { margin: 0; font: 650 var(--fs-meta) var(--font-mono); text-align: right; }

@media (max-width: 480px) {
  .data-confirm__cols { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .profil-link,
  .profil-support,
  .profil-xp__fill { transition: none; }
}
