/* Motion on the marketing pages (js/landing-motion.js, 2026-10-18).
   Everything is under html.rd-motion, which a head script sets only without
   reduced motion and removes if the module never runs. One easing family:
   --rv-ease (a long, soft out) for things arriving, quicker for small UI. */

:root {
  --rv-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --rv-ease-soft: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ── Hero: CSS only, so it starts with the first paint ─────────────────── */
@keyframes rv-rise {
  from { opacity: 0; transform: translateY(26px); }
  to { opacity: 1; transform: none; }
}
@keyframes rv-float-in {
  from { opacity: 0; transform: translateY(46px) scale(0.94) rotate(var(--rv-rot, 0deg)); }
  to { opacity: 1; transform: none; }
}
@keyframes rv-sky {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes rv-hill {
  from { transform: translateY(60px); }
  to { transform: none; }
}
html.rd-motion .rd-hero-title { animation: rv-rise 1s var(--rv-ease) both; }
html.rd-motion .rd-hero .rd-lede { animation: rv-rise 1s var(--rv-ease) 0.12s both; }
html.rd-motion .rd-hero-actions { animation: rv-rise 1s var(--rv-ease) 0.22s both; }
html.rd-motion .rd-hero-visual > .rd-tiles { animation: rv-sky 1.2s ease 0.5s both; }
/* Cards arrive with transform and keep bobbing with rd-float (translate). */
html.rd-motion .rd-hv-card { animation: rv-float-in 1.2s var(--rv-ease) both, rd-float 6s ease-in-out infinite; animation-delay: 0.2s, 0s; }
html.rd-motion .rd-hv-focus { --rv-rot: -2deg; animation-delay: 0.34s, -2s; }
html.rd-motion .rd-hv-reel { --rv-rot: 2deg; animation-delay: 0.48s, -4s; }
html.rd-motion .rd-scene .rd-sky,
html.rd-motion .rd-scene .rd-sun { animation: rv-sky 1.4s ease both; }
html.rd-motion .rd-scene .rd-hills.is-front { animation: rv-hill 1.3s var(--rv-ease) 0.05s both; }
html.rd-motion .rd-scene .rd-hills.is-back { animation: rv-hill 1.5s var(--rv-ease) 0.1s both; }
html.rd-motion .rd-scene .rd-range { animation: rv-hill 1.7s var(--rv-ease) 0.12s both; }

/* The main landing's hero (chat.html): the film and the copy rise in. */
html.rd-motion .duo-hero .duo-film { animation: rv-rise 1s var(--rv-ease) 0.05s both; }
html.rd-motion .duo-hero .duo-hero-copy { animation: rv-rise 1s var(--rv-ease) 0.18s both; }
html.rd-motion :is(.duo-feat-copy, .duo-art, .duo-ways > h2, .duo-proof > h2, .duo-close-inner):not(.is-in) { opacity: 0; transform: translateY(26px); }
html.rd-motion :is(.duo-feat-copy, .duo-art, .duo-ways > h2, .duo-proof > h2, .duo-close-inner) { transition: opacity 0.7s var(--rv-ease-soft), transform 0.9s var(--rv-ease); }
html.rd-motion .duo-art { transition-delay: 0.12s; }

/* ── Scroll reveals ────────────────────────────────────────────────────── */
html.rd-motion :is(.rd-section-head, .rd-split-copy, .rd-stats-copy, .rd-faq-intro, .rd-stage-switch, [data-reveal]):not(.is-in) {
  opacity: 0;
  transform: translateY(30px);
}
html.rd-motion :is(.rd-section-head, .rd-split-copy, .rd-stats-copy, .rd-faq-intro, .rd-stage-switch, .rd-close, [data-reveal]) {
  transition: opacity 0.8s var(--rv-ease-soft), transform 1s var(--rv-ease);
}
/* The copy column's parts follow the heading in. */
html.rd-motion .rd-split-copy > *:not(h2) { transition: opacity 0.8s var(--rv-ease-soft), transform 1s var(--rv-ease); }
html.rd-motion .rd-split-copy:not(.is-in) > *:not(h2) { opacity: 0; transform: translateY(14px); }
html.rd-motion .rd-split-copy > :nth-child(2) { transition-delay: 0.16s; }
html.rd-motion .rd-split-copy > :nth-child(3) { transition-delay: 0.26s; }
html.rd-motion .rd-split-copy > :nth-child(4) { transition-delay: 0.34s; }

/* Headlines rise word by word out of a mask. */
html.rd-motion .rd-w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding: 0.06em 0.02em 0.12em;
  margin: -0.06em -0.02em -0.12em;
}
html.rd-motion .rd-w > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 0.9s var(--rv-ease);
  transition-delay: calc(var(--i, 0) * 45ms + 60ms);
}
html.rd-motion .is-in .rd-w > span,
html.rd-motion .is-in.rd-w > span,
html.rd-motion h2.is-in .rd-w > span { transform: none; }

/* Feature media: the pastel canvas opens from a rounded window. */
html.rd-motion .rd-media {
  translate: 0 var(--rv-drift, 0px);
  clip-path: inset(0 round 0);
  transition: clip-path 1.1s var(--rv-ease), opacity 0.6s ease;
}
html.rd-motion .rd-media:not(.is-in) {
  clip-path: inset(9% 7% 9% 7% round 32px);
  opacity: 0.4;
}

/* Product screens tilt up flat as they arrive. */
html.rd-motion .rv-screen {
  transform-origin: 50% 100%;
  transition: transform 1.25s var(--rv-ease), opacity 0.7s ease, box-shadow 1.25s var(--rv-ease);
}
html.rd-motion .rv-screen:not(.is-in) {
  opacity: 0;
  transform: perspective(1400px) rotateX(14deg) translateY(56px) scale(0.95);
}
html.rd-motion .rd-media .rv-screen { transition-delay: 0.12s; }

/* Grids cascade. */
html.rd-motion .rv-stagger > * {
  transition: opacity 0.7s var(--rv-ease-soft), transform 0.95s var(--rv-ease);
  transition-delay: calc(var(--rv-i, 0) * 70ms);
}
html.rd-motion .rv-stagger:not(.is-in) > * {
  opacity: 0;
  transform: translateY(34px) scale(0.98);
}
/* Long lists shouldn't take seconds to arrive. */
html.rd-motion .rv-stagger > :nth-child(n + 9) { transition-delay: 0.56s; }
/* Hover lifts keep working after the cascade has run. */
html.rd-motion .rv-stagger.is-in > * { transition-delay: 0s; }
html.rd-motion .rv-stagger.is-in > * { transition: opacity 0.7s var(--rv-ease-soft), transform 0.5s var(--rv-ease), box-shadow 0.3s ease, background-color 0.3s ease; }

/* The closing panel lifts in like a card. */
html.rd-motion .rd-close:not(.is-in) { opacity: 0; transform: translateY(40px) scale(0.97); }

html.rd-motion { scroll-behavior: smooth; }

/* ── Tabs: one pill slides to the checked tab ─────────────────────────── */
html.rd-motion .rd-tabs.has-pill { position: relative; }
.rv-pill {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
  border-radius: 999px;
  background: var(--rd-bg, #fff);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08), 0 6px 14px -8px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  transition: transform 0.55s var(--rv-ease), width 0.55s var(--rv-ease), height 0.55s var(--rv-ease);
}
html.rd-motion .rd-tabs.has-pill .rd-tab { z-index: 1; }
html.rd-motion .rd-tabs.has-pill .rd-tab:has(input:checked) { background: transparent; box-shadow: none; }
@keyframes rv-panel {
  from { opacity: 0; transform: translateY(16px) scale(0.985); }
  to { opacity: 1; transform: none; }
}
html.rd-motion .rd-stage-switch .rd-panel { animation: rv-panel 0.65s var(--rv-ease) both; }
html.rd-motion .rd-frame.rv-screen { transition: transform 1.25s var(--rv-ease), opacity 0.7s ease, background-color 0.5s ease; }

/* ── Gallery shots tilt toward the cursor ──────────────────────────────── */
html.rd-motion .rv-tilt {
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.4s var(--rv-ease-soft);
}

/* ── A shooting star in the closing sky ────────────────────────────────── */
.rv-shoot {
  position: absolute;
  top: 14%;
  left: 18%;
  width: 130px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), #FFFFFF 85%, rgba(255, 255, 255, 0.4));
  opacity: 0;
  transform: rotate(18deg) translateX(-60px);
  animation: rv-shoot 11s ease-in 2.5s infinite;
}
@keyframes rv-shoot {
  0% { opacity: 0; transform: rotate(18deg) translateX(-60px); }
  1.5% { opacity: 1; }
  8% { opacity: 0; transform: rotate(18deg) translateX(420px); }
  100% { opacity: 0; transform: rotate(18deg) translateX(420px); }
}

/* ── Cursor light on cards ─────────────────────────────────────────────── */
.rd-spot { position: relative; isolation: isolate; }
.rd-spot::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.75), transparent 70%);
  opacity: 0;
  transition: opacity 0.35s ease;
}
.rd-spot:hover::after { opacity: 1; }

/* ── Buttons: a light sheen passes over the solid ones on hover ────────── */
html.rd-motion .rd-btn-solid { position: relative; overflow: hidden; }
html.rd-motion .rd-btn-solid::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, 0.28) 50%, transparent 70%);
  transform: translateX(-120%);
  pointer-events: none;
}
html.rd-motion .rd-btn-solid:hover::before { transform: translateX(120%); transition: transform 0.75s var(--rv-ease-soft); }

@media (max-width: 760px) {
  html.rd-motion .rd-media { translate: none; }
  html.rd-motion .rv-screen:not(.is-in) { transform: translateY(40px) scale(0.97); }
}

@media (prefers-reduced-motion: reduce) {
  html.rd-motion *,
  html.rd-motion *::before,
  html.rd-motion *::after { animation: none !important; transition: none !important; }
  html.rd-motion :is(.rd-section-head, .rd-split-copy, .rd-stats-copy, .rd-faq-intro, .rd-stage-switch, [data-reveal], .rd-close, .rd-media, .rv-screen, .rv-stagger > *, .rd-split-copy > *, .duo-feat-copy, .duo-art, .duo-ways > h2, .duo-proof > h2, .duo-close-inner) { opacity: 1 !important; transform: none !important; clip-path: none !important; scale: none !important; }
  html.rd-motion .rd-w > span { transform: none !important; }
}
