/* ===== MartBot — design tokens (inherited from FZNGroup manual, same
   variable names as fzngroup/css/style.css for family-wide consistency) ===== */
@font-face {
  font-family: "Sora";
  src: url("/assets/fonts/sora-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Sora";
  src: url("/assets/fonts/sora-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --azul-noite: #0A1F44;
  --azul-eletrico: #2E6BFF;
  --azul-nevoa: #8FA3C8;
  --off-white: #F4F6FA;
  /* Task 13: the brand electric blue (#2E6BFF) fails computed WCAG AA
     contrast as small/normal-weight TEXT against either background it sits
     on — 3.61:1 on azul-noite, 4.16:1 on off-white/white (both need 4.5:1) —
     while still being fine as a button/badge fill or as large-text (>=24px)
     accent color, where the AA bar drops to 3:1. These two variants are for
     text-sized uses only; --azul-eletrico itself is untouched for buttons,
     borders, and large-text accents. */
  --azul-eletrico-on-dark: #5889FF;  /* vs azul-noite: 4.98:1 */
  --azul-eletrico-on-light: #2960E6; /* vs off-white: 4.96:1, vs white: 5.37:1 */

  --ink: var(--azul-noite);
  --ink-soft: #4A5A7A;
  --paper: #FFFFFF;

  --on-dark: #FFFFFF;
  --on-dark-soft: rgba(244, 246, 250, .72);
  --on-dark-line: rgba(244, 246, 250, .14);
  --on-dark-surface: rgba(244, 246, 250, .05);

  --font-title: "Sora", "Arial", sans-serif;
  --font-body: "Inter", "Helvetica", "Arial", sans-serif;

  --radius: 18px;
  --shadow-sm: 0 1px 2px rgba(10, 31, 68, .04);
  --shadow: 0 1px 2px rgba(10, 31, 68, .04), 0 30px 60px -34px rgba(10, 31, 68, .28);
  --shadow-lg: 0 1px 2px rgba(10, 31, 68, .05), 0 40px 80px -30px rgba(10, 31, 68, .35);

  --wrap: 1440px;
  --pad-x: clamp(24px, 6vw, 72px);
  --section-pad-top: clamp(56px, 8vw, 104px);
  --section-pad: clamp(88px, 13vw, 168px);
  /* Fixed-height gradient handoff zone — see spec §Identidade visual for why
     this replaces fzngroup's content-height-calibrated 85% cutoff: this site
     has 8 home sections instead of 4, so a fixed pixel zone (vs. a percentage
     re-measured per section) is what stays maintainable. */
  --transition-h: 140px;

  --ease: cubic-bezier(.16, 1, .3, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--off-white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3 {
  font-family: var(--font-title);
  color: var(--azul-noite);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 .5em;
}
h1 { font-size: clamp(2.3rem, 5vw, 3.4rem); font-weight: 700; }
h2 { font-size: clamp(1.9rem, 4vw, 2.9rem); font-weight: 700; }
h3 { font-size: 1.2rem; font-weight: 600; letter-spacing: -0.01em; }

p {
  line-height: 1.75;
  margin: 0 0 1em;
  color: var(--ink-soft);
  max-width: 68ch;
}

/* --azul-eletrico itself fails AA as text color (see the -on-dark/-on-light
   note near its definition below) — use the text-safe on-light variant as
   the default link color, same fix already applied to .eyebrow/.step-num/
   .policy-card h2. */
a { color: var(--azul-eletrico-on-light); }

.wrap {
  position: relative;
  z-index: 1;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--pad-x);
}

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

/* ===== Section rhythm ===== */
.section {
  position: relative;
  padding: var(--section-pad-top) 0 var(--section-pad);
  background: var(--off-white);
  overflow: hidden;
}
.section-dark {
  background: var(--azul-noite);
  color: var(--on-dark-soft);
}
.section-dark h2, .section-dark h3 { color: #fff; }
.section-dark p { color: var(--on-dark-soft); }
/* No .section-dark a override: every link on the site that sits inside a
   dark section (the FAQ's /seguranca link) is actually on a white .card,
   not on azul-noite directly — the base `a` rule (--azul-eletrico-on-light)
   is already correct for it. A dark-background override was added once and
   removed after review: it dropped that same link's contrast from 4.50:1 to
   3.26:1 by applying the on-dark token to a link that was never on a dark
   background to begin with. If a link is ever placed directly on
   azul-noite (not inside a light card), add a scoped override then. */

/* Fixed-height gradient handoff at the bottom of a section — see
   --transition-h in Task 1. Reuses fzngroup's validated smoothstep color
   stops (same two colors, off-white <-> azul-noite), remapped from their
   85-100%-of-section-height range onto this fixed-height band's own 0-100%.
   Extra bottom padding keeps real content clear of the band regardless of
   viewport height; Task 13 verifies this measurement across viewports and
   this constant is the one to adjust if any section's content encroaches. */
.section--to-dark, .section--to-light {
  padding-bottom: calc(var(--section-pad) + 96px);
}
.section--to-dark::after,
.section--to-light::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--transition-h);
  pointer-events: none;
}
.section--to-dark::after {
  background: linear-gradient(to bottom,
    #f4f6fa 0%, #c1c8d3 30%, #7f8a9f 50%,
    #435370 68%, #223557 80%, #12264a 89%, #0c2145 95%, #0a1f44 100%);
}
.section--to-light::after {
  background: linear-gradient(to bottom,
    #0a1f44 0%, #3d4d6b 30%, #7f8b9f 50%,
    #bbc2ce 68%, #dce0e7 80%, #eceff4 89%, #f2f4f9 95%, #f4f6fa 100%);
}

.section-head { max-width: 46rem; }
.eyebrow {
  color: var(--azul-eletrico-on-light);
  font-family: var(--font-title);
  font-weight: 600;
  font-size: .78rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  margin-bottom: .9em;
}
/* Same component reused inside dark sections (#como-funciona,
   #implantacao, #faq) — swap to the on-dark-safe tint, same reasoning as
   .tag below. */
.section-dark .eyebrow { color: var(--azul-eletrico-on-dark); }
.section-rule {
  display: block;
  width: 44px;
  height: 3px;
  background: var(--azul-eletrico);
  border-radius: 3px;
  margin-bottom: 22px;
}

/* ===== Topbar ===== */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  background: rgba(244, 246, 250, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(10, 31, 68, .08);
  transition: background .35s var(--ease), border-color .35s var(--ease);
}
.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 80px;
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; padding: 6px 0; }
.brand-mark { flex: none; }
.brand-word {
  font-family: var(--font-title);
  font-weight: 700;
  font-size: 1.12rem;
  letter-spacing: -0.01em;
  color: var(--azul-noite);
}
.nav { display: flex; align-items: center; gap: 30px; }
.nav a { color: var(--ink); text-decoration: none; font-size: .93rem; font-weight: 500; transition: color .2s var(--ease); }
.nav a:hover { color: var(--azul-eletrico); }
.nav-cta {
  background: var(--azul-eletrico);
  color: #fff !important;
  padding: 10px 20px;
  border-radius: 999px;
  font-weight: 600 !important;
  transition: background .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.nav-cta:hover { background: #4c80ff; transform: translateY(-1px); box-shadow: 0 10px 24px -10px rgba(46,107,255,.6); }

/* Home page only: dark hero sits directly under a transparent topbar until
   scrolled (JS adds body.has-dark-hero only on index.html). Every other page
   just gets the solid/light topbar above, permanently — no scroll listener
   needed there. */
body.has-dark-hero .topbar { background: transparent; border-bottom-color: transparent; }
body.has-dark-hero .topbar .brand-word,
body.has-dark-hero .topbar .nav a:not(.nav-cta) { color: #fff; }
body.has-dark-hero .topbar.scrolled { background: rgba(244, 246, 250, .92); border-bottom-color: rgba(10, 31, 68, .08); }
body.has-dark-hero .topbar.scrolled .brand-word,
body.has-dark-hero .topbar.scrolled .nav a:not(.nav-cta) { color: var(--ink); }
/* Logo swap, same .scrolled trigger as the color swap above: the escuro
   (navy-bg) mark blends into the dark hero while the topbar is transparent;
   once scrolled the topbar turns light, so swap to the claro (white-bg)
   mark or the navy square would float visibly on the light bar. */
.brand-mark-light { display: none; }
.topbar.scrolled .brand-mark-dark { display: none; }
.topbar.scrolled .brand-mark-light { display: block; }

.nav-toggle {
  display: none;
  flex-direction: column; justify-content: center; gap: 5px;
  width: 40px; height: 40px;
  background: none; border: none; cursor: pointer;
}
.nav-toggle span { display: block; height: 2px; background: var(--azul-noite); border-radius: 2px; }
body.has-dark-hero .topbar:not(.scrolled) .nav-toggle span { background: #fff; }

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-body); font-weight: 600; text-decoration: none;
  padding: 15px 30px; border-radius: 999px; border: 1.5px solid transparent;
  cursor: pointer; font-size: .98rem;
  transition: transform .2s var(--ease), box-shadow .25s var(--ease), background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.btn-primary { background: var(--azul-eletrico); color: #fff; box-shadow: 0 16px 32px -14px rgba(46, 107, 255, .55); }
.btn-primary:hover { background: #4c80ff; transform: translateY(-2px); box-shadow: 0 20px 40px -14px rgba(46, 107, 255, .65); }
.btn-ghost { background: transparent; border-color: rgba(10, 31, 68, .18); color: var(--ink); }
.btn-ghost:hover { border-color: rgba(10, 31, 68, .38); transform: translateY(-2px); }
body.has-dark-hero .hero .btn-ghost { border-color: rgba(255,255,255,.28); color: #fff; }
body.has-dark-hero .hero .btn-ghost:hover { border-color: rgba(255,255,255,.6); }
.btn:focus-visible { outline: 2px solid var(--azul-eletrico); outline-offset: 3px; }

/* ===== Cards ===== */
.card {
  background: var(--paper);
  border: 1px solid rgba(10, 31, 68, .06);
  border-radius: var(--radius);
  padding: 32px 30px;
  box-shadow: var(--shadow);
}

/* ===== Reveal-on-scroll ===== */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* ===== Decorative mascot companion =====
   Reuses the same icon asset as the topbar/footer as-is (brand ficha bans
   recoloring/redesigning it). .mascot-wrap (icon + speech bubble) is
   position: fixed, parked at the vertical middle of the viewport —
   js/main.js holds it on one side (left or right) for as long as you're
   within a given section, alternating sides section by section, and only
   moves when you cross into the next one (not a continuous sweep while
   scrolling within a section). On the home page it also shows a short
   speech-bubble line per section ("as if it were narrating"), and once you
   reach FAQ it stops roaming and settles into a real, clickable "talk to
   us" button pinned bottom-right for the rest of the page. Hidden below
   900px: too little width left to hold a side without overlapping real
   content. Always an <a href="/contato"> in the markup — during the
   roaming/narrating phase pointer-events:none and tabindex="-1" keep it
   non-interactive and out of the tab order (it's decorative then), and
   js/main.js flips both on once it becomes the real button. */
.mascot-wrap {
  position: fixed;
  top: 45%;
  left: 60px;
  display: flex;
  /* Bubble stacks ABOVE the icon (column, bubble first via `order` below)
     instead of sitting beside it — a real bug found in manual testing: a
     bubble wide enough to read comfortably, placed beside the icon,
     reached far enough toward the center of the page to overlap real
     content in sections with a wide layout (e.g. the "Como funciona"
     carousel, whose text column starts almost as close to the edge as the
     icon itself does). Stacking keeps the whole widget's horizontal
     footprint close to the icon's own ~80px width regardless of message
     length; align-items flips (see .mascot-wrap--right) so the bubble
     grows away from whichever edge the icon is currently parked near,
     never off-screen. */
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  z-index: 30; /* above page content, below the topbar (50) and mobile CTA bar (40) */
  pointer-events: none;
  text-decoration: none;
  /* Only `left`/`top` ever actually change via JS (see js/main.js) — always
     as concrete px numbers, never toggled against `right`/`bottom`/`auto`,
     because CSS can't smoothly transition to/from `auto` (a real bug found
     in manual testing — it snapped instead of sliding). */
  transition: left 1.1s var(--ease), top 1.1s var(--ease), opacity .3s var(--ease);
}
.mascot-wrap.is-hidden { opacity: 0; }
.mascot-wrap--right { align-items: flex-end; }
.mascot-companion {
  flex: none;
  order: 1;
  width: 80px;
  height: auto; /* load-bearing: the HTML height="220" attribute would
    otherwise win over this width and stretch the image, since only width
    was being overridden by CSS before — img sizing quirk, not a canvas
    setting. */
  opacity: .85;
}
.mascot-bubble {
  flex: none;
  order: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .85rem;
  font-weight: 600;
  line-height: 1.35;
  padding: 10px 16px;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* Narrow and wrapping (not nowrap) — keeps the bubble's own width close
     to the icon's, on top of the column stacking above, so the combined
     widget's horizontal footprint stays predictable regardless of how long
     a given section's line is (some wrap to 3 lines at this width, which
     is fine — vertical room is cheap here, horizontal isn't). */
  max-width: 160px;
  white-space: normal;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.mascot-bubble:empty { display: none; }
/* "Como funciona" specifically (see js/main.js's MASCOT_NARROW_ZONES): even
   hugging the true viewport edge there didn't help, since the bubble still
   reaches its own fixed max-width rightward from wherever it starts — only
   an actually narrower max-width shrinks how far it reaches into that
   section's text column, which starts almost as close to the edge as the
   icon does. Wraps to more lines instead; vertical room is cheap, that
   section's horizontal room isn't. */
.mascot-wrap--narrow .mascot-bubble { max-width: 110px; }
.mascot-bubble.is-visible { opacity: 1; transform: translateY(0); }

/* Button end-state: pinned bottom-right (left/top set once, in px, by
   js/main.js — see the comment there), icon gets a solid backdrop so it
   reads as a tappable button instead of a floating decoration, and the
   bubble becomes a permanent (not fading) label instead of a per-section
   line. Keeps the same stacked (bubble-above-icon) layout the roaming
   phase uses — Felipe asked for the label on top here too, not beside the
   button. align-items: flex-end keeps both right-edge-aligned with the
   viewport corner regardless of which is wider. */
.mascot-wrap--button {
  pointer-events: auto;
  cursor: pointer;
  align-items: flex-end;
}
.mascot-wrap--button .mascot-bubble { max-width: none; white-space: nowrap; }
.mascot-wrap--button .mascot-companion {
  opacity: 1;
  background: var(--azul-eletrico);
  border-radius: 50%;
  padding: 14px;
  box-shadow: 0 16px 32px -14px rgba(46, 107, 255, .55);
}
.mascot-wrap--button .mascot-bubble {
  opacity: 1;
  transform: none;
  background: var(--azul-noite);
  color: #fff;
}
@media (max-width: 900px) {
  .mascot-wrap { display: none; }
}

/* ===== Mid-page section CTAs =====
   Ghost (outline) style, not the solid .btn-primary fill — four more solid
   blue buttons on top of the hero's and the final CTA's would push well
   past the manual de marca's 20%-of-screen cap on azul-elétrico. */
.section-cta { text-align: center; margin-top: 44px; }
.section-dark .section-cta .btn-ghost { border-color: rgba(255,255,255,.28); color: #fff; }
.section-dark .section-cta .btn-ghost:hover { border-color: rgba(255,255,255,.6); }

/* ===== Sticky mobile CTA bar ===== */
.mobile-cta-bar {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  padding: 12px var(--pad-x) calc(12px + env(safe-area-inset-bottom));
  background: rgba(244, 246, 250, .95);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(10, 31, 68, .1);
  transform: translateY(100%);
  transition: transform .3s var(--ease);
}
.mobile-cta-bar.is-visible { transform: translateY(0); }
.mobile-cta-bar .btn { display: block; width: 100%; text-align: center; }
@media (max-width: 720px) {
  .mobile-cta-bar { display: block; }
}
/* The drawer's own height is content-driven (auto), not viewport-stretched,
   so on a short viewport it can leave the fixed CTA bar peeking out below
   it — just hide the bar outright while the drawer is open. */
body:has(.nav.is-open) .mobile-cta-bar { display: none !important; }

/* ===== Footer ===== */
.footer { background: var(--azul-noite); color: var(--azul-nevoa); padding: 56px 0 36px; text-align: center; border-top: 1px solid var(--on-dark-line); }
.footer-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; }
.footer-brand .brand-word { color: #fff; }
.footer-seal { color: var(--azul-nevoa); font-size: .85rem; margin: 0 0 24px; }
.footer-nav { display: flex; justify-content: center; gap: 24px; margin-bottom: 22px; }
.footer-nav a { color: var(--on-dark-soft); text-decoration: none; font-size: .9rem; }
.footer-nav a:hover { color: #fff; }
/* Was rgba(143, 163, 200, .65) — correctly alpha-composited against
   azul-noite that comes out ~3.48:1 (needs 4.5:1), a real WCAG AA failure
   the contrast helper's parseRgb bug had been masking (it silently
   discarded alpha, so the test compared the raw (143,163,200) against
   azul-noite and reported 6.38:1 — a false pass). --on-dark-soft is
   already used one line up by .footer-nav a and composites to ~8.31:1. */
.footer-copy { font-size: .82rem; color: var(--on-dark-soft); margin: 0; max-width: none; }

/* ===== Responsive ===== */
/* ===== Hero ===== */
.hero {
  position: relative;
  background: var(--azul-noite);
  color: #fff;
  text-align: center;
  min-height: 92vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 140px 0 80px;
  overflow: hidden;
}
.hero-inner { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; }
.hero-eyebrow {
  color: var(--azul-eletrico-on-dark);
  font-family: var(--font-title);
  font-weight: 700;
  font-size: .82rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  margin-bottom: 20px;
  animation: rise .9s var(--ease) both;
}
.hero h1 { color: #fff; font-size: clamp(2.2rem, 6vw, 3.6rem); max-width: 18ch; margin-bottom: .5em; animation: rise .9s var(--ease) .1s both; }
.hero h1 .accent { color: var(--azul-eletrico); }
.hero-lede { color: var(--on-dark-soft); font-size: 1.1rem; max-width: 56ch; margin: 0 auto 2em; animation: rise .9s var(--ease) .2s both; }
.hero-pills { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 2.4em; animation: rise .9s var(--ease) .28s both; }
.hero-pill { border: 1px solid var(--on-dark-line); background: var(--on-dark-surface); color: #fff; font-size: .85rem; font-weight: 600; padding: 8px 18px; border-radius: 999px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; animation: rise .9s var(--ease) .36s both; }
.scroll-cue { width: 22px; height: 36px; margin-top: 48px; border: 1.5px solid rgba(255,255,255,.3); border-radius: 20px; display: flex; justify-content: center; padding-top: 7px; animation: rise .9s var(--ease) .5s both; }
.scroll-cue span { width: 3px; height: 7px; border-radius: 3px; background: var(--azul-nevoa); animation: cue 1.8s ease-in-out infinite; }

@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
@keyframes cue { 0%, 100% { transform: translateY(0); opacity: 1; } 50% { transform: translateY(8px); opacity: .3; } }

/* ===== Quote callout ("O problema") ===== */
.quote {
  position: relative;
  margin: 0 auto;
  padding: 40px 44px;
  background: var(--paper);
  border: 1px solid rgba(10, 31, 68, .06);
  border-left: 3px solid var(--azul-eletrico);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-family: var(--font-title);
  font-style: italic;
  font-size: 1.25rem;
  color: var(--azul-noite);
  line-height: 1.55;
  max-width: 640px;
}
.quote p { color: inherit; max-width: none; margin: 0; }

/* Consolidated prefers-reduced-motion block (previously split across three
   separate @media blocks added in different tasks — merged here so future
   fixes land in one place). The blanket *,*::before,*::after rule is the
   real guarantee: it collapses every animation/transition duration to
   effectively zero, no matter what property or selector introduces it later.
   The specific rules below are kept as belt-and-suspenders: they remove
   hover *transforms* outright (not just speed them up) and pin opacity/
   position for elements whose reduced-motion "settled" state isn't the
   default CSS state (reveal-on-scroll, hero entrance animations). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }

  html { scroll-behavior: auto; }

  /* Topbar: remove scroll-driven background/border transition */
  .topbar { transition: none !important; }

  /* Mobile CTA bar: same scroll-driven-chrome treatment as the topbar above */
  .mobile-cta-bar { transition: none !important; }

  /* Mobile nav: remove slide-in/out transition */
  .nav { transition: none !important; transform: translateY(0) !important; }

  /* Button hovers: remove lift transforms (not just speed them up) */
  .nav-cta:hover { transform: none !important; }
  .btn-primary:hover { transform: none !important; }
  .btn-ghost:hover { transform: none !important; }

  /* Reveal-on-scroll: remove entrance animations */
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }

  /* Hero entrance animations: settle immediately in final state */
  .hero-eyebrow, .hero h1, .hero-lede, .hero-pills, .hero-actions, .scroll-cue {
    animation: none !important; opacity: 1 !important; transform: none !important;
  }
  .scroll-cue span { animation: none !important; }

  /* Mascot: js/main.js itself skips the scroll-driven repositioning (and
     the narration/button state machine) under reduced motion, settling for
     its plain default CSS position — this just removes the transition so
     nothing animates even if something still touches its inline style. */
  .mascot-wrap { transition: none !important; }
}

@media (max-width: 720px) {
  .topbar-inner { height: 68px; }
  .nav {
    position: fixed; inset: 68px 0 auto 0;
    background: var(--off-white);
    flex-direction: column; align-items: flex-start; gap: 4px;
    padding: 18px 24px 26px;
    border-bottom: 1px solid rgba(10, 31, 68, 0.08);
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
  }
  .nav.is-open { transform: translateY(0); opacity: 1; pointer-events: auto; }
  .nav a { padding: 12px 0; width: 100%; }
  /* :not(.nav-cta) keeps the CTA pill's own white-on-blue (.nav-cta,
     color:#fff !important) intact — without it, this same-specificity
     !important rule (.nav a, 0,1,1) beat .nav-cta's (0,1,0) and rendered
     navy text on the blue button in the open mobile menu, found in the
     Task 13 manual visual pass (not caught by the automated contrast test,
     which only checks the drawer's default closed state). Same pattern
     already used at line 221 for the same reason. */
  .nav a:not(.nav-cta) { color: var(--ink) !important; }
  .nav-cta { text-align: center; margin-top: 8px; }
  .nav-toggle { display: flex; }
}

/* ===== Stat-tile (Prova) — dataviz skill guidance: two isolated facts with
   no honest baseline to compare against, so a stat-tile, not a chart. No
   legend, no delta. ===== */
.stat-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 32px; margin: 44px 0 56px; }
.stat-tile { text-align: center; }
.stat-tile .stat-value {
  font-family: var(--font-title);
  font-weight: 600;
  font-size: clamp(2.4rem, 6vw, 3.4rem);
  color: var(--azul-noite);
  line-height: 1;
  margin-bottom: .3em;
  font-variant-numeric: proportional-nums; /* isolated figure, not a table column */
}
.stat-tile .stat-label { color: var(--ink-soft); font-size: .95rem; max-width: 32ch; margin: 0 auto; }

.prova-context { text-align: center; color: var(--ink-soft); font-size: .95rem; margin: 24px auto 0; max-width: 50ch; }

@media (max-width: 720px) {
  .stat-row { grid-template-columns: 1fr; gap: 28px; }
}

/* ===== Screenshot frame (panel screenshots) ===== */
.screenshot-frame {
  background: var(--paper);
  border: 1px solid rgba(10, 31, 68, .08);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px;
  margin-bottom: 14px;
}
.screenshot-frame img { border-radius: calc(var(--radius) - 6px); }
/* width:100%/height:auto is load-bearing: without it, a plain (non-carousel)
   image renders at its own intrinsic width — 1200px, the source render size
   — leaving a blank strip of frame background beside it whenever the frame
   itself (which does stretch to fill .wrap, a normal block box) ends up
   wider than that, e.g. the metrics illustration in #prova on any viewport
   wider than ~1300px. :not(.carousel-img) matters: this selector's
   specificity (0,2,1) would otherwise beat .carousel-img's own explicit
   height:100% (0,1,0) and silently switch it back to auto-height, undoing
   the inset-based sizing that positions it inside the sticky carousel
   frame. */
.screenshot-frame img:not(.carousel-img) { width: 100%; height: auto; }
/* azul-nevoa reads fine on the dark section this was designed against
   (6.38:1 vs azul-noite) but fails WCAG AA on the light #prova instance
   of this same class (2.36:1 vs off-white) — default to the already-
   proven light-bg muted tone (ink-soft, used right next to it by
   .stat-label/.prova-context in that same section) and keep azul-nevoa
   only where the section is actually dark. */
.screenshot-caption { color: var(--ink-soft); font-size: .85rem; text-align: center; margin: 0 0 40px; }
.section-dark .screenshot-caption { color: var(--azul-nevoa); }

/* ===== Step carousel ("Como funciona" walkthrough) =====
   Scrollytelling pattern: the text column scrolls normally; the screenshot
   column is sticky and crossfades to the screenshot matching whichever
   .step-item js/main.js currently measures as closest to the viewport's
   vertical center. The 5 screenshots have different source aspect ratios
   (395/525/184px tall at 1200 wide) — stacking them with `position: absolute`
   inside a fixed-aspect-ratio frame (tallest ratio, 1200/525) and `object-fit:
   contain` keeps the frame a constant size across swaps instead of the frame
   jumping height on every crossfade. */
/* align-items default (stretch) is load-bearing here: .step-carousel-media
   must stretch to the full grid-row height (set by the much taller text
   column) for its position:sticky child to have room to stay stuck across
   the whole scroll range — with align-items:start (tried first), the media
   column was only as tall as its own content, so the sticky image scrolled
   away entirely once the text column ran past that height. */
.step-carousel { display: grid; grid-template-columns: minmax(280px, 420px) 1fr; gap: 48px; margin-top: 44px; }
.step-carousel-text { display: grid; gap: 96px; }
.step-item { opacity: .45; transition: opacity .4s var(--ease); }
.step-item.is-active { opacity: 1; }
.step-item .step-num {
  color: var(--azul-eletrico-on-light);
  font-family: var(--font-title);
  font-weight: 700;
  font-size: .8rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  margin-bottom: .4em;
}
.step-item h3 { margin-bottom: .3em; }
.step-item p { margin: 0; }
/* #como-funciona (the only current step-carousel) is a dark section — same
   on-dark-safe swap as .eyebrow above. */
.section-dark .step-item .step-num { color: var(--azul-eletrico-on-dark); }

/* .section's base overflow:hidden (used to guarantee the ::after gradient
   overlay and reveal-on-scroll entrance never bleed past the section edge)
   breaks position:sticky for any descendant: sticky requires every
   ancestor's overflow to be either visible or the actual scrolling element
   itself — an intervening overflow:hidden ancestor that ISN'T the scroller
   silently cancels stickiness with no error, which is why the screenshot
   was scrolling away instead of staying pinned. Safe to override here: the
   ::after overlay is bottom:0-anchored with an explicit height, so it was
   never actually relying on clipping to stay within the section's bounds. */
#como-funciona { overflow: visible; }
.step-carousel-media { position: relative; }
.step-carousel-sticky { position: sticky; top: calc(80px + 24px); }
.step-carousel-sticky .screenshot-frame {
  position: relative;
  aspect-ratio: 1200 / 525;
  overflow: hidden;
}
.carousel-img {
  position: absolute;
  inset: 10px; /* positions the box — matches .screenshot-frame's own padding */
  /* inset alone does NOT size a replaced element (img/video): with
     width/height left auto, an absolutely-positioned <img> falls back to
     its intrinsic HTML width/height attributes instead of filling the
     space between the insets, the way a plain div would. Explicit 100%
     here (measured against the box the insets already carved out) is what
     actually makes it fill that space; object-fit then does the fitting
     within it. */
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity .4s var(--ease);
}
.carousel-img.is-active { opacity: 1; }

@media (max-width: 720px) {
  .step-carousel { grid-template-columns: 1fr; gap: 20px; }
  /* Single column: media and text become separate grid rows, no longer
     sharing one to stretch against. Tried taking media out of flow
     (position: absolute, stretched to the text's full height) to reclaim
     desktop's full stick range — but on mobile there's only one column, so
     an always-stuck image at a fixed viewport position visually overlaps
     whichever text has scrolled underneath it (the two columns don't sit
     side by side the way they do on desktop, where overlap is impossible).
     Reserving space in the text can only prevent the overlap for the FIRST
     item, not every item the image drifts over while stuck. Simpler and
     honest instead: keep media in normal flow, first in visual order, with
     a fixed min-height — enough stick room to hold through roughly one
     text item before unsticking, with zero overlap risk since text always
     starts after media's own reserved space. */
  .step-carousel-media { order: -1; min-height: 480px; }
  .step-carousel-text { gap: 56px; }
  .step-carousel-sticky { top: calc(68px + 16px); }
}

/* ===== Differentiator tags ===== */
.tag-row { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 36px; }
.tag {
  font-size: .82rem; font-weight: 600; color: var(--ink-soft);
  background: rgba(10, 31, 68, .05);
  border: 1px solid rgba(10, 31, 68, .08);
  padding: 8px 16px; border-radius: 999px;
}
/* #como-funciona is a dark section (see Task 3's rhythm note) — the default
   .tag above assumes a light background and would go illegible on navy. */
.section-dark .tag { color: var(--on-dark-soft); background: var(--on-dark-surface); border-color: var(--on-dark-line); }

@media (max-width: 720px) {
  .step-list-item { grid-template-columns: 1fr; gap: 12px; }
}

/* ===== Implantação (3-step grid) ===== */
.step-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 44px; }
.step-card { text-align: center; }
.step-circle {
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--azul-eletrico); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-title); font-weight: 700;
  margin: 0 auto 16px;
}
.step-card h3 { margin-bottom: .4em; }
.step-card p { margin: 0 auto; max-width: 30ch; }

/* ===== Como contrata (2-up cards) ===== */
.cards-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; margin-top: 44px; }

/* ===== FAQ (native <details>, no JS) ===== */
.faq-list { display: grid; gap: 14px; margin-top: 40px; max-width: 760px; }
.faq-item { background: var(--paper); border: 1px solid rgba(10, 31, 68, .08); border-radius: var(--radius); padding: 22px 26px; }
.faq-item summary { cursor: pointer; font-family: var(--font-title); font-weight: 600; color: var(--azul-noite); list-style: none; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; float: right; color: var(--azul-eletrico); font-weight: 700; }
.faq-item[open] summary::after { content: "–"; }
.faq-item p { color: var(--ink); margin: 14px 0 0; }

/* ===== CTA final ===== */
.cta-final-sub { color: var(--on-dark-soft); margin: 0 auto 28px; max-width: 50ch; }

@media (max-width: 720px) {
  .step-grid { grid-template-columns: 1fr; gap: 28px; }
  .cards-grid-2 { grid-template-columns: 1fr; }
}

/* ===== /seguranca — page intro + card grid ===== */
.page-lede { font-size: 1.1rem; max-width: 60ch; }
.security-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; margin-top: 44px; }
.section-dark .security-grid .card { background: var(--paper); } /* cards stay white even inside a dark section, same pattern as screenshot-frame */
/* .section-dark h3/p target every heading/paragraph in the section regardless of
   nesting, so without this the card's own white background would be paired with
   the dark-section text colors (white h3, translucent-white p) — unreadable.
   Same fix already applied to .faq-item p for the same reason. */
.section-dark .security-grid .card h3 { color: var(--ink); }
.section-dark .security-grid .card p { color: var(--ink-soft); }

@media (max-width: 720px) {
  .security-grid { grid-template-columns: 1fr; }
}

/* ===== /privacidade — narrow reading column, single policy card ===== */
.wrap-narrow { max-width: 760px; margin: 0 auto; padding: 0 var(--pad-x); }
.policy-updated { color: var(--ink-soft); font-size: .85rem; margin-bottom: 2em; }
.policy-card {
  background: var(--paper);
  border: 1px solid rgba(10, 31, 68, .06);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 40px clamp(20px, 5vw, 48px);
}
.policy-card h2 {
  font-size: 1.05rem; color: var(--azul-eletrico-on-light);
  margin: 1.6em 0 .5em; padding-bottom: .4em;
  border-bottom: 1px solid rgba(10, 31, 68, .08);
}
.policy-card h2:first-child { margin-top: 0; }
.policy-card p, .policy-card li { max-width: none; }
.policy-card .aviso {
  background: rgba(46, 107, 255, .06);
  border: 1px solid rgba(46, 107, 255, .18);
  border-radius: 10px; padding: 12px 16px;
  font-size: .9rem; color: var(--ink);
}
.policy-card .contato-box {
  background: rgba(10, 31, 68, .03);
  border: 1px dashed rgba(10, 31, 68, .18);
  border-radius: 10px; padding: 14px 16px;
  font-size: .95rem;
}
