/* Meza.Libaneza: motion. Owner: motion (corrida site-2026-10-09). Linked by the head after site.css, on every page.
   Values are the tokens of brand/tokens.css (--ease-*, --dur-*, --stagger-*); nothing here invents a curve.
   Only transform, opacity and clip-path move. Exits are faster than entries.

   What moves, and why (one kind of motion per kind of content):
     page change        @view-transition: the page leaves in 160 ms and arrives in 300 ms; the header, the demo strip and
                        the phone bar stay put; going back runs the other way; switching language is a plain crossfade.
     title              [data-entra="linhas"]: masked lines rise one after another, then the cut letter swaps its halves.
     «eza» column       [data-rolo]: the logo's column turns like a reel and stops in place (site.js, first visit only).
     band               [data-revela="faixa"]: the azulejo band is laid tile by tile (site.js builds the tiles).
     photograph         [data-revela="foto"]: opens from the top with clip-path; the navy block and the band stay still.
     list               [data-revela="lista"]: items one after another, a short stagger with a ceiling.
     number             [data-revela="numero"]: the figure rises into its slot once, like the reel; no counter.
     block              [data-revela="bloco"]: lifts into place.
     press and hover    scale(.97) on press; the nav underline draws from the left; arrows nudge towards where they go.

   Hidden states exist only under .rv (set by site.js) and only on elements site.js marked .is-espera, so without
   JavaScript, or if site.js fails, everything is visible. The title arrival is CSS only (under .js, set by the head)
   and always ends visible. Reduced motion: no translate, scale or clip-path; a short fade, the reel and the cut letter
   already in place (tokens.css zeroes their durations). */

/* ---------- 1. changing page ---------- */
@view-transition { navigation: auto; }

/* .cabecalho (cabecalho) and .barra (barra) are named in site.css; the demo strip above the header stays put too.
   site.js removes a name before the old page is captured when that piece is off screen or under the phone menu. */
.faixa-demo { view-transition-name: demo; }

::view-transition-group(*) {
  animation-duration: var(--dur-page-in, 300ms);
  animation-timing-function: var(--ease-out, cubic-bezier(.23, 1, .32, 1));
}
::view-transition-old(root) { animation: pagina-sai var(--dur-page-out, 160ms) var(--ease-out, cubic-bezier(.23, 1, .32, 1)) both; }
::view-transition-new(root) { animation: pagina-entra var(--dur-page-in, 300ms) var(--ease-out, cubic-bezier(.23, 1, .32, 1)) 40ms both; }

/* back through the history: the other way round (html.vt-volta, from site.js) */
html.vt-volta::view-transition-old(root) { animation-name: pagina-sai-volta; }
html.vt-volta::view-transition-new(root) { animation-name: pagina-entra-volta; }

/* PT to EN on the same page: the words change in place, so nothing travels */
html.vt-lingua::view-transition-old(root) { animation: pagina-esmaece-sai var(--dur-page-out, 160ms) ease both; }
html.vt-lingua::view-transition-new(root) { animation: pagina-esmaece-entra 240ms ease both; }

/* the phone bar leaves through the bottom edge on /reservar (where it does not exist) and comes back the same way */
::view-transition-old(barra):only-child { animation: barra-sai var(--dur-exit, 160ms) var(--ease-out, cubic-bezier(.23, 1, .32, 1)) both; }
::view-transition-new(barra):only-child { animation: barra-entra var(--dur-page-in, 300ms) var(--ease-out, cubic-bezier(.23, 1, .32, 1)) both; }

@keyframes pagina-sai { to { opacity: 0; transform: translateY(-6px); } }
@keyframes pagina-entra { from { opacity: 0; transform: translateY(12px); } }
@keyframes pagina-sai-volta { to { opacity: 0; transform: translateY(6px); } }
@keyframes pagina-entra-volta { from { opacity: 0; transform: translateY(-12px); } }
@keyframes pagina-esmaece-sai { to { opacity: 0; } }
@keyframes pagina-esmaece-entra { from { opacity: 0; } }
@keyframes barra-sai { to { transform: translateY(100%); } }
@keyframes barra-entra { from { transform: translateY(100%); } }

/* ---------- 2. arriving on a page: the title by lines, then the cut letter, then what follows the title ----------
   One .linha > span per real line (site.css). --i is the line's place (site.js writes the exact one); the cut letter
   waits for the last line (--corte-atraso, from site.js). A title below the fold waits for the scroll (.is-espera). */
[data-entra="linhas"] .linha:nth-child(2) { --i: 1; }
[data-entra="linhas"] .linha:nth-child(3) { --i: 2; }
[data-entra="linhas"] .linha:nth-child(4) { --i: 3; }
[data-entra="linhas"] .linha:nth-child(5) { --i: 4; }
[data-entra="linhas"] { --entra-atraso: 120ms; }
[data-entra="linhas"].is-vista { --entra-atraso: 0ms; }

@media (prefers-reduced-motion: no-preference) {
  .js [data-entra="linhas"] .linha > span {
    animation: linha-sobe var(--dur-title-line) var(--ease-out) both;
    animation-delay: calc(var(--entra-atraso) + var(--i, 0) * var(--stagger-line));
  }
  .js [data-entra="linhas"] .cut::before,
  .js [data-entra="linhas"] .cut::after {
    animation: corte-troca var(--dur-cut-slide) var(--ease-out) both;
    animation-delay: var(--corte-atraso, calc(var(--entra-atraso) + 370ms));
  }
  /* the page title only: the lead and the actions next to it follow, short (--segue-atraso is set by site.js on the
     title's parent, from the number of lines) */
  .js h1[data-entra="linhas"] ~ :is(.lead, .acoes) {
    animation: segue var(--dur-enter) var(--ease-out) both;
    animation-delay: var(--segue-atraso, 280ms);
  }
  .js h1[data-entra="linhas"] ~ .acoes { animation-delay: calc(var(--segue-atraso, 280ms) + 70ms); }

  .rv [data-entra="linhas"].is-espera .linha > span { animation: none; transform: translateY(calc(100% + .35em)); }
  .rv [data-entra="linhas"].is-espera .cut::before,
  .rv [data-entra="linhas"].is-espera .cut::after { animation: none; transform: none; }
}
/* the line starts a full line plus .35em down: the mask (.linha) has .16em of room above for accents (Â, Ó) and
   .06em below, so 105% left a circumflex showing above the mask before the line rose */
@keyframes linha-sobe { from { transform: translateY(calc(100% + .35em)); } }
@keyframes corte-troca { from { transform: none; } }
@keyframes segue { from { opacity: 0; transform: translateY(8px); } }

/* a prerendered page holds its arrival until it is shown (site.js sets .pre-ativacao while document.prerendering) */
.pre-ativacao [data-entra="linhas"] .linha > span,
.pre-ativacao [data-entra="linhas"] .cut::before,
.pre-ativacao [data-entra="linhas"] .cut::after,
.pre-ativacao h1[data-entra="linhas"] ~ :is(.lead, .acoes) { animation-play-state: paused; }

/* The header band on a page reached without a view transition (the first page of a visit, a reload): it waits for
   site.js to say whether this is the first visit (lay it tile by tile) or not (show it), so it never shows, vanishes
   and comes back. If site.js never runs, it comes back by itself after 2.5 s. With a view transition the header is
   the same as on the page before, so it is never held. */
@media (prefers-reduced-motion: no-preference) {
  html.js:not(.rv):not(:active-view-transition) .faixa[data-faixa="topo"] {
    background-image: none;
    animation: faixa-rede 1ms 2.5s forwards;
  }
}
@keyframes faixa-rede { to { background-image: var(--faixa-img); } }

/* ---------- 3. along the page: each kind of content its own reveal ----------
   .is-espera  hidden, waiting to be seen (set by site.js, never on a photograph already on screen)
   .is-revelar the reveal is running; site.js removes it at the end so the element's own transitions come back */
@media (prefers-reduced-motion: no-preference) {
  /* photograph: opens from the top, inside its place; the block, the red quarter and the band stay still */
  .rv [data-revela="foto"].is-espera img,
  .rv img[data-revela="foto"].is-espera { clip-path: inset(0 0 100% 0); }
  .rv [data-revela="foto"].is-revelar img,
  .rv img[data-revela="foto"].is-revelar {
    clip-path: inset(0);             /* an inset to an inset: "none" cannot be interpolated and would jump */
    transition: clip-path var(--dur-photo-reveal) var(--ease-in-out);
  }

  /* list: items one after another (--atraso from site.js: 55 ms apart, 440 ms at most) */
  .rv [data-revela="lista"].is-espera > * { opacity: 0; transform: translateY(10px); }
  .rv [data-revela="lista"].is-revelar > * {
    transition: opacity 400ms var(--ease-out), transform var(--dur-reveal) var(--ease-out);
    transition-delay: var(--atraso, 0ms);
  }

  /* number: rises into its slot once (site.js wraps it in .numero-janela > .numero-tira) */
  .rv [data-revela="numero"].is-espera .numero-tira { transform: translateY(100%); }
  .rv [data-revela="numero"].is-revelar .numero-tira { transition: transform var(--dur-reveal) var(--ease-out); }

  /* block: lifts into place */
  .rv [data-revela="bloco"].is-espera { opacity: 0; transform: translateY(16px); }
  .rv [data-revela="bloco"].is-revelar { transition: opacity 400ms var(--ease-out), transform var(--dur-reveal) var(--ease-out); }

  /* band: laid tile by tile. The top row comes down, the bottom row comes up, like azulejos set into mortar. */
  .rv .faixa.is-espera { background-image: none; }
  .faixa-peca { clip-path: inset(0 0 100% 0); transition: clip-path var(--dur-tile) var(--ease-out); transition-delay: var(--d, 0ms); }
  .faixa-peca[data-r="1"] { clip-path: inset(100% 0 0 0); }
  .faixa.is-montar .faixa-peca { clip-path: inset(0); }

  /* the now marker of the hours waits off screen, then slides from the start of today's row to the time (WAAPI) */
  .rv .regua-agora.is-espera { opacity: 0; }
}
.numero-janela { display: inline-block; clip-path: inset(0 -0.25em); }
.numero-tira { display: inline-block; }
.faixa-pecas { position: absolute; inset: 0; pointer-events: none; }
.faixa-peca { position: absolute; background-image: var(--faixa-img); background-repeat: repeat-x; }

@media (prefers-reduced-motion: reduce) {
  /* everything that waits appears with a short fade, nothing travels */
  .rv .is-espera { opacity: 0; }
  .rv .is-revelar { transition: opacity var(--dur-fade-reduced) ease; }
  .js [data-entra="linhas"]:not(.is-espera) { animation: esmaece var(--dur-fade-reduced) ease both; }
}
@keyframes esmaece { from { opacity: 0; } }

/* ---------- 4. touch and pointer ----------
   .btn, the phone bar and the header buttons already press at .97 in site.css. */
@media (prefers-reduced-motion: no-preference) {
  .ligacao {
    transition: text-decoration-color var(--dur-hover) ease, color var(--dur-hover) ease, scale var(--dur-press) var(--ease-out);
  }
  .ligacao:active { scale: .97; }
  .btn .ic { transition: transform var(--dur-hover) var(--ease-out); }
}
@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
  /* the navigation underline draws from the left on hover and leaves faster than it came */
  .cabecalho-nav a:not([aria-current])::after {
    background: var(--color-text);
    transform: scaleX(0); transform-origin: left center;
    transition: transform var(--dur-exit) var(--ease-out);
  }
  .cabecalho-nav a:not([aria-current]):hover::after { transform: none; transition-duration: var(--dur-micro); }
  /* an arrow nudges towards where it goes */
  :is(.ligacao, .btn):hover .ic:has(use[href$="#arrow-right"]) { transform: translateX(3px); }
  :is(.ligacao, .btn):hover .ic:has(use[href$="#arrow-left"]) { transform: translateX(-3px); }
  :is(.ligacao, .btn):hover .ic:has(use[href$="#arrow-up-right"]) { transform: translate(2px, -2px); }
}

/* ---------- 5. print: everything in place ---------- */
@media print {
  .rv .is-espera, .rv .is-espera > *, .rv .is-espera img, .rv .is-espera .numero-tira, .rv .is-espera .linha > span {
    opacity: 1 !important; transform: none !important; clip-path: none !important;
  }
  .rv .faixa.is-espera { background-image: var(--faixa-img) !important; }
  .faixa-pecas { display: none; }
}
