/* =============================================================================
   rail — наскрізна шкала приладу. Above the fold на всіх ширинах, тому
   вантажиться блокуючи рендер.

   Мобільна база — горизонтальна смуга під шапкою. Від --bp-lg — вертикальна
   шкала на лівому полі, у власній колонці --rail-reserve.

   Рухаються тільки transform і opacity; JS пише єдину властивість
   --rail-progress (0…1) і --rail-kick (переліт покажчика в lamp test).
   ============================================================================= */

.rail {
  --rail-progress: 0;
  --rail-kick: 0;
  position: fixed;
  inset-block-start: var(--header-height);
  inset-inline: 0;
  /* Смуга — це шасі приладу, а не прозора плівка: контент не має просвічувати
     крізь поділки. Висота вмісту лишається --rail-mobile-height (8px), кромка
     додається зверху бордером, тому block-size рахує обидві (спец. 002 §14.22). */
  block-size: calc(var(--rail-mobile-height) + var(--border-width-hair));
  background: var(--rail-chassis-bg);
  border-block-end: var(--rail-chassis-edge);
  z-index: var(--z-rail);
  pointer-events: none;
}

/* Зона тапу смуги: прозора, на всю мінімальну висоту дотику. */
.rail::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: var(--rail-tap-min);
  pointer-events: auto;
}

.rail__scale {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  container-type: size;
}

/* ---- доріжка й заливка ------------------------------------------------------ */

.rail__track,
.rail__fill {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: var(--rail-track-width);
}

.rail__track { background: var(--rail-track); }

.rail__fill {
  background: var(--rail-fill);
  transform-origin: left center;
  transform: scaleX(var(--rail-progress));
  will-change: transform;
}

/* ---- поділки ---------------------------------------------------------------- */

.rail__step {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: calc(var(--i) / var(--rail-last, 12) * 100%);
  transform: translateX(-50%);
}

.rail__link {
  position: relative;
  display: block;
  pointer-events: auto;
}

/* Сама поділка — це риска 2×8px, тобто ціль у дев'ять разів менша за мінімум
   WCAG 2.2 (24×24). Збільшувати саму риску не можна: вона й має бути рискою.
   Тому хіт-область розсувається невидимим ::before поверх поділки — вигляд
   не змінюється, палець потрапляє. Той самий прийом, що вже застосований до
   мобільної смуги через --rail-tap-min. */
.rail__link::before {
  content: "";
  position: absolute;
  inset-block: 50%;
  inset-inline: 50%;
  min-inline-size: var(--tap-min);
  min-block-size: var(--tap-min);
  transform: translate(-50%, -50%);
}

.rail__tick {
  display: block;
  background: var(--rail-tick);
  transition:
    background-color var(--dur-fast) var(--ease-in),
    transform var(--dur-fast) var(--ease-in);
}

.rail__tick--major {
  inline-size: var(--rail-tick-major-width);
  block-size: var(--rail-tick-minor);
  transform-origin: center top;
}

/* Малих поділок на смузі немає — вони живуть тільки на вертикальній шкалі. */
.rail__minors,
.rail__tick--minor,
.rail__num,
.rail__label { display: none; }

/* ---- покажчик --------------------------------------------------------------- */

.rail__pointer {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: var(--rail-pointer-thickness);
  block-size: var(--rail-mobile-pointer);
  margin-inline-start: calc(var(--rail-pointer-thickness) / -2);
  background: var(--accent);
  transform: translateX(calc(var(--rail-progress) * 100cqw));
  will-change: transform;
}

.rail__dot {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 50%;
  inline-size: var(--rail-pointer-dot);
  block-size: var(--rail-pointer-dot);
  margin-inline-start: calc(var(--rail-pointer-dot) / -2);
  border-radius: var(--radius-chip);
  background: var(--accent);
  box-shadow: var(--shadow-lamp-soft);
  transition: box-shadow var(--dur-needle) var(--ease-in-out);
}

/* Один імпульс лампи при перетині поділки. */
.rail[data-pulse="true"] .rail__dot { box-shadow: var(--shadow-lamp); }

/* ---- стани поділки ---------------------------------------------------------- */

.rail__link[aria-current="true"] .rail__tick--major,
.rail__link[data-lamp="on"] .rail__tick--major {
  background: var(--rail-tick-active);
  transform: scaleY(var(--rail-tick-flare));
  transition:
    background-color var(--dur-needle) var(--ease-snap),
    transform var(--dur-needle) var(--ease-snap);
}

.rail__link[aria-current="true"] .rail__num,
.rail__link[data-lamp="on"] .rail__num {
  color: var(--rail-tick-active);
  transition: color var(--dur-needle) var(--ease-out);
}

/* =============================================================================
   Вертикальна шкала: власна колонка лівого поля.
   ============================================================================= */

@media (min-width: 64rem) {
  /* Тут .rail — це вже сама шкала всередині шасі; корпус малює ::before. */
  .rail {
    inset-block: var(--rail-top) var(--rail-bottom);
    inset-inline-start: var(--rail-gutter);
    inset-inline-end: auto;
    inline-size: var(--rail-tick-major);
    block-size: auto;
    background: none;
    border-block-end-width: 0;
  }

  /* Шасі: заглиблений канал приладу на всю висоту вікна. Не затемнення під
     рейкою, а конструкція — лишається темним і над світлими секціями
     (art-direction §2, спец. 002 §14.10). box-sizing тут content-box навмисно:
     канал має бути рівно --rail-reserve завширшки, а кромка стоїть на його
     зовнішній грані, на межі з циферблатом. */
  .rail::before {
    box-sizing: content-box;
    inset-block: calc(var(--rail-top) * -1) calc(var(--rail-bottom) * -1);
    inset-inline-start: calc(var(--rail-gutter) * -1);
    inset-inline-end: auto;
    inline-size: var(--rail-reserve);
    block-size: auto;
    background: var(--rail-chassis-bg);
    border-inline-end: var(--rail-chassis-edge);
    pointer-events: none;
  }

  .rail__track,
  .rail__fill {
    inline-size: var(--rail-track-width);
    block-size: 100%;
  }

  .rail__fill {
    transform-origin: top center;
    transform: scaleY(var(--rail-progress));
  }

  .rail__step {
    inset-block-start: calc(var(--i) / var(--rail-last, 12) * 100%);
    inset-inline-start: 0;
    transform: translateY(-50%);
  }

  /* Зона тапу/кліку — 44px по вертикалі. Поділка й номер лишаються оптично на
     осі поділки: крок --rail-step центрує себе через translateY(-50%), а
     всередині посилання все вирівняно по центру. Геометрія поділок не
     змінюється (спец. 002 §14.11). */
  .rail__link {
    display: flex;
    align-items: center;
    gap: var(--rail-label-offset);
    min-block-size: var(--rail-tap-min);
  }

  .rail__tick--major {
    inline-size: var(--rail-tick-major);
    block-size: var(--rail-tick-major-width);
    transform-origin: left center;
  }

  .rail__minors {
    display: block;
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: var(--rail-tick-minor);
  }

  .rail__tick--minor {
    display: block;
    position: absolute;
    inset-block-start: calc(var(--m) / 65 * 100%);
    inset-inline-start: 0;
    inline-size: var(--rail-tick-minor);
    block-size: var(--rail-tick-width);
  }

  .rail__num {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--fs-readout-label);
    font-weight: var(--fw-readout);
    line-height: var(--lh-readout);
    letter-spacing: var(--tracking-caps);
    color: var(--text-muted);
    transition: color var(--dur-fast) var(--ease-in);
  }

  /* Підпис виходить за межі шасі, тому носить власну підкладку: без неї він
     лягає просто на секцію і на світлому циферблаті (04, 08, 11) сірий моно
     по кремовому майже зникає. Підкладка того ж кольору, що й шасі, — підпис
     читається як частина корпусу, а не як напис поверх контенту. */
  /* Підпис поділки прибрано зовсім.

     Затиснутий каналом шасі він обрізався на восьми поділках з одинадцяти
     («INT…», «PRO…», «SER…»). Випущений за канал — накривав контент: на
     секції послуг чорна пілюля «SERVICES» лягала просто на рядок «Custom
     WordPress systems». Обидва стани гірші за відсутність.

     Робота, яку він мав робити, вже зроблена: номер на поділці каже, котра
     це секція, а назву секції видно на самому екрані — читач у ній і
     перебуває. Це також мінус одна мова з тих, через які сторінку названо
     важкою. */
  .rail__label { display: none; }


  .rail__link:hover .rail__num { color: var(--text-primary); }

  .rail__link[aria-current="true"] .rail__tick--major,
  .rail__link[data-lamp="on"] .rail__tick--major {
    transform: scaleX(var(--rail-tick-flare));
  }

  .rail__pointer {
    inline-size: var(--rail-pointer-length);
    block-size: var(--rail-pointer-thickness);
    margin-inline-start: 0;
    margin-block-start: calc(var(--rail-pointer-thickness) / -2);
    transform:
      translateY(calc(var(--rail-progress) * 100cqh))
      translateY(calc(var(--rail-kick) * var(--rail-overshoot) * -1));
  }

  .rail__dot {
    inset-block-start: 50%;
    inset-inline-start: 100%;
    margin-block-start: calc(var(--rail-pointer-dot) / -2);
    margin-inline-start: calc(var(--rail-pointer-dot) / -2);
  }
}

/* Від --bp-xl колонка рейки достатньо широка, щоб підпис активної секції стояв
   постійно й не заходив під текст: контент починається за 174px від краю. */
@media (min-width: 90rem) {
}

/* =============================================================================
   Прилад без анімації: стан лишається, рух зникає.
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  .rail__tick,
  .rail__num,
  .rail__label,
  .rail__dot { transition: none; }
}
