AGÊNC[IA] TLX//Motion System//v2.0
05

Motion

Animações que fazem seu site parecer vivo, não parado. Cada movimento guia o olho do visitante para onde importa. Aqui estão todas as regras.

01FILOSOFIA

5 princípios que guiam toda animação na TLX. Nada se mexe sem motivo — cada transição existe para mostrar algo ou facilitar a navegação.

#PrincípioDescrição
01IntencionalToda animação tem propósito funcional ou comunicativo. Nenhum movimento é decorativo sem razão.
02RápidoFeedback imediato. Durações curtas (150-400ms) para manter a interface responsiva e profissional.
03SuaveCurvas de easing naturais. Sem movimentos lineares ou abruptos. Tudo flui organicamente.
04CoerenteMesmos tokens em toda plataforma. Uma curva, uma duração, um padrão — consistência absoluta.
05AcessívelRespeita prefers-reduced-motion. Animações nunca são o único canal de informação.
02EASING CURVES

4 curvas de easing padronizadas. Clique em cada card para ver a animação em ação.

03DURAÇÕES

3 níveis de duração. Clique para visualizar o tempo relativo de cada token.

04PADRÕES

Padrões de animação reutilizáveis. Composições das curvas e durações para cenários comuns.

fadeInUpEntrada

Elemento entra de baixo com fade. Padrão para scroll entrance e montagem de página.

// fadeInUp
initial: { opacity: 0, y: 16 }
animate: { opacity: 1, y: 0 }
transition: {
  duration: 0.4,
  ease: [0, 0, 0.2, 1]  // Decelerate
}
fadeOutDownSaída

Elemento sai para baixo com fade. Usado ao desmontar ou navegar.

// fadeOutDown
animate: { opacity: 0, y: 16 }
transition: {
  duration: 0.25,
  ease: [0.4, 0, 1, 1]  // Accelerate
}
State ChangeInteração

Transição de estado (hover, active, disabled). Feedback imediato sem distração.

// State Change
transition: {
  duration: 0.15,
  ease: [0.4, 0, 0.2, 1]  // Smooth
}

// CSS equivalent
.element {
  transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
Scroll EntranceViewport

Elementos revelados ao entrar na viewport. Usa IntersectionObserver com once: true.

// Scroll Entrance (Framer Motion)
const ref = useRef(null);
const isInView = useInView(ref, {
  once: true,
  margin: "-20% 0px"
});

<motion.div
  ref={ref}
  initial={{ opacity: 0, y: 16 }}
  animate={isInView
    ? { opacity: 1, y: 0 }
    : { opacity: 0, y: 16 }
  }
  transition={{
    duration: 0.4,
    ease: [0, 0, 0.2, 1]
  }}
/>
05ACESSIBILIDADE

Respeitar preferências do usuário. Toda animação deve ser desativável via prefers-reduced-motion.

/* CSS — Desativar animações para usuários que preferem */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Framer Motion — Hook */
import { useReducedMotion } from "framer-motion";

function Component() {
  const shouldReduce = useReducedMotion();

  return (
    <motion.div
      animate={{ opacity: 1, y: shouldReduce ? 0 : 16 }}
      transition={{
        duration: shouldReduce ? 0 : 0.4
      }}
    />
  );
}

Checklist

  • Animações decorativas desativadas com prefers-reduced-motion
  • Transições de estado mantidas (opacity ok, transform removido)
  • Nenhuma informação transmitida exclusivamente por animação
  • Durações nunca excedem 400ms para feedback de interação
06LOGO ANIMATIONS

8 animações oficiais do logo TLX. Cada uma projetada para um contexto de uso específico.

01

Structural Reveal

1.2s

Logo se constrói letra por letra, simulando o processo de construção da marca. Stroke path animation com fill progressivo.

Uso:Hero sections, landing pages
02

Teal Pulse

2.0s

Logo pulsa com glow teal suave em loop. Indica processamento ou carregamento ativo.

Uso:Loading states, splash screens
03

Data Stream

1.5s

Partículas de dados fluem através das letras do logo, representando o fluxo de informação e análise.

Uso:Dashboards, analytics contexts
04

Blueprint Grid

1.8s

Logo aparece sobre grid blueprint que fade out, referenciando o aspecto projetual e construtivo da marca.

Uso:Apresentações, pitch decks
05

Layer Reveal

1.0s

Camadas do logo se empilham de baixo para cima com stagger. Comunica profundidade e construção em camadas.

Uso:Transições de página, apps
06

Metric Counter

1.5s

Letras do logo se comportam como contadores numéricos antes de resolver na forma final. Conecta marca e métricas.

Uso:Relatórios, resultados
07

Stagger Letters

0.8s

Cada letra entra com stagger de 50ms usando curva Decelerate. Simples, elegante, rápido.

Uso:Navegação, headers
08

Convergence

1.2s

Letras convergem de posições dispersas para a posição final. Comunica unificação e resolução.

Uso:Fechamento, CTA sections
07TOKENS

Tokens YAML completos do motion system. Source of truth para todas as plataformas.

motion:
  easing:
    smooth: "cubic-bezier(0.4, 0, 0.2, 1)"
    decelerate: "cubic-bezier(0, 0, 0.2, 1)"
    accelerate: "cubic-bezier(0.4, 0, 1, 1)"
    emphasis: "cubic-bezier(0.34, 1.56, 0.64, 1)"

  duration:
    fast: "150ms"
    normal: "250ms"
    slow: "400ms"

  patterns:
    fadeInUp:
      initial: { opacity: 0, y: 16 }
      animate: { opacity: 1, y: 0 }
      easing: decelerate
      duration: slow

    fadeOutDown:
      animate: { opacity: 0, y: 16 }
      easing: accelerate
      duration: normal

    stateChange:
      easing: smooth
      duration: fast

    scrollEntrance:
      initial: { opacity: 0, y: 16 }
      animate: { opacity: 1, y: 0 }
      easing: decelerate
      duration: slow
      trigger: viewport
      once: true

  logo:
    structural-reveal: { duration: "1.2s", loop: false }
    teal-pulse: { duration: "2.0s", loop: true }
    data-stream: { duration: "1.5s", loop: false }
    blueprint-grid: { duration: "1.8s", loop: false }
    layer-reveal: { duration: "1.0s", loop: false }
    metric-counter: { duration: "1.5s", loop: false }
    stagger-letters: { duration: "0.8s", loop: false }
    convergence: { duration: "1.2s", loop: false }

  a11y:
    reduced-motion: "remove transform, keep opacity"
    max-feedback-duration: "400ms"
    no-animation-only-info: true
08IMPLEMENTAÇÃO

Referência de implementação com Framer Motion. Padrões prontos para copiar e usar.

Framer Motion — Variantes base

import { motion, type Variants } from "framer-motion";

const fadeInUp: Variants = {
  hidden: { opacity: 0, y: 16 },
  visible: {
    opacity: 1,
    y: 0,
    transition: {
      duration: 0.4,
      ease: [0, 0, 0.2, 1], // Decelerate
    },
  },
};

<motion.div
  variants={fadeInUp}
  initial="hidden"
  animate="visible"
>
  {children}
</motion.div>

Framer Motion — Stagger children

const staggerContainer: Variants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.05,
      delayChildren: 0.1,
    },
  },
};

const staggerItem: Variants = {
  hidden: { opacity: 0, y: 12 },
  visible: {
    opacity: 1,
    y: 0,
    transition: {
      duration: 0.4,
      ease: [0, 0, 0.2, 1],
    },
  },
};

<motion.ul variants={staggerContainer} initial="hidden" animate="visible">
  {items.map((item) => (
    <motion.li key={item.id} variants={staggerItem}>
      {item.content}
    </motion.li>
  ))}
</motion.ul>

CSS Custom Properties

:root {
  /* Easing */
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
  --ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
  --ease-emphasis: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Duration */
  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --duration-slow: 400ms;
}

/* Uso */
.button {
  transition: all var(--duration-fast) var(--ease-smooth);
}

.modal {
  transition: transform var(--duration-slow) var(--ease-decelerate),
              opacity var(--duration-slow) var(--ease-decelerate);
}

Tailwind — Classes utilitárias

/* tailwind.config.js */
theme: {
  extend: {
    transitionTimingFunction: {
      smooth: "cubic-bezier(0.4, 0, 0.2, 1)",
      decelerate: "cubic-bezier(0, 0, 0.2, 1)",
      accelerate: "cubic-bezier(0.4, 0, 1, 1)",
      emphasis: "cubic-bezier(0.34, 1.56, 0.64, 1)",
    },
    transitionDuration: {
      fast: "150ms",
      normal: "250ms",
      slow: "400ms",
    },
  },
}

/* Uso no JSX */
<button className="transition-all duration-fast ease-smooth">
  Hover me
</button>