/* =====================================================================
   barbarasalgueiro.pt, folha de estilos unica.
   Os sete ficheiros anteriores (tokens, reset, base, layout, components,
   sections, utilities) bloqueavam o render em serie e custavam cerca de
   um segundo de First Contentful Paint. Sem build step nao ha forma de
   os combinar no deploy, portanto passaram a viver aqui, pela mesma
   ordem de cascata. Cada bloco mantem o seu cabecalho.
   ===================================================================== */

/* ############ TOKENS ############ */
:root {
  /* ─── Paleta da marca ───────────────────────────────────
     Base: #31150f  → dark warm (chocolate quase preto)
     Chestnut: #732e15  → castanho profundo
     Terra: #ca6f5c  → terracota
     Nude: #d69a78  → pêssego suave
     Red: #d72026  → CTA principal
     Todos os tokens semânticos derivam destes 5 hexes. */
  --c-bg: #31150f;
  /* Superfície mais profunda do site: hero, page-hero, secções dark e footer.
     Escurecida em 27/07/2026 na direcção do preto pedido para a identidade,
     mantendo um resto mínimo de calor para não criar corte de matiz contra
     --c-bg-soft na transição para a trust bar. */
  --c-bg-hero: #0F0806;
  --c-bg-elevated: #3F1E13;
  --c-bg-soft: #2A1109;
  --c-line: #4A2617;
  --c-line-strong: #732E15;

  /* Accent para texto, eyebrows, ícones, bordas dourada-style.
     Mantemos o nome --c-gold para não partir CSS existente, mas o
     valor agora é o "nude" da paleta, que garante AA em texto. */
  --c-gold: #D69A78;
  --c-gold-soft: #E4B497;
  --c-gold-deep: #A47155;
  --c-gold-glow: rgba(214, 154, 120, 0.22);
  /* Glow largo do hero. Alfa baixo porque agora assenta em fundo quase preto. */
  --c-glow-hero: rgba(214, 154, 120, 0.09);
  /* Tintas do nude. Existiam antes em hexes do dourado antigo (201,169,97),
     que ficou fora da paleta e fazia o estado seleccionado e o anel de foco
     acenderem num tom diferente do resto do site. */
  --c-gold-tint: rgba(214, 154, 120, 0.07);
  --c-gold-ring: rgba(214, 154, 120, 0.22);

  /* Superfície de painel sobre --c-bg-hero. Um degrau acima do quase preto:
     --c-bg-elevated é castanho e, desde o escurecimento, lia-se como um
     rectângulo castanho colado a um fundo preto. */
  --c-bg-panel: #181110;

  /* CTA vermelho vibrante. Usar como background do botão primário,
     nunca como texto sobre fundo escuro (contrast insuficiente). */
  --c-red: #D72026;
  --c-red-soft: #E24A4A;
  --c-red-deep: #A81820;

  /* Terracota para hover secundário / underline decorativo. */
  --c-terra: #CA6F5C;

  --c-text: #F5EEE4;
  --c-text-muted: #D6BFA9;
  --c-text-dim: #A47B62;

  --c-danger: #E26A6A;
  --c-success: #7BC29A;

  /* ─── Tipografia (identidade da marca) ─────────────────── */
  --ff-serif: "Black Mango", Georgia, "Times New Roman", serif;
  --ff-sans: "Montserrat", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --ff-script: "Lovely May", "Snell Roundhand", "Apple Chancery", cursive;

  --fs-300: clamp(0.8125rem, 0.78rem + 0.15vw, 0.875rem);
  --fs-400: clamp(0.9375rem, 0.9rem + 0.2vw, 1rem);
  --fs-500: clamp(1.0625rem, 1rem + 0.3vw, 1.125rem);
  --fs-600: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  --fs-700: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  --fs-800: clamp(2rem, 1.6rem + 2vw, 3rem);
  --fs-900: clamp(2.5rem, 1.9rem + 3.2vw, 4.75rem);

  --lh-tight: 1.08;
  --lh-snug: 1.25;
  --lh-body: 1.6;
  --ls-tight: -0.02em;
  --ls-wide: 0.14em;

  /* ─── Spacing (base 4px) ───────────────────────────────── */
  --s-0: 0;
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;
  --s-10: 8rem;
  --s-11: 12rem;

  /* ─── Layout ───────────────────────────────────────────── */
  --container: 72rem;
  --container-narrow: 56rem;
  --gutter: clamp(1rem, 4vw, 2rem);
  --section-y: clamp(4rem, 8vw, 7rem);

  /* ─── Radii ────────────────────────────────────────────── */
  --r-sm: 4px;
  --r-md: 10px;
  --r-lg: 18px;
  --r-pill: 999px;

  /* ─── Motion ───────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-luxe: cubic-bezier(0.22, 0.61, 0.36, 1);
  --d-fast: 160ms;
  --d-base: 260ms;
  --d-slow: 480ms;

  /* ─── Sombras / Glows ──────────────────────────────────── */
  --glow-gold: 0 0 0 1px rgba(214, 154, 120, 0.35),
    0 10px 30px -10px rgba(215, 32, 38, 0.3);
  --ring-focus: 0 0 0 2px var(--c-bg), 0 0 0 4px var(--c-red);
}


/* ############ RESET ############ */
/* Modern CSS reset, adapted from Andy Bell */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
html:focus-within { scroll-behavior: smooth; }
body { min-height: 100vh; line-height: 1.5; -webkit-font-smoothing: antialiased; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
a { color: inherit; text-decoration: none; }
ul, ol { padding: 0; list-style: none; }
hr { border: 0; height: 1px; background: var(--c-line); }
:focus-visible {
  outline: 2px solid var(--c-gold);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* [hidden] tem de ganhar sempre, mesmo a classes com display custom */
[hidden] { display: none !important; }

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


/* ############ BASE ############ */
/* Fontes self-hosted da identidade da marca.
   - Black Mango  · display serif para headings (peso único, Regular)
   - Montserrat   · sans variable (100–900), roman + italic separados
   - Lovely May   · script para toques de assinatura (peso único)
   Cada família tem 2 subsets, latin + latin-ext, browser escolhe via unicode-range. */

/* Black Mango, latin */
@font-face {
  font-family: "Black Mango";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/black-mango-latin.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;
}
@font-face {
  font-family: "Black Mango";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/black-mango-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Montserrat, latin (variable, 400–600) */
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin.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;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Montserrat italic (variable) */
@font-face {
  font-family: "Montserrat";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/montserrat-italic-latin.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;
}
@font-face {
  font-family: "Montserrat";
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/montserrat-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Lovely May, latin (script accent) */
@font-face {
  font-family: "Lovely May";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/lovely-may-latin.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;
}
@font-face {
  font-family: "Lovely May";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/lovely-may-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Inter, latin + latin-ext — fallback provisório até chegar o Montserrat roman. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin.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;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ─── Body ────────────────────────────────────────────── */
html {
  background: var(--c-bg);
  color: var(--c-text);
}
body {
  font-family: var(--ff-sans);
  font-size: var(--fs-400);
  font-weight: 400;
  line-height: var(--lh-body);
  background: var(--c-bg);
  color: var(--c-text);
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  overflow-x: hidden;
  -webkit-tap-highlight-color: transparent;
}

/* Black Mango e Lovely May são single-weight; desligar faux-bold evita
   renderização artificial quando o CSS pede 500/600. Faux-italic também
   ficaria descaracterizado. */
h1, h2, h3, h4, h5, h6,
.script,
.hero__title em,
[class*="__quote"],
.testimonial::before {
  font-synthesis: none;
}

/* ─── Headings ────────────────────────────────────────── */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--ff-serif);
  font-weight: 400;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--c-text);
}
/* Black Mango é single-weight display: peso 400 chega em qualquer escala. */
h1 { font-size: var(--fs-900); }
h2 { font-size: var(--fs-800); }
h3 { font-size: var(--fs-700); }
h4 { font-size: var(--fs-600); }
h5 { font-size: var(--fs-500); line-height: var(--lh-snug); }

p { color: var(--c-text); }
strong, b { font-weight: 600; color: var(--c-text); }
small { font-size: var(--fs-300); color: var(--c-text-muted); }

::selection { background: var(--c-gold); color: var(--c-bg); }

/* ─── Links ───────────────────────────────────────────── */
a {
  color: var(--c-gold);
  text-decoration: none;
  transition: color var(--d-fast) var(--ease-out);
}
a:hover { color: var(--c-gold-soft); }

/* Ligações no meio de um parágrafo levam sublinhado. Sem ele distinguem-se do
   texto à volta só pela cor, que é falha de WCAG 1.4.1: quem não separa o nude
   do branco quente não vê que ali há uma ligação. Fora dos parágrafos não se
   põe, porque navegação, rodapé e botões já se lêem como alvos pela posição e
   pela forma. São três ligações no site inteiro, e todas são mesmo texto
   corrido. */
p a:not(.btn) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

/* ─── Eyebrow / Kicker ────────────────────────────────── */
.eyebrow {
  display: inline-block;
  font-family: var(--ff-sans);
  font-size: var(--fs-300);
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-gold);
  margin-bottom: var(--s-4);
}

/* ─── Lead paragraph ──────────────────────────────────── */
.lead {
  font-size: var(--fs-500);
  color: var(--c-text-muted);
  line-height: var(--lh-body);
  max-width: 56ch;
}

/* ─── Underline gold ──────────────────────────────────── */
.gold {
  color: var(--c-gold);
}
.gold-underline {
  background-image: linear-gradient(var(--c-gold), var(--c-gold));
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 100% 1px;
}


/* ############ LAYOUT ############ */
/* ─── Container ──────────────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--container);
  padding-inline: var(--gutter);
  margin-inline: auto;
}
.container--narrow { max-width: var(--container-narrow); }

/* ─── Section ────────────────────────────────────────── */
.section {
  padding-block: var(--section-y);
  position: relative;
}
/* O header é sticky com 64px de altura mínima. Sem isto, saltar para uma
   âncora aterra com o topo da secção escondido por baixo dele. */
:target,
section[id] {
  scroll-margin-top: calc(64px + env(safe-area-inset-top, 0px) + var(--s-4));
}

.section--dark { background: var(--c-bg-hero); }
.section--soft { background: var(--c-bg-soft); }
.section--bordered {
  border-top: 1px solid var(--c-line);
  border-bottom: 1px solid var(--c-line);
}

/* ─── Stack composition (vertical rhythm) ─────────────── */
.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--stack-space, var(--s-4)); }
.stack--sm { --stack-space: var(--s-3); }
.stack--lg { --stack-space: var(--s-6); }
.stack--xl { --stack-space: var(--s-8); }

/* ─── Cluster (horizontal flex wrap with gap) ─────────── */
.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cluster-gap, var(--s-4));
  align-items: var(--cluster-align, center);
}
/* O centrado dos blocos de CTA final era `style="justify-content:center"` em
   cada sítio, e cada um desses inline soma um erro ao html-validate. Como
   classe, o alinhamento passa a ser uma decisão do componente. */
.cluster--center { justify-content: center; }
/* Em ecrã estreito os CTAs empilham e ocupam a largura toda. O hero já fazia
   isto; o resto do site não acompanhava, e cada cluster alinhava para seu
   lado conforme o `justify-content` inline que lhe tinha calhado: uns à
   esquerda com um vazio de 100px à direita, o das empresas encostado à
   direita, outros centrados. Empilhados, o alinhamento deixa de ser uma
   escolha por sítio.
   Não é preciso anular o `justify-content` inline: em coluna ele passa a
   distribuir na vertical, e é o `align-items: stretch` que manda na largura. */
@media (max-width: 600px) {
  .cluster {
    flex-direction: column;
    align-items: stretch;
  }
  .cluster > .btn { width: 100%; }
}

/* ─── Grid ───────────────────────────────────────────── */
.grid {
  display: grid;
  gap: var(--grid-gap, var(--s-5));
}
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--auto {
  grid-template-columns: repeat(auto-fit, minmax(var(--grid-min, 18rem), 1fr));
}
@media (max-width: 768px) {
  .grid--2, .grid--3 { grid-template-columns: 1fr; }
  .grid--auto { grid-template-columns: 1fr; }
}
@media (min-width: 769px) and (max-width: 1024px) {
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}

/* ─── Split layout (hero, sobre) ─────────────────────── */
.split {
  display: grid;
  gap: var(--s-8);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: var(--split-cols, 1.1fr 1fr); }
}
.split--reverse > :first-child { order: 2; }
@media (max-width: 899px) {
  .split--reverse > :first-child { order: 0; }
}


/* ############ COMPONENTS ############ */
/* ─── Buttons ────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: var(--s-3) var(--s-6);
  font-family: var(--ff-sans);
  font-size: var(--fs-400);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background var(--d-base) var(--ease-out),
    color var(--d-base) var(--ease-out),
    border-color var(--d-base) var(--ease-out),
    transform var(--d-base) var(--ease-luxe),
    box-shadow var(--d-base) var(--ease-out);
  text-decoration: none;
  white-space: nowrap;
}
/* Em ecrã estreito o rótulo tem de poder partir. Com `nowrap`, «Pedir proposta
   para a sua empresa» pedia 355px e não encolhia: dentro de uma coluna de 328
   saía pelos dois lados, porque o cluster centra. O `line-height` sobe porque
   o 1 do estado de uma linha cola as duas linhas uma à outra. */
@media (max-width: 600px) {
  .btn {
    white-space: normal;
    text-align: center;
    line-height: 1.25;
    padding-inline: var(--s-5);
  }
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--c-red);
  color: #fff; /* branco puro garante AA no vermelho (5.09:1) */
  border-color: var(--c-red);
}
.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--c-red-soft);
  border-color: var(--c-red-soft);
  color: #fff;
  box-shadow: var(--glow-gold);
}

/* Primário sem gastar o vermelho. Serve para avanços que são obrigatórios mas
   não são a conversão, como o «Continuar» de cada passo do diagnóstico: se o
   vermelho aparecer quatro vezes antes do «Enviar pedido», no fim já não diz
   nada. O texto vai a --c-bg-hero e não a --c-bg, para dar 8,3:1 sobre o
   nude. */
.btn--nude {
  background: var(--c-gold);
  color: var(--c-bg-hero);
  border-color: var(--c-gold);
}
.btn--nude:hover,
.btn--nude:focus-visible {
  background: var(--c-gold-soft);
  border-color: var(--c-gold-soft);
  color: var(--c-bg-hero);
}

.btn--ghost {
  background: transparent;
  color: var(--c-text);
  border-color: var(--c-line-strong);
}
.btn--ghost:hover {
  border-color: var(--c-gold);
  color: var(--c-gold);
}

.btn--link {
  padding: 0;
  min-height: auto;
  background: transparent;
  color: var(--c-gold);
  border: 0;
  border-radius: 0;
}
.btn--link:hover { color: var(--c-gold-soft); }

/* Marca de canal à cabeça do botão (WhatsApp). Vai a currentColor e não ao
   verde da marca: a paleta do site não tem verde, e um único ponto verde
   partia a disciplina cromática definida nos tokens. O `flex: none` impede
   que encolha quando o rótulo é longo. */
.btn__icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
}

/* ─── Card ────────────────────────────────────────────── */
.card {
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  padding: var(--s-6);
  transition:
    transform var(--d-base) var(--ease-luxe),
    border-color var(--d-base) var(--ease-out),
    box-shadow var(--d-base) var(--ease-out);
}
.card:hover {
  transform: translateY(-4px);
  border-color: var(--c-gold);
  box-shadow: var(--glow-gold);
}

/* ─── Pill / Badge ────────────────────────────────────── */
.pill {
  display: inline-flex;
  align-items: center;
  padding: var(--s-1) var(--s-3);
  font-size: var(--fs-300);
  font-weight: 500;
  letter-spacing: 0.05em;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  color: var(--c-text-muted);
}
.pill--gold {
  border-color: var(--c-gold);
  color: var(--c-gold);
}

/* ─── Divider ────────────────────────────────────────── */
.divider {
  width: 48px;
  height: 1px;
  background: var(--c-gold);
  border: 0;
  margin: var(--s-5) 0;
}

/* ─── Form fields ────────────────────────────────────── */
.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.form-label {
  font-size: var(--fs-400);
  font-weight: 500;
  color: var(--c-text);
}
.form-label[data-optional]::after {
  content: " (opcional)";
  color: var(--c-text-dim);
  font-weight: 400;
}
.form-hint {
  font-size: var(--fs-300);
  color: var(--c-text-dim);
}
.form-error {
  font-size: var(--fs-300);
  color: var(--c-danger);
  min-height: 1.25em;
}
/* Vazio não ocupa espaço. O `min-height` reservava a linha para o erro não
   empurrar o layout quando aparece, mas nos passos com opções o parágrafo é o
   último filho de um flex com `gap`, e somava um vão morto de meia dúzia de
   dezenas de píxeis por baixo da última linha regrada. O salto que o
   `min-height` evitava é de uma linha, e só acontece em campo com erro. */
/* Escondida só para os olhos, não retirada da árvore.
   Com `display: none` a região `aria-live` nascia fora da árvore de
   acessibilidade e só aparecia já com texto lá dentro, e regiões que passam de
   não renderizadas a renderizadas com conteúdo não são anunciadas de forma
   fiável. O objectivo original, não abrir vão morto por baixo da última linha
   regrada, mantém-se: em absoluto não ocupa espaço. */
.form-error:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

/* ─── Campos, em caixa ─────────────────────────────────────
   Foram filetes durante uma revisão inteira, e a razão era boa: uma ficha em
   papel preenche-se sobre uma linha. Na prática o campo tinha 51px de altura,
   transparente, e só mostrava o filete de baixo: o rótulo ficava a flutuar
   meio centímetro acima de um traço solto e lia-se como campo em falta.

   Agora as escolhas são cartões, e um cartão com contorno ao lado de um campo
   sem contorno são duas gramáticas no mesmo formulário. A caixa alinha as
   duas, e a altura passa a ser visível em vez de adivinhada. */
.input,
.textarea,
.select {
  width: 100%;
  padding: 0 var(--s-4);
  font-family: var(--ff-sans);
  /* 16px mínimo em mobile para evitar zoom automático no iOS */
  font-size: max(16px, var(--fs-400));
  color: var(--c-text);
  /* Fundo mais fundo do que o dos cartões, não igual. Duas razões, e a segunda
     é que manda: um cartão é superfície que se carrega e um campo é poço onde
     se escreve, portanto um sobe e o outro desce; e sobre `--c-bg-elevated` o
     `--c-text-dim` do placeholder dava 3,97:1, abaixo dos 4,5:1 do AA. Sobre
     `--c-bg-panel` dá 5,03:1. O contorno e o raio continuam iguais aos dos
     cartões, que é o que faz a gramática ser uma só. */
  background: var(--c-bg-panel);
  /* O `--c-line` chega para desenhar a caixa, porque o fundo já a separa da
     banda: a indicação visual do WCAG 1.4.11 deixou de depender só do traço. */
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  min-height: 48px;
  transition:
    border-color var(--d-fast) var(--ease-out),
    background var(--d-fast) var(--ease-out);
}
.input:hover,
.textarea:hover,
.select:hover { border-color: var(--c-gold-deep); }
/* O foco acende o contorno inteiro. Sem `box-shadow` a somar largura, não há
   salto de layout. O `:focus-visible` global continua a cobrir o teclado. */
.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--c-gold);
}
.input::placeholder,
.textarea::placeholder { color: var(--c-text-dim); }
.textarea {
  min-height: 7rem;
  padding: var(--s-3) var(--s-4);
  resize: vertical;
  line-height: 1.55;
}

.input[aria-invalid="true"],
.textarea[aria-invalid="true"],
.select[aria-invalid="true"] { border-color: var(--c-danger); }

/* ─── Escolhas, em cartão ──────────────────────────────────
   Eram linhas regradas de uma ficha. A ideia estava certa e a execução não:
   em duas colunas a régua da esquerda acabava a meio e a da direita começava
   mais à frente, portanto liam-se duas tabelas partidas e não uma ficha; e os
   títulos longos partiam em duas linhas, deixando as linhas com alturas
   diferentes.

   O cartão resolve as duas coisas de uma vez, porque cada opção passa a ter
   limites próprios e a altura da célula deixa de ter de bater com a do lado.
   A cartela de cores continua a ser a gramática do que marca posição: o
   controlo enche de nude, e o cartão escolhido acende contorno e fundo. */
.choice {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-3);
}
@media (min-width: 700px) {
  .choice { grid-template-columns: 1fr 1fr; }
}
.choice__item {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  /* 44px é o alvo de toque mínimo; o cartão passa disso com folga. */
  min-height: 44px;
  padding: var(--s-4) var(--s-5);
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  cursor: pointer;
  transition:
    background var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out);
}
.choice__item:hover { border-color: var(--c-gold-deep); }
.choice__item:has(input:checked) {
  background: var(--c-gold-tint);
  border-color: var(--c-gold);
}

/* Tecto de escolhas atingido: os cartões por marcar recuam para segundo plano.
   Não levam `disabled`, levam `aria-disabled`, portanto continuam a receber
   foco e a ser lidos. O cursor muda para dizer, antes do clique, que aquele
   cartão não vai responder. */
/* 0.6 e não 0.4: a 0.4 o texto caía para 3,51:1. Estas opções continuam a ser
   escolhíveis assim que se desmarcar outra, e foi por isso que levaram
   `aria-disabled` em vez de `disabled`, portanto têm de continuar a ler-se.
   A 0.6 dá 6,47:1. */
.choice__item[data-locked="true"] {
  opacity: 0.6;
  cursor: not-allowed;
}
.choice__item[data-locked="true"]:hover { border-color: var(--c-line); }
/* O contador vive entre a pergunta e os cartões, no lugar da linha de apoio
   dos outros passos. Sem ele, um cartão que deixa de responder ao clique
   lê-se como avaria e não como regra. */
.choice__counter {
  margin: 0;
  font-size: var(--fs-300);
  color: var(--c-gold);
  transition: color var(--d-fast) var(--ease-out);
}
.choice__counter[data-full="true"] { color: var(--c-gold-soft); }

/* O controlo é uma amostra da cartela: enche de nude ao ser escolhido.
   Quadrado quando se pode escolher mais do que um, redondo quando é um só. A
   forma distingue-os **por marcar**, que é quando a distinção serve para
   alguma coisa: antes, os dois eram o mesmo quadrado vazio e só depois de
   clicar é que se percebia se a escolha era exclusiva. */
.choice__item input,
.check input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 17px;
  height: 17px;
  margin: 0.25em 0 0;
  /* Por marcar, este contorno é o único sinal de que ali está um controlo.
     O `--c-gold-deep` dá 4,56:1 sobre o cartão e fica na família do nude que
     enche quando se marca. O `--c-line-strong` dava 1,91:1. */
  border: 1px solid var(--c-gold-deep);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  transition:
    background var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out),
    box-shadow var(--d-fast) var(--ease-out);
}
.choice__item input[type="radio"] { border-radius: 50%; }
.choice__item input:checked,
.check input:checked {
  background: var(--c-gold);
  border-color: var(--c-gold);
}
/* O bloco interior deixa o anel à vista, que é o que um radio marcado faz.
   A cor é a do cartão escolhido, não a do painel: o painel deixou de existir
   e o fundo por baixo do controlo é o `--c-gold-tint` sobre `--c-bg-elevated`. */
.choice__item input[type="radio"]:checked {
  box-shadow: inset 0 0 0 3px var(--c-bg-elevated);
}

.choice__title { display: block; font-weight: 600; color: var(--c-text); }
.choice__desc {
  display: block;
  font-size: var(--fs-300);
  line-height: 1.45;
  color: var(--c-text-muted);
  margin-top: var(--s-1);
}

/* Checkbox */
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  cursor: pointer;
  font-size: var(--fs-400);
  color: var(--c-text);
  line-height: 1.5;
}
.check input { accent-color: var(--c-gold); margin-top: 0.25em; flex-shrink: 0; }
.check a { text-decoration: underline; text-underline-offset: 2px; }

/* Honeypot, invisible para humanos, presente para bots */
.honeypot {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ─── Accordion (FAQ) ─────────────────────────────────── */
.faq-item {
  border-bottom: 1px solid var(--c-line);
}
.faq-item:first-child { border-top: 1px solid var(--c-line); }
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  font-family: var(--ff-serif);
  font-size: var(--fs-600);
  font-weight: 500;
  color: var(--c-text);
  cursor: pointer;
  list-style: none;
  transition: color var(--d-fast) var(--ease-out);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--c-gold); }
.faq-item summary::after {
  content: "";
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--d-base) var(--ease-luxe);
}
.faq-item[open] summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}
.faq-item__body {
  padding-bottom: var(--s-5);
  color: var(--c-text-muted);
  line-height: var(--lh-body);
  max-width: 60ch;
}

/* ─── Sticky CTA / Header ─────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(10, 10, 10, 0.85);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--d-base) var(--ease-out), background var(--d-base) var(--ease-out);
  padding-top: env(safe-area-inset-top, 0px);
}
.site-header__inner > .container { padding-inline: 0; }
.site-header[data-scrolled="true"] {
  border-bottom-color: var(--c-line);
  background: rgba(10, 10, 10, 0.95);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 64px;
}
@media (min-width: 700px) {
  .site-header__inner { gap: var(--s-5); min-height: 72px; }
}
.site-header__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--c-text);
}
.site-header__logo svg { width: 36px; height: 36px; }
.site-header__logo-text {
  /* Sem isto o nome parte em duas linhas quando a navegação aperta. */
  white-space: nowrap;
  font-family: var(--ff-serif);
  font-size: var(--fs-500);
  font-weight: 500;
  letter-spacing: 0.02em;
}
/* A navegação em linha só aparece quando cabe mesmo. Esteve nos 1150px, porque
   com sete entradas mais o CTA a barra empurrava o CTA para fora do ecrã em
   tudo o que fosse abaixo disso, e entre os 900 e os 1150 ficava o hambúrguer
   num ecrã que é claramente de desktop.
   Com Serviços, Empresas e Formação colapsados no menu de Serviços são cinco
   entradas, e a barra precisa de 890px. Desceu para 900, que é exactamente
   onde o hambúrguer entra: os dois trocam sem faixa morta pelo meio.
   Se voltarem a entrar itens na barra, medir antes de mexer neste número. */
.site-header nav { display: none; }
@media (min-width: 900px) {
  .site-header nav {
    display: flex;
    gap: var(--s-5);
    align-items: center;
  }
  .site-header nav a {
    color: var(--c-text-muted);
    font-size: var(--fs-400);
    font-weight: 500;
    transition: color var(--d-fast) var(--ease-out);
  }
  .site-header nav a:hover { color: var(--c-text); }
}
/* ─── Menu de Serviços na barra ─────────────────────────
   Serviços, Empresas e Formação colapsados num só item. Eram sete entradas
   mais o CTA, e a barra só as mostrava acima de 1150px: entre os 900 e os
   1150 desistia e passava tudo para o hambúrguer, num ecrã que é claramente
   de desktop. Com cinco entradas cabem muito antes. */
.nav-menu { position: relative; }
.nav-menu__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--ff-sans);
  font-size: var(--fs-400);
  font-weight: 500;
  color: var(--c-text-muted);
  transition: color var(--d-fast) var(--ease-out);
}
.nav-menu__trigger:hover,
.nav-menu[data-current="true"] .nav-menu__trigger { color: var(--c-text); }
.nav-menu__chevron {
  width: 14px;
  height: 14px;
  transition: transform var(--d-base) var(--ease-luxe);
}
.nav-menu__trigger[aria-expanded="true"] .nav-menu__chevron { transform: rotate(180deg); }

.nav-menu__panel {
  position: absolute;
  top: calc(100% + var(--s-3));
  left: 50%;
  transform: translateX(-50%);
  min-width: 13rem;
  padding-block: var(--s-2);
  background: var(--c-bg-panel);
  border: 1px solid var(--c-line);
  /* Canto vivo, como o resto do que é superfície nesta marca. */
  border-radius: 0;
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.8);
  z-index: 60;
}
/* O `hidden` sozinho não vence um `display` declarado, e o painel é uma lista.
   Ver a mesma armadilha nos controlos do carrossel. */
.nav-menu__panel[hidden] { display: none; }
/* Ponte por cima do vão entre o gatilho e o painel. Sem ela o rato atravessa
   uma faixa que não pertence a elemento nenhum, o `pointerleave` dispara e o
   menu fecha-se debaixo do cursor a caminho do primeiro item. */
.nav-menu__panel::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--s-3);
}
.nav-menu__panel li + li { border-top: 1px solid var(--c-line); }
.site-header .nav-menu__panel a {
  display: block;
  padding: var(--s-3) var(--s-4);
  white-space: nowrap;
  color: var(--c-text-muted);
}
.site-header .nav-menu__panel a:hover,
.site-header .nav-menu__panel a[aria-current="page"] { color: var(--c-gold); }

/* Em telemóvel o CTA sai da barra: o menu abre com «Reunião de diagnóstico»
   em destaque no fundo do painel, e o WhatsApp flutuante está sempre à vista.
   Três apelos na mesma dobra era demais, e este roubava metade da barra. */
@media (max-width: 699px) {
  .site-header__cta { display: none; }
}
.site-header__cta {
  padding: var(--s-2) var(--s-4);
  min-height: 40px;
  font-size: var(--fs-300);
}
@media (min-width: 700px) {
  .site-header__cta {
    padding: var(--s-3) var(--s-6);
    min-height: 48px;
    font-size: var(--fs-400);
  }
}

/* Logo, esconder o texto quando a barra aperta. Escondido para os olhos, não
   para o leitor de ecrã: com `display: none` a ligação ficava sem nome
   acessível nenhum, porque o SVG é `aria-hidden`. As mesmas regras do
   `.sr-only`.
   O nome não parte em duas linhas graças ao white-space: nowrap na regra
   acima. Só desaparece mesmo em telemóvel estreito, onde não há espaço. */
@media (max-width: 420px) {
  .site-header__logo-text {
  /* Sem isto o nome parte em duas linhas quando a navegação aperta. */
  white-space: nowrap;
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ─── Mobile menu (hamburger + drawer) ────────────────── */
.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-right: -8px;
  border-radius: var(--r-sm);
  color: var(--c-text);
  flex-shrink: 0;
}
.menu-toggle:hover { color: var(--c-gold); }
.menu-toggle svg { width: 22px; height: 22px; }
.menu-toggle__open { display: block; }
.menu-toggle__close { display: none; }
.menu-toggle[aria-expanded="true"] .menu-toggle__open { display: none; }
.menu-toggle[aria-expanded="true"] .menu-toggle__close { display: block; }
/* Tem de acompanhar o ponto de corte da barra, senão ou ficam os dois à vista
   ou não fica nenhum. */
@media (min-width: 900px) {
  .menu-toggle { display: none; }
}

.mobile-drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--d-base) var(--ease-out), visibility var(--d-base) var(--ease-out);
}
.mobile-drawer[data-open="true"] {
  visibility: visible;
  opacity: 1;
}
.mobile-drawer__scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.mobile-drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(86vw, 360px);
  /* Painel, não superfície elevada: `--c-bg-elevated` é castanho e, desde o
     escurecimento do fundo, o menu aberto lia-se como uma mancha castanha
     colada ao site. Mesma correcção que já se tinha feito ao painel do
     formulário. */
  background: var(--c-bg-panel);
  border-left: 1px solid var(--c-line-strong);
  padding: var(--s-6) var(--s-5) calc(var(--s-6) + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  transform: translateX(100%);
  transition: transform var(--d-slow) var(--ease-luxe);
  overflow-y: auto;
}
.mobile-drawer[data-open="true"] .mobile-drawer__panel {
  transform: translateX(0);
}
.mobile-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--s-5);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--c-line);
}
.mobile-drawer__close {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--c-text-muted);
  border-radius: var(--r-sm);
}
.mobile-drawer__close:hover { color: var(--c-gold); }
.mobile-drawer__close svg { width: 22px; height: 22px; }
.mobile-drawer__nav {
  display: flex;
  flex-direction: column;
}
.mobile-drawer__nav a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: var(--s-3) var(--s-2);
  color: var(--c-text);
  font-family: var(--ff-serif);
  font-size: var(--fs-600);
  font-weight: 500;
  border-bottom: 1px solid var(--c-line);
  transition: color var(--d-fast) var(--ease-out), padding-left var(--d-base) var(--ease-luxe);
}
.mobile-drawer__nav a:hover,
.mobile-drawer__nav a:focus-visible {
  color: var(--c-gold);
  padding-left: var(--s-4);
}
/* Sem `margin-top: auto`. Servia para empurrar o bloco para o fundo do painel,
   e o bloco passou a vir antes da navegação, onde o `auto` já não tem sentido
   nenhum. */
.mobile-drawer__cta {
  padding-block: var(--s-4) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
body[data-menu-open="true"] {
  overflow: hidden;
  touch-action: none;
}

/* ─── Floating WhatsApp ───────────────────────────────── */
.fab-whatsapp {
  position: fixed;
  right: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--c-gold);
  color: var(--c-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10px 25px -8px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(214,154,120,0.4);
  z-index: 40;
  transition:
    transform var(--d-base) var(--ease-luxe),
    background var(--d-base) var(--ease-out);
}
.fab-whatsapp:hover {
  transform: scale(1.06);
  background: var(--c-gold-soft);
}
/* Recolhido enquanto o formulário está no ecrã, onde assentava por cima do
   «Continuar». `visibility` além da opacity, senão continuava a apanhar o
   toque por cima do botão. */
.fab-whatsapp[data-tucked="true"] {
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px) scale(0.9);
  transition:
    opacity var(--d-base) var(--ease-out),
    transform var(--d-base) var(--ease-luxe),
    visibility 0s linear var(--d-base);
}
@media (prefers-reduced-motion: reduce) {
  .fab-whatsapp[data-tucked="true"] { transform: none; transition: none; }
}
.fab-whatsapp svg { width: 26px; height: 26px; }
@media (min-width: 1024px) {
  .fab-whatsapp { right: 28px; bottom: 28px; }
}

/* ─── Skip link ──────────────────────────────────────── */
.skip-link {
  position: absolute;
  top: -100px;
  left: var(--s-4);
  z-index: 100;
  padding: var(--s-3) var(--s-5);
  background: var(--c-gold);
  color: var(--c-bg);
  font-weight: 500;
  border-radius: var(--r-sm);
  transition: top var(--d-base) var(--ease-out);
}
.skip-link:focus { top: var(--s-4); color: var(--c-bg); }


/* ############ SECTIONS ############ */
/* ─── HERO ───────────────────────────────────────────── */
/* Hero tipográfico, sem imagem, em composição assimétrica: cartela de cores
   como espinha à esquerda, texto alinhado a ela. Ver CLAUDE.md, «Identidade
   do hero», para o raciocínio por trás. */
.hero {
  position: relative;
  background: var(--c-bg-hero);
  padding-block: clamp(3.5rem, 8vw, 6rem) clamp(4rem, 8vw, 6.5rem);
  overflow: hidden;
}
/* Glow deslocado para a esquerda, a acompanhar a espinha em vez de ficar
   centrado como um halo genérico. */
.hero::before {
  content: "";
  position: absolute;
  top: -40%;
  left: -10%;
  width: min(80%, 52rem);
  height: 120%;
  background: radial-gradient(ellipse at center, var(--c-glow-hero), transparent 62%);
  pointer-events: none;
  z-index: 0;
}
/* Transição suave para a trust bar: sem isto, o hero quase preto encosta
   a --c-bg-soft e lê-se como um degrau. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: clamp(2.5rem, 7vw, 5rem);
  background: linear-gradient(to bottom, transparent, var(--c-bg-soft));
  pointer-events: none;
  z-index: 0;
}
/* Grão. Duas funções: mata o banding do gradiente radial em fundo quase
   preto (visível em muitos ecrãs) e dá textura ao conjunto. SVG inline em
   data URI, portanto zero pedidos de rede. */
.hero__grain {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* O ruído vive no pseudo-elemento, não no `div`.
   Um elemento com `background-image` é candidato a Largest Contentful Paint, e
   este cobre o hero inteiro, portanto ganhava sempre. Pior: o simulador do
   Lighthouse trata o `data:` URI como um pedido de rede com ida e volta, e
   atribuía 1,3s de «carregamento» a uma imagem que é instantânea. O LCP ficava
   preso em 2,6s por causa de uma textura decorativa.
   Fundos de pseudo-elementos não são candidatos a LCP. Visualmente é igual. */
/* Trama gerada em CSS, não imagem.
   O ruído era um `feTurbulence` em `data:` URI. Funcionava, mas qualquer
   elemento com `background-image` é candidato a Largest Contentful Paint, e
   este cobre o hero inteiro. O simulador do Lighthouse tratava o `data:` URI
   como um pedido de rede com ida e volta e atribuía-lhe 1,3s, o que segurava a
   métrica em 2,6s por causa de uma textura decorativa. Passar para
   pseudo-elemento não resolveu: o fundo é atribuído ao elemento de origem.
   Gradientes são gerados pelo browser e não contam como recurso de imagem.
   Dois passos cruzados a 3px e 5px, para a trama não ler como grelha regular.
   Continua a cumprir o que interessa: partir o banding do gradiente radial
   sobre fundo quase preto. */
.hero__grain::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(rgba(245, 238, 228, 0.030) 0.5px, transparent 0.5px),
    radial-gradient(rgba(0, 0, 0, 0.035) 0.5px, transparent 0.5px);
  background-size: 3px 3px, 5px 5px;
  background-position: 0 0, 1px 2px;
}
/* Composição assimétrica: espinha vertical à esquerda, texto alinhado a ela.
   Nada centrado, para fugir ao registo de landing page genérica. */
.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

/* ── Cartela de cores ─────────────────────────────────────
   Referência directa ao instrumento da coloração pessoal. As cores saem
   dos tokens, portanto acompanham sozinhas a mudança de paleta. */
.hero__rail {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 0.5rem;
}
.hero__swatch {
  display: block;
  width: clamp(10px, 1.1vw, 14px);
  height: clamp(1.5rem, 3.4vw, 2.6rem);
  transform-origin: top;
}
.hero__swatch:nth-child(1) { background: var(--c-red); }
.hero__swatch:nth-child(2) { background: var(--c-terra); }
.hero__swatch:nth-child(3) { background: var(--c-gold); }
.hero__swatch:nth-child(4) { background: var(--c-gold-soft); }
.hero__swatch:nth-child(5) { background: var(--c-text); }
/* ── O imperativo ─────────────────────────────────────────
   «Faça-a trabalhar a seu favor.» saiu do H1 por duas razões. Uma de
   composição: em Montserrat pequena logo acima do subtítulo, que também é
   Montserrat, os dois competiam. Outra de conteúdo: o H1 é a tese, isto é a
   viragem para o leitor, e não tem de partilhar a mesma caixa.

   Base horizontal, usada em ecrã estreito ou baixo. */
.hero__imperative {
  font-family: var(--ff-sans);
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

@media (max-width: 860px) {
  /* Cartela deitada por cima do texto, imperativo como linha normal.
     `minmax(0, 1fr)` e não `1fr`: um item de grelha tem `min-width: auto`, por
     isso um `1fr` nunca encolhe abaixo do min-content do conteúdo. A coluna
     resolvia para 380px dentro dos 358 disponíveis a 390px de ecrã, e como o
     hero tem `overflow: hidden` não aparecia scroll lateral nenhum: o texto e
     os botões eram simplesmente cortados à direita. */
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--s-5); }
  .hero__rail { flex-direction: row; gap: 3px; padding-top: 0; }
  .hero__swatch { width: clamp(1.75rem, 9vw, 3rem); height: 10px; }
  .hero__imperative { margin-top: var(--s-5); }
}

/* Acima de 860px de largura e 640px de altura, corre na vertical ao lado da
   cartela, como o rótulo na lombada de um mostruário de cores. A condição de
   altura evita que uma frase de 29 caracteres na vertical seja cortada pelo
   overflow do hero em ecrãs baixos. */
@media (min-width: 861px) and (min-height: 640px) {
  .hero__inner { grid-template-rows: auto 1fr; }
  .hero__rail      { grid-area: 1 / 1; }
  .hero__content   { grid-area: 1 / 2 / span 2 / 3; }
  .hero__imperative {
    grid-area: 2 / 1;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    white-space: nowrap;
    justify-self: center;
    margin-top: var(--s-5);
    padding-block: var(--s-4);
    border-inline-start: 1px solid var(--c-line-strong);
    padding-inline-start: var(--s-3);
  }
}

.hero__title {
  font-size: clamp(2rem, 1.35rem + 2.6vw, 3.75rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.018em;
  /* A linha mais longa tem 29 caracteres. Abaixo disso, cada bloco do
     título parte em duas e a composição desfaz-se. */
  max-width: 32ch;
}
/* Cada bloco do título é a sua própria linha, para a cascata ser previsível
   em vez de depender de onde o texto calha quebrar. */
.hero__line { display: block; }

/* Palavra de assinatura em Lovely May, tratada como anotação à mão sobre
   texto impresso: ligeiramente rodada e fora da linha de base, como quem
   escreve por cima de uma prova de página. É o gesto do ofício dela. */
.hero__accent {
  /* Distância do traço à palavra. Está isolada porque a Lovely May tem
     descendentes longos e este é o número a afinar se o traço ficar
     colado ou solto de mais. */
  --underline-drop: 0.1em;
  position: relative;
  display: inline-block;
  white-space: nowrap;
  transform: rotate(-2.2deg) translateY(-0.04em);
}
/* A palavra em si. O padding alarga a caixa para além dos glifos e a margem
   negativa devolve o layout ao sítio. Assim o clip-path da escrita corta
   dentro de espaço vazio e nunca decepa laçadas nem descendentes do script. */
.hero__write {
  display: inline-block;
  padding: 0.4em 0.22em;
  margin: -0.4em -0.22em;
}
.hero__underline {
  position: absolute;
  left: 0;
  /* width: 100% e não `auto`: em elementos substituídos posicionados em
     absoluto, o auto resolve para a largura intrínseca do viewBox e o traço
     sai mais curto que a palavra. */
  width: 100%;
  height: 0.18em;
  bottom: calc(var(--underline-drop) * -1);
  color: var(--c-gold);
  overflow: visible;
}
.hero__title em {
  font-family: var(--ff-script);
  font-style: normal;
  color: var(--c-gold);
  letter-spacing: 0;
  line-height: 0.9;
}
.hero__sub {
  /* Ligeiramente acima de --fs-500 para equilibrar com o display do H1.
     Mantém o rácio H1/sub perto de 3:1 em vez dos 4.7:1 anteriores. */
  font-size: clamp(1.0625rem, 1rem + 0.5vw, 1.3125rem);
  color: var(--c-text-muted);
  max-width: 56ch;
  line-height: 1.6;
  margin-top: var(--s-5);
}
.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
}
/* 600px e não 480px: o mesmo ponto de corte dos `.cluster`, senão entre os dois
   valores o hero empilhava e as restantes secções não. */
@media (max-width: 600px) {
  .hero__ctas { flex-direction: column; align-items: stretch; }
  .hero__ctas .btn { width: 100%; }
}
.hero__meta {
  margin-top: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-4);
  align-items: center;
  font-size: var(--fs-300);
  color: var(--c-text-dim);
  letter-spacing: 0.02em;
}
@media (max-width: 600px) {
  .hero__meta-dot { display: none; }
  .hero__meta { gap: var(--s-1) var(--s-2); flex-direction: column; align-items: flex-start; }
}
.hero__meta-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--c-gold-deep);
  display: inline-block;
}
/* ── Entrada encenada do hero ─────────────────────────────
   Mesma gramática do resto do site (opacity + translateY 16px, 700ms,
   --ease-luxe), só que em cascata e disparada no load em vez de no scroll.
   CSS puro: sem JS, portanto não há risco de conteúdo invisível se um
   script falhar. Tudo anulado em prefers-reduced-motion, no fim do bloco. */
@keyframes heroUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
/* Escrita da palavra: a caixa vai-se abrindo da esquerda para a direita.
   Funciona com qualquer fonte, ao contrário de desenhar traçados, que exigiria
   ter as letras em path. Num script, cujas letras já se ligam entre si, lê-se
   como mão a escrever. Insets nunca negativos: o padding da .hero__write é que
   garante folga para as laçadas. */
@keyframes heroWrite {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes heroSwatch {
  from { opacity: 0; transform: scaleY(0); }
  to   { opacity: 1; transform: none; }
}
@keyframes heroSwatchH {
  from { opacity: 0; transform: scaleX(0); }
  to   { opacity: 1; transform: none; }
}
@keyframes heroDraw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
/* Sem transform: o imperativo usa-o para a rotação vertical. */
@keyframes heroFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* A cartela entra primeiro e o texto depois. Não é gosto: é o argumento do
   próprio título, «a imagem comunica antes de qualquer palavra». */
/* Os tempos foram comprimidos para cerca de metade em 11/08/2026. A ordem é
   que é identidade, os milissegundos não eram: com `animation-fill-mode: both`
   o texto está a `opacity: 0` até o atraso passar, e o Largest Contentful Paint
   só podia acontecer depois do último beat. Era o que segurava a métrica em
   2,8s. A cartela continua a entrar antes do texto, apenas mais depressa. */
.hero__swatch    { animation: heroSwatch 520ms var(--ease-luxe) both; }
.hero__swatch:nth-child(1) { animation-delay:  30ms; }
.hero__swatch:nth-child(2) { animation-delay:  70ms; }
.hero__swatch:nth-child(3) { animation-delay: 110ms; }
.hero__swatch:nth-child(4) { animation-delay: 150ms; }
.hero__swatch:nth-child(5) { animation-delay: 190ms; }

.hero__eyebrow,
.hero__line,
.hero__sub,
.hero__ctas,
.hero__meta {
  animation: heroUp 420ms var(--ease-luxe) both;
}
.hero__eyebrow   { animation-delay: 200ms; }
.hero__line--a   { animation-delay: 250ms; }
.hero__line--b   { animation-delay: 300ms; }
.hero__sub       { animation-delay: 380ms; }
.hero__ctas      { animation-delay: 440ms; }
.hero__meta      { animation-delay: 490ms; }
/* Último beat: a lombada acende-se depois de tudo o resto assentar. Fade
   simples, sem translação, porque o transform está ocupado com a rotação. */
.hero__imperative { animation: heroFade 700ms var(--ease-luxe) 860ms both; }

/* A frase assenta primeiro, deixando o lugar da palavra vazio. Só depois é
   que a palavra é escrita e sublinhada, como quem anota uma prova composta. */
.hero__write     { animation: heroWrite 640ms var(--ease-in-out) 400ms both; }
.hero__underline path {
  stroke-dasharray: 1;
  animation: heroDraw 620ms var(--ease-out) 1560ms both;
}

/* Em ecrã estreito a cartela é horizontal, logo cresce na horizontal. */
@media (max-width: 860px) {
  .hero__swatch { animation-name: heroSwatchH; transform-origin: left; }
}

/* ── Motion reduzido: estado final imediato ─────────────── */
@media (prefers-reduced-motion: reduce) {
  .hero__swatch,
  .hero__eyebrow,
  .hero__line,
  .hero__sub,
  .hero__ctas,
  .hero__meta,
  .hero__underline path {
    animation: none;
    opacity: 1;
    transform: none;
    stroke-dashoffset: 0;
  }
  /* Sem `transform: none`, senão perde a rotação que o põe na vertical. */
  .hero__imperative { animation: none; opacity: 1; }
  /* A palavra tem de aparecer inteira, sem a escrita progressiva. */
  .hero__write {
    animation: none;
    clip-path: none;
  }
}

/* O HERO NÃO LEVA FOTOGRAFIA. Decidido em 27/07/2026, testado outra vez em
   11/08/2026 com um retrato da sessão nova e revertido: a primeira dobra já
   leva cartela de cores, eyebrow, título em três linhas, subtítulo de cinco,
   dois CTAs, a linha de credenciais e o imperativo vertical. Acrescentar um
   retrato ao lado disso não é dar presença à marca, é encher.
   **O rosto dela aparece logo a seguir, na secção Sobre**, com a fotografia
   nova, que é onde tem contexto e espaço para respirar.
   Não há classe `.hero__media`: se voltar a ser preciso, é composição nova,
   não é ressuscitar isto. */

/* ─── Trust bar / Métricas ───────────────────────────── */
.trustbar {
  border-block: 1px solid var(--c-line);
  padding-block: var(--s-6);
  background: var(--c-bg-soft);
}
.trustbar__intro {
  text-align: center;
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
  margin-bottom: var(--s-5);
}
.trustbar__metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
  text-align: center;
}
@media (max-width: 640px) {
  .trustbar__metrics { grid-template-columns: 1fr; gap: var(--s-4); }
}
.metric__number {
  font-family: var(--ff-serif);
  font-size: var(--fs-800);
  color: var(--c-gold);
  font-weight: 500;
  line-height: 1;
  display: block;
}
.metric__label {
  font-size: var(--fs-400);
  color: var(--c-text-muted);
  margin-top: var(--s-2);
  display: block;
}

/* ─── Sobre ──────────────────────────────────────────── */
.about__media {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--c-line);
  background: var(--c-bg-elevated);
}
.about__media img { width: 100%; height: 100%; object-fit: cover; }

/* Retrato recortado, sem fundo próprio.
   Não pode entrar na moldura acima por duas razões. O `object-fit: cover` num
   rácio 4/5 cortaria pelo peito um recorte que é 1:1,88, e um PNG transparente
   dentro de uma caixa com fundo, contorno e raio volta a ser exactamente o
   rectângulo fotográfico que a identidade evita. Sem fundo é arte recortada
   assente na banda, que é outra coisa.
   A moldura fica no ficheiro: serve para qualquer fotografia normal que venha
   a entrar aqui. */
.about__media--cutout {
  aspect-ratio: 4 / 5;
  border: 0;
  border-radius: 0;
  background: none;
  overflow: visible;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.about__media--cutout img {
  position: relative;
  width: auto;
  max-width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
  /* A figura desvanece na banda em vez de acabar a direito.
     O original está cortado a meio da coxa, e um recorte que acaba num corte
     recto lê-se como erro, não como enquadramento. Chegou a estar aqui um
     filete a fazer de chão, que resolvia a flutuação mas assumia o corte em
     vez de o esconder. A máscara resolve as duas coisas de uma vez: não há
     aresta nenhuma para explicar.
     O prefixo `-webkit-` fica para o Safari anterior ao 15.4. */
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 26%);
  mask-image: linear-gradient(to top, transparent 0, #000 26%);
}
/* Acima do ponto de corte da `.split` a figura tem coluna própria, e a altura
   da coluna é a do texto ao lado. Sem isto sobrava um vão morto entre os pés e
   o fim da secção, que era o que mais se notava. Agora a coluna estica com a
   linha da grelha e sangra para dentro do `padding` inferior da secção, de
   modo que o desvanecimento acaba exactamente na aresta da banda.
   Abaixo desse ponto não se faz: em coluna única a fotografia vem antes do
   texto, e uma margem negativa puxaria o texto por cima dela. */
@media (min-width: 900px) {
  .about__media--cutout {
    align-self: stretch;
    aspect-ratio: auto;
    margin-bottom: calc(-1 * var(--section-y));
  }
}
.about__quote {
  font-family: var(--ff-serif);
  font-style: italic;
  font-size: var(--fs-600);
  line-height: 1.4;
  color: var(--c-text);
  border-left: 2px solid var(--c-gold);
  padding-left: var(--s-5);
  margin-block: var(--s-6);
  max-width: 50ch;
}
@media (max-width: 600px) {
  .about__quote { padding-left: var(--s-4); margin-block: var(--s-5); }
}
.about__credentials {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-5);
}

/* ─── Para Empresas (B2B band) ───────────────────────── */
.b2b {
  position: relative;
  background: #050505;
  border-top: 1px solid var(--c-gold-deep);
  padding-block: clamp(4rem, 7vw, 6rem);
}
/* Introdução e fotografia lado a lado. O ponto de corte é o mesmo da barra de
   topo, 900px, para o site não ter dois «isto agora é desktop» diferentes. */
.b2b__intro {
  display: grid;
  gap: var(--s-7);
  align-items: center;
}
@media (min-width: 900px) {
  .b2b__intro {
    grid-template-columns: 1.15fr 0.85fr;
    gap: var(--s-8);
  }
}
.b2b__media {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  /* Raio igual ao dos cards desta banda. Aqui não se usa canto vivo: seria o
     único elemento com aresta viva ao lado de quatro cards arredondados. */
  border-radius: var(--r-md);
  border: 1px solid var(--c-line);
}
.b2b__media img { width: 100%; height: 100%; object-fit: cover; }
/* Em coluna única a fotografia não precisa de ocupar um ecrã inteiro: ao lado
   do texto é apoio, sozinha e a toda a largura passava a ser o assunto. */
@media (max-width: 899px) {
  .b2b__media {
    max-width: 22rem;
    margin-inline: auto;
  }
}

.b2b__cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-4);
  margin-top: var(--s-6);
  /* Ao topo, senão os cards fechados esticavam à altura do que estiver aberto
     e a linha inteira saltava a cada clique. */
  align-items: start;
}
@media (max-width: 1100px) { .b2b__cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) { .b2b__cards { grid-template-columns: 1fr; } }
.b2b__card {
  background: var(--c-bg);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  padding: var(--s-5);
  transition: border-color var(--d-base) var(--ease-out);
}
.b2b__card[open] { border-color: var(--c-line-strong); }
/* Bloco, não flex: o <h3> e a linha vivem soltos dentro do <summary>, que é o
   que o content model permite. Um <span> a envolvê-los era inválido, porque
   span só aceita phrasing content. Daí a seta ir em absoluto. */
.b2b__card summary {
  display: block;
  position: relative;
  padding-right: var(--s-6);
  cursor: pointer;
  list-style: none;
}
.b2b__card summary::-webkit-details-marker { display: none; }
.b2b__card h3 {
  font-size: var(--fs-500);
  margin-bottom: var(--s-2);
  color: var(--c-text);
  transition: color var(--d-fast) var(--ease-out);
}
.b2b__card summary:hover h3 { color: var(--c-gold); }
.b2b__card-line {
  display: block;
  font-size: var(--fs-400);
  color: var(--c-text-muted);
}
/* Mesma seta da FAQ, para as duas zonas de abrir se lerem como a mesma coisa. */
.b2b__card summary::after {
  content: "";
  position: absolute;
  right: 2px;
  top: 0.5em;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid var(--c-gold);
  border-bottom: 1.5px solid var(--c-gold);
  transform: rotate(45deg);
  transition: transform var(--d-base) var(--ease-luxe);
}
.b2b__card[open] summary::after { transform: rotate(-135deg); }
/* Marcador igual ao dos cards de serviço: filete nude de 8px. */
.b2b__topics {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-line);
}
.b2b__topics li {
  font-size: var(--fs-300);
  color: var(--c-text-muted);
  position: relative;
  padding-left: var(--s-4);
}
.b2b__topics li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 8px;
  height: 1px;
  background: var(--c-gold);
}

/* ─── Page hero (páginas internas) ───────────────────── */
.page-hero {
  position: relative;
  background: var(--c-bg-hero);
  padding-block: clamp(4rem, 8vw, 6rem) clamp(1.25rem, 2.5vw, 2rem);
  overflow: hidden;
}
.page-hero::before {
  content: "";
  position: absolute;
  top: -30%;
  right: -10%;
  width: 55%;
  height: 100%;
  background: radial-gradient(circle at center, rgba(214,154,120,0.08), transparent 60%);
  pointer-events: none;
  z-index: 0;
}
.page-hero > .container { position: relative; z-index: 1; }
.page-hero__title {
  font-size: var(--fs-800);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.018em;
  max-width: 22ch;
  margin-top: var(--s-3);
}
.page-hero__sub {
  font-size: var(--fs-500);
  color: var(--c-text-muted);
  max-width: 60ch;
  line-height: 1.55;
  margin-top: var(--s-4);
}
.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
  font-size: var(--fs-300);
  color: var(--c-text-dim);
  letter-spacing: 0.02em;
  margin-bottom: var(--s-5);
}
.breadcrumbs a { color: var(--c-text-muted); }
.breadcrumbs a:hover { color: var(--c-gold); }
.breadcrumbs [aria-current="page"] { color: var(--c-gold); }

/* Página actual na navegação.
   A cor sozinha não chega: entre `--c-text-muted` e `--c-gold` há 1,36:1 de
   luminância, e são os dois tons quentes claros, portanto para quem tem
   discriminação cromática reduzida são a mesma coisa. É falha de WCAG 1.4.1,
   uso da cor como único meio. O filete acrescenta forma, e é a mesma gramática
   das amostras da cartela e dos pontos do carrossel. */
.site-header nav [aria-current="page"],
.mobile-drawer__nav [aria-current="page"],
.site-header .nav-menu__panel a[aria-current="page"] {
  color: var(--c-gold);
  box-shadow: 0 2px 0 var(--c-gold);
}
/* No painel do menu de Serviços e na gaveta as entradas têm padding lateral,
   e o filete a toda a largura da caixa ficava solto do texto. */
.site-header .nav-menu__panel a[aria-current="page"],
.mobile-drawer__nav [aria-current="page"] {
  box-shadow: inset 0 -2px 0 var(--c-gold);
}
/* O nome do percurso no menu de Serviços marca também o gatilho. */
.nav-menu[data-current="true"] .nav-menu__trigger {
  box-shadow: 0 2px 0 var(--c-gold);
}

/* ─── Formação ───────────────────────────────────────── */
.formacao {
  background: var(--c-bg-soft);
  border-top: 1px solid var(--c-line);
}
.formacao__creds {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
  margin-top: var(--s-7);
  list-style: none;
  padding: 0;
}
@media (max-width: 900px) { .formacao__creds { grid-template-columns: 1fr; } }
.cred-card {
  position: relative;
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  padding: var(--s-6) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.cred-card__badge {
  align-self: flex-start;
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-gold);
  border: 1px solid var(--c-gold-deep);
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-pill);
}
.cred-card h3 {
  font-family: var(--ff-serif);
  font-size: var(--fs-600);
  font-weight: 500;
  line-height: 1.25;
}
.cred-card p {
  font-size: var(--fs-400);
  color: var(--c-text-muted);
}

.formacao__statement {
  margin: var(--s-8) auto 0;
  text-align: left;
}
.formacao__quote {
  font-family: var(--ff-serif);
  font-style: italic;
  font-size: var(--fs-600);
  line-height: 1.4;
  color: var(--c-text);
  border-left: 2px solid var(--c-gold);
  padding-left: var(--s-5);
  margin-bottom: var(--s-6);
  max-width: 52ch;
}
.formacao__statement p {
  color: var(--c-text-muted);
  line-height: 1.65;
  margin-top: var(--s-4);
  max-width: 62ch;
}
.formacao__statement p:first-of-type { color: var(--c-text); }

.formacao__sub-head {
  margin-top: var(--s-9);
  padding-top: var(--s-7);
  border-top: 1px solid var(--c-line);
}
.formacao__sub-head .eyebrow { margin-bottom: var(--s-2); }
.formacao__sub-title {
  font-family: var(--ff-serif);
  font-size: var(--fs-700);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.formacao__sub-head .lead {
  margin-top: var(--s-3);
  max-width: 60ch;
}

/* Áreas de intervenção: cinco títulos, sem descrição. Em cartões ficariam
   caixas ocas, por isso são linhas numeradas de uma ficha, na mesma
   linguagem regrada do formulário de diagnóstico. */
.formacao__areas {
  margin-top: var(--s-6);
  border-top: 1px solid var(--c-line);
}
.area-row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: clamp(1rem, 3vw, 2rem);
  padding: clamp(1rem, 2.5vw, 1.5rem) var(--s-2);
  border-bottom: 1px solid var(--c-line);
  transition:
    padding-inline-start var(--d-base) var(--ease-luxe),
    background var(--d-base) var(--ease-out);
}
.area-row:hover {
  background: rgba(214, 154, 120, 0.04);
  padding-inline-start: var(--s-5);
}
.area-row__num {
  font-family: var(--ff-serif);
  font-size: var(--fs-500);
  color: var(--c-gold);
  line-height: 1;
}
.area-row h3 {
  font-size: clamp(1.15rem, 1rem + 0.8vw, 1.75rem);
  line-height: 1.25;
  color: var(--c-text);
}

.ufcd-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s-3);
  margin-top: var(--s-6);
  list-style: none;
  padding: 0;
}
@media (max-width: 768px) { .ufcd-list { grid-template-columns: 1fr; } }
.ufcd-item {
  background: var(--c-bg);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  padding: var(--s-5);
  transition: border-color var(--d-base) var(--ease-out);
}
.ufcd-item:hover { border-color: var(--c-gold-deep); }
.ufcd-item__meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-3);
}
.ufcd-item__code {
  font-family: var(--ff-sans);
  font-size: var(--fs-300);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-gold);
}
.ufcd-item__hours {
  font-size: var(--fs-300);
  color: var(--c-text-dim);
  padding-left: var(--s-3);
  border-left: 1px solid var(--c-line-strong);
}
/* O HTML usa h3, não h4. Com o selector errado estes títulos caíam no h3
   global (--fs-700) e saíam enormes dentro dos cartões. */
.ufcd-item h3 {
  font-size: var(--fs-400);
  font-weight: 500;
  line-height: 1.35;
  margin-bottom: var(--s-2);
  color: var(--c-text);
}
.ufcd-item p {
  font-size: var(--fs-300);
  color: var(--c-text-muted);
  line-height: 1.5;
}

/* ─── Serviços ───────────────────────────────────────── */
.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
  margin-top: var(--s-7);
}
@media (max-width: 1024px) { .services-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .services-grid { grid-template-columns: 1fr; } }

.service-card {
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 4vw, 2rem);
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  transition:
    transform var(--d-base) var(--ease-luxe),
    border-color var(--d-base) var(--ease-out),
    box-shadow var(--d-base) var(--ease-out);
}
.service-card:hover {
  transform: translateY(-4px);
  border-color: var(--c-gold);
  box-shadow: var(--glow-gold);
}
.service-card__icon {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--c-gold);
  border-radius: var(--r-sm);
  color: var(--c-gold);
  margin-bottom: var(--s-5);
}
.service-card__icon svg { width: 22px; height: 22px; }
.service-card__title {
  font-size: var(--fs-600);
  margin-bottom: var(--s-2);
}
.service-card__headline {
  color: var(--c-text-muted);
  font-size: var(--fs-400);
  margin-bottom: var(--s-4);
}
.service-card__bullets {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-line);
}
.service-card__bullets li {
  font-size: var(--fs-300);
  color: var(--c-text-muted);
  position: relative;
  padding-left: var(--s-4);
}
.service-card__bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 8px;
  height: 1px;
  background: var(--c-gold);
}
.service-card__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-5);
  color: var(--c-gold);
  font-weight: 500;
  font-size: var(--fs-400);
}
.service-card__cta::after {
  content: "→";
  transition: transform var(--d-base) var(--ease-luxe);
}
.service-card:hover .service-card__cta::after { transform: translateX(4px); }

/* ─── Método ─────────────────────────────────────────── */
.method-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-7);
  margin-top: var(--s-7);
  position: relative;
}
.method-step {
  display: grid;
  /* `minmax(0, 1fr)` e não `1fr`, pela mesma razão do hero: item de grelha tem
     `min-width: auto` e não encolhe abaixo do min-content. */
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-5);
  align-items: start;
}
@media (max-width: 640px) {
  .method-step { gap: var(--s-4); }
}
/* A fotografia entra como terceira coluna em ecrã largo e desce para baixo do
   texto em ecrã estreito. Cantos vivos e filete, como o resto. */
.method-step__media { margin: 0; grid-column: 1 / -1; }
.method-step__media img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--c-line);
}
@media (min-width: 861px) {
  /* Linhas alternadas, imagem de um lado e texto do outro. A imagem ocupa
     perto de metade da linha: com a coluna estreita de 17rem que isto tinha
     ao início, as fotografias liam-se como miniaturas e não como conteúdo.
     Alternar o lado dá ritmo à sequência e evita três linhas iguais. */
  .method-step {
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 26rem);
    gap: var(--s-6);
    align-items: center;
  }
  .method-step__media { grid-column: auto; }
  .method-step:nth-child(even) {
    grid-template-columns: minmax(0, 26rem) auto minmax(0, 1fr);
  }
  .method-step:nth-child(even) .method-step__media { grid-column: 1; grid-row: 1; }
  .method-step:nth-child(even) .method-step__num { grid-column: 2; grid-row: 1; }
  .method-step:nth-child(even) .method-step__body { grid-column: 3; grid-row: 1; }
  /* Sem isto, o parágrafo de 56ch obrigava a coluna do texto a ser mais larga
     do que o espaço que sobra da imagem. */
  .method-step__body p { max-width: none; }
}
.method-step__num {
  font-family: var(--ff-serif);
  font-size: clamp(2.5rem, 5vw, 4rem);
  color: var(--c-gold);
  line-height: 1;
  font-weight: 500;
  min-width: 3ch;
}
.method-step__body h3 {
  font-size: var(--fs-600);
  margin-bottom: var(--s-2);
}
.method-step__body p {
  color: var(--c-text-muted);
  max-width: 56ch;
}

/* ─── Testemunhos ────────────────────────────────────── */
/* A folga é entre o cabeçalho da secção e a fila, não no topo da fila. Em
   /testemunhos/ o cabeçalho visível deixou de existir, e a margem incondicional
   abria um vão de 150px entre o page-hero e o primeiro cartão. */
.section-head + .testimonials { margin-top: var(--s-7); }

/* Fila única em todas as larguras, com scroll-snap. Antes eram duas coisas
   diferentes: grelha que quebrava em linhas acima de 640px e fila scrollável
   abaixo. Uma fila só, com o número de colunas a mudar por breakpoint, é o que
   permite ao mesmo componente ser carrossel em qualquer largura assim que os
   testemunhos passarem dos três que cabem lado a lado.

   `grid-template-columns: none` é obrigatório. Com uma coluna explícita a
   `1fr` e `grid-auto-flow: column`, só o primeiro cartão cai na coluna
   explícita e fica com o espaço que sobra depois das implícitas. Dava 170px ao
   primeiro e 358px aos outros dois. Sem coluna explícita, todos os cartões são
   implícitos e medem o mesmo. */
.testimonials-track {
  display: grid;
  grid-template-columns: none;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 2 * var(--s-5)) / 3);
  gap: var(--s-5);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--c-gold-deep) transparent;
  -webkit-overflow-scrolling: touch;
}
/* O foco do teclado é posto na fila pelo JS, e sem `outline-offset` negativo
   o anel fica meio cortado pelo `overflow` do próprio contentor. */
.testimonials-track:focus-visible { outline-offset: -2px; }
.testimonials-track::-webkit-scrollbar { height: 6px; }
.testimonials-track::-webkit-scrollbar-track { background: transparent; }
.testimonials-track::-webkit-scrollbar-thumb { background: var(--c-gold-deep); border-radius: var(--r-pill); }
.testimonials-track > * {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
/* A barra de scroll só ocupa altura quando há mesmo o que percorrer. O
   atributo é posto pelo JS. */
[data-carousel="on"] .testimonials-track { padding-bottom: var(--s-4); }
/* Dois testemunhos, como na homepage, ocupam a largura toda em vez de dois
   terços com um vazio à direita. Abaixo de 1024px a regra geral já dá duas
   colunas, portanto o modificador só faz falta acima disso. */
@media (min-width: 1025px) {
  .testimonials--pair .testimonials-track {
    grid-auto-columns: calc((100% - var(--s-5)) / 2);
  }
}
@media (max-width: 1024px) {
  .testimonials-track { grid-auto-columns: calc((100% - var(--s-5)) / 2); }
}
@media (max-width: 640px) {
  .testimonials-track {
    /* Menos de 100% para o cartão seguinte espreitar: é o que diz a quem
       chega que a fila continua para o lado. */
    grid-auto-columns: 86%;
    gap: var(--s-4);
  }
}

/* ─── Controlos do carrossel ─────────────────────────────
   Construídos em JS e só visíveis quando a fila transborda, ver
   `assets/js/testimonials.js`. O `hidden` precisa de ser reforçado: sozinho
   não vence o `display: flex` da própria regra. */
.carousel-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  margin-top: var(--s-5);
}
.carousel-controls[hidden] { display: none; }

.carousel-dots {
  display: flex;
  align-items: center;
  gap: var(--s-1);
}
/* Os pontos não são pontos: são amostras, como as da cartela do hero e as do
   progresso do formulário. O alvo de toque são os 44px do botão, o filete de
   3px é só o que se vê. */
.carousel-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  min-height: 44px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}
/* O filete é o único elemento visual do botão, portanto tem de chegar aos 3:1
   do WCAG 1.4.11 sozinho. O --c-line-strong das bordas do resto do site dá
   1,8:1 contra a banda soft, e os pontos inactivos desapareciam. O
   --c-gold-deep dá 4,3:1.

   A amostra activa distingue-se por cor e por largura, não só por cor. */
.carousel-dot::before {
  content: "";
  width: 20px;
  height: 3px;
  background: var(--c-gold-deep);
  transition:
    background var(--d-base) var(--ease-out),
    width var(--d-base) var(--ease-luxe);
}
.carousel-dot:hover::before { background: var(--c-gold-soft); }
.carousel-dot[aria-current="true"]::before {
  width: 28px;
  background: var(--c-gold);
}

.carousel-buttons {
  display: flex;
  gap: var(--s-2);
}
.carousel-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--c-text-muted);
  background: transparent;
  /* Canto vivo, como as amostras e a ficha de diagnóstico. */
  border: 1px solid var(--c-line-strong);
  border-radius: 0;
  cursor: pointer;
  transition:
    color var(--d-base) var(--ease-out),
    border-color var(--d-base) var(--ease-out);
}
.carousel-btn:hover {
  color: var(--c-gold);
  border-color: var(--c-gold);
}
.carousel-btn svg { width: 20px; height: 20px; }
.testimonial {
  display: flex;
  flex-direction: column;
  padding: var(--s-6);
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
}
.testimonial::before {
  content: "“";
  font-family: var(--ff-script);
  font-size: 5rem;
  color: var(--c-gold);
  line-height: 0.7;
  margin-bottom: var(--s-3);
}
.testimonial__quote {
  font-family: var(--ff-serif);
  font-style: italic;
  font-size: var(--fs-500);
  line-height: 1.5;
  color: var(--c-text);
  flex: 1;
}
/* Numa coluna de 300px, a serifa a --fs-500 dá quatro palavras por linha e o
   cartão cresce sem fim. A aspa decorativa também encolhe. */
@media (max-width: 640px) {
  .testimonial { padding: var(--s-5); }
  .testimonial::before { font-size: 3.25rem; }
  .testimonial__quote { font-size: var(--fs-400); }
}
.testimonial__author {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-line);
}
/* Retrato do cliente, quando houver. Ainda não há: falta foto e autorização
   de uso de imagem. O layout fica preparado para que entrar uma seja
   acrescentar a `<img>` ao `figcaption`, sem tocar em mais nada.

   O `:has()` é o que evita um wrapper à volta do nome e do papel. Sem ele, um
   `grid-template-columns: auto 1fr` permanente deixaria o `column-gap` a
   afastar o texto da margem nos cartões sem retrato. Onde o `:has()` não for
   suportado, o retrato empilha por cima do nome, que é degradação aceitável. */
.testimonial__author:has(.testimonial__avatar) {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "avatar name"
    "avatar role";
  align-items: center;
  column-gap: var(--s-3);
  row-gap: var(--s-1);
}
.testimonial__avatar {
  grid-area: avatar;
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: var(--r-pill);
  border: 1px solid var(--c-gold-deep);
}
.testimonial__author:has(.testimonial__avatar) .testimonial__name { grid-area: name; }
.testimonial__author:has(.testimonial__avatar) .testimonial__role { grid-area: role; }
.testimonial__name {
  font-weight: 500;
  color: var(--c-text);
  font-family: var(--ff-sans);
  font-style: normal;
}
/* `--c-text-dim` e não `--c-text-muted` era o que estava, e falhava: o dim dá
   4,49:1 sobre `--c-bg`, mas o cartão do testemunho é `--c-bg-elevated`, que é
   mais claro, e ali desce para 3,97:1. Abaixo dos 4,5:1 que o AA pede a texto
   pequeno. O muted dá 8,45:1 e continua claramente secundário face ao nome,
   que é `--c-text` a 500. Regra geral: o dim não serve sobre superfícies
   elevadas. */
.testimonial__role {
  font-size: var(--fs-300);
  color: var(--c-text-muted);
}

/* ─── Galeria ────────────────────────────────────────── */
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3);
}
/* Mesma razão da fila de testemunhos: a folga separa a grelha do cabeçalho da
   secção, e sem cabeçalho não há nada de que a separar. */
.section-head + .gallery { margin-top: var(--s-7); }
@media (max-width: 1024px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) { .gallery { grid-template-columns: repeat(2, 1fr); } }
.gallery__item {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
}
.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--d-slow) var(--ease-luxe);
}
.gallery__item:hover img { transform: scale(1.04); }

/* ─── FAQ section ────────────────────────────────────── */
.faq-list {
  margin-top: var(--s-4);
  max-width: 56rem;
  margin-inline: auto;
}
/* Título de grupo dentro da FAQ, separa consultoria de formação. */
.faq-group__title {
  max-width: 56rem;
  margin-inline: auto;
  margin-top: var(--s-8);
  font-size: var(--fs-600);
  color: var(--c-gold);
}
.faq-group__title:first-of-type { margin-top: var(--s-7); }

/* ─── Formulário Diagnóstico ─────────────────────────── */
/* Sem painel. Era uma caixa com contorno e fundo próprio, pousada dentro de
   uma secção que já é uma banda escura: uma caixa dentro de outra, que é
   exactamente o desenho de um formulário genérico embutido numa página. O que
   segura a composição agora é a mesma coisa que segura o hero, tipografia e a
   cartela de cores, e o peso visual vive nos cartões de escolha.
   Saiu com ele o filete de cartela no topo do painel: as amostras de progresso
   ficam quatro linhas abaixo e diziam a mesma coisa duas vezes. */
.diagnostic {
  position: relative;
  max-width: 52rem;
  margin: var(--s-7) auto 0;
}
/* O `fieldset` traz do browser uma moldura `2px groove` e padding próprio, com
   a legend encaixada a cortá-la. Aqui é contentor semântico e mais nada.
   `min-width: 0` porque o fieldset tem largura mínima intrínseca própria e,
   sem isto, recusa encolher dentro de flex ou grid. */
.diagnostic__step {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
/* A pergunta é o assunto do ecrã, e passa a ter o peso disso: Black Mango, à
   escala dos H2 do site. Em Montserrat pequena com um filete por baixo lia-se
   como rótulo de campo, e não como a pergunta a que se está a responder.
   O `legend` de um fieldset sem moldura comporta-se como bloco normal. */
.diagnostic__step legend {
  display: block;
  width: 100%;
  padding: 0;
  font-family: var(--ff-serif);
  font-size: var(--fs-700);
  line-height: var(--lh-tight);
  color: var(--c-text);
  max-width: 22ch;
  /* A margem tem de estar aqui e não no elemento seguinte. Num fieldset com
     `display: flex`, o `legend` é a legenda renderizada e **não é item de
     flex**: fica fora da caixa de conteúdo e o `gap` não o apanha. Quem vem a
     seguir é o primeiro item, portanto não tem gap nenhum antes de si, e uma
     margem negativa lá posta sobe-lhe por cima da pergunta. */
  margin-bottom: var(--s-3);
}
/* Linha de apoio por baixo da pergunta. No passo 2 quem ocupa este lugar é o
   contador de escolhas, que sabe mais do que uma frase fixa saberia. */
.diagnostic__lede {
  margin: 0;
  font-size: var(--fs-300);
  color: var(--c-gold);
}
/* Progresso como amostras, não como barra genérica: quatro blocos que vão
   ganhando cor, na mesma progressão cromática da cartela. */
.diagnostic__progress {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  height: 6px;
  margin-bottom: var(--s-4);
}
.diagnostic__seg {
  background: var(--c-line);
  transition: background var(--d-slow) var(--ease-luxe);
}
.diagnostic__seg[data-done="true"]:nth-child(1) { background: var(--c-red); }
.diagnostic__seg[data-done="true"]:nth-child(2) { background: var(--c-terra); }
.diagnostic__seg[data-done="true"]:nth-child(3) { background: var(--c-gold); }
.diagnostic__seg[data-done="true"]:nth-child(4) { background: var(--c-gold-soft); }
/* O número do passo, em serifa, ao lado das amostras. */
.diagnostic__step-indicator {
  flex: none;
  font-family: var(--ff-serif);
  font-size: var(--fs-600);
  line-height: 1;
  color: var(--c-gold);
  /* Largura fixa: sem isto a linha das amostras encolhe e cresce conforme o
     número, e as amostras dançavam de passo para passo. */
  min-width: 5.5ch;
  text-align: right;
}
.diagnostic__step { display: none; flex-direction: column; gap: var(--s-5); }
.diagnostic__step[data-active="true"] { display: flex; animation: stepIn var(--d-slow) var(--ease-luxe); }
@keyframes stepIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.form-grid { display: grid; gap: var(--s-5); }
@media (min-width: 700px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  /* Nome e mensagem atravessam as duas colunas. Sem isto ficavam com metade da
     largura e a outra metade vazia, que era o defeito mais visível do passo. */
  .form-group--wide { grid-column: 1 / -1; }
}

/* ─── Passo 4: campos e resumo lado a lado ─────────────────
   A coluna da direita estava vazia. Não se enche com mais campos: pedir mais
   dados no passo onde se desiste é o contrário do que se quer. Enche-se com o
   que a pessoa já respondeu.
   Em coluna única o resumo vem **depois** dos campos, por ordem no DOM: quem
   navega por teclado ou leitor de ecrã percorre primeiro o que tem de
   preencher, e a revisão fica imediatamente antes do «Enviar pedido». */
.diagnostic__final { display: grid; gap: var(--s-6); align-items: start; }
@media (min-width: 900px) {
  .diagnostic__final { grid-template-columns: 1.3fr 0.7fr; gap: var(--s-7); }
}
.diagnostic__fields { display: flex; flex-direction: column; gap: var(--s-5); }
.diagnostic__recap {
  padding: var(--s-5);
  background: var(--c-bg-elevated);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
}
.diagnostic__recap-title {
  font-family: var(--ff-sans);
  font-size: var(--fs-300);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  /* `--c-gold-deep` dava 3,61:1 sobre o cartão. O nude cheio dá 5,52:1. */
  color: var(--c-gold);
  margin-bottom: var(--s-4);
}
.diagnostic__recap-list dt {
  font-size: 0.72rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  /* Regra que vale para o site todo: o `--c-text-dim` dá 3,97:1 sobre
     `--c-bg-elevated` e não serve em texto pequeno sobre superfícies
     elevadas. O muted dá 8,45:1. */
  color: var(--c-text-muted);
  margin-top: var(--s-4);
}
.diagnostic__recap-list dt:first-of-type { margin-top: 0; }
.diagnostic__recap-list dd {
  font-size: var(--fs-300);
  color: var(--c-text);
  margin-top: var(--s-1);
}
/* As entradas da lista de objectivos levam a amostra à frente, a mesma marca
   do progresso e dos pontos do carrossel. O reset do site tira o marcador a
   todas as listas, portanto o quadrado é desenhado aqui. */
.diagnostic__recap-list ul { display: flex; flex-direction: column; gap: var(--s-2); }
.diagnostic__recap-list li {
  display: flex;
  gap: var(--s-3);
  align-items: baseline;
  font-size: var(--fs-300);
  color: var(--c-text);
}
.diagnostic__recap-list li::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--c-gold);
}

/* Amostras de progresso e número do passo na mesma linha. */
.diagnostic__meter {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-6);
}
.diagnostic__meter .diagnostic__progress { flex: 1; margin-bottom: 0; }

.diagnostic__nav {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-line);
}
/* A régua da navegação existe em todos os passos. Havia aqui uma excepção
   para os passos com lista: a lista regrada acabava num filete, e a régua logo
   a seguir era o segundo traço seguido. Com cartões não há filete nenhum a
   fechar a lista, portanto a excepção deixou de ter objecto. */
/* Botões dimensionados ao conteúdo, não esticados a meio ecrã cada um.
   «Voltar» à esquerda, avanço à direita, como numa ficha paginada. */
.diagnostic__nav .btn { min-width: 0; }
.diagnostic__nav .btn:only-child { margin-left: auto; }
@media (max-width: 480px) {
  .diagnostic__nav { gap: var(--s-2); }
  .diagnostic__nav .btn { padding-inline: var(--s-4); font-size: var(--fs-300); }
}
.diagnostic__success {
  display: none;
  text-align: center;
  padding: var(--s-7) var(--s-4);
}
.diagnostic__success[data-visible="true"] { display: block; }
/* A cartela outra vez, agora a fechar. É a mesma marca do topo do painel e do
   hero, e faz o agradecimento pertencer à ficha em vez de parecer um ecrã de
   sucesso genérico. */
.diagnostic__success-rail {
  display: flex;
  justify-content: center;
  gap: 3px;
  margin-bottom: var(--s-5);
}
.diagnostic__success-rail span {
  width: clamp(1.5rem, 6vw, 2.5rem);
  height: 8px;
}
.diagnostic__success-rail span:nth-child(1) { background: var(--c-red); }
.diagnostic__success-rail span:nth-child(2) { background: var(--c-terra); }
.diagnostic__success-rail span:nth-child(3) { background: var(--c-gold); }
.diagnostic__success-rail span:nth-child(4) { background: var(--c-gold-soft); }
.diagnostic__success-rail span:nth-child(5) { background: var(--c-text); }
.diagnostic__success h3 {
  font-size: clamp(2.25rem, 1.7rem + 2.4vw, 3.5rem);
  line-height: 1;
  margin-bottom: var(--s-4);
}
.diagnostic__success p {
  color: var(--c-text-muted);
  max-width: 38ch;
  margin: 0 auto var(--s-6);
}
/* Sem raio e com barra à esquerda, como as restantes marcas da ficha. */
.diagnostic__error {
  background: rgba(226, 106, 106, 0.08);
  border: 0;
  border-left: 2px solid var(--c-danger);
  color: var(--c-danger);
  padding: var(--s-3) var(--s-4);
  border-radius: 0;
  font-size: var(--fs-400);
  margin-top: var(--s-3);
  display: none;
}
.diagnostic__error[data-visible="true"] { display: block; }

/* ─── Footer ─────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--c-line);
  background: var(--c-bg-hero);
  padding-block: var(--s-8) var(--s-6);
}
.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-7);
  margin-bottom: var(--s-8);
}
@media (max-width: 768px) { .site-footer__grid { grid-template-columns: 1fr; gap: var(--s-6); } }
/* h3 e não h4: os títulos das colunas do rodapé vinham a seguir a um h2 sem
   nenhum h3 pelo meio, e o Lighthouse acusava ordem de headings inválida. */
.site-footer h3 {
  font-family: var(--ff-sans);
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
  margin-bottom: var(--s-4);
  font-weight: 500;
}
.site-footer a {
  color: var(--c-text);
  display: inline-block;
}
.site-footer a:hover { color: var(--c-gold); }
.site-footer__col p,
.site-footer__col a { line-height: 1.7; }
.site-footer__bottom {
  border-top: 1px solid var(--c-line);
  padding-top: var(--s-5);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  font-size: var(--fs-300);
  color: var(--c-text-dim);
}
.site-footer__social {
  display: flex;
  gap: var(--s-3);
}
.site-footer__social a {
  width: 40px;
  height: 40px;
  border: 1px solid var(--c-line-strong);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-text-muted);
  transition: color var(--d-fast) var(--ease-out), border-color var(--d-fast) var(--ease-out);
}
.site-footer__social a:hover { color: var(--c-gold); border-color: var(--c-gold); }
.site-footer__social svg { width: 18px; height: 18px; }

/* ─── 404 ────────────────────────────────────────────── */
.error-page {
  min-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.error-page__code {
  font-family: var(--ff-serif);
  font-size: clamp(6rem, 18vw, 12rem);
  color: var(--c-gold);
  line-height: 1;
}

/* ─── Página de Serviços ─────────────────────────────── */
/* Índice de topo. Amostras deitadas: filete nude antes de cada nome, o mesmo
   marcador dos bullets dos cards. */
.svc-index {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  list-style: none;
  padding: 0;
}
.svc-index a {
  position: relative;
  padding-left: var(--s-4);
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-muted);
  transition: color var(--d-fast) var(--ease-out);
}
.svc-index a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 1px;
  background: var(--c-gold);
}
.svc-index a:hover { color: var(--c-gold); }

.svc-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}
/* Cantos vivos e filete superior, como as fichas do formulário. Nada de
   cartões arredondados: é a mesma decisão de identidade. */
.svc {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--s-6) var(--s-7);
  padding-top: var(--s-6);
  border-top: 1px solid var(--c-line);
  scroll-margin-top: 96px;
}
@media (max-width: 860px) { .svc { grid-template-columns: 1fr; gap: var(--s-5); } }
.svc--feature { border-top-color: var(--c-gold-deep); }
.svc__title {
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.25rem);
  line-height: 1.15;
  margin-bottom: var(--s-2);
}
.svc__headline {
  font-family: var(--ff-sans);
  font-size: var(--fs-400);
  color: var(--c-gold);
  margin-bottom: var(--s-4);
}
.svc__intro p + p { margin-top: var(--s-3); }
.svc__meta {
  margin-top: var(--s-4);
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-text-dim);
}
/* Fotografia do serviço, no topo da coluna do passo a passo. Cantos vivos e
   filete, como o resto da página. */
.svc__media {
  margin: 0 0 var(--s-5);
}
.svc__media img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--c-line);
}
.svc__steps-title {
  font-size: var(--fs-300);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-gold);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-line);
}
/* Numeração 01, 02, ... pela mesma gramática dos passos do formulário. Aqui
   pode ser contador CSS: ao contrário do formulário, nada está em
   display:none, portanto o contador não salta números. */
.svc__steps {
  counter-reset: svcstep;
  list-style: none;
  padding: 0;
}
.svc__steps li {
  counter-increment: svcstep;
  display: flex;
  gap: var(--s-3);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-line);
  font-size: var(--fs-300);
  color: var(--c-text-muted);
}
.svc__steps li::before {
  content: counter(svcstep, decimal-leading-zero);
  flex-shrink: 0;
  font-family: var(--ff-serif);
  color: var(--c-gold);
}


/* ############ UTILITIES ############ */
/* ─── Screen reader only ─────────────────────────────── */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ─── Reveal on scroll ───────────────────────────────── */
[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 700ms var(--ease-luxe),
    transform 700ms var(--ease-luxe);
  will-change: opacity, transform;
}
[data-reveal][data-visible="true"] {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ─── Text helpers ───────────────────────────────────── */
.text-center { text-align: center; }
.text-muted { color: var(--c-text-muted); }
.text-dim { color: var(--c-text-dim); }
.text-gold { color: var(--c-gold); }

/* Script accent (Lovely May). Usar com moderação, apenas para toques de
   assinatura, verbo-chave em headings ou ornamento tipográfico. */
.script {
  font-family: var(--ff-script);
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0;
}

/* Lista dentro de texto corrido (páginas legais). O reset tira os marcadores a
   todas as listas, por serem quase sempre grelhas de cards; aqui são mesmo
   enumerações e precisam de marcador.
   Sem `display: grid` nem `flex`: um item de lista dentro desses contentores é
   blockificado e perde o marcador. O espaçamento faz-se por margem. */
.prose-list {
  padding-left: var(--s-5);
  list-style: disc;
  color: var(--c-text-muted);
}
.prose-list li + li { margin-top: var(--s-2); }
.prose-list li::marker { color: var(--c-gold); }

.max-prose { max-width: 60ch; }
.mx-auto { margin-inline: auto; }

/* ─── Spacing utilities ──────────────────────────────── */
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mt-8 { margin-top: var(--s-8); }

/* ─── Section header (eyebrow + h2 + lead) ───────────── */
.section-head {
  max-width: 56rem;
  text-align: center;
  margin-inline: auto;
  margin-bottom: var(--s-6);
}
.section-head--start { text-align: start; margin-inline: 0; }
.section-head h2 {
  margin-bottom: var(--s-4);
}
.section-head .lead {
  margin-inline: auto;
}
.section-head--start .lead { margin-inline: 0; }

/* ─── Hide on viewport ───────────────────────────────── */
@media (min-width: 700px) {
  .show-mobile { display: none !important; }
}
@media (max-width: 699px) {
  .show-desktop { display: none !important; }
}

/* ─── Print ──────────────────────────────────────────── */
@media print {
  .fab-whatsapp, .site-header__cta, .hero__ctas, .skip-link,
  .hero__grain { display: none !important; }
  body { background: white; color: black; }
  /* As animações de entrada usam animation-fill-mode: both. Se a impressão
     acontecer antes de correrem, os elementos sairiam a opacity 0. */
  .hero__swatch, .hero__eyebrow,
  .hero__line, .hero__sub, .hero__meta {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  /* Sem transform, que aqui é a rotação para a vertical. */
  .hero__imperative { animation: none !important; opacity: 1 !important; }
  .hero__write {
    animation: none !important;
    clip-path: none !important;
  }
}


