/* The document is readable before motion.js runs. Only JS opts into motion. */
:root {
  --motion-scene: 900ms;
  --motion-factor: 1;
}

html [data-motion],
html .motion-leave,
html .motion-arrive,
html .hero-shell::before,
html .hero::after,
html .contact::after {
  animation: none;
}

/* Сборка после загрузки (MOTION-CONTRACT-2 §A1). До запуска motion.js первый экран скрыт не дольше 1,1 с:
   если скрипт не пришёл, всё входит само; скрипт снимает ожидание в том же кадре, где запускает сборку. */
html:not(.motion-enabled) :is([data-motion], .site-header .ad-brand, .site-header .header-nav > a, .attention-actions > *, .attention-options) {
  animation: motion-enter var(--motion-hero) var(--motion-enter) 1100ms 1 backwards;
}
html.motion-wait :is(.motion-part, .site-header .ad-brand, .site-header .header-nav > a, .attention-actions > *, .attention-options) {
  opacity: 0;
}
.motion-word { display: inline-block; }

html.motion-enabled .hero-shell::before {
  animation: motion-paper-grain 1200ms steps(1, end) infinite;
}
html.motion-enabled .hero::after {
  animation: fon-svet 20s var(--motion-breath) infinite alternate;
}
html.motion-enabled .contact::after {
  animation: fon-dyhanie 26s var(--motion-breath) infinite alternate;
}
html.motion-enabled .draft-content.motion-leave {
  animation: motion-step-out calc(var(--motion-small) * var(--motion-factor)) var(--motion-exit) both;
}
@keyframes motion-step-out {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-6px); }
}

/* Remove non-compositor transitions from the original interaction layer. */
html :is(.brand, .header-nav a, .hero-bottom a, .footer a, .telegram,
  .input-row, .message-form textarea, .primary, .copy-button, .examples button,
  .price-link, summary, .attention-primary) {
  transition-property: transform, opacity, clip-path;
}

/* G3: arrow, press and magnetic displacement share a single transform. */
html.motion-enabled :is(.attention-primary, .primary) {
  transform: translate(var(--magnet-x, 0px), var(--magnet-y, 0px))
    scale(var(--press-scale, 1)) !important;
  transition: transform calc(var(--motion-medium) * var(--motion-factor)) var(--motion-reveal);
}
html.motion-enabled :is(.attention-primary, .primary):not(:disabled):not([aria-disabled="true"]):active {
  --press-scale: .985;
  transition-duration: var(--motion-press);
}
html .attention-primary > span,
html .primary .arrow {
  display: inline-block;
  transition: translate calc(var(--motion-small) * var(--motion-factor)) var(--motion-response);
}
@media (hover: hover) {
  html.motion-enabled .attention-primary:hover > span,
  html.motion-enabled .primary:not(:disabled):not([aria-disabled="true"]):hover .arrow {
    translate: 2px -2px;
  }
}
@media (hover: none) {
  /* This hover colour was previously unconditional in attention.css. */
  html .attention-primary:hover { background: #a14120; }
}

/* G4: a lamp reflection, never an interactive surface. */
.motion-glow {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle 320px at var(--mx, 50%) var(--my, 50%),
    rgb(242 235 217 / .085), rgb(242 235 217 / 0) 75%);
}
@media (pointer: fine) and (min-width: 761px) {
  html.motion-enabled .motion-glow {
    display: block;
    transition: opacity var(--motion-medium) var(--motion-response);
  }
  html.motion-enabled :is(.browser, .contact).is-lit > .motion-glow { opacity: 1; }
}

/* G5: grid is the deliberate, contract-defined layout-animation exception. */
html .motion-details > .motion-answer {
  display: grid;
  grid-template-rows: 0fr;
  height: auto !important;
  overflow: hidden;
  transition: none;
}
html .motion-detail-body { min-height: 0; overflow: hidden; }
html .motion-details[data-grid-open="true"] > .motion-answer { grid-template-rows: 1fr; }
html.motion-enabled .motion-details > .motion-answer {
  transition: grid-template-rows calc(var(--motion-medium) * var(--motion-factor)) var(--motion-response);
}
html .motion-details > summary::after,
html .attention-options.motion-details[open] > summary::after {
  content: '+';
  transform: rotate(0);
  transition: transform calc(var(--motion-small) * var(--motion-factor)) var(--motion-response);
}
html .motion-details[data-grid-open="true"] > summary::after { transform: rotate(45deg); }

/* G6: opacity layers leave header geometry and document position intact. */
.site-header::before,
.site-header::after {
  content: '';
  position: absolute;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--motion-medium) var(--motion-response);
}
.site-header::before { inset: 0; z-index: -1; background: var(--paper); }
.site-header::after { left: 0; right: 0; bottom: -1px; height: 1px; background: var(--pencil); }
.site-header.is-scrolled::before { opacity: .55; }
.site-header.is-scrolled::after { opacity: .4; }

/* Signature feedback occupies space from the first CSS paint. */
.draft-caption { position: relative; padding-bottom: 22px; }
[data-motion-checks] {
  position: absolute;
  bottom: 0;
  left: 0;
  display: flex;
  gap: 12px;
  align-items: center;
  color: var(--brick);
  white-space: nowrap;
}
[data-motion-checks] > span { display: inline-block; }
.motion-title-line { display: inline-block; }

/* G2 and the lower-page signature: connect the process and layer the work. */
.step::after {
  content: '';
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--pencil);
  transform-origin: left center;
  pointer-events: none;
}
html.motion-enabled .step::after {
  transform: scaleX(0);
  transition: transform calc(var(--motion-scene) * var(--motion-factor)) var(--motion-enter);
}
html.motion-enabled .is-in .step::after { transform: scaleX(1); }
html.motion-enabled .step:nth-child(2)::after { transition-delay: 60ms; }
html.motion-enabled .step:nth-child(3)::after { transition-delay: 120ms; }

@media (min-width: 761px) {
  html.motion-enabled .work-phone {
    transform: translate(10px, 26px) scale(.96);
    transform-origin: bottom right;
    transition: transform var(--motion-scene) var(--motion-enter);
  }
  html.motion-enabled .is-in .work-phone { transform: translate(0, 0) scale(1); }
}
@media (hover: hover) and (pointer: fine) and (min-width: 761px) {
  html.motion-enabled .work-shots {
    transform: perspective(1000px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
    transition: transform var(--motion-medium) var(--motion-response);
  }
}
@supports (animation-timeline: view()) {
  html.motion-enabled .step::after {
    animation: motion-process-line var(--motion-scene) linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 40%;
    transition: none;
  }
  @media (min-width: 761px) {
    html.motion-enabled .work-phone {
      animation: motion-work-phone var(--motion-scene) linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 45%;
      transition: none;
    }
  }
}
@keyframes motion-process-line { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes motion-work-phone {
  from { transform: translate(10px, 26px) scale(.96); }
  to { transform: translate(0, 0) scale(1); }
}

/* The existing pricing note stays readable even before an interaction. */
.price-row::after {
  content: '';
  position: absolute;
  top: 22px;
  bottom: 22px;
  left: -10px;
  width: 2px;
  background: var(--brick);
  pointer-events: none;
  transform: scaleY(0);
  transform-origin: center;
}
html.motion-enabled .price-row::after {
  transition: transform var(--motion-medium) var(--motion-response);
}
.price-row:focus-within::after { transform: scaleY(1); }
html.motion-enabled .price-list:focus-within + .ladder-note {
  animation: motion-price-note var(--motion-large) var(--motion-enter) both;
}
@media (hover: hover) {
  .price-row:hover::after { transform: scaleY(1); }
  html.motion-enabled .price-list:has(.price-row:hover) + .ladder-note {
    animation: motion-price-note var(--motion-large) var(--motion-enter) both;
  }
}
@keyframes motion-price-note {
  from { clip-path: inset(0 100% 0 0); opacity: .5; }
  to { clip-path: inset(0); opacity: 1; }
}

@media (max-width: 760px) {
  :root { --motion-factor: .7; }
  [data-motion-checks] { gap: 9px; }
  .draft-caption { padding-bottom: 20px; }
}

/* G7/G8: explicit opt-out also stops inherited pseudo-element motion. */
html.motion-paused *,
html.motion-paused *::before,
html.motion-paused *::after { animation-play-state: paused !important; }
html.no-anim *,
html.no-anim *::before,
html.no-anim *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}
html.no-anim :is([data-motion], .motion-title-line, .draft-content, .draft-brand,
  .draft-nav-note, .draft-kicker, .draft-description, .draft-cta, .draft-services li,
  .photo-label, .photo-outline, #draft-address, [data-motion-checks], [data-motion-checks] > span, .ladder-note,
  .motion-part, .motion-word, .title-line, h1 em, .site-header .ad-brand, .site-header .header-nav > a,
  .attention-actions, .attention-actions > *, .attention-options, .hero-author img) {
  opacity: 1 !important;
  clip-path: none !important;
}
html.no-anim :is(.motion-word, .title-line, h1 em, .attention-actions, .hero-author img, .build-cursor) {
  transform: none !important;
  translate: none !important;
}
html.no-anim .build-layer { display: none !important; }
html.no-anim .hero::before { animation: none !important; opacity: 0 !important; }
html.no-anim :is(.attention-primary, .attention-primary > span, .primary, .primary .arrow,
  .copy-button, .brand, .header-nav a, .hero-bottom a, .footer a, .telegram,
  .telegram-arrow, .input-row, .message-form textarea, .examples button,
  .price-link, .price-arrow, .work-phone, .work-shots, summary),
html.no-anim .step::after { transform: none !important; }
html.no-anim .motion-glow { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  html *, html *::before, html *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
  html :is([data-motion], .motion-title-line, .draft-content, .draft-brand,
    .draft-nav-note, .draft-kicker, .draft-description, .draft-cta, .draft-services li,
    .photo-label, .photo-outline, #draft-address, [data-motion-checks], [data-motion-checks] > span, .ladder-note,
    .motion-part, .motion-word, .title-line, h1 em, .site-header .ad-brand, .site-header .header-nav > a,
    .attention-actions, .attention-actions > *, .attention-options, .hero-author img) {
    opacity: 1 !important;
    clip-path: none !important;
  }
  html :is(.motion-word, .title-line, h1 em, .attention-actions, .hero-author img, .build-cursor) {
    transform: none !important;
    translate: none !important;
  }
  html .build-layer { display: none !important; }
  html .hero::before { animation: none !important; opacity: 0 !important; }
  html h1 em { background-size: 100% .05em !important; }
  html :is(.attention-primary, .attention-primary > span, .primary, .primary .arrow,
    .copy-button, .brand, .header-nav a, .hero-bottom a, .footer a, .telegram,
    .telegram-arrow, .input-row, .message-form textarea, .examples button,
    .price-link, .price-arrow, .work-phone, .work-shots, summary),
  html .step::after { transform: none !important; }
  html .motion-glow { display: none !important; }
}

/* Добавка 26.09 (Fable): карандашная линия под курсивной фразой заголовка рисуется слева направо после входа заголовка. */
h1 em {
  background-image: linear-gradient(var(--brick, #b5452a), var(--brick, #b5452a));
  background-repeat: no-repeat;
  background-position: 0 calc(100% - .04em);
  background-size: 100% .05em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
h1.motion-assembling em { background-size: 0% .05em; }
@media (prefers-reduced-motion: no-preference) {
  html.motion-enabled h1.motion-inked em { animation: motion-underline 720ms cubic-bezier(.2, .7, .2, 1) both; }
}
html.no-anim h1 em { animation: none !important; background-size: 100% .05em !important; }
@keyframes motion-underline {
  from { background-size: 0% .05em; }
  to { background-size: 100% .05em; }
}

/* B. Каркас и курсор сборщика в макете (MOTION-CONTRACT-2 §B). Слой лежит рядом с #draft, вне наблюдателя рендера,
   не участвует в раскладке и не меняет текст. */
.build-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  color: rgb(234 225 200 / .42);
}
#draft[data-theme="dental"] ~ .build-layer { color: rgb(20 18 16 / .35); }
.build-frame {
  position: absolute;
  box-sizing: border-box;
  border: 1px dashed currentColor;
  opacity: 0;
}
.build-cursor {
  position: absolute;
  top: 0;
  left: 0;
  width: 12px;
  height: 12px;
  opacity: 0;
}
.build-cursor > i {
  display: block;
  width: 12px;
  height: 12px;
  background: var(--brick, #b5452a);
  clip-path: polygon(0 0, 100% 46%, 56% 56%, 46% 100%);
  filter: drop-shadow(0 1px 0 rgb(0 0 0 / .25));
}
#draft[data-theme="dental"] ~ .build-layer .build-cursor > i { background: var(--ink, #141210); filter: drop-shadow(0 1px 0 rgb(255 255 255 / .35)); }

/* C. Дыхание после сборки (MOTION-CONTRACT-2 §C): всё под html.motion-alive, ставится на паузу в скрытой вкладке
   и когда первый экран ушёл из вида; без reduce/no-anim ничего из этого не запускается. */
.hero::before {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
  left: 20%;
  top: -30%;
  width: 60vw;
  height: 60vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(234 225 200 / .5) 0%, rgb(234 225 200 / 0) 62%);
  opacity: 0;
  transition: opacity 1200ms var(--motion-breath);
}
.draft-cta { position: relative; overflow: hidden; }
.draft-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgb(255 255 255 / .28) 50%, transparent 62%);
  transform: translateX(-130%);
}
/* Дышит подложка за макетом, а не сам макет: кнопки и текст в панели остаются неподвижной целью. */
html.motion-alive .stage::before { animation: motion-float 7s var(--motion-breath) infinite alternate; }
html.motion-alive .hero::before { opacity: 1; animation: motion-light-drift 14s var(--motion-breath) infinite alternate; }
html.motion-alive .attention-primary > span { animation: motion-arrow-step 8s var(--motion-response) infinite; }
html.motion-alive .hero-bottom .down { animation: motion-bob 2.4s var(--motion-breath) infinite; }
html.motion-alive .draft-cta::before { animation: motion-sheen 9s linear infinite; }
@property --motion-march { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@supports ((mask: radial-gradient(#000, transparent)) or (-webkit-mask: radial-gradient(#000, transparent))) {
  html.motion-alive .photo-outline {
    border-color: transparent;
    background: repeating-conic-gradient(from var(--motion-march), #eae1c846 0 5deg, transparent 5deg 12deg);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1px));
    animation: motion-march 4s linear infinite;
  }
}
html.motion-hero-out :is(.photo-outline, .attention-primary > span, .hero-bottom .down, .build-cursor, .build-cursor > i),
html.motion-hero-out :is(.hero, .draft-cta, .stage)::before { animation-play-state: paused; }
@keyframes motion-float { from { translate: 0 -3px; } to { translate: 0 3px; } }
@keyframes motion-light-drift { from { transform: translate(-4%, -2%); } to { transform: translate(4%, 3%); } }
@keyframes motion-arrow-step { 0%, 5%, 100% { transform: translate(0, 0); } 2.5% { transform: translate(2px, -2px); } }
@keyframes motion-bob { 0%, 100% { transform: translateY(-1px); } 50% { transform: translateY(3px); } }
@keyframes motion-sheen { 0% { transform: translateX(-130%); } 7% { transform: translateX(130%); } 100% { transform: translateX(130%); } }
@keyframes motion-march { to { --motion-march: 12deg; } }
