/* ============================================================
   Nauta Fisioterapia — Landing Page
   ============================================================ */

:root {
  --cream: #F7EBDF;
  --cream-2: #F1E3D2;
  --white: #FFFFFF;
  --olive: #6E735C;
  --olive-deep: #565A47;
  --olive-darker: #454838;
  --sage: #767D62;
  --sage-deep: #5F6550;
  --caramel: #A56E43;
  --caramel-text: #8C5A36;
  --caramel-deep: #7D4F2E;
  --rose: #BF8969;
  --ink: #4B4F3D;
  --ink-soft: #5C6150;
  --line: rgba(110, 115, 92, 0.16);
  --line-on-dark: rgba(247, 235, 223, 0.24);

  /*
   * Layered, warm-toned shadows — caramel-based (#A56E43 ≈ 165,110,67) instead
   * of near-black, so elevation reads as depth in the brand's own palette
   * rather than generic drop shadow. --shadow-md is the resting/idle state,
   * --shadow-lg is what hover/elevated states grow into.
   */
  --shadow-sm: 0 1px 2px rgba(165, 110, 67, 0.04), 0 2px 4px rgba(165, 110, 67, 0.05);
  --shadow-md: 0 1px 2px rgba(165, 110, 67, 0.04), 0 4px 8px rgba(165, 110, 67, 0.06), 0 16px 32px rgba(165, 110, 67, 0.08);
  --shadow-lg: 0 2px 4px rgba(165, 110, 67, 0.07), 0 8px 20px rgba(165, 110, 67, 0.11), 0 28px 56px rgba(165, 110, 67, 0.16);

  /* Same warm family, deepened — for light UI sitting on the site's dark
     surfaces (mobile menu, floating WhatsApp button), where a pale caramel
     shadow would vanish against a dark backdrop. */
  --shadow-on-dark: 0 16px 40px -18px rgba(90, 51, 24, 0.55), 0 4px 10px rgba(90, 51, 24, 0.3);
  --shadow-on-dark-lg: 0 22px 52px -16px rgba(90, 51, 24, 0.62), 0 6px 14px rgba(90, 51, 24, 0.36);

  /* Deprecated aliases kept for any rule not yet migrated — same warm values */
  --shadow-soft: var(--shadow-lg);
  --shadow-card: var(--shadow-md);
  --shadow-lift: var(--shadow-lg);

  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", serif;
  --font-body: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --container: 1280px;
  --gutter: clamp(1.5rem, 5vw, 4rem);

  /* Section-padding tiers (64 / 96 / 128px). --section-pad is unchanged from
     its existing value — every section already uses this one shared token, so
     the scale was already consistent; these are just named so a section can
     opt into a lighter or heavier rhythm than the default. */
  --space-sm: clamp(3rem, 7vw, 4rem);   /* 64px  */
  --section-pad: clamp(5rem, 10vw, 9rem); /* 96–144px, existing default */
  --space-lg: clamp(6rem, 12vw, 8rem);  /* 128px */

  --radius-sm: 3px;
  --radius-md: 6px;
  --radius-pill: 999px;
  --header-h: 88px;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

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

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

::selection { background: var(--olive); color: var(--cream); }

:focus-visible {
  outline: 2px solid var(--caramel-deep);
  outline-offset: 3px;
  border-radius: 2px;
}

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
}

/* Fine print-like grain, purely decorative, sits above everything but blocks nothing */
.grain {
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 180px 180px;
}

@media (prefers-reduced-motion: reduce) {
  .grain { display: none; }
}

.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--caramel-text);
  margin: 0 0 1rem;
}

h1, h2, h3 {
  font-family: var(--font-display);
  color: var(--olive);
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
  letter-spacing: -0.015em;
}

h1 em, h2 em {
  font-style: italic;
  color: var(--caramel-deep);
}

h2 {
  font-size: clamp(2rem, 1.3rem + 2.6vw, 3rem);
}

p { margin: 0; }

.lede {
  color: var(--ink-soft);
  font-size: clamp(1rem, 0.95rem + 0.2vw, 1.15rem);
  line-height: 1.7;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.01em;
  padding: 1rem 1.85rem;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.4s var(--ease-out-expo), box-shadow 0.4s var(--ease-out-expo), background-color 0.35s var(--ease-out-expo), color 0.35s var(--ease-out-expo);
  white-space: nowrap;
  position: relative;
}

.btn svg { flex-shrink: 0; transition: transform 0.4s var(--ease-out-expo); }
.btn:hover svg { transform: rotate(-8deg) scale(1.08); }

.btn-primary {
  background: linear-gradient(155deg, var(--caramel), var(--caramel-deep));
  color: var(--cream);
  box-shadow: var(--shadow-md);
}

/* The recurring WhatsApp CTA — it's the one action that matters, so its
   hover is the most pronounced of the three button variants. */
.btn-primary:hover {
  background: linear-gradient(155deg, var(--caramel-deep), #5f3d23);
  transform: translateY(-4px) scale(1.03);
  box-shadow: var(--shadow-lg);
}

.btn-inverse {
  background: var(--cream);
  color: var(--olive-deep);
  box-shadow: var(--shadow-sm);
}

/* Sits on the dark cta-final section — a pale caramel shadow would vanish
   here, so it uses the deepened on-dark variant instead. */
.btn-inverse:hover {
  background: var(--white);
  transform: translateY(-3px) scale(1.02);
  box-shadow: var(--shadow-on-dark-lg);
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  top: 14px;
  left: 50%;
  z-index: 100;
  width: min(1180px, 94vw);
  transform: translateX(-50%);
  border-radius: 999px;
  background: rgba(69, 72, 56, 0.32);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid rgba(247, 235, 223, 0.16);
  box-shadow: 0 16px 40px -22px rgba(20, 22, 14, 0.45), inset 0 1px 0 rgba(247, 235, 223, 0.14);
  transition: background-color 0.4s var(--ease-out-expo), border-color 0.4s var(--ease-out-expo), box-shadow 0.4s var(--ease-out-expo), transform 0.4s var(--ease-out-expo);
}

.site-header.is-scrolled {
  background: rgba(247, 235, 223, 0.72);
  border-color: rgba(110, 115, 92, 0.18);
  box-shadow: 0 16px 40px -22px rgba(40, 42, 30, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

.site-header.is-hidden {
  transform: translateX(-50%) translateY(-160%);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 0.7rem;
  gap: 1rem;
}

.site-header__logo {
  position: relative;
  display: block;
  height: 32px;
  width: 118px;
}

.site-header__logo-img {
  position: absolute;
  inset: 0;
  height: 32px;
  width: auto;
  transition: opacity 0.35s var(--ease-out-expo);
}

.site-header__logo-img--dark { opacity: 0; }
.site-header.is-scrolled .site-header__logo-img--light { opacity: 0; }
.site-header.is-scrolled .site-header__logo-img--dark { opacity: 1; }

@media (min-width: 640px) {
  .site-header__logo { height: 38px; width: 140px; }
  .site-header__logo-img { height: 38px; }
}

.site-header__cta .btn {
  padding: 0.75rem 1.25rem;
  font-size: 0.88rem;
}

.site-header__cta { display: none; }

@media (min-width: 640px) {
  .site-header__cta { display: block; }
  .site-header__cta .btn span { display: inline; }
}

/* Hamburger toggle — mobile only */

.menu-toggle {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(247, 235, 223, 0.18);
  cursor: pointer;
  transition: background-color 0.3s var(--ease-out-expo);
}

.menu-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--cream);
  transition: transform 0.4s var(--ease-out-expo), opacity 0.25s var(--ease-out-expo), background-color 0.35s var(--ease-out-expo);
}

.site-header.is-scrolled .menu-toggle span { background: var(--olive-deep); }
.site-header.is-scrolled .menu-toggle { background: rgba(110, 115, 92, 0.1); }

.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

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

/* Mobile menu drawer — glass panel below header */

.mobile-menu {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 90;
  background: rgba(69, 72, 56, 0.55);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  padding: clamp(5.5rem, 22vw, 7rem) var(--gutter) 3rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 1.75rem;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  /* Kept on its own ease-out curve rather than the site's expo curve: expo's
     fast-start/slow-finish reads oddly on a height reveal (snaps open, then
     visibly crawls the last few px) — a gentler ease-out suits this one. */
  transition: max-height 0.5s cubic-bezier(.2,.8,.2,1), opacity 0.35s var(--ease-out-expo);
}

.mobile-menu.is-open {
  max-height: 75vh;
  opacity: 1;
  pointer-events: auto;
}

.mobile-menu__nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.25rem;
  margin-top: 1rem;
}

.mobile-menu__nav a {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--cream);
  text-align: center;
}

.mobile-menu__nav a:hover { color: var(--rose); }

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

/* ---------- Hero ---------- */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
}

.hero__media {
  position: relative;
  height: 480px;
  overflow: hidden;
  background: var(--olive-deep);
}

.hero__media .hero__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0%;
  transform: scale(1.08);
  will-change: transform;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(30, 32, 22, 0.3) 0%, rgba(30, 32, 22, 0) 26%);
  pointer-events: none;
}

.hero__content {
  position: relative;
  z-index: 3;
  align-self: stretch;
  margin-top: -34px;
  background: var(--olive-deep);
  color: var(--cream);
  padding: 1.75rem 1.25rem 2.5rem;
  box-shadow: 0 -20px 34px -10px rgba(0, 0, 0, 0.55);
}

.hero-br { display: inline; }

.hero__content-inner {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.hero__content h1 {
  color: var(--cream);
  font-size: 2rem;
  letter-spacing: -0.02em;
}

.hero__content h1 em { color: var(--rose); }

.hero__content .eyebrow { color: var(--rose); }

.hero__content .lede {
  color: rgba(247, 235, 223, 0.88);
  max-width: 42ch;
}

@media (min-width: 480px) {
  .hero__media { height: 540px; }
  .hero__content h1 { font-size: 2.3rem; }
}

@media (min-width: 640px) {
  .hero__media { height: 580px; }
  .hero__content h1 { font-size: 2.5rem; }
}

@media (min-width: 900px) {
  .hero {
    display: block;
  }

  .hero-br { display: none; }

  .hero__media {
    height: 680px;
  }

  .hero__media .hero__photo {
    object-position: 27% 0%;
  }

  .hero__scrim {
    background:
      linear-gradient(to bottom, rgba(30, 32, 22, 0.3) 0%, rgba(30, 32, 22, 0) 20%),
      linear-gradient(to right, rgba(20, 22, 14, 0.18) 0%, rgba(20, 22, 14, 0) 45%);
  }

  .hero__content {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    background: transparent;
    padding-right: 9rem;
    margin-top: 0;
    box-shadow: none;
  }

  .hero__content-inner {
    max-width: 460px;
    text-align: left;
  }

  .hero__content h1 {
    font-size: 2.9rem;
  }
}

@media (min-width: 1280px) {
  .hero__media { height: 760px; }
  .hero__content { padding-right: 15rem; }
  .hero__content h1 { font-size: 3.2rem; }
}

/* ---------- Section rhythm ---------- */

.section {
  padding-block: var(--section-pad);
  scroll-margin-top: 90px;
}

.section--white { background: var(--white); }
.section--cream { background: var(--cream); }

/*
 * Seams between FLAT sections.
 *
 * The folds that overlap their neighbour already sell their own edge — a
 * lifted card with rounded corners and a shadow (#diferencial, #processo,
 * .sobre), or a gradient of their own (.sobre::after, #localizacao::after).
 * What was left untreated is the plain butt-join between two flat fills,
 * which reads as a drawn line across the page. A 28px gradient into the next
 * section's colour dissolves it.
 *
 * The gradient sits INSIDE the section's own bottom padding rather than
 * bleeding past it: .processo clips its overflow to contain the photo, so
 * anything hanging below the edge would simply be cut off.
 *
 * Any [data-seam] value opts a section out; the value documents why. Note
 * that every seam in the page as it stands is opted out — the rule is kept
 * general so a future flat white/cream adjacency is covered without anyone
 * having to remember this exists.
 */
.section--white:not([data-seam]):has(+ .section--cream),
.section--cream:not([data-seam]):has(+ .section--white) {
  position: relative;
}

.section--white:not([data-seam]):has(+ .section--cream)::after,
.section--cream:not([data-seam]):has(+ .section--white)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 28px;
  pointer-events: none;
}

.section--white:not([data-seam]):has(+ .section--cream)::after {
  background: linear-gradient(to bottom, transparent, var(--cream));
}

.section--cream:not([data-seam]):has(+ .section--white)::after {
  background: linear-gradient(to bottom, transparent, var(--white));
}

/* ---------- Diferencial / Como funciona (manifesto blocks) ---------- */

.manifesto-section {
  position: relative;
  overflow: hidden;
}

/*
 * "Page lifted over the section above" shadows — retinted warm (a dark
 * caramel-brown, matching --shadow-on-dark's hue) instead of the previous
 * near-black ink. Kept as its own dark-enough recipe rather than the pale
 * --shadow-md/lg tokens: this overlap effect needs real contrast against the
 * white/cream section behind it to read as a shadow at all.
 */
#diferencial {
  z-index: 5;
  border-radius: 28px 28px 0 0;
  box-shadow: 0 -10px 24px -20px rgba(90, 51, 24, 0.18);
}

@media (min-width: 900px) {
  #diferencial {
    margin-top: -36px;
    border-radius: 36px 36px 0 0;
    box-shadow: 0 -22px 45px -26px rgba(90, 51, 24, 0.3);
  }
}

/* Section stacked directly under #diferencial, lifted slightly over it */
#processo {
  position: relative;
  z-index: 5;
  margin-top: -20px;
  box-shadow: 0 -12px 26px -20px rgba(90, 51, 24, 0.2);
}

@media (min-width: 900px) {
  #processo {
    margin-top: -32px;
    box-shadow: 0 -20px 42px -26px rgba(90, 51, 24, 0.28);
  }
}

.manifesto-section__mark {
  position: absolute;
  top: 50%;
  width: clamp(520px, 46vw, 820px);
  height: auto;
  opacity: 0.05;
  transform: translateY(-50%);
  pointer-events: none;
  z-index: 0;
}

.manifesto-section__mark--left { left: clamp(-220px, -10vw, -80px); }

.manifesto-section__mark--contained {
  display: none;
}

@media (min-width: 900px) {
  .manifesto-section__mark--contained {
    display: block;
    left: clamp(1rem, 4vw, 3rem);
    width: clamp(320px, 30vw, 520px);
  }
}

/* ---------- Diferencial (segunda dobra) ---------- */

/* ---------- Diferencial: pinned fold (desktop) ---------- */

/*
 * Same pin as the sobre fold: #diferencial becomes a tall scroll track and
 * .diferencial-pin holds one viewport, so the list stays put while the scroll
 * walks the highlight from 01 to 04 instead of moving the page.
 *
 * Unlike a photo fold, this one is four rows of TEXT whose height depends on
 * how the headline wraps — at 960px wide it grows tall enough to fill a 760px
 * window exactly. No media query can express that, so main.js measures the
 * content against the viewport and only then adds .can-pin. Everywhere it
 * doesn't fit, the section stays a normal scrolling block.
 */
.diferencial-pin {
  position: relative;
}

/*
 * Two independent gates, and that is deliberate. The media query is a hard
 * floor no stale JS state can cross — .can-pin is only recomputed on resize,
 * and a class left over from a wider viewport must never pin a phone.
 *
 * The frame loop does NOT read this class to decide which highlight model to
 * run; it measures whether the section actually became a tall track. Reading
 * the CSS's own output instead of re-deriving the condition is what keeps the
 * two from ever disagreeing.
 */
@media (min-width: 900px) {

#diferencial.can-pin {
  height: calc(100vh + var(--metodo-scrub, 105vh));
  padding-block: 0;
  /* Same reason as the sobre track: the pin carries the white and the rounded
     top corners, so a painted track would fill the notch outside that radius
     and flatten the card-lifted-over-the-hero edge. */
  background: transparent;
  /* Sticky resolves against the nearest scroll container — the section can't
     clip its own overflow, so the pin takes over both that and the rounded
     "lifted page" edge. */
  overflow: visible;
  border-radius: 0;
  box-shadow: none;
}

#diferencial.can-pin .diferencial-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--white);
  box-shadow: 0 -22px 45px -26px rgba(90, 51, 24, 0.3);
  /*
   * Rounded only while entering, where the corners cut into the hero and read
   * as a page lifting over it. Once the fold owns the whole screen there is
   * nothing behind it but the body, and the notch outside the radius showed
   * as cream chips in the top corners — so --fit squares them off on lock,
   * the same way the sobre pin does.
   */
  border-radius: calc((1 - var(--fit, 0)) * 36px) calc((1 - var(--fit, 0)) * 36px) 0 0;
}

#diferencial.can-pin .diferencial-pin > .container {
  width: 100%;
}

}

.diferencial-layout {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(2.5rem, 6vw, 3.5rem);
}

.diferencial-intro {
  text-align: center;
}

.diferencial-intro h2 {
  font-size: clamp(2.3rem, 1.6rem + 3.2vw, 3.4rem);
  max-width: 15ch;
  margin-inline: auto;
}

.diferencial-stack {
  display: grid;
}

/*
 * The four pillars are a hairline-ruled index at every width — the same
 * editorial list desktop uses, just stacked tighter.
 *
 * This used to be a swipe carousel on mobile. Card chrome plus dots read as
 * "swipe me", but the gesture was unreliable, which left the dots as the only
 * way through and made four short paragraphs feel like a puzzle. A plain
 * vertical list needs no gesture, no affordance and no explanation.
 */
.diferencial-grid {
  display: grid;
}

.diferencial-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding-block: 1.5rem 1.6rem;
  border-top: 1px solid var(--line);
  text-align: left;
}

.diferencial-card:last-child {
  border-bottom: 1px solid var(--line);
}

/*
 * Caramel rule that draws itself across the hairline. Driven purely by scroll
 * — main.js marks one row .is-active at a time, so the list lights 01 → 04 as
 * the fold is scrolled through and unlights coming back up. Deliberately not
 * a hover state: a pointer-triggered highlight competed with the scroll one,
 * and it never existed on touch at all. Kept outside the desktop breakpoint
 * so both layouts get it.
 */
.diferencial-card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--caramel);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease-cine);
}

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

.diferencial-card__num {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 500;
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1;
  color: var(--caramel-text);
}

/* Rule trailing the numeral — reads as an index entry, not a badge */
.diferencial-card__num::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.diferencial-card h3 {
  font-family: var(--font-body);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--olive);
  letter-spacing: 0;
  margin-bottom: 0.45rem;
}

.diferencial-card p {
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

@media (min-width: 900px) {
  .diferencial-layout {
    grid-template-columns: minmax(280px, 400px) 1fr;
    align-items: center;
    gap: clamp(3rem, 6vw, 5.5rem);
  }

  .diferencial-intro {
    text-align: left;
  }

  .diferencial-intro h2 {
    margin-inline: 0;
  }

  /* Wide enough for the numeral to move out of the text's way, into its own
     column — the one structural difference from the mobile list. */
  .diferencial-card {
    display: grid;
    grid-template-columns: 3.5rem 1fr;
    gap: 0 1.75rem;
    align-items: baseline;
    padding: 1.6rem 1.25rem 1.75rem 1rem;
    position: relative;
    transition: background 0.5s var(--ease-out-expo);
  }

  .diferencial-card.is-active {
    background: linear-gradient(90deg, rgba(247, 235, 223, 0.85), rgba(247, 235, 223, 0));
  }

  .diferencial-card__num {
    display: block;
    font-size: 1.35rem;
    /* caramel-deep at 85% — was 45% opacity of a lighter caramel, which
       measured 1.97:1 on white (fails WCAG AA's 4.5:1). This holds ~4.84:1
       while still reading as quieter than the solid hover state. */
    color: rgba(125, 79, 46, 0.85);
    transition: color 0.5s var(--ease-out-expo);
  }

  .diferencial-card__num::after {
    display: none;
  }

  .diferencial-card.is-active .diferencial-card__num {
    color: var(--caramel-text);
  }

  .diferencial-card h3 {
    font-size: 1.06rem;
  }

  .diferencial-card p {
    max-width: 56ch;
  }
}

@media (prefers-reduced-motion: reduce) {
  .diferencial-card::before { transition: none; }
}

/* ---------- Processo de cuidado ---------- */

/*
 * The photo is architecture here, not an object placed on the page: it bleeds
 * to the viewport edge with no frame, and the edge facing the copy is feathered
 * away so it dissolves into the cream instead of ending on a hard rectangle.
 */
.processo {
  position: relative;
  overflow: hidden;
}

/*
 * Top-edge haze, drawn ONCE across the full width.
 *
 * This used to be two separate effects — the section's box-shadow, which only
 * lands on the pale section above, plus a matching gradient inside the photo
 * to "carry" it across. Two different effects over two very different
 * backdrops never read as one line: the haze was plain over the flat fill and
 * invisible over the image. A single overlay spanning the whole edge is
 * continuous by construction instead of by tuning.
 *
 * z-index puts it over the photo but under .container, so the copy is
 * untouched.
 */
.processo::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 56px;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(90, 51, 24, 0.15) 0%,
    rgba(90, 51, 24, 0.05) 45%,
    rgba(90, 51, 24, 0) 100%
  );
}

/*
 * .section's own padding-block pushes the photo down on mobile, since it's
 * still a normal in-flow child here (it only goes absolute, ignoring the
 * parent's padding, at the desktop breakpoint below). Kill just the top half
 * so it bleeds flush to the section's edge; the bottom half still spaces the
 * copy out from the next section.
 */
@media (max-width: 899px) {
  .processo {
    padding-top: 0;
  }
}

.processo__media {
  position: relative;
  overflow: hidden;
  margin-bottom: clamp(2rem, 7vw, 3rem);
  height: clamp(320px, 66vw, 480px);
}

.processo__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}

.processo__body .lede {
  margin-top: 1.5rem;
  font-size: clamp(1.05rem, 1rem + 0.25vw, 1.2rem);
}

@media (min-width: 900px) {
  .processo {
    display: flex;
    align-items: center;
    min-height: clamp(560px, 66vh, 700px);
  }

  .processo > .container {
    position: relative;
    z-index: 1;
    width: 100%;
  }

  .processo__media {
    position: absolute;
    inset: 0 0 0 auto;
    width: clamp(380px, 46vw, 880px);
    height: auto;
    margin: 0;
  }

  /*
   * Only the edge facing the copy is softened — a cream scrim over the flat
   * cream background. Top and bottom stay flush with the section's own bounds.
   */
  .processo__media::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(to right, var(--cream) 0%, rgba(247, 235, 223, 0) 34%);
  }

  .processo__media img {
    object-position: 50% 34%;
  }

  .processo__body {
    max-width: 46ch;
    padding-right: clamp(1rem, 4vw, 3rem);
  }
}

/* ---------- Áreas de atuação ---------- */

.areas-head {
  max-width: 640px;
  margin: 0 auto clamp(2.75rem, 6vw, 4rem);
  text-align: center;
}

/*
 * A typographic index, not a card grid: names set in the display serif, columns
 * separated by hairlines rather than boxes, and a short caramel tick standing in
 * for the old icon badges.
 */
.areas {
  --area-pad: clamp(1.5rem, 3vw, 2.25rem);
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.25rem, 5vw, 2.75rem);
  max-width: 1120px;
  margin-inline: auto;
}

.area {
  position: relative;
  padding-top: 1.6rem;
}

.area::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 28px;
  height: 2px;
  background: var(--caramel);
}

.area h3 {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.45rem);
  font-weight: 500;
  color: var(--olive);
  line-height: 1.25;
  letter-spacing: 0;
  margin-bottom: 0.6rem;
}

.area p {
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 34ch;
}

@media (min-width: 600px) {
  .areas {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: auto auto;
    column-gap: 0;
  }

  .area {
    border-left: 1px solid var(--line);
    padding-inline: var(--area-pad);
    /* Share rows across columns so descriptions align despite uneven titles */
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 2;
    align-content: start;
  }

  .area::before { left: var(--area-pad); }

  /* First item of each row carries no rule and sits flush left */
  .area:nth-child(2n + 1) {
    border-left: 0;
    padding-left: 0;
  }

  .area:nth-child(2n + 1)::before { left: 0; }
}

@media (min-width: 900px) {
  .areas {
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: auto auto;
  }

  /* One row now, so only the very first item stays flush */
  .area:nth-child(2n + 1) {
    border-left: 1px solid var(--line);
    padding-left: var(--area-pad);
  }

  .area:nth-child(2n + 1)::before { left: var(--area-pad); }

  .area:first-child {
    border-left: 0;
    padding-left: 0;
  }

  .area:first-child::before { left: 0; }
}

.areas-note {
  max-width: 620px;
  margin: clamp(3rem, 6vw, 4rem) auto 0;
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.1rem, 1rem + 0.4vw, 1.3rem);
  color: var(--olive);
  line-height: 1.5;
}

/* ---------- Sobre a profissional (dobra cheia) ---------- */

/*
 * Full-bleed fold. The photo's own vignette is a flat #7A4F3C on every edge, so
 * the section background matches it exactly — on mobile the image and the copy
 * panel below read as one continuous field with no seam between them.
 */
/*
 * "Page lifted over the section above", like #diferencial and #processo — but
 * those read as lifted mainly from color CONTRAST (light card cut into a dark
 * section behind it); their box-shadow is barely visible on its own. Here the
 * polarity is reversed (dark card over the white #tratamos), so there is no
 * contrast to lean on — the shadow has to carry the effect by itself, hence
 * the stronger opacity/blur and no crushing negative spread.
 */
.sobre {
  --sobre-bg: #7A4F3C;
  position: relative;
  z-index: 5;
  overflow: hidden;
  margin-top: -20px;
  border-radius: 28px 28px 0 0;
  box-shadow: 0 -14px 34px -4px rgba(90, 51, 24, 0.32);
  background: var(--sobre-bg);
  color: var(--cream);
  scroll-margin-top: 90px;
}

/*
 * The bottom edge, going into #localizacao, has no lifted-card treatment (it's
 * a flat cut to white) — a 50px warm gradient softens the seam instead. Note
 * this is a much smaller effect than the top edge's shadow: it can't blend two
 * very different base colors (brown → white) on its own, just take the hardest
 * edge off the transition.
 */
.sobre::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 50px;
  background: linear-gradient(to bottom, transparent, rgba(45, 26, 12, 0.16));
  pointer-events: none;
}

.sobre__media {
  position: relative;
  overflow: hidden;
}

.sobre__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
}

.sobre__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.sobre__content {
  position: relative;
  z-index: 1;
  padding-block: clamp(2.5rem, 8vw, 3.5rem) clamp(3.5rem, 10vw, 4.5rem);
}

.sobre__body .eyebrow {
  /* 72% measured 3.96:1 on the section's brown — fails AA's 4.5:1. 85% holds ~4.82:1. */
  color: rgba(247, 235, 223, 0.85);
}

.sobre__body h2 {
  color: var(--cream);
  max-width: 15ch;
}

.sobre__body h2 em {
  color: var(--cream);
}

.sobre__body .lede {
  margin-top: 1.4rem;
  color: rgba(247, 235, 223, 0.88);
}

.sobre__signature {
  margin-top: 1.75rem;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(247, 235, 223, 0.6);
}

/*
 * Stacked below 1024px: photo band on top, copy below on the matching brown.
 * The overlay fold needs a viewport close to the photo's 16:9 or the cover crop
 * pushes her figure straight over the copy column.
 */
@media (max-width: 1023px) {
  /*
   * Height only — never aspect-ratio + max-height together: once max-height
   * clamps, the ratio shrinks the *width* to match and the photo stops
   * bleeding edge to edge. 125vw is the 4:5 height at full width.
   */
  .sobre__media {
    height: min(125vw, 620px);
  }

  /* Ease the photo into the flat panel so the join is invisible */
  .sobre__scrim {
    background: linear-gradient(
      to bottom,
      rgba(122, 79, 60, 0) 62%,
      var(--sobre-bg) 100%
    );
  }
}

/* Desktop: one full fold, copy laid over the open left side of the frame */
@media (min-width: 1024px) {
  .sobre {
    display: flex;
    align-items: center;
    /* 58vw keeps the frame near the photo's native 16:9, so the composition
       holds its proportions instead of cropping harder as the window widens. */
    min-height: min(90vh, 58vw);
    margin-top: -32px;
    border-radius: 36px 36px 0 0;
    box-shadow: 0 -18px 42px -6px rgba(90, 51, 24, 0.36);
  }

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

  /* Anchored to the top of the frame: on short windows the cover crop has to
     take from somewhere, and taking it off her head reads as a mistake. */
  .sobre__media img {
    object-position: 50% 0%;
  }

  .sobre__scrim {
    background: linear-gradient(
      to right,
      rgba(48, 29, 20, 0.92) 0%,
      rgba(48, 29, 20, 0.84) 30%,
      rgba(48, 29, 20, 0.52) 48%,
      rgba(48, 29, 20, 0) 72%
    );
  }

  .sobre__content {
    width: 100%;
    padding-block: 0;
  }

  .sobre__body {
    max-width: min(40ch, 34vw);
  }
}

/*
 * From 1280px there is enough room either side of her figure to split the copy
 * into two flanking columns. Below that the flanks are ~230px and the paragraph
 * collapses into a thin ribbon, so it stays as one block on the left.
 */
@media (min-width: 1280px) {
  .sobre__scrim {
    background:
      linear-gradient(
        to right,
        rgba(48, 29, 20, 0.92) 0%,
        rgba(48, 29, 20, 0.8) 20%,
        rgba(48, 29, 20, 0) 44%
      ),
      linear-gradient(
        to left,
        rgba(48, 29, 20, 0.92) 0%,
        rgba(48, 29, 20, 0.8) 18%,
        rgba(48, 29, 20, 0) 40%
      );
  }

  /* Wider than the site container so the columns reach further out */
  .sobre__content > .container {
    max-width: 1600px;
    padding-inline: clamp(1.75rem, 3.5vw, 3.25rem);
  }

  /* Centre track reserved for her figure, which fills the middle ~42% */
  .sobre__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 46vw minmax(0, 1fr);
    align-items: center;
    max-width: none;
  }

  .sobre__col--title { grid-column: 1; }
  .sobre__col--text { grid-column: 3; }

  .sobre__body h2 { max-width: none; }

  .sobre__col--text .lede { margin-top: 0; }
}

/* ---------- Localização ---------- */

/* Flat cut into .cta-final below — same 50px warm-gradient seam treatment as
   .sobre's bottom edge, softening the hardest part of the transition. */
#localizacao {
  position: relative;
}

#localizacao::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 50px;
  background: linear-gradient(to bottom, transparent, rgba(90, 51, 24, 0.05));
  pointer-events: none;
}

.local {
  display: grid;
  gap: clamp(2.5rem, 6vw, 3.5rem);
}

.local__details h2 {
  max-width: 20ch;
  text-wrap: balance;
}

.local__contacts {
  list-style: none;
  padding: 0;
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  display: grid;
  gap: 1.1rem;
}

.local__item {
  display: grid;
  grid-template-columns: 46px 1fr;
  align-items: center;
  gap: 1.05rem;
}

/* Soft rounded-square badges — wayfinding, not decoration */
.local__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--caramel-deep);
}

.local__text {
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--ink);
}

a.local__text {
  justify-self: start;
  color: var(--olive-deep);
  font-weight: 600;
  transition: color 0.3s var(--ease-out-expo);
}

a.local__text:hover { color: var(--caramel-text); }

.local__map {
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  aspect-ratio: 4 / 3;
  background: var(--cream-2);
}

.local__map iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

@media (min-width: 900px) {
  .local {
    grid-template-columns: 1fr 1fr;
    align-items: center;
  }
}

/* ---------- CTA final ---------- */

.cta-final {
  background: linear-gradient(155deg, var(--olive) 0%, var(--olive-deep) 55%, var(--olive-darker) 100%);
  color: var(--cream);
  text-align: center;
  position: relative;
  overflow: hidden;
}

/* Soft light from the top edge, replacing the oversized cropped watermark */
.cta-final::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(115% 85% at 50% 0%, rgba(247, 235, 223, 0.11), transparent 62%);
  pointer-events: none;
}

/* The mark now reads as a signature above the closing line, at a legible size */
.cta-final__mark {
  display: block;
  width: auto;
  height: clamp(44px, 6vw, 58px);
  margin: 0 auto clamp(1.5rem, 4vw, 2.25rem);
  opacity: 0.92;
}

.cta-final .container {
  max-width: 680px;
  position: relative;
  z-index: 1;
}

.cta-final h2 {
  color: var(--cream);
  font-size: clamp(1.9rem, 1.4rem + 2vw, 2.7rem);
}

.cta-final .lede {
  color: var(--cream);
  margin-top: 1.25rem;
}

.cta-final .hero__actions {
  margin-top: 2.25rem;
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--cream);
  border-top: 1px solid var(--line);
  padding-block: clamp(2.5rem, 6vw, 3.5rem);
}

.footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.25rem, 5vw, 3rem);
}

/* Vertical lockup (865×900) — needs real height for the wordmark to read */
.footer__logo {
  display: block;
  height: clamp(68px, 7vw, 82px);
  width: auto;
}

.footer__tagline {
  margin-top: 1.15rem;
  max-width: 32ch;
  font-size: 0.93rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

.footer__heading {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--caramel-text);
  margin-bottom: 1.15rem;
}

.footer__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.7rem;
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.footer__list a {
  color: var(--ink-soft);
  transition: color 0.3s var(--ease-out-expo);
}

.footer__list a:hover { color: var(--caramel-text); }

@media (min-width: 760px) {
  .footer__top {
    grid-template-columns: 1.5fr 1fr 1.3fr;
    gap: clamp(2rem, 5vw, 4.5rem);
  }
}

.footer__bottom {
  margin-top: clamp(2.25rem, 5vw, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.footer__credit {
  display: flex;
  align-items: center;
  gap: 7px;
  font-style: italic;
  font-weight: 500;
  font-size: 12.5px;
  /* Was 55% opacity (2.27:1, fails AA). Solid --ink-soft reaches 5.46:1; the
     italic + small size already read as "quieter" without needing to fade it. */
  color: var(--ink-soft);
}

.footer__credit .widz-mark {
  display: inline-flex;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-style: italic;
  font-size: 16px;
  text-decoration: none;
  letter-spacing: 0.2px;
  transition: opacity 0.3s var(--ease-out-expo);
}

.footer__credit .widz-mark:hover { opacity: 0.85; }
.footer__credit .widz-mark .w { color: #8FB800; }
.footer__credit .widz-mark .rest { color: #0B0B0C; }

/* ---------- Floating WhatsApp ---------- */

.wa-float {
  position: fixed;
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: clamp(1rem, 3vw, 1.75rem);
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: rgba(95, 101, 80, 0.45);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(247, 235, 223, 0.35);
  color: var(--cream);
  box-shadow: var(--shadow-on-dark), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;
  transition: opacity 0.35s ease, transform 0.4s var(--ease-out-expo), background-color 0.3s var(--ease-out-expo), box-shadow 0.4s var(--ease-out-expo);
}

.wa-float.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* This is the one persistent, always-on-screen CTA — its hover gets the
   most pronounced lift on the site, well past the buttons above. */
.wa-float:hover {
  background: rgba(86, 90, 71, 0.72);
  transform: translateY(-4px) scale(1.1);
  box-shadow: var(--shadow-on-dark-lg), inset 0 1px 0 rgba(255, 255, 255, 0.4);
}

/* ---------- Scroll reveal ---------- */

/*
 * Every hidden-until-revealed state is gated behind .motion, which the inline
 * boot script in <head> sets and a watchdog removes if the motion engine never
 * reports ready. A page whose JS failed to load, or that a browser opened in a
 * background tab (where rAF is suspended), therefore renders as plain, fully
 * visible content instead of a blank cream screen.
 */
.motion [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease-out-expo), transform 0.7s var(--ease-out-expo);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; }
}

/*
 * Editorial image reveal — opacity only, and lives on the <img> itself, not
 * the .processo__media/.sobre__media wrapper. That wrapper carries the
 * gradient masks and the "lifted page" box-shadow; animating ITS scale meant
 * the mask and the photo scaled at slightly different rates mid-transition,
 * which showed up as a torn/seamed edge for a frame or two while scrolling.
 * The wrapper now never moves — only the photo fades in, and only on
 * `opacity`, leaving `transform` entirely to .parallax-img below so the two
 * effects never fight over the same property.
 */
.motion [data-reveal-media] {
  opacity: 0;
  transition: opacity 1s var(--ease-out-expo);
}

[data-reveal-media].is-visible {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal-media] { opacity: 1; }
}

/*
 * Permanent overscan for main.js's scroll-parallax (translateY, set inline
 * per frame). object-fit:cover already crops these images flush to their
 * container, so without this extra 12% of scale the parallax shift would
 * pull the image away from one edge and expose the container behind it.
 */
.parallax-img {
  transform: scale(1.12);
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .parallax-img { transform: none !important; }
}


/* ============================================================
   MOTION SYSTEM
   ------------------------------------------------------------
   Everything below is movement. It is deliberately kept in one
   block, after the layout rules, so the static design can be
   read (and edited) without wading through animation, and so a
   single @media (prefers-reduced-motion) sweep at the bottom can
   switch the whole system off.
   ============================================================ */

:root {
  /* Long, cinematic deceleration — the site's signature curve. Slower to
     settle than --ease-out-expo, which stays on the small UI transitions. */
  --ease-cine: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
}

/* Lenis drives scrolling in a rAF loop; native smooth scrolling would fight
   it for the same scrollTop, so it is handed over entirely once Lenis loads. */
.has-lenis { scroll-behavior: auto; }
.has-lenis body { overscroll-behavior-y: none; }

/* ---------- Grouped reveal ---------- */

/*
 * A [data-reveal-group] wrapper enters as a sequence: each [data-rv] inside
 * carries its own --sd offset (set in JS from its position) so the eyebrow,
 * headline, paragraph and button arrive on separate beats instead of the
 * whole block sliding up as one slab.
 */
.motion [data-rv] {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  filter: blur(4px);
  transition:
    opacity 0.95s var(--ease-cine) var(--sd, 0ms),
    transform 1.05s var(--ease-cine) var(--sd, 0ms),
    filter 0.95s var(--ease-cine) var(--sd, 0ms);
}

.is-visible [data-rv] {
  opacity: 1;
  transform: none;
  filter: none;
}

/* A split headline animates through its own words — the element itself must
   stay put, or the words would ride a second, competing transform. */
.motion [data-rv][data-split] {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}

/* ---------- Word-by-word headline reveal ---------- */

/*
 * The site's most expensive-looking move, so it is spent only on the
 * headlines that carry the page. Words rise out of a blur with a hair of
 * rotation — the tilt is what stops it reading as a mechanical fade.
 */
.motion .rv-w {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 0.6em, 0) rotate(1.5deg);
  filter: blur(8px);
  transform-origin: 0% 100%;
  transition:
    opacity 0.9s var(--ease-cine),
    transform 1.15s var(--ease-cine),
    filter 0.9s var(--ease-cine);
  transition-delay: calc(var(--sd, 0ms) + var(--wi, 0) * 52ms);
}

.is-visible .rv-w {
  opacity: 1;
  transform: none;
  filter: none;
}

/* ---------- Hero: the opening shot ---------- */

/*
 * Letterbox open. The frame starts at a cinema crop and widens to full
 * height, which reads as a shot settling rather than a page loading. It
 * animates clip-path (not opacity) precisely so the photo — the LCP element —
 * is painted and measurable from the first frame.
 */
@keyframes heroOpen {
  from { clip-path: inset(24% 0 24% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

.hero__media {
  clip-path: inset(0 0 0 0);
  animation: heroOpen 1.5s var(--ease-cine) both;
}

/*
 * Ken Burns lives on <picture>, one layer above the <img> that JS writes
 * scroll and pointer parallax into. Two elements, two transforms — they
 * compose instead of overwriting each other every frame.
 */
.hero__media picture {
  display: block;
  width: 100%;
  height: 100%;
  animation: kenBurns 24s var(--ease-soft) infinite alternate;
}

@keyframes kenBurns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.07) translate3d(-1.4%, -1%, 0); }
}

/* Desktop only: the copy sits over the photo there, so it can drift up and
   dissolve on scroll. On mobile it is an opaque panel in the layout — fading
   it would just tear a hole in the page. */
@media (min-width: 900px) {
  .hero__content {
    transform: translate3d(0, calc(var(--hero-out, 0) * -70px), 0);
    opacity: calc(1 - var(--hero-out, 0) * 1.25);
    will-change: transform, opacity;
  }
}

/* Scroll cue — a light that travels down a hairline, then fades with the hero */
.hero__cue {
  position: absolute;
  left: clamp(1.5rem, 5vw, 4rem);
  bottom: 2.5rem;
  z-index: 4;
  display: none;
  align-items: center;
  gap: 0.85rem;
  opacity: calc(1 - var(--hero-out, 0) * 2.2);
  pointer-events: none;
}

@media (min-width: 900px) {
  .hero__cue { display: flex; }
}

.hero__cue-label {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(247, 235, 223, 0.72);
}

.hero__cue-line {
  position: relative;
  display: block;
  width: 64px;
  height: 1px;
  background: rgba(247, 235, 223, 0.28);
  overflow: hidden;
}

.hero__cue-line span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 26px;
  background: linear-gradient(90deg, transparent, var(--rose), transparent);
  animation: cueTravel 2.6s var(--ease-soft) infinite;
}

@keyframes cueTravel {
  0%        { transform: translateX(-30px); }
  60%, 100% { transform: translateX(66px); }
}

/* ---------- Sobre: the second cinematic fold ---------- */

/*
 * A single light sweep across the portrait when the fold first enters view.
 * It fires once (JS adds .is-lit and stops observing) — repeated on every
 * pass it would read as a glitch rather than an accent.
 */
.sobre__media::after {
  content: "";
  position: absolute;
  inset: -25%;
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  background: linear-gradient(
    104deg,
    transparent 38%,
    rgba(247, 235, 223, 0.17) 47%,
    rgba(247, 235, 223, 0.06) 55%,
    transparent 63%
  );
  transform: translate3d(-120%, 0, 0);
}

.sobre.is-swept .sobre__media::after {
  animation: sheen 2.6s var(--ease-cine) 0.4s both;
}

@keyframes sheen {
  0%   { transform: translate3d(-120%, 0, 0); opacity: 0; }
  22%  { opacity: 1; }
  100% { transform: translate3d(120%, 0, 0); opacity: 0; }
}

/*
 * Grow the portrait downward, never upward. The scroll-linked scale in
 * main.js is what animates this element, and with the default centre origin
 * it expanded past the top of the frame and clipped her head.
 */
#sobreImg {
  transform-origin: 50% 0%;
}

/* ---------- Sobre: pinned fold (desktop) ---------- */

/*
 * The fold holds the screen while the copy arrives. .sobre becomes a tall
 * scroll TRACK and .sobre__pin is one viewport tall, stuck to the top of it:
 * the portrait scrolls up, locks when it fills the screen, and the remaining
 * track length is scroll the visitor spends revealing the text instead of
 * moving the page. main.js turns that leftover distance into a 0→1 progress.
 *
 * Gated behind .motion and a real desktop viewport. Without it — reduced
 * motion, no JS, or any narrower screen — .sobre__pin is an inert wrapper and
 * the section keeps its original one-screen layout, copy and all.
 */
.sobre__pin {
  position: relative;
}

@media (min-width: 1024px) {
  .motion .sobre {
    /* One viewport of pinned shot + the distance spent scrubbing the copy */
    height: calc(100vh + var(--sobre-scrub, 120vh));
    min-height: 0;
    display: block;
    /*
     * The track must not paint. The pin is what carries the fold's colour,
     * and it has rounded top corners — so anything painted on the track shows
     * through the notch outside that radius. Left brown, it put a pale strip
     * of --sobre-bg exactly where the white section behind should show.
     * The pin always covers the viewport, so the track is never seen.
     */
    background: transparent;
    /* Sticky resolves against the nearest SCROLL container, so the section
       cannot clip its own overflow here or the pin would stick to the section
       instead of the viewport. The pin does the clipping instead. */
    overflow: visible;
    border-radius: 0;
    box-shadow: none;
  }

  /* Softening seam belongs to the visible frame, not the tall track */
  .motion .sobre::after {
    display: none;
  }

  .motion .sobre__pin {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    overflow: hidden;
    background: var(--sobre-bg);
    box-shadow: 0 -18px 42px -6px rgba(90, 51, 24, 0.36);
    /* --fit runs 0→1 as the shot locks in, squaring off the lifted-card
       corners at the exact moment it takes over the full screen. */
    border-radius: calc((1 - var(--fit, 0)) * 36px) calc((1 - var(--fit, 0)) * 36px) 0 0;
  }

  .motion .sobre__pin::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 50px;
    background: linear-gradient(to bottom, transparent, rgba(45, 26, 12, 0.16));
    pointer-events: none;
  }
}

/* ---------- Sobre: scroll-scrubbed copy ---------- */

.motion [data-pin-step] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-cine),
    transform 1.1s var(--ease-cine),
    filter 0.9s var(--ease-cine);
}

[data-pin-step].is-lit {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Split headlines hand their animation to the words, as elsewhere */
.motion [data-pin-step][data-split] {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}

[data-pin-step].is-lit .rv-w {
  opacity: 1;
  transform: none;
  filter: none;
}

.sobre__signature {
  position: relative;
  padding-left: 2.6rem;
}

/* Rule that draws itself out from the name, once the column has arrived */
.sobre__signature::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 2rem;
  height: 1px;
  background: rgba(247, 235, 223, 0.5);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1s var(--ease-cine) calc(var(--sd, 0ms) + 250ms);
}

.is-visible .sobre__signature::before,
.sobre__signature.is-lit::before { transform: scaleX(1); }

/* ---------- Magnetic elements ---------- */

/*
 * --mgx/--mgy are written by JS; the transform is composed here so the CSS
 * hover states (lift, scale) still apply on top instead of being clobbered
 * by an inline transform.
 */
/*
 * The lean itself is only a few px (see data-magnetic in main.js), so the
 * hover lift and scale are kept small too — stacked, a big lift on top of a
 * big lean is what made these read as jumping rather than responding.
 */
.btn,
[data-magnetic] {
  transform: translate3d(var(--mgx, 0px), var(--mgy, 0px), 0);
  transition: transform 0.5s var(--ease-cine), box-shadow 0.4s var(--ease-out-expo),
    background-color 0.35s var(--ease-out-expo), color 0.35s var(--ease-out-expo);
}

.btn-primary:hover {
  transform: translate3d(var(--mgx, 0px), calc(var(--mgy, 0px) - 2px), 0) scale(1.015);
}

.btn-inverse:hover {
  transform: translate3d(var(--mgx, 0px), calc(var(--mgy, 0px) - 2px), 0) scale(1.012);
}

/* Sheen that crosses the primary CTA on hover */
.btn-primary {
  overflow: hidden;
  isolation: isolate;
}

.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    105deg,
    transparent 40%,
    rgba(247, 235, 223, 0.22) 50%,
    transparent 60%
  );
  transform: translate3d(-130%, 0, 0);
  transition: transform 0.85s var(--ease-cine);
}

.btn-primary:hover::after { transform: translate3d(130%, 0, 0); }

.wa-float {
  transform: translate3d(var(--mgx, 0px), calc(var(--mgy, 0px) + 12px), 0) scale(0.9);
}

.wa-float.is-visible {
  transform: translate3d(var(--mgx, 0px), var(--mgy, 0px), 0) scale(1);
}

.wa-float.is-visible:hover {
  transform: translate3d(var(--mgx, 0px), calc(var(--mgy, 0px) - 2px), 0) scale(1.05);
}

/* Scroll-progress ring around the floating CTA — the page's only progress
   indicator, folded into an element that is already on screen. */
.wa-float__ring {
  position: absolute;
  inset: -5px;
  width: calc(100% + 10px);
  height: calc(100% + 10px);
  transform: rotate(-90deg);
  pointer-events: none;
  overflow: visible;
}

.wa-float__ring circle {
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
}

.wa-float__track { stroke: rgba(247, 235, 223, 0.18); }

.wa-float__bar {
  stroke: var(--rose);
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--scroll-progress, 0));
}

/* ---------- Cursor spotlight on sections ---------- */

[data-spotlight] { position: relative; }

[data-spotlight]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s var(--ease-cine);
  background: radial-gradient(
    28rem 28rem at var(--px, 50%) var(--py, 50%),
    var(--spot-color, rgba(165, 110, 67, 0.09)),
    transparent 68%
  );
}

[data-spotlight].is-tracking::after { opacity: 1; }

.cta-final { --spot-color: rgba(247, 235, 223, 0.13); }

/* ---------- Método rows ---------- */

@media (min-width: 900px) {
  .diferencial-card {
    transition: background 0.6s var(--ease-cine);
  }

  .diferencial-card__num {
    transition: color 0.6s var(--ease-cine), transform 0.7s var(--ease-cine);
    transform-origin: left center;
  }

  /* Kept small: the row is already picked out by its rule and background, and
     a large jump would shove the copy around while the list is being read. */
  .diferencial-card.is-active .diferencial-card__num {
    transform: scale(1.08);
  }
}

/* ---------- Áreas ---------- */

/* The caramel tick draws itself in as the column arrives */
.area::before {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.9s var(--ease-cine) var(--reveal-delay, 0ms), width 0.5s var(--ease-cine);
}

.area.is-visible::before { transform: scaleX(1); }

.area h3 {
  transition: transform 0.6s var(--ease-cine), color 0.4s var(--ease-out-expo);
}

@media (hover: hover) {
  .area:hover::before { width: 46px; }
  .area:hover h3 { transform: translate3d(6px, 0, 0); }
}

/* ---------- Localização ---------- */

.local__icon {
  transition: transform 0.6s var(--ease-cine), background-color 0.4s var(--ease-out-expo),
    color 0.4s var(--ease-out-expo), border-color 0.4s var(--ease-out-expo);
}

.local__item:hover .local__icon {
  transform: translate3d(0, -3px, 0) rotate(-6deg);
  background: var(--caramel);
  border-color: var(--caramel);
  color: var(--cream);
}

.local__map {
  overflow: hidden;
  transition: box-shadow 0.6s var(--ease-cine);
}

.local__map:hover { box-shadow: var(--shadow-lg); }

/* ---------- CTA final ---------- */

/* The mark breathes — a slow, barely-there float that keeps the closing
   panel from reading as a flat end-plate. */
.cta-final__mark {
  animation: markFloat 7s var(--ease-soft) infinite alternate;
}

@keyframes markFloat {
  from { transform: translate3d(0, -5px, 0); }
  to   { transform: translate3d(0, 5px, 0); }
}

/* ---------- Footer + nav link underlines ---------- */

.footer__list a,
.mobile-menu__nav a {
  position: relative;
}

.footer__list a::after,
.mobile-menu__nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease-cine);
}

.footer__list a:hover::after,
.mobile-menu__nav a:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* ---------- Grain ---------- */

/* Repositioning the grain on each frame-step gives it the flicker of real
   film stock instead of a static texture sitting on the page. */
.grain {
  inset: -8%;
  animation: grainDrift 5s steps(1) infinite;
}

@keyframes grainDrift {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-3%, 2%, 0); }
  40%  { transform: translate3d(2%, -3%, 0); }
  60%  { transform: translate3d(-2%, -2%, 0); }
  80%  { transform: translate3d(3%, 1%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ---------- Reduced motion: switch the whole system off ---------- */

@media (prefers-reduced-motion: reduce) {
  [data-rv],
  .rv-w,
  .is-visible [data-rv],
  .is-visible .rv-w {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }

  .hero__media,
  .hero__media picture,
  .cta-final__mark,
  .hero__cue-line span,
  .grain {
    animation: none;
  }

  .hero__media { clip-path: none; }

  .hero__cue { display: none; }

  .sobre__media::after { display: none; }

  .sobre__signature::before { transform: scaleX(1); }

  .area::before { transform: scaleX(1); }

  @media (min-width: 900px) {
    .hero__content { transform: none; opacity: 1; }
  }
}
