/* Wepster Pay (/pay/): 8. Автоматизація. Токени, основа й телефон — style/pay.css.

   1) Графітова панель «Від годин до секунд»: дві доріжки на одній осі часу. «Сьогодні» довга (етапи + ніч,
      коли ніхто не працює), «З Wepster Pay» крихітна на самому початку. Довжина = скільки триває, якісно.
      Скрипт (js/pay-ways.js) вмикає .is-live і в кадрі пускає по обох доріжках один «платіж»: у Wepster Pay він
      за мить доходить до «Доступ», у ручній повзе від етапу до етапу й зупиняється на ночі. Рух — CSS-кадри на
      одному циклі 9,6 с, тож усе синхронне; поза кадром цикл на паузі (--tl-run), без скрипта й за
      prefers-reduced-motion доріжки стоять у кінцевому стані.
   2) Віяло: від «Оплачено» шість ліній і шість дій, що загоряються по черзі.
   Вісь часу: на десктопі й планшеті горизонтальна, на телефоні (≤767) вертикальна: доріжки стають стовпчиками. */

/* =====================================================================
   1. ПАНЕЛЬ ЧАСУ
   ===================================================================== */

.py-tl {
  --tl-name: clamp(150px, 14vw, 190px);
  --tl-nw: .11;
  --tl-run: paused;

  position: relative;
  margin-top: clamp(28px, 4svh, 44px);
  padding: clamp(24px, 3vw, 44px);
  border-radius: var(--py-r-card);
  background: var(--c-bg);
  color: var(--c-ink);
}

.py-tl.is-on {
  --tl-run: running;
}

.py-tl-title {
  margin-bottom: clamp(26px, 4svh, 44px);
  font-size: clamp(30px, 3.4vw, 50px);
  line-height: 1.04;
}

.py-tl-body {
  display: grid;
  row-gap: 12px;
}

.py-tl-lane {
  display: grid;
  grid-template-columns: var(--tl-name) minmax(0, 1fr);
  align-items: center;
  column-gap: 24px;
}

.py-tl-name {
  display: grid;
  gap: 3px;
}

.py-tl-name b {
  font-size: 17px;
  font-weight: 700;
}

.py-tl-name > span {
  color: var(--c-soft);
  font-size: 14px;
  line-height: 1.3;
}

.py-tl-lane--now .py-tl-name b {
  color: var(--c-gain);
}

/* «секунди, 24/7» — головне, що має лишитись в оці, тож мʼятним і жирніше */
.py-tl-lane--now .py-tl-name > span {
  color: var(--c-gain);
  font-size: 15px;
  font-weight: 700;
}

/* Доріжка. Вона ж контейнер розмірів: рух жетона виражений у частках її довжини (cqw / cqh),
   тому на будь-якій ширині й у вертикальному вигляді він потрапляє рівно на етапи.
   --dx / --dy — вектор осі часу, --sx / --sy — де стоїть жетон на старті, --ex / --ey — відступ від кінця. */
.py-tl-track {
  --dx: 100cqw;
  --dy: 0px;
  --ux: 1;
  --uy: 0;
  --wl: max(calc(var(--tl-nw) * 100cqw), 112px);
  --sx: 14px;
  --sy: 0px;
  --ex: -14px;
  --ey: 0px;
  --tx0: 0px;
  --ty0: 50%;
  --f0x: 0;
  --f0y: 1;
  --fo: 0 50%;

  position: relative;
  height: 56px;
  container-type: size;
}

.py-tl-lane--now .py-tl-track {
  height: 64px;
  --ty0: 28px;
}

.py-tl-lane--was .py-tl-track {
  --c1: .075;
  --c2: .245;
  --c3: .45;
  --c4: .7;
  --ty0: 0px;
}

.py-tl-list {
  position: absolute;
  inset: 0;
}

/* ---------- Етапи ручної доріжки ---------- */

.py-tl-st {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--a) * 100% + 3px);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: calc((var(--b) - var(--a)) * 100% - 6px);
  padding: 0 8px;
  isolation: isolate;
  border-radius: 16px;
  background: var(--c-ghost);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
}

/* заливка «жетон тут уже був»: росте від початку етапу, у спокої її нема */
.py-tl-st::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: rgba(255, 255, 255, .14);
  transform: scale(var(--f0x), var(--f0y));
  transform-origin: var(--fo);
}

/* ніч: темний проміжок із пунктирним краєм: тут нікого нема */
.py-tl-night {
  border: 1.5px dashed rgba(255, 255, 255, .3);
  background: rgba(0, 0, 0, .3);
}

.py-tl-night svg {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--c-soft);
}

/* ---------- Доріжка Wepster Pay: два вузли й крихітний відрізок ---------- */

.py-tl-nd {
  position: absolute;
  top: 14px;
  z-index: 1;
  width: 28px;
  height: 28px;
}

.py-tl-nd--a {
  left: 0;
}

.py-tl-nd--b {
  left: calc(var(--wl) - 28px);
}

.py-tl-nd > span {
  position: absolute;
  top: 36px;
  left: 50%;
  color: var(--c-ink);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  transform: translateX(-50%);
}

.py-tl-ring {
  position: relative;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--c-accent);
}

.py-tl-nd--a .py-tl-ring::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-accent);
}

/* кінцевий стан вузла «Доступ»: мʼятна заливка й галочка */
.py-tl-nd--b .py-tl-ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--c-accent);
}

.py-tl-nd--b .py-tl-ring svg {
  position: relative;
  width: 17px;
  height: 17px;
  color: var(--c-accent-ink);
}

/* відрізок між вузлами й «порожній» хвіст доріжки: далі нічого не відбувається, бо вже все зроблено */
.py-tl-lane--now .py-tl-track::before,
.py-tl-lane--now .py-tl-track::after {
  content: "";
  position: absolute;
}

.py-tl-lane--now .py-tl-track::before {
  top: 26.5px;
  left: 14px;
  width: calc(var(--wl) - 28px);
  height: 3px;
  border-radius: 2px;
  background: var(--c-accent);
}

.py-tl-lane--now .py-tl-track::after {
  top: 27px;
  right: 0;
  left: calc(var(--wl) + 6px);
  border-top: 2px dotted var(--c-line);
}

/* ---------- Жетон «платіж» (без скрипта й у reduced motion його нема) ---------- */

.py-tl-tok {
  position: absolute;
  top: var(--ty0);
  left: var(--tx0);
  z-index: 3;
  display: none;
  place-items: center;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border-radius: 50%;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
}

/* поки платіж стоїть у ночі, край темного проміжку тричі спалахує мʼятним */
.py-tl-night::after {
  content: "";
  position: absolute;
  inset: -1.5px;
  border: 2px solid var(--c-accent);
  border-radius: inherit;
  opacity: 0;
}

/* ---------- Вісь ---------- */

.py-tl-axis {
  display: grid;
  grid-template-columns: var(--tl-name) minmax(0, 1fr);
  column-gap: 24px;
}

.py-tl-ticks {
  position: relative;
  grid-column: 2;
  height: 42px;
  border-top: 2px solid var(--c-line);
}

/* ніч на осі: товстіший відрізок під темним проміжком */
.py-tl-ticks::before {
  content: "";
  position: absolute;
  top: -3px;
  left: 56%;
  width: 28%;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .3);
}

.py-tl-ticks li {
  position: absolute;
  top: 14px;
  left: calc(var(--x) * 100%);
  color: var(--c-soft);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}

.py-tl-ticks li::before {
  content: "";
  position: absolute;
  top: -12px;
  left: 0;
  width: 2px;
  height: 8px;
  background: rgba(255, 255, 255, .3);
}

.py-tl-ticks li.is-mid {
  transform: translateX(-50%);
}

.py-tl-ticks li.is-mid::before {
  left: 50%;
}

/* =====================================================================
   ЦИКЛ: один «платіж» на двох доріжках (9,6 с)
   ===================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .py-tl.is-live .py-tl-tok {
    display: grid;
    animation: py-tl-was 9.6s var(--py-ease) infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-tok--now {
    animation-name: py-tl-now;
  }

  .py-tl.is-live .py-tl-night::after {
    animation: py-tl-glow 9.6s ease-in-out infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-st::before {
    animation: py-tl-fill-1 9.6s var(--py-ease) infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-st:nth-child(2)::before { animation-name: py-tl-fill-2; }
  .py-tl.is-live .py-tl-st:nth-child(3)::before { animation-name: py-tl-fill-3; }
  .py-tl.is-live .py-tl-st:nth-child(4)::before { animation-name: py-tl-fill-4; }
  .py-tl.is-live .py-tl-st:nth-child(5)::before { animation: none; }

  .py-tl.is-live .py-tl-nd--b .py-tl-ring::before {
    animation: py-tl-bfill 9.6s var(--py-ease) infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-nd--b .py-tl-ring svg {
    animation: py-tl-bicon 9.6s cubic-bezier(.34, 1.56, .64, 1) infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-ticks li {
    animation: py-tl-tick-1 9.6s linear infinite both;
    animation-play-state: var(--tl-run);
  }

  .py-tl.is-live .py-tl-ticks li:nth-child(2) { animation-name: py-tl-tick-2; }
  .py-tl.is-live .py-tl-ticks li:nth-child(3) { animation-name: py-tl-tick-3; }
  .py-tl.is-live .py-tl-ticks li:nth-child(4) { animation-name: py-tl-tick-4; }
}

/* без одиниць контейнера (cqw / cqh) жетон не знав би, куди їхати: тоді панель лишається в кінцевому стані */
@supports not (container-type: size) {
  .py-tl .py-tl-tok {
    display: none !important;
  }
}

/* ручний жетон: стоїть на етапах і зупиняється посеред ночі */
@keyframes py-tl-was {
  0% { opacity: 0; transform: translate(var(--sx), var(--sy)) scale(.5); }
  2% { opacity: 1; transform: translate(var(--sx), var(--sy)) scale(1); }
  9.4%, 15.6% { opacity: 1; transform: translate(calc(var(--c1) * var(--dx)), calc(var(--c1) * var(--dy))) scale(1); }
  25%, 32.3% { opacity: 1; transform: translate(calc(var(--c2) * var(--dx)), calc(var(--c2) * var(--dy))) scale(1); }
  42.7%, 50% { opacity: 1; transform: translate(calc(var(--c3) * var(--dx)), calc(var(--c3) * var(--dy))) scale(1); }
  60.4%, 85.4% { opacity: 1; transform: translate(calc(var(--c4) * var(--dx)), calc(var(--c4) * var(--dy))) scale(1); }
  92.7%, 100% { opacity: 0; transform: translate(calc(var(--c4) * var(--dx)), calc(var(--c4) * var(--dy))) scale(.6); }
}

/* жетон Wepster Pay: мить, і він уже в «Доступ» */
@keyframes py-tl-now {
  0% { opacity: 0; transform: translate(var(--sx), var(--sy)) scale(.5); }
  2% { opacity: 1; transform: translate(var(--sx), var(--sy)) scale(1); }
  5.2% { opacity: 1; transform: translate(calc(var(--wl) * var(--ux) + var(--ex)), calc(var(--wl) * var(--uy) + var(--ey))) scale(1); }
  8.3%, 100% { opacity: 0; transform: translate(calc(var(--wl) * var(--ux) + var(--ex)), calc(var(--wl) * var(--uy) + var(--ey))) scale(1.7); }
}

/* край ночі спалахує, поки жетон стоїть: три удари */
@keyframes py-tl-glow {
  0%, 59.9% { opacity: 0; }
  64.5%, 72.5%, 80.5% { opacity: .85; }
  68.5%, 76.5%, 84.5%, 100% { opacity: 0; }
}

/* заливка етапів: росте, поки жетон їде через етап, і гасне разом із циклом */
@keyframes py-tl-fill-1 {
  0%, 2% { opacity: 1; transform: scale(var(--f0x), var(--f0y)); }
  9.4%, 85.4% { opacity: 1; transform: scale(1, 1); }
  92.7%, 100% { opacity: 0; transform: scale(1, 1); }
}

@keyframes py-tl-fill-2 {
  0%, 15.6% { opacity: 1; transform: scale(var(--f0x), var(--f0y)); }
  25%, 85.4% { opacity: 1; transform: scale(1, 1); }
  92.7%, 100% { opacity: 0; transform: scale(1, 1); }
}

@keyframes py-tl-fill-3 {
  0%, 32.3% { opacity: 1; transform: scale(var(--f0x), var(--f0y)); }
  42.7%, 85.4% { opacity: 1; transform: scale(1, 1); }
  92.7%, 100% { opacity: 0; transform: scale(1, 1); }
}

@keyframes py-tl-fill-4 {
  0%, 50% { opacity: 1; transform: scale(var(--f0x), var(--f0y)); }
  60.4%, 85.4% { opacity: 1; transform: scale(1, 1); }
  92.7%, 100% { opacity: 0; transform: scale(1, 1); }
}

/* вузол «Доступ»: заливка й галочка зʼявляються, коли жетон доїхав */
@keyframes py-tl-bfill {
  0%, 5% { opacity: 0; transform: scale(.4); }
  8.3%, 85.4% { opacity: 1; transform: scale(1); }
  92.7%, 100% { opacity: 0; transform: scale(1); }
}

@keyframes py-tl-bicon {
  0%, 5.6% { opacity: 0; transform: scale(.3); }
  9.4%, 85.4% { opacity: 1; transform: scale(1); }
  92.7%, 100% { opacity: 0; transform: scale(1); }
}

/* підписи осі світлішають у міру того, як жетон доїжджає до своєї шкали (колір, а не прозорість: контраст ≥ 4,5:1 завжди) */
@keyframes py-tl-tick-1 {
  0%, 4% { color: var(--c-soft); }
  7%, 90% { color: var(--c-ink); }
  96%, 100% { color: var(--c-soft); }
}

@keyframes py-tl-tick-2 {
  0%, 14% { color: var(--c-soft); }
  17%, 90% { color: var(--c-ink); }
  96%, 100% { color: var(--c-soft); }
}

@keyframes py-tl-tick-3 {
  0%, 30% { color: var(--c-soft); }
  33%, 90% { color: var(--c-ink); }
  96%, 100% { color: var(--c-soft); }
}

@keyframes py-tl-tick-4 {
  0%, 48% { color: var(--c-soft); }
  51%, 90% { color: var(--c-ink); }
  96%, 100% { color: var(--c-soft); }
}

/* поява панелі при першому в'їзді в кадр (клас ставить скрипт, лише коли панель ще нижче екрана) */
@media (prefers-reduced-motion: no-preference) {
  .py-tl.is-intro {
    opacity: 0;
    transform: translateY(32px);
  }

  .py-tl.is-in {
    transition: opacity .8s ease-out, transform 1s var(--py-ease);
  }
}

/* =====================================================================
   2. ВІЯЛО: «Оплачено» → шість дій
   ===================================================================== */

.py-fan {
  display: grid;
  grid-template-columns: minmax(0, 3.4fr) minmax(0, 8.6fr);
  align-items: center;
  gap: 32px clamp(32px, 5vw, 80px);
  margin-top: clamp(56px, 8svh, 96px);
}

.py-fan-grid {
  --fan-row: 56px;
  --fan-dot: 76px;

  display: grid;
  grid-template-columns: var(--fan-dot) minmax(60px, 1fr) minmax(0, max-content);
  align-items: stretch;
}

/* вузол-тригер: графітове коло з галочкою; підпис висить під ним і не зсуває центр */
.py-fan-node {
  position: relative;
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  width: var(--fan-dot);
  height: var(--fan-dot);
  border-radius: 50%;
  color: var(--c-ink);
  cursor: pointer;
  transition: transform .35s var(--py-ease);
}

.py-fan-dot {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--c-dot-bg);
  color: var(--c-dot-ink);
}

.py-fan-dot svg {
  width: calc(var(--fan-dot) * .4);
  height: calc(var(--fan-dot) * .4);
}

.py-fan-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--c-gain);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.py-fan-lab {
  position: absolute;
  top: 100%;
  left: 50%;
  margin-top: 10px;
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  transform: translateX(-50%);
}

/* глобальна жовта пляма кнопок сайту (main.css) на вузлі зайва */
.py-fan-node:not(.x):hover,
.py-fan-node:not(.x):active {
  color: var(--c-ink);
}

.py-fan-node:not(.x):hover::before,
.py-fan-node:not(.x):active::before {
  content: none;
}

.py-fan-node:hover {
  transform: scale(1.05);
}

.py-fan-node:active {
  transform: scale(.97);
}

/* лінії: основа сірим, поверх неї по одній лінії зеленим, яку «проводить» зліва направо */
.py-fan-lines {
  position: relative;
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
}

.py-fan-lines svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.py-fan-lines path {
  fill: none;
  stroke: var(--c-line);
  stroke-width: 2;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.py-fan-lit path {
  stroke: var(--c-gain);
}

.py-fan-acts {
  grid-column: 3;
  grid-row: 1;
  display: grid;
  grid-auto-rows: var(--fan-row);
}

.py-fan-acts li {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  align-self: center;
  justify-self: start;
  gap: 12px;
  min-height: 46px;
  padding: 6px 20px 6px 6px;
  border-radius: var(--py-r-chip);
  background: var(--c-panel);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.2;
}

/* «увімкнена» дія: мʼятна підкладка (кінцевий стан — усі ввімкнені) */
.py-fan-acts li::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--c-accent);
}

.py-fan-ic {
  display: grid;
  flex: none;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--c-bg);
}

.py-fan-ic svg {
  width: 18px;
  height: 18px;
}

/* Скрипт «озброює» віяло: усе вимкнено; .is-run вмикає лінії й дії по черзі, кожну з кроком 480 мс */
@media (prefers-reduced-motion: no-preference) {
  .py-fan-grid.is-armed .py-fan-lit {
    clip-path: inset(0 100% 0 0);
  }

  .py-fan-grid.is-armed .py-fan-acts li::before {
    opacity: 0;
  }

  .py-fan-grid.is-armed.is-run .py-fan-lit {
    clip-path: inset(0);
    transition: clip-path .6s var(--py-ease) calc(var(--i) * 480ms + 250ms);
  }

  .py-fan-grid.is-armed.is-run .py-fan-acts li::before {
    opacity: 1;
    transition: opacity .45s ease-out calc(var(--i) * 480ms + 620ms);
  }

  .py-fan-grid.is-armed.is-run .py-fan-acts li {
    animation: py-fan-pop .6s var(--py-ease) calc(var(--i) * 480ms + 620ms) both;
  }

  .py-fan-grid.is-armed.is-run .py-fan-dot::after {
    animation: py-fan-ping .9s ease-out both;
  }

  /* повтор: стан скидається миттєво, без зворотного руху */
  .py-fan-grid.is-reset .py-fan-lit,
  .py-fan-grid.is-reset .py-fan-acts li::before {
    transition: none !important;
  }
}

@keyframes py-fan-pop {
  0% { transform: scale(.97); }
  45% { transform: scale(1.035); }
  100% { transform: scale(1); }
}

@keyframes py-fan-ping {
  0% { opacity: .7; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.7); }
}

/* =====================================================================
   АДАПТИВ
   ===================================================================== */

@media (max-width: 992px) {
  .py-tl-lane,
  .py-tl-axis {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 10px;
  }

  .py-tl-name {
    grid-auto-flow: column;
    justify-content: start;
    align-items: baseline;
    gap: 12px;
  }

  .py-tl-ticks {
    grid-column: 1;
  }

  .py-tl-st {
    font-size: 14px;
  }

  .py-fan {
    grid-template-columns: minmax(0, 1fr);
  }

  .py-fan-grid {
    max-width: 720px;
  }
}

/* ТЕЛЕФОН (до 767px). Вісь часу вертикальна: ліворуч шкала, посередині доріжка Wepster Pay, праворуч ручна.
   Лишаємо одну вісь, а не складаємо доріжки картками: рух жетона (кадри вище) рахується від довжини доріжки,
   тож вертикаль дає той самий «платіж» без переписування анімації. Читабельність — за рахунок ширини
   (вужче поле панелі й шкала), нижчої доріжки (272px замість 408px) і підписів, що переносяться, а не обрізаються. */
@media (max-width: 767px) {
  .py-tl {
    --tl-vh: 272px;
    --tl-nw: .23;

    padding: 22px 14px 22px;
  }

  .py-tl-title {
    margin-bottom: 20px;
    padding-inline: 4px;
  }

  .py-tl-body {
    grid-template-columns: 70px 88px minmax(0, 1fr);
    grid-template-rows: auto var(--tl-vh);
    column-gap: 8px;
    row-gap: 12px;
  }

  .py-tl-lane {
    display: contents;
  }

  .py-tl-name {
    grid-auto-flow: row;
    align-self: end;
    gap: 3px;
  }

  .py-tl-name b {
    font-size: var(--py-fs-4);
  }

  .py-tl-name > span,
  .py-tl-lane--now .py-tl-name > span {
    font-size: var(--py-fs-5);
  }

  /* підпис «З Wepster Pay» займає шкалу й свою доріжку разом: в одному рядку, не в чотири */
  .py-tl-lane--now .py-tl-name { grid-column: 1 / 3; grid-row: 1; }
  .py-tl-lane--now .py-tl-track { grid-column: 2; grid-row: 2; }
  .py-tl-lane--was .py-tl-name { grid-column: 3; grid-row: 1; }
  .py-tl-lane--was .py-tl-track { grid-column: 3; grid-row: 2; }

  .py-tl-track,
  .py-tl-lane--now .py-tl-track {
    --dx: 0px;
    --dy: 100cqh;
    --ux: 0;
    --uy: 1;
    --wl: max(calc(var(--tl-nw) * 100cqh), 70px);
    --sx: 0px;
    --sy: 14px;
    --ex: 0px;
    --ey: -14px;
    --tx0: 50%;
    --ty0: 0px;
    --f0x: 1;
    --f0y: 0;
    --fo: 50% 0;

    height: auto;
  }

  .py-tl-lane--was .py-tl-track {
    --tx0: 7px;
    --ty0: 0px;
  }

  .py-tl-lane--now .py-tl-track {
    --tx0: 14px;
  }

  .py-tl-st {
    top: calc(var(--a) * 100% + 3px);
    right: 0;
    bottom: auto;
    left: 0;
    width: auto;
    height: calc((var(--b) - var(--a)) * 100% - 6px);
    padding: 0 8px 0 20px;
    font-size: var(--py-fs-5);
  }

  .py-tl-nd {
    top: 0;
    left: 0;
    width: 28px;
    height: 28px;
  }

  .py-tl-nd--b {
    top: calc(var(--wl) - 28px);
    left: 0;
  }

  .py-tl-nd > span {
    top: 50%;
    left: 36px;
    font-size: var(--py-fs-5);
    transform: translateY(-50%);
  }

  .py-tl-lane--now .py-tl-track::before {
    top: 14px;
    left: 12.5px;
    width: 3px;
    height: calc(var(--wl) - 28px);
  }

  .py-tl-lane--now .py-tl-track::after {
    top: calc(var(--wl) + 6px);
    right: auto;
    bottom: 0;
    left: 13px;
    border-top: 0;
    border-left: 2px dotted var(--c-line);
  }

  .py-tl-axis {
    grid-column: 1;
    grid-row: 2;
    display: block;
  }

  .py-tl-ticks {
    grid-column: auto;
    height: 100%;
    border-top: 0;
    border-right: 2px solid var(--c-line);
  }

  .py-tl-ticks::before {
    top: 56%;
    right: -3px;
    left: auto;
    width: 4px;
    height: 28%;
  }

  .py-tl-ticks li {
    top: calc(var(--x) * 100%);
    right: 12px;
    left: auto;
    font-size: var(--py-fs-5);
    text-align: right;
  }

  .py-tl-ticks li::before {
    top: 50%;
    right: -12px;
    left: auto;
    width: 8px;
    height: 2px;
    margin-top: -1px;
  }

  .py-tl-ticks li.is-mid {
    transform: translateY(-50%);
  }

  .py-tl-ticks li.is-mid::before {
    left: auto;
  }

  .py-fan-grid {
    --fan-row: 52px;
    --fan-dot: 48px;

    grid-template-columns: var(--fan-dot) minmax(32px, 1fr) minmax(0, max-content);
  }

  .py-fan-acts li {
    gap: 10px;
    padding-right: 16px;
    font-size: var(--py-fs-5);
  }

  .py-fan-lab {
    font-size: var(--py-fs-5);
  }
}

@media (prefers-reduced-motion: reduce) {
  .py-fan-node {
    transition: none;
  }
}
