/*  Raport rozmowy modemowej - ta sama tozsamosc co panel FTN (panel/diag/app.css), ale uklad
    przyrzadu pomiarowego: jedna os czasu, kilka wykresow jeden pod drugim, wspolny celownik.
    Czarne tlo i monospace nie sa ozdoba - to ekran diagnostyczny, ktory ma sie czytac cyfra po cyfrze.

    WDROZENIE - ten plik ma na serwerze DWIE kopie i trzeba wgrac obie, inaczej poprawka widac
    tylko w jednym miejscu:
      /usr/local/share/dsc-diag/www/report/   -> /admin/report/  (panel sysopa, za Authelia)
      /usr/local/share/dsc-diag/public-lc/    -> /lc/            (raport publiczny)
    Kopie zapasowe ida do /var/backups/, nigdy obok pliku - w webroocie schodzilyby publicznie. */
:root {
  color-scheme: dark;
  /*  Paleta rozjasniona 17.09.2026 na prosbe sysopa: strona zostaje ciemna i terminalowa, ale
      przestaje byc czarna dziura - tla paneli i linie siatki sa o kilka stopni wyzej, a tekst
      pomocniczy przestal ginac na tle. Kolory znaczeniowe (magenta, niebieski, zielony) bez zmian,
      bo na nich stoi cala umowa: kto jest ktory i co jest dobre, a co zle. */
  --bg: #08080a; --panel: #131318; --panel2: #1a1a20; --rule: #2b2b33; --rule2: #3b3b45;
  --fg: #c6c6cc; --bright: #f0f0f4; --cap: #9a9aa4; --muted: #74747e;
  --red: #ff4040; --mag: #ff55ff; --ok: #55cc88; --warn: #ffaa33; --err: #ff4040; --notice: #6aa9ff;
  /*  Stala umowa kolorow w calym raporcie: niebieski to strona dzwoniaca, magenta to nasz modem.
      Ten sam podzial co w pliku stereo (lewy kanal dzwoniacy, prawy nasz), zeby nie myslec dwa razy. */
  --them: #6aa9ff; --us: #ff55ff;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--fg);
  font-family: "DejaVu Sans Mono", Menlo, Consolas, monospace; font-size: 14px; line-height: 1.5; }
a { color: var(--mag); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; }
:focus-visible { outline: 1px solid var(--mag); outline-offset: 2px; }

header.top { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap;
  max-width: 96rem; margin: 0 auto; padding: 1.4rem 1.4rem .6rem; }
h1 { color: var(--red); font-size: 1.3rem; letter-spacing: .3em; margin: 0; }
.sub { color: var(--mag); letter-spacing: .18em; font-size: .76rem; margin: .1rem 0 0; }
.status { font-size: .74rem; color: var(--cap); text-align: right; }
main { max-width: 96rem; margin: 0 auto; padding: .6rem 1.4rem 4rem; }
footer { max-width: 96rem; margin: 0 auto; padding: 1rem 1.4rem 2rem; color: var(--muted); font-size: .72rem;
  border-top: 1px solid var(--rule); display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
h2 { color: var(--red); font-size: .92rem; letter-spacing: .1em; margin: 0 0 .7rem; font-weight: normal; }
section { margin-top: 1.8rem; padding-top: 1rem; border-top: 1px solid var(--rule); min-width: 0; }
section:first-child { margin-top: .2rem; border-top: 0; padding-top: 0; }
.cap { color: var(--cap); font-size: .74rem; margin: .3rem 0 0; }
.dim { color: var(--cap); }
.num { font-variant-numeric: tabular-nums; }
.empty { color: var(--cap); }

/*  Naglowek rozmowy: kto, kiedy, czym i jak dlugo - plus werdykt, ktory ma byc widoczny od progu */
.head { display: flex; gap: 2rem; flex-wrap: wrap; align-items: flex-end; }
.head .who { font-size: 1.5rem; color: var(--bright); letter-spacing: .06em; }
.head .when { color: var(--cap); font-size: .8rem; }
.verdict { margin-left: auto; border: 1px solid var(--rule2); padding: .4rem .9rem; }
.verdict .label { font-size: .68rem; letter-spacing: .18em; color: var(--cap); }
.verdict .value { font-size: 1.05rem; }
.verdict.ok .value { color: var(--ok); } .verdict.ok { border-color: #1f5a3a; }
.verdict.warn .value { color: var(--warn); } .verdict.warn { border-color: #5a431f; }
.verdict.bad .value { color: var(--err); } .verdict.bad { border-color: #5a1f1f; }

/*  Dwie kolumny: co widzi nasz modem i co widzi sciezka VoIP. W tym zestawieniu siedzi cala wartosc
    raportu - dopiero obok siebie mowia, po czyjej stronie jest problem. */
.sides { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 62rem) { .sides { grid-template-columns: 1fr 1fr; } }
.side { border: 1px solid var(--rule); background: var(--panel); padding: .8rem 1rem; }
.side h3 { margin: 0 0 .6rem; font-size: .78rem; font-weight: normal; letter-spacing: .14em; color: var(--cap); }
.side.them h3 { color: var(--them); } .side.us h3 { color: var(--us); }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: .1rem .9rem; font-size: .82rem; }
.kv dt { color: var(--cap); } .kv dd { margin: 0; color: var(--bright); font-variant-numeric: tabular-nums; }

/*  Liczby, ktore maja uderzyc: strata, jitter, dryf, cisza przed handshakiem */
.tiles { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); margin-top: 1rem; }
.tile { border: 1px solid var(--rule); padding: .6rem .8rem; background: var(--panel); }
.tile .t { font-size: .68rem; letter-spacing: .12em; color: var(--cap); }
.tile .v { font-size: 1.25rem; color: var(--bright); font-variant-numeric: tabular-nums; }
.tile .u { font-size: .72rem; color: var(--cap); }
.tile.ok .v { color: var(--ok); } .tile.warn .v { color: var(--warn); } .tile.bad .v { color: var(--err); }

/*  Legenda etapow rozmowy - ta sama umowa kolorow co wstega pod kazdym widmem */
.legend { display: flex; gap: 1.1rem; flex-wrap: wrap; font-size: .72rem; color: var(--cap);
  margin-bottom: .5rem; align-items: center; }
.legend .kto { color: var(--fg); }
.legend .rozdziel { width: 1px; height: .9rem; background: var(--rule2); }
.legend i { display: inline-block; width: .8rem; height: .8rem; margin-right: .35rem;
  vertical-align: -1px; border: 1px solid rgba(255,255,255,.2); }

/*  Przyrzad: wykresy dziela jedna os czasu i jeden celownik, wiec czyta sie je jak jeden obraz */
.instrument { border: 1px solid var(--rule); background: var(--panel); margin-top: .6rem; position: relative; }
.lane { border-bottom: 1px solid var(--rule); position: relative; }
.lane:last-child { border-bottom: 0; }
/*  Podpis NAD wykresem, nie na nim: napis na spektrogramie zaslania dokladnie to, co ma byc widoczne.
    Po lewej co to za wykres, po prawej zakres skali wpisywany po policzeniu. */
.lane .lh { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline;
  padding: .25rem .6rem .1rem; font-size: .7rem; color: var(--cap); }
.lane .lhL { color: var(--fg); }
.lane .lhR { color: var(--muted); font-variant-numeric: tabular-nums; }
/*  Pasek z LEWEJ spina pasy jednej strony. Stoi w stalym wcieciu przyrzadu, poza plotnem, wiec
    niczego nie zaslania i - co wazniejsze - nie zwęża wykresu: wciecie jest takie samo dla WSZYSTKICH
    grup, takze wspolnych, wiec kazde plotno ma identyczna szerokosc i wszystkie stoja na jednej osi.
    Kolor wchodzi zmienna CSS ustawiana przez CSSOM (atrybut style blokuje CSP panelu). */
.instrument { padding-left: 5px; }
.grupa { position: relative; }
.grupa::before { content: ''; position: absolute; left: -5px; top: 0; bottom: 0; width: 3px;
  background: var(--barwa, transparent); }
.grupa + .grupa { border-top: 1px solid var(--rule); }
.lane canvas { display: block; width: 100%; }
/*  Tabliczka z odczytem jedzie za celownikiem, ale stoi w pasie NAGLOWKA - nad wykresem, nie na nim */
.lane .wart .przerwa { display: inline-block; width: .7rem; }
.lane .wart { position: absolute; top: .2rem; font-size: .68rem; line-height: 1.25;
  padding: 0 .3rem; background: rgba(0,0,0,.88); border: 1px solid var(--rule2);
  color: var(--bright); white-space: nowrap; pointer-events: none; z-index: 3;
  font-variant-numeric: tabular-nums; }
/*  Pas osi czasu nie ma naglowka, wiec jego tabliczka siada tuz nad kreskami */
.lane:not(:has(.lh)) .wart { top: 0; }
/*  Odczyt celownika: jeden wiersz na strone, w nim WSZYSTKO, co w tej chwili wiadomo - poziom,
    czestotliwosc, klasyfikacja sygnalu, pakiety, jitter i dryf. Stala wysokosc, zeby przyrzad nie
    podskakiwal przy przesuwaniu myszy nad wykresami. */
.readout { font-size: .76rem; padding: .45rem .8rem; border-top: 1px solid var(--rule);
  background: var(--panel2); font-variant-numeric: tabular-nums; min-height: 4.4rem; }
.readout b { color: var(--bright); font-weight: normal; }
.readout .k { color: var(--cap); }
.readout .chwila { margin-bottom: .15rem; }
.readout .ow { display: flex; gap: .9rem; flex-wrap: wrap; align-items: baseline; line-height: 1.7; }
.readout .ow > i { width: .6rem; height: .6rem; flex: none; align-self: center; }
.readout .ow .kto { color: var(--fg); min-width: 12rem; }
.readout .mala { display: inline-block; width: .5rem; height: .5rem; margin-right: .3rem; }
.controls { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; margin-top: .7rem; font-size: .78rem; }
.controls button { font: inherit; font-size: .76rem; color: var(--fg); background: var(--panel2);
  border: 1px solid var(--rule2); padding: .15rem .7rem; cursor: pointer; }
.controls button:hover { color: var(--bright); border-color: var(--mag); }
audio { height: 1.9rem; }

table { border-collapse: collapse; width: 100%; font-size: .78rem; }
th, td { text-align: left; padding: .18rem .7rem .18rem 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
th { color: var(--cap); font-weight: normal; letter-spacing: .06em; }
td.n, th.n { text-align: right; font-variant-numeric: tabular-nums; }
.tw { overflow-x: auto; }
.pill { display: inline-block; font-size: .68rem; padding: 0 .4rem; border: 1px solid var(--rule2); white-space: nowrap; }
.pill.ok { border-color: #1f5a3a; color: var(--ok); }
.pill.warn { border-color: #5a431f; color: var(--warn); }
.pill.bad { border-color: #5a1f1f; color: var(--err); }
/*  Wykresy zbiorcze: to samo, co na osi czasu, ale widziane jako rozklad - inne pytanie, inny obraz */
.minis { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.mini { border: 1px solid var(--rule); background: var(--panel); padding: .5rem .6rem; min-width: 0; }
.mini .t { font-size: .68rem; letter-spacing: .1em; color: var(--cap); }
.mini .u { font-size: .68rem; color: var(--muted); margin-top: .2rem; }
.mini canvas { display: block; width: 100%; height: 120px; }
.files { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .78rem; margin-top: .4rem; }

/* ---------------------------------------------------------------- diagnostyka modemu i line doctor
   Sekcje dorysowywane przez modemdiag.js i linedoctor.js: tabele "pomiar - wartosc - co to jest -
   po co", surowe ekrany ATI do rozwiniecia oraz zestawienie prob na ten sam numer. */
table td.ok { color: var(--ok); } table td.warn { color: var(--warn); } table td.bad { color: var(--err); }
.raw details { border: 1px solid var(--rule); background: var(--panel); margin: .4rem 0; }
.raw summary { cursor: pointer; padding: .4rem .7rem; color: var(--cap); font-size: .76rem;
  letter-spacing: .06em; }
.raw summary:hover { color: var(--bright); }
.raw pre { margin: 0; padding: .6rem .9rem; border-top: 1px solid var(--rule); overflow-x: auto;
  font-size: .74rem; color: var(--bright); white-space: pre; }
section h3 { margin: 1.2rem 0 .5rem; font-size: .78rem; font-weight: normal; letter-spacing: .14em;
  color: var(--cap); }
ul.stwierdzenia, ul.spostrzezenia { margin: .3rem 0; padding-left: 1.1rem; font-size: .8rem; }
ul.stwierdzenia li, ul.spostrzezenia li { margin: .15rem 0; }
ul.spostrzezenia li.uwaga { color: var(--warn); }
ul.spostrzezenia li.info { color: var(--fg); }
.linedoctor table { border-collapse: collapse; width: 100%; font-size: .78rem; }
.linedoctor th, .linedoctor td { border-bottom: 1px solid var(--rule); padding: .28rem .6rem;
  text-align: left; font-variant-numeric: tabular-nums; }
.linedoctor th { color: var(--cap); font-weight: normal; letter-spacing: .08em; }
.linedoctor table.korelacje td:last-child { color: var(--bright); }
.linedoctor .pusto { color: var(--cap); font-size: .78rem; }
/* Wartosci liczbowe i oktety V.8 nie moga sie lamac w polowie - "C1 65 13 10 27 0D" rozjechane
   na dwa wiersze czyta sie jak dwie rozne wartosci. */
table td.n { white-space: nowrap; }
ul.spostrzezenia li.ok { color: var(--ok); } ul.spostrzezenia li.zle { color: var(--err); }
ul.krzyzowe { font-size: .84rem; line-height: 1.5; }
ul.krzyzowe b { color: var(--bright); letter-spacing: .08em; }

/* ---------------------------------------------------------------- mierniki diagnostyki modemu
   Liczby z progiem rysujemy jako paski z zaznaczonym progiem: "35,6 dB" nie mowi nic, dopoki nie
   widac, gdzie na skali lezy granica. Cala surowizna siedzi nizej, w blokach <details>. */
.mierniki { display: grid; gap: .9rem 1.6rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  margin-top: 1rem; }
.miernik .glowa, .plan .glowa, .poziom { display: flex; align-items: baseline; gap: .6rem; }
.miernik .glowa .et, .plan .glowa .et { font-size: .68rem; letter-spacing: .12em; color: var(--cap); }
.miernik .glowa .wart, .plan .glowa .wart { margin-left: auto; font-size: .95rem; color: var(--bright);
  font-variant-numeric: tabular-nums; }
.miernik .wart.ok { color: var(--ok); } .miernik .wart.warn { color: var(--warn); }
.miernik .wart.bad { color: var(--err); }
.tor { position: relative; height: .55rem; background: var(--panel2); border: 1px solid var(--rule);
  margin: .25rem 0 .15rem; overflow: hidden; }
.tor .wyp { position: absolute; top: 0; bottom: 0; left: 0; background: var(--fg); }
.tor .wyp.ok { background: var(--ok); } .tor .wyp.warn { background: var(--warn); }
.tor .wyp.bad { background: var(--err); }
.tor .prog { position: absolute; top: -1px; bottom: -1px; width: 1px; background: var(--rule2); }
.tor .prog.zero { left: 50%; background: var(--cap); }
.skala { display: flex; justify-content: space-between; font-size: .64rem; color: var(--muted);
  font-variant-numeric: tabular-nums; }

.poziomy { margin-top: 1.2rem; max-width: 34rem; }
.poziom { margin: .2rem 0; }
.poziom .et { font-size: .7rem; color: var(--cap); width: 6rem; }
.poziom .tor { flex: 1; margin: 0; }
.poziom .wart { font-size: .78rem; color: var(--bright); width: 5rem; text-align: right;
  font-variant-numeric: tabular-nums; }

.plan { margin-top: 1.4rem; max-width: 46rem; }
.pasmo { position: relative; height: 2.4rem; background: var(--panel2); border: 1px solid var(--rule);
  margin: .3rem 0 .15rem; }
.pasmo .telefon { position: absolute; top: 0; bottom: 0; background: #2a2a32; }
.pasmo .v34 { position: absolute; top: .45rem; bottom: .45rem; background: var(--mag); opacity: .75; }
.pasmo .nosna { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--bright); }

.macierz { display: grid; grid-template-columns: 1fr 4rem 4rem; gap: 0 .4rem; margin-top: .8rem;
  max-width: 42rem; font-size: .78rem; }
.macierz .naglowek { color: var(--cap); font-size: .68rem; letter-spacing: .1em; padding-bottom: .3rem;
  border-bottom: 1px solid var(--rule); }
.macierz .naglowek.nas, .macierz .naglowek.oni { text-align: center; }
.macierz .co, .macierz .znak { padding: .18rem 0; border-bottom: 1px solid var(--rule); }
.macierz .znak { text-align: center; font-variant-numeric: tabular-nums; }
.macierz .zgodne { color: var(--muted); }
.macierz .rozne { color: var(--bright); background: #2a1a08; }
.macierz .znak.tak { color: var(--ok); } .macierz .znak.nie { color: var(--muted); }
.macierz .rozne.znak.tak { color: var(--warn); }

section > details { border: 1px solid var(--rule); background: var(--panel); margin: .5rem 0; }
section > details > summary { cursor: pointer; padding: .45rem .8rem; color: var(--cap); font-size: .78rem; }
section > details > summary:hover { color: var(--bright); }
section > details > *:not(summary) { padding: 0 .8rem .7rem; }
.pasmo .granica { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--cap); opacity: .8; }

/* ---------------------------------------------------------------- uklad kolumnowy pomiarow
   Trzy kolumny: mierniki modemu, liczby z warstwy pakietowej, liczniki lacza. Wczesniej te same
   dane szly jedna pod druga przez pol ekranu i nie dalo sie ich porownac wzrokiem. */
.kolumny { display: grid; gap: 1.2rem; grid-template-columns: 1fr; margin-top: 1rem; }
@media (min-width: 62rem) { .kolumny { grid-template-columns: minmax(20rem, 1.25fr) 1fr 1fr; } }
.kolumny .kol { border: 1px solid var(--rule); background: var(--panel); padding: .8rem 1rem; min-width: 0; }
.kolumny .kol > h3 { margin: 0 0 .7rem; font-size: .72rem; font-weight: normal; letter-spacing: .14em;
  color: var(--cap); }
.kolumna .grupa { margin-bottom: 1rem; }
.kolumna .grupa .tytul { font-size: .64rem; letter-spacing: .16em; color: var(--muted);
  border-bottom: 1px solid var(--rule); padding-bottom: .2rem; margin-bottom: .5rem; }
.mierniki.jedna { grid-template-columns: 1fr; gap: .6rem; margin-top: 0; }
.kolumna .poziomy, .kolumna .plan { margin-top: 0; max-width: none; }
.kolumna .poziom .et { width: 5rem; font-size: .68rem; }
.kolumna .poziom .wart { width: 4.6rem; font-size: .74rem; }

/* liczniki lacza - lista zamiast kafli: w waskiej kolumnie kafle rozjezdzaja sie na caly ekran */
.liczniki .poz { display: grid; grid-template-columns: 1fr auto; gap: 0 .6rem; padding: .3rem 0;
  border-bottom: 1px solid var(--rule); }
.liczniki .nazwa { font-size: .78rem; color: var(--fg); }
.liczniki .wart { font-size: .95rem; color: var(--bright); font-variant-numeric: tabular-nums;
  text-align: right; }
.liczniki .wart.ok { color: var(--ok); } .liczniki .wart.warn { color: var(--warn); }
.liczniki .opis { grid-column: 1 / -1; font-size: .68rem; color: var(--muted); }

/* zdolnosci i status w gornym rzedzie sa wezsze niz osobna sekcja */
.side .macierz { grid-template-columns: 1fr 2.4rem 2.4rem; font-size: .72rem; max-width: none; }
.side .macierz.status { grid-template-columns: 1fr 2.4rem; }
.side .macierz .naglowek { font-size: .62rem; }
.macierz .co { text-align: left; }
.macierz.status .co { padding-right: .4rem; }

/* ---------------------------------------------------------------- kondensacja gornego rzedu
   Cztery zestawienia maja sie zmiescic w jednym rzedzie bez rozjazdu, wiec w tym ukladzie ida
   mniejszym pismem i z ciasniejszymi odstepami. Ponizej 78rem wracaja do dwoch kolumn, a na
   telefonie do jednej - inaczej tabelka zdolnosci lamalaby sie w polowie slowa. */
@media (min-width: 78rem) { .sides.cztery { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 48rem) and (max-width: 77.99rem) { .sides.cztery { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.sides.cztery .side { padding: .7rem .8rem; min-width: 0; }
/*  Pismo w zestawieniach ma byc TAKIE SAMO jak w tabelkach obok - inaczej kolumna z rozmowa
    odznacza sie od sasiadow i wyglada jak inny element strony. */
.sides.cztery .kv { font-size: .68rem; gap: .06rem .6rem; line-height: 1.55; }
.sides.cztery .side h3 { font-size: .7rem; }
.sides.cztery .macierz { font-size: .68rem; grid-template-columns: 1fr 1.8rem 1.8rem; }
.sides.cztery .macierz.status { grid-template-columns: 1fr 1.8rem; }
.sides.cztery .macierz .co, .sides.cztery .macierz .znak { padding: .12rem 0; }
.sides.cztery .cap { font-size: .66rem; }

/*  Trzy kolumny strojenia ID_SDL. Wezsze pismo jak przy czterech panelach - to sa dlugie nazwy
    rejestrow z dopiskiem "(+Sxx)", ktore przy normalnym rozmiarze lamaly sie w polowie. */
@media (min-width: 62rem) { .sides.trzy { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.sides.trzy .side { padding: .7rem .8rem; min-width: 0; }
.sides.trzy .kv { font-size: .68rem; gap: .06rem .6rem; line-height: 1.55; }
.sides.trzy .side h3 { font-size: .7rem; }
/*  Blok, ktory jest w calosci nieczynny (AON bez ani jednego zadania): pokazany, bo zrzut idzie
    caly, ale przygaszony - inaczej szesnascie martwych liczb wyglada rownie waznie jak progi,
    ktore naprawde decyduja o wyniku rozmowy. */
.side.cichy { opacity: .55; }
.side.cichy h3 { color: var(--cap); }

/* dwie polowy zamiast trzech kolumn: po prawej dwie tabele jedna pod druga */
@media (min-width: 62rem) { .kolumny.dwie { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.kolumny .stos { display: flex; flex-direction: column; gap: 1.2rem; min-width: 0; }

/* ---------------------------------------------------------------- uzgodnienia V.8: inspektor
   Pola sa gęste i krotkie, a pelny opis pokazuje panel nad nimi, gdy najedziesz kursorem albo
   dojdziesz tabulatorem. Panel ma STALA wysokosc na cztery linie opisu: przy zmiennej skakal
   w gore i w dol razem z dlugoscia tekstu, a pod nim siedzi cala reszta sekcji. */
.negocjacja { margin-top: .6rem; }
/*  Pola po lewej, opis po prawej: kolumny pol sa niskie i szerokie, wiec prawa strona i tak
    stala pusta. Na waskim ekranie panel wraca nad pola, bo obok nie ma juz dla niego miejsca. */
.negocjacja.zBokiem { display: grid; gap: 1.2rem; grid-template-columns: 1fr; }
@media (min-width: 72rem) {
  .negocjacja.zBokiem { grid-template-columns: minmax(0, 1fr) minmax(17rem, 24rem); }
  .negocjacja.zBokiem .prawa { order: 2; }
  .negocjacja.zBokiem .inspektor { position: sticky; top: 1rem; margin-bottom: 0; min-height: 11rem; }
}
.negocjacja.zBokiem .lewa { min-width: 0; }
.inspektor { border: 1px solid var(--rule2); background: var(--panel2); padding: .6rem .9rem;
  min-height: 7rem; margin-bottom: 1rem; }
.inspektor .tytul { font-size: .76rem; letter-spacing: .1em; color: var(--mag); }
.inspektor .tresc { font-size: .84rem; color: var(--bright); margin-top: .25rem; line-height: 1.45; }
.inspektor .meta { font-size: .7rem; color: var(--cap); margin-top: .35rem;
  font-variant-numeric: tabular-nums; }

/* Grupy stoja obok siebie, a pola w kazdej z nich jedno pod drugim: sekcja rosnie w bok, nie w dol */
.kolumnyNeg { display: flex; gap: 1.1rem; flex-wrap: wrap; align-items: flex-start; }
.kolumnyNeg .podgrupa { min-width: 0; }
.podgrupa .tytul { font-size: .62rem; letter-spacing: .14em; color: var(--muted); margin-bottom: .3rem;
  white-space: nowrap; }
.pola { display: flex; gap: .35rem; flex-wrap: wrap; }
.pola.pion { flex-direction: column; flex-wrap: nowrap; gap: .25rem; }
.pole { border: 1px solid var(--rule); background: var(--panel2); padding: .28rem .45rem;
  min-width: 6.6rem; cursor: help; display: flex; align-items: baseline; gap: .4rem; }
.pole:hover, .pole:focus { border-color: var(--mag); outline: none; }
.pole .et { font-size: .72rem; color: var(--bright); white-space: nowrap; }
.pole .wart { font-size: .76rem; color: var(--bright); font-variant-numeric: tabular-nums;
  margin-left: auto; }
.pole .strony { font-size: .68rem; letter-spacing: .1em; margin-left: auto; white-space: nowrap; }
.pole .strony .tak { color: var(--ok); } .pole .strony .nie { color: var(--muted); }
.pole.oba { border-color: #1f5a3a; }
.pole.rozne { border-color: var(--warn); background: #2a1a08; }
.pole.zaden { opacity: .5; }
.pole.uzyta { outline: 1px solid var(--mag); outline-offset: 1px; }
.drabina .pole .et { font-variant-numeric: tabular-nums; }

/* Oktety: jeden wiersz na oktet, obie strony obok siebie */
/*  Tabelka oktetow ma zmiescic sie w tym samym rzedzie co kolumny pol, wiec jej szerokosc jest
    ograniczona, a nazwa kategorii - skracana wielokropkiem (pelna jest w panelu opisu). */
.oktety { display: flex; flex-direction: column; gap: .2rem; max-width: 22rem; }
.oktety .okt { display: grid; grid-template-columns: 1rem 3rem 3rem 1fr; gap: .35rem;
  align-items: baseline; border: 1px solid var(--rule); background: var(--panel2);
  padding: .22rem .45rem; cursor: help; }
.oktety .okt:hover, .oktety .okt:focus { border-color: var(--mag); outline: none; }
.oktety .okt.rozny { border-color: var(--warn); background: #2a1a08; }
.oktety .okt.naglowek { border-color: transparent; background: none; cursor: default;
  color: var(--muted); font-size: .6rem; letter-spacing: .1em; padding-bottom: 0; }
.oktety .nr { font-size: .62rem; color: var(--muted); }
.oktety .hex { font-size: .76rem; color: var(--bright); font-variant-numeric: tabular-nums; }
.oktety .kat { font-size: .62rem; color: var(--cap); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }

/* ---------------------------------------------------------------- pomiary toru (TIMS)
   Charakterystyka tlumieniowa jako slupki wokol zera i konstelacja na plotnie. */
.tlumienie { display: flex; gap: .25rem; align-items: flex-end; margin: .6rem 0; }
.tlumienie { flex-wrap: wrap; }
.tlumienie .slup { width: 2.1rem; text-align: center; }
.tlumienie .gora, .tlumienie .dol { height: 44px; display: flex; align-items: flex-end;
  justify-content: center; }
.tlumienie .dol { align-items: flex-start; }
.tlumienie i { display: block; width: 1.1rem; background: var(--them); }
.tlumienie .slup.zle i { background: var(--warn); }
.tlumienie .os { height: 1px; background: var(--rule2); }
.tlumienie .hz { font-size: .6rem; color: var(--muted); margin-top: .2rem;
  font-variant-numeric: tabular-nums; }
.konstelacja-box { display: flex; gap: 1.2rem; flex-wrap: wrap; align-items: flex-start; margin-top: .5rem; }
.konstelacja { border: 1px solid var(--rule); background: var(--panel); }
.konstelacja-box .obok { max-width: 30rem; }
.konstelacja-box .obok b { color: var(--bright); font-weight: normal; letter-spacing: .06em; }
.konstelacja-box .podpis-kon { color: var(--bright); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- negocjacja V.8 jako klocki
   Jeden wykres, dwa rzedy: gora my (CM), dol druga strona (JM). Kolor klocka = kategoria oktetu,
   czerwona ramka = powtorzenie, ktoremu brakuje oktetu. Nakladanie sie rzedow jest POPRAWNE:
   modem odbierajacy zaczyna JM, gdy wolajacy jeszcze powtarza CM. */
.bajty { display: flex; gap: .6rem; align-items: stretch; margin: .5rem 0 .2rem; }
.rzedy-podpisy { width: 6rem; display: flex; flex-direction: column; justify-content: space-around;
  font-size: .66rem; letter-spacing: .08em; color: var(--cap); text-align: right; }
.bajty-plansza { position: relative; flex: 1; min-height: 4.2rem; background: var(--panel2);
  border: 1px solid var(--rule); overflow: hidden; }
.bajty-plansza .kratka { position: absolute; top: 0; bottom: 0; width: 1px; background: #23232a; }
.bajty-plansza .srodek { position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: var(--rule); }
.bajty-plansza .rzad { position: absolute; left: 0; right: 0; height: 2.1rem; }
.bajty-plansza .rzad.calling { top: 0; }
.bajty-plansza .rzad.answering { bottom: 0; }
.bajty-plansza .bajt { position: absolute; top: .35rem; width: 1.7rem; margin-left: -.85rem;
  display: flex; justify-content: center; cursor: help; }
.bajty-plansza .bajt span { font-size: .62rem; font-variant-numeric: tabular-nums;
  padding: .12rem .2rem; border: 1px solid; background: var(--panel); }
.bajty-plansza .bajt:hover span, .bajty-plansza .bajt:focus span { background: #26262e; outline: none; }
.bajty-plansza .bajt.wariant span { background: #3a1414; }
.legenda-bajtow { display: flex; gap: .9rem; flex-wrap: wrap; font-size: .64rem; color: var(--cap);
  margin: .3rem 0 0 6.6rem; }
.legenda-bajtow i { display: inline-block; width: .6rem; height: .6rem; margin-right: .3rem; }
.legenda-bajtow .zle { color: var(--err); }
.inspektor.maly { min-height: 4.2rem; margin-bottom: .4rem; }
/* mala konstelacja przy wykresach - wlasna kolumna po prawej, przyklejona do gory przy przewijaniu */
.os-i-kon { display: flex; gap: .8rem; align-items: flex-start; }
.os-i-kon .instrument { flex: 1; min-width: 0; }
.kolumna-kon { width: 150px; flex: 0 0 150px; }
.mini-kon { position: sticky; top: .6rem; background: var(--panel); border: 1px solid var(--rule);
  padding: .4rem; }
.mini-kon .tyt { font-size: .58rem; letter-spacing: .1em; color: var(--cap); margin-bottom: .3rem; }
.mini-kon .podpis-kon { font-size: .6rem; margin-top: .3rem; }
@media (max-width: 60rem) { .os-i-kon { display: block; } .kolumna-kon { width: auto; }
  .mini-kon { position: static; margin-bottom: .6rem; } }
.jak-czytac { border-left: 2px solid var(--rule2); padding-left: .7rem; margin: .5rem 0; }
.jak-czytac .tyt { font-size: .6rem; letter-spacing: .14em; color: var(--cap); }
.jak-czytac ul { margin: .25rem 0 0; padding-left: 1rem; font-size: .74rem; color: var(--fg); }
.jak-czytac li { margin: .15rem 0; }
.cap.ostrzezenie { color: var(--warn); border-left: 2px solid var(--warn); padding-left: .6rem; }
/* os czasu pod wykresem bajtow - styl wrocil po przebudowie planszy (zgubil sie przy podmianie bloku) */
.osczasu { display: flex; justify-content: space-between; font-size: .62rem; color: var(--muted);
  margin: .15rem 0 0 6.6rem; font-variant-numeric: tabular-nums; }
/* brakujacy oktet: pusta ramka w miejscu, w ktorym powinien byl paść */
.bajty-plansza .bajt.brakuje span { min-width: .9rem; min-height: .85rem; border-style: dashed;
  background: transparent; }
.legenda-bajtow i.pusta { border: 1px dashed var(--err); background: transparent; }
/* opoznienie grupowe - slupki w gore od minimum; ksztalt wanny jest tu normalny */
.edd { display: flex; gap: .25rem; align-items: flex-end; flex-wrap: wrap; margin: .6rem 0; }
.edd .slup { width: 2.1rem; text-align: center; }
.edd .kolumna { height: 56px; display: flex; align-items: flex-end; justify-content: center; }
.edd i { display: block; width: 1.1rem; background: var(--ok); }
.edd .slup.zle i { background: var(--warn); }
.edd .hz { font-size: .6rem; color: var(--muted); margin-top: .2rem; font-variant-numeric: tabular-nums; }

/* konstelacja: obraz i sterowanie w jednej kolumnie, opis obok */
.konstelacja-box .lewa-kon { display: flex; flex-direction: column; gap: .4rem; }
.odtwarzacz-kon { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; max-width: 320px; }
.odtwarzacz-kon button { background: var(--panel2); color: var(--bright); border: 1px solid var(--rule2);
  padding: .25rem .7rem; font: inherit; font-size: .74rem; cursor: pointer; }
.odtwarzacz-kon button:hover { border-color: var(--mag); color: var(--mag); }
.odtwarzacz-kon .suwak-kon { flex: 1; min-width: 6rem; accent-color: var(--mag); }
.odtwarzacz-kon .zegar-kon { font-size: .68rem; color: var(--cap); font-variant-numeric: tabular-nums;
  width: 100%; }
.odtwarzacz-kon .cap { width: 100%; font-size: .66rem; }

/*  Logo ANSI - tylko na raporcie publicznym (report.js zdejmuje `hidden`). Te same reguly co na
    stronie publicznej diagnostyki, zeby oba miejsca wygladaly jak jedna strona, a nie dwie.
    `line-height: 0` na pojemniku: wiersze ANSI maja wlasna wysokosc co do piksela i kazdy dodatek
    od przegladarki rozjezdza polowki blokow.  */
/*  Marka: tytul, logo i podtytul jedno pod drugim. `inline-block` daje pojemnikowi szerokosc
    NAJSZERSZEGO dziecka, czyli logo - dzieki temu `text-align: center` na tytule i podtytule
    srodkuje je wzgledem szerokosci logo, a nie wzgledem calej strony.  */
.brand { display: inline-block; }
.brand h1, .brand .sub { text-align: center; }
.dsclogo { margin: .35rem 0 .45rem; line-height: 0; }
/*  Opis rozmowy po prawej stronie naglowka - przeciwwaga marki. `align-self: flex-start` bierze
    go z DOLU naglowka na GORE: naglowek ma `align-items: flex-end`, przez co blok zjezdzal pod
    sztuke i wygladal, jakby sie osunal. Teraz jego pierwsza linia stoi rowno z tytulem.  */
.callinfo { align-self: flex-start; }
.callinfo:empty { display: none; }
/*  Blok, a nie kolumna poszarpanych linii. `inline-block` zwezа go do najszerszego wiersza
    (numery), a `text-align: left` w srodku ustawia wszystkie linie na jednej krawedzi. Przy
    `text-align: right` kazda linia konczyla sie rowno, ale ZACZYNALA w innym miejscu - i to
    wlasnie wygladalo na rozjezdzanie sie prawej strony.  */
.callinfo .head { display: inline-block; text-align: left; }
.callinfo .verdict { display: block; margin: .45rem 0 0; }
.callinfo .who { font-size: 1.35rem; }
.dsclogo .dscvga .r:last-child .f13 { color: #ff5555; }
@media (max-width: 700px) {
  .dsclogo .dscvga.x2 { font-size: 12px; line-height: 12px; }
}

/*  Odnosnik do odtwarzacza pod naglowkiem raportu publicznego - ma byc widoczny, ale nie krzyczec
    glosniej niz numer rozmowy, wiec ten sam stopien co wiersze `when`.  */
.head .when a { color: #55ffff; text-decoration: none; border-bottom: 1px dotted #55ffff; }
.head .when a:hover { color: #ffffff; border-bottom-color: #ffffff; }

/*  Wiersz "you are here" w liscie nagran tego numeru - ten sam odcien co werdykt, zeby oko
    znajdowalo biezacy raport bez czytania.  */
.proby tr.teraz td { background: #1a1a2e; }

/*  Pusty `#status` nie ma zajmowac miejsca w siatce naglowka - w raporcie publicznym licznik
    pakietow stoi w bloku rozmowy, razem z kierunkiem.  */
.status:empty { display: none; }

/*  CULT OF THE MODEM tuz obok marki, nie posrodku naglowka. Bylo `margin: 0 auto`, czyli sztuka
    zabierala wolne miejsce z obu stron i stala w srodku - a wolne miejsce ma isc w JEDNO miejsce,
    miedzy nia a blok rozmowy, ktory i tak dociaga do prawej krawedzi swoim `margin-left: auto`.
    Wyrownania w pionie nie nadpisujemy - naglowek ma `align-items: flex-end`, wiec dol sztuki
    lezy w tej samej linii co podtytul "CALL REPORT".  */
.cotm { line-height: 0; }
.cotm:empty { display: none; }
/*  SKALI SZTUKI NIE RUSZAMY. Ma siedem wierszy po 32 px = 224 px, a marka obok (tytul 31 +
    logo 160 + podtytul 18 z odstepami) ma 222 px - dlatego sztuka zaczyna sie na poziomie
    tytulu "DEAD SOCKET CHURCH" i konczy rowno z linia "CALL REPORT". To jest zamysl, a nie
    przypadek; zejscie na skale 1:1 (probowane 20.09) daje polowe wysokosci i wyglada jak blad.

    Waskie okno zalatwia skalowanie calego naglowka (patrz nizej), a nie zmiana tej jednej
    skali - inaczej sztuka i marka rozjechalyby sie w pionie.  */


/*  Naglowek raportu publicznego: siatka TRZECH KOLUMN - marka, sztuka, opis rozmowy. Skrajne
    kolumny maja te sama szerokosc (`1fr`), srodkowa tyle, ile potrzebuje sztuka (`auto`), wiec
    sztuka stoi dokladnie posrodku naglowka niezaleznie od tego, jak szeroki wyjdzie ktorys bok.
    Flex tego nie dawal: tam o polozeniu decydowalo, ile miejsca zostalo, a nie gdzie jest srodek.
    `align-items: center` ustawia trzy bloki wzgledem siebie w pionie.  */
header.top.publiczny { display: flex; align-items: center; }
header.top.publiczny .brand { flex: 0 0 auto; }
/*  `margin: 0 auto` na SRODKOWYM elemencie flexa dzieli cale wolne miejsce po rowno na obie
    jego strony - czyli sztuka staje dokladnie posrodku ODSTEPU miedzy marka a numerami, a nie
    posrodku naglowka. Siatka `1fr auto 1fr` robila to drugie i przy roznej szerokosci bokow
    sztuka siedziala wyraznie blizej szerszego z nich.  */
header.top.publiczny .cotm { flex: 0 0 auto; margin: 0 auto; }
/*  Blok rozmowy zepchniety o JEDNA LINIE numerow w dol. Stoi przy gornej krawedzi naglowka,
    a sasiednie logo zaczyna sie nizej, wiec bez tego wisial wyraznie za wysoko. Odstep jest
    rowny stopniowi pisma numerow (`.callinfo .who`), zeby te dwie wartosci zmienialy sie razem.  */
header.top.publiczny .callinfo { flex: 0 0 auto; margin: 1.35rem 0 0; align-self: flex-start; }
header.top.publiczny .status { display: none; }
/*  Trzy bloki naglowka stoja w JEDNEJ linii i nie wolno im sie zlamac. Gdy okno jest za waskie,
    nie zawijamy i nie chowamy niczego - `dopasujNaglowek()` w report.js i modreplay.js skaluje
    caly naglowek `zoom`-em, wiec trojka kurczy sie w proporcji i sztuka dalej stoi rowno z marka.  */
header.top.publiczny { flex-wrap: nowrap; }

