/* ============================================================
   AR Arquitectura & Diseño — Base
   Reset, tipografía, componentes transversales y utilidades.
   Mobile-first: los @media son siempre min-width.
   ============================================================ */

/* ---- Satoshi auto-hospedada ----
   Extraída del propio export de Claude Design (referencia/).
   Auto-hospedar elimina una petición a un tercero y mejora el LCP
   (ESPECIFICACION-TECNICA.md §2).

   RECORTADAS: el export traía el juego completo de caracteres
   (cirílico, griego, vietnamita). El sitio está en español, así que
   se subsetearon a latino: 97 KB -> 59 KB, sin perder un solo glifo
   de los que usa el sitio. Las originales están en fonts/originales/.
   Para rehacerlo:  python herramientas/subsetear-fuentes.py

   Licencia: Fontshare / ITF Free Font License — PENDIENTE de
   confirmar para uso comercial. */
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi-300.woff2') format('woff2');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Satoshi';
  src: url('/fonts/satoshi-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ---- Reset mínimo ---- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--crema);
  color: var(--negro);
  font-family: var(--fuente);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, video, picture { display: block; max-width: 100%; }
img, video { height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }

a { color: var(--negro); }
a:hover { color: var(--verde-texto); }

::selection { background: var(--verde); color: var(--crema); }

input::placeholder, textarea::placeholder { color: var(--gris); }

/* ---- Foco visible (WCAG 2.1 AA — nunca outline:none) ---- */
:focus-visible {
  outline: 2px solid var(--verde);
  outline-offset: 3px;
  border-radius: 4px;
}
.sobre-oscuro :focus-visible { outline-color: var(--crema); }

/* ---- Saltar al contenido ---- */
.saltar {
  position: absolute;
  left: 50%;
  top: -100px;
  transform: translateX(-50%);
  z-index: calc(var(--z-modal) + 10);
  background: var(--negro);
  color: var(--crema);
  padding: 12px 24px;
  border-radius: var(--radio-pill);
  font-size: var(--txt-sm);
  font-weight: 500;
  text-decoration: none;
  transition: top var(--dur-rapida) var(--ease-suave);
}
.saltar:focus { top: 12px; color: var(--crema); }

/* ---- Solo para lectores de pantalla ---- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- Contenedor ---- */
.contenedor {
  max-width: var(--ancho-max);
  margin-inline: auto;
  padding-inline: var(--pad-lateral);
}

/* ---- Secciones ---- */
.seccion { background: var(--crema); padding-block: 0 var(--sp-seccion); }
.seccion--ancla { scroll-margin-top: 70px; }

/* PROBADO Y DESCARTADO: content-visibility: auto en las secciones de
   abajo. No movió la aguja (95-99 antes y después) y las secciones
   aparecían en blanco al saltar a ellas. Una optimización que no se
   puede verificar no se publica. */

/* ---- Etiqueta de sección (punto verde + texto en versalitas) ---- */
.etiqueta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gris);
}
.etiqueta::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--verde);
  flex: none;
}

/* ---- Titulares ---- */
.titular {
  font-weight: 300;
  font-size: var(--txt-h2);
  line-height: 1.1;
  letter-spacing: -0.015em;
  text-wrap: pretty;
}
.titular--h1 {
  font-size: var(--txt-h1);
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 15ch;
}

.texto-apoyo { font-size: 16.5px; color: var(--gris); max-width: 480px; }

/* ---- Botones ----
   Área táctil ≥ 44px en todos (WCAG 2.5.5). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 14px 32px;
  border: none;
  border-radius: var(--radio-pill);
  font-family: inherit;
  font-weight: 500;
  font-size: 16px;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-media) var(--ease),
              box-shadow var(--dur-media) ease-out,
              background var(--dur-media) ease-out;
}
.btn:hover { transform: translateY(-2px); }

.btn--verde { background: var(--verde); color: var(--negro); }
.btn--verde:hover {
  background: var(--verde-hover);
  color: var(--negro);
  box-shadow: 0 14px 32px rgba(105, 143, 0, 0.35);
}
.btn--verde:focus-visible { outline-color: var(--negro); }

.btn--negro { background: var(--negro); color: var(--crema); }
.btn--negro:hover {
  color: var(--crema);
  box-shadow: 0 14px 32px rgba(13, 13, 13, 0.3);
}

.btn--contorno {
  min-height: 44px;
  padding: 10px 22px;
  background: transparent;
  border: 1px solid var(--beige-oscuro);
  color: var(--negro);
  font-size: 14.5px;
}
.btn--contorno:hover { background: var(--crema-claro); transform: none; }

.btn--sm { min-height: 48px; padding: 12px 26px; font-size: 15px; }

/* ---- Cabecera fija ---- */
.cabecera {
  position: fixed;
  top: 14px; left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex;
  justify-content: center;
  pointer-events: none;
  padding-inline: 12px;
}

.nav {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 4px;
  background: rgba(240, 235, 227, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(212, 201, 184, 0.7);
  border-radius: var(--radio-pill);
  padding: 8px 10px;
  box-shadow: 0 8px 30px rgba(13, 13, 13, 0.08);
}

.nav__marca { display: flex; align-items: center; padding: 6px 12px 6px 8px; }
.nav__marca img { height: 20px; width: auto; }

/* El prototipo oculta los enlaces por debajo de 860px.
   Se conserva ese comportamiento con CSS, sin JS. */
.nav__enlaces { display: none; align-items: center; gap: 2px; }
@media (min-width: 861px) { .nav__enlaces { display: flex; } }

.nav__enlace {
  font-size: 14px;
  font-weight: 500;
  color: var(--negro);
  text-decoration: none;
  padding: 9px 16px;
  border-radius: var(--radio-pill);
  transition: background var(--dur-rapida) ease-out;
}
.nav__enlace:hover { background: rgba(13, 13, 13, 0.06); color: var(--negro); }

.nav__wa {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 9px 18px;
  background: var(--verde);
  border-radius: var(--radio-pill);
  color: var(--negro);
  font-weight: 500;
  font-size: 14px;
  text-decoration: none;
  margin-left: 6px;
  transition: background var(--dur-rapida) ease-out;
}
.nav__wa:hover { background: var(--verde-hover); color: var(--negro); }
.nav__wa:focus-visible { outline-color: var(--negro); }

/* ---- Pie de página ---- */
.pie {
  background: var(--negro);
  color: var(--crema);
  padding: clamp(64px, 9vh, 100px) 0 40px;
}
.pie a { color: var(--crema); text-decoration: none; }
.pie a:hover { color: var(--verde); }
.pie :focus-visible { outline-color: var(--verde); }

.pie__fila {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(40px, 6vw, 90px);
  align-items: center;
  justify-content: space-between;
}
/* Lockup de marca. Sigue el manual de identidad (Figma, "Guía
   mínima de uso"):
     · regla 2 — el logo con wordmark nunca por debajo de 120 px
     · regla 4 — el wordmark va CENTRADO bajo el símbolo, en Satoshi
       Light y en minúsculas (decisión de Alejandro, 26 jul 2026;
       la guía en Figma quedó actualizada con este criterio) */
.pie__marca {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: center;
  text-align: center;
  flex: none;
}
.pie__marca img { width: clamp(120px, 10vw, 132px); height: auto; }
/* El bloque de marca oficial (ar-wordmark-*.svg) ya trae el wordmark
   centrado bajo el símbolo, así que no hay que componerlo a mano. Se
   respeta el mínimo de 120 px de la guía de uso. */
.pie__marca img { width: clamp(132px, 14vw, 168px); height: auto; }
.pie__cols { display: flex; flex-wrap: wrap; gap: clamp(36px, 5vw, 72px); }
.pie__col { display: flex; flex-direction: column; gap: 12px; min-width: 150px; }
.pie__col--ancha { min-width: 180px; }
.pie__titulo {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gris-sobre-negro);
}
.pie__dato { font-size: 15px; color: rgba(240, 235, 227, 0.85); }
/* Los enlaces del pie medían 16 px de alto. WCAG 2.2 pide 24×24 como
   mínimo (2.5.8) y 44×44 como objetivo cómodo (2.5.5). */
.pie a, .pie__legal a {
  display: inline-block;
  padding-block: 6px;
}
.pie__legal {
  margin-top: clamp(48px, 7vh, 72px);
  padding-top: 24px;
  border-top: 1px solid rgba(240, 235, 227, 0.15);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  font-size: 13px;
  color: var(--gris-sobre-negro);
}

/* ---- Marcador de contenido pendiente ----
   Hace visible en desarrollo todo lo que falta por llenar
   (ESPECIFICACION-TECNICA.md §3.2). No cambia el color del texto
   para no romper el contraste. */
.pendiente {
  background: rgba(105, 143, 0, 0.1);
  box-shadow: inset 0 -1px 0 rgba(105, 143, 0, 0.45);
  border-radius: 3px;
  padding: 0 2px;
}

/* ---- Modo revisión de copy ----
   NO se ve nunca en el sitio normal. Se enciende añadiendo ?copys a
   la URL:  http://localhost:3000/?copys

   Antes esto era un subrayado verde y se leía como un error de
   ortografía. Ahora es un recuadro punteado alrededor del bloque, que
   es lo que de verdad comunica "esto es una caja de texto editable",
   y cada uno lleva su número para cruzarlo con COPYS.md. */
.ar-revision [data-copy] {
  outline: 1px dashed rgba(105, 143, 0, 0.55);
  outline-offset: 6px;
  border-radius: 2px;
  position: relative;
}
.ar-revision [data-copy]::after {
  content: attr(data-copy);
  position: absolute;
  top: -10px; left: -6px;
  z-index: 5;
  background: var(--verde);
  color: var(--crema);
  font-family: var(--fuente-mono);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 3px;
  pointer-events: none;
}
/* Los que además están sin llenar se marcan en rojo, para distinguir
   "puedo mejorarlo" de "falta el dato". */
.ar-revision [data-copy]:has(.pendiente),
.ar-revision [data-copy].pendiente {
  outline-color: rgba(138, 43, 13, 0.6);
}
.ar-revision [data-copy]:has(.pendiente)::after,
.ar-revision [data-copy].pendiente::after {
  background: var(--rojo-error);
}

/* ---- Placeholder de medio (video / plano por llegar) ---- */
.hueco-medio {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  text-align: center;
  border: 1px dashed var(--beige-oscuro);
  border-radius: var(--radio-lg);
  background: repeating-linear-gradient(45deg,
    var(--beige-alt) 0px, var(--beige-alt) 12px,
    var(--crema) 12px, var(--crema) 24px);
}
.hueco-medio span {
  font-family: var(--fuente-mono);
  font-size: 13px;
  color: var(--gris);
}

/* ---- Slot de imagen (mientras no hay foto real) ----
   Reserva la caja con aspect-ratio para no generar CLS cuando
   entren las imágenes reales en la Fase E. */
.slot {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
  background: var(--beige-alt);
  color: var(--gris);
  font-family: var(--fuente-mono);
  font-size: 12.5px;
  line-height: 1.45;
  overflow: hidden;
}
.slot > span { max-width: 100%; overflow-wrap: anywhere; }
.slot--oscuro { background: var(--negro-suave); color: var(--gris-sobre-negro); }
.slot--circulo { border-radius: 50%; }
.slot img { width: 100%; height: 100%; object-fit: cover; }
.hueco-medio span { max-width: 100%; overflow-wrap: anywhere; }

/* Cuando llega la foto real, el hueco deja de ser un hueco:
   fuera el relleno, el fondo beige y el texto del marcador. */
.slot--lleno {
  padding: 0;
  background: none;
  /* contain: la imagen manda; el hueco ya no reserva nada. */
}
.slot--lleno.slot--circulo img { border-radius: 50%; }

/* ============================================================
   CURSOR PERSONALIZADO Y MINIATURA DE PROYECTO
   ------------------------------------------------------------
   Recuperados del prototipo. Se activan SOLO cuando se cumplen
   todas estas condiciones (las comprueba js/cursor.js):
     · puntero fino con hover real  → nunca en táctil
     · sin prefers-reduced-motion
     · sin forced-colors (alto contraste de Windows)
     · CONTENIDO.interaccion.cursorPersonalizado === true

   Ambos elementos arrancan en display:none. Si el JS no corre,
   no existen y el cursor del sistema queda intacto.
   ============================================================ */

#ar-cursor-ring,
#ar-cursor-dot,
#port-thumb { display: none; }

.ar-cursor-activo #ar-cursor-ring,
.ar-cursor-activo #ar-cursor-dot { display: block; }

#ar-cursor-ring {
  position: fixed;
  left: -80px; top: -80px;
  width: 36px; height: 36px;
  border-radius: var(--radio-pill);
  background: transparent;
  border: 1.5px solid rgba(105, 143, 0, 0.55);
  pointer-events: none;
  z-index: 100;
  transform: translate(-50%, -50%);
  transition: width 0.32s var(--ease), height 0.32s var(--ease),
              background 0.3s ease-out, border-color 0.3s ease-out;
}

#ar-cursor-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--negro);
  opacity: 0;
  transition: opacity 0.25s ease-out;
  white-space: nowrap;
}

#ar-cursor-dot {
  position: fixed;
  left: -80px; top: -80px;
  width: 7px; height: 7px;
  border-radius: var(--radio-pill);
  background: var(--verde);
  pointer-events: none;
  z-index: 101;
  transform: translate(-50%, -50%);
  transition: opacity 0.2s ease-out;
  box-shadow: 0 0 0 4px rgba(105, 143, 0, 0.14);
}

/* ---- Estados del cursor ----
   Valores exactos del prototipo. Se manejan con clases en <html> y no
   con estilos en línea: así el estado "sobre verde" puede sobrescribir
   por especificidad sin pelearse con el JS. */

/* Sobre cualquier elemento interactivo: crece y se llena un poco de
   verde. Es el matiz que da la sensación de "agarre". */
.ar-cursor-inter #ar-cursor-ring {
  width: 48px; height: 48px;
  background: rgba(105, 143, 0, 0.12);
  border-color: var(--verde);
}

/* Sobre algo con etiqueta (comparador, fila de proyecto): se llena del
   verde de marca y muestra el texto. */
.ar-cursor-etiqueta #ar-cursor-ring {
  width: 86px; height: 86px;
  background: var(--verde);
  border-color: var(--verde);
}
.ar-cursor-etiqueta #ar-cursor-label { opacity: 1; }
.ar-cursor-etiqueta #ar-cursor-dot { opacity: 0; }

/* Al oprimir, el anillo se contrae. Sin transición, como el prototipo. */
.ar-cursor-presionado #ar-cursor-ring { transform: translate(-50%, -50%) scale(0.8); }

/* Sobre superficies verdes el cursor verde desaparecía.
   Único cambio respecto al prototipo: ahí se vuelve crema. */
.ar-cursor-sobre-verde #ar-cursor-ring {
  border-color: var(--crema);
  background: rgba(240, 235, 227, 0.2);
}
.ar-cursor-sobre-verde #ar-cursor-dot {
  background: var(--crema);
  box-shadow: 0 0 0 4px rgba(240, 235, 227, 0.22);
}

/* El cursor del sistema se oculta solo mientras el personalizado
   está vivo… */
.ar-cursor-activo, .ar-cursor-activo * { cursor: none !important; }

/* …pero NUNCA sobre campos de texto: sin el cursor en I no se ve
   dónde se está escribiendo. Ahí manda el nativo y el nuestro se
   esconde (lo gestiona cursor.js con .ar-cursor-oculto). */
.ar-cursor-activo input:not([type="checkbox"]):not([type="radio"]),
.ar-cursor-activo textarea { cursor: text !important; }
.ar-cursor-activo select,
.ar-cursor-activo input[type="checkbox"] { cursor: pointer !important; }

.ar-cursor-oculto #ar-cursor-ring,
.ar-cursor-oculto #ar-cursor-dot { opacity: 0; }

/* ---- Miniatura flotante del índice de proyectos ---- */
.ar-thumb-activo #port-thumb { display: block; }

#port-thumb {
  position: fixed;
  left: 0; top: 0;
  width: 300px; height: 210px;
  border-radius: 22px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease-out;
  z-index: 60;
  box-shadow: 0 24px 60px rgba(13, 13, 13, 0.3);
  background: var(--crema-claro);
}
#port-thumb [data-thumb-for] { position: absolute; inset: 0; display: none; }
#port-thumb [data-thumb-for].visible { display: block; }
#port-thumb .slot { font-size: 11.5px; }
#port-thumb img { width: 100%; height: 100%; object-fit: cover; }

@media (prefers-reduced-motion: reduce) {
  #ar-cursor-ring, #ar-cursor-dot, #port-thumb { display: none !important; }
  .ar-cursor-activo, .ar-cursor-activo * { cursor: auto !important; }
}
@media (forced-colors: active) {
  #ar-cursor-ring, #ar-cursor-dot, #port-thumb { display: none !important; }
  .ar-cursor-activo, .ar-cursor-activo * { cursor: auto !important; }
}

/* PROBADO Y RETIRADO: un enlace "Saltar el manifiesto".
   Se veía mal —al recibir el foco se superponía sobre la sección
   siguiente— y resultó innecesario: se comprobó que el manifiesto no
   contiene ningún otro elemento enfocable, así que Tab ya salta de
   "Agenda tu diagnóstico" directo al tirador del comparador. La
   §7.3 pide que la sección se pueda saltar, y el orden natural de
   tabulación ya lo cumple. Decisión de Alejandro, 26 jul 2026. */

/* ============================================================
   INTRO DE ENTRADA
   ------------------------------------------------------------
   REDISEÑADA: #intro ya no tiene logo propio, es solo un rectángulo
   negro que cubre la pantalla. El logo que se ve mientras tanto es
   el único logo que existe en todo el sitio — el del hero
   (#hero .hero__logo-caja, css/secciones.css)—, que vive por encima
   de este negro por z-index y aparece con su propio aparecer, sin
   depender de que la intro termine. Así el logo nunca se crea, se
   borra ni se intercambia por otro: solo el negro que tenía delante
   se disuelve y lo descubre. Antes se intentó tener un logo dentro
   de la intro que se encogía o se desvanecía hacia el del hero —
   con dos elementos separados siempre quedaba algún punto donde se
   notaba el cambio. Esta versión no tiene ese punto porque no hay
   cambio: es un solo logo, todo el tiempo.

   Nace VISIBLE por CSS puro — no espera a ningún script. La animación
   arIntroAutoSale la retira sola, con un temporizador en CSS puro
   (animation-delay), así que aunque js/intro.js no llegara a correr
   nunca, el overlay igual se va solo. Ese script solo permite
   adelantar la salida con un clic o una tecla (ver .saliendo).
   index.html trae además un <noscript> por si JavaScript está
   deshabilitado del todo.
   ============================================================ */
#intro {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--negro);
  animation: arIntroAutoSale 1.5s var(--ease-suave) 1.5s forwards;
}
/* El clic/tecla adelanta la salida — MISMA animación, mismo 1,5 s de
   duración, solo sin la espera previa. Antes esto se hacía con
   "#intro.saliendo { animation-delay: 0s; }", pero cambiar el retardo
   de una animación que ya está corriendo no reinicia su reloj: lo
   REINTERPRETA con el tiempo ya transcurrido desde que se aplicó la
   animación (al cargar la página), así que para cuando el retardo
   original de 1,5 s se cumplía, el cálculo daba la animación por
   terminada — saltaba directo a opacidad 0 en vez de desvanecerse.
   Por eso subir la duración en el CSS no cambiaba nada: nunca llegaba
   a jugarse. Ahora js/intro.js reinicia la animación de verdad
   (quitarla, forzar un reflow, volver a ponerla) en vez de solo
   tocarle el retardo — ver retirar() ahí. Esta clase ya no cambia el
   retardo: solo lo pone en 0 para cuando JS reconstruye la
   animación desde cero. */
#intro.saliendo { animation: arIntroAutoSale 1.5s var(--ease-suave) forwards; }

/* Ya se vio en esta sesión, o prefers-reduced-motion: el script
   síncrono del <head> puso esta clase ANTES del primer pintado, así
   que la intro ni llega a aparecer un instante. */
html.ar-sin-intro #intro { display: none; }

@keyframes arIntroAutoSale {
  from { opacity: 1; pointer-events: auto; }
  to   { opacity: 0; pointer-events: none; }
}

/* Mientras la intro está encima, se congela el scroll del fondo. La
   clase nace puesta en el propio <html> servido —no la agrega JS—
   para que el bloqueo también rija desde el primer pintado. */
.ar-intro-activa, .ar-intro-activa body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  /* Capa extra de defensa por si el script síncrono del <head> no
     llegara a correr: reduced-motion oculta el overlay Y libera el
     scroll solo con CSS, sin depender de JS en ningún punto. */
  #intro { display: none !important; }
  .ar-intro-activa, .ar-intro-activa body { overflow: visible !important; }
}
