/* ===========================================================================
   CAMADA 6 - PAGINA (apresentacao publica)

   A landing e a unica tela do sistema feita para quem ainda nao entrou. Ela
   herda tudo do resto: as cores sao as mesmas variaveis, os botoes sao os
   mesmos botoes, o fundo vivo e o mesmo componente do login e o painel dentro
   da janela e montado com os componentes de verdade do produto.

   REGRAS DESTE ARQUIVO
     1. nenhuma cor literal: tudo vem de tokens.css;
     2. nao reestilizar seletor interno de componente;
     3. O ESTADO ESTATICO E SEMPRE O ESTADO FINAL, nunca o invisivel.

   A terceira e a regra que sustenta as animacoes de rolagem. Cada bloco de
   `animation-timeline` esta dentro de DUAS guardas:

     @media (prefers-reduced-motion: no-preference)  quem pediu menos
                                                     movimento nao recebe;
     @supports (animation-timeline: ...)             quem nao tem a
                                                     funcionalidade nao recebe.

   Nas duas situacoes a pagina aparece inteira e legivel, porque o CSS fora das
   guardas ja e o fim da animacao. O caminho oposto (escrever `opacity: 0` e
   contar com o script para acender) e como uma pagina inteira desaparece num
   navegador que nao entendeu uma linha.

   POR QUE `animation-timeline` E NAO JAVASCRIPT: animacao ligada a rolagem
   feita a mao roda um listener de scroll a cada quadro, na mesma thread que
   desenha a pagina, e e a receita classica de rolagem que engasga. Declarada
   em CSS, ela e do compositor: a pagina nao tem uma linha de JavaScript
   proprio.
   =========================================================================== */

/*
  A ROLAGEM SUAVE MORA NO <html>, e nao no <body>: `scroll-behavior` no body
  NAO se propaga para o documento (diferente de `overflow`, que se propaga).
  Como o layout base nao deixa por classe no <html>, o `:has` alcanca de baixo
  para cima, e o efeito fica preso a esta pagina em vez de virar global.

  `scroll-padding` existe por causa da barra fixa do topo: sem ele, o link
  para uma secao a encosta no alto da janela e o titulo fica embaixo da barra.
*/
html:has(.ipr-site-body) {
  scroll-behavior: smooth;
  scroll-padding-block-start: 6rem;
}
@media (prefers-reduced-motion: reduce) {
  html:has(.ipr-site-body) { scroll-behavior: auto; }
}

.ipr-site-body {
  background: var(--color-bg-base);
  /* A janela do produto e inclinada, e o navegador reserva espaco horizontal
     para o que a inclinacao joga para fora. Sem isto aparece uma barra de
     rolagem lateral que nao leva a lugar nenhum. */
  overflow-x: hidden;
}

/* ===========================================================================
   BARRA DO TOPO
   =========================================================================== */

.ipr-site__topo {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-4) clamp(var(--space-5), 5vw, var(--space-12));
  /* ESTADO ESTATICO: ja de vidro. Quem nao tiver a animacao de rolagem ve uma
     barra legivel desde o primeiro quadro, e nao um texto solto sobre o
     fundo. */
  background: var(--color-surface-glass);
  -webkit-backdrop-filter: blur(14px);
          backdrop-filter: blur(14px);
  border-block-end: 1px solid var(--color-border-subtle);
}

.ipr-site__marca { text-decoration: none; }
.ipr-site__nav {
  display: flex;
  align-items: center;
  gap: clamp(var(--space-4), 3vw, var(--space-8));
}
.ipr-site__link {
  color: var(--color-text-secondary);
  text-decoration: none;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  transition: color var(--dur-base) var(--ease-out);
}
.ipr-site__link:hover { color: var(--color-text-primary); }

/* ===========================================================================
   1. A PROMESSA
   =========================================================================== */

.ipr-site__hero {
  min-block-size: 92dvh;
  display: grid;
  justify-items: center;
  align-content: start;
  /* Apertado de proposito: o alto da janela tem que aparecer ANTES de
     qualquer rolagem. Uma dobra que termina em espaco vazio nao convida
     ninguem a rolar. */
  gap: clamp(var(--space-6), 4vh, var(--space-10));
  padding-block: clamp(var(--space-8), 5vh, var(--space-10)) 0;
  padding-inline: var(--space-5);
  /* As duas luzes do `.ipr-ambiente` sobem: no lugar padrao elas ficariam
     atras da janela, e nao atras do titulo, que e o que precisa brilhar. */
  --luz-quente-y: 24%;
  --luz-quente-x: 50%;
  --luz-fria-y: 40%;
  --luz-fria-x: 74%;
  --malha-foco: radial-gradient(ellipse 85% 60% at 50% 30%, #000 10%, transparent 78%);
}

.ipr-site__hero-texto {
  inline-size: min(100%, 48rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  text-align: center;
}

.ipr-site__titulo {
  font-size: clamp(2.5rem, 6.4vw, 4.5rem);
  line-height: 1.02;
  letter-spacing: -.035em;
  text-wrap: balance;
}

.ipr-site__lead {
  max-inline-size: 40rem;
  color: var(--color-text-secondary);
  font-size: clamp(var(--font-size-md), 1.6vw, var(--font-size-lg));
  line-height: var(--line-normal);
  text-wrap: pretty;
}

.ipr-site__acoes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-block-start: var(--space-2);
}
/*
  O BOTAO ANDA UM POUCO NA DIRECAO DO PONTEIRO. Tres pixels, e o teto e
  deliberado: alvo que foge produz clique errado, e para quem tem tremor
  produz clique impossivel. A esta distancia o efeito e percebido como peso do
  objeto, e nao como o botao fugindo.

  ESCRITO COMO AJUSTE DE CONTEXTO (`.ipr-site__acoes .ipr-btn`), e nunca como
  `.ipr-btn--lg` sozinho: o teste de nome de classe com dono acusaria o CSS da
  pagina de redefinir um componente, e estaria certo.

  `translate` e livre porque `.ipr-btn:active` usa `transform`.
*/
.ipr-site__acoes .ipr-btn {
  translate: calc(var(--pointer-nx) * 3px) calc(var(--pointer-ny) * 2px);
  transition: --pointer-nx var(--dur-base) var(--ease-out),
              --pointer-ny var(--dur-base) var(--ease-out);
}

/* AQUI FICAVA A LINHA DE TRES NUMEROS (vinculos, convenios, tempo de
   resposta). Ela saiu inteira: os dois primeiros diziam, sem dizer, que a casa
   tem base propria. A prova passou a ser o que acontece na moldura abaixo. */

/* ===========================================================================
   A TRAVESSIA

   Uma tela que aparece de lado, gira ate ficar de frente, respira, e entao
   cresce ate ocupar o quadro e se dissolver: do outro lado ja e a proxima
   secao. A rolagem nao empurra a pagina, ela atravessa a tela.

   A TELA NAO MOSTRA NADA. Luz, textura fina e um reflexo cruzando o vidro.
   Interface por dentro nao entra em pagina publica, e um desenho de interface
   seria a mesma coisa com outro nome.

   O ESTADO ESTATICO DESTE ARQUIVO E A TELA DE FRENTE, PARADA E ACESA, no
   tamanho de repouso. Quem nao tiver `animation-timeline` ve um objeto
   inteiro, e nao um pedaco de uma sequencia que nao aconteceu.
   =========================================================================== */

.ipr-site__palco {
  inline-size: min(100%, 74rem);
  display: grid;
  gap: var(--space-8);
  /* A perspectiva mora no PAI. No proprio elemento, o ponto de fuga ficaria no
     centro dele e a tela pareceria uma figura girando no lugar, e nao um
     objeto no espaco da pagina. */
  perspective: 1600px;
  perspective-origin: 50% 40%;
}

/*
  O APARELHO. Ele e a moldura e o dono do movimento de rolagem: gira e cresce.
  Nada mais escreve `transform` aqui.

  A PROPORCAO E UMA VARIAVEL. Monitor, e nao telefone, porque o sistema se usa
  sentado numa tela larga: um celular aqui prometeria um aplicativo que nao
  existe. Trocar e mexer nesta linha.
*/
.ipr-site__aparelho {
  --aparelho-proporcao: 16 / 10;
  inline-size: min(100%, 54rem);
  aspect-ratio: var(--aparelho-proporcao);
  margin-inline: auto;
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-bg-sunken);
  box-shadow: var(--shadow-xl), var(--shadow-highlight);
  overflow: hidden;
  transform-style: preserve-3d;
}

/*
  O VIDRO. E o dono do movimento de PONTEIRO, e por isso e um elemento
  separado: se a inclinacao e o giro escrevessem `transform` no mesmo lugar,
  a segunda declaracao apagaria a primeira sem erro nenhum.

  Ele se move menos que o aparelho de proposito: e isso que da a sensacao de
  que a luz esta ATRAS do vidro, e nao pintada nele.
*/
.ipr-site__vidro {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  transform: rotateX(calc(var(--pointer-ny) * -2.4deg))
             rotateY(calc(var(--pointer-nx) * 3.2deg));
  /* O amortecimento numa linha, na propria variavel registrada. */
  transition: --pointer-nx 260ms var(--ease-out),
              --pointer-ny 260ms var(--ease-out);
}

/* A luz da tela. Um aparelho ligado se reconhece pela luz que sai dele, e nao
   pelo que esta escrito na tela. */
.ipr-site__luz {
  position: absolute;
  inset: -25%;
  /* DUAS LUZES, e nao uma: um halo no centro e uma aurora subindo do pe. Uma
     luz so, centrada, achata a tela num circulo; a de baixo e o que faz o
     vidro parecer iluminado POR TRAS. */
  background:
    radial-gradient(closest-side circle at 50% 42%, var(--color-aurora), transparent),
    radial-gradient(closest-side ellipse at 50% 108%, var(--color-accent-tint-strong), transparent);
  filter: blur(6px);
  translate: calc(var(--pointer-nx) * 1.2rem) calc(var(--pointer-ny) * .8rem);
}

/* A textura fina. Some durante o zoom: e o unico conteudo de alta frequencia
   da tela, e ampliada duas vezes ela apareceria borrada. */
.ipr-site__textura {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, var(--color-mesh-dot) 1.1px, transparent 1.1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 45%, #000 20%, transparent 76%);
          mask-image: radial-gradient(ellipse 80% 70% at 50% 45%, #000 20%, transparent 76%);
}

/* A MARCA, centrada e discreta: e o que a tela mostra. Discreta porque ela
   nao e o assunto da dobra (o assunto e o titulo, la em cima); ela existe para
   a tela nao ser um retangulo escuro e vazio. */
.ipr-site__marca-tela {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: .62;
  translate: calc(var(--pointer-nx) * .5rem) calc(var(--pointer-ny) * .35rem);
}

/* O reflexo que cruza o vidro enquanto ele gira. No repouso ja saiu de cena
   pela direita: sumir por POSICAO, e nao por `opacity: 0`, que a regra da casa
   proibe fora de keyframe. */
.ipr-site__reflexo {
  position: absolute;
  inset-block: -30%;
  inset-inline-start: 0;
  inline-size: 30%;
  background: linear-gradient(100deg, transparent, var(--color-sheen),
                              var(--color-sheen-edge), transparent);
  filter: blur(6px);
  translate: 260% 0;
  rotate: 8deg;
}

/* --- A legenda ------------------------------------------------------------
   TRES FRASES, e nao um paragrafo: cada uma tem o seu tempo na rolagem, e
   todas terminam antes de o zoom cobrir o quadro. Fora das guardas elas ficam
   empilhadas e se leem de uma vez, que e o poster desta parte. */
.ipr-site__legenda {
  display: grid;
  justify-items: center;
  gap: var(--space-1);
  text-align: center;
  text-wrap: balance;
  color: var(--color-text-secondary);
  font-size: clamp(var(--font-size-md), 1.5vw, var(--font-size-lg));
  line-height: var(--line-snug);
}

/* ===========================================================================
   SECOES 2, 3 e 4: moldura comum
   =========================================================================== */

.ipr-site__secao {
  inline-size: min(100%, var(--container-lg));
  margin-inline: auto;
  padding-block: clamp(var(--space-16), 14vh, 9rem);
  padding-inline: var(--space-5);
}
/* A ESTEIRA COMECA MAIS CEDO que as outras secoes. Ela e a secao que recebe a
   travessia: com o respiro cheio, a tela se dissolvia e ficava uma tela inteira
   de nada antes do primeiro titulo aparecer. */
.ipr-site__esteira { padding-block-start: clamp(var(--space-8), 6vh, var(--space-12)); }

.ipr-site__cabeca {
  max-inline-size: 44rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-block-end: clamp(var(--space-10), 8vh, var(--space-16));
}
/*
  A FRENTE DA REVELACAO DO TITULO. Mesma ideia da frente do corte: registrada
  para poder ser animada, e com o `initial-value` no ESTADO FINAL (110%, titulo
  inteiro visivel), que e o que vale quando nada anima.
*/
@property --revela { syntax: "<percentage>"; inherits: false; initial-value: 110%; }

.ipr-site__h2 {
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  letter-spacing: -.03em;
  text-wrap: balance;
  /* A mascara existe SEMPRE, e nao so durante a animacao: assim o titulo tem
     um comportamento so, e nao dois. Com a frente em 110% ela nao esconde
     nada. */
  -webkit-mask-image: linear-gradient(to right, #000 calc(var(--revela) - 14%),
                                      transparent var(--revela));
          mask-image: linear-gradient(to right, #000 calc(var(--revela) - 14%),
                                      transparent var(--revela));
}
.ipr-site__sub {
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  line-height: var(--line-normal);
  text-wrap: pretty;
}

/* ===========================================================================
   2. A ESTEIRA

   Cada passo e um <li> ALTO que rola normalmente, com um cartao GRUDADO
   dentro dele. O <li> alto e o que da a rolagem; o cartao grudado e o que
   fica parado enquanto ela acontece.

   E o <li> que declara a linha do tempo (`view-timeline-name`), e nao o
   cartao: elemento grudado PARA de se mover em relacao a janela, entao a
   propria linha do tempo dele congelaria no meio. O cartao apenas consome a
   linha do tempo do pai, que continua correndo.
   =========================================================================== */

/* A TRILHA. Fora das guardas ela ja esta cheia: o poster de uma barra de
   progresso e ela completa, e nao vazia. Fica na mesma coluna dos cartoes
   (que sao `min(100%, 54rem)` centrados), um pouco a esquerda deles. */
.ipr-site__trilho { position: relative; }
.ipr-site__trilha {
  position: absolute;
  inset-block: 0;
  inset-inline-start: max(0px, calc(50% - 27rem - 2rem));
  inline-size: 2px;
  border-radius: var(--radius-pill);
  background: var(--color-border-subtle);
  overflow: hidden;
}
.ipr-site__trilha::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, var(--color-accent-500), var(--color-accent-300));
  transform-origin: 50% 0;
}

.ipr-passos {
  display: grid;
  gap: 0;
}
.ipr-passo {
  min-block-size: 64vh;
  display: grid;
  align-content: start;
}
.ipr-passo__cartao {
  position: sticky;
  inset-block-start: 18vh;
  inline-size: min(100%, 54rem);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: clamp(var(--space-6), 4vw, var(--space-10));
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  background: var(--color-surface-glass);
  -webkit-backdrop-filter: blur(18px);
          backdrop-filter: blur(18px);
  box-shadow: var(--shadow-lg);
}
.ipr-passo__num {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--tracking-tight);
  color: var(--color-accent-400);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  /* O numero e o unico marcador de progresso da secao: sem ele, quatro
     cartoes iguais nao dizem em que ponto do caminho a pessoa esta. */
  opacity: .85;
}
.ipr-passo__titulo {
  font-size: clamp(1.5rem, 2.8vw, 2.15rem);
  letter-spacing: -.025em;
  text-wrap: balance;
}
.ipr-passo__texto {
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
  line-height: var(--line-normal);
  max-inline-size: var(--measure);
  text-wrap: pretty;
}
.ipr-passo__marcas {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-block-start: var(--space-2);
}
.ipr-passo__marcas li {
  display: flex;
  align-items: start;
  gap: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}
.ipr-passo__marcas .ipr-icon {
  flex: none;
  inline-size: 1.15rem;
  block-size: 1.15rem;
  color: var(--color-success);
  margin-block-start: .1rem;
}

/* ===========================================================================
   3. O QUE VEM JUNTO
   =========================================================================== */

.ipr-site__recursos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: var(--space-5);
}
.ipr-recurso {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-8);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  background: var(--color-surface-1);
  transition: border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.ipr-recurso:hover {
  border-color: var(--color-border-strong);
  transform: translateY(-2px);
}
/* O CARTAO INCLINA PARA O PONTEIRO, alem do brilho que o `.ipr-sheen` ja
   pinta. Escreve `rotate`, e nao `transform`: o `:hover` acima ja usa
   `transform`, e as duas na mesma propriedade nao compoem. Sao angulos
   pequenos de proposito: o cartao tem texto dentro, e texto inclinado demais
   fica desconfortavel de ler. */
.ipr-site__recursos .ipr-recurso {
  transform-style: preserve-3d;
  rotate: y calc(var(--pointer-nx) * 1.4deg);
  transition: border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              --pointer-nx var(--dur-base) var(--ease-out);
}
.ipr-site__recursos { perspective: 1200px; }
.ipr-recurso__icone {
  display: grid;
  place-items: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: var(--radius-md);
  background: var(--color-accent-tint);
  color: var(--color-accent-400);
}
.ipr-recurso__titulo { font-size: var(--font-size-xl); letter-spacing: -.02em; }
.ipr-recurso__texto {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  line-height: var(--line-normal);
}

/* ===========================================================================
   4. A SAIDA
   =========================================================================== */

.ipr-site__fim {
  text-align: center;
  /* O MESMO componente do hero e do login, com as luzes centradas atras da
     caixa. Sem ele a ultima tela e a unica sem nada vivo no fundo, e a pagina
     termina mais apagada do que comecou. */
  --luz-quente-y: 50%;
  --luz-quente-x: 50%;
  --luz-quente-tam: min(42rem, 110vw);
  --luz-quente-forca: .38;
  --luz-fria-y: 62%;
  --luz-fria-x: 66%;
  --luz-fria-tam: min(30rem, 90vw);
}
.ipr-site__fim-caixa {
  max-inline-size: 46rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  padding: clamp(var(--space-10), 8vw, 5rem) var(--space-6);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  background: var(--color-surface-1);
  box-shadow: var(--shadow-lg);
  /* O fio da marca por cima da caixa: o mesmo gradiente do cartao de login. */
  background-image: var(--gradient-hairline);
  background-size: 100% 1px;
  background-repeat: no-repeat;
}
.ipr-site__fim .ipr-site__sub { text-align: center; }

.ipr-site__rodape {
  border-block-start: 1px solid var(--color-border-subtle);
  padding: var(--space-8) var(--space-5);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-6);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  text-align: center;
}

/* ===========================================================================
   O MOVIMENTO LIGADO A ROLAGEM

   Tudo daqui para baixo e enfeite, e por isso mora dentro das duas guardas.
   Nada aqui esconde conteudo: cada `@keyframes` tem apenas o `from`, e o
   destino e o estado normal do elemento, que ja esta escrito la em cima.
   =========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {

    /* A barra do topo comeca SEM vidro e ganha o vidro nos primeiros 8rem.
       Repare que o `from` e o estado "invisivel" da barra, e nao do conteudo
       dela: o texto esta legivel nos dois extremos. */
    .ipr-site__topo {
      animation: ipr-topo-assenta linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 8rem;
    }
    @keyframes ipr-topo-assenta {
      from {
        background: transparent;
        -webkit-backdrop-filter: blur(0);
                backdrop-filter: blur(0);
        border-block-end-color: transparent;
      }
    }

    /* =====================================================================
       A SEQUENCIA DA TRAVESSIA.

       TUDO E `scroll(root block)`, e nao `view()`: a tela precisa comecar de
       lado ANTES de qualquer rolagem, e uma linha do tempo de "entrada na
       tela" ja estaria no fim no primeiro quadro, porque o objeto nasce
       visivel na dobra.

       A ALTURA DO HERO MORA AQUI DENTRO. Sao 190vh, e eles sao o combustivel
       da sequencia: fora da guarda, quem nao anima nada rolaria duas telas de
       nada. O palco fica grudado enquanto o texto sobe e sai.
       ===================================================================== */
    /* A ALTURA E MAIOR QUE A SEQUENCIA DE PROPOSITO. Elemento grudento so
       gruda enquanto o PAI esta na tela: o quanto ele fica parado e a altura
       do pai menos a altura dele. Com a sequencia terminando depois desse
       ponto, a tela escapava para cima no meio do zoom, e por baixo dela ja
       aparecia a proxima secao. */
    /* 182vh e o MINIMO que ainda deixa o palco grudado durante a sequencia
       inteira (medido: 98vh de janela contra 96vh de coreografia). Cada vh a
       mais aqui e um vh de tela escura entre a dissolucao e a esteira. */
    .ipr-site__hero { min-block-size: 182vh; }
    .ipr-site__palco { position: sticky; inset-block-start: 12vh; }

    /*
      GIRO, PAUSA E ZOOM NUMA ANIMACAO SO, porque os tres mexem na MESMA
      propriedade: escritos em animacoes separadas, a ultima apagaria as
      outras. A pausa e um par de quadros com o mesmo valor, que e como se
      escreve "nao acontece nada aqui" numa linha do tempo.

      O zoom vai ate 2,1: o suficiente para a tela passar das bordas do quadro
      numa janela de monitor. Alem disso so aumentaria o custo de composicao,
      porque o que cobre ja cobriu.
    */
    .ipr-site__aparelho {
      animation: ipr-travessia linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 68vh;
    }
    @keyframes ipr-travessia {
      0%   { transform: rotateY(-27deg) rotateX(12deg) translateY(2.5rem) scale(.9); }
      33%  { transform: rotateY(0deg) rotateX(0deg) translateY(0) scale(1); }
      55%  { transform: rotateY(0deg) rotateX(0deg) translateY(0) scale(1); }
      100% { transform: rotateY(0deg) rotateX(0deg) translateY(0) scale(2.1); }
    }

    /* A MOLDURA SE DISSOLVE no fim do zoom: raio a zero e borda transparente.
       E o que transforma "uma tela grande" em "voce esta dentro da tela". */
    .ipr-site__aparelho {
      animation: ipr-travessia linear both, ipr-travessia-borda linear both;
      animation-timeline: scroll(root block), scroll(root block);
      animation-range: 0 68vh, 44vh 66vh;
    }
    @keyframes ipr-travessia-borda {
      to { border-radius: 0; border-color: transparent; }
    }

    /* A textura sai antes do zoom apertar: e o unico desenho fino da tela, e
       ampliado ele apareceria borrado. */
    /* A TEXTURA SAI CEDO, e por um motivo tecnico: ela e o unico desenho de
       alta frequencia da tela (pontos de 1px), e ampliada duas vezes ela
       apareceria borrada. */
    .ipr-site__textura {
      animation: ipr-travessia-textura linear both;
      animation-timeline: scroll(root block);
      animation-range: 33vh 60vh;
    }
    /* A MARCA FICA ATE O FIM, e sai junto com a tela. Ela nao tem o problema
       da textura: o arquivo tem 504px de largura e chega no maximo a uns 460
       ampliado, ou seja, nunca passa da resolucao propria e nao borra.

       O tempo dela e o do zoom inteiro de proposito: e o unico momento em que
       a marca ocupa a tela cheia, e apagar antes disso joga fora justamente o
       quadro em que ela aparece grande. */
    .ipr-site__marca-tela {
      animation: ipr-travessia-textura linear both;
      animation-timeline: scroll(root block);
      animation-range: 64vh 80vh;
    }
    @keyframes ipr-travessia-textura { to { opacity: 0; } }

    /* O REFLEXO CRUZA O VIDRO enquanto a tela gira, e nao depois: e o que faz
       o giro parecer um objeto de vidro virando, e nao uma imagem rodando. */
    .ipr-site__reflexo {
      animation: ipr-travessia-reflexo linear both;
      animation-timeline: scroll(root block);
      animation-range: 3vh 26vh;
    }
    @keyframes ipr-travessia-reflexo { from { translate: -160% 0; } }

    /* E A TRAVESSIA: a tela se dissolve e do outro lado ja e a proxima secao.
       `opacity` e propriedade separada de `transform`, entao esta animacao
       convive com o zoom sem disputa. */
    .ipr-site__aparelho {
      animation: ipr-travessia linear both,
                 ipr-travessia-borda linear both,
                 ipr-travessia-sai linear both;
      animation-timeline: scroll(root block), scroll(root block), scroll(root block);
      /* MEDIDO, e nao estimado: com o hero em 200vh e o palco em 628px, ele
         fica grudado ate 104vh de rolagem. A sequencia inteira, incluindo a
         dissolucao, termina em 102vh para caber nessa janela com folga. */
      /* MEDIDO, e nao estimado. O palco fica grudado por
         (altura do hero - altura do palco - o encosto de 12vh), o que da 86vh
         nesta tela. A sequencia inteira termina ai: um vh a mais e a tela
         escapa para cima no meio da dissolucao, e um vh a menos e tela escura
         de graca antes da proxima secao. */
      animation-range: 0 68vh, 44vh 66vh, 70vh 82vh;
    }
    @keyframes ipr-travessia-sai { to { opacity: 0; } }

    /* =====================================================================
       A LEGENDA ACOMPANHA OS TEMPOS. As tres frases passam a ocupar a MESMA
       celula do grid (uma area so, todas em `grid-area: frase`) e se revezam
       por opacidade.

       Empilhadas, elas seriam tres linhas lidas de uma vez; sobrepostas, elas
       viram uma frase que se completa enquanto a figura acontece. E por isso
       que a troca mora aqui dentro: sem animacao, tres linhas soltas ainda
       fazem sentido; sem as tres, sobraria uma frase pela metade.
       ===================================================================== */
    .ipr-site__legenda {
      grid-template-areas: "frase";
      /* A altura para de depender de qual frase esta visivel: com as tres na
         mesma celula, o grid ja reserva a maior. */
      align-items: start;
      min-block-size: 3.5rem;
    }
    .ipr-site__frase { grid-area: frase; }

    .ipr-site__frase {
      animation-timeline: scroll(root block);
      animation-timing-function: linear;
      animation-fill-mode: both;
    }
    /* Uma por tempo: abrir, cortar, e a que fica. */
    /* As tres terminam ANTES de o zoom cobrir o quadro: a partir de mais ou
       menos 80vh a tela ja passou por cima da legenda. */
    .ipr-site__frase:nth-child(1) {
      animation-name: ipr-frase-passa;
      animation-range: 1vh 16vh;
    }
    .ipr-site__frase:nth-child(2) {
      animation-name: ipr-frase-passa;
      animation-range: 16vh 28vh;
    }
    .ipr-site__frase:nth-child(3) {
      animation-name: ipr-frase-passa;
      animation-range: 28vh 40vh;
    }
    /* Entra, fica, sai. As duas primeiras somem porque a proxima chega; a
       terceira nao tem proxima, e por isso tem keyframe proprio. */
    @keyframes ipr-frase-passa {
      0%   { opacity: 0; translate: 0 .5rem; }
      18%  { opacity: 1; translate: 0 0; }
      82%  { opacity: 1; translate: 0 0; }
      100% { opacity: 0; translate: 0 -.5rem; }
    }
  }

  @supports (animation-timeline: view()) {

    /* Os cartoes da esteira: chegam e recuam.

       SAO DUAS ANIMACOES, e cada uma escreve em propriedades DIFERENTES: a
       primeira em `translate` e `opacity`, a segunda em `scale` e `filter`.
       Escritas as duas em `transform`, a de tras apagaria a da frente sem
       aviso. Ter `translate`, `scale` e `rotate` como propriedades separadas
       existe exatamente para isto. */
    .ipr-passo { view-timeline-name: --passo; view-timeline-axis: block; }
    .ipr-passo__cartao {
      animation: ipr-passo-chega linear both, ipr-passo-recua linear both;
      animation-timeline: --passo, --passo;
      animation-range: entry 10% entry 90%, exit 10% exit 90%;
    }
    @keyframes ipr-passo-chega {
      from { opacity: 0; translate: 0 3.5rem; }
    }
    @keyframes ipr-passo-recua {
      to { opacity: .18; scale: .93; filter: blur(3px); }
    }

    /* Os cartoes de gestao sobem em escada: cada um responde a propria
       entrada na tela, entao o escalonamento sai da posicao deles na pagina e
       nao de uma lista de atrasos escrita a mao. */
    .ipr-recurso,
    .ipr-site__cabeca,
    .ipr-site__fim-caixa {
      animation: ipr-site-sobe linear both;
      animation-timeline: view();
      animation-range: entry 5% entry 60%;
    }
    @keyframes ipr-site-sobe {
      from { opacity: 0; translate: 0 2.5rem; }
    }

    /* O TITULO SE REVELA DA ESQUERDA PARA A DIREITA, como quem passa a mao
       sobre o vidro. E a mesma tecnica do corte da figura (uma parada de
       mascara animada), usada de novo em outra escala: a pagina tem UM
       vocabulario de movimento, e nao um efeito diferente por secao. */
    .ipr-site__h2 {
      animation: ipr-revela-texto linear both;
      animation-timeline: view();
      animation-range: entry 20% entry 90%;
    }
    @keyframes ipr-revela-texto { from { --revela: -14%; } }

    /* A TRILHA SE PREENCHE enquanto a lista atravessa a tela. `entry 100%` e
       `exit 0%` sao os dois extremos do periodo em que a lista esta INTEIRA
       na tela: antes ela ainda esta entrando, depois ja esta saindo. */
    .ipr-site__trilho { view-timeline-name: --trilho; view-timeline-axis: block; }
    .ipr-site__trilha::after {
      animation: ipr-trilha-enche linear both;
      animation-timeline: --trilho;
      animation-range: entry 100% exit 0%;
    }
    @keyframes ipr-trilha-enche { from { scale: 1 0; } }

    /* O FIO DA CAIXA FINAL SE DESENHA. Ele ja e um `background-image` de 1px
       no topo; animar `background-size` de 0 a 100% e o mesmo gesto de um
       traco sendo puxado, sem elemento nenhum a mais.

       Precisa vir DEPOIS da regra que agrupa a caixa com os cartoes: sao duas
       animacoes no mesmo elemento, e a lista de `animation-name` e escrita
       inteira aqui. */
    .ipr-site__fim-caixa {
      animation: ipr-site-sobe linear both, ipr-fio-desenha linear both;
      animation-timeline: view(), view();
      animation-range: entry 5% entry 60%, entry 25% entry 95%;
    }
    @keyframes ipr-fio-desenha { from { background-size: 0% 1px; } }
  }
}

/* ===========================================================================
   TELAS ESTREITAS
   =========================================================================== */

@media (max-width: 47.9375rem) {
  .ipr-site__link { display: none; }
  /* No celular a tela nasce de frente: girar em 3D um objeto que ja aparece
     pequeno custa uma camada de composicao e entrega quase nada. O zoom e a
     travessia continuam, porque sao eles o ponto da pagina. */
  .ipr-site__palco { perspective: none; }
  .ipr-site__aparelho { --aparelho-proporcao: 4 / 3; }
  /* Cartao grudado em tela de celular ocuparia a altura inteira e o passo
     seguinte nunca apareceria. Aqui a esteira volta a ser uma lista. */
  .ipr-passo { min-block-size: auto; margin-block-end: var(--space-8); }
  .ipr-passo__cartao { position: static; }
  /* Sem coluna sobrando, a trilha cairia em cima do texto. */
  .ipr-site__trilha { display: none; }
}

@media (max-width: 47.9375rem) {
  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: scroll()) {
      /* AS FAIXAS SAO AS MESMAS, e so a altura do hero muda. No celular o
         palco e bem mais baixo (a tela e 4/3 e a legenda ocupa menos), entao a
         janela do sticky ja da conta da coreografia inteira com 150vh, e o
         hero fica uma tela mais curto do que no monitor. */
      .ipr-site__hero { min-block-size: 150vh; }
      .ipr-site__palco { inset-block-start: 8vh; }
    }
    @supports (animation-timeline: view()) {
      /* Sem cartao grudado, recuar viraria "o cartao some enquanto voce le". */
      .ipr-passo__cartao {
        animation: ipr-passo-chega linear both;
        animation-range: entry 10% entry 90%;
      }
    }
  }
}
