/* ============================================================
   YAGO RANZE — Tattoo Artist
   Hero + Nav
   ============================================================ */

/* ---------- Reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

img { display: block; max-width: 100%; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

a { color: inherit; text-decoration: none; }

ul { list-style: none; }

/* ---------- Tokens ---------- */
:root {
  --ink:            #050505;
  --paper:          #f2f2f0;
  /* Texto, do mais forte ao mais apagado */
  --paper-dim:      rgba(242, 242, 240, 0.62);   /* texto secundario */
  --paper-ghost:    rgba(242, 242, 240, 0.44);   /* titulo grande em repouso */
  --paper-faint:    rgba(242, 242, 240, 0.34);   /* rotulo terciario, dica */
  --paper-whisper:  rgba(242, 242, 240, 0.08);   /* marca dagua gigante */

  /* Filetes, do mais visivel ao mais discreto */
  --hairline-hi:    rgba(242, 242, 240, 0.62);   /* borda de pill no hover */
  --hairline:       rgba(242, 242, 240, 0.28);   /* borda de pill em repouso */
  --rule-strong:    rgba(242, 242, 240, 0.22);   /* sublinhado de campo */
  --rule:           rgba(242, 242, 240, 0.14);   /* filete entre linhas */
  --rule-soft:      rgba(242, 242, 240, 0.08);   /* divisor entre dobras */

  --chip:           #121212;                     /* preenchimento escuro de pill */

  --nav-h:          clamp(64px, 7vw, 84px);
  --gutter:         clamp(20px, 3.6vw, 56px);

  /* 11px de minimo, nao 10: em caixa alta e espacado, 10px fica ilegivel
     no celular, que e onde o clamp encosta no minimo. */
  --micro:          clamp(11px, 0.78vw, 12px);   /* nav / rotulos */

  /* --- Escala tipografica: todo font-size do site sai daqui --- */
  --fs-brand:    clamp(13px, 1.15vw, 17px);         /* marca na nav */
  --fs-note:     clamp(0.92rem, 1.05vw, 1.08rem);   /* notas, contatos, preview */
  --fs-body:     clamp(0.95rem, 1.15vw, 1.18rem);   /* corpo: passos, respostas */
  --fs-input:    clamp(1rem, 1.25vw, 1.25rem);      /* campos do formulario */
  --fs-sm:       clamp(0.98rem, 1.38vw, 1.35rem);   /* titulo pequeno: aba, cidade */
  --fs-num:      clamp(1.1rem, 1.5vw, 1.6rem);      /* numero do passo */
  --fs-country:  clamp(1.05rem, 2vw, 2rem);         /* pais sob a cidade */
  --fs-md:       clamp(1.25rem, 2.2vw, 2.25rem);    /* frase da galeria */
  --fs-lg:       clamp(1.45rem, 2.75vw, 2.6rem);    /* pergunta do FAQ, titulo de passo */
  --fs-2xl:      clamp(1.5rem, 3vw, 3rem);          /* texto da apresentacao */
  --fs-xl:       clamp(1.65rem, 3.4vw, 3.4rem);     /* nome do passo, frase do rodape */
  --fs-menu:     clamp(2.2rem, 11vw, 3.6rem);       /* menu mobile */
  --fs-roll:     clamp(1.6rem, 5.4vw, 5.5rem);      /* rolo de termos */
  --fs-city:     clamp(3rem, 7.6vw, 8rem);          /* cidade em destaque */
  --display:      clamp(3.6rem, 10.2vw, 11.5rem);  /* nome no hero */

  --ease:           cubic-bezier(0.22, 1, 0.36, 1);   /* hovers — snappy */
  --ease-cine:      cubic-bezier(0.16, 1, 0.3, 1);    /* long, soft settle */
  --ease-dimmer:    cubic-bezier(0.45, 0, 0.25, 1);   /* light coming up */
}

/* ---------- Base ---------- */
body {
  background: var(--ink);
  color: var(--paper);
  font-family: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-variation-settings: "wdth" 100, "wght" 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* clip, not hidden: `hidden` turns body into a scroll container and breaks
     the sticky hero. `clip` contains overflow without that side effect. */
  overflow-x: clip;
}

body.is-locked { overflow: hidden; }

/* --------------------------------------------------------------
   MICRO-LABEL — a receita de rotulo pequeno do site inteiro.
   Toda etiqueta em caixa alta espacada usa uma destas duas regras;
   nao repita as cinco declaracoes em cada bloco.
   -------------------------------------------------------------- */
.nav__brand,
.nav__links a,
.nav__cta,
.hero__loc,
.hero__tour,
.mobile-menu__loc,
.mobile-menu__cta,
.intro__label,
.roll__label,
.steps__title,
.where__title,
.feature__when,
.faq__title,
.booking__badge,
.field__label,
.booking__back,
.booking__next,
.footer__label,
.chips a,
.footer__legal {
  font-size: var(--micro);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  line-height: 1;
}

/* Mesma receita, peso menor: usada quando o rotulo acompanha outro
   elemento mais forte e nao pode competir com ele. */
.tab__date,
.choice__when,
.booking__error,
.footer__hint {
  font-size: var(--micro);
  font-variation-settings: "wdth" 100, "wght" 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  line-height: 1;
}

/* ============================================================
   NAV
   ============================================================ */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  height: var(--nav-h);
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  isolation: isolate;
}

/* Liquid glass — a blurred, saturated dark pane that fades in once you scroll.
   Kept on a pseudo-element so the nav's own children stay crisp above it. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(9, 9, 9, 0.5);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid var(--rule-soft);
  /* top highlight — the sliver of light that sells the glass */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
  opacity: 0;
  transition: opacity 0.55s var(--ease);
}

.nav.is-scrolled::before { opacity: 1; }

/* No backdrop-filter (older Firefox) — fall back to a solid dark pane so the
   nav is still legible instead of transparent over the photo. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav::before { background: rgba(5, 5, 5, 0.92); }
}

.nav__brand {
  font-size: var(--fs-brand);
  font-variation-settings: "wdth" 96, "wght" 800;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

/* Trademark mark — raised so its cap aligns with the wordmark's cap height.
   vertical-align in em resolves against the mark's own size, so the offset
   holds at every step of the clamp. */
.nav__brand .mark {
  font-size: 0.66em;
  font-variation-settings: "wdth" 100, "wght" 600;
  letter-spacing: 0;
  vertical-align: 0.42em;
  margin-left: 0.12em;
}

.nav__menu {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.4vw, 38px);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2vw, 34px);
}

.nav__links a {
  position: relative;
  color: var(--paper-dim);
  padding-block: 6px;
  transition: color 0.35s var(--ease);
}

.nav__links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.45s var(--ease);
}

.nav__links a:hover,
.nav__links a:focus-visible { color: var(--paper); }

.nav__links a:hover::after,
.nav__links a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.nav__cta {
  padding: 0.95em 1.55em;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: transparent;
  white-space: nowrap;
  transition: background-color 0.4s var(--ease),
              border-color 0.4s var(--ease),
              box-shadow 0.4s var(--ease);
}

/* Hover keeps the pill dark — the border lifts and the fill deepens */
.nav__cta:hover,
.nav__cta:focus-visible {
  background: var(--chip);
  border-color: var(--hairline-hi);
  box-shadow: 0 0 0 1px rgba(5, 5, 5, 0.6), 0 8px 26px rgba(0, 0, 0, 0.45);
}

/* Hamburger — mobile only */
.nav__toggle {
  display: none;
  width: 30px;
  height: 30px;
  position: relative;
  flex: none;
}

.nav__toggle span {
  position: absolute;
  left: 3px;
  width: 24px;
  height: 1.5px;
  background: var(--paper);
  transition: transform 0.45s var(--ease), opacity 0.25s linear;
}

.nav__toggle span:nth-child(1) { top: 11px; }
.nav__toggle span:nth-child(2) { top: 18px; }

.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

/* ============================================================
   MOBILE MENU
   ============================================================ */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--ink);
  padding: calc(var(--nav-h) + 8vh) var(--gutter) calc(var(--gutter) + 8px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease), visibility 0.5s;
}

.mobile-menu.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.mobile-menu ul { display: flex; flex-direction: column; gap: 2px; }

.mobile-menu ul a {
  display: block;
  padding: 0.18em 0;
  font-size: var(--fs-menu);
  font-variation-settings: "wdth" 96, "wght" 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
}

.mobile-menu__cta {
  align-self: flex-start;
  margin-top: 40px;
  padding: 1.1em 2em;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--chip);
}

.mobile-menu__loc { margin-top: 32px; color: var(--paper-dim); }

/* ============================================================
   HERO
   ============================================================ */
/* Bounds the hero's sticky range — it releases once the intro has passed */
.stage { position: relative; }

/* Pinned, so the next section slides up over it while it plays its exit */
.hero {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  overflow: hidden;
  background: var(--ink);
}

.hero__media {
  position: absolute;
  inset: 0;
}

/* Every intro animation declares its resting state in the base rule and its
   "off" state at 0%, with fill-mode backwards. Killing the animation
   (reduced motion, no support) therefore lands on the finished look. */
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 32%;
  filter: grayscale(1) contrast(1.06) brightness(1);
  transform: scale(1);
  animation: houseLights 4.2s var(--ease-dimmer) 0.35s backwards;
}

/* Lights coming up on the subject */
@keyframes houseLights {
  0%   { filter: grayscale(1) contrast(1.06) brightness(0.06); transform: scale(1.09); }
  55%  { filter: grayscale(1) contrast(1.14) brightness(0.72); }
  100% { filter: grayscale(1) contrast(1.06) brightness(1);    transform: scale(1); }
}

/* --- Stage light: a dark cover with a soft hole that opens over the face --- */
@property --beam      { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
@property --beam-edge { syntax: "<percentage>"; inherits: false; initial-value: 200%; }

.hero__light {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    circle at 50% 40%,
    transparent 0%,
    transparent var(--beam),
    var(--ink) var(--beam-edge)
  );
  animation: stageLight 4.2s var(--ease-dimmer) 0.35s backwards;
}

@keyframes stageLight {
  0%   { --beam: 0%;  --beam-edge: 7%;   opacity: 1; }
  30%  { --beam: 9%;  --beam-edge: 30%;  opacity: 1; }
  55%  { --beam: 20%; --beam-edge: 58%;  opacity: 1; }
  100% { --beam: 72%; --beam-edge: 150%; opacity: 0; }
}

/* Legibility scrim — top for the nav, bottom for the wordmark */
.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(5,5,5,0.55) 0%, rgba(5,5,5,0) 26%),
    linear-gradient(to top,    rgba(5,5,5,0.78) 0%, rgba(5,5,5,0) 52%);
}

/* Film grain */
.grain {
  position: absolute;
  inset: -50%;
  pointer-events: none;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainShift 0.6s steps(3) infinite;
}

@keyframes grainShift {
  0%   { transform: translate(0, 0); }
  33%  { transform: translate(-2%, 1.5%); }
  66%  { transform: translate(1.5%, -2%); }
  100% { transform: translate(0, 0); }
}

.hero__inner {
  position: relative;
  z-index: 10;
  width: 100%;
  padding: var(--nav-h) var(--gutter) calc(var(--gutter) + 4px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: clamp(24px, 4vh, 52px);
}

/* --- Display wordmark --- */
.hero__name {
  display: flex;
  flex-direction: column;
  font-size: var(--display);
  font-variation-settings: "wdth" 104, "wght" 800;
  text-transform: uppercase;
  letter-spacing: -0.048em;
  line-height: 0.82;
  margin-left: -0.045em; /* optically align the round cap to the gutter */
}

.hero__name .line { display: block; padding-bottom: 0.04em; }

/* Same trick at display scale: small, lighter, cap-aligned to the big letters */
.hero__name .mark {
  font-size: 0.17em;
  font-variation-settings: "wdth" 100, "wght" 600;
  letter-spacing: 0;
  vertical-align: 3.35em;
  margin-left: 0.5em;
}

.hero__name .line__in {
  display: block;
  opacity: 1;
  filter: blur(0px);
  transform: none;
  will-change: filter, opacity, transform;
  animation: focusIn 3s var(--ease-cine) backwards;
}

.hero__name .line:nth-child(1) .line__in { animation-delay: 1.5s; }
.hero__name .line:nth-child(2) .line__in { animation-delay: 1.85s; }

/* Out of focus and dim, then it settles */
@keyframes focusIn {
  0%   { opacity: 0; filter: blur(34px); transform: translateY(18px) scale(1.035); }
  45%  { opacity: 0.85; }
  100% { opacity: 1; filter: blur(0px);  transform: none; }
}

/* --- Footer row --- */
.hero__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  animation: fadeUp 1.4s var(--ease-cine) 3.4s backwards;
}

/* Tour line — pairs with the location at the same weight, so the two read as
   one row of metadata. nowrap keeps the date list off two lines on mobile. */
.hero__tour { white-space: nowrap; }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

/* Nav arrives once the lights are up */
.nav { animation: fadeUp 1.3s var(--ease-cine) 3s backwards; }

/* ============================================================
   HERO EXIT — the intro, played backwards on scroll

   JS writes --ex-* on .hero from scroll position. These rules only take
   over once .is-intro-done is set (on the body), because until then the
   intro @keyframes own the same properties and would win the cascade.
   ============================================================ */
.is-intro-done .hero__media img {
  animation: none;
  filter: grayscale(1) contrast(1.06) brightness(var(--ex-bright, 1));
  transform: scale(var(--ex-scale, 1));
}

.is-intro-done .hero__light {
  animation: none;
  --beam: var(--ex-beam, 72%);
  --beam-edge: var(--ex-beam-edge, 150%);
  opacity: var(--ex-light, 0);
}

.is-intro-done .hero__name .line__in {
  animation: none;
  opacity: var(--ex-text, 1);
  filter: blur(var(--ex-blur, 0px));
  transform: translateY(var(--ex-y, 0px));
}

.is-intro-done .hero__foot,
.is-intro-done .hero__name .mark {
  animation: none;
  opacity: var(--ex-text, 1);
}

/* ============================================================
   INTRO — second fold
   ============================================================ */
.intro {
  position: relative;
  z-index: 20;               /* rides over the pinned hero */
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: calc(var(--nav-h) + 6vh) var(--gutter) 12vh;
  background: var(--ink);
  border-top: 1px solid var(--rule-soft);
}

.intro__inner {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(24px, 5vw, 80px);
}

/* Coluna direita: rotulo + video vertical. O 9:16 ocupa exatamente o vazio
   que essa dobra tinha antes, sem empurrar nada. */
.intro__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: clamp(12px, 2vh, 20px);
}

/* Dimensionado pela ALTURA, nao pela largura: e a altura que briga com a
   dobra de 100svh num video vertical. A largura sai da proporcao. */
.intro__video {
  position: relative;
  /* clamp, nao min: em notebook de tela baixa um `min(vh)` puro encolhe o
     video a ponto de ele virar miniatura. O piso segura a presenca. */
  height: clamp(340px, 62vh, 580px);
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: #0d0d0d;
  border: 1px solid var(--rule);
}

.intro__video video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Botao de som — mesmo vidro do selo do formulario */
.video__sound {
  position: absolute;
  left: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: rgba(5, 5, 5, 0.62);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  border-top: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
  color: var(--paper);
  transition: background-color 0.35s var(--ease);
}

.video__sound:hover { background: rgba(5, 5, 5, 0.82); }

/* Alto-falante: um triangulo com a onda cortada quando esta mudo */
.video__sound-icon {
  position: relative;
  width: 9px;
  height: 9px;
  border-left: 3px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  flex: none;
}

.video__sound-icon::after {
  content: "";
  position: absolute;
  left: 1px;
  top: 50%;
  width: 9px;
  height: 1px;
  background: currentColor;
  transform: translateY(-50%) rotate(-45deg);
  transform-origin: left center;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}

/* Som ligado: a barra do "mudo" gira pra fora e some */
.video__sound[aria-pressed="true"] .video__sound-icon::after {
  opacity: 0;
  transform: translateY(-50%) rotate(0deg) scaleX(0);
}

.video__sound-text {
  font-size: var(--micro);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  line-height: 1;
}

/* O video entra junto com a copy */
.js .intro__aside { opacity: 0; filter: blur(12px); transform: translateY(16px); }

.js .intro__text.is-revealed ~ .intro__aside {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 1.1s var(--ease-cine) 0.15s,
              filter 1.2s var(--ease-cine) 0.15s,
              transform 1.2s var(--ease-cine) 0.15s;
}

.intro__text {
  max-width: 100%;
  font-size: var(--fs-2xl);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.28;
  letter-spacing: -0.018em;
  text-wrap: pretty;         /* avoids a lone word on the last line */
}

.intro__label {
  color: var(--paper-dim);
  white-space: nowrap;
}

/* ============================================================
   WORD REVEAL — reusable; any .words element gets it
   ============================================================ */
.words .word { display: inline-block; will-change: filter, opacity, transform; }

/* The hidden state is applied only once JS is running, so the copy stays
   readable if the script never loads. */
.js .words .word {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(12px);
}

.js .words.is-revealed .word {
  animation: wordIn 1.2s var(--ease-cine) forwards;
  animation-delay: calc(var(--i) * 42ms);
}

@keyframes wordIn {
  to { opacity: 1; filter: blur(0px); transform: none; }
}

/* ============================================================
   WORKS — text roll
   ============================================================ */
.works { position: relative; z-index: 20; background: var(--ink); }

/* Tall parent = the scroll runway the pinned panel plays across */
.roll { height: 250svh; }

.roll__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 4vh, 44px);
  padding: var(--nav-h) var(--gutter);
  text-align: center;
}

.roll__label {
  color: var(--paper-dim);
}

.roll__lines {
  font-size: var(--fs-roll);
  font-variation-settings: "wdth" 100, "wght" 300;
  letter-spacing: -0.02em;
  line-height: 1.24;
}

/* The mask: exactly one line tall, so only one term shows at a time */
.roll__line {
  display: block;
  height: 1.24em;   /* === line-height, so the window is one line */
  overflow: hidden;
}

.roll__stack {
  display: block;
  /* two terms stacked; -50% of the stack is exactly one term */
  transform: translateY(calc(var(--r, 0) * -50%));
  will-change: transform;
}

.roll__stack > span { display: block; white-space: nowrap; }

/* ============================================================
   WORKS — pinned quote with the gallery passing over it
   ============================================================ */
.works__body { position: relative; }

.works__pin {
  position: sticky;
  top: 0;
  z-index: 1;
  height: 100svh;
  display: grid;
  place-items: center;
  padding: var(--nav-h) var(--gutter);
}

.works__quote {
  max-width: min(60ch, 62%);
  font-size: var(--fs-md);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.35;
  letter-spacing: -0.012em;
  text-align: center;
  text-wrap: pretty;
}

.gallery {
  position: relative;
  z-index: 2;          /* passes in front of the pinned quote */
  display: flex;
  flex-direction: column;
  gap: clamp(70px, 14vh, 170px);
  padding: 0 var(--gutter) 18vh;
}

.work {
  position: relative;
  width: min(47%, 640px);
  aspect-ratio: var(--ratio, 4 / 3);
  overflow: hidden;
  background: #0d0d0d;
}

.work--left { align-self: flex-start; }
.work--right { align-self: flex-end; }
.work--center { align-self: center; }

.work img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Marked by JS when the file isn't there yet — reveals the placeholder */
.work.is-empty img { display: none; }

/* Placeholder sits behind the image, so it simply disappears once a real
   file exists at that path. */
.work__ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule);
  font-size: var(--micro);
  font-variation-settings: "wdth" 100, "wght" 600;
  letter-spacing: 0.06em;
  color: var(--paper-faint);
}

/* Gallery items rise in — subtle, so it doesn't fight the pinned quote */
.js .work { opacity: 0; transform: translateY(34px); }

.js .work.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity 1s var(--ease-cine), transform 1.1s var(--ease-cine);
}

/* ============================================================
   COMO FUNCIONA — numbered steps
   ============================================================ */
.steps {
  position: relative;
  z-index: 20;
  background: var(--ink);
  padding: 16vh var(--gutter) 18vh;
}

.steps__title {
  color: var(--paper-dim);
  margin-bottom: clamp(40px, 7vh, 90px);
}

.steps__list { list-style: none; }

.step {
  position: relative;
  display: grid;
  /* Third column is a fixed band, so the copy ends flush with the right
     gutter instead of trailing off mid-row */
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 30rem);
  align-items: start;
  gap: clamp(20px, 4vw, 64px);
  padding: clamp(28px, 4.5vh, 52px) 0;
}

/* The rule draws itself in rather than being there already */
.step::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--rule);
  transform: scaleX(0);
  transform-origin: left;
}

.js .step.is-revealed::before {
  transform: scaleX(1);
  transition: transform 1.1s var(--ease-cine);
}

/* Zine page number: large, set back, never competing with the step name */
.step__num {
  font-size: var(--fs-num);
  font-variation-settings: "wdth" 100, "wght" 700;
  letter-spacing: 0.04em;
  line-height: 1.1;
  color: var(--paper-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 0.28em;   /* optically level with the step name's cap */
}

.step__name {
  font-size: var(--fs-xl);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: -0.028em;
  line-height: 1;
}

.step__desc {
  font-size: var(--fs-body);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.5;
  color: var(--paper-dim);
  text-wrap: pretty;
  padding-top: 0.2em;
}

/* Rows arrive in sequence, in the site's blur-focus language */
.js .step__num,
.js .step__name,
.js .step__desc {
  opacity: 0;
  filter: blur(12px);
  transform: translateY(14px);
}

.js .step.is-revealed .step__num,
.js .step.is-revealed .step__name,
.js .step.is-revealed .step__desc {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 1s var(--ease-cine), filter 1.1s var(--ease-cine),
              transform 1.1s var(--ease-cine);
}

.js .step.is-revealed .step__name { transition-delay: 0.07s; }
.js .step.is-revealed .step__desc { transition-delay: 0.14s; }

/* ============================================================
   ONDE EU ATENDO
   ============================================================ */
.where {
  position: relative;
  z-index: 20;
  background: var(--ink);
  padding: 13vh var(--gutter) 0;
  border-top: 1px solid var(--rule-soft);
}

.where__title {
  color: var(--paper-dim);
  margin-bottom: clamp(28px, 4vh, 56px);
}

.where__stage {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 88px);
  padding-bottom: clamp(48px, 8vh, 110px);
}

/* No aspect-ratio here: the canvas carries its own size (set by globe.js),
   and giving the box its own square would make the two define each other. */
.where__globe {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
}

.where__globe canvas {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Radar ping over the selected city. It sits at the centre of the disc
   because that is exactly where the globe parks whatever city is chosen —
   no 3D projection needed. --settled is written by globe.js and stays 0
   while the sphere is still turning. */
/* Two layers on purpose: the wrapper carries the --settled gate, the
   pseudo-element carries the pulse. Putting both on one element would let
   the animation's own opacity override the gate. */
.globe__ping {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  pointer-events: none;
  opacity: var(--settled, 0);
}

.globe__ping::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--paper);
  animation: ping 2.6s var(--ease-cine) infinite;
}

@keyframes ping {
  0%   { transform: scale(0.55); opacity: 0.85; }
  70%  { transform: scale(5); opacity: 0; }
  100% { transform: scale(5); opacity: 0; }
}

/* --- Featured city --- */
/* Without JS the panels simply stack and read as a list. With JS they share
   one grid cell so the box never resizes between cities. */
.js .where__feature { display: grid; }
.js .where__feature > .feature { grid-area: 1 / 1; }

.feature + .feature { margin-top: 8vh; }
.js .feature + .feature { margin-top: 0; }

.js .feature { opacity: 0; visibility: hidden; }
.js .feature.is-active { opacity: 1; visibility: visible; }

.feature__when {
  display: block;
  color: var(--paper-dim);
  font-variant-numeric: tabular-nums;
  margin-bottom: clamp(12px, 2vh, 22px);
}

.feature__city {
  font-size: var(--fs-city);
  font-variation-settings: "wdth" 102, "wght" 800;
  text-transform: uppercase;
  letter-spacing: -0.045em;
  line-height: 0.9;
  margin-left: -0.035em; /* optical alignment, same as the hero wordmark */
}

.feature__country {
  display: block;
  font-size: var(--fs-country);
  font-variation-settings: "wdth" 100, "wght" 300;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--paper-dim);
  margin-top: clamp(8px, 1.4vh, 16px);
}

.feature__note {
  max-width: 34ch;
  margin-top: clamp(16px, 2.6vh, 30px);
  font-size: var(--fs-note);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.5;
  color: var(--paper-dim);
  text-wrap: pretty;
}

/* Swapping cities re-runs the site's focus-in, so the change reads as a
   cut rather than a crossfade. Gated on the section having been reached,
   otherwise it would fire on page load far below the fold. */
.js .where.is-revealed .feature.is-active > * {
  animation: focusSwap 0.85s var(--ease-cine) both;
}

.js .where.is-revealed .feature.is-active .feature__city { animation-delay: 0.05s; }
.js .where.is-revealed .feature.is-active .feature__country { animation-delay: 0.11s; }
.js .where.is-revealed .feature.is-active .feature__note { animation-delay: 0.17s; }

@keyframes focusSwap {
  from { opacity: 0; filter: blur(16px); transform: translateY(14px); }
  to   { opacity: 1; filter: blur(0px);  transform: none; }
}

/* --- Tab strip --- */
.where__tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--rule);
}

.tab {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: clamp(20px, 3vh, 34px) 0 clamp(24px, 4vh, 44px);
  text-align: left;
  color: inherit;
}

/* Active marker rides the rule above the tab */
.tab::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--paper);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--ease);
}

.tab.is-active::before { transform: scaleX(1); }

.tab__city {
  font-size: var(--fs-sm);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: -0.012em;
  line-height: 1;
  color: var(--paper-ghost);
  transition: color 0.4s var(--ease);
}

.tab__date {
  color: var(--paper-faint);
  font-variant-numeric: tabular-nums;
  transition: color 0.4s var(--ease);
}

.tab.is-active .tab__city,
.tab:hover .tab__city,
.tab:focus-visible .tab__city { color: var(--paper); }

.tab.is-active .tab__date { color: var(--paper-dim); }

/* No WebGL (or the script never ran): drop the globe, let the panels stack
   as a plain list, and stand the tabs down — no affordance for something
   that cannot respond. */
.no-globe .where__globe { display: none; }
.no-globe .where__stage { grid-template-columns: minmax(0, 1fr); }
.no-globe .where__tabs { display: none; }

/* Section arrives in the site's blur-focus language */
.js .where__stage,
.js .where__tabs { opacity: 0; }

.js .where.is-revealed .where__stage,
.js .where.is-revealed .where__tabs {
  opacity: 1;
  transition: opacity 1s var(--ease-cine);
}

.js .where.is-revealed .where__tabs { transition-delay: 0.2s; }

/* ============================================================
   DÚVIDAS — acordeão
   ============================================================ */
.faq {
  position: relative;
  z-index: 20;
  background: var(--ink);
  padding: 15vh var(--gutter) 17vh;
  border-top: 1px solid var(--rule-soft);
}

.faq__title {
  color: var(--paper-dim);
  margin-bottom: clamp(32px, 5vh, 64px);
}

.qa { border-bottom: 1px solid var(--rule); }
.qa:first-child { border-top: 1px solid var(--rule); }

.qa__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 4vw, 60px);
  padding: clamp(22px, 3.4vh, 40px) 0;
  text-align: left;
  color: inherit;
}

.qa__text {
  font-size: var(--fs-lg);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: -0.026em;
  line-height: 1.05;
  /* dim until opened — the open question carries the eye */
  color: var(--paper-ghost);
  transition: color 0.45s var(--ease);
}

.qa__q:hover .qa__text,
.qa__q:focus-visible .qa__text { color: rgba(242, 242, 240, 0.78); }
.qa.is-open .qa__text { color: var(--paper); }

/* Plus that becomes a minus — two bars, one folds away */
.qa__mark {
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
}

.qa__mark::before,
.qa__mark::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1px;
  margin-top: -0.5px;
  background: var(--paper-dim);
  transition: transform 0.45s var(--ease), background-color 0.45s var(--ease);
}

.qa__mark::after { transform: rotate(90deg); }
.qa.is-open .qa__mark::after { transform: rotate(0deg); }

.qa.is-open .qa__mark::before,
.qa.is-open .qa__mark::after { background: var(--paper); }

/* Height is animated from a measured value written by main.js — `auto`
   is not an animatable height, and a fixed max-height guess either clips
   long answers or leaves dead time on short ones. */
.qa__a {
  overflow: hidden;
  height: 0;
}

.js .qa__a { transition: height 0.55s var(--ease-cine); }

.qa__a p {
  max-width: 62ch;
  padding: 0 0 clamp(26px, 4vh, 44px);
  font-size: var(--fs-body);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.55;
  color: var(--paper-dim);
  text-wrap: pretty;
  opacity: 0;
  filter: blur(10px);
  transform: translateY(10px);
}

.js .qa.is-open .qa__a p {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 0.7s var(--ease-cine) 0.12s,
              filter 0.8s var(--ease-cine) 0.12s,
              transform 0.8s var(--ease-cine) 0.12s;
}

/* No JS: [hidden] is gone from the markup by then, so make sure the answers
   simply show rather than staying collapsed at height 0. */
html:not(.js) .qa__a { height: auto; }
html:not(.js) .qa__a p { opacity: 1; filter: none; transform: none; }

/* Section arrives in the site's blur-focus language */
.js .qa { opacity: 0; filter: blur(12px); transform: translateY(14px); }

.js .qa.is-revealed {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 1s var(--ease-cine), filter 1.1s var(--ease-cine),
              transform 1.1s var(--ease-cine);
}

/* ============================================================
   AGENDAMENTO — formulário em passos
   ============================================================ */
.booking {
  position: relative;
  z-index: 20;
  background: var(--ink);
  padding: 13vh var(--gutter) 15vh;
  border-top: 1px solid var(--rule-soft);
}

.booking__frame {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
  border: 1px solid var(--rule);
  overflow: hidden;
  min-height: min(660px, 78vh);
}

/* --- Photo side --- */
.booking__media { position: relative; overflow: hidden; }

.booking__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 42% 50%;
  /* Sem filtro de propósito: aqui a foto vale mais crua, é a dobra onde a
     pessoa decide mandar mensagem. Único ponto de cor da página. */
  /* slow drift keeps the panel from reading as a flat plate */
  transform: scale(1.06);
  animation: mediaDrift 26s ease-in-out infinite alternate;
}

@keyframes mediaDrift {
  from { transform: scale(1.06) translate(0, 0); }
  to   { transform: scale(1.12) translate(-1.6%, -1.2%); }
}

.booking__badge {
  position: absolute;
  left: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  background: rgba(5, 5, 5, 0.62);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  border-top: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
}

/* Same odometer trick as the works roll, reused for the step number */
.badge__num {
  display: block;
  height: 1em;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

.badge__roll {
  display: block;
  transform: translateY(calc(var(--s, 0) * -25%));
  transition: transform 0.6s var(--ease-cine);
}

.badge__roll i { display: block; height: 1em; font-style: normal; }

.badge__label { color: var(--paper-dim); }

/* --- Form side --- */
.booking__form {
  display: flex;
  flex-direction: column;
  padding: clamp(26px, 4vw, 56px);
  border-left: 1px solid var(--rule);
}

.booking__progress {
  display: grid;
  grid-auto-flow: column;
  gap: 6px;
  list-style: none;
  margin-bottom: clamp(26px, 5vh, 54px);
}

.booking__progress li {
  height: 2px;
  background: var(--rule);
  overflow: hidden;
}

.booking__progress li::after {
  content: "";
  display: block;
  height: 100%;
  background: var(--paper);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.6s var(--ease-cine);
}

.booking__progress li.is-done::after { transform: scaleX(1); }

/* Panels share one grid cell so the box never jumps between steps */
.step-panel { border: 0; }

.js .booking__stack { display: grid; align-content: start; }

.js .booking__stack > .step-panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.js .booking__stack > .step-panel.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.step-panel + .step-panel { margin-top: 8vh; }
.js .step-panel + .step-panel { margin-top: 0; }

.step-panel__title {
  padding: 0;
  font-size: var(--fs-lg);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: -0.028em;
  line-height: 1;
}

.step-panel__sub {
  margin: 12px 0 clamp(26px, 4vh, 40px);
  font-size: var(--fs-note);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.5;
  color: var(--paper-dim);
}

/* Each element of the active panel focuses in, staggered */
.js .booking.is-revealed .step-panel.is-active > * {
  animation: focusSwap 0.7s var(--ease-cine) both;
}

.js .step-panel.is-active > *:nth-child(2) { animation-delay: 0.05s; }
.js .step-panel.is-active > *:nth-child(3) { animation-delay: 0.1s; }
.js .step-panel.is-active > *:nth-child(4) { animation-delay: 0.15s; }

/* --- Fields --- */
/* Underlines, not boxes: the whole site is built on hairlines, and a rounded
   input would read as borrowed from somewhere else. */
.field { display: block; margin-bottom: clamp(20px, 3vh, 30px); }

.field__label {
  display: block;
  margin-bottom: 10px;
  color: var(--paper-dim);
}

.field input,
.field textarea {
  width: 100%;
  padding: 0 0 12px;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  color: var(--paper);
  font: inherit;
  font-size: var(--fs-input);
  font-variation-settings: "wdth" 100, "wght" 400;
  line-height: 1.4;
  resize: vertical;
  transition: border-color 0.4s var(--ease);
}

.field input::placeholder,
.field textarea::placeholder { color: var(--paper-faint); }

.field input:focus,
.field textarea:focus { outline: none; border-bottom-color: var(--paper); }

.field.has-error input,
.field.has-error textarea { border-bottom-color: #ff6b5a; }

.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2vw, 28px); }

/* --- City choices --- */
.choices { display: grid; gap: 1px; background: var(--rule); border-block: 1px solid var(--rule); }

.choice {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(14px, 2.2vh, 20px) 0;
  background: var(--ink);
  cursor: pointer;
}

.choice input { position: absolute; opacity: 0; pointer-events: none; }

.choice__city {
  font-size: var(--fs-sm);
  font-variation-settings: "wdth" 100, "wght" 700;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--paper-ghost);
  transition: color 0.35s var(--ease);
}

.choice__when {
  color: var(--paper-faint);
  white-space: nowrap;
  transition: color 0.35s var(--ease);
}

.choice:hover .choice__city { color: rgba(242, 242, 240, 0.75); }

.choice:has(input:checked) .choice__city { color: var(--paper); }
.choice:has(input:checked) .choice__when { color: var(--paper-dim); }

.choice:has(input:focus-visible) { outline: 1px solid var(--hairline-hi); outline-offset: 2px; }

/* --- Review --- */
.preview {
  border: 1px solid var(--rule);
  padding: clamp(18px, 2.6vw, 26px);
  font-size: var(--fs-note);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.65;
  color: var(--paper-dim);
  white-space: pre-wrap;
  max-height: 34vh;
  overflow-y: auto;
}

.preview b {
  font-variation-settings: "wdth" 100, "wght" 700;
  color: var(--paper);
}

/* --- Footer --- */
.booking__error {
  margin-top: 18px;
  color: #ff6b5a;
}

.booking__foot {
  margin-top: auto;
  padding-top: clamp(24px, 4vh, 40px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.booking__back {
  color: var(--paper-dim);
  transition: color 0.35s var(--ease);
}

.booking__back:hover { color: var(--paper); }
.booking__back[hidden] { display: none; }

.booking__next {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 1.05em 1.8em;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--chip);
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease),
              box-shadow 0.4s var(--ease);
}

.booking__next:hover,
.booking__next:focus-visible {
  border-color: var(--hairline-hi);
  box-shadow: 0 0 0 1px rgba(5, 5, 5, 0.6), 0 8px 26px rgba(0, 0, 0, 0.45);
}

.booking__arrow { transition: transform 0.4s var(--ease); }
.booking__next:hover .booking__arrow { transform: translateX(4px); }

/* Section arrives in the site's blur-focus language */
.js .booking__frame { opacity: 0; filter: blur(14px); transform: translateY(16px); }

.js .booking.is-revealed .booking__frame {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 1.1s var(--ease-cine), filter 1.2s var(--ease-cine),
              transform 1.2s var(--ease-cine);
}

/* ============================================================
   RODAPÉ
   ============================================================ */
.footer {
  position: relative;
  z-index: 20;
  background: var(--ink);
  padding: 14vh var(--gutter) 0;
  border-top: 1px solid var(--rule-soft);
  overflow: hidden; /* crops the oversized wordmark */
}

.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 0.8fr);
  align-items: start;
  gap: clamp(32px, 5vw, 80px);
}

.footer__claim {
  max-width: 16ch;
  font-size: var(--fs-xl);
  font-variation-settings: "wdth" 100, "wght" 300;
  letter-spacing: -0.025em;
  line-height: 1.1;
  text-wrap: balance;
}

.footer__label {
  display: block;
  margin-bottom: clamp(16px, 2.4vh, 26px);
  color: var(--paper-dim);
}

/* Pill chips, borrowing the nav CTA's shape so the page closes on the same
   vocabulary it opened with */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chips a {
  display: inline-block;
  padding: 0.75em 1.15em;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--chip);
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

.chips a:hover,
.chips a:focus-visible {
  border-color: var(--hairline-hi);
  box-shadow: 0 0 0 1px rgba(5, 5, 5, 0.6), 0 8px 22px rgba(0, 0, 0, 0.45);
}

.footer__contacts {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: var(--fs-note);
  font-variation-settings: "wdth" 100, "wght" 300;
  line-height: 1.3;
}

.footer__contacts a {
  color: var(--paper-dim);
  border-bottom: 1px solid transparent;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}

.footer__contacts a:hover,
.footer__contacts a:focus-visible {
  color: var(--paper);
  border-bottom-color: var(--hairline);
}

.footer__hint {
  margin-left: 8px;
  color: var(--paper-faint);
}

.footer__legal {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  margin-top: clamp(46px, 8vh, 92px);
  padding-top: clamp(16px, 2.4vh, 24px);
  border-top: 1px solid var(--rule-soft);
  color: var(--paper-faint);
}

/* Oversized wordmark, cropped by the footer's own bottom edge. Pure vw so
   the ten characters keep the same relationship to the gutters at any
   width — a clamp would let it drift off the margins. */
.footer__mark {
  margin-top: clamp(24px, 5vh, 60px);
  margin-bottom: -0.18em; /* the crop */
  /* 14vw, not more: vw counts the scrollbar but the gutter does not, so a
     value tuned on a scrollbar-less page overflows once the page scrolls. */
  font-size: 14vw;
  font-variation-settings: "wdth" 102, "wght" 800;
  text-transform: uppercase;
  letter-spacing: -0.05em;
  line-height: 0.78;
  color: var(--paper-whisper);
  white-space: nowrap;
  user-select: none;
  margin-left: -0.035em; /* optical alignment, same as the hero */
}

/* Section arrives in the site's blur-focus language */
.js .footer__top,
.js .footer__legal { opacity: 0; filter: blur(12px); transform: translateY(14px); }

.js .footer.is-revealed .footer__top,
.js .footer.is-revealed .footer__legal {
  opacity: 1;
  filter: blur(0px);
  transform: none;
  transition: opacity 1s var(--ease-cine), filter 1.1s var(--ease-cine),
              transform 1.1s var(--ease-cine);
}

.js .footer.is-revealed .footer__legal { transition-delay: 0.12s; }

.js .footer__mark { opacity: 0; }

.js .footer.is-revealed .footer__mark {
  opacity: 1;
  transition: opacity 1.4s var(--ease-cine) 0.25s;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 900px) {
  :root {
    /* A taxa de 10.2vw do desktop encosta no minimo abaixo de ~565px e para
       de crescer, o que deixa o nome pequeno demais justamente onde ele
       deveria dominar a tela. Aqui ele ocupa ~80% da largura util. */
    --display: clamp(3.2rem, 21vw, 8.5rem);
  }

  .nav__menu { display: none; }
  .nav__toggle { display: block; }

  .hero__media img { object-position: 50% 24%; }

  .hero__name { letter-spacing: -0.045em; }

  /* Respiro real no rodape do hero: o gutter sozinho (20px no celular)
     colava as duas linhas na borda de baixo. */
  .hero__inner { padding-bottom: clamp(30px, 5.5vh, 60px); }

  .hero__foot { flex-direction: column; align-items: flex-start; gap: 12px; }
  .hero__loc,
  .hero__tour { font-size: 12px; }

  /* Label drops above the copy — no room for a side column */
  .intro__inner { grid-template-columns: 1fr; gap: 26px; }
  .intro__aside { order: -1; align-items: flex-start; }
  .intro__video { height: min(52vh, 460px); }
  .intro__text { max-width: 100%; }

  .works__quote { max-width: 100%; }

  /* One column — the left/right zigzag has no room to read */
  .work,
  .work--left,
  .work--right,
  .work--center { width: 100%; align-self: stretch; }

  /* Number sits above; name and copy stack in one column */
  .step {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    padding: 26px 0;
  }

  .step__num { padding-top: 0; }
  .step__desc { max-width: 100%; padding-top: 4px; }

  /* Globe above the copy — side by side leaves neither enough room */
  .where__stage { grid-template-columns: minmax(0, 1fr); gap: 30px; }
  .where__globe { justify-self: center; }
  .feature__note { max-width: 100%; }

  /* Two rows of tabs instead of four cramped columns */
  .where__tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
  .tab { padding: 20px 0 24px; }
  .tab:nth-child(n + 3) { border-top: 1px solid var(--rule); }

  /* Photo above the form; side by side leaves the fields too narrow */
  .booking__frame { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .booking__media { aspect-ratio: 4 / 3; }
  .booking__form { border-left: 0; border-top: 1px solid var(--rule); }
  .field-row { grid-template-columns: minmax(0, 1fr); }
  .preview { max-height: none; }

  /* Footer stacks; the wordmark grows to keep filling the width */
  .footer__top { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .footer__claim { max-width: 100%; }
  .footer__legal { flex-direction: column; gap: 10px; }
  .footer__mark { font-size: 15.4vw; margin-bottom: -0.2em; }
}

@media (min-width: 901px) {
  .mobile-menu { display: none; }
}

/* ============================================================
   MOTION PREFERENCES
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .hero__media img,
  .hero__name .line__in,
  .hero__foot,
  .nav,
  .grain {
    animation: none !important;
    opacity: 1 !important;
    filter: grayscale(1) contrast(1.06);
    transform: none !important;
  }

  .hero__name .line__in { filter: none; }

  /* The stage light is pure motion — drop it rather than freeze it */
  .hero__light { display: none; }

  /* Copy appears outright; JS also skips the scroll-driven exit here */
  .js .words .word,
  .js .intro__label,
  .js .work,
  .js .where__stage,
  .js .where__tabs,
  .js .feature.is-active > *,
  .js .qa,
  .js .qa__a p,
  .js .booking__frame,
  .js .step-panel.is-active > *,
  .js .booking__media img,
  .js .footer__top,
  .js .footer__legal,
  .js .footer__mark,
  .js .intro__aside,
  .js .step__num,
  .js .step__name,
  .js .step__desc {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
    animation: none !important;
  }

  .js .step::before { transform: scaleX(1) !important; }

  /* Ping holds as a plain ring instead of pulsing */
  .globe__ping::after { animation: none !important; transform: scale(2.2); opacity: 0.75; }

  /* Unmask the roll so all six terms read as a plain list instead of
     depending on a scroll animation that no longer runs */
  .roll { height: auto; }
  .roll__sticky { position: static; height: auto; padding-block: 18vh; }
  .roll__line { height: auto; overflow: visible; }
  .roll__stack { transform: none !important; }

  * { transition-duration: 0.01ms !important; }
}
