@layer motion {
/* ТТ Москвина — motion library (CSS part). Pairs with ttm-motion.js (≈3 KB, no dependencies).
   Every effect animates transform/opacity/background-size only and switches off under prefers-reduced-motion.
   Numbers (M01…) match design-kit/index.html so the owner can keep or drop each one. */



/* M01 Reveal on scroll — content stays in the DOM; only the html.ttm-motion class (set by JS) hides it. */
.ttm-motion [data-reveal] { opacity: 0; transform: translateY(var(--reveal-distance)); }
.ttm-motion [data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}

/* M02 Stagger: children of [data-reveal-stagger] get --i from JS (max 8, then they share the last delay). */
.ttm-motion [data-reveal-stagger] > * { opacity: 0; transform: translateY(24px); }
.ttm-motion [data-reveal-stagger].is-in > * {
  opacity: 1; transform: none;
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
  transition-delay: calc(min(var(--i, 0), 8) * var(--stagger));
}

/* M03 Split headline — words rise one by one (short headlines only, ≤ 8 words). */
[data-split] .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
[data-split] .w > span { display: inline-block; }
.ttm-motion [data-split] .w > span { transform: translateY(105%); }
.ttm-motion [data-split].is-in .w > span {
  transform: none; transition: transform 700ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}

/* M04 Sticker — rotated label that straightens and grows a little on hover (Aardvark). */
.ttm-sticker { display: inline-block; transform: rotate(var(--tilt, -6deg)); transition: transform var(--dur-slow) var(--ease-spring); }
.ttm-sticker:hover, a:hover > .ttm-sticker, a:focus-visible > .ttm-sticker { transform: rotate(0deg) scale(1.06); }
.ttm-sticker--wobble { animation: ttm-wobble 6s var(--ease-standard) infinite; }
@keyframes ttm-wobble { 0%, 100% { transform: rotate(var(--tilt, -6deg)); } 50% { transform: rotate(calc(var(--tilt, -6deg) * -0.5)); } }

/* M05 Float loop — slow up-and-down for 3D renders and shapes (Dellecod / Tilda “sbs” loop). */
.ttm-float { animation: ttm-float var(--float-dur, 6s) ease-in-out infinite; animation-delay: var(--float-delay, 0s); }
@keyframes ttm-float { 0%, 100% { transform: translateY(0) rotate(var(--float-rot, 0deg)); } 50% { transform: translateY(var(--float-y, -10px)) rotate(calc(var(--float-rot, 0deg) * -1)); } }

/* M06 Marquee ribbon — slogan or grades running across a band; JS adds the pause button. */
.ttm-marquee { --gap: 2.5rem; display: flex; overflow: hidden; gap: var(--gap); user-select: none; position: relative; }
.ttm-marquee__track { display: flex; flex: none; gap: var(--gap); min-width: 100%; justify-content: space-around; animation: ttm-marquee var(--marquee-dur, 28s) linear infinite; }
.ttm-marquee:hover .ttm-marquee__track, .ttm-marquee:focus-within .ttm-marquee__track, .ttm-marquee.is-paused .ttm-marquee__track { animation-play-state: paused; }
@keyframes ttm-marquee { to { transform: translateX(calc(-100% - var(--gap))); } }
.ttm-marquee__pause { width: 44px; height: 44px; border-radius: 50%; border: 2px solid currentColor; background: transparent; color: inherit; display: inline-grid; place-items: center; cursor: pointer; margin: .5rem 1rem; }
.ttm-marquee__pause:focus-visible { outline: 3px solid var(--color-focus, #3B308F); outline-offset: 2px; }

/* M07 Pinned steps (“How it works”) — pure CSS sticky; JS marks the active step. */
.ttm-pin { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-7, 3rem); }
.ttm-pin__visual { position: sticky; top: 15vh; height: 70vh; align-self: start; }
.ttm-pin__step { min-height: 60vh; display: flex; flex-direction: column; justify-content: center; opacity: .35; transition: opacity var(--dur-slow) var(--ease-standard); }
.ttm-pin__step.is-active { opacity: 1; }
@media (max-width: 899px) { .ttm-pin { grid-template-columns: 1fr; } .ttm-pin__visual { position: relative; top: 0; height: auto; } .ttm-pin__step { min-height: 0; opacity: 1; padding-block: 1.5rem; } }

/* M08 Pill button with arrow cap (Aardvark): the cap slides right and the arrow turns on hover. */
.ttm-btn { display: inline-flex; align-items: center; gap: .75rem; min-height: 48px; padding: .375rem .375rem .375rem 1.5rem; border-radius: 999px;
  background: var(--color-primary, #FF008C); color: var(--color-on-primary, #080909); font: 800 1rem/1 var(--font-text, Manrope, sans-serif);
  text-decoration: none; border: 0; cursor: pointer; transition: background-color var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard); }
.ttm-btn__cap { width: 36px; height: 36px; border-radius: 50%; background: var(--ttm-black, #080909); color: #fff; display: grid; place-items: center; flex: none;
  transition: transform var(--dur-slow) var(--ease-spring); }
.ttm-btn__cap svg { width: 18px; height: 18px; transition: transform var(--dur-slow) var(--ease-spring); }
.ttm-btn:hover { background: var(--color-primary-hover, #3B308F); color: var(--color-on-primary-hover, #FFFFFF); }
.ttm-btn:hover .ttm-btn__cap { transform: translateX(4px); }
.ttm-btn:hover .ttm-btn__cap svg { transform: rotate(-45deg); }
.ttm-btn:active { transform: scale(.97); }
.ttm-btn:focus-visible { outline: 3px solid var(--color-focus, #3B308F); outline-offset: 2px; }

/* M09 Card hover lift — two options: a) lift only; b) lift + hard ink shadow (sticker feel). */
.ttm-lift { transition: transform var(--dur-base) var(--ease-standard), box-shadow var(--dur-base) var(--ease-standard); }
.ttm-lift:hover, .ttm-lift:focus-within { transform: translateY(-4px); }
.ttm-lift--ink:hover, .ttm-lift--ink:focus-within { transform: translate(-3px, -3px); box-shadow: 6px 6px 0 var(--ttm-black, #080909); }

/* M10 Rhombus loader — replaces spinners (search, filters, form submit). */
.ttm-loader { width: 28px; height: 28px; display: inline-block; }
.ttm-loader::before { content: ""; display: block; width: 100%; height: 100%; background: currentColor; clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); animation: ttm-pulse 1.2s ease-in-out infinite; }
@keyframes ttm-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(.7) rotate(90deg); } }

/* M11 Logo intro — see brand/logo/tt-moskvina_logo-animation.html (classes .ttm-logo, .is-intro, .is-loading). */

/* M12 Marker highlight — the magenta/yellow marker sweeps in behind key words when revealed.
   (A solid colour: the gradient syntax is only a way to size the band.) */
.ttm-mark { background: linear-gradient(var(--mark, #FD48F2), var(--mark, #FD48F2)) no-repeat 0 85% / 100% .55em; padding-inline: .08em; }
.ttm-motion .ttm-mark[data-reveal], .ttm-motion [data-reveal] .ttm-mark { background-size: 0% .55em; }
.ttm-motion .ttm-mark[data-reveal].is-in, .ttm-motion [data-reveal].is-in .ttm-mark { background-size: 100% .55em; transition: background-size 700ms var(--ease-out) 250ms; }

/* M13 Draw-in doodles — underline, circle and arrow strokes draw themselves (SVG with pathLength="1"). */
.ttm-draw path, .ttm-draw circle { stroke-dasharray: 1; }
.ttm-motion .ttm-draw path, .ttm-motion .ttm-draw circle { stroke-dashoffset: 1; }
.ttm-motion .ttm-draw.is-in path, .ttm-motion .ttm-draw.is-in circle { stroke-dashoffset: 0; transition: stroke-dashoffset 900ms var(--ease-out) 200ms; }

/* M14 Notebook margin line draws down the hero on load (~600 ms). */
.ttm-margin { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--ttm-hotpink, #FF008C); transform-origin: top; }
.ttm-motion .ttm-margin { animation: ttm-grow-y 600ms var(--ease-out) both 200ms; }
@keyframes ttm-grow-y { from { transform: scaleY(0); } }

/* M15 Colour-field switch — the page background eases to each section's colour as it enters (Aardvark storytelling). */
.ttm-fields { transition: background-color 600ms var(--ease-standard); }

/* M17 Accordion — smooth open for <details> where supported (FAQ, grade sections). */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  details.ttm-acc::details-content { block-size: 0; overflow: clip; transition: block-size var(--dur-slow) var(--ease-standard), content-visibility var(--dur-slow) allow-discrete; }
  details.ttm-acc[open]::details-content { block-size: auto; }
}
details.ttm-acc summary .ttm-acc__icon { transition: transform var(--dur-base) var(--ease-standard); }
details.ttm-acc[open] summary .ttm-acc__icon { transform: rotate(45deg); }

/* Reduced motion: everything visible, nothing moves. */
@media (prefers-reduced-motion: reduce) {
  .ttm-motion [data-reveal], .ttm-motion [data-reveal-stagger] > *, .ttm-motion [data-split] .w > span { opacity: 1 !important; transform: none !important; transition: none !important; }
  .ttm-sticker, .ttm-sticker--wobble, .ttm-float, .ttm-marquee__track, .ttm-loader::before, .ttm-margin, .ttm-btn__cap, .ttm-btn__cap svg { animation: none !important; transition: none !important; }
  .ttm-motion .ttm-mark { background-size: 100% .55em !important; transition: none !important; }
  .ttm-motion .ttm-draw path, .ttm-motion .ttm-draw circle { stroke-dashoffset: 0 !important; transition: none !important; }
  .ttm-lift:hover, .ttm-lift:focus-within { transform: none; }
  .ttm-marquee { flex-wrap: wrap; }
}

/* ===== v2 — Dellecod / West Garden motion (scanned 15 Oct 2026) ===== */

/* M19 Slow spin — 3D renders turn very slowly (Dellecod: 20–50 s, linear, infinite); --breathe adds a gentle scale. */
.ttm-spin { animation: ttm-spin var(--spin-dur, 36s) linear infinite; }
.ttm-spin--rev { animation-direction: reverse; }
.ttm-spin--breathe { animation-name: ttm-spin-breathe; }
@keyframes ttm-spin { to { transform: rotate(360deg); } }
@keyframes ttm-spin-breathe { 0% { transform: rotate(0) scale(1); } 50% { transform: rotate(180deg) scale(var(--breathe, .86)); } 100% { transform: rotate(360deg) scale(1); } }

/* M20 Drop-in — objects fall into place with a bounce when their section appears (Dellecod “bounceFin”). */
.ttm-motion [data-drop] { opacity: 0; }
.ttm-motion [data-drop].is-in { opacity: 1; animation: ttm-drop var(--drop-dur, 1.6s) linear both; animation-delay: var(--drop-delay, 0s); }
@keyframes ttm-drop {
  0% { transform: translateY(var(--drop-from, -60vh)) rotate(var(--drop-rot, -200deg)); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
  52% { transform: translateY(0) rotate(0); animation-timing-function: cubic-bezier(0, .55, .45, 1); }
  68% { transform: translateY(-9%) rotate(4deg); animation-timing-function: cubic-bezier(.55, 0, 1, .45); }
  80% { transform: translateY(0) rotate(0); animation-timing-function: cubic-bezier(0, .55, .45, 1); }
  90% { transform: translateY(-2.5%); }
  100% { transform: none; }
}

/* M21 Pendulum — labels and hashtag pills swing from their top edge (Dellecod: ±16°, 3 s). */
.ttm-swing { transform-origin: 50% -40%; animation: ttm-swing var(--swing-dur, 3.2s) ease-in-out infinite alternate; }
@keyframes ttm-swing { from { transform: rotate(calc(var(--tilt, 0deg) - var(--swing, 7deg))); } to { transform: rotate(calc(var(--tilt, 0deg) + var(--swing, 7deg))); } }

/* M22 Slide-in from the side (Tilda fadeinleft / fadeinright, 100 px). */
.ttm-motion [data-reveal="left"] { transform: translateX(-100px); }
.ttm-motion [data-reveal="right"] { transform: translateX(100px); }
.ttm-motion [data-reveal="left"].is-in, .ttm-motion [data-reveal="right"].is-in { transform: none; transition-duration: 900ms; }

/* M23 Zoom-in cards (West Garden). */
.ttm-motion [data-reveal="zoom"] { transform: scale(.9); }
.ttm-motion [data-reveal="zoom"].is-in { transform: none; }

/* M24 Depth blur — copies of objects in the far background or close foreground (Dellecod blurred renders). */
.ttm-depth-far { filter: blur(var(--blur, 7px)); opacity: .75; }
.ttm-depth-near { filter: blur(var(--blur, 10px)); }

/* M25 Pointer parallax — layers drift a few pixels with the mouse (desktop only, set by JS on [data-depth]). */
[data-depth] { transition: translate 600ms cubic-bezier(.2, 0, 0, 1); }

/* M26 Particles — slow rising glow points for dark heroes (West Garden journal). */
.ttm-particles { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.ttm-particles i { position: absolute; bottom: -10px; width: var(--s, 6px); height: var(--s, 6px); background: var(--pc, #FFD24A); clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  opacity: .0; animation: ttm-rise var(--d, 14s) linear infinite; animation-delay: var(--delay, 0s); box-shadow: 0 0 12px var(--pc, #FFD24A); }
@keyframes ttm-rise { 10% { opacity: var(--o, .8); } 90% { opacity: var(--o, .8); } to { transform: translate(var(--dx, 30px), calc(-1 * var(--h, 420px))) rotate(180deg); opacity: 0; } }

/* Off-screen sections and the user's “stop animation” switch pause every loop (WCAG 2.2.2). */
.ttm-motion [data-anim="paused"] *, .ttm-still *, .ttm-still *::before { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
  .ttm-spin, .ttm-swing, .ttm-particles i, .ttm-motion [data-drop] { animation: none !important; opacity: 1 !important; }
  .ttm-particles { display: none; }
  .ttm-motion [data-reveal] { transform: none !important; }
  [data-depth] { translate: none !important; }
}

}
