feat(landing): штамп, лента недели, состояния кнопки, липкая CTA

Оттиск штампа при загрузке и при успехе формы, заполнение ленты
недели по IntersectionObserver, мигающие точки при отправке.
Только CSS и transform/opacity; анимации включает скрипт в head,
поэтому без JS и при prefers-reduced-motion всё сразу в финале.
Липкая CTA на мобиле: «Заказать кофе», прячется у формы, при фокусе
в ней и при открытой клавиатуре. Ритм секций плотнее.
This commit is contained in:
2026-10-17 16:56:52 +03:00
parent dc70ebccd8
commit d8d67c036f
5 changed files with 209 additions and 4 deletions
+105 -2
View File
@@ -140,11 +140,11 @@
max-width: var(--container-page);
}
.section-y {
padding-block: 72px;
padding-block: 48px;
}
@media (min-width: 1024px) {
.section-y {
padding-block: 128px;
padding-block: 80px;
}
}
@@ -483,3 +483,106 @@
}
}
}
/* Моушн (DESIGN.md → «Моушн»). Без JS и при reduced-motion — сразу финальное состояние. */
@keyframes stamp-in {
from {
opacity: 0;
transform: rotate(calc(var(--stamp-rotate, -6deg) - 3deg)) scale(1.18);
}
to {
opacity: 0.92;
transform: rotate(var(--stamp-rotate, -6deg)) scale(1);
}
}
@keyframes busy-dot {
0%,
100% {
opacity: 0.3;
}
33% {
opacity: 1;
}
}
@keyframes fade-in {
from {
opacity: 0;
}
}
@media (prefers-reduced-motion: no-preference) {
[data-motion] .stamp[data-stamp='load'] {
animation: stamp-in 380ms var(--ease-out-expo) 250ms both;
}
.stamp[data-stamp='event'] {
animation: stamp-in 380ms var(--ease-out-expo) 80ms both;
}
.busy-dots i {
animation: busy-dot 480ms steps(1) infinite;
}
.busy-dots i:nth-child(2) {
animation-delay: 160ms;
}
.busy-dots i:nth-child(3) {
animation-delay: 320ms;
}
[data-lead-notice] > * {
animation: fade-in 160ms ease-out;
}
/* лента недели */
[data-motion] .week .week-rule {
transition: transform 600ms var(--ease-out-quart);
}
[data-motion] .week .week-mark {
transition: transform 320ms var(--ease-out-quart) 300ms;
}
[data-motion] .week .week-note {
transition:
opacity 320ms var(--ease-out-quart) 300ms,
transform 320ms var(--ease-out-quart) 300ms;
}
[data-motion] .week .week-day:nth-child(5) .week-mark,
[data-motion] .week .week-day:nth-child(5) .week-note {
transition-delay: 480ms;
}
[data-motion] .week .week-bracket-line {
transition: transform 500ms var(--ease-out-quart) 680ms;
}
[data-motion] .week .week-bracket-note {
transition: opacity 240ms ease-out 1000ms;
}
[data-motion] .week:not([data-inview]) .week-rule,
[data-motion] .week:not([data-inview]) .week-mark {
transform: scaleX(0);
}
[data-motion] .week:not([data-inview]) .week-note {
opacity: 0;
transform: translateY(6px);
}
[data-motion] .week:not([data-inview]) .week-bracket-line {
transform: scaleY(0);
}
[data-motion] .week:not([data-inview]) .week-bracket-note {
opacity: 0;
}
@media (min-width: 1024px) {
[data-motion] .week:not([data-inview]) .week-bracket-line {
transform: scaleX(0);
}
}
/* липкая CTA */
.sticky-cta {
transition: transform 180ms var(--ease-in-quart);
}
.sticky-cta[data-visible] {
transition: transform 240ms var(--ease-out-quart);
}
}
.sticky-cta:not([data-visible]) {
transform: translateY(100%);
visibility: hidden;
transition-property: transform, visibility;
}