/* ============================================================
   DSAYN Showroom: escaparate público
   Paleta canónica DSAYN. Antracita = identidad; azul acción = CTA;
   gradiente data (#0066ff→#00d2ff) SOLO en narrativa de datos.
   ============================================================ */

:root {
  /* Antracita: #111827 es el ÚNICO fondo oscuro de marca (13/07/2026). El #1F2937 se queda
     para texto, logo y hover: como fondo, junto al pie daba dos navys casi iguales (1,21:1). */
  --brand-anthracite:      #1F2937;
  --brand-anthracite-deep: #111827;
  --brand-anthracite-soft: #374151;

  /* Azul acción: CTAs, links, focus */
  --action-blue:       #2563eb;
  --action-blue-hover: #1d4fd8;

  /* Azul/cyan data: SOLO narrativa de datos */
  --data-blue:    #0066ff;
  --data-cyan:    #00d2ff;
  --data-gradient:      linear-gradient(135deg, var(--data-blue) 0%, var(--data-cyan) 100%);
  --data-gradient-dark: linear-gradient(135deg, #001a4d 0%, #0044cc 100%);

  /* Sobre fondo oscuro (brand-spec: gate de contraste AA calculado) */
  --data-blue-light:  #4d94ff;   /* 5,91:1 sobre navy; el #0066ff da 3,67:1 y suspende a 14 px */
  --gray-on-navy:     #9CA3AF;   /* 6,99:1 sobre navy; el #6e6e73 da 2,72:1 y suspende */

  /* Neutros */
  --color-text:       #1d1d1f;
  --color-text-soft:  #424245;
  --color-muted:      #6e6e73;
  --color-line:       #d2d2d7;
  --color-line-soft:  #e8e8ed;
  --color-bg:         #ffffff;
  --color-bg-soft:    #f6f8fb;   /* cuerpo claro canónico (brand-spec). El #fbfbfd anterior
                                    se diferenciaba del blanco en un 1 %: las tarjetas flotaban */
  --color-bg-cream:   #eef1f6;   /* chips: un escalón por debajo del cuerpo, para que se lean */

  /* Tipografía */
  --font-display: "Inter", 'Inter Fallback', -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, sans-serif;
  --font-body:    "Inter", 'Inter Fallback', -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;

  /* Escala (brand-spec §Tamaños): 12 px = suelo absoluto (legal), 13 = eyebrow/chip,
     15 = rótulo y secundario, 16 = suelo de prosa. Nada por debajo de 12 px. */
  --fs-legal: 0.8125rem;  /* 13 px: legal, fuentes, © */
  --fs-xs:    0.8125rem;  /* 13 px: eyebrow, chips, meta */
  --fs-label: 0.9375rem;  /* 15 px: rótulos de sección/tarjeta/campo */
  --fs-sm:    0.9375rem;  /* 15 px: secundario: listas, notas */
  --fs-base:  1.0625rem;  /* 17 px: prosa (suelo: 16 px) */
  --fs-lg:    1.5rem;
  --fs-2xl:   clamp(2rem, 1.5rem + 2.5vw, 3.25rem);

  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 28px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 12px 32px rgba(15, 23, 42, 0.10);
  --shadow-lg: 0 32px 64px rgba(15, 23, 42, 0.12);
  --shadow-blue: 0 24px 48px rgba(37, 99, 235, 0.22);

  /* Contenedor único (brand-spec): mismo ancho Y mismo padding en toda pieza DSAYN.
     Fluido: crece con la pantalla y se planta en 1.560 px. */
  --container: min(94vw, 1560px);
  --transition: 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ============= Reset ============= */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  overflow-wrap: break-word;
}
img, svg { display: block; max-width: 100%; height: auto; }
a { color: var(--action-blue); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--action-blue-hover); }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; }
:focus-visible { outline: 3px solid var(--action-blue); outline-offset: 3px; border-radius: 4px; }

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 20px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--action-blue); color: #fff; padding: var(--space-3) var(--space-5);
  border-radius: 0 0 var(--radius-sm) 0; font-weight: 600;
}
.skip-link:focus { left: 0; }

/* ============= Botones =============
   Escala DSAYN (brand-spec): CTA maestro del cierre = píldora con gradiente data,
   fluido clamp(16px,1.1vw,17px), UNO por pieza. El resto de botones: 17 px, sólido (primario/tarjeta) o
   con borde (secundario). El gradiente NO se repite: si hay dos, ninguno manda. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-base);
  padding: 0.85em 1.6em; border-radius: var(--radius-pill); border: 1.5px solid transparent;
  cursor: pointer; transition: transform var(--transition), background var(--transition), box-shadow var(--transition), color var(--transition);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn-primary { background: var(--action-blue); color: #fff; box-shadow: var(--shadow-blue); }
.btn-primary:hover { background: var(--action-blue-hover); color: #fff; }
.btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,0.35); }
.btn-ghost:hover { background: rgba(255,255,255,0.1); color: #fff; }
.btn-dark { background: var(--brand-anthracite-deep); color: #fff; }
.btn-dark:hover { background: var(--brand-anthracite); color: #fff; }   /* el hover aclara: si no, no se nota */
.btn-outline { background: transparent; color: var(--brand-anthracite); border-color: var(--color-line); }
.btn-outline:hover { border-color: var(--action-blue); color: var(--action-blue); }

/* ============= Hero ============= */
.hero {
  position: relative; color: #fff; overflow: hidden;
  background: radial-gradient(120% 120% at 80% 0%, #24324a 0%, var(--brand-anthracite-deep) 45%, var(--brand-anthracite-deep) 100%);
  padding: 52px 0 40px;   /* geometría canónica del hero */
}
/* Cabecera armonizada con DSAYN Calculadora: brandlink + acento + etiqueta */
.hero-brand { display: block; margin-bottom: 0; }   /* el logo sale del flujo: si no, estira la fila del wordmark */
.brandlink { color: inherit; text-decoration: none; cursor: pointer; }
.brandlink:hover { opacity: 0.9; }
.hero-wordmark { font-family: var(--font-display); font-size: 22px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.2; color: #fff; }
.hero-logo { position: absolute; top: 52px; right: max(20px, calc(50vw - (var(--container) / 2) + 20px)); height: 30px; width: auto; opacity: 0.95; z-index: 3; }
.hero-accent { height: 4px; width: 72px; background: var(--data-gradient); border-radius: 2px; margin: 20px 0 24px; }
.hero-label { font-size: 13px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--data-cyan); line-height: 1.2; margin-bottom: 14px; }
.hero h1 .accent { background: var(--data-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.hero-claim a { color: inherit; text-decoration: none; }
.hero-claim a:hover { text-decoration: underline; text-underline-offset: 3px; }
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(60% 60% at 15% 100%, rgba(0,102,255,0.22) 0%, transparent 60%);
}
.hero .container { position: relative; z-index: 2; }
.hero h1 {
  /* Ocupa el ancho del contenedor: sin 'balance' (rompía la línea antes de tiempo). */
  font-size: clamp(30px, 3.4vw, 46px); letter-spacing: -0.02em; max-width: 100%; margin-bottom: var(--space-4);   /* escala canónica del titular */
  background: linear-gradient(180deg, #fff 60%, #c7d2e6 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.hero-claim { font-style: italic; color: var(--data-cyan); font-weight: 600; }
/* Sin tope en ch: la frase usa el ancho real del contenedor (hasta el logo). */
.hero-sub { font-weight: 400; font-size: 17px; color: #c7d2e6; max-width: 100%; margin-bottom: var(--space-6); }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }

/* ============= Secciones ============= */
.section { padding: clamp(3.5rem, 6vw, 6.5rem) 0; }
.section-soft { background: var(--color-bg-soft); }
.section-dark { background: var(--brand-anthracite-deep); color: #fff; }
.section-head { max-width: 100%; margin-bottom: var(--space-8); }
.eyebrow {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--action-blue); margin-bottom: var(--space-3);
}
.section-dark .eyebrow { color: var(--data-cyan); }
.section-head h2 { font-size: var(--fs-2xl); margin-bottom: var(--space-4); }
.section-head p { font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem); color: var(--color-muted); max-width: 100%; }
/* Remate del hero: la promesa que cala, en blanco pleno. */
.hero-sub strong { color: #fff; font-weight: 700; }
.section-dark .section-head p { color: #b9c4d6; }

/* ============= Apps grid ============= */
.apps-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 2vw, 2.5rem); }
/* 780, no 720: por debajo de ~780 px la tarjeta a tres columnas deja la cabecera
   sin altura para el rótulo de tres líneas + icono (16/9 recorta). Una columna. */
@media (max-width: 780px) { .apps-grid { grid-template-columns: 1fr; } }
.app-card {
  position: relative; cursor: pointer;
  /* La cabecera visual se dimensiona con el ancho REAL de la tarjeta (cqw), no con el
     de la ventana: en iPad, con tres columnas, la tarjeta se estrecha, el rótulo pasa
     a 2-3 líneas y un icono de tamaño fijo se comía el aire (16/9 + overflow:hidden). */
  container-type: inline-size;
  display: flex; flex-direction: column; background: var(--color-bg); border: 1px solid var(--color-line-soft);
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.app-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-lg); border-color: var(--color-line); }

/* Toda la tarjeta clicable, incluida la zona de color.
   ANTES: un ::after del botón estirado a toda la tarjeta. Fallaba en cuanto el
   ratón tocaba el botón, porque `.btn:hover` lleva `transform` y un elemento con
   transform se convierte en el bloque contenedor de sus descendientes absolutos:
   la capa de clic se encogía al tamaño del botón y la tarjeta dejaba de abrirse
   hasta recargar. Ahora es un ANCLA REAL (.app-stretch), hija de .app-card, a la
   que ningún hover puede reducirle el área. */
.app-stretch { position: absolute; inset: 0; z-index: 3; }
.app-card .app-card-visual { position: relative; z-index: 0; }
.app-card .app-card-body { position: static; z-index: auto; }
.app-card .app-card-cta .btn { position: relative; z-index: 4; }   /* conserva su foco y su hover */

/* Entrada con más movimiento y escalonada (sobre la base .reveal-up) */
.app-card.reveal-up {
  transform: translateY(40px) scale(0.95);
  transition: opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1), transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.app-card:hover .app-card-visual .glyph { transform: scale(1.08) rotate(-4deg); transition: transform var(--transition); }
.app-card-visual {
  position: relative; aspect-ratio: 16 / 9; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  /* Aire e icono proporcionales a la tarjeta: nunca se tocan, ni a 3 columnas en iPad.
     PRIMERO el valor fijo, DESPUÉS el fluido: un navegador sin container queries descarta
     la declaración con `cqw` entera (unidad desconocida = declaración inválida) y se queda
     con la de arriba. Sin esa primera línea caía al valor por defecto (gap 0, padding 0). */
  gap: 1.125rem;
  gap: clamp(0.875rem, 4.5cqw, 1.375rem);
  padding: 0.75rem;
  padding: clamp(0.5rem, 3.5cqw, 1rem);
  background: var(--data-gradient-dark, linear-gradient(135deg, #001a4d 0%, #0044cc 100%));
  color: #fff; overflow: hidden;
}
.app-card-visual .glyph {
  /* 3,4 rem en tarjeta ancha; encoge con ella (12 cqw) y nunca baja de 2 rem.
     El fijo de 2,6 rem es el respaldo para el navegador sin container queries: sin él, la
     declaración con `cqw` se descartaba y el pictograma heredaba la prosa del cuerpo (17 px),
     que es el «no escala» que vio José. 2,6 rem cabe en la tarjeta más estrecha (~300 px). */
  font-size: 2.6rem;
  font-size: clamp(2rem, 12cqw, 3.4rem);
  line-height: 1;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,0.35));
}
.app-card-visual .tag {
  /* En columna, NO absoluta: con la tarjeta estrecha (iPad) el rótulo ocupa tres líneas y,
     flotando, se montaba encima del icono. Ahora el icono baja y nunca se solapan. */
  max-width: 100%; text-align: center;
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.25);
  border-radius: var(--radius-pill); padding: 0.3em 0.9em; backdrop-filter: blur(4px);
}
.app-card-body { display: flex; flex-direction: column; flex: 1; padding: var(--space-6); }
.app-card-body h3 { font-size: var(--fs-lg); margin-bottom: var(--space-3); }
/* Prosa: nunca por debajo de 16 px (aquí 17, base del cuerpo). */
.app-problem { color: var(--color-text-soft); font-size: var(--fs-base); line-height: 1.6; margin-bottom: var(--space-5); }
.app-meta { margin-bottom: var(--space-5); }
/* Rótulo de tarjeta: organiza la lectura → 15 px, no letra pequeña. */
.app-meta dt {
  font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--color-muted); margin-bottom: var(--space-2);
}
.app-tech { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.app-tech span {
  font-size: var(--fs-xs); font-weight: 500; color: var(--brand-anthracite-soft);
  background: var(--color-bg-cream); border: 1px solid var(--color-line-soft);
  border-radius: var(--radius-sm); padding: 0.25em 0.7em;
}
.app-made {
  display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--fs-xs); font-weight: 600;
  color: var(--action-blue); margin-bottom: var(--space-5);
}
.app-made::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--data-cyan); box-shadow: 0 0 0 3px rgba(0,210,255,0.2); }
.app-card-cta { margin-top: auto; }
.app-card-cta .btn { width: 100%; }

/* Acentos de color por app en la cabecera visual */
.app-card--meteo .app-card-visual { background: linear-gradient(135deg, #0a3d91 0%, #00a6d6 100%); }
.app-card--calc  .app-card-visual { background: linear-gradient(135deg, #063a2f 0%, #0e9e6e 100%); }
.app-card--tesla .app-card-visual { background: linear-gradient(135deg, #3a0d0d 0%, #b3261e 100%); }

/* ============= Brochure (destacado) ============= */
.brochure-feature {
  position: relative; cursor: pointer;
  display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
/* Todo el bloque del brochure clicable (stretched link → descarga del PDF) */
/* Enlace-overlay real: cubre todo el bloque (la imagen lleva transform y crea
   su propio contexto de apilado, por eso el ::after no bastaba). El botón queda
   por encima (z-index mayor) para conservar su hover y foco propios. */
.brochure-stretch { position: absolute; inset: 0; z-index: 1; }
.brochure-copy .btn { position: relative; z-index: 2; }
/* Halo: una hoja blanca sobre antracita satura la vista porque el salto de
   luminancia es de golpe (17,7:1 de borde). El halo interpola el escalón, así que
   el ojo llega al blanco por una rampa. Va DETRÁS de la imagen (z-index -1) para
   no tapar el enlace estirado del bloque. */
.brochure-preview { position: relative; display: flex; justify-content: center; isolation: isolate; }
.brochure-preview::before {
  content: ""; position: absolute; z-index: -1;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(165%, 900px); aspect-ratio: 1 / 1.2;
  background: radial-gradient(closest-side,
    rgba(255,255,255,0.42) 0%,
    rgba(173,200,255,0.22) 55%,
    rgba(255,255,255,0) 80%);
  filter: blur(36px); pointer-events: none;
}
.brochure-preview img {
  width: 100%; max-width: clamp(300px, 26vw, 460px); border-radius: var(--radius-sm);
  /* El resplandor tiene que salir POR FUERA del papel: el halo del ::before queda
     tapado por la propia hoja y no se ve. Estas tres sombras son el halo real:
     filo blanco (1 px), resplandor cercano, resplandor azulado abierto, y la
     sombra oscura que despega la hoja del fondo. */
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.26),
    0 0 22px rgba(255,255,255,0.42),
    0 0 60px rgba(255,255,255,0.24),
    0 0 110px rgba(140,180,255,0.28),
    0 26px 60px rgba(0,0,0,0.50);
  transform: rotate(-2deg); transition: transform var(--transition);
}
.brochure-feature:hover .brochure-preview img { transform: rotate(0) translateY(-4px); }
.brochure-copy h2 { font-size: var(--fs-2xl); margin-bottom: var(--space-4); }
.brochure-copy p { font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem); color: var(--color-muted); margin-bottom: var(--space-6); }
/* El brochure vive en bloque oscuro: el gris medio ahí suspende (2,72:1). */
.section-dark .brochure-copy p { color: #b9c4d6; }

/* ============= Formulario / CTA (sobre cuerpo claro) ============= */
.cta-wrap { display: grid; grid-template-columns: 1fr 1.1fr; gap: var(--space-8); align-items: start; }
.cta-copy h2 { font-size: var(--fs-2xl); margin-bottom: var(--space-4); }
.cta-copy p { color: var(--color-muted); font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem); margin-bottom: var(--space-5); }
/* Vías de contacto: tarjetas, no texto suelto. Se tocan, luego se ven. */
.cta-ways { list-style: none; display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-6); }
.cta-ways li {
  display: flex; gap: var(--space-4); align-items: center; font-size: var(--fs-base);
  background: var(--color-bg); border: 1px solid var(--color-line-soft);
  border-radius: var(--radius-md); padding: 0.9rem 1.1rem; box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.cta-ways li:hover { transform: translateX(3px); box-shadow: var(--shadow-md); border-color: var(--color-line); }
/* Icono en cuadro con el gradiente data: el mismo lenguaje visual que el resto de la pieza. */
.cta-ways .ico {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: var(--radius-sm);
  /* Gradiente OSCURO: el blanco sobre el cian claro da 1,80:1 y suspende hasta como icono. */
  background: var(--data-gradient-dark); color: #fff;
}
.cta-ways .ico svg { width: 21px; height: 21px; }
.cta-ways .w { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cta-ways .k {
  color: var(--color-muted); font-weight: 700; font-size: var(--fs-xs);
  letter-spacing: 0.06em; text-transform: uppercase;
}
.cta-ways a { color: var(--brand-anthracite); font-weight: 600; overflow-wrap: anywhere; }
.cta-ways a:hover { color: var(--action-blue); }
.emph-no { color: #c1121f; font-weight: 800; }   /* rojo que aguanta AA sobre claro; el #ff6b6b daba 2,68:1 */

/* El formulario es la acción de la página: tiene cuerpo, borde y una franja de
   gradiente data arriba. Sobre el cuerpo claro (#f6f8fb) el blanco ya se despega. */
.contact-form {
  position: relative; overflow: hidden;
  background: var(--color-bg); border: 1px solid var(--color-line-soft); border-radius: var(--radius-lg);
  padding: clamp(1.75rem, 3vw, 2.75rem); box-shadow: var(--shadow-lg);
}
.contact-form::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--data-gradient);
}
.field { margin-bottom: var(--space-5); }
.field label { display: block; font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--brand-anthracite-soft); margin-bottom: var(--space-2); }
.field input, .field select, .field textarea {
  width: 100%; font-family: var(--font-body); font-size: var(--fs-base); color: var(--color-text);
  background: var(--color-bg-soft); border: 1.5px solid var(--color-line); border-radius: var(--radius-sm);
  padding: 0.75em 0.9em; transition: border-color var(--transition), background var(--transition);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--action-blue); background: #fff; outline: none;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);   /* el foco se ve, no se adivina */
}
.field input::placeholder, .field textarea::placeholder { color: var(--color-muted); }   /* 4,77:1 sobre el campo; el #8b8b90 daba 3,19:1 */
.field textarea { min-height: 120px; resize: vertical; }
.field-check { display: flex; gap: var(--space-3); align-items: flex-start; }
.field-check input { width: auto; margin-top: 4px; }
/* Consentimiento y notas: se leen, luego son secundario (15 px), no letra pequeña. */
.field-check label { text-transform: none; letter-spacing: normal; font-weight: 400; color: var(--color-muted); font-size: var(--fs-sm); line-height: 1.5; margin-bottom: 0; }
.form-note { font-size: var(--fs-sm); color: var(--color-muted); margin-top: var(--space-4); }

/* ============= Bloque de cierre canónico (brand-spec) =============
   Claim en gradiente data · subclaim hueso · CTA en botón · marca · legal.
   Mismo bloque en showroom, Meteo, Simulador y Eléctrico: si no, parece que
   cada pieza la hizo un equipo distinto. Las 4 columnas quedan solo para la
   home y servicios de dsayn.com, donde hay sitio que navegar. */
.site-footer { background: var(--color-bg-soft); padding-block: var(--space-7) var(--space-8); }
.closing {
  background: var(--brand-anthracite-deep); border-radius: var(--radius-lg);
  /* El legal cierra la tarjeta: menos aire abajo que arriba. */
  padding: clamp(16px, 2vw, 24px) clamp(1.25rem, 4vw, 3rem) 14px; text-align: center;
}
.closing-claim {
  font-family: var(--font-display); font-style: italic; font-weight: 700;
  font-size: clamp(22px, 2.2vw, 34px); line-height: 1.3;
  margin-bottom: var(--space-4);
  background: var(--data-gradient); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.closing-sub { color: #fff; font-size: 17px; line-height: 1.6; max-width: min(88%, 820px); margin: 14px auto 22px; }
.closing-cta {
  display: inline-flex; align-items: center; gap: var(--space-2);
  background: var(--data-gradient); color: #fff; font-family: var(--font-display); font-weight: 700;
  font-size: clamp(16px, 1.1vw, 17px); padding: clamp(11px, 0.9vw, 13px) clamp(26px, 2.3vw, 34px); border-radius: var(--radius-pill); box-shadow: var(--shadow-blue);
  transition: transform var(--transition);
}
.closing-cta:hover { transform: translateY(-2px); color: #fff; }
/* Línea de marca, idéntica en todas las piezas (sobre navy). */
.fbrand { font-size: 14px; color: #fff; margin-top: 24px; }
.fbrand .fb-name { color: var(--data-blue-light); }   /* 5,91:1 (AA); el #0066ff a 14 px suspende */
.fbrand .fb-mail { color: var(--gray-on-navy); }
.fbrand a { color: var(--data-cyan); }
/* Legal: SIEMPRE al final y precedido de línea separadora (brand-spec, bloque 5).
   Sobre navy va gray-on-navy: el gray-medium (#6e6e73) da 2,72:1 y suspende. */
.closing-legal {
  margin-top: 18px; padding-top: 12px; padding-bottom: 2px;
  border-top: 1px solid rgba(255,255,255,0.12);
  font-size: var(--fs-legal); line-height: 1.5; color: var(--gray-on-navy);
}
.closing-legal a { color: var(--gray-on-navy); text-decoration: underline; text-underline-offset: 2px; }
.closing-legal a:hover { color: var(--data-cyan); }

/* ============= Animaciones ============= */
.reveal-up { opacity: 0; transform: translateY(22px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal-up.is-visible { opacity: 1; transform: none; }
[data-delay="1"] { transition-delay: 0.08s; }
[data-delay="2"] { transition-delay: 0.16s; }
[data-delay="3"] { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-up { opacity: 1; transform: none; transition: none; }
  .btn:hover, .app-card:hover { transform: none; }
  .brochure-feature:hover .brochure-preview img { transform: rotate(-2deg); }
}

/* ============= Responsive ============= */
@media (max-width: 820px) {
  .brochure-feature { grid-template-columns: 1fr; gap: var(--space-6); text-align: center; }
  .brochure-preview img { max-width: 260px; transform: none; }
  .brochure-copy .btn { width: 100%; }
}
@media (max-width: 900px) {
  .cta-wrap { grid-template-columns: 1fr; gap: var(--space-7); }
}
@media (max-width: 640px) {
  .hero-brand { margin-bottom: 22px; gap: 12px; }
  .hero-wordmark { font-size: 18px; }
  .hero-logo { height: 24px; }
  .hero-accent { margin-bottom: 22px; }
  .hero-label { margin-bottom: 16px; }
  .hero h1 { margin-bottom: var(--space-5); }
}
@media (max-width: 520px) {
  .hero-actions .btn { width: 100%; }
}

/* ===== GEOMETRÍA CANÓNICA DE LA CABECERA (13/07/2026) =====================================
   wordmark → acento → eyebrow → titular → contexto. Mismas alturas y misma tipografía en TODAS
   las piezas: el gate check_render_canon.py compara las cabeceras entre sí y falla si difieren. */
.hero { position: relative; }
.hero .hero-wordmark, .hero .wordmark { display: block; font-size: 22px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.2; color: #fff; text-decoration: none; margin: 0; }
.hero .hero-logo { position: absolute; top: 52px; right: max(20px, calc(50vw - (min(94vw, 1560px) / 2) + 20px)); height: 40px !important; width: auto; opacity: .95; z-index: 3; }
.hero .hero-accent, .hero .accent { height: 4px; width: 72px; border-radius: 2px; margin: 20px 0 24px; line-height: 0; }
.hero .hero-eyebrow, .hero .eyebrow, .hero .hero-label { display: block; font-size: 13px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; line-height: 1.2; margin: 0 0 14px; }
.hero h1 { font-size: clamp(30px, 3.4vw, 46px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; margin: 0; }


/* ===== LOGO Y FONDO CANÓNICOS DE LA CABECERA (13/07/2026) =============================
   Un solo logo (mismo asset), misma altura, misma posición; y el MISMO fondo en todas.
   Gate: check_render_canon.py compara src, x, y, ancho del logo y el fondo entre piezas. */
.hero, header.hero, .hero-head, header.top { background:#111827;background-image:radial-gradient(900px 360px at 78% -10%, rgba(0,102,255,.30), transparent 60%) !important; }
.hero .hero-logo, header.hero .hero-logo, .hero-head .hero-logo, header.top .hero-logo {
  position: absolute !important; top: 52px !important;
  right: calc((100% - min(94%, 1560px)) / 2 + 20px) !important;
  height: 40px !important; width: auto !important; opacity: .95; z-index: 3; }
.hero .hero-logolink, .hero-head .hero-logolink, header.hero .hero-logolink, header.top .hero-logolink { display: contents !important; }
.hero, header.hero, .hero-head, header.top { min-height: 400px !important; }
/* con min-height, un hero flex centraría el contenido: se ancla arriba (la cabecera empieza siempre a 52 px) */
.hero, header.hero, .hero-head, header.top { align-items: flex-start !important; align-content: flex-start !important; justify-content: flex-start !important; }


/* ORDEN CANÓNICO (14/07/2026): wordmark → eyebrow → acento → titular → contexto */
.hero .hero-eyebrow, .hero .eyebrow, .hero .hero-label,
header.hero .hero-eyebrow, header.hero .eyebrow, header.hero .hero-label,
.hero-head .hero-eyebrow, header.top .hero-eyebrow { margin: 22px 0 12px !important; }
.hero .hero-accent, .hero .accent, header.hero .hero-accent, header.hero .accent,
.hero-head .hero-accent, header.top .hero-accent { margin: 0 0 22px !important; }

/* CANON 14/07/2026 — primera línea: «DSAYN Pieza» en blanco · eyebrow en cian, en la MISMA línea. */
.hero .hero-brand, header.hero .hero-brand, .hero-head .hero-brand { display: inline !important; margin: 0 !important; }
.hero .hero-wordmark, .hero .wordmark, header.hero .hero-wordmark, .hero-head .hero-wordmark,
header.top .hero-wordmark { display: inline !important; vertical-align: baseline; }
.hero .hero-eyebrow, .hero .eyebrow, .hero .hero-label,
header.hero .hero-eyebrow, header.hero .eyebrow, header.hero .hero-label,
.hero-head .hero-eyebrow, header.top .hero-eyebrow {
  display: inline !important; margin: 0 !important; vertical-align: baseline; }
.hero .hero-eyebrow::before, .hero .eyebrow::before, .hero .hero-label::before,
header.hero .hero-eyebrow::before, header.hero .eyebrow::before, header.hero .hero-label::before,
.hero-head .hero-eyebrow::before, header.top .hero-eyebrow::before {
  content: "·"; color: #fff; font-weight: 700; letter-spacing: 0; margin: 0 10px 0 8px; }
.hero .hero-accent, .hero .accent, header.hero .hero-accent, header.hero .accent,
.hero-head .hero-accent, header.top .hero-accent { margin: 22px 0 24px !important; }

/* La primera línea mide SIEMPRE 26 px, la escriba quien la escriba (si no, el alto de la caja de
   línea depende del texto y el acento y el titular bailan 1-2 px entre piezas). */
.hero .hero-wordmark, .hero .wordmark, header.hero .hero-wordmark, .hero-head .hero-wordmark, header.top .hero-wordmark,
.hero .hero-eyebrow, .hero .eyebrow, .hero .hero-label, header.hero .hero-eyebrow, header.hero .eyebrow,
header.hero .hero-label, .hero-head .hero-eyebrow, header.top .hero-eyebrow {
  display: inline-block !important; line-height: 26px !important; vertical-align: baseline !important; }

/* El contexto respira lo mismo bajo el titular en todas las piezas (referencia: la Cartera). */
.hero h1, header.hero h1, .hero-head h1, header.top h1 { margin: 0 !important; }
.hero > p, .hero .hero-sub, .hero .lead, .hero .desc, .hero .sub,
header.hero > p, header.hero .desc, .hero-head .sub, .hero-head > p, header.top .tb-lead {
  margin: 20px 0 0 !important; }

/* CTA del hero: un punto más pequeño, para que la llamada a la acción quepa en el navy canónico. */

.hero .hero-actions .btn { font-size: clamp(16px, 1.1vw, 17px) !important;
  padding: clamp(11px, .9vw, 13px) clamp(26px, 2.3vw, 34px) !important; }

.hero, header.hero, .hero-head, header.top { padding-bottom: 32px !important; }



.hero { padding-bottom: 34px !important; }


/* AFINADO DEL REPARTO VERTICAL (14/07/2026): mismos huecos, sin aire muerto, para que el navy
   entre en 400 px con el CTA a tamaño completo. Se aplica a las seis piezas por igual. */
.hero .hero-eyebrow, .hero .eyebrow, .hero .hero-label, header.hero .hero-eyebrow, header.hero .eyebrow,
header.hero .hero-label, .hero-head .hero-eyebrow, header.top .hero-eyebrow { margin: 0 !important; }
.hero .hero-accent, .hero .accent, header.hero .hero-accent, header.hero .accent,
.hero-head .hero-accent, header.top .hero-accent { margin: 18px 0 18px !important; }
.hero, header.hero, .hero-head, header.top { padding-bottom: 14px !important; }

.hero > p, .hero .hero-sub, .hero .lead, .hero .desc, .hero .sub, header.hero > p, header.hero .desc,
header.hero .hero-inner > p, .hero-head .sub, .hero-head > p { margin: 16px 0 0 !important; }
header.top .tb-lead { margin: 2px 0 0 !important; }

/* El CTA se CENTRA en el aire que sobra: con el titular en una línea (pantalla ancha) baja solo,
   y con dos líneas (1440) se queda a 26 px del contexto. Nunca queda colgado ni pegado al borde. */
.hero > .container { display: flex; flex-direction: column;
                     min-height: calc(400px - 52px - 14px); }
.hero .hero-line { display: block; }
.hero .hero-actions { margin: auto 0 !important; padding-top: 0 !important; }
.hero .hero-sub { margin-bottom: 14px !important; }   /* mismo hueco mínimo que el cierre del hero */

/* CTA secundario: sigue siendo secundario (el azul manda), pero se lee como botón.
   El borde al 16 % efectivo sobre navy se difuminaba: sube al 45 % y gana un fondo tenue. */
.hero .btn-ghost { border-color: rgba(255,255,255,.45) !important;
                   background: rgba(255,255,255,.06) !important; color: #fff !important;
                   border-width: 1.5px !important; }
.hero .btn-ghost:hover { border-color: rgba(255,255,255,.75) !important;
                         background: rgba(255,255,255,.12) !important; }

/* El cuerpo va sobre el fondo claro de marca; las tarjetas, blancas encima (ley 14/07/2026). */
body { background: #f6f8fb !important; }
.section { background: transparent !important; }
.hero { margin-bottom: 34px !important; }
.hero + .section { padding-top: 62px !important; }   /* escaparate: 96 px de aire hasta la tinta */

/* ===== ESTRECHO: el logo no compite con la cabecera (14/07/2026) =======================
   El logo va en absoluto arriba a la derecha. Cuando la ventana se estrecha, la línea
   «wordmark · eyebrow» crece hacia él y se le monta encima. Por debajo de 1024 px el logo
   se retira: el wordmark ya dice DSAYN, así que la marca no se pierde. */
@media (max-width: 1024px) {
  .hero .hero-logo, header.hero .hero-logo, .hero-head .hero-logo, header.top .hero-logo { display: none !important; }
  .hero, header.hero, .hero-head, header.top { min-height: 0 !important; }
}

/* En móvil la tarjeta de app medía 731 px: casi una pantalla por app, tres pantallas de scroll
   para ver tres. Se recorta la parte ilustrativa (el glifo), no el contenido. */
/* La banda de color crecía con el ancho de la tarjeta (aspect-ratio 16/9): en una sola columna
   se disparaba. Se acota por ALTURA, que es lo que importa; el ratio solo manda mientras cabe. */
.app-card-visual { max-height: 220px !important; min-height: 132px !important; }

@media (max-width: 700px) {
  .app-card-visual { aspect-ratio: 21 / 9 !important; min-height: 0 !important; padding: 16px !important; }
  .app-card-visual .glyph { font-size: 42px !important; }
  .app-card-body { padding: 18px 18px 20px !important; }
  .app-card-body p { font-size: 15px; line-height: 1.5; }
}

/* La cabecera NO se anima: ya está a la vista al cargar, así que el reveal-up solo produce un
   tirón (se ve en su sitio y medio segundo después sube 22 px). La animación queda para el
   cuerpo, que es donde tiene sentido: aparecer al hacer scroll. */
.hero .reveal-up { opacity: 1 !important; transform: none !important; transition: none !important; }
