/* app-analiza.css — ekran Analiza (`#view-analysis`) w powłoce v3.
 *
 * Wykonanie kontraktu `.planning/design/ANALIZA-2026-09-02.md` na słowniku
 * wizualnym fal 1 do 5 (`POWLOKA-V3-FALA-1-2026-09-02.md`): karty na
 * `--bg-raised`, obwódka 1 px `--border`, promień `--radius-lg`, liczby
 * i notacja w Geist Mono, zieleń wyłącznie na akcji.
 *
 * PODZIAŁ PLIKÓW. `css/analysis.css` zostaje tym, czym był: importem,
 * wykresem oceny, kolorami klasyfikacji i wnętrzem kart sprzed 02.09.
 * Tutaj mieszka WYŁĄCZNIE nowe słownictwo ekranu (zakładki, karty graczy,
 * pasek pod planszą, karta bieżącego ruchu, karta otwarcia, karta momentów)
 * oraz cały blok desktopowy. Plik powłoki `css/app-desktop.css` jest
 * NIETKNIĘTY: geometria planszy (`--board-size`, `--board-head`, `--eval-w`,
 * `--ctx-w`) jest tu tylko CZYTANA, bo pilnuje jej `planszaKotwica.spec.js`.
 */

/* ================= ZAKŁADKI KOLUMNY DANYCH =================
   Przynależność karty do zakładki niesie `data-analiza-for` (lista nazw
   rozdzielona spacją), a stan panelu `data-analiza-panel` na `.side-panel`.
   Dzięki temu lista ruchów stoi jednocześnie w „Przeglądzie" i w „Ruchach”
   bez przenoszenia jej w DOM i bez drugiego źródła prawdy. */

.analiza-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
}
.analiza-tabs[hidden] { display: none; }

.analiza-tab {
  flex: 1 1 0;
  min-width: 0;
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--text-dim);
  cursor: pointer;
  font: 600 13px/1 var(--font-sans, inherit);
  padding: 10px 6px;
  transition: color var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
}
.analiza-tab:hover { color: var(--text); }
.analiza-tab:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: -2px; }
.analiza-tab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--accent);
}

/* Karta spoza aktywnej zakładki znika z układu. Cztery reguły zamiast jednej,
   bo `~=` porównuje się z WARTOŚCIĄ atrybutu, a nie z innym atrybutem. */
.analysis-play-layout > .side-panel[data-analiza-panel="overview"] > [data-analiza-for]:not([data-analiza-for~="overview"]),
.analysis-play-layout > .side-panel[data-analiza-panel="moves"] > [data-analiza-for]:not([data-analiza-for~="moves"]),
.analysis-play-layout > .side-panel[data-analiza-panel="analysis"] > [data-analiza-for]:not([data-analiza-for~="analysis"]),
.analysis-play-layout > .side-panel[data-analiza-panel="openings"] > [data-analiza-for]:not([data-analiza-for~="openings"]) {
  display: none;
}

/* ================= NAGŁÓWEK EKRANU ================= */

.analiza-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-3);
}
.analiza-head__title { margin: 0;
}
.analiza-head__back { color: var(--text-dim); font-size: 13px; text-decoration: none; }
.analiza-head__back:hover { color: var(--accent); text-decoration: underline; }

/* ================= NAGŁÓWKI KART RAPORTU =================
   Kontrakt, sekcja 2 „Rytm": nagłówki kart tłustym pismem, nie wersalikami
   w monospace. Powloka daje `.card-head h2` w wersalikach 13 px — to jest
   język paneli sterowania, a raport z partii jest tekstem do czytania. */

#view-analysis .side-panel .card-head h2 {
  color: var(--text);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
}

/* ================= TEKST TYLKO DLA CZYTNIKA EKRANU ================= */

.analiza-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ================= PASY GRACZY =================
   Makieta ANALIZA-2026-09-04: portret, nazwa, siła z podpisem, znacznik
   „Bot" i wynik partii po prawej. Do 04.09 stało tu kółko z figurą i słowo
   „Czarne", które nie mówiło NIC o tym, z kim się grało.

   Element i klasy zostają wspólne z pasem gracza w partii
   (`.player-strip.player-card`), żeby dwa ekrany nie miały dwóch wyglądów
   tej samej rzeczy. Zegara TU NIE MA: zaimportowany PGN nie niesie czasu. */

.analiza-player {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.analiza-player .analiza-player__face {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--bg-sunken);
  font-size: 18px;
  line-height: 1;
}
.analiza-player .player-card__id { display: grid; gap: 3px; min-width: 0; }
.analiza-player .player-name {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.analiza-player__meta { display: flex; align-items: center; gap: 6px; min-width: 0; }
.analiza-player__piece { flex: none; color: var(--text-dim); font-size: 13px; line-height: 1; }
.analiza-player .player-card__rating {
  color: var(--text-dim);
  font: 600 12.5px/1.15 var(--font-mono);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.analiza-player__tag {
  flex: none;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 650;
}
/* ⚠️ Przewaga materialna zostaje PIGUŁKĄ z css/panel.css, razem ze swoją parą
   kolorów. Nadpisanie samego `color` na `--text-dim` gasiło napis na zielonym
   tle: w motywie jasnym pigułka była pusta. Makieta jej nie ma, ale liczba
   mówi o OGLĄDANEJ pozycji i zmienia się przy każdej strzałce, więc zostaje. */
.analiza-player .material-diff { margin-left: auto; }
.analiza-player__score { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.analiza-player .material-diff + .analiza-player__score { margin-left: var(--sp-2); }
.analiza-player__points { font: 750 22px/1 var(--font-mono); color: var(--text); }
.analiza-player__score.is-winner .analiza-player__points { color: var(--accent); }
.analiza-player__cup { font-size: 15px; line-height: 1; }

/* Podświetlenie „teraz ten kolor jest na ruchu" zostaje, ale schodzi do samej
   obwódki: karta gracza w partii maluje tu jeszcze tło, a w raporcie ten stan
   nie jest wezwaniem do działania, tylko drobną informacją o pozycji. */
.analiza-player.is-turn {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: var(--bg-raised);
}

/* ================= PAS RUCHÓW POD PLANSZĄ =================
   Makieta: strzałka wstecz, kafle z zapisem (bieżący na zielono), strzałka
   dalej, licznik po prawej. Kafle są poziomym pasem PRZEWIJANYM, nie oknem
   na pięć pozycji: przewijanie daje dostęp do całej partii jednym gestem,
   a `scrollStripToCurrent` w js/views/analysis.js pilnuje, żeby bieżący
   kafel zawsze wracał na środek. */

.analiza-strip {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.analiza-strip__nav { display: flex; flex: none; gap: 4px; }
.analiza-strip__nav .nav-arrow { width: 44px; min-width: 44px; padding: 9px 0; }
.analiza-strip__moves {
  /* `position: relative` NIE jest ozdoba: `scrollStripToCurrent` liczy srodek
     z `offsetLeft` kafla, a ten jest liczony wzgledem NAJBLIZSZEGO
     pozycjonowanego przodka. Bez tej linii bierze go od korpusu strony
     i biezacy ruch laduje przy lewej krawedzi, obciety. */
  position: relative;
  display: flex;
  flex: 1 1 auto;
  gap: 5px;
  min-width: 0;
  margin: 0;
  padding: 1px;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* Kafel przy krawedzi pasa jest UCIETY, bo pas przewija sie w poziomie.
     Twarde ciecie w polowie napisu wyglada na usterke; wygaszenie mowi
     „tu jest wiecej" i jest jedynym zadaniem tej maski. */
  /* Maska bierze z gradientu WYLACZNIE kanal alfa, wiec barwa nie jest tu
     decyzja o motywie i idzie `currentColor`, a nie literal koloru. */
  mask-image: linear-gradient(to right, transparent 0, currentColor 10px, currentColor calc(100% - 10px), transparent 100%);
}
.analiza-strip__moves::-webkit-scrollbar { display: none; }

.analiza-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: 8px 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text-dim);
  cursor: pointer;
  font: 600 10.5px/1 var(--font-mono);
  white-space: nowrap;
}
.analiza-chip__san { color: var(--text); font-size: 12.5px; font-weight: 700; }
.analiza-chip:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.analiza-chip:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }

/* Bieżący ruch dostaje JEDNO wypełnienie, wspólne dla wszystkich werdyktów:
   pigułka z tłem `currentColor` i tekstem w kolorze tła gubiła napis (usterka
   zmierzona 03.09 na kadrze 390). Werdykt niesie kropka obok zapisu i karta
   werdyktu tuż pod paskiem, która nazywa go słowem. */
.analiza-chip.is-current {
  border-color: var(--accent);
  background: var(--accent);
}
.analiza-chip.is-current,
.analiza-chip.is-current .analiza-chip__san { color: var(--accent-contrast); }

/* Kropka werdyktu TYLKO przy klasach, które coś zmieniają w ocenie partii.
   „Dobry" i „Najlepszy" to większość ruchów w każdej partii; kropka przy
   każdym z nich zamieniłaby pas w konfetti. Kolory są CZYTANE z tokenów
   klasyfikacji, nigdy tu definiowane. */
.analiza-chip.cls-brilliant { color: var(--cls-brilliant); }
.analiza-chip.cls-great { color: var(--cls-great); }
.analiza-chip.cls-miss { color: var(--cls-miss); }
.analiza-chip.cls-brilliant::after,
.analiza-chip.cls-great::after,
.analiza-chip.cls-inaccuracy::after,
.analiza-chip.cls-mistake::after,
.analiza-chip.cls-miss::after,
.analiza-chip.cls-blunder::after {
  content: "";
  align-self: center;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.analiza-chip.is-current::after { background: var(--accent-contrast); }

.analiza-strip__counter {
  flex: none;
  margin: 0;
  color: var(--text-dim);
  font: 650 12.5px/1 var(--font-mono);
  letter-spacing: 0;
}


/* ================= KARTA WERDYKTU RUCHU ================= */

.move-explain-card .explain-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}
.explain-move { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.explain-mark {
  flex: none;
  width: 46px;
  height: 46px;
  font-size: 19px;
}
.explain-move__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.explain-san { font: 750 19px/1.1 var(--font-mono); letter-spacing: -.02em; }
.explain-label { font-size: 13.5px; font-weight: 650; }
.explain-eval {
  flex: none;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-sunken);
  font: 750 15px/1 var(--font-mono);
}
/* Wypełnienie mówi, po czyjej stronie stoi ocena PO tym ruchu. Ta sama umowa,
   co na wykresie: liczby są z perspektywy białych, a plansza w analizie nigdy
   się nie obraca, więc „zielone u góry" znaczy zawsze to samo. */
.explain-eval.is-white { border-color: var(--accent); background: var(--accent); color: var(--accent-contrast); }
.explain-eval.is-black { border-color: var(--border); background: var(--bg-sunken); color: var(--text); }
.explain-text { margin: 0; font-size: 14px; line-height: 1.55; }
.explain-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }

/* ================= KARTA TRENERA =================
   Makieta: maskotka po lewej na całą wysokość karty, tytuł i akapit po prawej,
   zielony przycisk na szerokość kolumny tekstu. Maskotką jest SZACH
   (js/ui/mascot.js), a nie uśmiechnięty pionek z obrazu: mamy własną postać. */

.training-recommendation-card {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: start;
  column-gap: var(--sp-3);
  row-gap: var(--sp-2);
}
.training-recommendation-card > * { grid-column: 2; }
.training-recommendation-head { display: contents; }
.training-recommendation-head .mascot {
  grid-column: 1;
  grid-row: 1 / span 3;
  width: 72px;
  height: auto;
  align-self: start;
}
.training-recommendation-head__text { grid-column: 2; min-width: 0; }
.training-recommendation-head__text h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.training-recommendation-head__text .training-recommendation-kicker {
  margin: 2px 0 0;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.training-recommendation-hint { margin: 0; }
.training-recommendation-hint > summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12.5px;
  padding: 4px 0;
  list-style-position: inside;
}
.training-recommendation-hint > summary:hover { color: var(--text); }
.training-recommendation-hint > summary:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
.training-recommendation-hint[open] > summary { margin-bottom: var(--sp-2); }

.training-recommendation-actions { display: grid; gap: var(--sp-2); justify-items: start; }
.training-recommendation-actions .btn { width: 100%; }
.training-library-link {
  color: var(--text-dim);
  font-size: 12.5px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.training-library-link:hover { color: var(--accent); }

/* ================= ZAKŁADKA „OTWARCIA" ================= */

.analiza-opening__name { margin: 0 0 4px; font-size: 15px; font-weight: 650; }
.analiza-opening__book { margin: 0 0 var(--sp-2); font-size: 13px; color: var(--text-dim); }
.analiza-opening__moves {
  margin: 0 0 var(--sp-2);
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-sunken);
  color: var(--text-dim);
  font: 500 12.5px/1.7 var(--font-mono);
  word-spacing: .3em;
}
.analiza-opening__link { text-decoration: none; }

/* ================= PASEK TRZECH IKON I CICHE STEROWANIE ================= */

.analiza-actions { display: flex; gap: var(--sp-2); }
.analiza-action { font-size: 16px; line-height: 1; }
.analiza-quiet { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.analiza-quiet .btn { flex: 1 1 auto; }

/* ================= KARTA „DOKŁADNOŚĆ" =================
   Element, którego produkt NIE MIAŁ w tej formie, i to on daje ekranowi
   ciężar (kontrakt, sekcja 2). Dwie duże liczby w ramkach po bokach, między
   nimi przebieg oceny z osią od +2 do −2, pod spodem rząd liczników
   WSZYSTKICH DZIEWIĘCIU werdyktów: Twoja liczba w kolorze klasy, liczba
   przeciwnika wierszem niżej.

   Kolory klasyfikacji są tu wyłącznie CZYTANE (`var(--cls-...)`): to standard
   wspólny z lichess i chess.com, definiowany w css/base.css. */

.dokl {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.dokl-side { display: grid; justify-items: center; gap: 6px; min-width: 0; }
.dokl-box {
  display: grid;
  justify-items: center;
  gap: 1px;
  min-width: 86px;
  padding: 10px 12px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-sunken);
}
.dokl-side.is-me .dokl-box { border-color: var(--accent); }
.dokl-box__value { font: 750 27px/1 var(--font-mono); letter-spacing: -.03em; }
.dokl-box__unit { color: var(--text-dim); font-size: 11px; font-weight: 650; }
.dokl-side__who {
  max-width: 100px;
  margin: 0;
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  overflow: hidden;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dokl-chart { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px; }
.dokl-chart__axis {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin: 0;
  padding: 2px 0;
  list-style: none;
  color: var(--text-dim);
  font: 500 9px/1 var(--font-mono);
  text-align: right;
}
.dokl-chart__svg {
  display: block;
  width: 100%;
  height: 76px;
  /* Palec położony na wykresie ma przewijać raport, a nie go blokować. */
  touch-action: pan-y;
}
.dokl-chart__area--up { fill: var(--accent); opacity: .5; }
.dokl-chart__area--down { fill: var(--text-dim); opacity: .28; }
.dokl-chart__zero { stroke: var(--border); stroke-width: 1; }
.dokl-chart__line { fill: none; stroke: var(--accent-strong); stroke-width: 1.6; stroke-linejoin: round; }
.dokl-chart__marker { stroke: var(--text-dim); stroke-width: 1; opacity: .5; }
.dokl-chart__dot { fill: var(--accent-strong); }

.dokl-legend {
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  gap: 4px 2px;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
}

/* ⚠️ KOLUMNA STOI PIONOWO, a nie „znak obok liczby" jak na makiecie.
   Zmierzone: makieta ma sześć klas, produkt ma dziewięć (CLASS_META
   w js/analysis.js). Karta ma w środku 326 px na telefonie 390 i 306 px
   w kolumnie danych na komputerze, czyli 34 do 36 px na kolumnę. Plakietka
   17 px plus liczba 14 px obok siebie zjada 34 px i między sąsiednimi parami
   nie zostaje ani piksel — rząd czyta się wtedy jak jeden ciąg cyfr.
   Klas nie ubywa, ubywa im szerokości: znak, Twoja liczba, liczba
   przeciwnika, jedna pod drugą. */
.dokl-cls {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  gap: 4px;
}
.dokl-cls .cls-badge { width: 18px; height: 18px; font-size: 9px; }
.dokl-cls__me { font: 750 14px/1 var(--font-mono); }
.dokl-cls__foe {
  min-width: 22px;
  padding-top: 4px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font: 600 12px/1 var(--font-mono);
  text-align: center;
}
.dokl-cls--brilliant .dokl-cls__me { color: var(--cls-brilliant); }
.dokl-cls--great .dokl-cls__me { color: var(--cls-great); }
.dokl-cls--best .dokl-cls__me { color: var(--cls-best); }
.dokl-cls--book .dokl-cls__me { color: var(--cls-book); }
.dokl-cls--good .dokl-cls__me { color: var(--cls-good); }
.dokl-cls--inaccuracy .dokl-cls__me { color: var(--cls-inaccuracy); }
.dokl-cls--mistake .dokl-cls__me { color: var(--cls-mistake); }
.dokl-cls--miss .dokl-cls__me { color: var(--cls-miss); }
.dokl-cls--blunder .dokl-cls__me { color: var(--cls-blunder); }

/* Stopka karty: siła gry w tej partii z nazwą progu. Makieta jej nie ma, ale
   liczba jest policzona (`performanceRating`) i to JEDYNE miejsce, w którym
   raport mówi, co ta gra była warta. Stoi cicho, pod liczbami werdyktów. */
/* Stopka karty: siła gry w tej partii z nazwą progu. Makieta jej nie ma, ale
   liczba jest policzona (`performanceRating`) i to JEDYNE miejsce, w którym
   raport mówi, co ta gra była warta. Podpis stoi NAD liczbami: w rzędzie
   „liczba, podpis, liczba" środkowy napis wchodził na progi po obu stronach
   (zmierzone na kadrze 390: kolumna środkowa 108 px przy 306 px całości). */
.summary-card .summary-elo-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: end;
  gap: 2px var(--sp-2);
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3) 0 0;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  background: none;
}
.summary-card .summary-elo-vs {
  grid-column: 1 / -1;
  margin-bottom: 2px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
}
.summary-card .summary-elo-side { display: grid; gap: 2px; justify-items: start; }
.summary-card .summary-elo-side--b { justify-items: end; text-align: right; }
.summary-card .summary-elo-val { color: var(--text); font: 700 14px/1 var(--font-mono); white-space: nowrap; }
.summary-card .summary-elo-tier {
  padding: 0;
  border: 0;
  background: none;
  color: var(--tier-color, var(--text-dim));
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0;
  text-transform: none;
}

/* ================= IMPORT: JEDNA ZWARTA KARTA =================
   Cel z kontraktu (sekcja 3): karta mieści się w kadrze 900 px. */

.analiza-import .import-hint { margin-bottom: var(--sp-3); }
.analiza-import .pgn-textarea { min-height: 108px; }
.analiza-import .analysis-presets { margin: var(--sp-3) 0 0; padding: 0; border: 0; }
.analiza-import .analysis-presets legend { font-size: 12px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-dim); margin-bottom: 6px; }
/* Tryb analizy jako dwa CHIPY, nie dwie karty: opis schodzi do drugiej linii
   i traci wagę, bo wybór jest binarny i odwracalny. */
.analiza-import .analysis-preset-card { padding: 8px 12px; gap: 1px; }
.analiza-import .mode-btn-title { font-size: 13.5px; }
.analiza-import .mode-btn-desc { font-size: 11.5px; }
.analiza-import__actions { margin-top: var(--sp-3); }
.analiza-import .analysis-budget-status { margin: var(--sp-2) 0 0; }
.analiza-import .import-error:empty { display: none; }

.analiza-import__more {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
}
.analiza-import__more > summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 13px;
  padding: 12px 0; /* 44 px celu dotyku (D-F4-02) */
  list-style-position: inside;
}
.analiza-import__more > summary:hover { color: var(--text); }
.analiza-import__more > summary:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
.analiza-import__more[open] > summary { margin-bottom: var(--sp-3); }
.analiza-import__more .connected-accounts-section { margin: 0; }

/* ================= DESKTOP (od 900 px) ================= */

@media (min-width: 900px) {

  /* ⚠️ NAGŁÓWEK WYCHODZI Z PRZEPŁYWU. Każdy piksel nad `.play-layout` spycha
     planszę w dół, a plansza jest KOTWICĄ układu: `planszaKotwica.spec.js`
     porównuje jej prostokąt z partią i zadaniem (1440x900: x=342 y=106
     w=640). Nagłówek stoi więc w pasie 52 px, który powłoka i tak rezerwuje
     u góry pola treści na dwie ikony (motyw, ustawienia) — te są `fixed`
     przy PRAWEJ krawędzi, więc lewa połowa pasa jest wolna.
     Link powrotny idzie w tym samym wierszu, nie pod tytułem: pas ma 42 px
     użytecznej wysokości i dwa wiersze by się w nim nie zmieściły. */
  #view-analysis .analysis-layout { position: relative; }
  #view-analysis .analiza-head {
    position: absolute;
    top: -42px;
    left: 0;
    right: 140px;
    flex-wrap: nowrap;
    align-items: baseline;
    margin: 0;
  }

  /* Stopka serwisu chowa się na czas czytania raportu — ten sam wzorzec, co
     w sesji zadania (D-07, fala 3) i w partii (fala 4). Bez tego dokument miał
     1592 px w kadrze wysokim na 900. Wyjście z raportu samo ją przywraca. */
  body:has(#view-analysis.is-active [data-role="results"]:not([hidden])) .site-footer { display: none; }

  /* Kolumna danych. Kolejność na ekranie daje `order`, bo kolejność w DOM jest
     zajęta przez obietnicę „lekcja jest pierwszą kartą raportu"
     (`analysisLocales.spec.js`). */
  #view-analysis .analysis-play-layout > .side-panel {
    /* Wysokość kolumny planszy, liczona z tokenów powłoki. Bez niej długa
       partia wypychała pasek akcji setki pikseli pod zgięcie. */
    --analiza-col-h: calc(var(--board-size) + 2 * var(--board-head) + 4 * var(--sp-2));
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    gap: var(--sp-3);
    height: var(--analiza-col-h);
    overflow-y: auto;
    /* Ekran mieści się w jednym kadrze, więc lepkość nie ma tu czego trzymać,
       a lepki element przed dojściem do swojego `top` jest PRZESUWANY w dół
       (ta sama pułapka, co w fali 3). */
    position: static;
    padding-right: 2px;
  }

  #view-analysis .analysis-play-layout > .side-panel > * { grid-column: 1 / -1; }

  /* ⚠️ KARTA TRENERA STOI TRZECIA, a nie pod kartą dokładności, jak w makiecie.
     Kolumna ma 340 px, więc „Przegląd" i tak się w kadrze nie mieści i przewija
     się sam. Karta lekcji zepchnięta pod kartę dokładności lądowała przy
     y = 1049, czyli POD dolną krawędzią okna — a „lekcja jest widoczna od
     razu" to obietnica produktu, której pilnuje `analysisLayout.spec.js`.
     Makieta przegrywa z pomiarem.

     Karta dokładności awansowała za to z miejsca piątego na czwarte: to ona
     jest w makiecie drugą kartą raportu i to ona niesie ciężar ekranu, więc
     stoi przed listą notacji, która ma jeszcze własną zakładkę. */
  #view-analysis .analiza-tabs { order: 1; position: sticky; top: 0; z-index: 2; background: var(--bg); }
  #view-analysis .move-explain-card { order: 2; }
  #view-analysis .training-recommendation-card { order: 3; }
  #view-analysis .summary-card { order: 4; }
  #view-analysis .moves-card { order: 5; }
  #view-analysis .variations-card { order: 6; }
  #view-analysis .phase-card { order: 7; }
  #view-analysis .phase-training-card { order: 8; }
  #view-analysis .analiza-moments-card { order: 9; }
  #view-analysis .analiza-opening-card { order: 10; }
  #view-analysis .analiza-actions { order: 11; }
  #view-analysis .analiza-quiet { order: 12; }

  /* Pasy graczy mają wysokość pasa nad planszą — tę samą, co karta gracza
     w partii i nagłówek w Zadaniu. Kotwica planszy zostaje nietknięta. */
  #view-analysis .board-stack > .analiza-player {
    min-height: var(--board-head);
    height: var(--board-head);
    padding: 4px 10px;
    margin: 0;
  }
  #view-analysis .board-stack > .analiza-player .analiza-player__face { width: 34px; height: 34px; font-size: 15px; }
  #view-analysis .board-stack > .analiza-player .player-name { font-size: 14px; }
  #view-analysis .board-stack > .analiza-player .player-card__rating { font-size: 11.5px; }
  #view-analysis .board-stack > .analiza-player .analiza-player__points { font-size: 18px; }

  /* Wykres oceny jest paskiem osi czasu, a nie rozdziałem: bez chromu karty
     i bez zdania o wybranej pozycji (mówi o niej karta bieżącego ruchu). */
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-card {
    padding: 0;
    border: 0;
    background: none;
  }
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-card .eval-chart-title { display: none; }
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-card .eval-chart-trend,
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-card .eval-chart-selected { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  /* Tytuł karty jest schowany, więc przełącznik układu zostaje sam: bez tej
     linii stałby przy LEWEJ krawędzi planszy jako sierota po nagłówku. */
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-head { margin: 0 0 4px; justify-content: flex-end; }
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-visual { aspect-ratio: 12 / 1; min-height: 52px; }
  #view-analysis .analysis-play-layout:not(.has-chart-on-side) .eval-chart-data-toggle { margin-top: 4px; }

  /* Lista ruchów: dwie kolumny notacji plus wąska kolumna numeru, wszystko
     w Geist Mono. W „Przeglądzie" mieści się w połowie kolumny danych, więc
     ocena każdego półruchu jest tam schowana; w „Ruchach" wraca. */
  #view-analysis .moves-card .analysis-move-list { max-height: 236px; }
  #view-analysis .side-panel[data-analiza-panel="moves"] .analysis-move-list { max-height: calc(var(--analiza-col-h) - 148px); }
  #view-analysis .side-panel[data-analiza-panel="moves"] .move-eval { display: inline; }

  #view-analysis .analiza-quiet .btn { font-size: 12px; }
}

/* ================= TELEFON (poniżej 900 px) =================
   Kolejność z makiety, wiersz po wierszu: pas gracza, plansza, pas gracza,
   pas ruchów, zakładki, karta werdyktu, karta dokładności, karta trenera.
   Pasek pięciu zakładek na dole zostaje (to powłoka, nie ten ekran). */

@media (max-width: 899px) {
  #view-analysis .analiza-head { margin-bottom: var(--sp-2); }
  #view-analysis .analysis-play-layout > .side-panel {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
  }

  /* ⚠️ KOLEJNOŚĆ MAKIETY, NIE KOLEJNOŚĆ DOM. W DOM pierwsza jest karta trenera
     (obietnica produktu, `analysisLocales.spec.js`), a na obrazie stoi ona
     POD kartą dokładności. Na telefonie kolumna przewija się razem z całą
     stroną, więc lekcja nie ucieka pod zgięcie tak jak na desktopie i można
     oddać makiecie jej kolejność co do karty. */
  #view-analysis .analysis-play-layout > .side-panel > .analiza-tabs { order: 1; }
  #view-analysis .analysis-play-layout > .side-panel > .move-explain-card { order: 2; }
  #view-analysis .analysis-play-layout > .side-panel > .summary-card { order: 3; }
  #view-analysis .analysis-play-layout > .side-panel > .training-recommendation-card { order: 4; }
  #view-analysis .analysis-play-layout > .side-panel > .moves-card { order: 5; }
  #view-analysis .analysis-play-layout > .side-panel > .variations-card { order: 6; }
  #view-analysis .analysis-play-layout > .side-panel > .phase-card { order: 7; }
  #view-analysis .analysis-play-layout > .side-panel > .phase-training-card { order: 8; }
  #view-analysis .analysis-play-layout > .side-panel > .analiza-moments-card { order: 9; }
  #view-analysis .analysis-play-layout > .side-panel > .analiza-opening-card { order: 10; }
  #view-analysis .analysis-play-layout > .side-panel > .analiza-actions { order: 11; }
  #view-analysis .analysis-play-layout > .side-panel > .analiza-quiet { order: 12; }

  /* Zakładki są jedynym sterowaniem kolumny danych na telefonie, więc jadą
     z treścią, a nie chowają się nad zgięciem. */
  #view-analysis .analiza-tabs { position: sticky; top: 0; z-index: 2; background: var(--bg); }
  #view-analysis .analiza-tab { font-size: 12.5px; padding: 11px 4px; }

  /* ⚠️ WYKRES PEŁNOZAKRESOWY MIESZKA W ZAKŁADCE „ANALIZA". Przenosi go tam
     `updateChartPosition` w js/views/analysis.js, a nie ten arkusz: karta ma
     stać POD zakładkami, a w kolumnie planszy stała nad nimi i zabierała
     141 px, przez które zakładki lądowały na y = 975 przy kadrze 844.
     Reguła niżej jest siatką bezpieczeństwa na wypadek, gdyby moduł się nie
     doładował: pusta ramka pod planszą byłaby wtedy jedyną rzeczą, którą
     widać między paskiem ruchów a zakładkami. */
  #view-analysis .analysis-play-layout .board-stack > .eval-chart-card { display: none; }
  #view-analysis .side-panel > .eval-chart-card { order: 5; }
  /* Tytuł karty wykresu wraca do rytmu raportu: tłuste pismo, nie wersaliki
     w monospace. */
  #view-analysis .side-panel > .eval-chart-card .eval-chart-title {
    color: var(--text);
    font: 700 17px/1.2 var(--font-sans, inherit);
    letter-spacing: -.01em;
    text-transform: none;
  }

  /* ⚠️ PAS MA NA TELEFONIE DWIE STRZAŁKI, nie cztery. Zmierzone przy 390 px:
     rząd ma 358 px, a strzałka 34 px, odstęp 8 px i licznik 47 px. Przy
     czterech strzałkach na kafle zostawało 172 px, czyli JEDEN kafel w kadrze
     przy szerokości kafla 53 px; przy dwóch zostaje 244 px, czyli cztery.
     Makieta pokazuje pięć kafli i dwie strzałki — do pięciu brakuje jednego,
     bo polski zapis („0-0-0", „♗xf3") jest szerszy niż na obrazie.
     „Początek" i „koniec" zostają na komputerze, gdzie rząd ma 640 px. */
  #view-analysis .analiza-strip__edge { display: none; }
  #view-analysis .analiza-strip .nav-arrow { width: 44px; min-width: 44px; padding: 9px 0; }
  #view-analysis .analiza-strip { gap: 6px; }

  /* Lista notacji w zakładce „Ruchy": kafle w siatce numer + białe + czarne.
     Zawijany jeden rząd rozrywał parę („7." zostawało na końcu wiersza,
     a jego posunięcia schodziły niżej), więc grupowanie niesie SIATKA. */
  #view-analysis .analysis-move-list {
    position: relative;
    grid-template-columns: 2.2em 1fr 1fr;
    align-items: center;
    gap: 5px;
    padding: 2px;
  }
  #view-analysis .analysis-move-list .move-num {
    padding: 0;
    color: var(--text-dim);
    font-size: 12px;
    text-align: right;
  }
  #view-analysis .analysis-move-list .move-san {
    display: block;
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    font-size: 13px;
    line-height: 1.15;
    text-align: center;
    white-space: nowrap;
  }
  /* ⚠️ Tło TYLKO dla pigułek, które NIE są bieżącym ruchem. */
  #view-analysis .analysis-move-list .move-san:not(.is-current) { background: var(--bg-sunken); }
  /* ⚠️ USTERKA ODZIEDZICZONA, naprawiona TUTAJ TYLKO PONIŻEJ 900 px.
     `css/analysis.css` maluje bieżący ruch sklasyfikowany jako niedokładność,
     błąd albo gafę regułą `background: currentColor` i W TYM SAMYM bloku
     ustawia `color: var(--bg-raised)`. Tło i napis wychodziły tym samym
     kolorem, czyli pigułka bieżącego ruchu była pusta (zmierzone sondą na
     kadrze 390x844: tło i napis `rgb(26, 30, 36)`). */
  #view-analysis .analysis-move-list .move-san.is-current {
    border-color: transparent;
    background: var(--accent);
    color: var(--accent-contrast);
  }
  #view-analysis .side-panel[data-analiza-panel="moves"] .move-eval { display: inline; }

  /* Karta dokładności na wąskim ekranie: liczby schodzą o stopień, a rząd
     dziewięciu werdyktów zostaje rzędem — mierzone przy 320 px. */
  /* Proporcja z makiety: liczby zajmuja po okolo jednej piatej szerokosci
     karty, reszta idzie na przebieg oceny. Przy odstepie 12 px i ramkach
     86 px na wykres zostawalo 130 px z 326; przy 8 px i 70 px zostaje 170. */
  #view-analysis .dokl { gap: var(--sp-2); }
  #view-analysis .dokl-box { min-width: 70px; padding: 8px 6px 6px; }
  #view-analysis .dokl-box__value { font-size: 25px; }
  #view-analysis .dokl-side__who { max-width: 84px; }
  #view-analysis .dokl-chart__svg { height: 68px; }
  #view-analysis .dokl-legend { gap: 4px 0; }
}

/* ================= NAJWĘŻSZY TELEFON (poniżej 360 px) =================
   Zmierzone przy 320 px: rząd dziewięciu werdyktów obok siebie daje 25 px na
   kolumnę, czyli plakietkę 16 px i liczbę bez miejsca. Kolumna wstaje wtedy
   pionowo (znak, Twoja liczba, liczba przeciwnika) i rząd zostaje rzędem
   dziewięciu, zamiast gubić klasy albo zawijać się na dwa wiersze. */

@media (max-width: 359px) {
  #view-analysis .dokl-cls .cls-badge { width: 16px; height: 16px; font-size: 8px; }
  #view-analysis .dokl-cls__me { font-size: 13px; }
  #view-analysis .dokl-cls__foe { min-width: 18px; font-size: 11px; }
  #view-analysis .dokl-box { min-width: 64px; }
  #view-analysis .dokl-box__value { font-size: 20px; }
}

/* ⚠️ Ocena półruchu ma własną regułę `display`, więc domyślka stoi PRZED
   każdym blokiem, który ją włącza. Bez tego atrybut i tak by nie pomógł:
   klasa z `display` bije regułę przeglądarki dla `hidden`. */
.move-eval { display: none; margin-left: 6px; color: var(--text-dim); font: 500 11px/1 var(--font-mono); }
