/* ============================================================
   RISON — Landing page
   Implements templates/landing-page/LandingPage.dc.html from the
   RISON Design System. Every value below resolves to a token in
   _ds/rison/tokens/*.css — no raw hex outside of those files.
   ============================================================ */

/* ── Light-scope token refinements ───────────────────────
   Project-level overrides, kept here rather than in _ds/ so the
   vendored design system stays re-pullable.

   The DS ships one shadow ramp, tuned for its near-black default
   surfaces (--shadow-md is 36% pure black at 4px). Reused verbatim
   on paper it reads as a gray smudge rather than elevation, while
   the 6% hairline leaves the card with no edge at all — heavy
   shadow, no definition. The light scope gets slate-tinted shadows
   that are wider and far softer, plus a border with enough weight
   to actually draw the card's edge.
   ──────────────────────────────────────────────────────── */

[data-theme="light"] {
  --bg-void: #fafbfa;
  --bg-base: #fafbfa;
  --bg-surface: #f3f5f5;

  --shadow-sm: 0 1px 2px rgba(13, 21, 25, .05);
  --shadow-md: 0 1px 2px rgba(13, 21, 25, .04), 0 6px 16px -10px rgba(13, 21, 25, .16);
  --shadow-lg: 0 1px 2px rgba(13, 21, 25, .04), 0 18px 40px -20px rgba(13, 21, 25, .22);
  --shadow-xl: 0 28px 64px -28px rgba(13, 21, 25, .26);
  /* A white inset highlight is invisible on a white card — on paper
     the top edge catches light as a faint cool tint instead. */
  --shadow-inset-hairline: inset 0 1px 0 rgba(255, 255, 255, .8);

  --border-subtle: rgba(13, 21, 25, .09);
  --border-default: rgba(13, 21, 25, .14);
  --border-strong: rgba(13, 21, 25, .22);

  /* The DS's light tertiary (#7c8081) lands at 3.85:1 on this
     background — under the 4.5:1 AA floor for normal text, and it
     carries real copy: the reassurance line under every CTA, the
     trust label, the stat suffixes, the footer. Darkened just far
     enough to pass (4.87:1) while staying lighter than --text-
     secondary (6.0:1), so the hierarchy between them survives. */
  --text-tertiary: #5a7280;

  /* Focus ring at 40% alpha blended to 2.11:1 against the page —
     below the 3:1 that WCAG requires of non-text indicators. */
  --ring: rgba(43, 65, 76, .8);
}

/* ── Page shell ─────────────────────────────────────────── */

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--font-body);
  color: var(--text-body);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main { flex: 1; }

.container {
  max-width: var(--container-xl);
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: var(--space-4);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-control);
  background: var(--action-solid);
  color: var(--action-solid-fg);
  font: var(--type-label);
  transform: translateY(-200%);
  transition: var(--transition-control);
}

.skip-link:focus-visible {
  transform: translateY(0);
  opacity: 1;
  color: var(--action-solid-fg);
}

/* ── Section rhythm ─────────────────────────────────────── */

.section {
  padding: var(--pad-section-y) var(--pad-page-x);
  scroll-margin-top: 5rem;
}

/* readme › Spacing: sections breathe at 128px, 72px when tight. */
.section--tight { padding-block: 4.5rem; }

.section--alt {
  background: var(--bg-base);
  border-top: var(--rule-hairline);
}

/* ── Type helpers ───────────────────────────────────────── */

.dim { color: var(--text-secondary); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  font: var(--type-eyebrow);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--text-secondary);
}

.eyebrow__dot {
  width: 7px;
  height: 7px;
  background: currentColor;
}

.eyebrow--critical { color: var(--status-critical); }
.eyebrow--positive { color: var(--status-positive); }
.eyebrow--plain { color: var(--text-tertiary); }

.reassurance {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  letter-spacing: .06em;
  color: var(--text-primary);
}

.wordmark--lg { font-size: var(--text-xl); }

a.wordmark:hover { color: var(--text-primary); }

.wordmark__logo {
  display: block;
  height: 20px;
  width: auto;
}

.section-heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  align-items: center;
  text-align: center;
  max-width: var(--container-md);
  margin-inline: auto;
}

/* The DS's --type-h2 (30px) is sized for product UI. On a marketing
   page opening at 60px it reads as a step down rather than a second
   voice, so section heads scale up and tighten to hold their own. */
.section-heading h2 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: clamp(1.75rem, 3.2vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -.03em;
}

.section-heading p {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
  max-width: 46ch;
}

/* ── Buttons ────────────────────────────────────────────── */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border-radius: var(--radius-pill);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  white-space: nowrap;
  cursor: pointer;
  /* Press reads faster than hover — a release should feel like the
     surface springing back, not easing back. */
  transition: transform 180ms var(--ease-out), box-shadow 200ms var(--ease-out),
    background-color 200ms var(--ease-out), border-color 200ms var(--ease-out),
    color 200ms var(--ease-out);
}

.btn--sm { height: 34px; padding-inline: var(--space-5); font-size: var(--text-sm); }
.btn--lg { height: 52px; padding-inline: 28px; font-size: var(--text-base); }

.btn--solid {
  background: var(--action-solid);
  color: var(--action-solid-fg);
  box-shadow: var(--shadow-sm);
}

.btn--solid:hover {
  background: var(--action-solid-hover);
  color: var(--action-solid-fg);
  opacity: 1;
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.btn--solid:active {
  background: var(--action-solid-press);
  transform: translateY(0) scale(var(--press-scale));
  box-shadow: var(--shadow-sm);
  transition-duration: 90ms;
}

.btn--quiet {
  background: var(--action-quiet);
  border: var(--border-width) solid var(--action-outline);
  color: var(--text-primary);
}

.btn--quiet:hover {
  background: var(--action-quiet-hover);
  border-color: var(--action-outline-hover);
  color: var(--text-primary);
  opacity: 1;
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.btn--quiet:active {
  transform: translateY(0) scale(var(--press-scale));
  box-shadow: none;
  transition-duration: 90ms;
}

/* Scale on a pill distorts the corner radius; lift + shadow reads
   as the same affordance without deforming the shape. Motion is
   also suppressed entirely when the user asks for less of it. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover, .btn:active { transform: none; }
}

/* ── Cards ──────────────────────────────────────────────── */

.card {
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-card);
  padding: var(--pad-card);
  box-shadow: var(--elevation-card);
  transition: var(--transition-surface);
}

.icon-frame {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: var(--action-quiet);
  border: var(--border-width) solid var(--border-subtle);
  color: var(--text-secondary);
}

.icon-frame svg { width: 18px; height: 18px; transition: transform 260ms var(--ease-precise); }

.feature-card:hover .icon-frame svg { transform: scale(1.12); }

@media (prefers-reduced-motion: reduce) {
  .feature-card:hover .icon-frame svg { transform: none; }
}

/* ── Grids ──────────────────────────────────────────────── */

.grid {
  display: grid;
  gap: var(--gap-grid);
  list-style: none;
  margin: 0;
  padding: 0;
}

.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--5 { grid-template-columns: repeat(5, 1fr); }

/* ── Header ─────────────────────────────────────────────── */

.site-header {
  /* Fixed, not sticky: a sticky header still reserves its own
     height in normal flow, so the hero's sticky pin sits that many
     pixels below the viewport top at scroll 0 — the pin doesn't
     lock until the page has scrolled past that reserved gap, which
     reads as a dead zone before the hero video starts responding.
     Fixed removes the header from flow entirely, so the hero starts
     at y:0 and the pin engages from the very first scroll pixel.
     The header already floats translucent/blurred over content by
     design (see --glass below), and every anchor target already
     carries scroll-margin-top to clear it — this was already the
     intended floating-nav pattern. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-4) var(--space-8);
  background: var(--bg-void);
  background: color-mix(in srgb, var(--bg-void) 69%, transparent);
  backdrop-filter: var(--glass);
  -webkit-backdrop-filter: var(--glass);
  border-bottom: var(--rule-hairline);
  transition: padding-block 220ms var(--ease-out), background-color 220ms var(--ease-out),
    box-shadow 220ms var(--ease-out);
}

.site-header.is-scrolled {
  padding-block: 10px;
  background: color-mix(in srgb, var(--bg-void) 84%, transparent);
  backdrop-filter: saturate(160%) blur(16px);
  -webkit-backdrop-filter: saturate(160%) blur(16px);
  box-shadow: var(--shadow-sm);
}

@media (prefers-reduced-motion: reduce) {
  .site-header { transition: none; }
}

.nav-capsule {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--action-quiet);
  border: var(--border-width) solid var(--border-subtle);
}

.nav-capsule a {
  padding: 7px var(--space-4);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  border: var(--border-width) solid transparent;
  transition: color 200ms var(--ease-out), background-color 200ms var(--ease-out),
    border-color 200ms var(--ease-out);
}

.nav-capsule a:hover {
  color: var(--text-primary);
  background: var(--action-quiet-hover);
  opacity: 1;
}

.nav-capsule a[aria-current="true"] {
  color: var(--text-primary);
  background: var(--action-quiet-press);
  border-color: var(--border-default);
}

/* ── Hero ───────────────────────────────────────────────── */

.hero {
  position: relative;
  /* 100vh pinned viewport + a shorter scrub track. Long tracks (the
     skill's own 5vh-per-frame guideline would put this near 600vh)
     read as empty scrolling on a page whose job is to reach the
     CTA quickly — this is a brief cinematic beat, not the whole
     page's scroll budget. */
  height: 165vh;
  scroll-margin-top: 5rem;
}

.hero__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Extra top padding, not just var(--space-6) on every side — the
     header is fixed (out of flow) and floats over whatever's at the
     very top of the viewport. In a real browser window (address bar,
     bookmarks, tab strip all eating into the actual viewport height,
     unlike a plain devtools 100vh) the vertically centered eyebrow
     line could land close enough to y:0 that the header's own ~70px
     bar covers its top half. Extra top padding shifts the centered
     block down without touching the horizontal/bottom spacing. */
  padding: 7rem var(--space-6) var(--space-6);
  text-align: center;
}

.hero__canvas,
.hero__video {
  position: absolute;
  inset: 0;
  /* Replaced elements need an explicit size to stretch under abspos —
     inset:0 alone sizes them to their intrinsic dimensions instead. */
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.hero__video { display: none; }

/* No blur anywhere in front of the video — legibility comes from
   opacity alone. The center, where the text column sits, goes
   nearly opaque; it fades out fast enough that the video is still
   clearly a moving, recognizable image at the hero's edges. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 74% 66% at 50% 48%,
      color-mix(in srgb, var(--bg-void) 90%, transparent) 0%,
      color-mix(in srgb, var(--bg-void) 62%, transparent) 55%,
      transparent 78%),
    linear-gradient(to bottom,
      color-mix(in srgb, var(--bg-void) 26%, transparent) 0%,
      transparent 18%, transparent 80%,
      color-mix(in srgb, var(--bg-void) 36%, transparent) 100%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  max-width: var(--container-lg);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
}

/* The scroll-scrub is user-driven — the frame advances only as the
   reader scrolls and stops when they stop — so it is not gated on
   prefers-reduced-motion. Autonomous motion on this page (hero
   entrance, scroll reveals, the CTA button) still honours it. */

.hero__title {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: clamp(2rem, 5.6vw, 3.25rem);
  line-height: 1.02;
  letter-spacing: var(--tracking-tighter);
  color: var(--text-primary);
}

.hero__lead {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
  max-width: 46ch;
}

.hero__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}

/* ── Soluções ───────────────────────────────────────────── */

.feature-grid { margin-top: var(--space-20); }

.feature-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  transition: transform 320ms var(--ease-precise), box-shadow 320ms var(--ease-precise),
    border-color 320ms var(--ease-precise);
}

.feature-card h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-xl);
  letter-spacing: -.025em;
}

.feature-card p {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
  max-width: 34ch;
}

.feature-card:hover {
  transform: translateY(-7px) scale(1.02);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lg);
}

@media (prefers-reduced-motion: reduce) {
  .feature-card:hover { transform: none; }
}

/* ── Antes / depois ─────────────────────────────────────── */

.compare {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.compare__panel {
  position: relative;
  padding: var(--space-8);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.compare__spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--border-width-thick);
}

.compare__panel--critical .compare__spine { background: var(--status-critical); }
.compare__panel--positive .compare__spine { background: var(--status-positive); }

.compare__list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5) var(--space-8);
  margin: var(--space-6) 0 0;
  padding: 0;
  list-style: none;
}

.compare__list li {
  display: flex;
  gap: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
}

.compare__list--strong li { color: var(--text-body); }

/* ✕ and ✓ have different advance widths — a fixed box keeps the
   two columns' text edges aligned with each other. */
.compare__glyph {
  flex: none;
  width: 1em;
  font-weight: var(--weight-bold);
  text-align: center;
}

.compare__panel--critical .compare__glyph { color: var(--status-critical); }
.compare__panel--positive .compare__glyph { color: var(--status-positive); }

/* ── Números ────────────────────────────────────────────── */

/* ── Processo ───────────────────────────────────────────── */

.step-grid { margin-top: var(--space-20); }

/* Process track — a single line connecting every numbered card,
   centered on the numbers. Idle: a faint dashed guide. On hover, a
   solid fill is *drawn* from card 1 up to whichever card is under
   the cursor — hand-timed in JS (assets/js/process-track.js) rather
   than left to a single CSS transition, because a plain transition
   only knows a start and end value. It can't tell us the instant
   the fill visually passes card 2 versus card 3, and that instant
   is exactly what needs to drive each number lighting up in turn.
   The JS runs its own requestAnimationFrame tween along the DS's
   own --ease-precise curve, and on every frame checks the current
   position against each card's threshold — crossing one flips its
   .step-card--active class right then, which is what the number and
   card-lift styles below key off. Reversed on mouseleave, so the
   cards deactivate in the same order the line retracts through them.

   Position and length still come from measuring the actual
   .step-card__num centers, re-measured on resize and on the
   row-vs-stack breakpoint. The line renders behind the cards
   (z-index 0 vs. 1), so it only shows through the gaps between
   them — each card's opaque background covers it elsewhere, which
   is what makes the segments read as discrete steps completing
   rather than one bar sliding underneath the row. */
.step-track-wrap { position: relative; }

.step-track {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease-out);
}

.step-track--horizontal {
  top: 0;
  left: 0;
  height: 2px;
  background-image: repeating-linear-gradient(
    to right, var(--border-strong) 0 4px, transparent 4px 9px
  );
}

.step-track--vertical {
  top: 0;
  left: 0;
  width: 2px;
  background-image: repeating-linear-gradient(
    to bottom, var(--border-strong) 0 4px, transparent 4px 9px
  );
}

.step-track__fill {
  position: absolute;
  inset: 0;
  background: var(--text-primary);
  /* No CSS transition here — the JS tween sets a new transform
     value every animation frame, so a transition on top of that
     would just fight it (and blur the exact per-card timing). */
}

.step-track--horizontal .step-track__fill { transform: scaleX(0); transform-origin: left center; }
.step-track--vertical .step-track__fill { transform: scaleY(0); transform-origin: center top; }

.step-card {
  position: relative;
  z-index: 1; /* stays above .step-track, which runs behind the row */
  padding: var(--space-8) var(--space-6) var(--space-6);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  transition: transform 380ms var(--ease-precise), box-shadow 380ms var(--ease-precise);
}

/* Lifted either by literal hover, or by having been reached by the
   traveling line (.step-card--active, toggled from JS) — a card the
   line already passed through stays "awake" until the line retracts
   back past it, rather than dropping the instant the cursor moves on. */
.step-card:hover,
.step-card.step-card--active {
  transform: translateY(-8px) scale(1.03);
  box-shadow: var(--shadow-lg);
}

@media (prefers-reduced-motion: reduce) {
  .step-card:hover,
  .step-card.step-card--active { transform: none; }
}

.step-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.step-card__num {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-xs);
  /* Idle: the brand slate, not pure black — the square only goes
     to full dark once the line actually reaches it. */
  background: var(--s-500);
  color: var(--text-invert);
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  transition: background-color 320ms var(--ease-out);
}

.step-card--active .step-card__num { background: var(--surface-invert); }

/* One-shot arrival flash — added by JS the instant a card is
   reached, removed once the keyframe finishes so it can replay the
   next time this card activates. */
.step-card__num.is-pulsing { animation: step-num-pulse 320ms var(--ease-out); }

@keyframes step-num-pulse {
  0% { transform: scale(1); }
  45% { transform: scale(1.08); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .step-card__num { transition-duration: 1ms; }
  .step-card__num.is-pulsing { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .step-card:hover .step-card__num { transform: none; }
}

.step-card__rule {
  flex: 1;
  height: 1px;
  background: var(--rule-fade);
  transform-origin: left;
}

.js .step-card__rule {
  transform: scaleX(0);
  transition: transform 500ms var(--ease-precise) 200ms;
}

.js .step-card.is-visible .step-card__rule { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .js .step-card__rule { transform: scaleX(1); transition: none; }
}

.step-card h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--text-lg);
  margin-bottom: var(--space-2);
}

.step-card p {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
}

/* ── Footer ─────────────────────────────────────────────── */

/* The footer breaks from the page's light scope on purpose — a
   dark, generously rounded floating card (per the client's own
   reference mock), rather than a full-bleed bar. Colors below are
   pinned to the ramp tokens (--s-*, --rn-white) instead of the
   semantic --text-*/--border-* ones, because those flip to their
   light-theme values under [data-theme="light"] and would render as
   near-black text on this near-black card. */
.site-footer {
  padding: var(--space-10) var(--space-6) var(--space-16);
  background: var(--bg-void);
}

.site-footer__card {
  max-width: var(--container-xl);
  margin-inline: auto;
  border-radius: 32px;
  background: linear-gradient(180deg, #171e23, #0d1216);
  box-shadow: 0 30px 60px -24px rgba(5, 8, 10, .45);
  overflow: hidden;
}

.site-footer__top {
  padding: var(--space-16) var(--space-8);
  display: flex;
  gap: var(--space-16);
  flex-wrap: wrap;
  justify-content: space-between;
}

.site-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Text, not the header's PNG crop — that image bakes in a light
   background and dark ink meant for the light page, so it would
   show as a pale box with unreadable text on this dark card. A
   plain wordmark has no background by definition and just needs
   its color pinned light, same reasoning as the rest of the card. */
.site-footer__card .wordmark { color: var(--rn-white); }

.site-footer__tagline {
  font-size: var(--text-sm);
  color: var(--s-300);
}

.site-footer__nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
}

.site-footer__nav a {
  position: relative;
  width: fit-content;
  font-size: var(--text-sm);
  color: var(--s-300);
}

.site-footer__nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 220ms var(--ease-out);
}

.site-footer__nav a:hover {
  color: var(--rn-white);
  opacity: 1;
}

.site-footer__nav a:hover::after { transform: scaleX(1); }

.site-footer .badge {
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding-inline: var(--space-3);
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .06);
  font-size: var(--text-sm);
  color: var(--s-300);
  align-self: flex-start;
}

.site-footer__legal {
  border-top: 1px solid rgba(255, 255, 255, .08);
  padding: var(--space-5);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--s-300);
}

/* ── Contato ────────────────────────────────────────────── */

/* The corner-bracket square that used to frame the standalone CTA
   banner — that section is gone, folded into this one, so its one
   "technical drawing" gesture moves here instead of disappearing.
   Still square (no border-radius), still just a hairline + four 2px
   brackets, no fill treatment or glow — this frame's job is to hold
   the page's closing block, not to compete with it for attention. */
.contact__frame {
  position: relative;
  padding: var(--space-12);
  border: var(--border-width) solid var(--border-default);
  background: var(--bg-surface);
}

.contact__frame-corner {
  position: absolute;
  width: 14px;
  height: 14px;
  pointer-events: none;
}

.contact__frame-corner--tl { top: -1px; left: -1px; border-top: var(--border-width-thick) solid var(--text-primary); border-left: var(--border-width-thick) solid var(--text-primary); }
.contact__frame-corner--tr { top: -1px; right: -1px; border-top: var(--border-width-thick) solid var(--text-primary); border-right: var(--border-width-thick) solid var(--text-primary); }
.contact__frame-corner--bl { bottom: -1px; left: -1px; border-bottom: var(--border-width-thick) solid var(--text-primary); border-left: var(--border-width-thick) solid var(--text-primary); }
.contact__frame-corner--br { bottom: -1px; right: -1px; border-bottom: var(--border-width-thick) solid var(--text-primary); border-right: var(--border-width-thick) solid var(--text-primary); }

/* Asymmetric on purpose: the intro holds the left column and the
   form sits in the right, then the email/phone pair breaks full
   width underneath — the page's only section that isn't centered,
   which is what gives the closing block its own weight. */
.contact__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-12);
  align-items: start;
}

.contact__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.contact__intro h2 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: clamp(1.5rem, 2.8vw, 2.125rem);
  line-height: 1.08;
  letter-spacing: -.03em;
}

.contact__intro p {
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
  max-width: 34ch;
}

/* ── Form ─────────────────────────────────────────────── */

.contact__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.field-set {
  border: 0;
  margin: 0;
  padding: 0;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  margin-top: var(--space-2);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.field-label {
  padding: 0; /* <legend> carries UA padding */
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.field-sub,
.field-opt {
  font-size: var(--text-sm);
  font-weight: var(--weight-normal);
  color: var(--text-tertiary);
}

/* Underline only — no box, no fill. The rule is the control's
   entire visual body, so it carries the focus state too. */
.field-input {
  width: 100%;
  padding: var(--space-2) 0;
  border: 0;
  border-bottom: 1px solid var(--border-default);
  border-radius: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--text-primary);
  transition: border-color 260ms var(--ease-out);
}

.field-input::placeholder { color: var(--text-tertiary); }

.field-input:hover { border-bottom-color: var(--border-strong); }

/* :focus, not :focus-visible. The global ring is a 4px halo — right
   for pills and cards, but it would draw a floating rectangle around
   a control that has no box, so the underline thickens instead. And
   a text field should show where you're typing whether you clicked
   or tabbed in; :focus-visible would hide that from mouse users. */
.field-input:focus,
.field-input:focus-visible {
  outline: none;
  box-shadow: none;
  border-bottom-color: var(--s-500);
  border-bottom-width: 2px;
  padding-bottom: calc(var(--space-2) - 1px); /* keeps the baseline from shifting */
}

.field-textarea {
  resize: vertical;
  min-height: 3.5rem;
}

.field-select { position: relative; }

.field-select .field-input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-6);
  cursor: pointer;
}

.field-chevron {
  position: absolute;
  right: 0;
  top: 50%;
  translate: 0 -50%;
  width: 16px;
  height: 16px;
  color: var(--text-tertiary);
  pointer-events: none;
}

/* Off-screen, not display:none — display:none is exactly the tell
   spam bots check for and skip, so a purely visual hide (still
   present in the layout, still focusable by anything not reading
   CSS) is what actually catches them. Genuine visitors never
   tab-stop into it: tabindex="-1" pulls it out of the tab order,
   and it's absolutely positioned off both viewport edges either way. */
.field-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  left: -9999px;
}

.field-check {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
}

.field-check input {
  width: 16px;
  height: 16px;
  accent-color: var(--s-500);
  cursor: pointer;
}

.field-error {
  font-size: var(--text-sm);
  color: var(--status-critical);
  min-height: 0;
}

.field-input[aria-invalid="true"] { border-bottom-color: var(--status-critical); }

.form-status {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.btn--pill {
  align-self: flex-start;
  height: 44px;
  padding-inline: var(--space-8);
  font-size: var(--text-sm);
}

/* ── E-mail + telefone: the section's focal point ──────── */

/* Grouped left, not split edge-to-edge. The reference pushes these
   to opposite margins, but that only holds when the type is large
   enough to span the container — at this size it left a ~550px void
   between them and the pair stopped reading as one block. Sharing a
   left edge with the intro column above keeps the composition
   asymmetric while letting the two lines belong to each other. */
.contact__highlight {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-4) var(--space-12);
  margin-top: var(--space-20);
}

/* Sized to sit just under the section heading (40px), not above it.
   At the previous 52px it out-shouted the h2 and read as a second
   headline competing with it; below that line it still holds the
   focal weight through bold + full-contrast ink, without fighting
   the section's own title for first place. Tracking relaxes with
   the smaller size — -.04em is display-scale tightening. */
.contact__big {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: clamp(1.125rem, 2.1vw, 1.625rem);
  line-height: 1.1;
  letter-spacing: -.03em;
  color: var(--text-primary);
  transition: opacity 220ms var(--ease-out);
}

.contact__big:hover { color: var(--text-primary); opacity: .6; }

/* ── Meta row ─────────────────────────────────────────── */

/* Right-aligned, matching the reference. The left side stays empty
   on purpose: the reference puts a copyright there, but this page's
   real footer sits a few pixels below and already carries one —
   repeating it would just read as a duplicate. */
.contact__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-6);
  margin-top: var(--space-10);
  padding-top: var(--space-5);
  border-top: var(--rule-hairline);
}

/* A full sentence now, not a short label — the eyebrow's tracked-out
   mono caps (built for 1-4 word tags) would read as shouting once
   the text became a real sentence with a period. Sentence case in
   the body face matches how .reassurance is treated elsewhere. */
.contact__hello {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}

.contact__social {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  list-style: none;
  margin: 0;
  padding: 0;
}

.contact__social a {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  color: var(--text-tertiary);
  transition: color 220ms var(--ease-out), transform 220ms var(--ease-precise);
}

.contact__social svg { width: 20px; height: 20px; }

.contact__social a:hover {
  color: var(--text-primary);
  opacity: 1;
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .contact__social a:hover { transform: none; }
}

@media (max-width: 860px) {
  .contact__grid { grid-template-columns: 1fr; gap: var(--space-8); }
  .contact__highlight { margin-top: var(--space-16); gap: var(--space-4); }
  .contact__big { font-size: clamp(1.0625rem, 4vw, 1.375rem); }
  .contact__meta { margin-top: var(--space-8); }
}

@media (max-width: 560px) {
  .field-row { grid-template-columns: 1fr; gap: var(--space-4); }
  .btn--pill { width: 100%; }
  .contact__highlight { flex-direction: column; }
  .contact__meta { justify-content: space-between; gap: var(--space-4); }
}

/* ── Motion ───────────────────────────────────────────────
   Every rule below animates only transform/opacity (plus the
   header's backdrop-filter, already load-bearing for the glass
   effect). Nothing here touches width/height/top/left/margin/
   padding except the header's own padding-block, a deliberate,
   threshold-gated exception (toggled at most twice per scroll
   session, on one small fixed element — not a per-frame cost).
   ────────────────────────────────────────────────────────── */

:root {
  --stagger: 60ms;
  --hero-stagger: 110ms;
}

@media (max-width: 640px) {
  :root {
    --stagger: 35ms;
    --hero-stagger: 70ms;
  }
}

/* Scroll reveal: fade + small rise, once per element. */

.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: var(--transition-reveal);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (max-width: 640px) {
  .js .reveal { transform: translateY(8px); }
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}

/* Reveal stagger — cards/steps read as a sequence, not a block. */

.feature-grid > .reveal:nth-child(1) { transition-delay: calc(var(--stagger) * 0); }
.feature-grid > .reveal:nth-child(2) { transition-delay: calc(var(--stagger) * 1); }
.feature-grid > .reveal:nth-child(3) { transition-delay: calc(var(--stagger) * 2); }
.feature-grid > .reveal:nth-child(4) { transition-delay: calc(var(--stagger) * 3); }
.feature-grid > .reveal:nth-child(5) { transition-delay: calc(var(--stagger) * 4); }
.feature-grid > .reveal:nth-child(6) { transition-delay: calc(var(--stagger) * 5); }
.feature-grid > .reveal:nth-child(7) { transition-delay: calc(var(--stagger) * 6); }
.feature-grid > .reveal:nth-child(8) { transition-delay: calc(var(--stagger) * 7); }

.step-grid > .reveal:nth-child(1) { transition-delay: calc(var(--stagger) * 0); }
.step-grid > .reveal:nth-child(2) { transition-delay: calc(var(--stagger) * 1); }
.step-grid > .reveal:nth-child(3) { transition-delay: calc(var(--stagger) * 2); }
.step-grid > .reveal:nth-child(4) { transition-delay: calc(var(--stagger) * 3); }
.step-grid > .reveal:nth-child(5) { transition-delay: calc(var(--stagger) * 4); }

/* Comparativo: first panel, then the second — a beat apart. */

.compare > .reveal:nth-child(2) { transition-delay: 140ms; }

/* Contato: intro, form, then the email/phone pair and meta row —
   the closing block arrives in reading order. */

.contact__form { transition-delay: calc(var(--stagger) * 1); }
.contact__highlight { transition-delay: calc(var(--stagger) * 2); }
.contact__meta { transition-delay: calc(var(--stagger) * 3); }

@media (max-width: 640px) {
  .compare > .reveal:nth-child(2) { transition-delay: 80ms; }
}

/* Hero entrance — plays once on load, not on scroll. Headline,
   subheadline and actions arrive as a short, deliberate sequence. */

.js .hero__inner > * {
  opacity: 0;
  animation: hero-rise 650ms var(--ease-precise) forwards;
}

.js .hero__inner > *:nth-child(1) { animation-delay: 0ms; }
.js .hero__inner > *:nth-child(2) { animation-delay: var(--hero-stagger); }
.js .hero__inner > *:nth-child(3) { animation-delay: calc(var(--hero-stagger) * 2); }
.js .hero__inner > *:nth-child(4) { animation-delay: calc(var(--hero-stagger) * 3); }
.js .hero__inner > *:nth-child(5) { animation-delay: calc(var(--hero-stagger) * 4); }

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 640px) {
  @keyframes hero-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .js .hero__inner > * { animation: none; opacity: 1; transform: none; }
}

/* Parallax — extremely little, and only the page's own ambient
   glow. Native background-attachment, no scroll-linked JS. */

@media (min-width: 861px) and (prefers-reduced-motion: no-preference) {
  body { background-attachment: fixed; }
}

/* ── Responsive ─────────────────────────────────────────── */

@media (max-width: 1024px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--5 { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 860px) {
  .site-header { flex-wrap: wrap; padding-inline: var(--space-6); }
  .nav-capsule { order: 3; width: 100%; justify-content: center; }

  /* The header is fixed (see .site-header), and wrapping to its
     3-row mobile layout makes it noticeably taller — ~140px — with
     no flow space reserved for it anymore. Every section needs
     enough scroll-margin to clear it on an anchor jump, and the
     hero specifically needs matching top padding since it's the
     one section that sits at the very top with nothing above it. */
  .section, .hero { scroll-margin-top: 9.5rem; }

  .section { padding-block: var(--space-20); }
  .section--tight { padding-block: var(--space-12); }

  /* Below the pin breakpoint: skip the scroll-scrub entirely — the
     native video loop is far lighter than streaming 120 frames on
     a mobile connection, and there's no scroll track to pay for. */
  .hero { height: auto; }
  .hero__pin {
    position: relative;
    /* A fixed height here fights the fixed header: .hero__pin still
       centers its content (align-items, inherited from the base
       rule), and once the text stack is taller than a hard 70vh box
       it overflows equally in both directions — including upward,
       past the padding and under the header, then gets clipped by
       overflow:hidden on top of that. auto + min-height lets the
       box grow to fit real content instead of fighting it. */
    height: auto;
    min-height: 60vh;
    padding: 9.5rem var(--space-6) var(--space-16);
  }
  .hero__canvas { display: none; }
  .hero__video { display: block; }

  .grid--3 { grid-template-columns: 1fr; }
  .compare__list { grid-template-columns: 1fr; gap: var(--space-4); }
  .contact__frame { padding: var(--space-8); }
  .site-footer__top { gap: var(--space-10); padding-inline: var(--space-6); }
}

@media (max-width: 560px) {
  .grid--4 { grid-template-columns: 1fr; }
  .grid--5 { grid-template-columns: 1fr; }
  .btn--lg, .btn--terminal { width: 100%; }
  .btn--terminal { font-size: var(--text-sm); padding-inline: var(--space-4); }
  .hero__actions { width: 100%; }
  .hero__lead { max-width: none; }
}

/* ── Touch targets ───────────────────────────────────────
   Measured on a phone viewport, the nav links came in at 39px, the
   header CTA at 34px and the footer links at 23px — all under the
   44px minimum for a finger.

   Keyed on pointer:coarse rather than a width breakpoint, because
   the constraint is the input device, not the screen: a touch
   laptop needs the bigger target at 1400px, and a narrow desktop
   window does not. Padding grows the hit area while the text stays
   optically where it was, so the desktop composition is untouched.
   ──────────────────────────────────────────────────────── */

@media (pointer: coarse) {
  .nav-capsule a,
  .btn--sm {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  .site-header .wordmark { min-height: 44px; }

  .site-footer__nav { gap: 0; }

  .site-footer__nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}
