/* =================================================================
   Cunha Ribeiro | stylesheet
   Tokens: three tiers, reference (--ref) then system (--color, --space)
   then component (--nav, --cta). No hardcoded literals in components.
   ================================================================= */

/* ===================== self-hosted Montserrat =====================
   The font is served from this repo, NOT from fonts.googleapis.com.
   This is a legal requirement, not a preference: the published Politica de
   Cookies states "alojamos localmente os tipos de letra do site ... nao
   contacta servidores externos". A Google Fonts <link> sends every visitor's
   IP to Google on page load, before consent, and makes that sentence false.

   ONE FILE, 37 KB. Montserrat v31 is a VARIABLE font: a single woff2 carries
   the whole weight axis (fvar/gvar/STAT confirmed in the file), which is why
   Google itself returns the SAME url for every weight it lists. The
   font-weight: 200 600 range below is what makes the browser interpolate
   200/300/400/500/600 out of that one file. Do NOT "fix" this into five
   static @font-face rules: they would all point at identical bytes.

   LATIN SUBSET ONLY. Verified against the rendered text of index.html: every
   character the site uses falls inside this range. The single exception is the
   CTA arrow "→" (U+2192), which NO Montserrat subset covers, so it falls back
   to a system glyph exactly as it already did when Google served the font.
   "↓" (U+2193, the policy PDF download links) IS covered.

   WordPress: this file goes in the theme at assets/fonts/ and is declared in
   the theme stylesheet. Do NOT let a plugin re-add Google Fonts.
   ================================================================= */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 200 600;          /* variable axis, not five separate faces */
  font-display: swap;
  src: url('assets/fonts/montserrat-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- reference tier (primitives) --- */
  --ref-ink: #0A0A0A;          /* the one black, every dark surface */
  --ref-graphite: #111111;
  --ref-slate: #2B2B2B;
  --ref-mist: #9A9A9A;
  --ref-stone: #6B6B6B;
  --ref-ash: #5A5A5A;
  --ref-cloud: #E7E7E7;
  --ref-cloud-12: rgba(231, 231, 231, 0.12);
  --ref-paper: #FAFAFA;
  --ref-white: #FFFFFF;
  --ref-white-04: rgba(255, 255, 255, 0.04);
  --ref-white-06: rgba(255, 255, 255, 0.06);
  --ref-white-10: rgba(255, 255, 255, 0.10);
  --ref-white-14: rgba(255, 255, 255, 0.14);
  --ref-white-28: rgba(255, 255, 255, 0.28);
  --ref-white-55: rgba(255, 255, 255, 0.55);
  --ref-white-70: rgba(255, 255, 255, 0.70);
  --ref-black-10: rgba(0, 0, 0, 0.10);
  --ref-black-22: rgba(0, 0, 0, 0.22);

  /* --- system tier (semantic; default = dark context) --- */
  --color-bg: var(--ref-ink);
  --color-bg-raised: var(--ref-graphite);
  --color-text: var(--ref-white);
  --color-text-secondary: var(--ref-cloud);
  --color-text-muted: var(--ref-mist);
  --color-hairline: var(--ref-white-14);
  --color-hairline-strong: var(--ref-white-28);
  --color-wash: var(--ref-white-04);

  /* --- type --- */
  --font-sans: 'Montserrat', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --fs-eyebrow: 12px;
  --ls-eyebrow: 0.18em;
  --fs-nav: 11px;
  --ls-nav: 0.08em;
  --fs-heading: clamp(1.6rem, 2.8vw, 2.4rem);
  --fs-heading-lg: clamp(1.7rem, 3vw, 2.7rem);
  --fs-body: clamp(16px, 1.15vw, 18px);
  --fs-body-sm: clamp(0.95rem, 1vw, 1rem);
  --lh-body: 1.6;
  --lh-heading: 1.2;

  --fs-hero-phrase: clamp(13px, 1.2vw, 18px);
  --fw-hero-phrase: 400;
  --ls-hero-phrase: 0.08em;
  --tt-hero-phrase: uppercase;
  --lh-hero-phrase: 1.4;

  /* --- spacing --- */
  --pad-edge: 6vw;
  --pad-section-x: 6.5vw;
  --pad-section-y: 14vh;

  /* --- media edge polish (rounded + feathered so images don't hard-cut the bg) --- */
  --media-radius: clamp(8px, 0.9vw, 14px);
  --media-feather: clamp(4px, 0.5vw, 7px);

  /* --- component tier --- */
  --nav-pad-y: 26px;
  --nav-h: calc(var(--nav-pad-y) * 2 + 16px);
  /* Nav geometry as tokens, so the Sustentabilidade flyout can align to the nav without
     restating its numbers. --nav-link-pad-x is the side padding every top-level nav word carries
     (the drawn hover box needs it), so a nav LABEL's edge is the nav item's box edge minus this.
     --nav-menu-item-pad-x is the same for a dropdown item. The flyout's right padding is the
     difference between the two | see .nav__menu. */
  --nav-link-pad-x: 10px;
  --nav-menu-item-pad-x: 6px;
  --cta-border: var(--ref-white-28);
  --cta-border-hover: var(--ref-white);
  --maxw-prose: 60ch;

  /* --- motion (the animation system; soft, editorial register) --- */
  --ease-soft: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-gentle: cubic-bezier(0.16, 1, 0.30, 1);
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 300ms;
  --dur-base: 420ms;
  --dur-mid: 680ms;
  --dur-slow: 900ms;
  --dur-xslow: 1200ms;
  --rise-sm: 12px;
  --rise-md: 18px;
  --stag-word: 40ms;
  --stag-item: 90ms;
}

/* ============================ base ============================ */

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

html, body { margin: 0; padding: 0; }

/* Viewport hardening: the layout viewport must never exceed the device width. An
   intrinsically-wide descendant would otherwise blow the mobile initial containing
   block and collapse in-flow content to a fraction of the screen. overflow-x:hidden
   is the fallback line; clip wins where supported and avoids creating a scroll container. */
html, body {
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
}

/* clip only (no hidden fallback): hidden here would turn these into scroll
   containers and break position:sticky descendants (produção index rail). */
main, [data-page] {
  max-width: 100%;
  overflow-x: clip;
}

body {
  background: var(--ref-ink);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a { color: inherit; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
}

/* ===================== typography utilities ===================== */

.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0;
}

.body { font-weight: 400; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--color-text-secondary); }

.cta-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--color-hairline-strong);
  transition: border-color var(--dur-fast) ease;
}
.cta-link:hover { border-bottom-color: var(--cta-border-hover); }
.cta-link .arrow { font-size: 14px; transition: transform var(--dur-fast) var(--ease-soft); }
.cta-link:hover .arrow { transform: translateX(4px); }

.cta-button {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  padding: 15px 26px;
  border: 1px solid var(--cta-border);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--color-text);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--dur-fast) ease, background var(--dur-fast) ease, transform var(--dur-fast) ease;
}
.cta-button:hover { border-color: var(--cta-border-hover); background: var(--color-wash); transform: translateY(-1px); }

/* ===================== scroll reveal (JS-gated) ===================== */
/* JS adds body.reveal-ready (so no-JS shows everything) and toggles .is-revealed as
   each [data-reveal] enters view (app.js initReveal). */
body.reveal-ready [data-reveal] {
  opacity: 0; transform: translateY(var(--rise-md));
  transition: opacity var(--dur-mid) ease, transform var(--dur-mid) var(--ease-gentle);
}
body.reveal-ready [data-reveal].is-revealed { opacity: 1; transform: none; }

body.reveal-ready .stats[data-reveal] { opacity: 1; transform: none; }
body.reveal-ready .stats[data-reveal] .stats__item {
  opacity: 0; transform: translateY(var(--rise-sm));
  transition: opacity var(--dur-mid) ease, transform var(--dur-mid) var(--ease-gentle);
}
body.reveal-ready .stats[data-reveal].is-revealed .stats__item { opacity: 1; transform: none; }
body.reveal-ready .stats[data-reveal] .stats__item:nth-child(2) { transition-delay: calc(var(--stag-item) * 1); }
body.reveal-ready .stats[data-reveal] .stats__item:nth-child(3) { transition-delay: calc(var(--stag-item) * 2); }
body.reveal-ready .stats[data-reveal] .stats__item:nth-child(4) { transition-delay: calc(var(--stag-item) * 3); }

/* ---- reveal variants (data-reveal="..."); each overrides the default block above ---- */

body.reveal-ready [data-reveal="rule"] {
  opacity: 1; transform: scaleX(0); transform-origin: center;
  transition: transform var(--dur-slow) var(--ease-gentle);
}
body.reveal-ready [data-reveal="rule"].is-revealed { transform: scaleX(1); }

body.reveal-ready [data-reveal="vrule"] {
  opacity: 1; transform: scaleY(0); transform-origin: top;
  transition: transform var(--dur-slow) var(--ease-gentle);
}
body.reveal-ready [data-reveal="vrule"].is-revealed { transform: scaleY(1); }

body.reveal-ready [data-reveal="eyebrow"] {
  opacity: 0; transform: none; letter-spacing: 0.04em;
  transition: opacity var(--dur-mid) ease, letter-spacing var(--dur-slow) var(--ease-gentle);
}
body.reveal-ready [data-reveal="eyebrow"].is-revealed { opacity: 1; letter-spacing: var(--ls-eyebrow); }

/* words: a heading rises word by word from behind an invisible line. JS (splitWords)
   wraps each word; --rv-i drives the per-word stagger. Padding + matched negative
   margin give diacritics/descenders room so the mask never clips the glyphs.
   No-JS / reduced-motion: words are never split, the heading shows plainly. */
body.reveal-ready [data-reveal="words"] { opacity: 1; transform: none; }
.rv-word { display: inline-block; overflow: hidden; vertical-align: top; padding: 0.1em 0 0.12em; margin: -0.1em 0 -0.12em; }
.rv-word__inner {
  display: inline-block;
  transform: translateY(120%);
  transition: transform var(--dur-slow) var(--ease-gentle);
  transition-delay: calc(var(--rv-i, 0) * var(--stag-word));
}
body.reveal-ready [data-reveal="words"].is-revealed .rv-word__inner { transform: none; }

body.reveal-ready [data-reveal="media"] {
  opacity: 1; transform: none;
  clip-path: inset(100% 0 0 0);
  transition: clip-path var(--dur-slow) var(--ease-gentle);
}
body.reveal-ready [data-reveal="media"].is-revealed { clip-path: inset(0 0 0 0); }
body.reveal-ready [data-reveal="media"] > img,
body.reveal-ready [data-reveal="media"] > video {
  transform: scale(1.06);
  transition: transform var(--dur-xslow) var(--ease-gentle);
}
body.reveal-ready [data-reveal="media"].is-revealed > img,
body.reveal-ready [data-reveal="media"].is-revealed > video { transform: none; }

/* ===================== media edge polish ===================== */
/* Contained image/video rectangles get rounded vertices + feathered edges so they dissolve
   into the #0A0A0A instead of hard-cutting it. The soft edge is a two-axis gradient mask
   intersected (visible only where BOTH the horizontal and vertical feathers are opaque, so
   all four sides + the corners fade). Composes with the [data-reveal="media"] clip-path wipe
   (mask and clip-path are independent). Full-bleed heroes/bands are intentionally excluded
   (they span to the viewport edge, so there is no edge to soften). Add new contained media here. */
.grupo-intro__ph,
.contacto__map,
.artigo__cover {
  border-radius: var(--media-radius);
  overflow: hidden;
  -webkit-mask-image:
    linear-gradient(to right,  transparent 0, #000 var(--media-feather), #000 calc(100% - var(--media-feather)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--media-feather), #000 calc(100% - var(--media-feather)), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right,  transparent 0, #000 var(--media-feather), #000 calc(100% - var(--media-feather)), transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 var(--media-feather), #000 calc(100% - var(--media-feather)), transparent 100%);
  mask-composite: intersect;
}

/* ===================== smooth scroll + page transition ===================== */

/* Lenis (smooth momentum scroll); these classes are added by the library at runtime.
   The default `iframe { pointer-events: none }` rule is intentionally omitted so the
   contacto Google Map stays interactive. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

[data-page].is-entering { animation: pageIn var(--dur-base) var(--ease-gentle); }
@keyframes pageIn { from { opacity: 0; } to { opacity: 1; } }

/* ===================== micro-interactions ===================== */

body.reveal-ready [data-magnetic] { transition: opacity var(--dur-mid) ease, transform var(--dur-base) var(--ease-soft); }

/* ============================ layout ============================ */

.section {
  background: var(--color-bg);
  color: var(--color-text);
  padding: var(--pad-section-y) var(--pad-section-x);
}

[data-page][hidden] { display: none; }

/* ============================= nav ============================= */

.nav {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--nav-pad-y) var(--pad-edge) 0;
  /* notch/safe-area clearance under viewport-fit=cover; falls back to the line above */
  padding: calc(var(--nav-pad-y) + env(safe-area-inset-top))
           calc(var(--pad-edge) + env(safe-area-inset-right))
           0
           calc(var(--pad-edge) + env(safe-area-inset-left));
}

.nav__wordmark {
  display: inline-flex; align-items: center;
  text-decoration: none;
}
.nav__logo { display: block; height: clamp(26px, 2.4vw, 34px); width: auto; }

.nav__right { display: flex; align-items: center; gap: 18px; }

.nav__links { display: flex; align-items: center; gap: 6px; }

.nav__link {
  position: relative;
  display: inline-block;
  padding: 6px var(--nav-link-pad-x);
  font-size: var(--fs-nav);
  font-weight: 500;
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--ref-white);
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-soft);
}
.nav__link:hover { transform: scale(1.06); }
.nav__draw { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.nav__draw rect {
  fill: none; stroke: var(--ref-white-55); stroke-width: 1;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset var(--dur-base) var(--ease-inout), filter var(--dur-fast) ease, stroke var(--dur-fast) ease;
}
.nav__link:hover .nav__draw rect {
  stroke-dashoffset: 0; stroke: var(--ref-white);
  filter: drop-shadow(0 0 3px var(--ref-white-28));
  transition: stroke-dashoffset var(--dur-base) var(--ease-inout),
              filter var(--dur-fast) ease var(--dur-base), stroke var(--dur-fast) ease;
}
.nav__link.is-current .nav__draw rect {
  stroke-dashoffset: 0; stroke: var(--ref-white-55); filter: drop-shadow(0 0 2px var(--ref-white-14));
}
.nav__link.is-current:hover .nav__draw rect {
  stroke: var(--ref-white); filter: drop-shadow(0 0 4px var(--ref-white-28));
}
.nav__sep { color: var(--ref-white-28); font-size: var(--fs-nav); user-select: none; }

.nav__divider { width: 1px; height: 16px; background: var(--ref-white-14); }

.nav__lang { position: relative; }
.nav__lang-toggle {
  position: relative;
  display: inline-flex; align-items: center;
  padding: 6px var(--nav-link-pad-x);
  font-size: var(--fs-nav); font-weight: 500; letter-spacing: var(--ls-nav);
  text-transform: uppercase; color: var(--ref-white);
  background: none; border: 0; cursor: pointer; font-family: inherit;
}
.nav__lang:hover .nav__lang-toggle .nav__draw rect,
.nav__lang.is-open .nav__lang-toggle .nav__draw rect,
.nav__lang:focus-within .nav__lang-toggle .nav__draw rect {
  stroke-dashoffset: 0; stroke: var(--ref-white);
  filter: drop-shadow(0 0 3px var(--ref-white-28));
  transition: stroke-dashoffset var(--dur-base) var(--ease-inout),
              filter var(--dur-fast) ease var(--dur-base), stroke var(--dur-fast) ease;
}
/* centred under the chosen language, then nudged right by half the arrow+gap so the CODE
   (not the code+arrow group) sits dead-centre under PT, with the arrow as a right accent */
.nav__lang-panel {
  position: absolute; top: 100%; left: 50%; transform: translateX(calc(-50% + 10px));
  display: flex; flex-direction: column; align-items: stretch;
  padding: 9px 12px; gap: 9px;
  visibility: hidden; pointer-events: none;
  transition: visibility 0s linear var(--dur-base);
}
.nav__lang .nav__lang-opt { justify-content: center; }
.nav__lang:hover .nav__lang-panel,
.nav__lang.is-open .nav__lang-panel,
.nav__lang:focus-within .nav__lang-panel {
  visibility: visible; pointer-events: auto;
  transition: visibility 0s;
}

.nav__burger { display: none; }
.nav__caret { display: none; }
.nav__langbar { display: none; }
.nav__links-draw { display: none; }
.nav-scrim { display: none; }
.nav__links-inner, .nav__links-list, .nav__row, .nav__menu-inner, .nav__menu-list { display: contents; }

/* ---- mobile nav (<=860px): centred fixed bar + compact dropdown card ---- */
@media (max-width: 860px) {
  .nav {
    position: fixed;
    height: var(--nav-h);
    height: calc(var(--nav-h) + env(safe-area-inset-top));
    padding: 0 var(--pad-edge);
    padding: env(safe-area-inset-top)
             calc(var(--pad-edge) + env(safe-area-inset-right))
             0
             calc(var(--pad-edge) + env(safe-area-inset-left));
    border-bottom: 1px solid transparent;
    transition: background 0.3s ease, border-color 0.3s ease;
  }
  body.nav-solid .nav { background: var(--ref-ink); border-bottom-color: var(--ref-white-14); }

  .nav__divider { display: none; }
  .nav__wordmark, .nav__lang, .nav__burger { position: relative; z-index: 62; }
  .nav__lang-toggle { padding: 12px 10px; }   /* >=44px tap target for PT */

  .nav__burger {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
    width: 44px; height: 44px;
    background: none; border: 0; cursor: pointer; padding: 0;
    -webkit-tap-highlight-color: transparent;
  }
  .nav__burger span {
    width: 22px; height: 1.5px; background: var(--ref-white);
    transition: transform 0.3s ease, opacity 0.2s ease; transform-origin: center;
  }
  body.nav-open .nav__burger span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
  body.nav-open .nav__burger span:nth-child(2) { opacity: 0; }
  body.nav-open .nav__burger span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

  /* scroll-lock while the card is open. This html/body rule is the MANDATORY
     non-Lenis fallback (lenis is null under reduced motion or if its script
     fails); app.js pairs it with lenis.stop()/start(). JS sets .nav-open on
     BOTH html and body so the lock holds regardless of overflow propagation. */
  html.nav-open, html.nav-open body { overflow: hidden; }

  /* scrim: dims the page under the open card; tap = close. Below the bar (z 48 < 50). */
  .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 48; border: 0; padding: 0; cursor: default;
    background: rgba(10, 10, 10, 0.35);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity var(--dur-base) ease, visibility 0s linear var(--dur-base);
  }
  body.nav-open .nav-scrim {
    opacity: 1; visibility: visible; pointer-events: auto;
    transition: opacity var(--dur-base) ease, visibility 0s;
  }

  .nav__links {
    position: fixed; z-index: 55;
    top: calc(var(--nav-h) + 8px);
    top: calc(var(--nav-h) + env(safe-area-inset-top) + 8px);
    right: var(--pad-edge);
    right: calc(var(--pad-edge) + env(safe-area-inset-right));
    left: auto;
    width: min(76vw, 300px);
    display: grid; grid-template-rows: 0fr; gap: 0; align-items: stretch;   /* stretch beats the desktop row's align-items:center */
    background: var(--ref-ink);
    border: 1px solid var(--ref-white-14);
    max-height: calc(100svh - var(--nav-h) - 24px);
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: grid-template-rows var(--dur-base) var(--ease-gentle),
                transform var(--dur-base) var(--ease-gentle),
                opacity 0.28s ease,
                visibility 0s linear var(--dur-base);
  }
  body.nav-open .nav__links {
    grid-template-rows: 1fr; opacity: 1; visibility: visible; transform: translateY(0);
    transition: grid-template-rows var(--dur-base) var(--ease-gentle),
                transform var(--dur-base) var(--ease-gentle),
                opacity 0.28s ease,
                visibility 0s;
  }

  .nav__links-draw {
    display: block; position: absolute; top: -1px; left: -1px;
    width: calc(100% + 2px); height: calc(100% + 2px);
    overflow: visible; pointer-events: none; z-index: 2;
  }
  .nav__links-draw rect {
    fill: none; stroke: var(--ref-white); stroke-width: 1;
    stroke-dasharray: 100; stroke-dashoffset: 100;
    transition: stroke-dashoffset var(--dur-fast) var(--ease-inout), filter var(--dur-fast) ease;
  }
  body.nav-open .nav__links-draw rect {
    stroke-dashoffset: 0;
    filter: drop-shadow(0 0 3px var(--ref-white-28));
    transition: stroke-dashoffset var(--dur-base) var(--ease-inout) 160ms,
                filter var(--dur-fast) ease 580ms;   /* glow once the line closes (160 + 420) */
  }

  .nav__links-inner {
    display: block; min-height: 0; overflow: hidden auto; -webkit-overflow-scrolling: touch;
  }
  .nav__links-list { display: block; padding: 6px 18px 10px; }

  .nav__sep { display: none; }
  .nav__link .nav__draw { display: none; }
  .nav__link:hover { transform: none; }

  .nav__link {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    min-height: 48px; padding: 12px 2px;
    font-size: 0.875rem; font-weight: 300; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ref-white-70);
    border-bottom: 1px solid var(--ref-white-10);
    -webkit-tap-highlight-color: transparent;
    opacity: 0; transform: translateX(26px);
    transition: opacity var(--dur-base) ease, transform var(--dur-base) var(--ease-gentle), color var(--dur-fast) ease;
  }
  .nav__link.is-current { color: var(--ref-white); }
  .nav__link.is-current::after {
    content: ''; flex: none; width: 5px; height: 5px; border-radius: 50%; background: var(--ref-white);
  }
  .nav__links-list > .nav__link:last-child { border-bottom: 0; }
  body.nav-open .nav__link { opacity: 1; transform: translateX(0); }
  /* stagger by list position (children: 1 Grupo, 3 Produção, 5 Sustentabilidade item,
     7 Contactos; the even children are the hidden desktop seps) */
  body.nav-open .nav__links-list > .nav__link:nth-child(1) { transition-delay: 55ms, 55ms, 0s; }
  body.nav-open .nav__links-list > .nav__link:nth-child(3) { transition-delay: 110ms, 110ms, 0s; }
  body.nav-open .nav__item--has-menu .nav__link { transition-delay: 165ms, 165ms, 0s; }
  body.nav-open .nav__links-list > .nav__link:nth-child(7) { transition-delay: 220ms, 220ms, 0s; }

  /* (the Sustentabilidade caret accordion rules live in the ≤860 block right AFTER
     the desktop "Sustentabilidade dropdown" section | they override its flyout at
     equal specificity, so they must come later in the file. See ~"nav: dropdown".) */

  .nav__lang { display: none; }
  .nav__langbar {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    margin: 0 18px;
    padding: 12px 0 calc(14px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--ref-white-10);
  }
  .nav__langbar-opt {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; padding: 8px 10px;              /* >=44px tap target */
    background: none; border: 0; cursor: pointer; font-family: inherit;
    font-size: 0.8rem; font-weight: 300; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--ref-white-55); -webkit-tap-highlight-color: transparent;
    transition: color var(--dur-fast) ease;
  }
  .nav__langbar-opt.is-current { color: var(--ref-white); font-weight: 400; }
  .nav__langbar-opt:hover { color: var(--ref-white-70); }
  .nav__langbar-sep { color: var(--ref-white-28); font-size: 0.8rem; user-select: none; }
}

/* ----- funding logo lockups (footer band) -----
   STATIC at every viewport: a marquee's width:max-content track widens the mobile
   layout viewport and collapses the page to a fraction of the screen. */
.logobar { position: relative; width: 100%; overflow: hidden; }
.logobar__track {
  display: flex; align-items: center; justify-content: center;
  width: 100%; gap: clamp(8px, 1vw, 16px);
}
.logobar__link {
  display: inline-flex; flex: none; text-decoration: none;
}
.logobar__link .logobar__logo { transition: opacity 0.18s ease; }
.logobar__link:hover .logobar__logo,
.logobar__link:focus-visible .logobar__logo { opacity: 0.7; }
.logobar__logo {
  display: block; flex: none; width: auto; max-width: none;
  height: var(--logobar-h, clamp(18px, 1.9vw, 24px));
}

@media (max-width: 760px) {
  .logobar__track { flex-wrap: wrap; row-gap: 10px; }
}

/* ============================ footer ============================ */

.footer { background: var(--color-bg); color: var(--ref-white); border-top: 1px solid var(--color-hairline); }
.footer__wrap { padding: clamp(44px, 5vw, 64px) var(--pad-section-x) 0; }

.footer__label {
  font-size: 10px; font-weight: 500; letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--ref-stone);
}

.footer__main { display: grid; grid-template-columns: 1.6fr 1fr 1.4fr; gap: clamp(28px, 3.2vw, 44px); align-items: start; }

.footer__logo { display: block; height: clamp(32px, 3.2vw, 44px); width: auto; }
.footer__contact { margin-top: clamp(20px, 2.2vw, 30px); }
.footer__contact .footer__label { margin-bottom: 12px; }
.footer__socials { display: flex; gap: 10px; margin-top: clamp(18px, 2vw, 26px); }
.footer__social {
  display: flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border: 1px solid var(--color-hairline); border-radius: 50%; color: var(--color-text-muted);
  text-decoration: none; transition: color 0.18s ease, border-color 0.18s ease;
}
.footer__social:hover { color: var(--ref-white); border-color: var(--cta-border-hover); }
.footer__social svg { width: 14px; height: 14px; fill: currentColor; }

.footer__nav-col .footer__label { margin-bottom: 22px; }
.footer__menu { display: flex; flex-direction: column; gap: 13px; }
.footer__menu a { font-size: 13px; font-weight: 400; color: var(--ref-white); text-decoration: none; transition: color 0.18s ease; }
.footer__menu a:hover { color: var(--color-text-muted); }

.footer__actions-col { display: flex; flex-direction: column; }
.footer__contact-info {
  font-style: normal; display: flex; flex-direction: column; gap: 10px; margin-bottom: 0;
}
.footer__contact-line {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 13px; font-weight: 300; line-height: 1.5; color: var(--color-text-secondary); text-decoration: none;
}
.footer__contact-icon { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--color-text-muted); transition: color 0.18s ease; }
.footer__contact-phone, .footer__contact-mail { color: var(--ref-white); transition: color 0.18s ease; }
.footer__contact-phone:hover, .footer__contact-mail:hover { color: var(--color-text-muted); }
.footer__newsletter { margin-top: 0; }
.footer__newsletter .footer__label { margin-bottom: 10px; }
.footer__nl-text { margin: 0 0 16px; font-weight: 300; font-size: 12px; line-height: 1.6; color: var(--color-text-muted); }
.footer__nl-form { display: flex; border: 1px solid var(--color-hairline); }
.footer__nl-form input {
  flex: 1; min-width: 0; background: transparent; border: none; outline: none;
  font-family: var(--font-sans); font-size: 12px; font-weight: 300; color: var(--ref-white); padding: 12px 14px;
}
.footer__nl-form input::placeholder { color: var(--ref-stone); }
.footer__nl-form button {
  background: transparent; border: none; border-left: 1px solid var(--color-hairline);
  font-family: var(--font-sans); font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--color-text-muted); padding: 12px 18px; cursor: pointer; white-space: nowrap;
  transition: color 0.18s ease, background 0.18s ease;
}
.footer__nl-form button:hover { color: var(--ref-white); background: var(--ref-white-06); }
@media (max-width: 860px) {
  /* iOS zooms any focused input under 16px (860 covers iPad-portrait 768 too);
     the button rises to a 44px tap target */
  .footer__nl-form input { font-size: 16px; }
  .footer__nl-form button { min-height: 44px; }
}

.footer__policyrow {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: clamp(20px, 3vw, 48px);
  margin-top: clamp(40px, 5vw, 64px); padding-top: clamp(18px, 2vw, 24px);
  border-top: 1px solid var(--color-hairline);
}
.footer__band { --logobar-h: clamp(22px, 2.4vw, 30px); }
@media (min-width: 761px) {
  .footer__band .logobar__track { justify-content: flex-end; }
  .footer__policyrow .logobar,
  .footer__policyrow .logobar__track { width: auto; }
}
@media (max-width: 760px) { .footer__band { flex-basis: 100%; } }

.footer__policies { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.footer__policies a { font-size: 11px; font-weight: 300; color: var(--ref-stone); text-decoration: none; transition: color 0.18s ease; }
.footer__policies a:hover { color: var(--color-text-muted); }

.footer__bottom {
  margin-top: 20px; padding: 22px 0 52px; border-top: 1px solid var(--ref-white-10);
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
}
.footer__bottom span { font-size: 12px; font-weight: 300; color: var(--ref-stone); }

@media (max-width: 960px) {
  .footer__main { grid-template-columns: 1fr 1fr; gap: 48px; }
  .footer__brand-col { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  .footer__wrap { padding: 64px 6vw 0; }
  .footer__main { grid-template-columns: 1fr; gap: 40px; }
  .footer__bottom { flex-direction: column; align-items: flex-start; gap: 8px; }
}

/* ============================= hero ============================= */

.hero {
  position: relative; width: 100%; overflow: hidden;
  /* svh = stable small-viewport height: no jump when the mobile address bar
     shows/hides. The vh line is the fallback for browsers without svh. */
  min-height: 100vh;
  min-height: 100svh;
  background: var(--ref-ink);
}
.hero__media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  background: var(--ref-ink);
}
.media-slot {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: var(--ref-graphite); color: var(--ref-ash);
  font-size: var(--fs-eyebrow); letter-spacing: var(--ls-nav); text-transform: uppercase; text-align: center;
  padding: 0 24px;
}
.hero__scrim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10,10,10,0.25), rgba(10,10,10,0) 28%, rgba(10,10,10,0) 60%, rgba(10,10,10,0.45)); pointer-events: none; }
.hero__caption {
  position: absolute; left: var(--pad-edge); z-index: 10;
  bottom: 22px;
  bottom: calc(22px + env(safe-area-inset-bottom));   /* clear the iOS home indicator (viewport-fit=cover) */
  font-size: var(--fs-nav); font-weight: 400; letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--ref-white-70); pointer-events: none;
}
.hero__sound {
  position: absolute; right: var(--pad-edge); z-index: 10;
  bottom: 20px;   /* measured: puts the button's centre on the caption's centre line */
  bottom: calc(20px + env(safe-area-inset-bottom));
  width: 40px; height: 40px; padding: 0; display: grid; place-items: center;
  border: 1px solid var(--ref-white-28); border-radius: 50%;
  background: rgba(10, 10, 10, 0.25); color: var(--ref-white-70); cursor: pointer;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: border-color var(--dur-fast) ease, color var(--dur-fast) ease;
}
.hero__sound:hover { border-color: var(--ref-white-70); color: var(--ref-white); }
.hero__sound svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hero__sound .hero__sound-on { display: none; }
.hero__sound[aria-pressed="true"] .hero__sound-on { display: block; }
.hero__sound[aria-pressed="true"] .hero__sound-off { display: none; }
/* below 360px the one-line caption (~267px) reaches under the button, so the button lifts to sit
   just above the caption line instead (wrapping the caption was tried: its &nbsp; separators
   carry onto line 2 and indent it). 360px and up keep >= 10px of clearance on one line. */
@media (max-width: 359px) {
  .hero__sound { bottom: 58px; bottom: calc(58px + env(safe-area-inset-bottom)); }
}
/* ================= números + apresentação (home) ================= */

.numeros { text-align: center; }

.stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  max-width: 1200px; margin: clamp(40px, 6vh, 80px) auto 0;
}
.stats__item {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 10px 16px;
}
.stats__figure {
  font-weight: 300; font-size: clamp(1.9rem, 3vw, 2.75rem);
  letter-spacing: -0.01em; line-height: 1; color: var(--color-text);
}
.stats__label {
  font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--color-text-muted);
}

.numeros__divider {
  height: 1px; background: var(--color-hairline);
  margin: clamp(60px, 12vh, 130px) calc(-1 * var(--pad-section-x));
}

.numeros__intro { max-width: 86ch; margin: 0 auto; }   /* measure sized to hold the lead on exactly 3 lines with margin on both sides (76ch sat on the 4-line edge -> tipped to 4 on narrower windows); body keeps its own 60ch */
.numeros__lead {
  margin: 24px 0 0; font-weight: 500; font-size: clamp(1rem, 1.35vw, 1.3rem);
  line-height: 1.5; letter-spacing: -0.005em; color: var(--color-text); text-wrap: balance;
}
.numeros__body {
  margin: 28px auto 0; font-weight: 300; font-size: var(--fs-body);
  line-height: var(--lh-body); color: var(--color-text-secondary); max-width: 60ch; text-wrap: pretty;
}
.numeros__cta { margin-top: 40px; }

@media (max-width: 900px) {
  .stats { grid-template-columns: repeat(2, 1fr); gap: clamp(30px, 6vw, 44px) clamp(24px, 5vw, 48px); max-width: 460px; }
  .stats__item { padding: 0; }
}

/* ======================== pilares (home) ======================== */

.pilares__grid { display: grid; grid-template-columns: 1fr 1.28fr 1fr; align-items: stretch; }
.pilar { position: relative; padding: 0 clamp(28px, 3vw, 44px); text-align: center; }
.pilar:first-child { padding-left: 0; }
.pilar:last-child { padding-right: 0; }
.pilar__rule {
  position: absolute; left: -1px; top: 0; bottom: 0; width: 3px; pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--color-hairline) 12%, var(--color-hairline) 88%, transparent);
  /* Horizontal feather so the hairline is defined by this gradient, NOT by a 1px box landing on the
     device-pixel grid. A bare 1px line landed on different sub-pixels per gutter (fluid 1fr 1.28fr 1fr
     columns), so at HiDPI/scaled displays one divider smeared across 2px = looked thicker. Now both
     render identically at any sub-pixel x / DPR. Centre of the feather sits on the column boundary. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 35%, #000 65%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 35%, #000 65%, transparent 100%);
}
.pilar__index { font-weight: 200; font-size: clamp(66px, 7vw, 118px); line-height: 0.85; letter-spacing: -0.03em; color: var(--ref-cloud-12); }
.pilar__title { font-weight: 600; font-size: clamp(1.1rem, 1.3vw, 1.35rem); line-height: 1.25; letter-spacing: -0.01em; color: var(--color-text); margin: 26px 0 16px; }
.pilar__body { font-weight: 300; font-size: 15px; line-height: 1.78; color: var(--color-text-muted); margin: 0; }
.pilar__note { margin: 18px 0 0; padding-top: 18px; border-top: 1px solid var(--ref-white-10); font-style: italic; font-weight: 300; font-size: 13px; line-height: 1.7; color: var(--color-text-muted); }
@media (max-width: 860px) {
  .pilares__grid { grid-template-columns: 1fr; }
  .pilar { padding: 0; }
  .pilar__rule { display: none; }
  .pilar + .pilar { border-top: 1px solid var(--color-hairline); margin-top: clamp(40px, 9vw, 56px); padding-top: clamp(40px, 9vw, 56px); }
}

/* ===================== contact + map ===================== */

.contacto { text-align: center; }
.contacto__map {
  width: 100%; aspect-ratio: 21 / 7; min-height: 280px;
  border: 1px solid var(--color-hairline); background: var(--color-bg-raised);
}
/* The greyscale filter sits on the IFRAME, not on .contacto__map, deliberately: the
   container carries the feathered two-axis mask, border-radius and overflow of the
   contained-media group, and a filter there would open a second stacking context
   around that machinery. */
.contacto__map iframe { width: 100%; height: 100%; border: 0; filter: grayscale(1); }
@media (max-width: 680px) { .contacto__map { aspect-ratio: 4 / 5; } }

/* ===================== contact form =====================
   Floating labels are pure CSS (:placeholder-shown), so the form reads correctly
   with JS off. */
.cform__title {
  margin: clamp(12px, 1.5vw, 18px) 0 0; max-width: 16ch;
  font-weight: 300; font-size: clamp(1.6rem, 2.5vw, 2.2rem);
  line-height: 1.16; letter-spacing: -0.02em; color: var(--color-text); text-wrap: balance;
}
.cform__lede {
  margin: clamp(16px, 1.9vw, 22px) 0 0; max-width: 42ch;
  font-weight: 300; font-size: var(--fs-body-sm); line-height: 1.65;
  color: var(--color-text-secondary); text-wrap: pretty;
}

.cform { width: 100%; max-width: none; margin: 0; text-align: left; }
.cform__fields { display: flex; flex-direction: column; gap: clamp(28px, 3.4vw, 42px); }
.cform__fields[hidden] { display: none; }   /* JS toggles this on submit; explicit so display:flex doesn't defeat [hidden] */
.cform__row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(22px, 3vw, 40px); }

.cform__field { position: relative; }
.cform__input {
  display: block; width: 100%;
  background: transparent; border: none; border-bottom: 1px solid var(--color-hairline);
  border-radius: 0; outline: none; color: var(--color-text);
  font-family: var(--font-sans); font-size: var(--fs-body-sm); font-weight: 400; letter-spacing: -0.005em;
  padding: 6px 0 10px;
  transition: border-color var(--dur-fast) ease;
}
textarea.cform__input { resize: vertical; min-height: 112px; line-height: 1.6; }
.cform__input::placeholder { color: transparent; }   /* placeholder=" " exists only to drive :placeholder-shown; the label is the visible cue */
@media (max-width: 860px) {
  .cform__input { font-size: 16px; }   /* iOS zooms any focused input under 16px (covers iPad-portrait 768) */
}
.cform__input:focus-visible { outline: none; }        /* the drawn baseline + white label are the focus indicator (visible, high-contrast) */

.cform__label {
  position: absolute; left: 0; top: 6px; transform-origin: left center;
  font-weight: 300; font-size: var(--fs-body-sm); color: var(--ref-stone);
  pointer-events: none;
  transition: transform var(--dur-fast) var(--ease-soft), color var(--dur-fast) ease, letter-spacing var(--dur-fast) ease;
}
.cform__input:focus ~ .cform__label,
.cform__input:not(:placeholder-shown) ~ .cform__label {
  transform: translateY(-22px) scale(0.8);
  text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--color-text-muted);
}
.cform__input:focus ~ .cform__label { color: var(--ref-white); }

.cform__line {
  position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--ref-white); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-mid) var(--ease-gentle), background var(--dur-fast) ease;
}
.cform__input:focus ~ .cform__line { transform: scaleX(1); background: var(--ref-white); }
.cform__input:not(:placeholder-shown):not(:focus) ~ .cform__line { transform: scaleX(1); background: var(--color-hairline-strong); }

.cform__actions { display: flex; flex-direction: column; align-items: center; gap: 18px; margin-top: clamp(20px, 2.4vw, 30px); }
.cform__actions--start { align-items: flex-start; }
.cform__actions--start .cform__consent { text-align: left; }
.cform__submit { padding-inline: clamp(26px, 3vw, 40px); }
.cform__submit .arrow { margin-left: 12px; font-size: 14px; transition: transform var(--dur-fast) var(--ease-soft); }
.cform__submit:hover .arrow { transform: translateX(4px); }
.cform__consent { margin: 0; font-weight: 300; font-size: 12px; line-height: 1.6; color: var(--color-text-muted); text-align: center; }
.cform__consent a { color: var(--color-text); text-decoration: none; border-bottom: 1px solid var(--color-hairline-strong); transition: border-color var(--dur-fast) ease; }
.cform__consent a:hover { border-bottom-color: var(--cta-border-hover); }

.cform__success { text-align: center; padding: clamp(20px, 4vw, 40px) 0; }
.cform__success-mark {
  width: 46px; height: 46px; margin: 0 auto 20px; border-radius: 50%;
  border: 1px solid var(--color-hairline-strong); display: grid; place-items: center; color: var(--ref-white);
}
.cform__success-mark svg { display: block; }
.cform__success-title { margin: 0; font-weight: 400; font-size: clamp(1.2rem, 1.8vw, 1.5rem); letter-spacing: -0.01em; color: var(--ref-white); }
.cform__success-text { margin: 12px auto 0; max-width: 40ch; font-weight: 300; font-size: var(--fs-body-sm); line-height: 1.65; color: var(--color-text-secondary); }

body.reveal-ready .cform__fields > [data-reveal]:nth-child(2) { transition-delay: calc(var(--stag-item) * 1); }
body.reveal-ready .cform__fields > [data-reveal]:nth-child(3) { transition-delay: calc(var(--stag-item) * 2); }
body.reveal-ready .cform__fields > [data-reveal]:nth-child(4) { transition-delay: calc(var(--stag-item) * 3); }

@media (max-width: 640px) {
  .cform__row { grid-template-columns: 1fr; gap: clamp(28px, 8vw, 34px); }
}

/* ===================== Contactos page ===================== */
.contactos__row {
  display: flex; align-items: flex-start; gap: clamp(48px, 6vw, 88px);
  max-width: 1120px; margin: 0 auto;
}
.contactos__aside { flex: 0 0 37%; }
.contactos__form-col { flex: 1 1 auto; min-width: 0; }

.contactos__details { margin-top: clamp(34px, 4.2vw, 54px); }
.contactos__label {
  margin: 0 0 16px; font-size: var(--fs-eyebrow); font-weight: 500;
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--color-text-muted);
}
.contactos__info { font-style: normal; display: flex; flex-direction: column; gap: 14px; }
.contactos__line {
  display: flex; align-items: flex-start; gap: 12px;
  font-weight: 300; font-size: var(--fs-body-sm); line-height: 1.55; color: var(--color-text-secondary);
  text-decoration: none;
}
.contactos__line--link { color: var(--color-text); transition: color var(--dur-fast) ease; }
.contactos__line--link:hover { color: var(--ref-white); }
.contactos__icon { flex: none; width: 17px; height: 17px; margin-top: 1px; color: var(--color-text-muted); }

@media (max-width: 860px) {
  .contactos__row { flex-direction: column; gap: clamp(40px, 8vw, 56px); }
  .contactos__aside, .contactos__form-col { flex: 1 1 auto; width: 100%; }
  .contactos__aside .cform__lede { max-width: 52ch; }
}

/* ===================== Notícias page (news archive) ===================== */
.noticias__head { margin: 0 auto; text-align: center; }
.noticias__painel { max-width: 600px; margin-inline: auto; }
.noticias__title {
  margin: clamp(12px, 1.5vw, 18px) auto 0;
  font-weight: 600; font-size: clamp(0.9rem, 1.15vw, 1.2rem);
  line-height: 1.28; letter-spacing: -0.01em; color: var(--color-text); text-wrap: balance;
}
.noticias__lede {
  margin: clamp(14px, 1.7vw, 20px) auto 0; max-width: 46ch;
  font-weight: 300; font-size: var(--fs-body); line-height: 1.65;
  color: var(--color-text-secondary); text-wrap: pretty;
}

.noticia__media {
  display: block; position: relative; overflow: hidden;
  aspect-ratio: 1 / 1; margin: 0 0 18px;
  border-radius: var(--media-radius); background: var(--color-bg-raised);
}
.noticia__media img { width: 100%; height: 100%; object-fit: cover; object-position: var(--noticia-focus, 50% 50%); transition: transform var(--dur-slow) var(--ease-gentle); }
/* .noticia--retrato: the focal point for a PORTRAIT source. The y value is a fraction
   of the slack, not of the photo, so it holds at every viewport width. */
.noticia--retrato { --noticia-focus: 50% 18%; }
@media (hover: hover) { .noticia__media:hover img { transform: scale(1.04); } }
.noticia__ph {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-nav);
  text-transform: uppercase; color: var(--ref-ash); user-select: none;
}

.noticia__date {
  display: block; font-size: var(--fs-eyebrow); font-weight: 500;
  letter-spacing: var(--ls-nav); text-transform: uppercase; color: var(--color-text-muted);
}
.noticia__title { margin: 10px 0 0; font-weight: 500; font-size: clamp(1.05rem, 1.3vw, 1.25rem); line-height: 1.3; letter-spacing: -0.01em; color: var(--color-text); }
.noticia__title a { color: inherit; text-decoration: none; }
.noticia__title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.noticia__excerpt {
  margin: 10px 0 0; font-weight: 300; font-size: var(--fs-body-sm); line-height: 1.6;
  color: var(--color-text-secondary); text-wrap: pretty;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.noticia__more { margin-top: 16px; }

/* A centred flex-wrap, not a grid: 1, 2 or 3 posts all sit centred at the 3-up card
   width; a grid would pin a lone card to the left column. The column gap is a variable
   because the card basis has to subtract it. */
.noticias__grid {
  --noticias-gap-x: clamp(28px, 3vw, 44px);
  --noticias-cols: 3;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(34px, 3.6vw, 56px) var(--noticias-gap-x);
  max-width: 1180px; margin: clamp(52px, 6vw, 92px) auto 0;
}
.noticias__grid > .noticia {
  flex: 0 1 calc((100% - (var(--noticias-cols) - 1) * var(--noticias-gap-x)) / var(--noticias-cols));
  min-width: 0;
}
body.reveal-ready .noticias__grid > .noticia:nth-child(3n+2) { transition-delay: calc(var(--stag-item) * 1); }
body.reveal-ready .noticias__grid > .noticia:nth-child(3n+3) { transition-delay: calc(var(--stag-item) * 2); }

@media (max-width: 980px) { .noticias__grid { --noticias-cols: 2; } }
@media (max-width: 560px) { .noticias__grid { --noticias-cols: 1; } }

.page-pad-top { padding-top: calc(var(--nav-h) + clamp(40px, 6vw, 88px)); }

/* ===================== grupo: intro ===================== */

/* Full-bleed building plate behind the section: z-index:-1 paints above the section's
   own background and below its content. The scrim's two gradients (to the right: the
   reading panel over the building's dark mass; to the bottom: the sky) are measured
   against the photo for text contrast: re-measure before changing any stop. */
.grupo-intro { position: relative; isolation: isolate; overflow: hidden; }
.grupo-intro__bg {
  position: absolute; inset: 0; z-index: -1;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 calc(var(--nav-h) + 30px), #000 calc(100% - 96px), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 calc(var(--nav-h) + 30px), #000 calc(100% - 96px), transparent 100%);
}
.grupo-intro__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 82%;
}

@media (min-width: 821px) {
  /* The global img { max-width: 100% } reset clamps any width over 100% here, so the
     frame is pulled left, not widened. Widening it would also scale `cover` up and crop
     the roofline out of the band. */
  .grupo-intro__img {
    left: -12%;
    /* Both edges are feathered with eased (smoothstep) alpha stops, in the IMG BOX's own
       percentages (section x% sits at box x + 12). The feather only removes picture, so it
       can only darken the copy's backdrop: the scrim's measured contrast holds as a floor. */
    -webkit-mask-image: linear-gradient(to right,
        transparent 12%, rgba(0, 0, 0, 0.156) 15%, rgba(0, 0, 0, 0.5) 18%, rgba(0, 0, 0, 0.844) 21%, #000 24%,
        #000 68%, rgba(0, 0, 0, 0.844) 75.5%, rgba(0, 0, 0, 0.5) 83%, rgba(0, 0, 0, 0.156) 90.5%, rgba(0, 0, 0, 0.036) 94%, transparent 98%);
            mask-image: linear-gradient(to right,
        transparent 12%, rgba(0, 0, 0, 0.156) 15%, rgba(0, 0, 0, 0.5) 18%, rgba(0, 0, 0, 0.844) 21%, #000 24%,
        #000 68%, rgba(0, 0, 0, 0.844) 75.5%, rgba(0, 0, 0, 0.5) 83%, rgba(0, 0, 0, 0.156) 90.5%, rgba(0, 0, 0, 0.036) 94%, transparent 98%);
  }
}
.grupo-intro__mask {
  position: absolute; inset: 0;
  background:
    linear-gradient(to right,
      rgba(10, 10, 10, 0.18) 0%,
      rgba(10, 10, 10, 0.26) 26%,
      rgba(10, 10, 10, 0.70) 45%,
      rgba(10, 10, 10, 0.95) 60%,
      rgba(10, 10, 10, 0.97) 100%),
    linear-gradient(to bottom,
      rgba(10, 10, 10, 0.70) 0%,
      rgba(10, 10, 10, 0.22) 30%,
      rgba(10, 10, 10, 0.06) 60%,
      rgba(10, 10, 10, 0.28) 100%);
}

.grupo-intro__row { display: flex; align-items: center; justify-content: flex-end; gap: 6vw; }
.grupo-intro__photo { width: 40%; flex: none; }
.grupo-intro__ph {
  position: relative; width: 100%; aspect-ratio: 4 / 5;
  border: 1px solid var(--color-hairline); background: var(--color-bg-raised);
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 0 24px; line-height: 1.6;
  font-size: var(--fs-eyebrow); letter-spacing: var(--ls-nav); text-transform: uppercase; color: var(--ref-ash);
}
.grupo-intro__text { width: 50%; flex: none; }
.grupo-intro__title {
  margin: 18px 0 0; font-weight: 500; font-size: clamp(1.2rem, 1.7vw, 1.6rem);
  line-height: 1.28; letter-spacing: -0.01em; color: var(--color-text); text-wrap: balance;
}
.grupo-intro__body {
  margin: 18px 0 0; font-weight: 400; font-size: clamp(13.5px, 0.92vw, 15px);
  line-height: 1.65; color: var(--color-text-secondary); max-width: 58ch; text-wrap: pretty;
}
/* intro "Ler mais" collapse (mobile only, wired in the <=760 block below): desktop shows all
   three paragraphs and never the toggle. display:contents keeps the paragraph rhythm untouched. */
.grupo-intro__toggle { display: none; }
.grupo-intro__more, .grupo-intro__more-inner { display: contents; }


@media (max-width: 820px) {
  .grupo-intro__row { flex-direction: column; align-items: flex-start; gap: 48px; }
  .grupo-intro__photo, .grupo-intro__text { width: 100%; }
  .grupo-intro__photo { max-width: 380px; }

  /* Stacked: the copy is full-width, so the desktop to-right ramp no longer covers it, and
     the sky is in shot at every phone size. A near-flat veil, 0.90 -> 0.84, keeps the
     #9A9A9A eyebrow at about 5.3:1 over the brightest sky; 0.80 would fail 4.5:1. */
  .grupo-intro__img { transform: scale(1.35); transform-origin: 50% 100%; }
  .grupo-intro__mask {
    background: linear-gradient(to bottom,
      rgba(10, 10, 10, 0.87) 0%,
      rgba(10, 10, 10, 0.84) 45%,
      rgba(10, 10, 10, 0.86) 100%);
  }
}

/* --- mobile (<=760): the intro body starts collapsed at paragraph 1, "Ler mais" reveals
   the rest --- */
@media (max-width: 760px) {
  .grupo-intro__more { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-base) var(--ease-gentle); }
  .grupo-intro__more.is-open { grid-template-rows: 1fr; }
  .grupo-intro__more-inner { display: block; min-height: 0; overflow: hidden; }
  .grupo-intro__toggle {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 20px; min-height: 44px; padding: 6px 0;
    background: none; border: 0; cursor: pointer; font-family: inherit;
    font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase; color: var(--ref-white-70);
    -webkit-tap-highlight-color: transparent; transition: color var(--dur-fast) ease;
  }
  .grupo-intro__toggle:hover { color: var(--ref-white); }
  .grupo-intro__toggle-caret { flex: none; transition: transform var(--dur-base) var(--ease-gentle); }
  .grupo-intro__toggle[aria-expanded="true"] .grupo-intro__toggle-caret { transform: rotate(180deg); }
}

/* ===================== grupo: historia timeline ===================== */

.grupo-intro { padding-bottom: clamp(64px, 8vw, 116px); }
.grupo-historia {
  background: var(--color-bg); color: var(--color-text);
  padding-bottom: clamp(64px, 7vw, 104px);
}
.tl-head {
  padding: clamp(16px, 2vw, 32px) var(--pad-edge) 0;
  text-align: center;
}
.tl-head__title {
  margin: 20px 0 0; font-weight: 600; font-size: clamp(0.9rem, 1.15vw, 1.2rem);
  line-height: 1.28; letter-spacing: -0.01em; color: var(--color-text); text-wrap: balance;
}
.tl-head__lede {
  margin: 26px auto 0; font-weight: 300; font-size: var(--fs-body); line-height: 1.65;
  color: var(--color-text-muted); max-width: 60ch; text-wrap: pretty;
}
.tl-head__painel { max-width: 700px; margin-inline: auto; }
.tl-head__heading { display: contents; }

/* --- ambient chapter-opener plate --- */
.tl-head--ambient {
  position: relative; isolation: isolate; overflow: hidden;
  /* 45vw frames the plate's buildings (they fill y 25%..91% of the file); it pairs with
     the 90% object-position in .tl-head__bg img: change them together. */
  min-height: max(420px, min(100svh, 45vw));
  display: flex; flex-direction: column; justify-content: center;
  padding-left: 0; padding-right: 0;
}
.tl-head__bg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  --amb-feather: clamp(80px, 13vh, 170px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--amb-feather), #000 calc(100% - var(--amb-feather)), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 var(--amb-feather), #000 calc(100% - var(--amb-feather)), transparent 100%);
}
.tl-head__bg img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  /* 90% = spend the band's vertical overflow on the TOP: ~18% of the plate is cropped off the
     empty void above the roofs and only ~2% off the base. Shared by both breakpoints so the
     framing is identical on desktop and mobile. Lower it toward 50% to re-admit the void. */
  object-position: center 90%;
}
.tl-head__bg::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse 56% 62% at 50% 50%,
    rgba(10, 10, 10, 0.72) 0%, rgba(10, 10, 10, 0.42) 46%, rgba(10, 10, 10, 0) 78%);
}
.tl-head--ambient .tl-head__painel { position: relative; z-index: 1; padding-inline: var(--pad-edge); }
/* Desktop: the copy fits inside the plate's dark corridor (~30% of the file's width
   through y27..67%, ~24% lower down). The plate takes no horizontal crop, so
   image-% == vw and the measure is set in vw. The <=760 layout is a different composition. */
@media (min-width: 761px) {
  .tl-head--ambient {
    --amb-measure: 24vw;   /* content width, leaving ~2.5vw of air to each facade */
    /* Centre the copy on the CORRIDOR's wide zone, not on the band: the channel pinches below
       y67%, so the block is lifted by (padding-bottom - padding-top) / 2. */
    padding-bottom: max(9rem, 6vw);
  }
  .tl-head--ambient .tl-head__painel {
    max-width: var(--amb-measure);
    padding-inline: 0;     /* the measure IS the corridor; no edge padding to subtract from it */
  }
  .tl-head--ambient .tl-head__lede { max-width: none; }
}
/* "ambient": the entrance for a FULL-BLEED PLATE, a compositor-only glide (opacity plus a
   faint rise-and-zoom). Its own variant so the plate does NOT inherit the default
   translateY on the masked layer, which would drag the feather with it.
   It ties the base [data-reveal] rule on specificity and wins on source order: moving it
   would silently disarm it.
   The rise/zoom uses `translate` and `scale`, NOT `transform`: these plates carry their
   own transform (the Sobre Nós img is scale(1.35) on phones), which a `transform` here,
   and `.is-revealed { transform: none }`, would wipe. */
body.reveal-ready [data-reveal="ambient"] {
  opacity: 0; transform: none;
  transition: opacity var(--dur-xslow) var(--ease-gentle);
  will-change: opacity;
}
body.reveal-ready [data-reveal="ambient"].is-revealed { opacity: 1; }
body.reveal-ready [data-reveal="ambient"] img {
  translate: 0 22px; scale: 1.05;
  transition: translate 1800ms var(--ease-gentle), scale 1800ms var(--ease-gentle);
  will-change: translate, scale;
}
body.reveal-ready [data-reveal="ambient"].is-revealed img { translate: none; scale: none; }
@media (max-width: 760px) {
  .tl-head--ambient {
    min-height: 0; display: block;
    padding-top: 0; padding-bottom: 0;
  }
  .tl-head__bg {
    position: relative;
    /* 753 = 941 x 0.8, the same 80% window the desktop band frames. Keep it in step with
       the desktop 45vw and the shared object-position. */
    inset: 0 0 auto 0; height: auto; aspect-ratio: 1672 / 753;
    --amb-feather: clamp(18px, 5vw, 44px);
  }
  .tl-head__bg img { object-fit: cover; }
  .tl-head__bg::after { content: none; }
  .tl-head__heading { display: block; margin-top: clamp(8px, 3vw, 20px); }
  .tl-head__lede { margin-top: clamp(18px, 5vw, 28px); max-width: 46ch; }
}

.tl { position: relative; margin-top: clamp(26px, 2.6vw, 38px); }
.tl__viewport {
  position: relative; overflow: hidden;
  /* The axis is centred, so each half is height/2 and a card hangs off it at 50%+20px.
     Floor/cap keep >=44px clearance under the tallest card at 1512 and 1920. Do not go
     below ~420px: the cards are absolutely positioned inside overflow:hidden and would
     clip, and this copy is client-editable, so a longer entry must still fit. */
  height: clamp(560px, 55vh, 600px); margin: 0 var(--pad-edge);
}
.tl__track {
  position: relative; height: 100%; display: flex; width: max-content; will-change: transform;
  transition: transform 0.52s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.tl__axis { position: absolute; top: 50%; left: 0; width: 100%; height: 1px; background: var(--color-hairline); transform: translateY(-0.5px); }
/* the stream of light replicates the produção chain fill; width is paging-driven (initTimeline) */
.tl__progress {
  position: absolute; top: 50%; left: 0; width: 0; height: 1px;
  background: linear-gradient(to right, var(--ref-white-55) 0, var(--ref-white-55) calc(100% - 48px), transparent 100%);
  transform: translateY(-0.5px); transition: width 0.52s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* the mobile vertical stream (scroll-driven, initGrupoTimeline); desktop uses .tl__progress */
.tl__fill { display: none; }

.tl__col { position: relative; flex: none; width: var(--tl-col-w, 360px); height: 100%; opacity: 0.22; transition: opacity 0.5s ease; }
.tl__col.is-seen { opacity: 1; }
.tl__card { position: absolute; left: 0; right: 0; display: flex; flex-direction: column; gap: 6px; max-width: 36ch; padding-right: 22px; }
.tl__col.is-above .tl__card { bottom: calc(50% + 20px); }
.tl__col.is-below .tl__card { top: calc(50% + 20px); }
.tl__year { font-weight: 600; font-size: clamp(1.1rem, 1.35vw, 1.4rem); line-height: 1; color: var(--color-text); }
.tl__body { margin: 0; font-weight: 300; font-size: clamp(0.76rem, 0.82vw, 0.85rem); line-height: 1.5; color: var(--color-text-muted); text-wrap: pretty; }
.tl__dot {
  position: absolute; top: 50%; left: 0; width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid var(--ref-white); background: var(--color-bg); transform: translateY(-50%);
  transition: background 0.5s ease, box-shadow 0.5s ease;
}
.tl__col.is-seen .tl__dot { background: var(--ref-white); box-shadow: 0 0 0 3px var(--ref-white-06); }

.tl__fade { position: absolute; top: 0; width: 44px; height: 100%; pointer-events: none; opacity: 0; transition: opacity 0.4s ease; }
.tl__fade--left { left: 0; background: linear-gradient(to left, transparent, var(--color-bg)); }
.tl__fade--right { right: 0; background: linear-gradient(to right, transparent, var(--color-bg)); }
.tl__fade.is-on { opacity: 1; }

.tl__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--color-bg); border: 1px solid var(--cta-border); color: var(--ref-white);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: border-color 0.3s ease, opacity 0.35s ease;
}
.tl__arrow:hover { border-color: var(--cta-border-hover); }
.tl__arrow--back { left: max(2px, calc((var(--pad-edge) - 38px) / 2)); }
.tl__arrow--fwd { right: max(2px, calc((var(--pad-edge) - 38px) / 2)); }
.tl__arrow[disabled] { opacity: 0; pointer-events: none; }

/* mobile (<=760px, matches VERTICAL_MAX in app.js): the horizontal carousel
   becomes a simple vertical timeline, stacked and scrolled, no paging. The JS
   guard clears the carousel's inline transform/colW so this layout is clean. */
@media (max-width: 760px) {
  .tl { margin-top: clamp(42px, 9vw, 68px); }
  .tl__viewport { overflow: visible; height: auto; margin: 0 var(--pad-edge); }
  .tl__track { display: block; width: auto; height: auto; transform: none; }
  .tl__axis { top: 8px; bottom: 6px; left: 4px; width: 1px; height: auto; transform: none; }
  .tl__progress, .tl__fade, .tl__arrow { display: none; }
  /* the produção-replica stream, vertical: same fill, same soft leading edge.
     Height driven by initGrupoTimeline as the page scrolls. */
  .tl__fill {
    display: block; position: absolute; top: 8px; left: 4px; width: 1px; height: 0; z-index: 1;
    background: linear-gradient(to bottom, var(--ref-white-55) 0, var(--ref-white-55) calc(100% - 48px), transparent 100%);
  }
  .tl.is-static .tl__fill { bottom: 6px; height: auto; }
  .tl__col { width: auto; height: auto; opacity: 1; padding: 0 0 clamp(28px, 7vw, 40px) 30px; }
  .tl__col:last-child { padding-bottom: 0; }
  .tl__card { position: static; max-width: none; padding-right: 0; }
  .tl__col.is-above .tl__card, .tl__col.is-below .tl__card { position: static; }
  .tl__dot { top: 8px; left: 0; transform: none; }
}

/* ===================== produção: hero ===================== */

.prod-hero {
  position: relative; overflow: hidden; background: var(--color-bg);
  min-height: 100vh;
  min-height: 100svh;   /* stable on mobile address-bar show/hide; vh line = fallback */
  display: flex; align-items: center; justify-content: center;
}
.prod-hero__media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center; transform: scale(1.08);
}
@media (max-width: 760px) {
  /* no parallax on touch (app.js clears the inline transform ≤760); the 1.08
     crop only existed as parallax headroom, so mobile shows the frame clean */
  .prod-hero__media { transform: none; }
}
.prod-hero__scrim { position: absolute; left: 0; right: 0; z-index: 2; pointer-events: none; }
.prod-hero__scrim--top { top: 0; height: 34%; background: linear-gradient(to bottom, rgba(10, 10, 10, 0.6), transparent); }
.prod-hero__scrim--center { inset: 0; background: radial-gradient(ellipse 75% 60% at 50% 50%, rgba(10, 10, 10, 0.72) 0%, rgba(10, 10, 10, 0.42) 42%, rgba(10, 10, 10, 0.12) 72%, transparent 100%); }
.prod-hero__text {
  /* in-flow, flex-centred by .prod-hero: stable through address-bar reflow (an absolute
     top:50% + translate re-centres on every vh change) */
  position: relative; z-index: 4; width: min(94vw, 1220px);
  text-align: center;
}
.prod-hero__title {
  margin: 0 auto; text-wrap: balance; color: var(--color-text);
  font-size: var(--fs-hero-phrase); font-weight: var(--fw-hero-phrase);
  letter-spacing: var(--ls-hero-phrase); text-transform: var(--tt-hero-phrase);
  line-height: var(--lh-hero-phrase);
}
/* the "ray": its bright fill is driven by the SAME viewport-centre fill line as the chain
   (initProducao), so the leading edge flows from the phrase into the chain with no seam. */
.prod-hero__ray {
  position: absolute; left: 50%; transform: translateX(-50%); z-index: 3;
  top: calc(50% + clamp(34px, 5vh, 54px)); bottom: 0; width: 1px; pointer-events: none;
}
.prod-hero__ray-track {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, transparent 0, var(--color-hairline) 44px, var(--color-hairline) 100%);
}
/* height set by initProducao; soft fade-in from the phrase (top 44px) + soft leading edge (last 40px) */
.prod-hero__ray-fill {
  position: absolute; top: 0; left: 0; width: 100%; height: 0;
  background: linear-gradient(to bottom, transparent 0, var(--ref-white-55) 44px, var(--ref-white-55) calc(100% - 40px), transparent 100%);
}

/* ===================== produção: process chain ===================== */
/* A continuous centre hairline, a scroll-grown fill + glow head, and ten services
   alternating image/text sides, each with a node on the line. JS (initProducao) drives
   fill height, glow position and node lit-state. */

.prod-chain {
  position: relative; isolation: isolate;   /* own stacking context: lets the R&D hero photo sit at z-index:-1 ABOVE this bg but below the line/fill/rail */
  background: var(--color-bg); padding: clamp(80px, 12vh, 120px) 0 100px;
  /* geometry shared by the stages + the index rail: at >=1100px the outer gutter grows to
     clear the fixed rail */
  --prod-rail-w: clamp(150px, 13vw, 190px);
  --prod-outer: 9vw;
  --prod-inner: clamp(40px, 5.5vw, 80px);
}
@media (min-width: 1100px) { .prod-chain { --prod-outer: calc(var(--prod-rail-w) + 2vw); } }
.prod-chain__line, .prod-chain__fill, .prod-chain__glow { position: absolute; left: 50%; transform: translateX(-50%); pointer-events: none; }
.prod-chain__line {
  top: 0; bottom: 0; width: 1px; z-index: 0;
  background: linear-gradient(to bottom, transparent 0, var(--color-hairline) 150px, var(--color-hairline) calc(100% - 150px), transparent 100%);
}
.prod-chain__fill {
  top: 0; width: 1px; height: 0; z-index: 1;
  background: linear-gradient(to bottom, var(--ref-white-55) 0, var(--ref-white-55) calc(100% - 48px), transparent 100%);
}
/* the glow head stays in the DOM/JS but hidden; the fill's soft edge carries the frontier */
.prod-chain__glow { display: none; }
.prod-chain.is-static .prod-chain__fill { height: 100%; }
.prod-chain.is-static .prod-chain__glow { display: none; }

.prod-stage { position: relative; display: flex; flex-direction: row; margin-bottom: clamp(120px, 15vw, 190px); scroll-margin-top: clamp(40px, 10vh, 104px); }   /* low enough that a landed stage's node sits ABOVE the 50vh fill line -> the spy marks the clicked item */
.prod-stage:last-child { margin-bottom: 0; }

.prod-stage__node {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 5;
  width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid var(--ref-white-28); background: var(--color-bg);
  transition: border-color var(--dur-base) var(--ease-soft), background var(--dur-base) var(--ease-soft), box-shadow var(--dur-base) var(--ease-soft);
}
.prod-stage__node.is-lit {
  border-color: var(--ref-white); background: var(--ref-white);
  box-shadow: 0 0 5px 1px var(--ref-white-28), 0 0 14px 3px var(--ref-white-06);
}

.prod-stage:nth-of-type(even) .prod-stage__media { order: 2; justify-content: flex-end; padding: 0 var(--prod-outer) 0 var(--prod-inner); }
.prod-stage:nth-of-type(even) .prod-stage__text { order: 1; padding: 0 var(--prod-inner) 0 var(--prod-outer); }
.prod-stage:nth-of-type(even) .prod-stage__inner { align-self: flex-start; text-align: left; }

.prod-stage__name { margin: 0 0 14px; font-weight: 600; font-size: 16px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--color-text); }
.prod-stage__desc { margin: 0; font-weight: 300; font-size: 14px; line-height: 1.75; color: var(--color-text-muted); max-width: 46ch; }

/* ---- stage as full-viewport BACKGROUND photo (z-index:-1): the centre line, node and
   índice rail run over it unchanged ---- */
.prod-stage--hero {
  position: relative; display: block; overflow: hidden;
  width: 100vw; margin-left: calc(50% - 50vw);
  min-height: 100vh; min-height: 100svh;
  margin-bottom: clamp(120px, 15vw, 190px);
}
/* only the FIRST hero (R&D) is pulled flush under the video hero to kill the black stripe;
   the other nine keep the normal inter-stage gap so they never overlap the step above */
.prod-stage--hero:first-of-type { margin-top: calc(-1 * clamp(80px, 12vh, 120px)); }

/* Step 1: the band is never wider than its plate's own 16:9. On a wider window it grows
   to 56.25vw so `cover` crops nothing; on a ~16:9 window it is a no-op.
   Knob = 56.25vw (the plate's h/w). */
#servico-rd.prod-stage--hero { min-height: max(100vh, 56.25vw); min-height: max(100svh, 56.25vw); }

/* Steps 2 + 3: same knob. The vw value is ALWAYS the wired plate's own height/width, so it
   is not free: re-derive it whenever a plate is swapped, or the band silently re-crops.
   Steps 1 to 3 share the 1672x941 geometry and one constant. */
#servico-modelagem.prod-stage--hero { min-height: max(100vh, 56.25vw); min-height: max(100svh, 56.25vw); }
#servico-corte.prod-stage--hero { min-height: max(100vh, 56.25vw); min-height: max(100svh, 56.25vw); }
.prod-stage--hero .prod-stage__node { opacity: 1; }

.prod-hero-svc__bg {
  position: absolute; inset: 0; z-index: -1;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 10vh, #000 calc(100% - 16vh), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 10vh, #000 calc(100% - 16vh), transparent 100%);
}
.prod-hero-svc__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.prod-hero-svc__mask {
  position: absolute; inset: 0;
  background: linear-gradient(115deg, rgba(10, 10, 10, 0.78) 0%, rgba(10, 10, 10, 0.72) 50%, rgba(10, 10, 10, 0.62) 100%);
}

/* content layer: above the line/fill (z3), below the node/rail; "1" centred left, text centred right */
.prod-hero-svc__grid {
  position: absolute; inset: 0; z-index: 3;
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
}
.prod-hero-svc__col { display: flex; align-items: center; justify-content: center; }
.prod-hero-svc__num {
  font-weight: 200; font-size: clamp(140px, 20vw, 300px); line-height: 0.8;
  letter-spacing: -0.03em; color: var(--ref-white);
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.85), 0 0 12px rgba(0, 0, 0, 0.7), 0 2px 50px rgba(0, 0, 0, 0.6);
}
.prod-hero-svc__inner { max-width: 42ch; }
.prod-hero-svc__name { color: var(--ref-white); text-shadow: 0 1px 24px rgba(0, 0, 0, 0.7); }
.prod-hero-svc__desc { color: var(--ref-cloud); font-size: 15px; max-width: 42ch; text-shadow: 0 1px 20px rgba(0, 0, 0, 0.7); }
body.reveal-ready .prod-hero-svc__grid[data-reveal] { opacity: 1; transform: none; }
body.reveal-ready .prod-hero-svc__num,
body.reveal-ready .prod-hero-svc__inner {
  opacity: 0; transform: translateY(18px);
  transition: opacity var(--dur-mid) ease, transform var(--dur-mid) var(--ease-gentle);
}
body.reveal-ready .prod-hero-svc__grid.is-revealed .prod-hero-svc__num { opacity: 1; transform: none; transition-delay: 120ms; }
body.reveal-ready .prod-hero-svc__grid.is-revealed .prod-hero-svc__inner { opacity: 1; transform: none; transition-delay: 220ms; }
@media (max-width: 760px) {
  /* Mobile: each step's photo stays a full-bleed background with the text overlaid, in a
     shorter ~4:3 band so a 16:9 plate keeps ~75% of its width. */
  .prod-stage.prod-stage--hero { min-height: 0; aspect-ratio: 6 / 5; margin-bottom: 14px; padding: 0; }   /* 2-class specificity beats the ≤900 .prod-stage rule; taller band (bigger image) + tight gap */
  .prod-stage--hero:first-of-type { margin-top: calc(-1 * clamp(56px, 10vh, 80px)); }

  /* Step 1 on mobile: a 3/2 band keeps ~84% of the 16:9 plate's width.
     Knob = this ratio (toward 16/9 = less crop, shorter). */
  /* min-height:0 must be repeated here: the desktop #servico-rd rule is an ID selector, so it
     out-specifies the .prod-stage.prod-stage--hero reset above and its max(100svh,56.25vw)
     would otherwise keep this band full-height and make the crop far WORSE, not better. */
  #servico-rd.prod-stage.prod-stage--hero { min-height: 0; aspect-ratio: 3 / 2; }

  /* Steps 2 + 3 join step 1 on the 3/2 band (all three plates share 1672x941). Same
     min-height:0 repetition, same reason: the desktop ID rules out-specify the
     .prod-stage.prod-stage--hero reset. */
  #servico-modelagem.prod-stage.prod-stage--hero,
  #servico-corte.prod-stage.prod-stage--hero { min-height: 0; aspect-ratio: 3 / 2; }

  /* full-bleed background, top+bottom edges blurred into the black like desktop | desktop's 10vh/16vh
     feather would swallow a short band, so use band-proportional % (same ~10%/15% top/bottom ratio) */
  .prod-hero-svc__bg {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 85%, transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 85%, transparent 100%);
  }
  .prod-hero-svc__mask { background: linear-gradient(to top, rgba(10, 10, 10, 0.92) 0%, rgba(10, 10, 10, 0.5) 28%, rgba(10, 10, 10, 0) 62%); }

  .prod-hero-svc__grid { grid-template-columns: 1fr; align-content: end; padding: 0 6vw 22px 52px; }
  /* The ball is anchored to the TOP of the text block (the title is always one line), not
     to the band: the copy is bottom-loaded, so its distance from the band edge varies.
     11px is the RESTING position: __inner carries the reveal's translateY(18px) until
     .is-revealed lands, so never calibrate against an unrevealed stage.
     left:-28px = 52px grid padding - 28 = the 24px chain line; the -50% x translate lands
     the ball's centre on it. The node keeps its real geometry because initProducao lights it
     when the fill passes its centre. Desktop: .prod-hero-svc__col is unpositioned, so the
     node still resolves against .prod-hero-svc__grid. */
  .prod-hero-svc__col--text { position: relative; }
  .prod-stage--hero .prod-stage__node { top: 11px; left: -28px; transform: translate(-50%, -50%); }
  .prod-hero-svc__col { justify-content: flex-start; }
  .prod-hero-svc__num { font-size: clamp(60px, 16vw, 96px); line-height: 0.82; }
  .prod-hero-svc__inner { max-width: none; margin-top: 2px; }
}

/* ----- o índice: services rail -----
   Sticky at the viewport centre INSIDE .prod-chain, so it appears and leaves with the
   chain. height:0 keeps it out of flow; the list hangs centred via translateY.
   Scroll-spy (initProducao) toggles .is-current; links are plain anchors (no-JS safe). */
.prod-index { position: sticky; top: 50vh; height: 0; z-index: 6; }
/* JS-gated fade (reveal-ready = the engine is live): hidden until the chain reaches the
   viewport centre, out again before the CTA. No-JS never gets reveal-ready -> rail always
   visible; reduced-motion (initProducao early-returns, no .is-in) forced visible below. */
body.reveal-ready .prod-index { opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease-soft); }
body.reveal-ready .prod-index.is-in { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) {
  body.reveal-ready .prod-index { opacity: 1; pointer-events: auto; transition: none; }
}
.prod-index__list {
  list-style: none; margin: 0; padding: 0;
  position: absolute; left: clamp(24px, 2.5vw, 36px); top: 0; transform: translateY(-50%);
  width: calc(var(--prod-rail-w) - clamp(24px, 2.5vw, 36px));
  display: flex; flex-direction: column; gap: clamp(8px, 1vh, 12px);
}
.prod-index__link {
  position: relative; display: inline-block; padding-left: 18px;
  font-size: 11px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase;
  line-height: 1.5; color: var(--ref-stone); text-decoration: none;
  transition: color var(--dur-fast) var(--ease-soft);
}
.prod-index__link::before {
  content: ''; position: absolute; left: 0; top: 0.7em; width: 10px; height: 1px;
  background: currentColor; opacity: 0; transform: scaleX(0.4); transform-origin: left center;
  transition: opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-soft);
}
.prod-index__link:hover { color: var(--color-text-muted); }
.prod-index__link.is-current { color: var(--ref-white); }
.prod-index__link.is-current::before { opacity: 1; transform: scaleX(1); }
@media (max-width: 1099px) { .prod-index { display: none; } }

.prod-cta { text-align: center; padding-top: 0; }

@media (max-width: 900px) {
  .prod-chain { padding: clamp(56px, 10vh, 80px) 0 72px; }
  .prod-chain__line, .prod-chain__fill { left: 24px; transform: none; }
  .prod-chain__glow { display: none; }
  /* the centred ray can't meet the left-aligned mobile chain line, so it is hidden here;
     the centred scroll cue stays */
  .prod-hero__ray { display: none; }

  .prod-stage { flex-direction: column; margin-bottom: 64px; padding: 0 6vw 0 56px; }
  .prod-stage__media, .prod-stage:nth-of-type(even) .prod-stage__media { order: 1; padding: 0; justify-content: flex-start; }
  .prod-stage__text, .prod-stage:nth-of-type(even) .prod-stage__text { order: 2; padding: 28px 0 0; }
  .prod-stage__node { left: 24px; top: 6px; transform: translate(-50%, 0); }
  .prod-stage__inner, .prod-stage:nth-of-type(even) .prod-stage__inner { max-width: none; align-self: flex-start; text-align: left; }
  .prod-stage__name { font-size: 14px; }
  .prod-stage__desc { font-size: 13px; line-height: 1.7; max-width: none; }
}

/* ===================== nav: "Sustentabilidade" dropdown ===================== */
.nav__item--has-menu { position: relative; display: inline-flex; align-items: center; }
/* Anchored to the parent's RIGHT edge, not centred: a label of any length (a rename, a
   translation) keeps its last letter under the last letter of SUSTENTABILIDADE. The right
   padding is the parent link's side padding minus the item's, written in tokens so the
   relation survives a padding change. */
.nav__menu {
  position: absolute; top: 100%; right: 0;
  display: flex; flex-direction: column; align-items: stretch;
  min-width: 210px; gap: 8px;
  padding: 12px calc(var(--nav-link-pad-x) - var(--nav-menu-item-pad-x)) 12px 14px;
  visibility: hidden; pointer-events: none;
  transition: visibility 0s linear var(--dur-base);
}
.nav__item--has-menu:hover .nav__menu,
.nav__item--has-menu:focus-within .nav__menu {
  visibility: visible; pointer-events: auto;
  transition: visibility 0s;
}
.nav__menu-link, .nav__lang-opt {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  font-size: var(--fs-nav); font-weight: 500; letter-spacing: var(--ls-nav);
  text-transform: uppercase; color: var(--ref-mist); text-decoration: none;
  background: none; border: 0; cursor: pointer; font-family: inherit;
  padding: 4px var(--nav-menu-item-pad-x); white-space: nowrap;
  opacity: 0; transform: translateY(-6px);
  transition: opacity var(--dur-base) var(--ease-gentle),
              transform var(--dur-base) var(--ease-gentle),
              color var(--dur-fast) var(--ease-soft);
}
.nav__menu-link:hover, .nav__lang-opt:hover { color: var(--ref-white); }
.nav__item--has-menu:hover .nav__menu-link,
.nav__item--has-menu:focus-within .nav__menu-link,
.nav__lang:hover .nav__lang-opt,
.nav__lang.is-open .nav__lang-opt,
.nav__lang:focus-within .nav__lang-opt { opacity: 1; transform: translateY(0); }
.nav__item--has-menu:hover .nav__menu-link:nth-child(2),
.nav__item--has-menu:focus-within .nav__menu-link:nth-child(2),
.nav__lang:hover .nav__lang-opt:nth-child(2),
.nav__lang.is-open .nav__lang-opt:nth-child(2),
.nav__lang:focus-within .nav__lang-opt:nth-child(2) { transition-delay: calc(var(--stag-item) * 1), calc(var(--stag-item) * 1), 0s; }
.nav__item--has-menu:hover .nav__menu-link:nth-child(3),
.nav__item--has-menu:focus-within .nav__menu-link:nth-child(3) { transition-delay: calc(var(--stag-item) * 2), calc(var(--stag-item) * 2), 0s; }

/* ---- mobile (<=860px): the flyout becomes the dropdown-card ACCORDION ----
   Placed AFTER the desktop flyout rules above so these equal-specificity overrides win
   the cascade. */
@media (max-width: 860px) {
  .nav__item--has-menu { display: block; position: static; }
  .nav__row { display: flex; align-items: stretch; border-bottom: 1px solid var(--ref-white-10); }
  .nav__row .nav__link { flex: 1 1 auto; border-bottom: 0; }
  .nav__caret {
    display: flex; flex: none; width: 44px; min-height: 48px;
    align-items: center; justify-content: center;
    background: none; border: 0; cursor: pointer; color: var(--ref-white-55);
    -webkit-tap-highlight-color: transparent;
    opacity: 0; transition: opacity var(--dur-base) ease, color var(--dur-fast) ease;
  }
  body.nav-open .nav__caret { opacity: 1; transition-delay: 165ms; }
  .nav__caret svg { display: block; transition: transform var(--dur-base) var(--ease-gentle); }
  .nav__item--has-menu.is-sub-open .nav__caret svg { transform: rotate(180deg); }
  .nav__menu {
    position: static; left: auto; right: auto; top: auto; transform: none;
    visibility: visible; pointer-events: auto;
    min-width: 0; padding: 0; margin: 0; gap: 0;
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-base) var(--ease-gentle);
  }
  .nav__item--has-menu.is-sub-open .nav__menu { grid-template-rows: 1fr; }
  .nav__menu-inner { display: block; min-height: 0; overflow: hidden; }
  .nav__menu-list { display: block; padding: 2px 0 6px 16px; border-bottom: 1px solid var(--ref-white-10); }
  .nav__menu-link {
    display: flex; align-items: center; min-height: 40px; padding: 8px 2px;
    font-size: 0.8rem; font-weight: 300; letter-spacing: 0.06em;
    text-transform: none;
    color: var(--ref-white-55); justify-content: flex-start;
    -webkit-tap-highlight-color: transparent;
    opacity: 0; transform: translateX(16px);
    transition: opacity var(--dur-base) ease, transform var(--dur-base) var(--ease-gentle), color var(--dur-fast) ease;
  }
  .nav__item--has-menu.is-sub-open .nav__menu-link { opacity: 1; transform: translateX(0); }
  .nav__item--has-menu.is-sub-open .nav__menu-link:nth-child(1) { transition-delay: 40ms; }
  .nav__item--has-menu.is-sub-open .nav__menu-link:nth-child(2) { transition-delay: 90ms; }
  .nav__item--has-menu.is-sub-open .nav__menu-link:nth-child(3) { transition-delay: 140ms; }
}

/* ===================== sustentabilidade: hero ===================== */
.sus-hero {
  position: relative; width: 100%; overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;   /* stable on mobile address-bar show/hide; vh line = fallback */
  background: var(--ref-ink);
  display: flex; align-items: center; justify-content: center;
}
.sus-hero__media { position: absolute; inset: 0; }
.sus-hero__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 44%, rgba(10,10,10,0) 44%, rgba(10,10,10,0.5) 100%),
    linear-gradient(180deg, rgba(10,10,10,0.5) 0%, rgba(10,10,10,0.1) 28%, rgba(10,10,10,0.26) 62%, rgba(10,10,10,0.96) 100%);
}
.sus-hero__inner {
  position: relative; z-index: 2;
  padding: 0 var(--pad-edge); text-align: center;
}
.sus-hero__title {
  margin: 0 auto; text-wrap: balance; color: var(--color-text);
  font-size: var(--fs-hero-phrase); font-weight: var(--fw-hero-phrase);
  letter-spacing: var(--ls-hero-phrase); text-transform: var(--tt-hero-phrase);
  line-height: var(--lh-hero-phrase);
}
.sus-hero__cue {
  position: absolute; z-index: 3; left: 50%;
  bottom: clamp(22px, 4vh, 40px);
  bottom: calc(clamp(22px, 4vh, 40px) + env(safe-area-inset-bottom));   /* clear the iOS home indicator */
  transform: translateX(-50%);
  display: inline-flex; align-items: center; justify-content: center; padding: 10px;
  color: var(--ref-white-70); text-decoration: none;
  transition: color var(--dur-fast) var(--ease-soft);
}
.sus-hero__cue:hover { color: var(--ref-white); }
.sus-hero__cue-arrow { display: block; animation: susCueBob 2.4s var(--ease-inout) infinite; }
@keyframes susCueBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@media (prefers-reduced-motion: reduce) { .sus-hero__cue-arrow { animation: none !important; } }
/* __img is the still twin of __video: deliberately one selector rather than a copy, so
   the two can never drift apart. Reduced motion pauses the video (app.js calmVideos). */
.sus-hero__video, .sus-hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* No phone reframe for this plate: it fills the hero edge to edge like the other heroes. */

/* ===================== sustentabilidade + projetos: beat anchors ===================== */
/* Every beat carries .sus-beat; its scroll-margin-top clears the fixed main nav on mobile.
   Desktop nav is absolute (scrolls away), so no desktop offset is needed. */
.sus-beat { scroll-margin-top: 0; }

/* ===================== sustentabilidade: O nosso compromisso ===================== */
.sus-compromisso__grid {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  max-width: 1000px; margin: 0 auto;
}
.sus-compromisso__eyebrow { margin-bottom: clamp(20px, 2.4vw, 30px); }
.sus-compromisso__statement {
  margin: 0 0 clamp(28px, 3.4vw, 40px); max-width: none;
  font-weight: 700; font-size: clamp(15px, 1.45vw, 19px);
  line-height: 1.4; letter-spacing: -0.005em; color: var(--color-text);
}
.sus-compromisso__painel { width: 100%; max-width: 920px; margin-inline: auto; }
.sus-compromisso__body {
  margin: 0 auto; max-width: 64ch;
  display: flex; flex-direction: column; gap: clamp(14px, 1.4vw, 20px);
}
.sus-compromisso__body p {
  margin: 0; font-weight: 400; font-size: var(--fs-body); line-height: 1.65;
  color: var(--color-text-secondary); text-wrap: pretty;
}
body.reveal-ready .sus-compromisso__statement { transition-delay: var(--stag-item); }

/* ===================== sustentabilidade: ambient background (compromisso beat) ===================== */
/* Full-bleed plate behind THIS beat only, feathered vertically (no side feather: the
   trees reach the viewport edges). A radial scrim behind the copy guarantees legibility. */
.sus-compromisso--ambient {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: clamp(620px, 90vh, 940px);
  display: flex; flex-direction: column; justify-content: center;
}
.sus-compromisso__bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.sus-compromisso__bg picture { display: block; width: 100%; height: 100%; }
.sus-compromisso__bg img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  --amb-feather: clamp(90px, 15vh, 190px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--amb-feather), #000 calc(100% - var(--amb-feather)), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 var(--amb-feather), #000 calc(100% - var(--amb-feather)), transparent 100%);
}
.sus-compromisso__bg::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse 62% 58% at 50% 46%,
    rgba(10, 10, 10, 0.78) 0%, rgba(10, 10, 10, 0.5) 42%, rgba(10, 10, 10, 0) 74%);
}
.sus-compromisso--ambient .sus-compromisso__grid { position: relative; z-index: 1; }
@media (max-width: 760px) {
  .sus-compromisso--ambient { min-height: 88vh; }
  .sus-compromisso__bg img { --amb-feather: clamp(60px, 10vh, 120px); }
  .sus-compromisso__bg::after {
    background: radial-gradient(ellipse 96% 72% at 50% 48%,
      rgba(10, 10, 10, 0.82) 0%, rgba(10, 10, 10, 0.55) 50%, rgba(10, 10, 10, 0) 82%);
  }
}

/* ===================== projetos: unified project beat ===================== */
body.reveal-ready .sus-project__narrative p:nth-child(2) { transition-delay: var(--stag-item); }
body.reveal-ready .sus-project__narrative p:nth-child(3) { transition-delay: calc(var(--stag-item) * 2); }

/* ===================== projetos: research cards, 2 + 1 ===================== */
/* Two columns, three items: the third card flows into row 2, column 1 with no span or
   special rule, so a fourth card needs no CSS change. Cards in a row share one height
   (align-items: stretch). */
.proj__grid {
  max-width: 1100px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(2, 1fr); align-items: stretch;
  gap: clamp(18px, 2vw, 30px);
}
.proj-card {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  padding: clamp(24px, 2.4vw, 36px);
  background: var(--color-bg-raised);
  border: 1px solid var(--color-hairline);
  border-radius: var(--media-radius);
  box-shadow: inset 0 1px 0 var(--ref-white-06);
  scroll-margin-top: calc(var(--nav-h) + 20px);
  transition: transform var(--dur-base) var(--ease-soft),
              border-color var(--dur-base) var(--ease-soft),
              box-shadow var(--dur-base) var(--ease-soft);
}
.proj-card__title {
  margin: 0; color: var(--color-text);
  font-weight: 500; font-size: clamp(1.15rem, 1.4vw, 1.4rem);
  letter-spacing: -0.005em; line-height: 1.15; text-wrap: balance;
}
.proj-card__rule {
  display: block; width: 44px; height: 1px;
  margin: clamp(14px, 1.6vw, 20px) 0 clamp(16px, 1.8vw, 22px);
  background: var(--color-hairline-strong);
  transition: width var(--dur-slow) var(--ease-gentle), background-color var(--dur-base) var(--ease-soft);
}
.proj-card__body { display: flex; flex-direction: column; gap: 16px; }
.proj-card__body p {
  margin: 0; font-weight: 400; font-size: clamp(13px, 0.82vw, 14px); line-height: 1.65;
  color: var(--color-text-secondary); text-wrap: pretty;
}

/* The second selector is the one that fires: the reveal system pins `transform: none`
   on every [data-reveal], and that selector (0,3,1) outranks a bare .proj-card:hover
   (0,2,0). The entrance rise uses `translate`, leaving `transform` to the hover. The
   bare selector serves the no-JS path, where body.reveal-ready never lands. */
@media (hover: hover) and (pointer: fine) {
  .proj-card:hover,
  body.reveal-ready .proj__grid > .proj-card[data-reveal]:hover { transform: translateY(-5px); }
}
.proj-card:hover,
.proj-card:focus-within {
  border-color: var(--color-hairline-strong);
  box-shadow: inset 0 1px 0 var(--ref-white-10), 0 26px 60px -30px rgba(0, 0, 0, 0.72);
}
.proj-card:hover .proj-card__rule,
.proj-card:focus-within .proj-card__rule { width: 66px; background: var(--ref-white-55); }

/* align-self is load-bearing: .proj-card is a column flex container whose default
   align-items:stretch would pull this anchor to the full card width and drag the
   .cta-link border-bottom across the panel. [data-cta-pending] = no href yet: it keeps
   the finished look with a "not yet" pointer; adding the href is the only edit needed. */
.proj-card__cta { margin-top: clamp(20px, 2.2vw, 28px); align-self: flex-start; }
.proj-card__cta[data-cta-pending] { cursor: default; }

/* Entrance: --rv-d is the card's place in the ladder, declared once and inherited, so
   every inner offset is written against the card's own arrival.
   Not animated with `transform`: the card rises with `translate` (transform is the hover
   lift's channel), and the rule draws with `scale` (width is its hover growth, 44px ->
   66px). Each channel keeps its own duration and delay. */
body.reveal-ready .proj__grid > .proj-card[data-reveal] {
  --rv-d: 0ms;
  opacity: 0; transform: none; translate: 0 var(--rise-md);
  transition:
    opacity var(--dur-mid) ease,
    translate var(--dur-slow) var(--ease-gentle),
    transform var(--dur-base) var(--ease-soft),
    border-color var(--dur-base) var(--ease-soft),
    box-shadow var(--dur-base) var(--ease-soft);
  transition-delay: var(--rv-d), var(--rv-d), 0s, 0s, 0s;
}
body.reveal-ready .proj__grid > .proj-card[data-reveal].is-revealed { opacity: 1; translate: none; }
body.reveal-ready .proj__grid > .proj-card[data-reveal]:nth-child(2) { --rv-d: var(--stag-item); }
body.reveal-ready .proj__grid > .proj-card[data-reveal]:nth-child(3) { --rv-d: calc(var(--stag-item) * 2); }

body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__title,
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__body,
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__cta {
  opacity: 0; translate: 0 var(--rise-sm);
  transition: opacity var(--dur-mid) ease, translate var(--dur-mid) var(--ease-gentle);
}
body.reveal-ready .proj__grid > .proj-card[data-reveal].is-revealed .proj-card__title,
body.reveal-ready .proj__grid > .proj-card[data-reveal].is-revealed .proj-card__body,
body.reveal-ready .proj__grid > .proj-card[data-reveal].is-revealed .proj-card__cta { opacity: 1; translate: none; }
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__title { transition-delay: calc(var(--rv-d) + 90ms); }
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__body  { transition-delay: calc(var(--rv-d) + 230ms); }
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__cta   { transition-delay: calc(var(--rv-d) + 320ms); }

/* the rule draws itself out. width + background-color are restated because this rule replaces the
   shorthand, and they are the hover's channels: dropping them would freeze the 44 -> 66px growth. */
body.reveal-ready .proj__grid > .proj-card[data-reveal] .proj-card__rule {
  scale: 0 1; transform-origin: left center;
  transition:
    width var(--dur-slow) var(--ease-gentle),
    background-color var(--dur-base) var(--ease-soft),
    scale var(--dur-slow) var(--ease-gentle);
  transition-delay: 0s, 0s, calc(var(--rv-d) + 170ms);
}
body.reveal-ready .proj__grid > .proj-card[data-reveal].is-revealed .proj-card__rule { scale: none; }

@media (max-width: 820px) {
  .proj__grid { grid-template-columns: 1fr; gap: clamp(16px, 4vw, 24px); }
}

/* ===================== sustentabilidade: Certificações (credentials ledger) ===================== */
.sus-cert__head { max-width: 64ch; margin: 0 auto; text-align: center; }

/* The marks + statement sit in their own relative box so the quotation marks enclose
   ONLY the phrase, never the rule/attribution under it. */
.sus-cert__citation {
  margin: clamp(20px, 2.4vw, 32px) auto 0; max-width: 64ch;
}
.sus-cert__citation-quote {
  position: relative; margin: 0 auto;
  padding: 0 clamp(26px, 4vw, 48px);
}
.sus-cert__citation-mark {
  position: absolute; font-style: italic; line-height: 1;
  font-size: clamp(34px, 4.4vw, 56px); color: var(--color-text);
  pointer-events: none; user-select: none;
}
.sus-cert__citation-mark--open { top: clamp(-6px, -0.4vw, 0px); left: 0; }
.sus-cert__citation-mark--close { bottom: clamp(-8px, -0.5vw, -2px); right: 0; }
.sus-cert__citation-text {
  margin: 0 auto; max-width: 42ch; text-wrap: balance;
  font-style: normal; font-weight: 600; font-size: clamp(15px, 1.35vw, 18.5px);
  letter-spacing: -0.005em; line-height: 1.68; color: var(--color-text);
}
.sus-cert__citation-rule {
  display: block; width: 40px; height: 1px;
  margin: clamp(22px, 2.4vw, 30px) auto clamp(16px, 1.8vw, 20px);
  background: var(--ref-white-28);
}
.sus-cert__citation-by { display: flex; flex-direction: column; gap: 3px; }
.sus-cert__citation-name {
  font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--color-text-muted);
}
.sus-cert__citation-role {
  margin-top: 1px; font-size: 10.5px; font-weight: 400; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ref-white-55);
}
.sus-cert__grid {
  margin: clamp(72px, 9vh, 120px) auto 0; max-width: 1040px;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(34px, 4.4vh, 64px) clamp(28px, 3vw, 52px);
}
.sus-cert__cta { margin-top: clamp(44px, 5.5vw, 76px); text-align: center; }
/* fixed basis + no grow so the incomplete last row (7 certs = 3 + 3 + 1) stays centred rather
   than leaving a lone left cell; wraps 3 -> 2 -> 1 as the width shrinks. */
.sus-cert__item {
  flex: 0 1 300px;
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
/* Uniform visual mass: the seals (OCS x2, RCS x2, GOTS) are square marks trimmed to the
   ring, so one box height is one disc diameter; the wide lockups (BCI, Sedex) are
   width-capped and shorter. Every asset is pre-trimmed to its own bbox. Seals render
   light via grayscale -> invert; Sedex opts out (see --sedex). */
.sus-cert__logo { display: flex; align-items: center; justify-content: center; height: clamp(38px, 4vw, 50px); margin-bottom: clamp(14px, 1.6vw, 20px); }
.sus-cert__logo img {
  display: block; width: auto; height: 100%; max-width: 100%;
  filter: grayscale(1) invert(1) brightness(0.95); opacity: 0.82;
}
.sus-cert__logo--wide img { width: auto; height: auto; max-height: 62%; max-width: clamp(68px, 6.3vw, 82px); }
/* Sedex: natural colour, no monochrome filter: the PNG carries the white wordmark + the
   pink dot on transparent. */
.sus-cert__logo--sedex img { filter: none; opacity: 0.92; max-width: clamp(76px, 7.2vw, 94px); }
.sus-cert__code {
  margin: 0; font-weight: 500; font-size: clamp(1rem, 1.1vw, 1.15rem);
  line-height: 1.2; letter-spacing: 0.01em; color: var(--color-text);
}
.sus-cert__name {
  margin: 5px 0 0; font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--color-text-muted);
}
.sus-cert__desc {
  margin: clamp(12px, 1.4vw, 16px) auto 0; max-width: 32ch;
  font-weight: 400; font-size: clamp(13px, 0.9vw, 14px); line-height: 1.6;
  color: var(--color-text-secondary); text-wrap: pretty;
}

@media (max-width: 860px) {

  .sus-beat { scroll-margin-top: var(--nav-h); }

  .sus-cert__grid { gap: clamp(30px, 8vw, 44px); }
  .sus-cert__item { flex-basis: 100%; }
}

/* ============== material grain ============== */

:root {
  --tex-grain: 0.05;
}

body::after {
  content: '';
  position: fixed; inset: 0; z-index: 90;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: var(--tex-grain);
}

/* ============== presentation family ============== */
:root {
  --marca-rule-w: clamp(36px, 5vw, 84px);
  --painel-pad: clamp(30px, 3.4vw, 52px);
}

.marca { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 24px); }
.marca--center { justify-content: center; }
.marca__rule {
  display: block; height: 1px; flex: 0 0 var(--marca-rule-w);
  background: var(--color-hairline);
}

/* O PAINEL | the .proj-card surface generalised to non-interactive prose: raised graphite,
   hairline, radius, lit-from-above inset. No hover lift (a panel that is not a link must
   not pretend to be one). */
.painel {
  position: relative;
  background: var(--color-bg-raised);
  border: 1px solid var(--color-hairline);
  border-radius: var(--media-radius);
  box-shadow: inset 0 1px 0 var(--ref-white-06);
  padding: var(--painel-pad);
}

.numeros__painel { max-width: 980px; margin: 0 auto; }   /* 980 holds the lead to 3 lines across desktop */
.numeros__painel .numeros__intro { max-width: none; }

/* .painel--hover: the transitions are declared under body.reveal-ready at a specificity
   that beats the reveal engine's own transition on [data-reveal] / [data-reveal="rule"]
   (else the hover would snap), and re-list the reveal's opacity/transform (panel) +
   scaleX draw (rules) so the entrance is preserved. */
body.reveal-ready .painel--hover {
  transition: opacity var(--dur-mid) ease, transform var(--dur-mid) var(--ease-gentle),
              border-color var(--dur-base) var(--ease-soft), box-shadow var(--dur-base) var(--ease-soft);
}
body.reveal-ready .painel--hover .marca__rule {
  transition: transform var(--dur-slow) var(--ease-gentle),
              flex-basis var(--dur-slow) var(--ease-gentle),
              background-color var(--dur-base) var(--ease-soft);
}
@media (hover: hover) and (pointer: fine) {
  .painel--hover:hover {
    border-color: var(--color-hairline-strong);
    box-shadow: inset 0 1px 0 var(--ref-white-10), 0 26px 60px -30px rgba(0, 0, 0, 0.72);
  }
  .painel--hover:hover .marca__rule {
    flex-basis: calc(var(--marca-rule-w) * 1.4);
    background: var(--ref-white-55);
  }
}

.cta-band { display: flex; align-items: center; gap: clamp(20px, 3vw, 40px); }
.cta-band::before, .cta-band::after { content: ''; height: 1px; flex: 1 1 auto; }
.cta-band::before { background: linear-gradient(to right, transparent, var(--color-hairline)); }
.cta-band::after { background: linear-gradient(to left, transparent, var(--color-hairline)); }
body.reveal-ready .cta-band[data-reveal] { opacity: 1; transform: none; }
body.reveal-ready .cta-band[data-reveal]::before,
body.reveal-ready .cta-band[data-reveal]::after {
  transform: scaleX(0);
  transition: transform var(--dur-slow) var(--ease-gentle) 200ms;
}
body.reveal-ready .cta-band[data-reveal]::before { transform-origin: right; }
body.reveal-ready .cta-band[data-reveal]::after { transform-origin: left; }
body.reveal-ready .cta-band[data-reveal].is-revealed::before,
body.reveal-ready .cta-band[data-reveal].is-revealed::after { transform: scaleX(1); }

/* ===================== mobile tap targets =====================
   Mobile-only padding/min-size lifts to the 44px touch floor: transparent hit-area
   growth, type sizes and colours untouched. */
@media (max-width: 760px) {
  .nav__wordmark { min-height: 44px; align-items: center; }
  .nav__lang-toggle { min-height: 44px; min-width: 44px; justify-content: center; }

  /* arrow text CTAs: 44px hit area (inline-flex + align-center, so min-height grows the
     box symmetrically) */
  .cta-link { min-height: 44px; }

  .cform__input { min-height: 44px; }

  .contactos__line--link { display: inline-block; padding-block: 8px; }

  /* footer: socials to the floor; text links lifted to a comfortable stacked
     rhythm (>=28px rows + list gaps | the strict 44 would balloon the footer) */
  .footer__social { width: 44px; height: 44px; }
  .footer__contact-line { padding-block: 6px; }
  .footer__menu a { display: inline-block; padding-block: 6px; }
  .footer__policies a { display: inline-block; padding-block: 6px; }

  .noticia__title a { display: inline-block; padding-block: 6px; }

  .sus-hero__cue { min-width: 44px; min-height: 44px; }
}

/* ===================== policy / legal pages ===================== */
.policy__inner { max-width: 46rem; margin: 0 auto; }

.policy__head {
  padding-bottom: clamp(26px, 3.6vw, 40px);
  margin-bottom: clamp(30px, 4vw, 48px);
  border-bottom: 1px solid var(--color-hairline);
}
.policy__head .eyebrow { margin-bottom: 16px; }
.policy__title {
  margin: 0;
  font-weight: 600;
  font-size: var(--fs-heading-lg);
  line-height: var(--lh-heading);
  letter-spacing: -0.01em;
  color: var(--color-text);
  text-wrap: balance;
}
.policy__meta {
  margin: 16px 0 0;
  font-size: var(--fs-body-sm);
  color: var(--color-text-muted);
}
.policy__download { margin-top: 22px; }
.policy__download .arrow { font-size: 15px; }
.policy__download:hover .arrow { transform: translateY(3px); }

/* --- the document body --- */
.policy__doc { color: var(--color-text-secondary); font-weight: 300; }
.policy__doc > * { margin: 0; }
.policy__doc > * + * { margin-top: 1.15em; }
.policy__doc p { font-size: var(--fs-body); line-height: 1.75; }
.policy__doc > h2 {
  margin-top: clamp(38px, 4.6vw, 56px);
  margin-bottom: 0.1em;
  font-weight: 600;
  font-size: clamp(1.06rem, 1.5vw, 1.3rem);
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--color-text);
}
.policy__doc > h3 {
  margin-top: 1.9em;
  font-weight: 600;
  font-size: 1rem;
  color: var(--color-text);
}
.policy__doc a {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--color-hairline-strong);
  transition: text-decoration-color var(--dur-fast) ease;
}
.policy__doc a:hover { text-decoration-color: var(--ref-white); }
.policy__doc strong { font-weight: 600; color: var(--color-text); }

/* lists: a restrained hairline marker, never a check or disc (design law) */
.policy__doc ul { list-style: none; padding: 0; }
.policy__doc li {
  position: relative;
  padding-left: 24px;
  font-size: var(--fs-body);
  line-height: 1.7;
}
.policy__doc li + li { margin-top: 0.7em; }
.policy__doc li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 11px;
  height: 1px;
  background: var(--color-hairline-strong);
}

/* tables (finalidades / cookies): hairline grid, greyscale. Wrapped in
   .policy__table-wrap so a wide table scrolls INSIDE its own box on small screens
   without widening the page (keeps documentElement.scrollWidth === clientWidth, the
   mobile gate's assertion). */
.policy__doc > .policy__table-wrap { margin-top: 1.3em; }
.policy__table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-top: 1px solid var(--color-hairline);
}
.policy__doc table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: var(--fs-body-sm);
}
.policy__doc thead th {
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--color-text-muted);
}
.policy__doc th, .policy__doc td {
  padding: 13px 18px 13px 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-hairline);
}
.policy__doc td { color: var(--color-text-secondary); font-weight: 300; line-height: 1.55; }
.policy__doc th:first-child, .policy__doc td:first-child { padding-left: 2px; }
.policy__doc code {
  font-family: 'Segoe UI Mono', ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.9em;
  color: var(--color-text);
  background: var(--color-wash);
  padding: 1px 6px;
  border-radius: 3px;
}

@media (max-width: 760px) {
  .policy__doc table { min-width: 32rem; }
  .policy__doc th, .policy__doc td { padding: 12px 14px 12px 0; }
}

/* ===================== notícia article (single post) =====================
   The reading shell above is SHARED, not copied: .policy__inner / __head / __title /
   __meta / __doc dress both the legal pages and a notícia article, so the two cannot
   drift and this block only holds what a legal page does not have. The article page
   carries BOTH classes (.policy .artigo). */

/* back to the archive. The arrow points LEFT, so it must nudge LEFT on hover: the global
   .cta-link:hover .arrow sends it right, which would read as "forward". Same shape of
   per-variant override as .policy__download, which redirects its arrow downward. */
.artigo__back { margin-bottom: clamp(26px, 3.2vw, 36px); }   /* more air than the policy pages' eyebrow-to-title step: .cta-link draws a border-bottom
   directly under the title's cap line */
.artigo__back:hover .arrow { transform: translateX(-4px); }

.artigo__lede {
  margin: 18px 0 0;
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--color-text-secondary);
  text-wrap: pretty;
}

/* cover plate. It also joins the contained-media group near the top of this file (rounded
   vertices + the two-axis feather), so it dissolves into the #0A0A0A like every other
   contained image instead of hard-cutting it. The mask there and the [data-reveal="media"]
   clip-wipe are independent and compose, as that block's own comment records. */
.artigo__cover {
  position: relative;
  margin: 0 0 clamp(30px, 4vw, 44px);
  /* 3/2, like .noticia__media, so the news module uses one ratio end to end; still `cover`,
     so a 16/9 featured image crops to fit. */
  aspect-ratio: 3 / 2;
  background: var(--color-bg-raised);
}
.artigo__cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.artigo__cover-ph {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: var(--fs-eyebrow); font-weight: 500; letter-spacing: var(--ls-nav);
  text-transform: uppercase; color: var(--ref-ash); user-select: none;
}
