/* Wall Experts — hoja del sitio.
 *
 * Cero hex aquí dentro: todo color sale de tokens.css, que a su vez sale de
 * 02-brand. Si aparece un `#` fuera de un comentario, es un bug.
 *
 * Los valores estructurales están MEDIDOS del markup del 2026-08-03, no
 * estimados. Cada uno lleva su medida en el comentario.
 *
 * Mobile-first: toda media query es min-width.
 */

/* ---------- Manrope, autohospedada. Cero peticiones de red por fuentes ---------- */
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-latin-ext-var.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  margin: 0;
  background: var(--we-bg);
  color: var(--we-text);
  font-family: var(--we-font-sans);
  font-size: var(--we-text-base);
  line-height: var(--we-leading-loose);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; height: auto; }
h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: var(--we-primary); text-underline-offset: 3px; }
button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--we-primary);
  outline-offset: 2px;
  border-radius: var(--we-radius-sm);
}
.skip {
  position: absolute; left: 16px; top: -200px; z-index: 200;
  padding: 12px 24px; background: var(--we-navy); color: var(--we-white);
  border-radius: var(--we-radius-lg); font-weight: 700; text-decoration: none;
}
.skip:focus { top: 16px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------- Layout ----------
   El texto del markup arranca en el 7% del ancho. Con el contenedor a 86% y
   centrado, el margen sale justo ahí. */
.wrap { width: 86%; max-width: 1240px; margin-inline: auto; }

.section { padding-block: clamp(48px, 7vw, 96px); }
.section--alt { background: var(--we-mist); }

.sec-head { max-width: 60ch; margin-bottom: clamp(28px, 4vw, 48px); }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head h2 {
  font-size: clamp(1.7rem, 3.4vw, 2.75rem);
  font-weight: 800; line-height: 1.15; letter-spacing: -0.03em;
  color: var(--we-heading); text-wrap: balance;
}
.sec-head p { margin-top: 14px; color: var(--we-text-muted); line-height: 1.6; }

/* Eyebrow. Medido: #6B727A, versalitas, sobre el titular. */
.eyebrow {
  font-size: .8rem; font-weight: 700; letter-spacing: var(--we-tracking-caps);
  text-transform: uppercase; color: var(--we-slate); margin-bottom: 12px;
}

/* ---------- Cabecera ----------
   Medida: 9.5% de alto en un markup de 1024 → 97px. Se fija en 84 para que en
   pantalla apaisada no coma tanto del héroe (ver D-05 en SPECS: el markup es
   cuadrado, sus verticales no se trasladan tal cual). */
.header {
  position: sticky; top: 0; z-index: 60;
  background: var(--we-paper);
  border-bottom: 1px solid var(--we-line-soft);
}
.nav { display: flex; align-items: center; gap: 24px; min-height: 84px; }
.nav__logo { flex: none; }
.nav__logo img { height: 42px; width: auto; }
.nav__links { display: none; margin-left: auto; gap: clamp(14px, 1.8vw, 28px); }
@media (min-width: 980px) { .nav__links { display: flex; align-items: center; } }
.nav__links a {
  color: var(--we-ink-nav); text-decoration: none; font-weight: 600;
  font-size: .96rem; white-space: nowrap;
}
.nav__links a:hover { color: var(--we-navy); }
.nav__links a[aria-current="page"] { color: var(--we-navy); font-weight: 700; }

.nav__tel {
  display: none; align-items: center; gap: 8px;
  color: var(--we-ink-nav); text-decoration: none; font-weight: 700; white-space: nowrap;
}
@media (min-width: 1120px) { .nav__tel { display: inline-flex; } }
.nav__tel svg { width: 18px; height: 18px; flex: none; }

.nav__cta { margin-left: auto; }
@media (min-width: 980px) { .nav__cta { margin-left: 0; } }

/* Menú de móvil sin JS: checkbox hermano. Funciona con JS deshabilitado, y así
   no hay script que la CSP tenga que autorizar. */
.menu-state { position: absolute; opacity: 0; pointer-events: none; }
.menu-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none; cursor: pointer;
  border: 1px solid var(--we-line); border-radius: var(--we-radius-md);
  color: var(--we-ink-nav); background: var(--we-white);
}
@media (min-width: 980px) { .menu-btn { display: none; } }
.drawer { display: none; padding-bottom: 20px; }
.menu-state:checked ~ .wrap .drawer { display: block; }
.drawer ul { display: grid; gap: 4px; }
.drawer a {
  display: block; padding: 12px 4px; color: var(--we-ink-nav);
  text-decoration: none; font-weight: 600;
  border-bottom: 1px solid var(--we-line-soft);
}

/* ---------- Botones ----------
   Relleno simétrico por defecto. El markup dibuja los dos del héroe como
   pastillas sin icono, así que no hay badge que compensar. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 48px; padding: 6px 26px;
  border: 1px solid transparent; border-radius: var(--we-radius-pill);
  font-size: var(--we-text-base); font-weight: 700;
  text-decoration: none; cursor: pointer;
  transition: background-color .15s, color .15s, border-color .15s;
}
/* D-01. El cian del markup con texto blanco da 2.15:1 contra un mínimo de 4.5,
   así que el botón principal iría ilegible. --we-cyan-deep conserva matiz y
   saturación y sube a 4.86:1. */
.btn--primary { background: var(--we-primary); color: var(--we-white); }
.btn--primary:hover { background: var(--we-primary-hover); }
/* D-02. El borde del markup (#E2E3E5) da 1.28:1 sobre blanco: el control no se
   ve. --we-line da 3.18:1, que es el mínimo de componente de interfaz. */
.btn--ghost {
  background: var(--we-white); color: var(--we-navy);
  border-color: var(--we-border);
}
.btn--ghost:hover { background: var(--we-mist); }
.btn--lg { min-height: 54px; padding-inline: 32px; font-size: 1.05rem; }

/* ---------- Héroe ----------
   El markup pone la foto a sangre con el texto encima a la izquierda. La
   relación NO se copia del markup: es cuadrado (D-05). Se fija por vw. */
.hero { position: relative; isolation: isolate; overflow: hidden; background: var(--we-mist); }
.hero__bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  /* 40% y no 50%: la foto viene en 1.75:1 y el héroe pide 2.36, así que `cover`
     recorta 26% del alto. El pintor va del 14% al 81% de la fuente; con 40% se
     ve del 10% al 84% y entra entero con aire por los dos lados. A partir del
     55% le corta la cabeza. Medido, no estimado. */
  object-position: 50% 40%;
}
/* Velo. `to right` y no un ángulo: con ángulo la línea del degradado mide más
   que la caja, las paradas caen fuera y nunca llega a transparente. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to right,
    rgba(245,246,248,.96) 0%,  rgba(245,246,248,.92) 30%,
    rgba(245,246,248,.70) 46%, rgba(245,246,248,.20) 62%,
    rgba(245,246,248,0) 76%);
}
.hero__inner {
  position: relative;
  min-height: clamp(440px, 42vw, 620px);
  display: flex; align-items: center;
  padding-block: clamp(40px, 5vw, 72px);
}
.hero__text { max-width: min(48%, 620px); }
@media (max-width: 899px) {
  .hero__text { max-width: 100%; }
  .hero::before { background: rgba(245,246,248,.94); }
}
.hero h1 {
  font-size: clamp(2.1rem, 5vw, 4rem);
  font-weight: 800; line-height: 1.06; letter-spacing: -0.035em;
  color: var(--we-heading); text-wrap: balance;
}
.hero__lede {
  margin-top: 18px; font-size: clamp(1rem, 1.25vw, 1.2rem);
  line-height: 1.6; color: var(--we-ink); max-width: 42ch;
}
.hero__cta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 28px; }

/* ---------- Tira de ventajas ----------
   Los tres iconos bajo el héroe, medidos del markup: círculo #F2F3F5, trazo
   #104384, etiqueta #294664. */
.perks { padding-block: clamp(40px, 5vw, 72px); }
.perks ul { display: grid; gap: 32px; text-align: center; }
@media (min-width: 760px) { .perks ul { grid-template-columns: repeat(3, 1fr); } }
.perks li { display: grid; justify-items: center; gap: 14px; }
.perk__ico {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--we-mist); color: var(--we-accent);
  display: flex; align-items: center; justify-content: center;
}
.perk__ico svg { width: 28px; height: 28px; }
.perks b { font-size: 1.05rem; font-weight: 700; color: var(--we-navy-ink); }
/* `:not(.perk__ico)` — sin ella esta regla (0,1,1) le gana a `.perk__ico`
   (0,1,0) y le impone `display: block`, con lo que su `align-items` y
   `justify-content` dejan de aplicar y el glifo se va a la esquina superior
   izquierda del círculo: 18 px de desviación en los dos ejes.

   Es el tercer caso del mismo choque en este proyecto y sus hermanos —`.footer a`
   contra `.btn--on-dark` en Home Refresh, `.sa-label > span` contra `.sa-ico` en
   SparkBin—. El patrón es siempre el mismo: una regla escrita para el texto de
   un bloque alcanza a un hijo que es un componente. */
.perks span:not(.perk__ico) { display: block; font-size: .95rem; color: var(--we-text-muted); max-width: 34ch; }

/* ---------- Tarjetas ---------- */
.cards { display: grid; gap: 24px; }
@media (min-width: 720px)  { .cards--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .cards--3 { grid-template-columns: repeat(3, 1fr); } }
.card {
  background: var(--we-white); border: 1px solid var(--we-line-soft);
  border-radius: var(--we-radius-xl); padding: clamp(20px, 2.4vw, 30px);
  display: grid; gap: 10px; align-content: start;
}
.section--alt .card { background: var(--we-white); }
.card__ico {
  width: 48px; height: 48px; border-radius: var(--we-radius-md);
  background: var(--we-mist); color: var(--we-accent);
  display: flex; align-items: center; justify-content: center; margin-bottom: 6px;
}
.card__ico svg { width: 24px; height: 24px; }
.card h3 { font-size: 1.15rem; font-weight: 700; color: var(--we-heading); line-height: 1.35; }
.card p { color: var(--we-text-muted); line-height: 1.6; font-size: .97rem; }

/* ---------- Lista con marca ---------- */
.checks { display: grid; gap: 12px; }
.checks li { display: flex; gap: 12px; align-items: flex-start; line-height: 1.55; }
.checks svg { width: 20px; height: 20px; flex: none; margin-top: 3px; color: var(--we-accent); }

/* ---------- Banda de cierre ---------- */
.band {
  background: var(--we-navy); color: var(--we-white);
  padding-block: clamp(44px, 6vw, 84px);
}
.band h2 { color: var(--we-white); }
.band p { color: rgba(255,255,255,.82); }
.band .btn--primary { background: var(--we-white); color: var(--we-navy); }
.band .btn--primary:hover { background: var(--we-mist); }

/* ---------- Marcador de imagen ----------
   Mientras no exista la foto, el hueco se ve. Es lo que evita publicar
   descuidos: un marcador rojo se nota, una imagen ausente no. */
.imgph {
  display: grid; place-items: center; min-height: 180px; padding: 20px;
  border: 2px dashed var(--we-danger); border-radius: var(--we-radius-lg);
  color: var(--we-danger); font-size: .85rem; font-weight: 600; text-align: center;
}

/* ---------- Pie ---------- */
.footer { background: var(--we-navy); color: var(--we-white); padding-block: 56px 32px; }
.footer__cols { display: grid; gap: 32px; }
@media (min-width: 760px) { .footer__cols { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer img { height: 44px; width: auto; }
.footer h2 { font-size: .85rem; text-transform: uppercase;
  letter-spacing: var(--we-tracking-caps); color: rgba(255,255,255,.72); margin-bottom: 14px; }
.footer ul { display: grid; gap: 8px; }
/* `:not(.btn)` — sin ella este selector (0,1,1) le gana a la clase del botón
   (0,1,0) y pinta texto blanco sobre pastilla blanca. Pasó en Home Refresh y
   estuvo invisible en 19 páginas. */
.footer a:not(.btn) { color: rgba(255,255,255,.82); text-decoration: none; }
.footer a:not(.btn):hover { color: var(--we-white); text-decoration: underline; }
.footer__legal {
  margin-top: 36px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.16);
  display: grid; gap: 6px; font-size: .85rem; color: rgba(255,255,255,.72);
}

/* La cabecera es fija: sin esto, un ancla deja el titular detrás del nav. */
:target { scroll-margin-top: 100px; }

/* ---------- Utilidades ----------
   Existen como clase y no como `style=` porque la CSP del sitio llevará
   `style-src 'self'` sin `unsafe-inline`, igual que SparkBin. Un atributo
   `style` se bloquea en producción sin dar ningún error visible. */
.u-center { text-align: center; }
.u-measure { max-width: 62ch; }
.footer__tag { margin-top: 16px; color: rgba(255,255,255,.82); }
.u-mt { margin-top: 32px; }
.u-mt-lg { margin-top: 48px; }

/* El sprite de iconos. Va por clase y no por `style="position:absolute"`: con
   `style-src 'self'` el atributo se bloquea, el SVG vuelve al flujo y empuja
   toda la página hacia abajo sin dar ningún error. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* El titular de página usa el mismo tamaño que .sec-head h2: en estas páginas
   el h1 ES la cabecera de la primera sección, y jerarquía semántica y escala
   tipográfica no tienen por qué coincidir. */
.sec-head h1 {
  font-size: clamp(1.9rem, 3.8vw, 3rem);
  font-weight: 800; line-height: 1.12; letter-spacing: -0.03em;
  color: var(--we-heading); text-wrap: balance;
}

/* Las tarjetas de la sección que encabeza el h1 usan h2 por jerarquía —el h3
   saltaba un nivel—, pero su tamaño es el de una tarjeta, no el de un titular
   de sección. Semántica y escala no tienen por qué coincidir. */
.card h2 { font-size: 1.15rem; font-weight: 700; color: var(--we-heading); line-height: 1.35; }

/* Logo del nav: mark + nombre en texto. Ver el comentario del partial. */
.nav__logo { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.nav__logo img { height: 40px; width: auto; flex: none; }
.nav__wm {
  font-size: 1.28rem; font-weight: 800; letter-spacing: -0.02em;
  color: var(--we-navy); white-space: nowrap;
}

/* ---------- Formulario ---------- */
.form { display: grid; gap: var(--we-space-4); }
@media (min-width: 760px) { .form { grid-template-columns: 1fr 1fr; } }
/* `align-self: start` para que un campo con pista debajo no estire al de al
   lado: sin esto los dos inputs de una fila dejan de coincidir. */
.form > .field, .form > p { align-self: start; }
.field { display: grid; gap: var(--we-space-2); }
.field--wide { grid-column: 1 / -1; }
.field label { font-size: var(--we-text-sm); font-weight: 600; color: var(--we-heading); }
.field .req { color: var(--we-danger); }
.field input, .field select, .field textarea {
  min-height: 48px; padding: 10px 14px;
  border: 1px solid var(--we-border); border-radius: var(--we-radius-md);
  background: var(--we-white); color: var(--we-text);
  font: inherit; width: 100%;
}
.field textarea { min-height: 110px; resize: vertical; }
.field .hint { font-size: var(--we-text-xs); color: var(--we-text-muted); }
/* El error aparece solo cuando el usuario ya interactuó: `:user-invalid` y no
   `:invalid`, que marcaría en rojo un formulario recién abierto. */
.field .error { display: none; font-size: var(--we-text-sm); font-weight: 600; color: var(--we-danger); }
.field input:user-invalid ~ .error,
.field select:user-invalid ~ .error { display: block; }
.field input:user-invalid, .field select:user-invalid { border-color: var(--we-danger); }

/* Trampa antibot. Fuera de pantalla y no `display:none` ni `visibility:hidden`:
   los bots que rellenan formularios saltan esas dos propiedades justo porque
   delatan la trampa. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; margin: 0; }

.form__estado {
  grid-column: 1 / -1; margin: 0;
  padding: var(--we-space-4) var(--we-space-5);
  border-radius: var(--we-radius-lg); font-weight: 600; line-height: 1.5;
}
.form__estado[hidden] { display: none; }
.form__estado--ok  { background: #E8F5EE; color: #14603A; border: 1px solid #A8DCC0; }
.form__estado--mal { background: #FDECEA; color: #8E1D17; border: 1px solid #F3B7B1; }
.field--fallo input, .field--fallo select, .field--fallo textarea { border-color: var(--we-danger); }
.form button[disabled] { opacity: .6; cursor: progress; }
