/* Bike Fit Lab — motion.css
 * Animações contidas em cima de site.css. Tudo depende de classes dadas por motion.js:
 *   html.has-motion  — motion.js correu e o utilizador NÃO pediu movimento reduzido
 *   html.m-page      — fade-in da página (só quando o script correu nos primeiros 1,5 s)
 *   html.m-settled   — 1,5 s depois do arranque: garante que nada fica invisível
 *   .fig.fig--on     — a figura entrou no viewport (figures.js ou motion.js; idempotente)
 *   .header.is-compact — já se desceu mais de 80 px
 * Sem motion.js nada disto se aplica; sem `.has-motion` nenhum estado inicial esconde conteúdo.
 */

/* ===== 7. Página: fade-in curto do <main> ===== */
@keyframes m-page-in { from { opacity: 0; } to { opacity: 1; } }
.has-motion.m-page main { animation: m-page-in 400ms var(--ease-out) both; }
.m-settled main { animation: none; opacity: 1; }

/* ===== 1. Traço que se desenha (pathLength="1" dado pelo JS, classe .m-stroke) =====
 * dasharray 1 1.5 com offset 1.25: o traço fica fora do caminho com margem para os terminais quadrados;
 * em .fig--on o offset vai a 0 e o traço desenha-se por ordem no DOM (--d, 40 ms por elemento, máx. 600 ms). */
.has-motion .fig .m-stroke { stroke-dasharray: 1 1.5; stroke-dashoffset: 1.25; }
.has-motion .fig.fig--on .m-stroke { stroke-dashoffset: 0; transition: stroke-dashoffset 800ms var(--ease-out) var(--d, 0ms); }

/* Articulações, pontos interativos, números e texto: aparecem depois do traço (500 ms + escalonamento --p). */
/* Um transform em CSS anula o atributo transform="translate(...)" do SVG, por isso os elementos
   posicionados por atributo ([transform]) só fazem fade; os outros também escalam. */
.has-motion .fig :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text):not(.f-hot *, .f-num *, .f-station *, .f-receipt *) {
  opacity: 0;
}
.has-motion .fig :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text):not(.f-hot *, .f-num *, .f-station *, .f-receipt *, [transform]) {
  transform: scale(0.6);
  transform-box: fill-box;
  transform-origin: center;
}
.has-motion .fig.fig--on :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text):not(.f-hot *, .f-num *, .f-station *, .f-receipt *) {
  opacity: 1;
  transition: opacity 400ms var(--ease-out) calc(500ms + var(--p, 0ms)), transform 500ms var(--ease-out) calc(500ms + var(--p, 0ms));
}
.has-motion .fig.fig--on :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text):not(.f-hot *, .f-num *, .f-station *, .f-receipt *, [transform]) {
  transform: none;
}

/* Preenchimentos do selim: a opacidade sobe por etapas, p1→p4, 120 ms entre si. */
.has-motion .fig .f-p { opacity: 0; }
.has-motion .fig.fig--on .f-p { transition: opacity 600ms var(--ease-out); }
.has-motion .fig.fig--on .f-p1 { opacity: 0.18; transition-delay: 700ms; }
.has-motion .fig.fig--on .f-p2 { opacity: 0.38; transition-delay: 820ms; }
.has-motion .fig.fig--on .f-p3 { opacity: 0.62; transition-delay: 940ms; }
.has-motion .fig.fig--on .f-p4 { opacity: 0.9; transition-delay: 1060ms; }

/* ===== 6. Processo em faixa: a rota desenha-se (acima) e as estações aparecem em sequência ===== */
.has-motion .fig--strip .f-band { opacity: 0; }
.has-motion .fig--strip.fig--on .f-band { opacity: 1; transition: opacity 500ms var(--ease-out) calc(var(--i, 0) * 80ms); }
.has-motion .fig--strip :is(.f-station, .f-receipt) { opacity: 0; transform: translateY(6px); }
.has-motion .fig--strip.fig--on :is(.f-station, .f-receipt) {
  opacity: 1;
  transform: none;
  transition: opacity 400ms var(--ease-out) calc(350ms + var(--i, 0) * 70ms), transform 500ms var(--ease-out) calc(350ms + var(--i, 0) * 70ms);
}

/* ===== 2. Pulso único nos pontos interativos (2 ciclos, 900 ms, 1,2 s depois de .fig--on) ===== */
@keyframes m-pulse {
  from { opacity: 0.4; transform: scale(0.7); }
  to { opacity: 0; transform: scale(2); }
}
.has-motion .fig.fig--on .f-hot__ring {
  transform-box: fill-box;
  transform-origin: center;
  animation: m-pulse 900ms var(--ease-out) 1200ms 2 none;
}
/* O pino de uma foto anotada não leva transform (é posicionado por --x/--y): o anel é um pseudo-elemento. */
.has-motion .fig--foto .fig-foto__pin::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--fg2);
  opacity: 0;
  pointer-events: none;
}
.has-motion .fig--foto.fig--on .fig-foto__pin::after { animation: m-pulse 900ms var(--ease-out) 1200ms 2 none; }

/* ===== 3. Contadores: o número conta dentro de uma caixa com a largura final (sem deslocação do layout) ===== */
.m-count { display: inline-block; text-align: end; font-variant-numeric: tabular-nums; }

/* ===== 4. Micro-interações =====
 * .button:active e .chip:active (scale .97) já existem em site.css. */

/* Sublinhado que cresce da esquerda na navegação do cabeçalho (pseudo-elemento, cor plana; os .link mantêm
   a transição de cor do sublinhado de site.css). */
.has-motion .nav__list a { position: relative; }
.has-motion .nav__list a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; background: currentColor;
  transform: scaleX(0); transform-origin: left center; transition: transform var(--t-hover) var(--ease-out);
}
.has-motion .nav__list a[aria-current="page"]::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .has-motion .nav__list a:hover::after, .has-motion .nav__list a:focus-visible::after { transform: scaleX(1); }
}
}

/* Lista "mais artigos": o título desloca-se 0.25rem em hover. */
.has-motion .row--link a > span:last-child { transition: transform var(--t-hover) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .has-motion .row--link a:hover > span:last-child { transform: translateX(0.25rem); }
}

/* Galeria: zoom suave na imagem em hover (os pais .drag figure / .mod--pair > * têm overflow hidden em site.css). */
.has-motion .drag img { transition: transform 700ms var(--ease-soft); }
@media (hover: hover) and (pointer: fine) {
  .has-motion .drag figure:hover img, .has-motion .drag .mod--pair > :hover img { transform: scale(1.03); }
}

/* FAQ: o markup atual são parágrafos (sem <details>). Se um dia houver <details> na lista, o conteúdo abre com um fade. */
@keyframes m-fade-up { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.has-motion .faq__list details[open] > :not(summary) { animation: m-fade-up var(--t-ui) var(--ease-out) both; }

/* ===== 5. Cabeçalho compacto ao descer (só onde o cabeçalho é sticky, ≥ 56.25em) =====
 * A fotografia fixa (.stage) acompanha: o seu topo e a sua altura transitam com o cabeçalho, sem salto. */
@media (min-width: 56.25em) {
  .has-motion .header__row { transition: min-height var(--t-ui) var(--ease-out); }
  .has-motion .header.is-compact .header__row { min-height: 3.5rem; }
  /* A margem cresce o que a linha encolhe: a pegada do cabeçalho no fluxo não muda, nada abaixo se desloca. */
  .has-motion .header { transition: margin-bottom var(--t-ui) var(--ease-out); }
  .has-motion .header.is-compact { margin-bottom: 1rem; }
  .has-motion .stage { transition: top var(--t-ui) var(--ease-out), height var(--t-ui) var(--ease-out); }
  .has-motion .header.is-compact ~ main .stage { top: 3.5rem; height: calc(100svh - 3.5rem); }
}

/* ===== Movimento reduzido: tudo desligado (o JS nem põe .has-motion, isto é a rede de segurança) ===== */
@media (prefers-reduced-motion: reduce) {
  .has-motion.m-page main { animation: none; opacity: 1; }
  .has-motion .fig .m-stroke { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
  .has-motion .fig :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text),
  .has-motion .fig--strip :is(.f-band, .f-station, .f-receipt) { opacity: 1; transition: none; }
  .has-motion .fig :is(.f-joints circle, .f-contacts rect, .f-hot, .f-num, text):not([transform]),
  .has-motion .fig--strip :is(.f-band, .f-station, .f-receipt):not([transform]) { transform: none; }
  .has-motion .fig .f-p { transition: none; }
  .has-motion .fig .f-p1 { opacity: 0.18; } .has-motion .fig .f-p2 { opacity: 0.38; }
  .has-motion .fig .f-p3 { opacity: 0.62; } .has-motion .fig .f-p4 { opacity: 0.9; }
  .has-motion .fig.fig--on .f-hot__ring, .has-motion .fig--foto.fig--on .fig-foto__pin::after { animation: none; }
  .has-motion .nav__list a::after, .has-motion .row--link a > span:last-child, .has-motion .drag img,
  .has-motion .header__row, .has-motion .header, .has-motion .stage { transition: none; }
  .has-motion .faq__list details[open] > :not(summary) { animation: none; }
}
