Scroll Motion logo

Scroll Motion

Community
joaquimftt-web
scroll-motion

Use when implementing or reviewing scroll-triggered entrances, bounded group entrances or decorative scroll-position indicators with Terra Motion Skills in React, including focus, safe geometry, reduced motion and cleanup.

Overview

Publisherjoaquimftt-web
Repositoryterra-motion-skills
Skill namescroll-motion
Stars
3
Forks
0
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by joaquimftt-web on GitHub. Read the source before you install it.

Installation

Install the Scroll Motion AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/joaquimftt-web/terra-motion-skills/tree/main/skills/scroll-motion
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/joaquimftt-web/terra-motion-skills.git /tmp/terra-motion-skills
mkdir -p .claude/skills
cp -r /tmp/terra-motion-skills/skills/scroll-motion .claude/skills/scroll-motion
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Scroll Motion in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Scroll Motion on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Scroll Motion is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Scroll motion

Escolha pela função da interface. As três recipes deste guia foram integradas à main pela PR #1 e têm demonstrações no GitHub Pages, junto às cinco anteriores. Esse é o registro histórico de L1/L2. O catálogo desta atualização L3 reúne 11 recipes, quatro skills e 16 subpaths; consulte também layout-transitions. A publicação de L3 exige seus próprios gates. Merge 491a934, CI/deploy 39881855054 aprovados. Pacotes npm não publicados; Release/tag v0.1.0 histórica. Leia as APIs reais antes de editar: ScrollReveal, StaggeredEntrance, ScrollProgress. Não importe o showcase, helpers privados ou estilos V4.

Aplicação

  1. Identifique a intenção: apresentar um bloco, coordenar um grupo ou indicar posição real. Não confunda posição com leitura.
  2. Escolha M06 ScrollReveal para bloco com entrada temporal; M07 StaggeredEntrance para lista inteira; M08 ScrollProgress para ligação direta à posição. Não resolver streaming/live edge, drag/reorder, tabs, overlays ou hero ornamental com estas APIs.
  3. Declare scroll root, conteúdo focável e geometria. M06/M07 só observam viewport. M08 distingue documento, seção na viewport e container vertical com wrapper em fluxo normal.
  4. Antes de aplicar entrada, verifique overflow/clipping, sombra, filtros, pseudoelementos, posicionamento e transforms. Conteúdo já visível ao montar/hidratar permanece estático, nunca é escondido ou deslocado para recuperar uma entrada perdida.
  5. Em grupo de cards use M07 sozinho, com M06 em blocos irmãos. Não envolver o mesmo grupo em M06, montar M06 por item nem somar transforms no li privado. Não criar contextos/providers para resolver essa composição.
  6. Importe por subpath; nenhum CSS próprio é obrigatório nestas três recipes. O consumidor define cores/superfícies. Preserve texto opaco, ordem DOM, estado dos filhos e navegação nativa.

Parâmetros

RecipeAPI e defaultsUnidade/limite
ScrollRevealduration260, offset8, once=true, replayKey, reduceMotion=false; children/props/ref divduration ms finito≥0; offset px0–24; key string/número finito
StaggeredEntranceitems readonly, getKey, renderItem, ref ul; mesmos defaults +stagger50stagger ms0–200; key estável/string única/não vazia
ScrollProgresssource default document; ref div da barrasem duration/replay/fade/spring/eixo/offsets genéricos

M07: delay(i)=min(i×stagger,200)ms. Com20 itens e default:0/50/100/150/200/200…; a cauda começa junta, não espera950ms. Total≤duration+200ms, default460ms. Não alterar o teto para preservar uma sequência artificialmente lenta. Grupos longos continuam custosos O(n); preferir grupos curtos por contexto, sem inventar virtualização.

duration0 ou offset0 encerra entrada e atrasos imediatamente. Preferência reduzida do sistema OR reduceMotion vence os valores selecionados. Use o DurationControl da vitrine apenas na vitrine, nunca como dependência da recipe.

M08 source:

  • {type:'document'}: scrollTop/(scrollHeight-clientHeight).
  • {type:'section',targetRef}: passagem da seção na viewport, (viewportHeight-top)/(viewportHeight+height), limitada0–1. Não é percentual de texto lido.
  • {type:'container',containerRef,contentRef}: proporção do container; contentRef é wrapper interno em fluxo normal, observa crescimento para invalidar medida. Não trocar o denominador pela altura do wrapper nem passar nó externo/absoluto. Ref nula não significa window.

Exemplo

Exemplos independentes de showcase, compilados contra os exports públicos locais. O consumidor fornece conteúdo/estilo, sem copiar identidade Terra Commerce.

tsx
import { useState } from 'react';
import { ScrollReveal } from '@motion-skills-lab/motion-recipes/scroll-reveal';
import { StaggeredEntrance } from '@motion-skills-lab/motion-recipes/staggered-entrance';

const resources = [
  { id: 'delivery', title: 'Entrega' },
  { id: 'returns', title: 'Trocas' },
] as const;
export function Resources() {
  const [replay, setReplay] = useState(0);
  return (
    <section>
      <ScrollReveal>
        <h2>Informações úteis</h2>
      </ScrollReveal>
      <button type="button" onClick={() => setReplay((v) => v + 1)}>
        Repetir grupo
      </button>
      <StaggeredEntrance
        items={resources}
        getKey={(item) => item.id}
        duration={260}
        stagger={50}
        replayKey={replay}
        renderItem={(item) => (
          <article>
            <h3>{item.title}</h3>
            <input aria-label={'Nota ' + item.id} />
          </article>
        )}
      />
    </section>
  );
}
tsx
import { useRef } from 'react';
import { ScrollProgress } from '@motion-skills-lab/motion-recipes/scroll-progress';

export function ContainerPosition() {
  const containerRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLDivElement>(null);
  return (
    <section>
      <h2>Posição na rolagem</h2>
      <ScrollProgress source={{ type: 'container', containerRef, contentRef }} />
      <div
        ref={containerRef}
        role="region"
        aria-label="Conteúdo rolável"
        tabIndex={0}
        style={{ maxHeight: 240, overflowY: 'auto' }}
      >
        <div ref={contentRef}>
          {Array.from({ length: 20 }, (_, i) => (
            <p key={i}>Linha estável {i + 1}</p>
          ))}
        </div>
      </div>
    </section>
  );
}

Restrições

  • Preparação M06/M07 somente quando todo conteúdo estiver comprovadamente abaixo da viewport, margem24px. Geometria incerta, sombra no alvo, clipping, inicialização tardia, ausência de IO/matchMedia ou falha de animação → fallback estático. Não relaxar o verificador para tornar a demo mais expressiva. Não prometer funcionamento animado em qualquer card CSS.
  • Replay é mudança de replayKey, não remontagem de filhos. Valor inicial não dispara replay. Trajetória visível contínua posição atual→offset→0; cancelar geração anterior. Foco/gesto interno bloqueia; nunca disputar a posição do controle usado.
  • M07 insere ul/li reais. renderItem devolve conteúdo do li, não outro li. Chaves alteradas/inserção/remoção/reordenação encerram grupo, sem animação de layout. Mesmas chaves/ordem com novas referências não reiniciam. Keys+replay no mesmo render respeitam foco, redução e gesto ainda ativo.
  • Mudança de duração/offset/stagger/once encerra execução corrente; novo valor vale para intenção elegível posterior. Alterar redução ao vivo conclui; desativá-la não retoma fila antiga.
  • M08 suporta fluxo normal. Sem faixa rolável mantém valor0/barra inativa, não100% lido. Sem ResizeObserver recalcula em eventos disponíveis, sem promessa de atualização imediata de mutação silenciosa. Refs desconectadas/estrangeiras e geometria inválida não viram window ou NaN.
  • Não adicionar polling por frame, observador por item, smooth-scroll global ou CSS experimental obrigatório. Motion14.3 useScroll não detecta todo crescimento por padrão; trackContentSize pode fazer polling. Não assumir assinatura reduced-motion dinâmica apenas pelo hook sem teste na versão instalada.

Acessibilidade

  • Conteúdo M06/M07 sempre no DOM, opaco e interativo. Sem inert/aria-hidden/focus trap para coreografia. Foco/pointerdown encerra antes do handler do consumidor, em todo o grupo inclusive itens atrasados. Nenhum item retoma depois.
  • Ordem DOM acompanha leitura; não usar CSS order para inverter sequência. Não alterar refs nativas ou descartar cleanup React19.
  • Reduced motion inicial e ao vivo elimina entrada/espera. Desconhecimento de preferência mantém estado seguro. M08 continua informativo direto, sem suavização ornamental.
  • Barra M08 é decorativa/aria-hidden, sem tabulação, live region, role=status/progressbar ou promessa de leitura. Container rolável pode ser region nomeada e focável pelo consumidor; a barra não captura teclado/toque.
  • SSR e primeiro cliente iguais: texto final legível e barra inicialmente inativa. Sem JS, navegação e conteúdo continuam úteis. Imports SSR-safe não bastam para afirmar hidratação validada.

Validação

Antes de declarar a integração pronta, execute e registre:

  1. Tipos/exports, consumidor externo só dist/manifests, casos TS negativos e exemplos desta skill.
  2. SSR real/noJS e hydrateRoot: positivo saudável e mismatch real tardio rejeitado após interações.
  3. Entradas automáticas preparadas, inicialmente visíveis e fallbacks de sombra/clipping/falha. Medir trajetórias e gravar motion real; screenshot isolado não valida entrada.
  4. M07 grupos1/6/20, atraso real pela WAAPI, cauda simultânea200ms,0/default/800ms, foco no último, chaves alteradas e replay rápido/gesto concorrente.
  5. M08 documento/seção/container, resize, conteúdo assíncrono, refs válidas/nulas, ausência de faixa/observer, scroll reverso/restaurado/BFCache, custo de contentRef sem polling ocioso.
  6. StrictMode, cancelamento de callbacks/listeners/frames/observers após troca/unmount; redução durante espera e execução; teclado/foco/axe/toque.
  7. Bases local/Pages,320/390/1024/1440, zoom nativo200%, overflow e regressões M01–M05/duas skills anteriores.

Diferencie resultados Windows por etapa, CI/build e deploy do merge 491a934 aprovados na execução 39881855054, smoke HTTPS de 42 testes automatizados, resultados de alterações posteriores sujeitos a validação própria, demos apenas lidas e dispositivos/browsers/AT não disponíveis. Axe não certifica anúncios de leitor de tela. Não usar “compatível” ou “publicado” por existir exemplo local.

Frequently asked questions

What does the Scroll Motion AI skill do?

Use when implementing or reviewing scroll-triggered entrances, bounded group entrances or decorative scroll-position indicators with Terra Motion Skills in React, including focus, safe geometry, reduced motion and cleanup.

Why use Scroll Motion on TypingMind?

Because you install it once and use it with any model. Scroll Motion is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Scroll Motion in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/joaquimftt-web/terra-motion-skills/tree/main/skills/scroll-motion. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Scroll Motion?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Scroll Motion?

As many as you like. As long as a model supports skills, you can use Scroll Motion with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Scroll Motion AI skill free?

Yes. It is published on GitHub by joaquimftt-web under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇