/* ==========================================================================
   FAKTURA KIT — craft + motion primitives.
   Палитра, типографика и композиция задаются в style.css КАЖДОГО сайта.
   Здесь только то, что одинаково правильно везде: токены мотиона,
   стартовые состояния, reduced-motion, focus, tap-targets.
   Правила — ANTI-AI-SLOP.md §3, §6.
   ========================================================================== */

:root {
  /* микро-слой: миллисекунды */
  --d-fast: 120ms;
  --d-default: 200ms;
  --d-slow: 320ms;
  --d-reveal: 600ms;

  --ease-out: cubic-bezier(0, 0, 0.2, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-reveal: cubic-bezier(0.16, 1, 0.3, 1);

  --nav-h: 64px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}
body {
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none; /* никакого синтетического жира на кириллице */
}

img,
video {
  display: block;
  max-width: 100%;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

/* ---- focus: видимый, но не на мышиный клик ---- */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

/* ---- tap ---- */
a,
button,
[role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* ---- якоря под липкий хедер ---- */
[id] {
  scroll-margin-top: calc(var(--nav-h) + 16px);
}

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

/* ==========================================================================
   1. МАСКА-REVEAL  (замена opanity+translateY — ANTI-AI-SLOP §2.6)
   Стартовое состояние под .js, чтобы без JS контент просто был виден.
   ========================================================================== */

[data-reveal] {
  display: block;
  overflow: clip; /* clip, не hidden: не создаёт scroll-контейнер */
}
.js [data-reveal] > img,
.js [data-reveal] > video,
.js [data-reveal] > picture {
  clip-path: inset(0 0 100% 0);
}
[data-reveal="right"] {
  --reveal-from: inset(0 100% 0 0);
}
.js [data-reveal="right"] > img {
  clip-path: inset(0 100% 0 0);
}

/* внутренняя рамка для параллакса/зума */
.frame {
  position: relative;
  overflow: clip;
}
.frame > img {
  position: absolute;
  inset: -8% 0;
  width: 100%;
  height: 116%;
  object-fit: cover;
}

/* ==========================================================================
   2. SPLIT-LINES — маски строк ставит плагин, класс нужен только для CSS
   ========================================================================== */
.line-mask {
  overflow: clip;
  padding-bottom: 0.06em; /* клиренс под выносные у ц щ р д */
}

/* ==========================================================================
   3. PIN-СЦЕНА с подменой контента
   ========================================================================== */
[data-pin-scene] .scene__media {
  position: relative;
  overflow: clip;
}
[data-pin-scene] .scene__media > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
[data-pin-scene] .scene__media > img:first-child {
  position: relative;
}
[data-pin-scene] .scene__panel + .scene__panel {
  position: absolute;
  inset: 0;
}
[data-pin-scene] .scene__panels {
  position: relative;
}

/* ==========================================================================
   4. ГОРИЗОНТАЛЬНЫЙ ТРЕК
   ========================================================================== */
[data-htrack] {
  overflow: clip;
}
[data-htrack-inner] {
  display: flex;
  width: max-content;
  will-change: transform;
}

/* ==========================================================================
   5. MARQUEE (максимум один на страницу)
   ========================================================================== */
[data-marquee] {
  overflow: clip;
  white-space: nowrap;
}
[data-marquee-track] {
  display: inline-flex;
  will-change: transform;
}

/* ==========================================================================
   6. DRAG-REVEAL «до/после», «фасад/наповнення»
   ========================================================================== */
.cmp {
  position: relative;
  overflow: clip;
  touch-action: pan-y; /* вертикальный скролл страницы не крадём */
  cursor: ew-resize;
  user-select: none;
}
.cmp > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cmp__top {
  position: absolute;
  inset: 0;
  clip-path: inset(0 50% 0 0);
}
.cmp__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  background: #fff;
  pointer-events: none;
}
.cmp__handle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  translate: -50% -50%;
  border: 2px solid #fff;
  border-radius: 50%;
}
.cmp__cap {
  position: absolute;
  bottom: 12px;
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #fff;
  mix-blend-mode: difference;
}

/* ==========================================================================
   6b. SWATCH — сцена с наложенными кадрами, верхний открывается шторкой
   ========================================================================== */
[data-sw-stage] {
  position: relative;
  overflow: clip;
}
[data-sw-img] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
[data-sw-img]:first-child {
  position: relative;
}
[data-sw-btn] {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}
[data-sw-btn] i {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--sw);
  flex: 0 0 auto;
  transition: box-shadow var(--d-fast) var(--ease-out);
}
[data-sw-btn][aria-pressed="true"] i {
  box-shadow: 0 0 0 2px currentColor;
}

/* ==========================================================================
   6c. STICKY-STACK
   ========================================================================== */
[data-stack-card] {
  position: sticky;
  top: calc(var(--nav-h) + 24px);
  will-change: transform;
}

/* ==========================================================================
   6d. HOVER-LIST — превью за курсором (только мышь)
   ========================================================================== */
[data-hoverlist] {
  position: relative;
}
[data-hl-preview] {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 4;
  width: clamp(200px, 20vw, 300px);
  aspect-ratio: 4 / 5;
  overflow: clip;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  translate: -50% -50%;
  display: none;
}
[data-hl-preview] img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@media (hover: hover) and (pointer: fine) {
  [data-hl-preview] {
    display: block;
  }
  [data-hoverlist].is-hover [data-hl-img] {
    opacity: 0.28;
    transition: opacity var(--d-default) var(--ease-out);
  }
  [data-hoverlist].is-hover [data-hl-img].is-on {
    opacity: 1;
  }
}

/* ==========================================================================
   7. КУРСОР-ПУЗЫРЬ — только мышь, только тонкий указатель
   ========================================================================== */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  pointer-events: none;
  translate: -50% -50%;
  clip-path: inset(50% round 999px); /* схлопнут в покое — приём Studio X */
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0;
}
@media (hover: hover) and (pointer: fine) {
  .cursor {
    opacity: 1;
  }
}

/* ==========================================================================
   8. REDUCED MOTION — критерий: весь контент виден, ничего не залипло
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .js [data-reveal] > img,
  .js [data-reveal] > video,
  .js [data-reveal] > picture {
    clip-path: none !important;
  }
  .frame > img {
    position: relative;
    inset: auto;
    height: auto;
  }
  .cursor {
    display: none;
  }
  .cmp {
    cursor: default;
  }
}
