/* Harmonogram planu produkcji - wykres kolejek maszyn.
 *
 * SPIS TREŚCI (sekcje w tej kolejności):
 *   pasek narzędzi: przyciski, ostrzeżenie o połączeniu, podziałka
 *   układ panelu
 *   wiersz, kolumna maszyn i oś
 *   kafelek
 *   linia "teraz"
 *   zawężenia: zaznaczone zlecenie i filtr
 *   pasek narzędzi - układ
 *   przeciąganie i znaczniki kafelka
 *   wąskie kafelki
 *   kolory statusów
 *   pas stanu poprzedniej operacji
 *
 * UWAGA: kolejność reguł w tym pliku ma znaczenie. .schedule-bar-in_progress.is-overrun,
 * .schedule-bar.is-dimmed i .schedule-bar.is-downtime mają tę samą wagę, więc o wyniku
 * decyduje to, która stoi niżej. Przestawianie bloków może zmienić wygląd bez zmiany
 * ani jednej reguły.
 *
 * UWAGA DRUGA: kreskowanie przekroczonego planu wisi na .schedule-bar-in_progress,
 * a nie na samym .is-overrun. Powód stoi przy tej regule i nie jest kosmetyczny -
 * inaczej wstrzymana operacja wygląda jak pracująca.
 */

/* ========================================================================== */
/* PASEK NARZĘDZI: PRZYCISKI, OSTRZEŻENIE O POŁĄCZENIU, PODZIAŁKA
   Ostrzeżenie zapala markOffline w JS. Układ trzech grup jest niżej, w sekcji
   "pasek narzędzi - układ". */
/* ========================================================================== */

/* Ostrzeżenie o zerwanej rozmowie z serwerem. Wygląd bierze z .disclaimer, czyli z tego
   samego stylu co pozostałe ostrzeżenia w programie, tylko niższe, żeby nie rozpychało
   paska. Reguła z [hidden] jest konieczna: .disclaimer ustawia display, a to bije
   domyślne ukrywanie atrybutem. */
.schedule-offline {
    padding: 5px 10px;
    font-size: 0.9em;
}

.schedule-offline[hidden] {
    display: none;
}

/* Przełącznik podziałki nad wykresem. Zmiana działki nie odpytuje serwera -
   paski niosą sekundy, a piksele przelicza production_schedule_controller. */
.schedule-scales {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Flaga "Automatyczne odświeżanie" przy przycisku "Teraz". Kreska "teraz" stoi
   nieruchomo w zerze osi, a dane są z chwili wczytania - ta flaga jest jedyną drogą
   do tego, żeby ekran sam się aktualizował. Kwadracik i napis w jednej linii,
   bo pasek narzędzi jest jednowierszowy. Cała etykieta jest klikalna. */
.schedule-autorefresh {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    color: var(--color-font-light);
    cursor: pointer;
}

.schedule-scale {
    padding: 2px 10px;
    border-radius: var(--button-radius);
}

.schedule-scale.is-active {
    background: var(--color-background-light);
    color: var(--color-font);
    font-weight: bold;
}


/* ========================================================================== */
/* UKŁAD PANELU
   Wysokość wykresu wynika z liczby maszyn - zmienną --schedule-rows podaje widok. */
/* ========================================================================== */

/* Ramka turbo (.bottom-main-content) ma wysokość z siatki strony i overflow: hidden.
   Panel bierze z niej wszystko, co zostało, i jest kolumną, która umie się skurczyć -
   bez tego przy niższym oknie dolna krawędź wykresu schodzi pod obcięcie razem
   z poziomym paskiem przewijania. */
.schedule-panel {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* Gdy maszyn jest więcej, niż mieści się w oknie, kurczyć ma się wyłącznie wykres.
   Bez tego flex rozdziela brakujące piksele proporcjonalnie i pasek narzędzi też dostaje
   swoją część, czyli robi się odrobinę niższy niż na pozostałych zakładkach. */
.schedule-panel > .above-table-div {
    flex: 0 0 auto;
}

.schedule {
    --schedule-col-width: 190px;
    --schedule-row-height: 96px;
    --schedule-head-height: 32px;

    position: relative;
    overflow: auto;
    /* Bez tego Chrome przechwytuje poziomy gest, gdy oś dojdzie do końca, i zamienia go
       na nawigację: przeskok karty albo cofnięcie strony. Przy wykresie, po którym jeździ
       się w bok cały czas, zdarza się to co chwilę. "contain" trzyma gest w środku
       wykresu i wyłącza samą nawigację gestem na tym elemencie. */
    overscroll-behavior-x: contain;
    /* Wysokość z liczby maszyn gniazda, którą widok podaje zmienną: małe gniazdo kończy się
       pod ostatnim wierszem, zamiast rozciągać się na całe okno. Gdy maszyn jest więcej,
       niż mieści się w ramce, flex-shrink docina wykres do okna i reszta schodzi pod
       pionowe przewijanie - bez sztywnego limitu wierszy.

       Te 18 px to zapas na poziomy pasek przewijania. W systemach, gdzie pasek zabiera
       miejsce (nie na macOS), bez zapasu odgryzałby kawałek ostatniego wiersza
       i doskakiwałby do tego pionowy pasek na kilkanaście pikseli. */
    height: calc(var(--schedule-head-height)
                 + var(--schedule-rows, 8) * var(--schedule-row-height)
                 + 18px);
    flex: 0 1 auto;
    min-height: 0;
    background: white;
}

/* ========================================================================== */
/* WIERSZ, KOLUMNA MASZYN I OŚ
   Kolumna maszyn i nagłówek osi są przyklejone. Warstwy opisane przy .schedule-machine-col. */
/* ========================================================================== */
/* Wiersz musi być szeroki na tyle, ile jego zawartość. Domyślnie blok bierze szerokość
   okna, a oś jest od niego dużo szersza - wtedy kreska rozdzielająca maszyny urywa się

   przy pierwszym przewinięciu w prawo. */
.schedule-row {
    display: flex;
    align-items: stretch;
    width: max-content;
    min-width: 100%;
    height: var(--schedule-row-height);
    border-bottom: 1px solid var(--color-gray);
    background: white;
}

.schedule-head {
    position: sticky;
    top: 0;
    z-index: 6;
    height: var(--schedule-head-height);
    color: var(--color-font-light);
}

/* Pierwsza kolumna zostaje na miejscu przy przewijaniu osi w bok */
/* Warstwy w kontenerze: kafelki 0, linia "teraz" 2, przeciągany kafelek 3,
   bieżące trafienie filtra 4, kolumna maszyn 5, nagłówek osi 6. Bez tego linia "teraz"
   wychodziła na kolumnę maszyn, bo obie miały tę samą warstwę, a tor jest w kodzie
   po kolumnie. */
.schedule-machine-col {
    position: sticky;
    left: 0;
    z-index: 5;
    flex: 0 0 var(--schedule-col-width);
    width: var(--schedule-col-width);
    display: flex;
    /* Kolumna, bo w widoku zlecenia pod nazwą maszyny stoi jeszcze podpis
       z gniazdem i numerami operacji. Przy jednej linii wychodzi na to samo. */
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    padding: 0 12px;
    background: white;
    border-right: 1px solid var(--color-gray);
}

.schedule-head .schedule-machine-col {
    z-index: 7;
}

/* Podpis pod nazwą maszyny: z jakiego jest gniazda i które operacje zlecenia na niej
   stoją. Tylko w widoku zlecenia - w gnieździe wszystkie wiersze są z tego samego
   gniazda i nie ma czego dopisywać. */
.schedule-machine-note {
    max-width: 100%;
    font-size: 12px;
    color: var(--color-font-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Szerokość osi jest ta sama dla nagłówka i wszystkich torów, więc kontroler wpisuje ją
   raz na panelu jako zmienną, a nie w każdy element z osobna. */
.schedule-axis,
.schedule-track {
    position: relative;
    flex: 0 0 auto;
    width: var(--schedule-total-px);
}

/* Z kontrolera przychodzi stylem inline samo przesunięcie działki - reszta jest tutaj. */
.schedule-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    padding-left: 6px;
    font-size: 12px;
    white-space: nowrap;
    border-left: 1px solid var(--color-gray);
}


/* ========================================================================== */
/* KAFELEK
   Geometrię (pozycja, szerokość) ustawia JS stylem inline - powód opisany przy .schedule-bar. */
/* ========================================================================== */
.schedule-bar {
    overflow: hidden;
    padding: 4px 8px;
    border: 1px solid var(--color-gray-2);
    border-radius: 3px;
    background: var(--color-background);
}

/* table.css dokleja kółko "i" do każdego diva z title i ustawia mu position: relative.
   Na kafelku harmonogramu kółko zjada linię, a position: relative wywracał układ -
   cały pasek jest hoverowalny, więc znacznik jest tu zbędny. */
.schedule-bar[title]::after {
    content: none;
}

.schedule-bar:hover {
    border-color: var(--color-font);
}

.schedule-bar-line {
    /* nad wypełnieniem i ogonem przekroczenia */
    position: relative;
    z-index: 1;
    display: flex;
    gap: 8px;
    align-items: baseline;
    white-space: nowrap;
    font-size: 13px;
    /* Cztery linie muszą zmieścić się w 80 px kafelka razem z paddingiem */
    line-height: 17px;
}

.schedule-bar-line a {
    font-size: 13px;
}

.schedule-bar-name {
    overflow: hidden;
    text-overflow: ellipsis;
}

.schedule-bar-icons {
    align-items: center;
    gap: 6px;
}

.schedule-bar-icons > div {
    display: flex;
    align-items: center;
}

.schedule-bar-icons img {
    height: 16px;
    width: auto;
}

/* Przerwy w sekwencji zlecenia. Minus, czyli nakładanie się operacji, na czerwono. */
.schedule-bar-gaps {
    color: var(--color-font-light);
    font-size: 12px;
    gap: 12px;
}

.schedule-gap {
    font-size: 12px;
}

.schedule-gap-overlap {
    color: var(--color-red);
    font-weight: bold;
}

/* Wypełnienie: jaka część planowanego czasu jest już zaraportowana. Szerokość w procentach
   podaje serwer, więc zmiana podziałki niczego tu nie przelicza. */
.schedule-bar-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    background: rgba(17, 24, 39, 0.12);
    pointer-events: none;
}

/* Przekroczony plan ("W trakcie, po czasie"): całe tło kafelka w ukośne paski z drugiego,
   ciemniejszego odcienia żółci. Długość paska zostaje bez zmian - o ile plan został
   przekroczony, mówi tekst przy ikonach i dymek.

   KRESKOWANIE TYLKO DLA REALIZACJI, i to jest decyzja, nie przeoczenie. Przekroczyć plan
   może też operacja WSTRZYMANA - raporty zostają, gdy ktoś ją wstrzyma. Gdyby reguła szła
   po samym .is-overrun, przykryłaby czerwień wstrzymania żółcią realizacji i wstrzymana
   operacja wyglądałaby jak pracująca. A w tym programie wstrzymanie przykrywa realizację,
   nie odwrotnie - patrz Operation#status_with_hold.

   Kreskowania w czerwieni celowo nie robimy: tak wygląda przestój maszyny (sekcja na końcu
   pliku), a te dwie rzeczy nie mogą być nie do odróżnienia. Na wstrzymanym kafelku
   o przekroczeniu mówi więc tekst "+N ponad plan" i dymek. */
.schedule-bar-in_progress.is-overrun {
    background: repeating-linear-gradient(45deg,
        #FDE68A,
        #FDE68A 6px,
        #FEF9C3 6px,
        #FEF9C3 12px);
    border-color: #CA8A04;
}

.schedule-bar.is-overrun .schedule-bar-fill {
    display: none;
}

.schedule-progress {
    font-size: 12px;
    color: var(--color-font-light);
}

/* Kolor bierze z kafelka, bo na wstrzymanej operacji tło jest już czerwone i czerwony
   druk by się na nim zgubił. Wyróżnia sama grubość. */
.schedule-overrun-label {
    font-size: 12px;
    font-weight: bold;
    color: inherit;
}


/* ========================================================================== */
/* LINIA "TERAZ"
   Stoi nieruchomo w zerze osi, czyli dokładnie tam, gdzie serwer policzył paski.
   Pozycja ze zmiennej --schedule-now-px, jednej na cały panel. */
/* ========================================================================== */
/* Linia nie jedzie i to jest decyzja: paski są z chwili wczytania, więc jadąca kreska
   przy stojących paskach kłamałaby o tym, jak stare są dane. Zamiast niej godzina
   wyliczenia stoi przy podpisie "teraz" na osi, a świeżość daje odświeżenie panelu -
   ręczne albo z pola "Automatyczne odświeżanie". */
.schedule-now {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--schedule-now-px);
    width: 0;
    border-left: 1px dashed var(--color-blue);
    pointer-events: none;
    z-index: 2;
}

/* ========================================================================== */
/* ZAWĘŻENIA: ZAZNACZONE ZLECENIE I FILTR
   Przygaszanie idzie kolorami, nie przezroczystością - powód opisany niżej. */
/* ========================================================================== */
/* Zaznaczone zlecenie: jego operacje podświetlone, reszta przygaszona. Zaznaczenie
   żyje w pamięci przeglądarki, więc trzyma się przy przechodzeniu między gniazdami

   i nie kosztuje ani jednego zapytania. */
.schedule-bar.is-selected-order {
    box-shadow: inset 0 0 0 2px var(--color-button);
}

/* Przygaszenie idzie kolorami, nie przezroczystością. Półprzezroczysty element to dla
   przeglądarki osobna warstwa - przy kilkuset kafelkach gniazda przewijanie osi dławiło
   się po zaznaczeniu zlecenia, a efekt jest ten sam. */
.schedule-bar.is-dimmed,
.schedule-bar.is-dimmed.is-overrun {
    background: #FCFCFC;
    border-color: var(--color-gray);
    color: var(--color-gray-2);
}

/* UWAGA przy dokładaniu treści do kafelka: przygaszenie działa przez ustawienie color
   na samym kafelku, a to dziedziczy się tylko tam, gdzie nikt nie ustawił własnego
   koloru. Każdy element ze swoim color MUSI więc trafić na tę listę, inaczej zostanie
   w pełnej barwie na przygaszonym kafelku. Tak było z linią przerw: .schedule-bar-gaps
   ma własny kolor, więc czasy świeciły pełną siłą, choć reszta kafelka była szara. */
.schedule-bar.is-dimmed a,
.schedule-bar.is-dimmed .schedule-bar-short,
.schedule-bar.is-dimmed .schedule-bar-gaps,
.schedule-bar.is-dimmed .schedule-gap-overlap,
.schedule-bar.is-dimmed .schedule-progress,
.schedule-bar.is-dimmed .schedule-overrun-label {
    color: var(--color-gray-2);
}

/* Wypełnienie i ikony na przygaszonym kafelku zostałyby w pełnym kolorze i ściągały oko */
.schedule-bar.is-dimmed .schedule-bar-fill,
.schedule-bar.is-dimmed .schedule-bar-icons {
    display: none;
}

/* ========================================================================== */
/* PASEK NARZĘDZI - UKŁAD
   Trzy grupy: akcje po lewej, filtr pośrodku, podziałka po prawej. */
/* ========================================================================== */
/* Filtr stoi pośrodku paska narzędzi, żeby nie sklejał się wizualnie z podziałką.
   Wolne miejsce dzielą po równo grupa po lewej i po prawej, więc filtr wypada
   w środku strony, a nie w środku luki między nimi - inaczej uciekałby w prawo,
   gdy po lewej zapali się ostrzeżenie albo zaznaczone zlecenie.

   Obie grupy mają domyślne min-width: auto, więc szersza od połowy nic nie ściśnie,

   tylko zepchnie filtr z osi. Przy wąskim oknie pasek zawija się jak dotąd. */
.schedule-panel .left-actions,
.schedule-panel .right-actions {
    flex: 1 1 0;
}

.schedule-panel .right-actions {
    justify-content: flex-end;
}

.schedule-panel .schedule-filter {
    flex: 0 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

/* Ile kafelków przechodzi filtr. Bez tej liczby ekran, na którym nic nie pasuje,
   wygląda tak samo jak popsuty - wszystko szare i nie wiadomo dlaczego.
   Bez własności display, żeby działał zwykły atrybut hidden. */
.schedule-panel .schedule-filter-count {
    font-size: 13px;
    color: var(--color-font-light);
    white-space: nowrap;
}

.schedule-selection {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.schedule-selection[hidden] {
    display: none;
}

.schedule-selection-label {
    color: var(--color-font-light);
}

/* ========================================================================== */
/* PRZECIĄGANIE I ZNACZNIKI KAFELKA
   Kafelek przeciągany, ostatnio przestawiony, bieżące trafienie filtra i kafelek ze złymi czasami. */
/* ========================================================================== */
/* Kafelek, na którym stanął obchód trafień (Enter w polu filtra). Obwódka jest
   z zewnątrz i w kolorze, którego nie używa żaden status ani zaznaczenie zlecenia,
   żeby dało się ją wypatrzyć po przewinięciu przez pół gniazda. */
.schedule-bar.is-current-match {
    outline: 2px solid var(--color-orange);
    outline-offset: 1px;
    z-index: 4;
}

/* Kafelek, którego nie dało się postawić, bo przyszły złe czasy. Bez tego znaku taki
   kafelek po prostu zlewa się z innymi przy lewej krawędzi i wygląda jak niedziałający
   skrypt - patrz markBroken w production_schedule_controller.js. */
.schedule-bar.is-broken {
    outline: 2px dashed var(--color-red);
    outline-offset: -1px;
}

/* Ostatnio przestawiony kafelek. Po przeciągnięciu wraca cały harmonogram, więc bez
   obwódki trudno wypatrzyć, co się właśnie ruszyło. Znika przy kolejnym odświeżeniu. */
.schedule-bar.is-moved {
    border: 2px solid var(--color-font);
}


/* Przeciąganie w obrębie kolejki własnej maszyny. touch-action wyłącza przewijanie
   palcem nad paskiem, inaczej gest ucieka do kontenera zamiast chwytać kafelek. */
.schedule-bar[data-draggable="true"] {
    cursor: grab;
    touch-action: none;
}

/* Ciągnięty kafelek przesuwa się transformem, więc uprzedzamy przeglądarkę, żeby
   trzymała go w osobnej warstwie i nie przemalowywała przy każdym drgnięciu myszy. */
.schedule-bar.is-dragging {
    cursor: grabbing;
    z-index: 3;
    opacity: 0.9;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    will-change: transform;
}


/* ========================================================================== */
/* WĄSKIE KAFELKI
   Progi czytelności ustawia placeBar w JS klasami is-tiny, is-compact i is-vertical. */
/* ========================================================================== */
/* Skrót na wąski kafelek: ZL-9/4, czyli kod zlecenia bez zer wiodących i numer operacji.
   Pokazuje go dopiero klasa is-compact, bo na pełnym kafelku jest cały nagłówek. */
.schedule-bar-short {
    display: none;
    /* nad wypełnieniem, tak jak zwykłe linie kafelka */
    position: relative;
    z-index: 1;
    font-size: 13px;
    line-height: 17px;
    white-space: nowrap;
    overflow: hidden;
    /* Gdy i skrót się nie mieści, lepsze wielokropek niż cichy cios: obcięte ZL-99999
       wygląda jak poprawny kod innego zlecenia. */
    text-overflow: ellipsis;
    color: var(--color-link);
}

/* Progi czytelności - klasy dokłada production_schedule_controller po zmierzeniu paska */
.schedule-bar.is-tiny {
    padding: 0;
}

.schedule-bar.is-tiny .schedule-bar-line {
    display: none;
}

/* Wąski kafelek: zamiast urwanego w połowie nagłówka sam skrót */
.schedule-bar.is-compact {
    padding: 4px;
}

.schedule-bar.is-compact .schedule-bar-line {
    display: none;
}

.schedule-bar.is-compact .schedule-bar-short {
    display: block;
}

/* Najwęższe kafelki z pasma: skrót nie mieści się w poziomie, więc kładziemy go pionowo.
   writing-mode to zwykły layout, nie osobna warstwa jak obrót transformem, więc przy
   setkach kafelków nic nie kosztuje. Wysokość wiersza daje około 79 px, czyli tyle,
   ile potrzeba na ZL-9/4. */
.schedule-bar.is-vertical {
    padding: 2px;
}

.schedule-bar.is-vertical .schedule-bar-short {
    writing-mode: vertical-rl;
    /* Obrót o pół obrotu odwraca kierunek czytania na dolny do górnego, czyli tak jak
       podpisuje się osie wykresów. Robimy to transformem, a nie wartością sideways-lr,
       bo tamta jest dużo młodsza i nie wszędzie działa. Sam obrót nie tworzy osobnej
       warstwy, więc przewijania nie dotyka. */
    transform: rotate(180deg);
    height: 100%;
}

/* Od jedenastu znaków (ZL-99999/12 w górę) skrót nie mieści się w 73 px przebiegu
   przy 13 px, a przy 11 px wchodzi nawet ZL-999999/23, czyli najdłuższy możliwy numer. */
.schedule-bar.is-vertical .schedule-bar-short.is-long {
    font-size: 11px;
    line-height: 14px;
}


/* ========================================================================== */
/* KOLORY STATUSÓW
   Tło i obwódka kafelka zależnie od statusu operacji. Zakończone na wykres nie trafiają. */
/* ========================================================================== */
/* Kolory statusów: Zaplanowane błękitne, W trakcie żółte, Wstrzymane czerwone.
   Te same trójki (tło, obwódka, druk) noszą plakietki statusu w tabelach -
   patrz tablica styli w StatesHelper#status_span. */
.schedule-bar-waiting {
    background: #F0F9FF;
    border-color: #7DD3FC;
    color: #0C4A6E;
}

.schedule-bar-in_progress {
    background: #FEF9C3;
    border-color: #EAB308;
    color: #713F12;
}

.schedule-bar-on_hold {
    background: #FEE2E2;
    border-color: #F87171;
    color: #7F1D1D;
}


/* ========================================================================== */
/* PRZESTOJE MASZYN
   Ten sam kształt kafelka co operacja, wyróżnia go czerwone kreskowane tło,
   dzięki czemu stojąca maszyna rzuca się w oczy bez najeżdżania kursorem. */
/* ========================================================================== */
.schedule-bar.is-downtime {
    background: repeating-linear-gradient(45deg,
        #FECACA,
        #FECACA 6px,
        #FEE2E2 6px,
        #FEE2E2 12px);
    border-color: #F87171;
    color: #7F1D1D;
}

/* Na kafelku przestoju nic nie jest klikalne - nie ma zlecenia ani widoku operacji.
   .schedule-bar-short świeci niebieskim linkowym, bo u operacji zastępuje linki,
   więc tutaj obiecywałby klikalność. Ujednolicamy kolor z tekstem kafelka. */
.schedule-bar.is-downtime .schedule-bar-short {
    color: #7F1D1D;
}

/* ZAWĘŻENIE - bez tego kreskowanie świeci pełną siłą na wygaszonym wykresie:
   is-downtime ma tę samą wagę co is-dimmed, a ta sekcja stoi na końcu pliku. */
.schedule-bar.is-dimmed.is-downtime {
    background: #FCFCFC;
    border-color: var(--color-gray);
    color: var(--color-gray-2);
}

/* To samo zawężenie dla skrótu: reguła wyżej remisuje wagą z .is-dimmed i wygrywa
   kolejnością. */
.schedule-bar.is-dimmed.is-downtime .schedule-bar-short {
    color: var(--color-gray-2);
}


/* ========================================================================== */
/* PAS STANU POPRZEDNIEJ OPERACJI
   Cienki pas u góry kafelka mówiący o SĄSIEDZIE, nie o samym kafelku: czy tę
   operację da się już zacząć.
     zielony  - nic nie blokuje (pierwsza w zleceniu albo poprzednia zakończona),
     żółty    - poprzednia leci właśnie na maszynie, czyli zaraz się zwolni,
     czerwony - poprzednia wstrzymana, czyli coś się zacięło.

   TRZY KOLORY, NIE WIĘCEJ. Poprzednia czekająca w kolejce albo jeszcze poza planem
   pasa nie dostaje: to zwykłe "jeszcze długo", stan większości kafelków - pas na
   każdym z nich robi się szumem i gubi te trzy, które coś znaczą. Barwy są z palety
   statusów, bo pas pokazuje po prostu stan tamtej operacji - nic nowego nie trzeba
   się uczyć.

   DLACZEGO PAS, A NIE OBWÓDKA: obwódka niesie już status samego kafelka, a do tego
   nadpisuje ją "ostatnio przestawiony" (.is-moved). ::before jest jedynym zupełnie
   wolnym kanałem - div[title] z table.css zajmuje wyłącznie ::after (kółko "i",
   na kafelku zgaszone w sekcji "kafelek").

   DLACZEGO GEOMETRIA, A NIE IKONA: poniżej 150 px kafelek gubi ikony i cały tekst,
   poniżej 20 px zostaje sam kolor - a przy grubej podziałce, czyli wtedy, gdy się
   planuje, większość kafelków jest właśnie taka. Pas widać na każdej szerokości.

   Klasy rozdaje ScheduleHelper#schedule_predecessor_class - tylko operacjom
   zaplanowanym, bo ta w trakcie już wystartowała, a wstrzymana stoi z własnego
   powodu. Słowami to samo mówi dymek, patrz #schedule_predecessor_title. */
/* ========================================================================== */
.schedule-bar.is-prev-ready::before,
.schedule-bar.is-prev-running::before,
.schedule-bar.is-prev-held::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    pointer-events: none;
}

.schedule-bar.is-prev-ready::before {
    background: #4ADE80;
}

.schedule-bar.is-prev-running::before {
    background: #EAB308;
}

.schedule-bar.is-prev-held::before {
    background: #F87171;
}

/* ZAWĘŻENIE - na przygaszonym kafelku pas świeciłby pełną siłą i ściągał oko,
   tak samo jak wypełnienie i ikony, które znikają w sekcji "zawężenia".
   Waga ta sama co reguły wyżej, więc ta MUSI stać pod nimi. */
.schedule-bar.is-dimmed::before {
    display: none;
}
