/* =========================================================================
   RequestMe — Motion layer
   Loaded last, on the five public pages only. Purely additive: nothing here
   is required for the site to work, it makes the working site feel premium.
   Every animation is transform/opacity only (GPU-friendly, no layout
   thrash). The blanket prefers-reduced-motion override in base.css already
   forces all durations to ~0 — the JS side additionally short-circuits
   itself under that preference (see motion.js) since rAF-driven counters
   aren't covered by a CSS duration.
   ========================================================================= */

/* ---- Smooth cross-document page transitions (progressive enhancement) --- */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: rmViewOut 180ms var(--ease-standard) both; }
  ::view-transition-new(root) { animation: rmViewIn 220ms var(--ease-standard) both; }
}
@keyframes rmViewOut { to { opacity: 0; } }
@keyframes rmViewIn { from { opacity: 0; transform: translateY(6px); } }

/* Entry fade for the very first paint / browsers without view-transitions */
body { animation: rmPageIn 520ms var(--ease-standard) both; }
@keyframes rmPageIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---- Reveal-on-scroll variants (base opacity/transform lives in marketing.css) */
[data-reveal] { transition-duration: 640ms; }
[data-reveal="left"] { transform: translateX(-28px); }
[data-reveal="left"].is-visible { transform: none; }
[data-reveal="right"] { transform: translateX(28px); }
[data-reveal="right"].is-visible { transform: none; }
[data-reveal="scale"] { transform: scale(0.94); }
[data-reveal="scale"].is-visible { transform: scale(1); }
[data-reveal="fade"] { transform: none; }

/* ---- Card lift & depth --------------------------------------------------- */
.card, .plan-card, .testimonial-card, .doc-mock, .browser-frame, .tg-card, .list-manager-row {
  transition: transform 260ms var(--ease-standard), box-shadow 260ms var(--ease-standard), border-color 260ms var(--ease-standard);
}
.card:hover, .testimonial-card:hover, .plan-card:hover, .doc-mock:hover, .browser-frame:hover {
  transform: translateY(-4px);
  box-shadow: 0 20px 36px -18px rgba(11, 14, 20, 0.22);
}
.plan-card.is-featured:hover { transform: translateY(-6px); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card:hover,
  :root:not([data-theme="light"]) .testimonial-card:hover,
  :root:not([data-theme="light"]) .plan-card:hover,
  :root:not([data-theme="light"]) .doc-mock:hover,
  :root:not([data-theme="light"]) .browser-frame:hover {
    box-shadow: 0 20px 40px -16px rgba(0, 0, 0, 0.55);
  }
}
:root[data-theme="dark"] .card:hover,
:root[data-theme="dark"] .testimonial-card:hover,
:root[data-theme="dark"] .plan-card:hover,
:root[data-theme="dark"] .doc-mock:hover,
:root[data-theme="dark"] .browser-frame:hover {
  box-shadow: 0 20px 40px -16px rgba(0, 0, 0, 0.55);
}
.doc-mock { transition: transform 300ms var(--ease-standard), box-shadow 300ms var(--ease-standard); }
.doc-mock:hover { box-shadow: 0 24px 48px -20px color-mix(in srgb, var(--action-primary) 32%, rgba(11,14,20,.2)); }

/* ---- Buttons: hover lift, glow, ripple ------------------------------------ */
.btn { position: relative; overflow: hidden; transform: translateZ(0); }
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary:hover { box-shadow: 0 10px 24px -8px color-mix(in srgb, var(--action-primary) 55%, transparent); }
.btn-telegram:hover { box-shadow: 0 10px 24px -8px rgba(34, 158, 217, 0.5); }
.btn .rm-ripple {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: rgba(255, 255, 255, 0.45);
  transform: scale(0); opacity: 0.9;
  animation: rmRipple 620ms ease-out forwards;
}
.btn-ghost .rm-ripple, .btn-quiet .rm-ripple, .btn-ghost-on-dark .rm-ripple {
  background: color-mix(in srgb, var(--action-primary) 30%, transparent);
}
@keyframes rmRipple { to { transform: scale(2.6); opacity: 0; } }

/* ---- Chips & nav links: elegant hover ------------------------------------- */
.chip { transition: transform 180ms var(--ease-standard), border-color 180ms, color 180ms, background-color 180ms; }
.chip:hover:not([aria-selected="true"]) { border-color: var(--action-primary); color: var(--text-primary); transform: translateY(-1px); }

.nav-links a:not([aria-current="page"]) {
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%; background-repeat: no-repeat; background-size: 0% 2px;
  transition: background-size 260ms var(--ease-standard), color 200ms;
}
.nav-links a:not([aria-current="page"]):hover { background-size: 100% 2px; }

.footer-col a { transition: color 180ms, padding-left 180ms var(--ease-standard); }
.footer-col a:hover { padding-left: 4px; }

/* ---- Sticky nav: hide on scroll down, reveal on scroll up ----------------- */
.site-header { transition: transform 320ms var(--ease-standard), border-color 200ms, background-color 200ms; }
.site-header.is-hidden { transform: translateY(-100%); }

/* ---- Dashboard tab-panel crossfade ----------------------------------------- */
.tab-panel { transition: opacity 220ms var(--ease-standard), transform 220ms var(--ease-standard); }
.tab-panel.is-leaving { opacity: 0; transform: translateY(6px); }
.tab-panel.is-entering { opacity: 0; transform: translateY(6px); }

/* ---- Accordion content fade (pairs with max-height in components.css) ----- */
.accordion-panel-inner { opacity: 0; transition: opacity 260ms var(--ease-standard) 40ms; }
.accordion-item.is-open .accordion-panel-inner { opacity: 1; }

/* Rendered accordion rows fade/stagger in on insertion — CSS-only, so it
   works the instant render.js writes them, no scroll-observer needed. */
@keyframes rmFadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.accordion-item { animation: rmFadeUp 460ms var(--ease-standard) both; }
.accordion-item:nth-child(1) { animation-delay: 0ms; }
.accordion-item:nth-child(2) { animation-delay: 50ms; }
.accordion-item:nth-child(3) { animation-delay: 100ms; }
.accordion-item:nth-child(4) { animation-delay: 150ms; }
.accordion-item:nth-child(5) { animation-delay: 200ms; }
.accordion-item:nth-child(6) { animation-delay: 250ms; }
.accordion-item:nth-child(n+7) { animation-delay: 300ms; }

/* ---- Workflow step animation: number pop-in on reveal ---------------------- */
.step-num { transform: scale(0.5); opacity: 0; transition: transform 480ms var(--ease-standard) 80ms, opacity 480ms var(--ease-standard) 80ms; }
.step-item.is-visible .step-num { transform: scale(1); opacity: 1; }
.steps-list { position: relative; }
.steps-list::before {
  content: ""; position: absolute; left: 35px; top: 8px; bottom: 8px; width: 1px;
  background: linear-gradient(var(--border-hairline), var(--border-hairline)) no-repeat;
  background-size: 100% 0%; transition: background-size 900ms var(--ease-standard);
}
.steps-list.is-drawn::before { background-size: 100% 100%; }

/* ---- Pricing amount pulse on billing toggle -------------------------------- */
@keyframes rmPulse { 0% { transform: scale(1); } 35% { transform: scale(1.1); color: var(--action-primary); } 100% { transform: scale(1); } }
.plan-price .amount.is-pulsing { animation: rmPulse 480ms var(--ease-standard); display: inline-block; }
.switch { transition: background-color 220ms var(--ease-standard); }
.switch::after { transition: transform 220ms var(--ease-standard); }

/* ---- Floating ambient background orbs -------------------------------------- */
.bg-orb { position: absolute; border-radius: 50%; filter: blur(60px); pointer-events: none; z-index: 0; opacity: 0.32; }
.bg-orb--a { width: 420px; height: 420px; background: radial-gradient(circle, var(--action-primary), transparent 70%); animation: rmFloatA 24s ease-in-out infinite; }
.bg-orb--b { width: 320px; height: 320px; background: radial-gradient(circle, var(--brass-600), transparent 72%); opacity: 0.18; animation: rmFloatB 30s ease-in-out infinite; animation-delay: -8s; }
@keyframes rmFloatA {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(26px, -22px) scale(1.06); }
  66% { transform: translate(-18px, 20px) scale(0.96); }
}
@keyframes rmFloatB {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-24px, 18px) scale(1.08); }
}
.hero, .page-hero, section.section-inverse { isolation: isolate; overflow: clip; }
.hero-glow { animation: rmGlowPulse 9s ease-in-out infinite; }
@keyframes rmGlowPulse { 0%, 100% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.07); } }
section.section-inverse .bg-orb, section.final-cta .bg-orb { opacity: 0.22; }
/* Orbs sit at z-index:0 behind every section's actual content container */
.wrap-wide, .wrap-narrow, .wrap, .hero-grid { position: relative; z-index: 1; }

/* ---- Contact form success state ------------------------------------------- */
#contact-success:not([hidden]) { animation: rmFadeUp 480ms var(--ease-standard) both; }

/* ---- Loading skeleton (shown until JS renders real content) ---------------- */
.skeleton-card {
  border-radius: var(--radius-m); border: 1px solid var(--border-hairline);
  background: var(--bg-fill); min-height: 148px; position: relative; overflow: hidden;
}
.skeleton-card::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--bg-hover) 70%, white 15%), transparent);
  transform: translateX(-100%);
  animation: rmShimmer 1.5s ease-in-out infinite;
}
:root[data-theme="dark"] .skeleton-card::after { background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .skeleton-card::after { background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent); }
}
@keyframes rmShimmer { to { transform: translateX(100%); } }

/* ---- Respect the user: JS also checks this, but belt-and-braces here too -- */
@media (prefers-reduced-motion: reduce) {
  .bg-orb, .hero-glow { animation: none !important; }
  body { animation: none !important; }
  .steps-list::before { transition: none; background-size: 100% 100%; }
}

/* =========================================================================
   Next-gen hero: animated mesh gradient + film grain
   Four soft, heavily-blurred brand-blue blobs (plus a touch of brass).
   Each blob runs TWO independent infinite loops at once — a "flow"
   (translate + non-uniform scale + a few degrees of rotate) and a
   "breathe" (a gentle opacity dip) — every one of them on its own prime
   -ish duration between 21s and 29s. Only `transform` and `opacity` are
   ever animated: both are compositor-only properties, so the browser
   rasterizes each blurred blob exactly once and every frame after that is
   pure GPU compositing — no repaint, no layout, 60fps regardless of how
   many blobs are on screen.

   Why eight loops with mismatched, mutually-coprime-ish periods (21, 22,
   23, 24, 27, 28, 29s) instead of one shared cycle: any single loop is
   trivially seeable as "the same thing again" once you've watched it
   twice. Eight independent loops layered on four overlapping blobs only
   realign to their exact combined starting state after the LCM of all
   eight periods — on the order of days, not seconds — so nothing about
   the composite scene ever visibly resets, even though every individual
   layer underneath is a small seamless loop (0% and 100% match exactly
   on all of them, so no layer itself ever jumps).

   The Request Preview mockup sits above this with its own always-on
   ambient glow, so it reads as the lit, in-focus object against a calm,
   slow-moving atmosphere — never the other way around.
   ========================================================================= */
.mesh-gradient { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.mesh-blob { position: absolute; border-radius: 50%; filter: blur(90px); will-change: transform, opacity; }
.mesh-blob--1 {
  width: 620px; height: 620px; top: -18%; left: -6%;
  background: radial-gradient(circle, var(--brand-500), transparent 68%); opacity: .22;
  animation: meshFlowA 23s ease-in-out infinite, meshBreatheA 27s ease-in-out infinite;
}
.mesh-blob--2 {
  width: 520px; height: 520px; top: 2%; right: -10%;
  background: radial-gradient(circle, var(--brand-800), transparent 70%); opacity: .20;
  animation: meshFlowB 29s ease-in-out infinite -9s, meshBreatheB 22s ease-in-out infinite -4s;
}
.mesh-blob--3 {
  width: 460px; height: 460px; bottom: -22%; left: 26%;
  background: radial-gradient(circle, var(--brass-600), transparent 72%); opacity: .10;
  animation: meshFlowC 21s ease-in-out infinite -15s, meshBreatheC 28s ease-in-out infinite -11s;
}
.mesh-blob--4 {
  width: 380px; height: 380px; bottom: -2%; right: 14%;
  background: radial-gradient(circle, var(--brand-300), transparent 70%); opacity: .16;
  animation: meshFlowD 27s ease-in-out infinite -20s, meshBreatheD 24s ease-in-out infinite -7s;
}

@keyframes meshFlowA {
  0%, 100% { transform: translate(0%, 0%) scale(1, 1) rotate(0deg); }
  21%      { transform: translate(4%, 2%) scale(1.12, 0.9) rotate(7deg); }
  48%      { transform: translate(1%, 6%) scale(0.94, 1.1) rotate(-5deg); }
  76%      { transform: translate(-3%, 3%) scale(1.05, 0.97) rotate(4deg); }
}
@keyframes meshFlowB {
  0%, 100% { transform: translate(0%, 0%) scale(1, 1) rotate(0deg); }
  33%      { transform: translate(-4%, 2%) scale(0.9, 1.15) rotate(-7deg); }
  61%      { transform: translate(-1%, -4%) scale(1.08, 0.92) rotate(5deg); }
  87%      { transform: translate(3%, 1%) scale(0.98, 1.04) rotate(-3deg); }
}
@keyframes meshFlowC {
  0%, 100% { transform: translate(0%, 0%) scale(1, 1) rotate(0deg); }
  37%      { transform: translate(3%, -3%) scale(1.1, 0.95) rotate(6deg); }
  68%      { transform: translate(-2%, 4%) scale(0.92, 1.12) rotate(-6deg); }
}
@keyframes meshFlowD {
  0%, 100% { transform: translate(0%, 0%) scale(1, 1) rotate(0deg); }
  44%      { transform: translate(-3%, -4%) scale(1.06, 0.94) rotate(-8deg); }
  79%      { transform: translate(2%, 3%) scale(0.95, 1.08) rotate(5deg); }
}

@keyframes meshBreatheA { 0%, 100% { opacity: .22; } 42% { opacity: .18; } }
@keyframes meshBreatheB { 0%, 100% { opacity: .20; } 58% { opacity: .16; } }
@keyframes meshBreatheC { 0%, 100% { opacity: .10; } 38% { opacity: .08; } }
@keyframes meshBreatheD { 0%, 100% { opacity: .16; } 63% { opacity: .13; } }

/* A whisper of film grain keeps the gradient from reading as flat/digital. */
.mesh-grain {
  position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .035; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}
:root[data-theme="dark"] .mesh-grain { opacity: .05; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .mesh-grain { opacity: .05; } }

@media (prefers-reduced-motion: reduce) { .mesh-blob { animation: none !important; } }

/* Eyebrow reads as a small glass badge when it sits over the mesh. */
.hero-copy .eyebrow {
  display: inline-flex; padding: 6px 14px; border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--bg-page) 55%, transparent);
  border: 1px solid var(--border-hairline);
  backdrop-filter: blur(8px);
}

/* The Request Preview mockup stays the visual focus: an ambient glow at
   rest (not just on :hover) so it already reads as "lit" against the mesh. */
.hero-visual .doc-mock {
  box-shadow:
    var(--shadow-elevated),
    0 0 0 1px color-mix(in srgb, var(--action-primary) 8%, transparent),
    0 30px 60px -24px color-mix(in srgb, var(--action-primary) 26%, transparent);
}
